1: <?php declare(strict_types=1);
2:
3: namespace Salient\Core\Concern;
4:
5: use Salient\Container\RequiresContainer;
6: use Salient\Contract\Container\ContainerInterface;
7: use Salient\Contract\Core\Entity\Constructible;
8: use Salient\Contract\Core\Entity\Treeable;
9: use Salient\Core\Legacy\Introspector;
10: use Salient\Utility\Exception\InvalidArgumentTypeException;
11: use Generator;
12:
13: /**
14: * @api
15: *
16: * @phpstan-require-implements Constructible
17: */
18: trait ConstructibleTrait
19: {
20: use RequiresContainer;
21:
22: /**
23: * @inheritDoc
24: */
25: public static function construct(
26: array $data,
27: ?object $parent = null,
28: ?ContainerInterface $container = null
29: ) {
30: if ($parent && !$parent instanceof Treeable) {
31: throw new InvalidArgumentTypeException(2, 'parent', Treeable::class, $parent);
32: }
33:
34: $container = self::requireContainer($container);
35:
36: return Introspector::getService($container, static::class)
37: ->getCreateFromClosure(true)($data, $container, null, $parent);
38: }
39:
40: /**
41: * @inheritDoc
42: */
43: public static function constructMultiple(
44: iterable $data,
45: int $conformity = Constructible::CONFORMITY_NONE,
46: ?object $parent = null,
47: ?ContainerInterface $container = null
48: ): Generator {
49: if ($parent && !$parent instanceof Treeable) {
50: throw new InvalidArgumentTypeException(3, 'parent', Treeable::class, $parent);
51: }
52:
53: $container = self::requireContainer($container);
54: $introspector = Introspector::getService($container, static::class);
55:
56: foreach ($data as $key => $data) {
57: /** @disregard P1012 */
58: $closure ??= $conformity === self::CONFORMITY_PARTIAL || $conformity === self::CONFORMITY_COMPLETE
59: ? $introspector->getCreateFromSignatureClosure(array_keys($data), true)
60: : $introspector->getCreateFromClosure(true);
61:
62: yield $key => $closure($data, $container, null, $parent);
63: }
64: }
65: }
66: