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, ]; } }