reconstruction of the project
This commit is contained in:
+119
-35
@@ -2,12 +2,13 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Models\BaseModel;
|
||||
|
||||
class Role extends BaseModel
|
||||
{
|
||||
protected $table = 'roles';
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'slug',
|
||||
@@ -18,52 +19,135 @@ class Role extends BaseModel
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
const CREATED_AT = 'created_at';
|
||||
const UPDATED_AT = 'updated_at';
|
||||
|
||||
public function findByNamesOrSlugs(array $keys): array
|
||||
protected $casts = [
|
||||
'priority' => 'integer',
|
||||
'is_active' => 'boolean',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
/* ============================================================
|
||||
* Scopes
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
public function scopeActive(Builder $q): Builder
|
||||
{
|
||||
if (empty($keys)) return [];
|
||||
|
||||
// Normalize for case-insensitive matching
|
||||
$lower = array_map('strtolower', $keys);
|
||||
|
||||
// We’ll match on lower(name) or lower(slug)
|
||||
return $this->where('is_active', 1)
|
||||
->groupStart()
|
||||
->whereIn('LOWER(name)', $lower)
|
||||
->orWhereIn('LOWER(slug)', $lower)
|
||||
->groupEnd()
|
||||
->orderBy('priority', 'ASC') // highest priority first
|
||||
->findAll();
|
||||
return $q->where('is_active', 1);
|
||||
}
|
||||
|
||||
public function getRouteByNameOrSlug(string $key): ?string
|
||||
public function scopeOrderByPriority(Builder $q, string $dir = 'asc'): Builder
|
||||
{
|
||||
$row = $this->where('is_active', 1)
|
||||
->groupStart()
|
||||
->where('LOWER(name)', strtolower($key))
|
||||
->orWhere('LOWER(slug)', strtolower($key))
|
||||
->groupEnd()
|
||||
return $q->orderBy('priority', $dir);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* Helpers (CI-compatible)
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Find roles by names or slugs (case-insensitive), active only, ordered by priority ASC.
|
||||
*/
|
||||
|
||||
// Put these INSIDE the Role model, replacing the current implementations
|
||||
|
||||
public static function findByNamesOrSlugs(array $keys): array
|
||||
{
|
||||
$keys = array_values(array_filter(array_map('strval', $keys)));
|
||||
if (empty($keys)) return [];
|
||||
|
||||
$lower = array_map('mb_strtolower', $keys);
|
||||
$placeholders = implode(',', array_fill(0, count($lower), '?'));
|
||||
|
||||
return static::query()
|
||||
->active()
|
||||
->where(function (Builder $q) use ($lower, $placeholders) {
|
||||
$q->whereRaw("LOWER(name) IN ($placeholders)", $lower)
|
||||
->orWhereRaw("LOWER(slug) IN ($placeholders)", $lower);
|
||||
})
|
||||
->orderBy('priority', 'asc')
|
||||
->get()
|
||||
->all();
|
||||
}
|
||||
|
||||
public static function getIdsByNames(array $names): array
|
||||
{
|
||||
$names = array_values(array_filter(array_map('strval', $names)));
|
||||
if (empty($names)) return [];
|
||||
|
||||
$lower = array_map('mb_strtolower', $names);
|
||||
$placeholders = implode(',', array_fill(0, count($lower), '?'));
|
||||
|
||||
$ids = static::query()
|
||||
->select('id')
|
||||
->whereRaw("LOWER(name) IN ($placeholders)", $lower)
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
return array_map('intval', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dashboard_route by name or slug (case-insensitive), active only.
|
||||
*/
|
||||
public static function getRouteByNameOrSlug(string $key): ?string
|
||||
{
|
||||
$key = trim((string) $key);
|
||||
if ($key === '') return null;
|
||||
|
||||
$lower = mb_strtolower($key);
|
||||
|
||||
$role = static::query()
|
||||
->active()
|
||||
->where(function (Builder $q) use ($lower) {
|
||||
$q->whereRaw('LOWER(name) = ?', [$lower])
|
||||
->orWhereRaw('LOWER(slug) = ?', [$lower]);
|
||||
})
|
||||
->first();
|
||||
|
||||
return $row['dashboard_route'] ?? null;
|
||||
return $role?->dashboard_route;
|
||||
}
|
||||
|
||||
public function getRoles()
|
||||
/**
|
||||
* Equivalent to CI getRoles(): returns all roles.
|
||||
*/
|
||||
public static function getRoles()
|
||||
{
|
||||
return $this->findAll();
|
||||
return static::query()->get();
|
||||
}
|
||||
|
||||
/** Map role names -> role IDs */
|
||||
public function getIdsByNames(array $names): array
|
||||
/**
|
||||
* DB-agnostic LOWER(column) expression for whereIn.
|
||||
* Laravel doesn't allow whereIn on expressions directly, so we use whereRaw.
|
||||
* This helper returns the SQL snippet used in whereRaw calls.
|
||||
*/
|
||||
protected static function lowerExpr(string $column): string
|
||||
{
|
||||
$names = array_values(array_filter(array_map('strval', $names)));
|
||||
if (empty($names)) return [];
|
||||
|
||||
// collation is usually case-insensitive; if not, add LOWER() both sides
|
||||
$ids = $this->select('id')->whereIn('name', $names)->findColumn('id');
|
||||
return array_map('intval', $ids ?? []);
|
||||
// Used only inside whereRaw with bindings.
|
||||
// Example: whereInRaw not available, so we build "LOWER(column) in (?, ?, ?)" via whereRaw below
|
||||
// In our code above we used whereIn(static::lowerExpr('name'), $lower) which is not allowed by Eloquent.
|
||||
// To keep things correct, we implement a macro-like helper below instead.
|
||||
return $column;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* Optional: validation rules helper (FormRequest/controller)
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
public static function rules(?int $id = null): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'slug' => ['required', 'string', 'max:255', 'unique:roles,slug,' . ($id ?? 'NULL') . ',id'],
|
||||
'description' => ['nullable', 'string', 'max:2000'],
|
||||
'dashboard_route' => ['nullable', 'string', 'max:255'],
|
||||
'priority' => ['nullable', 'integer', 'min:0'],
|
||||
'is_active' => ['nullable', 'boolean'],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user