84 lines
2.8 KiB
PHP
84 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Preferences;
|
|
|
|
use App\Models\Preferences;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
|
|
class PreferencesQueryService
|
|
{
|
|
public function __construct(private PreferencesOptionsService $options)
|
|
{
|
|
}
|
|
|
|
public function getForUser(int $userId): array
|
|
{
|
|
$row = Preferences::query()->where('user_id', $userId)->first();
|
|
|
|
$base = $this->options->defaultPreferences();
|
|
if (!$row) {
|
|
return [
|
|
'preferences' => $base,
|
|
'options' => $this->optionsPayload(),
|
|
];
|
|
}
|
|
|
|
return [
|
|
'preferences' => array_merge($base, $this->mapRow($row)),
|
|
'options' => $this->optionsPayload(),
|
|
];
|
|
}
|
|
|
|
public function paginate(array $filters, int $page = 1, int $perPage = 20): LengthAwarePaginator
|
|
{
|
|
$query = Preferences::query()
|
|
->leftJoin('users', 'users.id', '=', 'user_preferences.user_id')
|
|
->select('user_preferences.*', 'users.firstname', 'users.lastname', 'users.email');
|
|
|
|
if (!empty($filters['user_id'])) {
|
|
$query->where('user_preferences.user_id', (int) $filters['user_id']);
|
|
}
|
|
|
|
if (!empty($filters['q'])) {
|
|
$term = '%' . strtolower(trim((string) $filters['q'])) . '%';
|
|
$query->where(function ($q) use ($term) {
|
|
$q->whereRaw('LOWER(users.firstname) LIKE ?', [$term])
|
|
->orWhereRaw('LOWER(users.lastname) LIKE ?', [$term])
|
|
->orWhereRaw('LOWER(users.email) LIKE ?', [$term]);
|
|
});
|
|
}
|
|
|
|
$sortBy = (string) ($filters['sort_by'] ?? 'updated_at');
|
|
$sortDir = strtolower((string) ($filters['sort_dir'] ?? 'desc')) === 'asc' ? 'asc' : 'desc';
|
|
$allowedSorts = ['updated_at', 'created_at', 'user_id'];
|
|
|
|
if (in_array($sortBy, $allowedSorts, true)) {
|
|
$query->orderBy('user_preferences.' . $sortBy, $sortDir);
|
|
} else {
|
|
$query->orderBy('user_preferences.updated_at', 'desc');
|
|
}
|
|
|
|
return $query->paginate($perPage, ['*'], 'page', $page);
|
|
}
|
|
|
|
private function optionsPayload(): array
|
|
{
|
|
return [
|
|
'style_options' => $this->options->styleOptions(),
|
|
'menu_options' => $this->options->menuOptions(),
|
|
];
|
|
}
|
|
|
|
private function mapRow(Preferences $row): array
|
|
{
|
|
return [
|
|
'receive_email_notifications' => (bool) ($row->notification_email ?? false),
|
|
'receive_sms_notifications' => (bool) ($row->notification_sms ?? false),
|
|
'theme' => $row->theme ?? null,
|
|
'language' => $row->language ?? null,
|
|
'style_color' => $row->style_color ?? null,
|
|
'menu_color' => $row->menu_color ?? null,
|
|
];
|
|
}
|
|
}
|