data mapper POC
[m6w6/pq-gateway] / lib / pq / Mapper / Property / All.php
1 <?php
2
3 namespace pq\Mapper\Property;
4
5 use pq\Gateway\Row;
6 use pq\Mapper\Mapper;
7 use pq\Mapper\RefProperty;
8 use pq\Mapper\RefPropertyInterface;
9 use UnexpectedValueException;
10
11 class All implements RefPropertyInterface
12 {
13 use RefProperty;
14
15 function __construct(Mapper $mapper, $property) {
16 $this->mapper = $mapper;
17 $this->property = $property;
18 }
19
20 function read(Row $row, $objectToUpdate) {
21 $val = $this->extract($objectToUpdate);
22 if (!isset($val)) {
23 $map = $this->mapper->mapOf($this->refClass);
24 $all = $map->allOf($row, $this->refName, $objects);
25 $this->assign($objectToUpdate, $objects);
26 $map->mapAll($all);
27 }
28 }
29
30 function write($object, Row $rowToUpdate) {
31 $property = $this->findRefProperty($object);
32 $map = $this->mapper->mapOf($this->refClass);
33 $refs = $this->extract($object);
34 foreach ($refs as $ref) {
35 $property->assign($ref, $object);
36 }
37 return function() use($map, $refs) {
38 foreach ($refs as $ref) {
39 $map->unmap($ref);
40 }
41 };
42
43 if (!$this->container->getObjects()->rowId($rowToUpdate, true)) {
44 return [$this, "write"];
45 } else {
46 /* $object = User */
47 /* $refs = array(Email) */
48 /* $property = Property\Ref(Email::$user)->to(User)->by("email_user") */
49 /* now update array(Email) with id of User, i.e. $ref->user_id = $object->id */
50 $map = $this->mapper->mapOf($this->refClass);
51 $refs = $this->extract($object);
52 foreach ($refs as $ref) {
53 $property->assign($ref, $object);
54 $map->unmap($ref);
55 }
56 }
57 }
58
59 private function findRefProperty($object) {
60 $map = $this->mapper->mapOf($this->refClass);
61 $property = array_filter($map->getProperties(), function($property) use($object) {
62 if ($property instanceof RefPropertyInterface) {
63 return $property->references($object) && $property->on($this->refName);
64 }
65 });
66
67 if (1 != count($property)) {
68 // FIXME: move the decl
69 throw new UnexpectedValueException(
70 sprintf("%s does not reference %s exactly once through %s",
71 $this->refClass, $this->container->getClass(), $this->refName));
72 }
73 return current($property);
74 }
75
76 function read2(RowGateway $row) {
77 #echo __METHOD__." ".$this;
78 $ref = $this->getRefMap()->ref($row, $this->refName);
79 $value = $this->mapper->map($ref, $this->refClass);
80 return [$this->property => $value];
81 }
82
83 function write2($object) {
84 #echo __METHOD__." ".$this;
85 $value = $this->extract($object);
86 foreach ($value as $ref) {
87 $this->mapper->queue(function() use(&$object, &$ref) {
88 $map = $this->getRefMap()->getRefMapping($this->refName);
89 $map->assign($ref, $object);
90 $this->mapper->unmap($ref, $this->getRefMap());
91 });
92 }
93 return [];
94 }
95 }