1 | <?php |
||
2 | declare(strict_types=1); |
||
3 | |||
4 | namespace Stratadox\TableLoader\Loader; |
||
5 | |||
6 | use Stratadox\Hydrator\Hydrates; |
||
7 | use Stratadox\IdentityMap\IdentityMap; |
||
8 | use Stratadox\IdentityMap\MapsObjectsByIdentity as Map; |
||
9 | use Stratadox\TableLoader\Loader\ContainsResultingObjects as Objects; |
||
0 ignored issues
–
show
|
|||
10 | use Throwable; |
||
11 | |||
12 | /** |
||
13 | * Converts a table into objects. |
||
14 | * |
||
15 | * @author Stratadox |
||
16 | */ |
||
17 | final class SimpleTable implements LoadsTables |
||
18 | { |
||
19 | private $label; |
||
20 | private $make; |
||
21 | private $identity; |
||
22 | |||
23 | private function __construct( |
||
24 | string $label, |
||
25 | Hydrates $hydrator, |
||
26 | IdentifiesEntities $identity |
||
27 | ) { |
||
28 | $this->label = $label; |
||
29 | $this->make = $hydrator; |
||
30 | $this->identity = $identity; |
||
31 | } |
||
32 | |||
33 | /** |
||
34 | * Makes a new simple table converter. |
||
35 | * |
||
36 | * @param string $label The label to apply. |
||
37 | * @param Hydrates $hydrator The hydrator to produces the objects. |
||
38 | * @param IdentifiesEntities $identity The row identification mechanism. |
||
39 | * @return LoadsTables The simple table converter. |
||
40 | */ |
||
41 | public static function converter( |
||
42 | string $label, |
||
43 | Hydrates $hydrator, |
||
44 | IdentifiesEntities $identity |
||
45 | ): LoadsTables { |
||
46 | return new self($label, $hydrator, $identity); |
||
47 | } |
||
48 | |||
49 | /** @inheritdoc */ |
||
50 | public function from(array $input, Map $map = null): Objects |
||
51 | { |
||
52 | $result = Result::fromArray([], $map ?: IdentityMap::startEmpty()); |
||
53 | foreach ($input as $row) { |
||
54 | try { |
||
55 | $result = $this->loadInto($result, $row); |
||
56 | } catch (Throwable $exception) { |
||
57 | throw UnmappableRow::encountered($exception, $this->label, $row); |
||
58 | } |
||
59 | } |
||
60 | return $result; |
||
61 | } |
||
62 | |||
63 | /** @throws Throwable */ |
||
64 | private function loadInto(Objects $result, array $row): Objects |
||
65 | { |
||
66 | $class = $this->make->classFor($row); |
||
67 | $id = $this->identity->forIdentityMap($row); |
||
68 | if ($result->has($class, $id)) { |
||
69 | return $result->include($this->label, $id, $result->get($class, $id)); |
||
70 | } |
||
71 | return $result->add( |
||
72 | $this->label, |
||
73 | $this->identity->forLoading($row), |
||
74 | $id, |
||
75 | $this->make->fromArray($row) |
||
76 | ); |
||
77 | } |
||
78 | } |
||
79 |
Let?s assume that you have a directory layout like this:
and let?s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: