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

Cecilapp / Cecil / 15735686664

18 Jun 2025 02:29PM UTC coverage: 82.609% (-0.02%) from 82.627%
15735686664

push

github

ArnaudLigny
refactor: code quality

0 of 1 new or added line in 1 file covered. (0.0%)

79 existing lines in 5 files now uncovered.

3116 of 3772 relevant lines covered (82.61%)

0.83 hits per line

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

66.1
/src/Collection/Collection.php
1
<?php
2

3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <arnaud@ligny.fr>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace Cecil\Collection;
15

16
/**
17
 * Class Collection.
18
 *
19
 * Represents a collection of items, providing methods to manage them.
20
 */
21
class Collection implements CollectionInterface
22
{
23
    /**
24
     * Collection's identifier.
25
     * @var string
26
     */
27
    protected $id;
28
    /**
29
     * Collection's items.
30
     * @var array
31
     */
32
    protected $items = [];
33

34
    public function __construct(string $id, array $items = [])
35
    {
36
        $this->setId($id);
1✔
37
        $this->items = $items;
1✔
38
    }
39

40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function setId(string $id): BaseInterface
44
    {
45
        $this->id = $id;
1✔
46

47
        return $this;
1✔
48
    }
49

50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function getId(): string
54
    {
55
        return $this->id;
1✔
56
    }
57

58
    /**
59
     * Search an item by ID.
60
     */
61
    protected function searchItem(string $id): ?array
62
    {
63
        return array_filter($this->items, function (ItemInterface $item) use ($id) {
1✔
64
            return $item->getId() == $id;
1✔
65
        });
1✔
66
    }
67

68
    /**
69
     * {@inheritdoc}
70
     *
71
     * @throws \DomainException
72
     */
73
    public function getPosition(string $id): int
74
    {
75
        $result = $this->searchItem($id);
1✔
76
        $position = key($result);
1✔
77
        if (!\is_int($position)) {
1✔
UNCOV
78
            throw new \DomainException(\sprintf('"%s" does not exist in "%s" collection.', $id, $this->getId()));
×
79
        }
80

81
        return $position;
1✔
82
    }
83

84
    /**
85
     * {@inheritdoc}
86
     */
87
    public function has(string $id): bool
88
    {
89
        $result = $this->searchItem($id);
1✔
90
        if (\is_array($result) && !empty($result)) {
1✔
91
            return true;
1✔
92
        }
93

94
        return false;
1✔
95
    }
96

97
    /**
98
     * {@inheritdoc}
99
     *
100
     * @throws \DomainException
101
     */
102
    public function add(ItemInterface $item): CollectionInterface
103
    {
104
        if ($this->has($item->getId())) {
1✔
105
            throw new \DomainException(\sprintf('Failed adding "%s" in "%s" collection: item already exists.', $item->getId(), $this->getId()));
1✔
106
        }
107
        $this->items[] = $item;
1✔
108

109
        return $this;
1✔
110
    }
111

112
    /**
113
     * {@inheritdoc}
114
     *
115
     * @throws \DomainException
116
     */
117
    public function replace(string $id, ItemInterface $item): CollectionInterface
118
    {
119
        try {
120
            $this->items[$this->getPosition($id)] = $item;
1✔
UNCOV
121
        } catch (\DomainException) {
×
UNCOV
122
            throw new \DomainException(\sprintf('Failed replacing "%s" in "%s" collection: item does not exist.', $id, $this->getId()));
×
123
        }
124

125
        return $this;
1✔
126
    }
127

128
    /**
129
     * {@inheritdoc}
130
     *
131
     * @throws \DomainException
132
     */
133
    public function remove(string $id): CollectionInterface
134
    {
135
        try {
136
            unset($this->items[$this->getPosition($id)]);
1✔
UNCOV
137
        } catch (\DomainException) {
×
UNCOV
138
            throw new \DomainException(\sprintf('Failed removing "%s" in "%s" collection: item does not exist.', $id, $this->getId()));
×
139
        }
140

141
        return $this;
1✔
142
    }
143

144
    /**
145
     * {@inheritdoc}
146
     *
147
     * @throws \DomainException
148
     */
149
    public function get(string $id): ItemInterface
150
    {
151
        try {
152
            return $this->items[$this->getPosition($id)];
1✔
UNCOV
153
        } catch (\DomainException) {
×
UNCOV
154
            throw new \DomainException(\sprintf('Failed getting "%s" in "%s" collection: item does not exist.', $id, $this->getId()));
×
155
        }
156
    }
157

158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function keys(): array
162
    {
UNCOV
163
        return array_keys($this->items);
×
164
    }
165

166
    /**
167
     * {@inheritdoc}
168
     */
169
    public function first(): ?ItemInterface
170
    {
171
        if (\count($this->items) < 1) {
1✔
UNCOV
172
            return null;
×
173
        }
174
        $items = $this->items;
1✔
175

176
        return array_shift($items);
1✔
177
    }
178

179
    /**
180
     * {@inheritdoc}
181
     */
182
    public function last(): ?ItemInterface
183
    {
184
        if (\count($this->items) < 1) {
×
UNCOV
185
            return null;
×
186
        }
UNCOV
187
        $items = $this->items;
×
188

UNCOV
189
        return array_pop($items);
×
190
    }
191

192
    /**
193
     * {@inheritdoc}
194
     */
195
    public function count(): int
196
    {
197
        return \count($this->items);
1✔
198
    }
199

200
    /**
201
     * {@inheritdoc}
202
     */
203
    public function toArray(): array
204
    {
205
        return $this->items;
1✔
206
    }
207

208
    /**
209
     * {@inheritdoc}
210
     */
211
    public function toJson(): string
212
    {
UNCOV
213
        return \sprintf("%s\n", json_encode($this->items));
×
214
    }
215

216
    /**
217
     * {@inheritdoc}
218
     */
219
    public function getIterator(): \ArrayIterator
220
    {
221
        return new \ArrayIterator($this->items);
1✔
222
    }
223

224
    /**
225
     * {@inheritdoc}
226
     */
227
    public function usort(?\Closure $callback = null): CollectionInterface
228
    {
229
        $callback ? usort($this->items, $callback) : usort($this->items, function ($a, $b) {
1✔
UNCOV
230
            if ($a == $b) {
×
UNCOV
231
                return 0;
×
232
            }
233

UNCOV
234
            return ($a < $b) ? -1 : 1;
×
235
        });
1✔
236

237
        return new static($this->getId(), $this->items); /** @phpstan-ignore-line */
1✔
238
    }
239

240
    /**
241
     * {@inheritdoc}
242
     */
243
    public function reverse(): CollectionInterface
244
    {
UNCOV
245
        return new static($this->getId(), array_reverse($this->items)); /** @phpstan-ignore-line */
×
246
    }
247

248
    /**
249
     * {@inheritdoc}
250
     */
251
    public function filter(\Closure $callback): CollectionInterface
252
    {
253
        return new static($this->getId(), array_filter($this->items, $callback)); /** @phpstan-ignore-line */
1✔
254
    }
255

256
    /**
257
     * {@inheritdoc}
258
     */
259
    public function map(\Closure $callback): CollectionInterface
260
    {
261
        return new static($this->getId(), array_map($callback, $this->items)); /** @phpstan-ignore-line */
1✔
262
    }
263

264
    /**
265
     * Implements \ArrayAccess.
266
     *
267
     * @param string $offset
268
     *
269
     * @return bool
270
     */
271
    #[\ReturnTypeWillChange]
272
    public function offsetExists($offset): bool
273
    {
274
        return $this->has((string) $offset);
1✔
275
    }
276

277
    /**
278
     * Implements \ArrayAccess.
279
     *
280
     * @param string $offset
281
     *
282
     * @return CollectionInterface|ItemInterface|null
283
     */
284
    #[\ReturnTypeWillChange]
285
    public function offsetGet($offset)
286
    {
287
        return $this->get((string) $offset);
1✔
288
    }
289

290
    /**
291
     * Implements \ArrayAccess.
292
     *
293
     * @param mixed         $offset
294
     * @param ItemInterface $value
295
     *
296
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
297
     */
298
    #[\ReturnTypeWillChange]
299
    public function offsetSet($offset, $value): void
300
    {
UNCOV
301
        $this->add($value);
×
302
    }
303

304
    /**
305
     * Implements \ArrayAccess.
306
     *
307
     * @param string $offset
308
     *
309
     * @return void
310
     */
311
    #[\ReturnTypeWillChange]
312
    public function offsetUnset($offset): void
313
    {
UNCOV
314
        $this->remove($offset);
×
315
    }
316

317
    /**
318
     * Returns the collection ID.
319
     *
320
     * @return string
321
     */
322
    public function __toString()
323
    {
324
        return $this->getId();
1✔
325
    }
326
}
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

© 2026 Coveralls, Inc