Passed
Pull Request — master (#1)
by Kevin
02:03
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
use Doctrine\Persistence\ObjectRepository;
6
7
/**
8
 * @author Kevin Bond <[email protected]>
9
 */
10
abstract class ModelFactory extends Factory
11
{
12 74
    private function __construct()
13
    {
14 74
        parent::__construct(static::getClass());
15 74
    }
16
17
    /**
18
     * @param array|callable|string $defaultAttributes If string, assumes state
19
     * @param string                ...$states         Optionally pass default states (these must be methods on your ObjectFactory with no arguments)
20
     */
21 74
    final public static function new($defaultAttributes = [], string ...$states): self
22
    {
23
        // todo - is this too magical?
24 74
        if (\is_string($defaultAttributes)) {
25 2
            $states = \array_merge([$defaultAttributes], $states);
26 2
            $defaultAttributes = [];
27
        }
28
29 74
        $factory = new static();
30
        $factory = $factory
31 74
            ->withAttributes([$factory, 'getDefaults'])
32 74
            ->withAttributes($defaultAttributes)
33 74
            ->initialize()
34
        ;
35
36 74
        if (!$factory instanceof static) {
0 ignored issues
show
introduced by
$factory is always a sub-type of static.
Loading history...
37 4
            throw new \TypeError(\sprintf('"%1$s::initialize()" must return an instance of "%1$s".', static::class));
38
        }
39
40 74
        foreach ($states as $state) {
41 2
            $factory = $factory->{$state}();
42
        }
43
44 74
        return $factory;
45
    }
46
47
    /**
48
     * Try and find existing object for the given $attributes. If not found,
49
     * instantiate and persist.
50
     *
51
     * @return Proxy|object
52
     */
53 2
    final public static function findOrCreate(array $attributes): object
54
    {
55 2
        if ($found = self::repository(true)->find($attributes)) {
56 2
            return $found;
57
        }
58
59 2
        return self::new()->create($attributes);
60
    }
61
62
    /**
63
     * Get a random persisted object.
64
     *
65
     * @return Proxy|object
66
     */
67
    final public static function random(): object
68
    {
69
        return self::repository(true)->random();
70
    }
71
72
    /**
73
     * @param int      $min The minimum number of objects to return (if max is null, will always return this amount)
74
     * @param int|null $max The max number of objects to return
75
     *
76
     * @return Proxy[]|object[]
77
     */
78
    final public static function randomSet(int $min, ?int $max = null): array
79
    {
80
        return self::repository(true)->randomSet($min, $max);
81
    }
82
83
    /**
84
     * @return RepositoryProxy|ObjectRepository
85
     */
86 10
    final public static function repository(bool $proxy = true): ObjectRepository
87
    {
88 10
        return PersistenceManager::repositoryFor(static::getClass(), $proxy);
89
    }
90
91
    /**
92
     * Override to add default instantiator and default afterInstantiate/afterPersist events.
93
     *
94
     * @return static
95
     */
96 74
    protected function initialize()
97
    {
98 74
        return $this;
99
    }
100
101
    /**
102
     * @param array|callable $attributes
103
     */
104 6
    final protected function addState($attributes = []): self
105
    {
106 6
        return $this->withAttributes($attributes);
107
    }
108
109
    abstract protected static function getClass(): string;
110
111
    abstract protected function getDefaults(): array;
112
}
113