|
6 | 6 | use Articulate\Concise\Contracts\EntityMapper; |
7 | 7 | use Articulate\Concise\Contracts\Mapper; |
8 | 8 | use Articulate\Concise\Contracts\Repository; |
| 9 | +use Closure; |
9 | 10 | use Illuminate\Database\RecordsNotFoundException; |
10 | 11 | use Illuminate\Foundation\Application; |
11 | 12 | use Illuminate\Support\Str; |
@@ -153,50 +154,49 @@ public function repository(string $class): Repository |
153 | 154 | * |
154 | 155 | * @template EntityObject of object |
155 | 156 | * |
156 | | - * @param class-string<EntityObject> $class |
157 | | - * @param string|int $identity |
158 | | - * @param array<string, mixed> $data |
| 157 | + * @param class-string<EntityObject> $class |
| 158 | + * @param string|int $identity |
| 159 | + * @param array<string, mixed> $data |
| 160 | + * @param (\Closure():EntityObject)|null $factory |
159 | 161 | * |
160 | | - * @return object|null |
| 162 | + * @return object |
161 | 163 | * |
162 | | - * @phpstan-return EntityObject|null |
| 164 | + * @phpstan-return EntityObject |
163 | 165 | * |
164 | 166 | * @throws \Illuminate\Contracts\Container\BindingResolutionException |
165 | 167 | */ |
166 | | - public function lazy(string $class, string|int $identity, array $data = []): ?object |
| 168 | + public function lazy(string $class, string|int $identity, array $data = [], ?Closure $factory = null): object |
167 | 169 | { |
168 | 170 | /** @var \Articulate\Concise\Contracts\EntityMapper<EntityObject>|null $mapper */ |
169 | 171 | $mapper = $this->entity($class); |
170 | 172 |
|
171 | 173 | if ($mapper === null) { |
172 | | - return null; |
| 174 | + throw new RuntimeException('No entity mapper registered for class [' . $class . ']'); |
173 | 175 | } |
174 | 176 |
|
175 | 177 | $repository = $this->repository($class); |
176 | 178 |
|
177 | 179 | try { |
178 | 180 | $reflector = new ReflectionClass($class); |
179 | | - $lazy = $reflector->newLazyProxy( |
180 | | - /** |
181 | | - * @phpstan-param EntityObject $proxy |
182 | | - */ |
183 | | - function (object $proxy) use ($repository, $identity, $mapper) { |
184 | | - /** @var EntityObject|null $entity */ |
185 | | - $entity = $repository->getOne(Criterion::forIdentifier($identity)); |
186 | | - |
187 | | - if ($entity === null) { |
188 | | - throw new RecordsNotFoundException('No results for entity [' . $mapper->class() . ']'); |
189 | | - } |
190 | | - |
191 | | - return $entity; |
| 181 | + |
| 182 | + $factory ??= static function (object $proxy) use ($repository, $identity, $mapper) { |
| 183 | + /** @var EntityObject|null $entity */ |
| 184 | + $entity = $repository->getOne(Criterion::forIdentifier($identity)); |
| 185 | + |
| 186 | + if ($entity === null) { |
| 187 | + throw new RecordsNotFoundException('No results for entity [' . $mapper->class() . ']'); |
192 | 188 | } |
193 | | - ); |
| 189 | + |
| 190 | + return $entity; |
| 191 | + }; |
| 192 | + |
| 193 | + $lazy = $reflector->newLazyProxy($factory); |
194 | 194 |
|
195 | 195 | $reflector->getProperty($mapper->identity())->setRawValueWithoutLazyInitialization($lazy, $identity); |
196 | 196 | } catch (Throwable $e) { |
197 | 197 | report($e); |
198 | 198 |
|
199 | | - return null; |
| 199 | + throw new RuntimeException('Unable to create lazy proxy for entity [' . $class . ']'); |
200 | 200 | } |
201 | 201 |
|
202 | 202 | foreach ($data as $property => $value) { |
|
0 commit comments