Stratadox /
TableLoader
| 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:
. |-- OtherDir | |-- Bar.php | `-- Foo.php `-- SomeDir `-- Foo.phpand let?s assume the following content of
Bar.php:If both files
OtherDir/Foo.phpandSomeDir/Foo.phpare 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.phpHowever, as
OtherDir/Foo.phpdoes 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: