您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

114 行
3.5KB

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Repositories;
  4. use Core\Repository;
  5. class HouseholdRepository extends Repository
  6. {
  7. protected string $table = 'households';
  8. protected string $primaryKey = 'id';
  9. public function countAll(string $search = '', string $territoryId = '', string $doNotCall = ''): int
  10. {
  11. [$sql, $params] = $this->buildFilterQuery(
  12. 'SELECT COUNT(*) AS n FROM households h
  13. JOIN territories t ON t.id = h.territory_id',
  14. $search, $territoryId, $doNotCall
  15. );
  16. $row = $this->database->first($sql, $params);
  17. return (int) ($row['n'] ?? 0);
  18. }
  19. /** @return list<array<string,mixed>> */
  20. public function findPaged(int $page, int $perPage, string $search = '', string $territoryId = '', string $doNotCall = ''): array
  21. {
  22. $offset = ($page - 1) * $perPage;
  23. [$where, $params] = $this->buildFilterQuery(
  24. 'SELECT h.*, t.name AS territory_name FROM households h
  25. JOIN territories t ON t.id = h.territory_id',
  26. $search, $territoryId, $doNotCall
  27. );
  28. return $this->database->query(
  29. $where . ' ORDER BY t.name ASC, h.street_name ASC, h.street_number ASC
  30. LIMIT :limit OFFSET :offset',
  31. array_merge($params, ['limit' => $perPage, 'offset' => $offset])
  32. );
  33. }
  34. /** @return list<array<string,mixed>> */
  35. public function findAllByTerritory(int|string $territoryId): array
  36. {
  37. return $this->database->query(
  38. 'SELECT * FROM households WHERE territory_id = :id
  39. ORDER BY street_name ASC, street_number ASC',
  40. ['id' => $territoryId]
  41. );
  42. }
  43. /** @return list<array<string,mixed>> */
  44. public function findAllByTerritories(array $territoryIds): array
  45. {
  46. if (empty($territoryIds)) {
  47. return [];
  48. }
  49. $placeholders = implode(',', array_fill(0, count($territoryIds), '?'));
  50. return $this->database->query(
  51. "SELECT h.*, t.name AS territory_name
  52. FROM households h
  53. JOIN territories t ON t.id = h.territory_id
  54. WHERE h.territory_id IN ({$placeholders})
  55. ORDER BY t.name ASC, h.street_name ASC, h.street_number ASC",
  56. array_values($territoryIds)
  57. );
  58. }
  59. public function findWithTerritory(int|string $id): ?array
  60. {
  61. return $this->database->first(
  62. 'SELECT h.*, t.name AS territory_name
  63. FROM households h
  64. JOIN territories t ON t.id = h.territory_id
  65. WHERE h.id = :id',
  66. ['id' => $id]
  67. );
  68. }
  69. /** @return array{string, array<string,mixed>} */
  70. private function buildFilterQuery(string $base, string $search, string $territoryId, string $doNotCall): array
  71. {
  72. $conditions = [];
  73. $params = [];
  74. if ($search !== '') {
  75. $conditions[] = '(h.address LIKE :s OR h.street_name LIKE :s)';
  76. $params['s'] = '%' . $search . '%';
  77. }
  78. if ($territoryId !== '') {
  79. $conditions[] = 'h.territory_id = :tid';
  80. $params['tid'] = $territoryId;
  81. }
  82. if ($doNotCall === '1') {
  83. $conditions[] = 'h.do_not_call = 1';
  84. } elseif ($doNotCall === '0') {
  85. $conditions[] = 'h.do_not_call = 0';
  86. }
  87. $sql = $base;
  88. if (!empty($conditions)) {
  89. $sql .= ' WHERE ' . implode(' AND ', $conditions);
  90. }
  91. return [$sql, $params];
  92. }
  93. }

Powered by TurnKey Linux.