Passed
Pull Request — master (#185)
by Tobias
02:54
created

ModelFactory::__callStatic()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
ccs 3
cts 3
cp 1
crap 2
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A ModelFactory::createMany() 0 5 1
1
<?php
2
3
namespace Zenstruck\Foundry;
4
5
/**
6
 * @template TModel of object
7
 * @extends Factory<TModel>
8
 *
9
 * @author Kevin Bond <[email protected]>
10
 */
11
abstract class ModelFactory extends Factory
12
{
13 604
    public function __construct()
14
    {
15 604
        parent::__construct(static::getClass());
16 604
    }
17
18
    /**
19
     * @return list<TModel&Proxy<TModel>>
0 ignored issues
show
Bug introduced by
The type Zenstruck\Foundry\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
     * @psalm-return list<Proxy<TModel>>
21
     */
22
    public static function createMany(): array
23
    {
24 611
        $arguments = \func_get_args();
25
26 611
        return static::new()->many($arguments[0])->create($arguments[1] ?? []);
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::new()->ma...rguments[1] ?? array()) returns the type array which is incompatible with the documented return type Zenstruck\Foundry\list.
Loading history...
27 10
    }
28 10
29
    /**
30
     * @param array|callable|string $defaultAttributes If string, assumes state
31
     * @param string                ...$states         Optionally pass default states (these must be methods on your ObjectFactory with no arguments)
32 611
     *
33 16
     * @return static
34 10
     */
35
    final public static function new($defaultAttributes = [], string ...$states): self
36
    {
37
        if (\is_string($defaultAttributes)) {
38 604
            $states = \array_merge([$defaultAttributes], $states);
39 604
            $defaultAttributes = [];
40 604
        }
41
42
        try {
43 604
            $factory = self::isBooted() ? self::configuration()->factories()->create(static::class) : new static();
44 20
        } catch (\ArgumentCountError $e) {
45
            throw new \RuntimeException('Model Factories with dependencies (Model Factory services) cannot be created before foundry is booted.', 0, $e);
46
        }
47 600
48 10
        $factory = $factory
49
            ->withAttributes([$factory, 'getDefaults'])
50
            ->withAttributes($defaultAttributes)
51 600
            ->initialize()
52
        ;
53
54
        if (!$factory instanceof static) {
0 ignored issues
show
introduced by
$factory is always a sub-type of static.
Loading history...
55
            throw new \TypeError(\sprintf('"%1$s::initialize()" must return an instance of "%1$s".', static::class));
56
        }
57
58
        foreach ($states as $state) {
59
            $factory = $factory->{$state}();
60
        }
61
62 10
        return $factory;
63
    }
64 10
65 10
    /**
66
     * A shortcut to create a single model without states.
67
     *
68 10
     * @return Proxy<TModel>&TModel
69
     * @psalm-return Proxy<TModel>
70
     */
71
    final public static function createOne(array $attributes = []): Proxy
72
    {
73
        return static::new()->create($attributes);
74 20
    }
75
76 20
    /**
77
     * Try and find existing object for the given $attributes. If not found,
78
     * instantiate and persist.
79
     *
80
     * @return Proxy<TModel>&TModel
81
     * @psalm-return Proxy<TModel>
82 10
     */
83
    final public static function findOrCreate(array $attributes): Proxy
84 10
    {
85
        if ($found = static::repository()->find($attributes)) {
86
            return \is_array($found) ? $found[0] : $found;
0 ignored issues
show
introduced by
The condition is_array($found) is always false.
Loading history...
87
        }
88
89
        return static::new()->create($attributes);
90 10
    }
91
92 10
    /**
93
     * @see RepositoryProxy::first()
94
     *
95
     * @return Proxy<TModel>&TModel
96 210
     * @psalm-return Proxy<TModel>
97
     *
98 210
     * @throws \RuntimeException If no entities exist
99
     */
100
    final public static function first(string $sortedField = 'id'): Proxy
101
    {
102
        if (null === $proxy = static::repository()->first($sortedField)) {
103
            throw new \RuntimeException(\sprintf('No "%s" objects persisted.', static::getClass()));
104
        }
105
106 600
        return $proxy;
107
    }
108 600
109
    /**
110
     * @see RepositoryProxy::last()
111
     *
112
     * @return Proxy<TModel>&TModel
113
     * @psalm-return Proxy<TModel>
114
     *
115
     * @throws \RuntimeException If no entities exist
116 30
     */
117
    final public static function last(string $sortedField = 'id'): Proxy
118 30
    {
119
        if (null === $proxy = static::repository()->last($sortedField)) {
120
            throw new \RuntimeException(\sprintf('No "%s" objects persisted.', static::getClass()));
121
        }
122
123
        return $proxy;
124
    }
125
126
    /**
127
     * @see RepositoryProxy::random()
128
     *
129
     * @return Proxy<TModel>&TModel
130
     * @psalm-return Proxy<TModel>
131
     */
132
    final public static function random(array $attributes = []): Proxy
133
    {
134
        return static::repository()->random($attributes);
135
    }
136
137
    /**
138
     * Fetch one random object and create a new object if none exists.
139
     *
140
     * @return Proxy<TModel>&TModel
141
     * @psalm-return Proxy<TModel>
142
     */
143
    final public static function randomOrCreate(array $attributes = []): Proxy
144
    {
145
        try {
146
            return static::repository()->random($attributes);
147
        } catch (\RuntimeException $e) {
148
            return static::new()->create($attributes);
149
        }
150
    }
151
152
    /**
153
     * @see RepositoryProxy::randomSet()
154
     *
155
     * @return list<TModel&Proxy<TModel>>
156
     */
157
    final public static function randomSet(int $number, array $attributes = []): array
158
    {
159
        return static::repository()->randomSet($number, $attributes);
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::repositor...t($number, $attributes) returns the type array which is incompatible with the documented return type Zenstruck\Foundry\list.
Loading history...
160
    }
161
162
    /**
163
     * @see RepositoryProxy::randomRange()
164
     *
165
     * @return list<TModel&Proxy<TModel>>
166
     */
167
    final public static function randomRange(int $min, int $max, array $attributes = []): array
168
    {
169
        return static::repository()->randomRange($min, $max, $attributes);
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::repositor...min, $max, $attributes) returns the type array which is incompatible with the documented return type Zenstruck\Foundry\list.
Loading history...
170
    }
