• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemsdk / docker-symfony-api / #85

pending completion
#85

push

DKravtsov
Updated dependencies, refactoring.

21 of 21 new or added lines in 14 files covered. (100.0%)

1440 of 2683 relevant lines covered (53.67%)

21.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.0
/src/General/Infrastructure/Repository/BaseRepository.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace App\General\Infrastructure\Repository;
6

7
use App\General\Domain\Entity\Interfaces\EntityInterface;
8
use App\General\Domain\Repository\Interfaces\BaseRepositoryInterface;
9
use App\General\Infrastructure\Repository\Traits\RepositoryMethodsTrait;
10
use App\General\Infrastructure\Repository\Traits\RepositoryWrappersTrait;
11
use Doctrine\ORM\EntityManager;
12
use Doctrine\ORM\QueryBuilder;
13
use Doctrine\Persistence\ManagerRegistry;
14
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
15

16
use function array_map;
17
use function array_unshift;
18
use function implode;
19
use function in_array;
20
use function serialize;
21
use function sha1;
22
use function spl_object_hash;
23

24
/**
25
 * Class BaseRepository
26
 *
27
 * @package App\General
28
 */
29
#[AutoconfigureTag('app.rest.repository')]
30
#[AutoconfigureTag('app.stopwatch')]
31
abstract class BaseRepository implements BaseRepositoryInterface
32
{
33
    use RepositoryMethodsTrait;
34
    use RepositoryWrappersTrait;
35

36
    private const INNER_JOIN = 'innerJoin';
37
    private const LEFT_JOIN = 'leftJoin';
38

39
    /**
40
     * @psalm-var class-string
41
     */
42
    protected static string $entityName;
43

44
    /**
45
     * @var array<int, string>
46
     */
47
    protected static array $searchColumns = [];
48
    protected static EntityManager $entityManager;
49
    protected ManagerRegistry $managerRegistry;
50

51
    /**
52
     * Joins that need to attach to queries, this is needed for to prevent duplicate joins on those.
53
     *
54
     * @var array<string, array<array<int, scalar>>>
55
     */
56
    private static array $joins = [
57
        self::INNER_JOIN => [],
58
        self::LEFT_JOIN => [],
59
    ];
60

61
    /**
62
     * @var array<string, array<int, string>>
63
     */
64
    private static array $processedJoins = [
65
        self::INNER_JOIN => [],
66
        self::LEFT_JOIN => [],
67
    ];
68

69
    /**
70
     * @var array<int, array{0: callable, 1: array<mixed>}>
71
     */
72
    private static array $callbacks = [];
73

74
    /**
75
     * @var array<int, string>
76
     */
77
    private static array $processedCallbacks = [];
78

79
    /**
80
     * {@inheritdoc}
81
     *
82
     * @psalm-return class-string
83
     */
84
    public function getEntityName(): string
85
    {
86
        return static::$entityName;
145✔
87
    }
88

89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function getSearchColumns(): array
93
    {
94
        return static::$searchColumns;
64✔
95
    }
96

97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function save(EntityInterface $entity, ?bool $flush = null, ?string $entityManagerName = null): self
101
    {
102
        $flush ??= true;
144✔
103
        // Persist on database
104
        $this->getEntityManager($entityManagerName)->persist($entity);
144✔
105

106
        if ($flush) {
144✔
107
            $this->getEntityManager($entityManagerName)->flush();
144✔
108
        }
109

110
        return $this;
144✔
111
    }
112

113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function remove(EntityInterface $entity, ?bool $flush = null, ?string $entityManagerName = null): self
117
    {
118
        $flush ??= true;
5✔
119
        // Remove from database
120
        $this->getEntityManager($entityManagerName)->remove($entity);
5✔
121

122
        if ($flush) {
5✔
123
            $this->getEntityManager($entityManagerName)->flush();
5✔
124
        }
125

126
        return $this;
5✔
127
    }
128

129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function processQueryBuilder(QueryBuilder $queryBuilder): void
133
    {
134
        // Reset processed joins and callbacks
135
        self::$processedJoins = [
64✔
136
            self::INNER_JOIN => [],
64✔
137
            self::LEFT_JOIN => [],
64✔
138
        ];
64✔
139
        self::$processedCallbacks = [];
64✔
140
        $this->processJoins($queryBuilder);
64✔
141
        $this->processCallbacks($queryBuilder);
64✔
142
    }
143

144
    /**
145
     * {@inheritdoc}
146
     */
147
    public function addLeftJoin(array $parameters): self
148
    {
149
        if ($parameters !== []) {
×
150
            $this->addJoinToQuery(self::LEFT_JOIN, $parameters);
×
151
        }
152

153
        return $this;
×
154
    }
155

156
    /**
157
     * {@inheritdoc}
158
     */
159
    public function addInnerJoin(array $parameters): self
160
    {
161
        if ($parameters !== []) {
×
162
            $this->addJoinToQuery(self::INNER_JOIN, $parameters);
×
163
        }
164

165
        return $this;
×
166
    }
167

168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function addCallback(callable $callable, ?array $args = null): self
172
    {
173
        $args ??= [];
×
174
        $hash = sha1(serialize([spl_object_hash((object)$callable), ...$args]));
×
175

176
        if (!in_array($hash, self::$processedCallbacks, true)) {
×
177
            self::$callbacks[] = [$callable, $args];
×
178
            self::$processedCallbacks[] = $hash;
×
179
        }
180

181
        return $this;
×
182
    }
183

184
    /**
185
     * Process defined joins for current QueryBuilder instance.
186
     */
187
    protected function processJoins(QueryBuilder $queryBuilder): void
188
    {
189
        foreach (self::$joins as $joinType => $joins) {
64✔
190
            array_map(
64✔
191
                static fn (array $joinParameters): QueryBuilder => $queryBuilder->{$joinType}(...$joinParameters),
64✔
192
                $joins,
64✔
193
            );
64✔
194

195
            self::$joins[$joinType] = [];
64✔
196
        }
197
    }
198

199
    /**
200
     * Process defined callbacks for current QueryBuilder instance.
201
     */
202
    protected function processCallbacks(QueryBuilder $queryBuilder): void
203
    {
204
        foreach (self::$callbacks as [$callback, $args]) {
64✔
205
            array_unshift($args, $queryBuilder);
×
206
            $callback(...$args);
×
207
        }
208

209
        self::$callbacks = [];
64✔
210
    }
211

212
    /**
213
     * Method to add defined join(s) to current QueryBuilder query. This will keep track of attached join(s) so any of
214
     * those are not added multiple times to QueryBuilder.
215
     *
216
     * @note processJoins() method must be called for joins to actually be added to QueryBuilder. processQueryBuilder()
217
     *       method calls this method automatically.
218
     *
219
     * @see QueryBuilder::leftJoin()
220
     * @see QueryBuilder::innerJoin()
221
     *
222
     * @param string $type Join type; leftJoin, innerJoin or join
223
     * @param array<int, scalar> $parameters Query builder join parameters
224
     */
225
    private function addJoinToQuery(string $type, array $parameters): void
226
    {
227
        $comparison = implode('|', $parameters);
×
228

229
        if (!in_array($comparison, self::$processedJoins[$type], true)) {
×
230
            self::$joins[$type][] = $parameters;
×
231

232
            self::$processedJoins[$type][] = $comparison;
×
233
        }
234
    }
235
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc