|
- <?php
-
- declare(strict_types=1);
-
- namespace App\Repositories;
-
- use Core\Repository;
-
- class HouseholdRepository extends Repository
- {
- protected string $table = 'households';
- protected string $primaryKey = 'id';
-
- public function countAll(string $search = '', string $territoryId = '', string $doNotCall = ''): int
- {
- [$sql, $params] = $this->buildFilterQuery(
- 'SELECT COUNT(*) AS n FROM households h
- JOIN territories t ON t.id = h.territory_id',
- $search, $territoryId, $doNotCall
- );
-
- $row = $this->database->first($sql, $params);
- return (int) ($row['n'] ?? 0);
- }
-
- /** @return list<array<string,mixed>> */
- public function findPaged(int $page, int $perPage, string $search = '', string $territoryId = '', string $doNotCall = ''): array
- {
- $offset = ($page - 1) * $perPage;
-
- [$where, $params] = $this->buildFilterQuery(
- 'SELECT h.*, t.name AS territory_name FROM households h
- JOIN territories t ON t.id = h.territory_id',
- $search, $territoryId, $doNotCall
- );
-
- return $this->database->query(
- $where . ' ORDER BY t.name ASC, h.street_name ASC, h.street_number ASC
- LIMIT :limit OFFSET :offset',
- array_merge($params, ['limit' => $perPage, 'offset' => $offset])
- );
- }
-
- /** @return list<array<string,mixed>> */
- public function findAllByTerritory(int|string $territoryId): array
- {
- return $this->database->query(
- 'SELECT * FROM households WHERE territory_id = :id
- ORDER BY street_name ASC, street_number ASC',
- ['id' => $territoryId]
- );
- }
-
- /** @return list<array<string,mixed>> */
- public function findAllByTerritories(array $territoryIds): array
- {
- if (empty($territoryIds)) {
- return [];
- }
-
- $placeholders = implode(',', array_fill(0, count($territoryIds), '?'));
-
- return $this->database->query(
- "SELECT h.*, t.name AS territory_name
- FROM households h
- JOIN territories t ON t.id = h.territory_id
- WHERE h.territory_id IN ({$placeholders})
- ORDER BY t.name ASC, h.street_name ASC, h.street_number ASC",
- array_values($territoryIds)
- );
- }
-
- public function findWithTerritory(int|string $id): ?array
- {
- return $this->database->first(
- 'SELECT h.*, t.name AS territory_name
- FROM households h
- JOIN territories t ON t.id = h.territory_id
- WHERE h.id = :id',
- ['id' => $id]
- );
- }
-
- /** @return array{string, array<string,mixed>} */
- private function buildFilterQuery(string $base, string $search, string $territoryId, string $doNotCall): array
- {
- $conditions = [];
- $params = [];
-
- if ($search !== '') {
- $conditions[] = '(h.address LIKE :s OR h.street_name LIKE :s)';
- $params['s'] = '%' . $search . '%';
- }
-
- if ($territoryId !== '') {
- $conditions[] = 'h.territory_id = :tid';
- $params['tid'] = $territoryId;
- }
-
- if ($doNotCall === '1') {
- $conditions[] = 'h.do_not_call = 1';
- } elseif ($doNotCall === '0') {
- $conditions[] = 'h.do_not_call = 0';
- }
-
- $sql = $base;
- if (!empty($conditions)) {
- $sql .= ' WHERE ' . implode(' AND ', $conditions);
- }
-
- return [$sql, $params];
- }
- }
|