Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.49% covered (warning)
80.49%
33 / 41
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
SqlActionRepository
80.00% covered (warning)
80.00%
32 / 40
66.67% covered (warning)
66.67%
2 / 3
7.39
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 findByCategory
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
3
 findByName
57.89% covered (warning)
57.89%
11 / 19
0.00% covered (danger)
0.00%
0 / 1
3.67
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Action\Infrastructure\Repository;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Action\Domain\Model\ActionMetadata;
12use App\Core\Action\Domain\Repository\ActionRepositoryInterface;
13use PDO;
14
15/**
16 * SQL Action Repository Implementation.
17 *
18 * Persists and fetches action configurations from `a_core_action_records`.
19 *
20 * @package App\Core\Action\Infrastructure\Repository
21 */
22final readonly class SqlActionRepository implements ActionRepositoryInterface
23{
24    /**
25     * SqlActionRepository constructor.
26     *
27     * @param PDO    $pdo         Database connection.
28     * @param string $tablePrefix Table name prefix.
29     */
30    public function __construct(
31        private PDO $pdo,
32        private string $tablePrefix = 'a_'
33    ) {
34    }
35
36    /** {@inheritdoc} */
37    public function findByCategory(string $category, ?int $moduleId = null): array
38    {
39        $tableName = $this->tablePrefix . 'core_action_records';
40
41        if ($moduleId !== null) {
42            $sql = "SELECT `id`, `module_id`, `name`, `label`, `category`, `target_type`,
43                           `handler_key`, `icon_class`, `button_class`, `confirmation_required`,
44                           `confirmation_message`, `sort_order`, `is_active`, `is_system`
45                    FROM `{$tableName}`
46                    WHERE `category` = :category
47                      AND `is_active` = 1
48                      AND (`module_id` IS NULL OR `module_id` = :module_id)
49                    ORDER BY `sort_order` ASC, `id` ASC";
50
51            $stmt = $this->pdo->prepare($sql);
52            $stmt->execute([
53                ':category'  => $category,
54                ':module_id' => $moduleId,
55            ]);
56        } else {
57            $sql = "SELECT `id`, `module_id`, `name`, `label`, `category`, `target_type`,
58                           `handler_key`, `icon_class`, `button_class`, `confirmation_required`,
59                           `confirmation_message`, `sort_order`, `is_active`, `is_system`
60                    FROM `{$tableName}`
61                    WHERE `category` = :category
62                      AND `is_active` = 1
63                      AND `module_id` IS NULL
64                    ORDER BY `sort_order` ASC, `id` ASC";
65
66            $stmt = $this->pdo->prepare($sql);
67            $stmt->execute([':category' => $category]);
68        }
69
70        /** @var array<int, array<string, mixed>> $rows */
71        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
72
73        $actions = [];
74        foreach ($rows as $row) {
75            $actions[] = ActionMetadata::fromRow($row);
76        }
77
78        return $actions;
79    }
80
81    /** {@inheritdoc} */
82    public function findByName(string $name, ?int $moduleId = null): ?ActionMetadata
83    {
84        $tableName = $this->tablePrefix . 'core_action_records';
85
86        if ($moduleId !== null) {
87            $sql = "SELECT `id`, `module_id`, `name`, `label`, `category`, `target_type`,
88                           `handler_key`, `icon_class`, `button_class`, `confirmation_required`,
89                           `confirmation_message`, `sort_order`, `is_active`, `is_system`
90                    FROM `{$tableName}`
91                    WHERE `name` = :name
92                      AND `is_active` = 1
93                      AND (`module_id` = :module_id OR `module_id` IS NULL)
94                    ORDER BY `module_id` DESC
95                    LIMIT 1";
96
97            $stmt = $this->pdo->prepare($sql);
98            $stmt->execute([
99                ':name'      => $name,
100                ':module_id' => $moduleId,
101            ]);
102        } else {
103            $sql = "SELECT `id`, `module_id`, `name`, `label`, `category`, `target_type`,
104                           `handler_key`, `icon_class`, `button_class`, `confirmation_required`,
105                           `confirmation_message`, `sort_order`, `is_active`, `is_system`
106                    FROM `{$tableName}`
107                    WHERE `name` = :name
108                      AND `is_active` = 1
109                      AND `module_id` IS NULL
110                    LIMIT 1";
111
112            $stmt = $this->pdo->prepare($sql);
113            $stmt->execute([':name' => $name]);
114        }
115
116        /** @var array<string, mixed>|false $row */
117        $row = $stmt->fetch(PDO::FETCH_ASSOC);
118
119        if ($row === false) {
120            return null;
121        }
122
123        return ActionMetadata::fromRow($row);
124    }
125}