reconstruction of the project

This commit is contained in:
root
2026-03-08 16:33:24 -04:00
parent 23b7db1107
commit c8de5f7edc
9157 changed files with 77877 additions and 1073823 deletions
+144 -65
View File
@@ -2,12 +2,18 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;
class UserRole extends BaseModel
{
use SoftDeletes;
protected $table = 'user_roles';
protected $primaryKey = 'id';
protected $fillable = [
'user_id',
'role_id',
@@ -16,82 +22,155 @@ class UserRole extends BaseModel
'deleted_at',
'updated_by',
];
public $timestamps = true;
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
protected $deletedField = 'deleted_at';
/**
* ✅ Fetch all role names assigned to a specific user
*
* @param int $userId
* @return array Array of roles, e.g., [['name' => 'parent'], ['name' => 'teacher']]
protected $casts = [
'user_id' => 'integer',
'role_id' => 'integer',
'updated_by' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
/* ============================================================
* Relationships
* ============================================================
*/
public function create()
{
$users = $this->db->table('users')
->select('users.*')
->join('user_roles', 'user_roles.user_id = users.id')
->join('roles', 'roles.id = user_roles.role_id')
->whereNotIn('roles.name', ['parent', 'teacher'])
->groupBy('users.id') // prevent duplicates if user has multiple roles
->get()
->getResultArray();
return view('expenses/create', ['users' => $users]);
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
/**
* 🔁 Deprecated: Use getAllRolesByUserId instead
* Get the first role name by user ID
*
* @param int $userId
* @return string|null
*/
public function getRolesByUserId(int $userId): array
{
$roles = $this->select('roles.name as role_name')
->join('roles', 'roles.id = user_roles.role_id')
->where('user_roles.user_id', $userId)
->get()
->getResultArray();
// Always return an array
return is_array($roles) ? $roles : [];
}
/**
* ✅ Insert or update a role assignment
*
* @param int $userId
* @param int $roleId
* @return bool|int
*/
public function updateOrInsertRole($userId, $roleId)
public function role(): BelongsTo
{
// Check if this exact (user_id, role_id) already exists
$exists = $this->where([
'user_id' => $userId,
'role_id' => $roleId
])->first();
return $this->belongsTo(Role::class, 'role_id');
}
if ($exists) {
// Already exists, nothing to do
/* ============================================================
* Scopes
* ============================================================
*/
public function scopeForUser(Builder $q, int $userId): Builder
{
return $q->where('user_id', $userId);
}
public function scopeForRole(Builder $q, int $roleId): Builder
{
return $q->where('role_id', $roleId);
}
public function scopeForSchoolYear(Builder $q, ?string $schoolYear): Builder
{
if ($schoolYear === null || trim($schoolYear) === '') return $q;
return $q->where('school_year', $schoolYear);
}
/* ============================================================
* CI-compatible methods (converted)
* ============================================================
*/
/**
* CI: getRolesByUserId($userId)
* Returns: [ ['role_name' => 'parent'], ['role_name' => 'teacher'] ]
*/
public static function getRolesByUserId(int $userId): array
{
return static::query()
->selectRaw('roles.name as role_name')
->join('roles', 'roles.id', '=', 'user_roles.role_id')
->where('user_roles.user_id', $userId)
->whereNull('user_roles.deleted_at')
->orderBy('roles.priority', 'asc')
->orderBy('roles.name', 'asc')
->get()
->map(fn ($r) => ['role_name' => (string) $r->role_name])
->all();
}
/**
* CI: updateOrInsertRole($userId, $roleId)
* Idempotent (does nothing if already exists and not soft-deleted).
* If the row exists but is soft-deleted, restores it.
*/
public static function updateOrInsertRole(int $userId, int $roleId, ?int $editorId = null): bool
{
$editorId = $editorId ?? (auth()->id() ?? null);
$existing = static::withTrashed()
->where('user_id', $userId)
->where('role_id', $roleId)
->first();
if ($existing) {
if ($existing->trashed()) {
$existing->restore();
}
// keep updated_by fresh
if ($editorId !== null) {
$existing->updated_by = $editorId;
$existing->save();
}
return true;
}
// Otherwise, insert new user-role mapping
return $this->insert([
static::query()->create([
'user_id' => $userId,
'role_id' => $roleId,
'updated_by' => session()->get('user_id')
'updated_by' => $editorId,
]);
return true;
}
/* ============================================================
* Replacement for the CI "create()" method (query only)
* ============================================================
* In Laravel, view rendering belongs in Controllers, not Models.
* This returns the user list that your CI method was building.
*
* CI logic:
* users joined to roles through user_roles, excluding parent/teacher,
* groupBy users.id to avoid duplicates.
*/
public static function usersExcludingRoles(array $excludedRoleNames = ['parent', 'teacher']): array
{
$excluded = array_values(array_unique(array_filter(array_map('strval', $excludedRoleNames))));
$excludedLower = array_map('strtolower', $excluded);
$placeholders = implode(',', array_fill(0, count($excludedLower), '?'));
return DB::table('users')
->select('users.*')
->join('user_roles', 'user_roles.user_id', '=', 'users.id')
->join('roles', 'roles.id', '=', 'user_roles.role_id')
->whereNull('user_roles.deleted_at')
->whereRaw("LOWER(roles.name) NOT IN ($placeholders)", $excludedLower)
->groupBy('users.id')
->orderBy('users.lastname', 'asc')
->orderBy('users.firstname', 'asc')
->get()
->map(fn ($r) => (array) $r)
->all();
}
/* ============================================================
* Optional validation helper
* ============================================================
*/
public static function rules(bool $updating = false): array
{
$req = $updating ? 'sometimes' : 'required';
return [
'user_id' => [$req, 'integer', 'min:1', 'exists:users,id'],
'role_id' => [$req, 'integer', 'min:1', 'exists:roles,id'],
'semester' => ['nullable', 'string', 'max:20'],
'school_year'=> ['nullable', 'string', 'max:20'],
'updated_by' => ['nullable', 'integer'],
];
}
}