1: <?php
2:
3: namespace PHPixie\ORM\Relationships\Type\Embeds\Type\Many;
4:
5: class Handler extends \PHPixie\ORM\Relationships\Type\Embeds\Handler
6: {
7: protected function mapConditionBuilder($builder, $side, $collection, $plan)
8: {
9: $config = $side->config();
10: $builder->startConditionGroup($collection->logic(), $collection->isNegated());
11:
12: $builder->andNot($config->path, null);
13: $container = $builder->addSubarrayItemPlaceholder($config->path);
14:
15: $this->mappers->conditions()->map(
16: $container,
17: $config->itemModel,
18: $collection->conditions(),
19: $plan
20: );
21:
22: $builder->endGroup();
23: }
24:
25: public function offsetSet($entity, $config, $offset, $item)
26: {
27: $this->assertModelName($item, $config->itemModel);
28: $this->removeItemFromOwner($item);
29: $this->setItem($entity, $config, $offset, $item);
30: }
31:
32: public function offsetUnset($entity, $config, $offset){
33: $this->unsetItems($entity, $config, array($offset));
34: }
35:
36: public function offsetCreate($entity, $config, $offset, $data){
37: $embeddedModel = $this->models->embedded();
38: $item = $embeddedModel->loadEntityFromData($config->itemModel, $data);
39: $this->setItem($entity, $config, $offset, $item);
40: return $item;
41: }
42:
43: public function removeItems($entity, $config, $items) {
44: if(!is_array($items)) {
45: $items = array($items);
46: }
47: $property = $entity->getRelationshipProperty($config->ownerItemsProperty);
48: $arrayNodeLoader = $property->value();
49: $cachedItems = $arrayNodeLoader->getCachedEntities();
50:
51: $offsets = array();
52: foreach($items as $item) {
53: $this->assertModelName($item, $config->itemModel);
54: $offset = array_search($item, $cachedItems, true);
55: if($offset === false)
56: throw new \PHPixie\ORM\Exception\Relationship("Item specified for removal was not found on the model");
57: $offsets[]=$offset;
58: }
59:
60: $this->unsetItems($entity, $config, $offsets);
61: }
62:
63:
64: protected function setItem($entity, $config, $offset, $item)
65: {
66: $property = $entity->getRelationshipProperty($config->ownerItemsProperty);
67: $arrayNodeLoader = $property->value();
68:
69: $count = $arrayNodeLoader->count();
70:
71: if($offset === null) {
72: $offset = $count;
73: }elseif($offset > $count) {
74: throw new \PHPixie\ORM\Exception\Relationship("There may be no gaps in items array. Key $offset is larger than item count $count");
75: }
76:
77: if($offset < $count) {
78: $this->unsetCachedItemOwner($arrayNodeLoader, $offset);
79: }
80:
81: $arrayNodeLoader->cacheEntity($offset, $item);
82:
83: $document = $item->data()->document();
84:
85: $arrayNode = $arrayNodeLoader->arrayNode();
86: $arrayNode->offsetSet($offset, $document);
87:
88: $item->setOwnerRelationship($entity, $config->ownerItemsProperty);
89: $this->checkArrayNode($entity, $config, $arrayNode);
90:
91: }
92:
93: protected function unsetItems($entity, $config, $offsets)
94: {
95: $property = $entity->getRelationshipProperty($config->ownerItemsProperty);
96: $arrayNodeLoader = $property->value();
97: $cachedEntities = $arrayNodeLoader->getCachedEntities();
98: $arrayNode = $arrayNodeLoader->arrayNode();
99:
100: sort($offsets, SORT_NUMERIC);
101:
102: foreach($offsets as $key => $offset) {
103:
104: $cachedEntities[$offset]->unsetOwnerRelationship();
105:
106: $adjustedOffset = $offset - $key;
107: $arrayNode->offsetUnset($adjustedOffset);
108: $arrayNodeLoader->shiftCachedEntities($adjustedOffset);
109: }
110:
111: $this->checkArrayNode($entity, $config, $arrayNode);
112: }
113:
114: public function removeAllItems($entity, $config) {
115: $property = $entity->getRelationshipProperty($config->ownerItemsProperty);
116: $arrayNodeLoader = $property->value();
117: $cachedEntities = $arrayNodeLoader->getCachedEntities();
118:
119: foreach($cachedEntities as $item) {
120: $item->unsetOwnerRelationship();
121: }
122:
123: $arrayNodeLoader->clearCachedEntities();
124: $arrayNode = $arrayNodeLoader->arrayNode();
125: $arrayNode->clear();
126: $this->checkArrayNode($entity, $config, $arrayNode);
127: }
128:
129: public function loadProperty($config, $entity)
130: {
131: $arrayNode = $this->checkArrayNode($entity, $config);
132:
133: $arrayNodeLoader = $this->loaders->arrayNode(
134: $config->itemModel,
135: $arrayNode,
136: $entity,
137: $config->ownerItemsProperty
138: );
139:
140: $property = $entity->getRelationshipProperty($config->ownerItemsProperty);
141: $property->setValue($arrayNodeLoader);
142: }
143:
144: protected function unsetCachedItemOwner($arrayNodeLoader, $offset)
145: {
146: $oldItem = $arrayNodeLoader->getCachedEntity($offset);
147: if($oldItem !== null) {
148: $oldItem->unsetOwnerRelationship();
149: }
150: }
151:
152: protected function checkArrayNode($entity, $config, $arrayNode = null)
153: {
154: $document = $entity->data()->document();
155: $documentPlanner = $this->planners->document();
156: list($parent, $key) = $documentPlanner->getParentDocumentAndKey($document, $config->path, true);
157:
158: if($arrayNode === null) {
159: $arrayNode = $documentPlanner->getArrayNode($parent, $key, true);
160: }
161:
162: if($arrayNode->count() === 0) {
163: $parent->remove($key);
164:
165: }else{
166: $parent->set($key, $arrayNode);
167: }
168:
169: return $arrayNode;
170: }
171: }
172: