Passed
Push — master ( 6bd319...2d574a )
by Kevin
04:56
created

ModelFactory::initialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Zenstruck\Foundry;
4
5
/**
6
 * @template TModel of object
7
 * @template-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
     * @param array|callable|string $defaultAttributes If string, assumes state
20
     * @param string                ...$states         Optionally pass default states (these must be methods on your ObjectFactory with no arguments)
21
     *
22
     * @return static
23
     */
24 611
    final public static function new($defaultAttributes = [], string ...$states): self
25
    {
26 611
        if (\is_string($defaultAttributes)) {
27 10
            $states = \array_merge([$defaultAttributes], $states);
28 10
            $defaultAttributes = [];
29
        }
30
31
        try {
32 611
            $factory = self::isBooted() ? self::configuration()->factories()->create(static::class) : new static();
33 16
        } catch (\ArgumentCountError $e) {
34 10
            throw new \RuntimeException('Model Factories with dependencies (Model Factory services) cannot be created before foundry is booted.', 0, $e);
35
        }
36
37
        $factory = $factory
38 604
            ->withAttributes([$factory, 'getDefaults'])
39 604
            ->withAttributes($defaultAttributes)
40 604
            ->initialize()
41
        ;
42
43 604
        if (!$factory instanceof static) {
0 ignored issues
show
introduced by
$factory is always a sub-type of static.
Loading history...
44 20
            throw new \TypeError(\sprintf('"%1$s::initialize()" must return an instance of "%1$s".', static::class));
45
        }
46
47 600
        foreach ($states as $state) {
48 10
            $factory = $factory->{$state}();
49
        }
50
51 600
        return $factory;
52
    }
53
54
    /**
55
     * Try and find existing object for the given $attributes. If not found,
56
     * instantiate and persist.
57
     *
58
     * @return Proxy|object
59
     *
60
     * @psalm-return Proxy<TModel>
61
     */
62 10
    final public static function findOrCreate(array $attributes): Proxy
63
    {
64 10
        if ($found = static::repository()->find($attributes)) {
65 10
            return \is_array($found) ? $found[0] : $found;
0 ignored issues
show
introduced by
The condition is_array($found) is always false.
Loading history...
66
        }
67
68 10
        return static::new()->create($attributes);
69
    }
70
71
    /**
72
     * @see RepositoryProxy::random()
73
     */
74 20
    final public static function random(): Proxy
75
    {
76 20
        return static::repository()->random();
77
    }
78
79
    /**
80
     * @see RepositoryProxy::randomSet()
81
     */
82 10
    final public static function randomSet(int $number): array
83
    {
84 10
        return static::repository()->randomSet($number);
85
    }
86
87
    /**
88
     * @see RepositoryProxy::randomRange()
89
     */
90 10
    final public static function randomRange(int $min, int $max): array
91
    {
92 10
        return static::repository()->randomRange($min, $max);
93
    }
94
95
    /** @psalm-return RepositoryProxy<TModel> */
96 210
    final public static function repository(): RepositoryProxy
97
    {
98 210
        return static::configuration()->repositoryFor(static::getClass());
99
    }
100
101
    /**
102
     * Override to add default instantiator and default afterInstantiate/afterPersist events.
103
     *
104
     * @return static
105
     */
106 600
    protected function initialize()
107
    {
108 600
        return $this;
109
    }
110
111
    /**
112
     * @param array|callable $attributes
113
     *
114
     * @return static
115
     */
116 30
    final protected function addState($attributes = []): self
117
    {
118 30
        return $this->withAttributes($attributes);
119
    }
120
121
    /** @psalm-return class-string<TModel> */
122
    abstract protected static function getClass(): string;
123
124
    abstract protected function getDefaults(): array;
125
}
126