1: <?php
2:
3: namespace PHPixie\ORM\Relationships\Type\OneTo\Type\Many;
4:
5: class Handler extends \PHPixie\ORM\Relationships\Type\OneTo\Handler
6: {
7: public function loadOwnerProperty($side, $item)
8: {
9: $owner = parent::loadSingleProperty($side, $item);
10: if($owner === null) {
11: $this->removeItemOwner($side->config(), $item);
12:
13: }else {
14: $this->addOwnerItems($side->config(), $owner, $item);
15: }
16: }
17:
18: public function loadItemsProperty($side, $owner)
19: {
20: $config = $side->config();
21: $preloadValue = $this->relationship->ownerPreloadValue($config->itemOwnerProperty, $owner);
22:
23: $loader = $this->query($side, $owner)->find(array(
24: $preloadValue
25: ));
26:
27: $loader = $this->loaders->editableProxy($loader);
28: $property = $owner->getRelationshipProperty($config->ownerProperty());
29: $property->setValue($loader);
30: }
31:
32: public function mapPreload($side, $preloadProperty, $reusableResult, $plan)
33: {
34: if($preloadProperty instanceof Value\Preload\Owner) {
35: $owner = $preloadProperty->owner();
36: return $this->relationship->ownerPropertyPreloader($owner);
37: }
38:
39: return parent::mapPreload($side, $preloadProperty, $reusableResult, $plan);
40: }
41:
42: public function addOwnerItems($config, $owner, $items)
43: {
44: $this->processOwner('add', $config, $owner, $items);
45: $this->processItems('set', $config, $items, $owner);
46: }
47:
48: public function removeOwnerItems($config, $owner, $items)
49: {
50: $this->processOwner('remove', $config, $owner, $items);
51: $this->processItems('remove', $config, $items);
52: }
53:
54: public function removeItemOwner($config, $item)
55: {
56: $this->processItems('remove', $config, $item);
57: }
58:
59: public function removeAllOwnerItems($config, $owner)
60: {
61: $property = $this->getLoadedProperty($owner, $config->ownerProperty());
62: if($property === null)
63: return;
64:
65: $loader = $property->value();
66: $items = $loader->accessedEntities();
67:
68: $loader->removeAll();
69: $this->processItems('remove', $config, $items, null, false);
70: }
71:
72: public function resetProperties($side, $items)
73: {
74: $config = $side->config();
75:
76: if($side->type() === 'owner') {
77: $this->resetOwnerProperties($config, $items);
78: }else{
79: $this->processItems('reset', $config, $items);
80: }
81: }
82:
83: protected function resetOwnerProperties ($config, $owners)
84: {
85: if(!is_array($owners))
86: $owners = array($owners);
87:
88: foreach($owners as $owner) {
89: $this->processOwner('reset', $config, $owner);
90:
91: }
92:
93: }
94:
95: protected function processItems($action, $config, $items, $owner = null, $processOldOwner = true)
96: {
97: if(!is_array($items))
98: $items = array($items);
99:
100: if($action == 'set' && !$this->isEntityValue($owner))
101: $action = 'reset';
102:
103: foreach($items as $item) {
104: if(!$this->isEntityValue($item))
105: continue;
106:
107: $property = $item->getRelationshipProperty($config->itemOwnerProperty, $action !== 'reset');
108:
109: if($property === null)
110: continue;
111:
112: if($processOldOwner && $property->isLoaded()) {
113: $oldOwner = $property->value();
114: if($oldOwner !==null ) {
115:
116: if( !($action === 'set' && $owner->id() === $oldOwner->id()) )
117: $this->processOwner('remove', $config, $oldOwner, $item);
118: }
119: }
120:
121: if($action === 'reset') {
122: $property->reset();
123:
124: }elseif($action === 'set') {
125: $property->setValue($owner);
126:
127: }else{
128: $property->setValue(null);
129:
130: }
131: }
132: }
133:
134: protected function processOwner($action, $config, $owner, $items = array())
135: {
136: if(!is_array($items))
137: $items = array($items);
138:
139:
140: if(!($owner instanceof \PHPixie\ORM\Models\Type\Database\Entity))
141: return;
142:
143:
144: $property = $this->getLoadedProperty($owner, $config->ownerProperty());
145:
146: if($property === null)
147: return;
148:
149: foreach($items as $item) {
150: if(!($item instanceof \PHPixie\ORM\Models\Type\Database\Entity)) {
151: $action = 'reset';
152: break;
153: }
154: }
155:
156: $loader = $property->value();
157:
158: if($action === 'reset') {
159: $property->reset();
160:
161: }elseif($action === 'add') {
162: $loader->add($items);
163:
164: }else{
165: $loader->remove($items);
166:
167: }
168:
169: }
170:
171: public function unlinkPlan($config, $owners, $items)
172: {
173: return $this->getUnlinkPlan($config, true, $owners, true, $items);
174: }
175:
176: public function unlinkItemsPlan($config, $items)
177: {
178: return $this->getUnlinkPlan($config, false, null, true, $items);
179: }
180:
181: public function unlinkOwnersPlan($config, $owners)
182: {
183: return $this->getUnlinkPlan($config, true, $owners, false, null);
184: }
185:
186: }
187: