Passed
Push — master ( c9b77f...b81667 )
by Jesse
02:08
created

Objects::addToMapIfNew()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 4
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\TableLoader;
5
6
use function is_null;
7
use Stratadox\Hydrator\CannotHydrate;
8
use Stratadox\Hydrator\Hydrates;
9
use Stratadox\IdentityMap\AlreadyThere;
10
use Stratadox\IdentityMap\MapsObjectsByIdentity as Map;
11
use Throwable;
12
13
/**
14
 * Makes partially hydrated objects from an input array.
15
 *
16
 * @author Stratadox
17
 */
18
final class Objects implements MakesObjects
19
{
20
    private $hydrate;
21
    private $relevantData;
22
    private $identifier;
23
24
    private function __construct(
25
        Hydrates $theObjects,
26
        FiltersTheArray $toTheRelevantDataOnly,
27
        IdentifiesEntities $forIndexation
28
    ) {
29
        $this->hydrate = $theObjects;
30
        $this->relevantData = $toTheRelevantDataOnly;
31
        $this->identifier = $forIndexation;
32
    }
33
34
    /**
35
     * Makes a new object extractor that produces partially hydrated objects.
36
     *
37
     * @param Hydrates           $theObjects            Hydrator for the objects.
38
     * @param FiltersTheArray    $toTheRelevantDataOnly The filter for the input
39
     *                                                  array.
40
     * @param IdentifiesEntities $forIndexation         The row identification
41
     *                                                  mechanism.
42
     * @return MakesObjects                             The object extractor.
43
     */
44
    public static function producedByThis(
45
        Hydrates $theObjects,
46
        FiltersTheArray $toTheRelevantDataOnly,
47
        IdentifiesEntities $forIndexation
48
    ): MakesObjects {
49
        return new self($theObjects, $toTheRelevantDataOnly, $forIndexation);
50
    }
51
52
    /** @inheritdoc */
53
    public function from(array $input, Map $map): ContainsResultingObjects {
54
        $data = $this->relevantData->only($input);
55
        $label = $this->relevantData->label();
56
        $objects = [];
57
        foreach ($data as $row) {
58
            if ($this->identifier->isNullFor($row)) {
59
                continue;
60
            }
61
            $hash = $this->identifier->forLoading($row);
62
            if (isset($objects[$hash])) {
63
                continue;
64
            }
65
            try {
66
                $class = $this->hydrate->classFor($row);
67
                $id = $this->identifier->forIdentityMap($row);
68
                if ($map->has($class, $id)) {
69
                    $object = $map->get($class, $id);
70
                } else {
71
                    $object = $this->hydrate->fromArray($row);
72
                    $map = $map->add($id, $object);
73
                }
74
                $objects[$hash] = $object;
75
            } catch (Throwable $exception) {
76
                throw UnmappableRow::encountered($exception, $label, $row);
77
            }
78
        }
79
        return Result::fromArray([$label => $objects], $map);
80
    }
81
}
82