25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.8KB

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Repositories;
  4. use App\Models\Campaign;
  5. use Core\Repository;
  6. class CampaignRepository extends Repository
  7. {
  8. protected string $table = 'campaign';
  9. protected string $primaryKey = 'id';
  10. public function count(): int
  11. {
  12. $row = $this->database->first('SELECT COUNT(*) AS total FROM campaign');
  13. return (int) ($row['total'] ?? 0);
  14. }
  15. /** @return list<array<string, mixed>> */
  16. public function recentWithType(int $limit = 5): array
  17. {
  18. return $this->database->query(
  19. "SELECT TOP ({$limit}) c.id, c.created_at, ct.name AS campaign_type_name
  20. FROM campaign c
  21. INNER JOIN campaign_type ct ON c.campaign_type_id = ct.id
  22. ORDER BY c.id DESC"
  23. );
  24. }
  25. /** @return list<array<string, mixed>> */
  26. public function countByType(): array
  27. {
  28. return $this->database->query(
  29. 'SELECT ct.name AS campaign_type_name, COUNT(c.id) AS campaign_count
  30. FROM campaign_type ct
  31. LEFT JOIN campaign c ON c.campaign_type_id = ct.id
  32. GROUP BY ct.id, ct.name
  33. ORDER BY campaign_count DESC, ct.name ASC'
  34. );
  35. }
  36. /**
  37. * All campaigns joined with their campaign type name, ordered by id desc.
  38. *
  39. * @return list<array<string, mixed>>
  40. */
  41. public function allWithType(): array
  42. {
  43. return $this->database->query(
  44. 'SELECT c.id, c.campaign_type_id, c.attribute_values,
  45. c.created_at, c.updated_at,
  46. ct.name AS campaign_type_name,
  47. ct.attributes AS campaign_type_attributes
  48. FROM campaign c
  49. INNER JOIN campaign_type ct ON c.campaign_type_id = ct.id
  50. ORDER BY c.id DESC'
  51. );
  52. }
  53. /**
  54. * Single campaign joined with its campaign type name and attributes.
  55. */
  56. public function findWithType(int $id): ?array
  57. {
  58. return $this->database->first(
  59. 'SELECT c.id, c.campaign_type_id, c.attribute_values,
  60. c.created_at, c.updated_at,
  61. ct.name AS campaign_type_name,
  62. ct.attributes AS campaign_type_attributes
  63. FROM campaign c
  64. INNER JOIN campaign_type ct ON c.campaign_type_id = ct.id
  65. WHERE c.id = :id',
  66. ['id' => $id]
  67. );
  68. }
  69. /**
  70. * Return the most recently inserted campaign for a given type.
  71. * Used after an INSERT to retrieve the generated id for audit logging.
  72. */
  73. public function findLatestByType(int $typeId): ?array
  74. {
  75. return $this->database->first(
  76. 'SELECT TOP (1) * FROM campaign
  77. WHERE campaign_type_id = :type_id
  78. ORDER BY id DESC',
  79. ['type_id' => $typeId]
  80. );
  81. }
  82. public function create(Campaign $campaign): bool
  83. {
  84. return $this->database->execute(
  85. 'INSERT INTO campaign (campaign_type_id, attribute_values)
  86. VALUES (:campaign_type_id, :attribute_values)',
  87. [
  88. 'campaign_type_id' => $campaign->campaignTypeId,
  89. 'attribute_values' => json_encode($campaign->attributeValues, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE),
  90. ]
  91. );
  92. }
  93. public function update(Campaign $campaign): bool
  94. {
  95. return $this->database->execute(
  96. 'UPDATE campaign
  97. SET campaign_type_id = :campaign_type_id,
  98. attribute_values = :attribute_values,
  99. updated_at = CURRENT_TIMESTAMP
  100. WHERE id = :id',
  101. [
  102. 'campaign_type_id' => $campaign->campaignTypeId,
  103. 'attribute_values' => json_encode($campaign->attributeValues, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE),
  104. 'id' => $campaign->id,
  105. ]
  106. );
  107. }
  108. }

Powered by TurnKey Linux.