Issues (178)

src/Collection/LoophpCollectionFactory.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\ORM\Collection;
6
7
use Cycle\ORM\Collection\Pivoted\LoophpPivotedCollection;
8
use Cycle\ORM\Collection\Pivoted\PivotedStorage;
9
use Cycle\ORM\Exception\CollectionFactoryException;
10
use loophp\collection\Collection;
11
use loophp\collection\CollectionDecorator;
12
use loophp\collection\Contract\Collection as CollectionInterface;
13
14
/**
15
 * @template TCollection of Collection
16
 *
17
 * @template-implements CollectionFactoryInterface<TCollection>
18
 */
19
final class LoophpCollectionFactory implements CollectionFactoryInterface
20
{
21
    /** @var class-string<TCollection> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TCollection> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TCollection>.
Loading history...
22
    private string $class = Collection::class;
23
24
    private bool $decoratorExists = false;
25
26
    public function __construct()
27
    {
28
        if (!\class_exists(Collection::class, true)) {
29
            throw new CollectionFactoryException(
30
                \sprintf(
31
                    'There is no %s class. To resolve this issue you can install `loophp/collection` package.',
32
                    Collection::class
33
                )
34
            );
35
        }
36
37
        if (\class_exists(CollectionDecorator::class, true)) {
38
            $this->decoratorExists = true;
39
        }
40
    }
41
42
    public function getInterface(): string
43
    {
44
        return CollectionInterface::class;
45
    }
46
47
    public function withCollectionClass(string $class): static
48
    {
49
        if (
50
            $this->decoratorExists &&
51
            (\is_a($class, CollectionDecorator::class, true) || $class === CollectionInterface::class)
52
        ) {
53
            $clone = clone $this;
54
            $clone->class = $class === CollectionInterface::class ? Collection::class : $class;
55
56
            return $clone;
57
        }
58
59
        if ($class !== Collection::class) {
60
            throw new CollectionFactoryException(\sprintf(
61
                'Unsupported collection class `%s`.',
62
                $class
63
            ));
64
        }
65
66
        return clone $this;
67
    }
68
69
    public function collect(iterable $data): CollectionInterface
70
    {
71
        if ($data instanceof PivotedStorage && $this->decoratorExists) {
72
            if ($this->class === Collection::class || $this->class === CollectionInterface::class) {
73
                return new LoophpPivotedCollection($data->getElements(), $data->getContext());
74
            }
75
76
            if (\is_a($this->class, LoophpPivotedCollection::class)) {
77
                return new $this->class($data->getElements(), $data->getContext());
78
            }
79
        }
80
81
        return $this->class::fromIterable($data);
82
    }
83
}
84