02855fd279a678c5a76ebe536991a4c76d20f3c7
[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 /**
16 * Create a child rows mapping
17 * @param Mapper $mapper
18 * @param string $property
19 */
20 function __construct(Mapper $mapper, $property) {
21 $this->mapper = $mapper;
22 $this->property = $property;
23 }
24
25 /**
26 * Read the child objects
27 * @param Row $row
28 * @param object $objectToUpdate
29 */
30 function read(Row $row, $objectToUpdate) {
31 $val = $this->extract($objectToUpdate);
32 if (!isset($val)) {
33 $map = $this->mapper->mapOf($this->refClass);
34 $all = $map->allOf($row, $this->refName, $objects);
35 $this->assign($objectToUpdate, $objects);
36 $map->mapAll($all);
37 }
38 }
39
40 /**
41 * Write the child rows
42 * @param object $object
43 * @param Row $rowToUpdate
44 * @return callable deferred callback
45 */
46 function write($object, Row $rowToUpdate) {
47 if (($refs = $this->extract($object))) {
48 $property = $this->findRefProperty($object);
49 foreach ($refs as $ref) {
50 $property->assign($ref, $object);
51 }
52 return function() use($refs) {
53 $map = $this->mapper->mapOf($this->refClass);
54 foreach ($refs as $ref) {
55 $map->unmap($ref);
56 }
57 };
58 }
59 }
60
61 /**
62 * Find the referring property that references $object on our foreign key
63 * @param object $object
64 * @return RefPropertyInterface[]
65 * @throws UnexpectedValueException
66 */
67 private function findRefProperty($object) {
68 $map = $this->mapper->mapOf($this->refClass);
69 $property = array_filter($map->getProperties(), function($property) use($object) {
70 if ($property instanceof RefPropertyInterface) {
71 return $property->references($object) && $property->on($this->refName);
72 }
73 });
74
75 if (1 != count($property)) {
76 // FIXME: move the decl
77 throw new UnexpectedValueException(
78 sprintf("%s does not reference %s exactly once through %s",
79 $this->refClass, $this->container->getClass(), $this->refName));
80 }
81 return current($property);
82 }
83 }