phpdoc
[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 $property = $this->findRefProperty($object);
48 $map = $this->mapper->mapOf($this->refClass);
49 $refs = $this->extract($object);
50 foreach ($refs as $ref) {
51 $property->assign($ref, $object);
52 }
53 return function() use($map, $refs) {
54 foreach ($refs as $ref) {
55 $map->unmap($ref);
56 }
57 };
58 }
59
60 /**
61 * Find the referring property that references $object on our foreign key
62 * @param object $object
63 * @return RefPropertyInterface[]
64 * @throws UnexpectedValueException
65 */
66 private function findRefProperty($object) {
67 $map = $this->mapper->mapOf($this->refClass);
68 $property = array_filter($map->getProperties(), function($property) use($object) {
69 if ($property instanceof RefPropertyInterface) {
70 return $property->references($object) && $property->on($this->refName);
71 }
72 });
73
74 if (1 != count($property)) {
75 // FIXME: move the decl
76 throw new UnexpectedValueException(
77 sprintf("%s does not reference %s exactly once through %s",
78 $this->refClass, $this->container->getClass(), $this->refName));
79 }
80 return current($property);
81 }
82 }