171
172
    /**
173
     * @see RepositoryProxy::count()
174
     */
175
    final public static function count(): int
176
    {
177
        return static::repository()->count();
178
    }
179
180
    /**
181
     * @see RepositoryProxy::truncate()
182
     */
183
    final public static function truncate(): void
184
    {
185
        static::repository()->truncate();
186
    }
187
188
    /**
189
     * @see RepositoryProxy::findAll()
190
     *
191
     * @return list<TModel&Proxy<TModel>>
192
     */
193
    final public static function all(): array
194
    {
195
        return static::repository()->findAll();
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::repository()->findAll() returns the type array which is incompatible with the documented return type Zenstruck\Foundry\list.
Loading history...
196
    }
197
198
    /**
199
     * @see RepositoryProxy::find()
200
     *
201
     * @return Proxy<TModel>&TModel
202
     * @psalm-return Proxy<TModel>
203
     *
204
     * @throws \RuntimeException If no entity found
205
     */
206
    final public static function find($criteria): Proxy
207
    {
208
        if (null === $proxy = static::repository()->find($criteria)) {
209
            throw new \RuntimeException(\sprintf('Could not find "%s" object.', static::getClass()));
210
        }
211
212
        return $proxy;
213
    }
214
215
    /**
216
     * @see RepositoryProxy::findBy()
217
     *
218
     * @return list<TModel&Proxy<TModel>>
219
     */
220
    final public static function findBy(array $attributes): array
221
    {
222
        return static::repository()->findBy($attributes);
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::repository()->findBy($attributes) returns the type array which is incompatible with the documented return type Zenstruck\Foundry\list.
Loading history...
223
    }
224
225
    final public static function assert(): RepositoryAssertions
226
    {
227
        return static::repository()->assert();
228
    }
229
230
    /**
231
     * @psalm-return RepositoryProxy<TModel>
232
     */
233
    final public static function repository(): RepositoryProxy
234
    {
235
        return static::configuration()->repositoryFor(static::getClass());
236
    }
237
238
    /**
239
     * @internal
240
     * @psalm-return class-string<TModel>
241
     */
242
    final public static function getEntityClass(): string
243
    {
244
        return static::getClass();
245
    }
246
247
    /** @psalm-return class-string<TModel> */
248
    abstract protected static function getClass(): string;
249
250
    /**
251
     * Override to add default instantiator and default afterInstantiate/afterPersist events.
252
     *
253
     * @return static
254
     */
255
    protected function initialize()
256
    {
257
        return $this;
258
    }
259
260
    /**
261
     * @param array|callable $attributes
262
     *
263
     * @return static
264
     */
265
    final protected function addState($attributes = []): self
266
    {
267
        return $this->withAttributes($attributes);
268
    }
269
270
    abstract protected function getDefaults(): array;
271
}
272