Passed
Pull Request — master (#127)
by Wouter
02:45
created

without_autorefresh()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 7
nop 2
dl 0
loc 22
ccs 0
cts 0
cp 0
crap 30
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace Zenstruck\Foundry;
4
5
use Faker;
6
use ProxyManager\Proxy\ValueHolderInterface;
7
8
/**
9
 * @see Factory::__construct()
10
 *
11
 * @template TObject as object
12
 * @psalm-param class-string<TObject> $class
13
 * @psalm-return AnonymousFactory<TObject>
14
 */
15
function factory(string $class, $defaultAttributes = []): AnonymousFactory
16 110
{
17
    return new AnonymousFactory($class, $defaultAttributes);
18
}
19
20
/**
21
 * @see Factory::create()
22
 *
23
 * @return Proxy|object
24
 *
25
 * @template TObject of object
26
 * @psalm-param class-string<TObject> $class
27
 * @psalm-return Proxy<TObject>
28
 */
29
function create(string $class, $attributes = []): Proxy
30 50
{
31
    return factory($class)->create($attributes);
32
}
33
34
/**
35
 * @see Factory::createMany()
36
 *
37
 * @return Proxy[]|object[]
38
 *
39
 * @template TObject of object
40
 * @psalm-param class-string<TObject> $class
41
 * @psalm-return list<Proxy<TObject>>
42
 */
43
function create_many(int $number, string $class, $attributes = []): array
44 10
{
45
    return factory($class)->many($number)->create($attributes);
46
}
47
48
/**
49
 * Instantiate object without persisting.
50
 *
51
 * @return Proxy|object "unpersisted" Proxy wrapping the instantiated object
52
 *
53
 * @template TObject of object
54
 * @psalm-param class-string<TObject> $class
55
 * @psalm-return Proxy<TObject>
56
 */
57
function instantiate(string $class, $attributes = []): Proxy
58 10
{
59
    return factory($class)->withoutPersisting()->create($attributes);
60
}
61
62
/**
63
 * Instantiate X objects without persisting.
64
 *
65
 * @return Proxy[]|object[] "unpersisted" Proxy's wrapping the instantiated objects
66
 *
67
 * @template TObject of object
68
 * @psalm-param class-string<TObject> $class
69
 * @psalm-return list<Proxy<TObject>>
70
 */
71
function instantiate_many(int $number, string $class, $attributes = []): array
72 10
{
73
    return factory($class)->withoutPersisting()->many($number)->create($attributes);
74
}
75
76
/**
77
 * @see Configuration::repositoryFor()
78
 */
79
function repository($objectOrClass): RepositoryProxy
80 140
{
81
    return Factory::configuration()->repositoryFor($objectOrClass);
82
}
83
84
/**
85
 * @see Factory::faker()
86
 */
87
function faker(): Faker\Generator
88 10
{
89
    return Factory::faker();
90
}
91
92
/**
93
 * Enables autorefresh on the model.
94
 *
95
 * @param Proxy|ValueHolderInterface $model
96
 */
97
function enable_autorefresh(object $model): void
98
{
99
    if ($model instanceof Proxy) {
100
        $model->enableAutoRefresh();
101
102
        return;
103
    }
104
105
    if ($model instanceof ValueHolderInterface) {
106
        $realModel = $model->getWrappedValueHolderValue();
107
        if (!$realModel) {
108
            return;
109
        }
110
111
        $realModel->_foundry_autoRefresh = true;
112
    }
113
}
114
115
/**
116
 * Disables autorefresh on the model.
117
 *
118
 * @param Proxy|ValueHolderInterface $model
119
 */
120
function disable_autorefresh(object $model): void
121
{
122
    if ($model instanceof Proxy) {
123
        $model->disableAutoRefresh();
124
125
        return;
126
    }
127
128
    if ($model instanceof ValueHolderInterface) {
129
        $realModel = $model->getWrappedValueHolderValue();
130
        if (!$realModel) {
131
            return;
132
        }
133
134
        $realModel->_foundry_autoRefresh = false;
135
    }
136
}
137
138
/**
139
 * Ensures "autoRefresh" is disabled when executing $callback. Re-enables
140
 * "autoRefresh" after executing callback if it was enabled.
141
 *
142
 * @param Proxy|ValueHolderInterface $model
143
 * @param callable                   $callback (Proxy|ValueHolderInterface $model): void
144
 *
145
 * @template TModel as Proxy|ValueHolderInterface
146
 * @psalm-param TModel $model
147
 * @psalm-param callable(TModel):void $callback
148
 */
149
function without_autorefresh(object $model, callable $callback): void
150
{
151
    if ($model instanceof Proxy) {
152
        $model->withoutAutoRefresh($callback);
153
154
        return;
155
    }
156
157
    $originalValue = null;
158
    if ($model instanceof ValueHolderInterface) {
159
        $realModel = get_real_object($model);
160
161
        /** @psalm-suppress NoInterfaceProperties */
162
        $originalValue = \property_exists($realModel, '_foundry_autoRefresh') ? $realModel->_foundry_autoRefresh : true;
163
        /** @psalm-suppress NoInterfaceProperties */
164
        $realModel->_foundry_autoRefresh = false;
165
    }
166
167
    ($callback)($model);
168
169
    if (null !== $originalValue) {
170
        $realModel->_foundry_autoRefresh = $originalValue;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $realModel does not seem to be defined for all execution paths leading up to this point.
Loading history...
171
    }
172
}
173
174
function force_set(object $model, string $property, $value): void
175
{
176
    force_set_all($model, [$property => $value]);
177
}
178
179
function force_set_all(object $model, array $properties): void
180
{
181
    foreach ($properties as $property => $value) {
182
        Instantiator::forceSet(get_real_object($model), $property, $value);
183
    }
184
}
185
186
/**
187
 * @return mixed
188
 */
189
function force_get(object $model, string $property)
190
{
191
    return Instantiator::forceGet(get_real_object($model), $property);
192
}
193
194
/**
195
 * @template T of object
196
 * @psalm-param T|Proxy<T>|ValueHolderInterface<T> $proxyObject
197
 * @psalm-return T
198
 *
199
 * @psalm-suppress InvalidReturnType
200
 * @psalm-suppress InvalidReturnStatement
201
 */
202
function get_real_object(object $proxyObject): object
203
{
204
    if ($proxyObject instanceof Proxy) {
205
        return $proxyObject->object();
206
    }
207
208
    if ($proxyObject instanceof ValueHolderInterface && $valueHolder = $proxyObject->getWrappedValueHolderValue()) {
209
        return $valueHolder;
210
    }
211
212
    return $proxyObject;
213
}
214