1
|
|
|
<?php |
2
|
|
|
namespace Maphper\Relation; |
3
|
|
|
class One implements \Maphper\Relation { |
4
|
|
|
private $mapper; |
5
|
|
|
private $parentField; |
6
|
|
|
private $localField; |
7
|
|
|
private $parentObject; |
8
|
|
|
private $data; |
9
|
|
|
private $siblings = []; |
10
|
|
|
|
11
|
|
|
public function __construct(\Maphper\Maphper $mapper, $parentField, $localField, array $criteria = []) { |
12
|
|
|
if ($criteria) $mapper = $mapper->filter($this->criteira); |
|
|
|
|
13
|
|
|
$this->mapper = $mapper; |
14
|
|
|
$this->parentField = $parentField; |
15
|
|
|
$this->localField = $localField; |
16
|
|
|
} |
17
|
|
|
|
18
|
|
|
public function getData($parentObject, &$siblings = null) { |
19
|
|
|
//Don't actually fetch the related data, return an instance of $this that will lazy load data when __get is called |
20
|
|
|
$clone = clone $this; |
21
|
|
|
$clone->parentObject = $parentObject; |
22
|
|
|
$siblings[] = $clone; |
23
|
|
|
$clone->siblings = $siblings; |
24
|
|
|
|
25
|
|
|
// var_dump($siblings); |
26
|
|
|
return $clone; |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
private function lazyLoad() { |
30
|
|
|
if (!isset($this->data)) { |
31
|
|
|
|
32
|
|
|
if ($this->parentObject == null) throw new \Exception('Error, no object set'); |
33
|
|
|
|
34
|
|
|
$this->eagerLoad(); |
35
|
|
|
|
36
|
|
|
} |
37
|
|
|
return $this->data; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
private function eagerLoad() { |
41
|
|
|
$recordsToLoad = []; |
42
|
|
|
//Get a list of records by FK to eager load |
43
|
|
|
foreach ($this->siblings as $sibling) { |
44
|
|
|
$recordsToLoad[] = $sibling->parentObject->{$sibling->parentField}; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
$recordsToLoad = array_unique($recordsToLoad); |
48
|
|
|
//Fetch the results so they're in the cache for the corresponding maphper object |
49
|
|
|
$results = $this->mapper->filter([$this->localField => $recordsToLoad]); |
|
|
|
|
50
|
|
|
|
51
|
|
|
$this->loadDataIntoSiblings($results); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
private function loadDataIntoSiblings($results) { |
55
|
|
|
$cache = []; |
56
|
|
|
foreach ($results as $result) { |
57
|
|
|
$cache[$result->{$this->localField}] = $result; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
foreach ($this->siblings as $sibling) { |
61
|
|
|
$sibling->data = $cache[$sibling->parentObject->{$this->parentField}]; |
62
|
|
|
} |
63
|
|
|
/* |
64
|
|
|
foreach ($this->siblings as $sibling) { |
65
|
|
|
if ($sibling->criteria) $sibling->data = $sibling->mapper->filter($sibling->criteria)->filter([$sibling->localField => $sibling->parentObject->{$sibling->parentField}])->item(0); |
66
|
|
|
else $sibling->data = $sibling->mapper->filter([$sibling->localField => $sibling->parentObject->{$this->parentField}])->item(0); |
67
|
|
|
} |
68
|
|
|
*/ |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
public function __call($func, array $args = []) { |
72
|
|
|
if ($this->lazyLoad() == null) return ''; |
73
|
|
|
return call_user_func_array([$this->lazyLoad(), $func], $args); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
public function __get($name) { |
77
|
|
|
if ($this->lazyLoad()) return $this->lazyLoad()->$name; |
78
|
|
|
else return null; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
public function __isset($name) { |
82
|
|
|
return isset($this->lazyLoad()->$name); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function overwrite($parentObject, &$data) { |
86
|
|
|
$this->mapper[] = $data; |
87
|
|
|
if (!isset($parentObject->{$this->parentField}) || $parentObject->{$this->parentField} != $data->{$this->localField}) { |
88
|
|
|
$parentObject->{$this->parentField} = $data->{$this->localField}; |
89
|
|
|
//Trigger an update of the parent object |
90
|
|
|
return true; |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
public function getFilter($object) { |
95
|
|
|
return [$this->parentField => $object->{$this->localField}]; |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.