Issues (590)

src/Collection/CollectionFactory.php (4 issues)

1
<?php
2
3
namespace Bdf\Prime\Collection;
4
5
use Bdf\Prime\Repository\RepositoryInterface;
6
7
/**
8
 * Factory for CollectionInterface
9
 */
10
class CollectionFactory
11
{
12
    /**
13
     * Alias of known collection class
14
     *
15
     * @var array<string, class-string<CollectionInterface>|callable(array):CollectionInterface>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, class-stri...y):CollectionInterface> at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in array<string, class-string<CollectionInterface>|callable(array):CollectionInterface>.
Loading history...
16
     */
17
    private $aliases = [
18
        'array' => ArrayCollection::class,
19
    ];
20
21
    /**
22
     * List of collection factories, indexed by the class name
23
     *
24
     * @var array<class-string<CollectionInterface>, callable(array):CollectionInterface>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string<Colle...y):CollectionInterface> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string<CollectionInterface>, callable(array):CollectionInterface>.
Loading history...
25
     */
26
    private $factories = [];
27
28
29
    /**
30
     * Cannot instantiate externally
31
     */
32 413
    protected function __construct()
33
    {
34 413
    }
35
36
    /**
37
     * Register a new wrapper alias for @see Query::wrapAs()
38
     *
39
     * <pre><code>
40
     * $factory->registerWrapperAlias('myCollection', MyCollection::class);
41
     * $factory->wrap($data, 'myCollection'); //Will perform `new MyCollection($data);`
42
     * $factory->registerWrapperAlias('myCollection', function ($data) {
43
     *      $collection = new MyCollection($data);
44
     *      $collection->doSomething();
45
     *      return $collection;
46
     * });
47
     * $factory->wrap($data, 'myCollection'); //Will perform `$closure($data);`
48
     * $factory->registerWrapperAlias('myCollection', MyCollection::class, function ($data) {
49
     *     return new MyCollection(...);
50
     * });
51
     * $factory->wrap($data, 'myCollection'); //Will perform `$closure($data);`
52
     * $factory->wrap($data, MyCollection::class);
53
     * </code></pre>
54
     *
55
     * @param string $wrapperAlias The wrapper alias name
56
     * @param class-string<CollectionInterface>|callable(array):CollectionInterface $wrapperClass The wrapper class, or callable for instantiate the wrapper
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<CollectionI...ay):CollectionInterface at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<CollectionInterface>|callable(array):CollectionInterface.
Loading history...
57
     * @param callable(array):CollectionInterface|null $factory The wrapper factory. If null use the constructor
58
     *
59
     * @return void
60
     */
61 417
    public function registerWrapperAlias(string $wrapperAlias, $wrapperClass, ?callable $factory = null)
62
    {
63 417
        $this->aliases[$wrapperAlias] = $wrapperClass;
64
65 417
        if ($factory) {
66
            /** @var class-string<CollectionInterface> $wrapperClass */
67 414
            $this->factories[$wrapperClass] = $factory;
68
        }
69
    }
70
71
    /**
72
     * Wrap data with a wrapper class
73
     *
74
     * @param T[] $data
75
     * @param string|callable $wrapper
76
     *
77
     * @return CollectionInterface<T>
78
     *
79
     * @template T
80
     */
81 33
    public function wrap(array $data, $wrapper = 'array')
82
    {
83 33
        if (is_string($wrapper) && isset($this->aliases[$wrapper])) {
84 20
            $wrapper = $this->aliases[$wrapper];
85
        }
86
87 33
        if (is_string($wrapper)) {
88 32
            if (isset($this->factories[$wrapper])) {
89 14
                return $this->factories[$wrapper]($data);
90
            } else {
91 18
                return new $wrapper($data);
92
            }
93
        }
94
95 1
        return $wrapper($data);
96
    }
97
98
    /**
99
     * Get the wrapper class from a wrapper alias
100
     *
101
     * @param string $wrapper
102
     *
103
     * @return class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
104
     */
105 9
    public function wrapperClass(string $wrapper): string
106
    {
107 9
        if (isset($this->aliases[$wrapper])) {
108 8
            $wrapper = $this->aliases[$wrapper];
109
        }
110
111 9
        if (!is_string($wrapper) || !class_exists($wrapper)) {
112 1
            throw new \InvalidArgumentException('');
113
        }
114
115 8
        return $wrapper;
116
    }
117
118
    /**
119
     * Create a CollectionFactory related to an EntityRepository
120
     *
121
     * @param RepositoryInterface $repository
122
     *
123
     * @return static
124
     */
125 412
    public static function forRepository(RepositoryInterface $repository): self
126
    {
127 412
        $factory = new static();
128 412
        $factory->registerWrapperAlias('collection', EntityCollection::class, [$repository, 'collection']);
129
130 412
        return $factory;
131
    }
132
133
    /**
134
     * Create a CollectionFactory for simple Queries
135
     *
136
     * /!\ The CollectionFactory instance is shared by ALL queries. You should not overrides wrapper aliases
137
     *
138
     * @return static
139
     */
140 19
    public static function forDbal(): self
141
    {
142 19
        static $instance;
143
144 19
        if ($instance === null) {
145 1
            $instance = new static();
146
        }
147
148 19
        return $instance;
149
    }
150
151
    /**
152
     * Get the handled collection classes
153
     *
154
     * @return string[]
155
     */
156 413
    public static function collections(): array
157
    {
158 413
        return [ArrayCollection::class, EntityCollection::class];
159
    }
160
}
161