ManyMany::doUpdateInterMapper()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 4
nc 6
nop 3
dl 0
loc 5
rs 9.2222
c 0
b 0
f 0
1
<?php
2
namespace Maphper\Relation;
3
class ManyMany implements \IteratorAggregate, \ArrayAccess, \Countable, \Maphper\Relation {
4
	private $results;
5
	private $localField;
6
	private $parentField;
7
	private $iterator = 0;
8
	private $otherInfo;
9
	private $relatedMapper;
10
	private $intermediateMapper;
11
	private $autoTraverse = false;
12
	private $object;
13
	private $intermediateName;
14
15
	public function __construct(\Maphper\Maphper $intermediateMapper, \Maphper\Maphper $relatedMapper, $localField, $parentField, $intermediateName = null) {
16
		$this->intermediateMapper = $intermediateMapper;
17
		$this->relatedMapper = $relatedMapper;
18
		$this->localField = $localField;
19
		$this->parentField = $parentField;
20
		$this->autoTraverse = $intermediateName ? false : true;
21
		$this->intermediateName = $intermediateName ?: 'rel_' . $parentField;
22
		$this->intermediateMapper->addRelation($this->intermediateName, new One($this->relatedMapper, $parentField, $localField));
23
24
	}
25
26
	public function getData($parentObject) {
27
		$this->object = $parentObject;
28
		return clone $this;
29
	}
30
31
	public function overwrite($parentObject, &$data) {
32
		list($relatedField, $valueField, $mapper) = $this->getOtherFieldNameInfo();
33
		$this->results = $data;
34
		$this->object = $parentObject;
35
		if (empty($parentObject->{$relatedField})) return;
36
		foreach ($data as $dt) $this[] = $dt;
37
	}
38
39
	//bit hacky, breaking encapsulation, but simplest way to work out the info for the other side of the many:many relationship.
40
	private function getOtherFieldNameInfo() {
41
		if ($this->otherInfo == null) {
42
			$propertyReader = function($name) {return $this->$name;	};
43
44
			$reader = $propertyReader->bindTo($this->intermediateMapper, $this->intermediateMapper);
45
46
			foreach ($reader('relations') as $relation) {
47
				$propertyReader = $propertyReader->bindTo($relation, $relation);
48
				if ($propertyReader('parentField') != $this->parentField) {
49
					$relation = $relation->getData($this->object);
0 ignored issues
show
Unused Code introduced by
The assignment to $relation is dead and can be removed.
Loading history...
50
					$this->otherInfo = [$propertyReader('localField'),  $propertyReader('parentField'), $propertyReader('mapper')];
51
				}
52
			}
53
		}
54
		return $this->otherInfo;
55
	}
56
57
	public function count() {
58
		return count($this->getResults());
59
	}
60
61
	private function getResults() {
62
		list ($relatedField, $valueField, $relatedMapper) = $this->getOtherFieldNameInfo();
63
64
		$x = $this->intermediateMapper->filter([$valueField => $this->object->$relatedField]);
0 ignored issues
show
Bug introduced by
The method filter() does not exist on Maphper\Maphper. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

64
		/** @scrutinizer ignore-call */ 
65
  $x = $this->intermediateMapper->filter([$valueField => $this->object->$relatedField]);
Loading history...
65
		return $x;
66
	}
67
68
	public function getIterator() {
69
		$results = $this->getResults()->getIterator();
70
		return new ManyManyIterator($results, $this->autoTraverse ? $this->intermediateName : null);
71
	}
72
73
	public function item($i) {
74
		return iterator_to_array($this->getIterator(), false)[$i];
75
	}
76
77
	public function offsetExists($name) {
78
		$items = $this->getResults()->filter([$this->parentField => $name]);
79
80
		return $items->getIterator()->valid();
81
	}
82
83
	public function offsetGet($name) {
84
		$items = $this->getResults()->filter([$this->parentField => $name]);
85
86
		return $items->getIterator()->current()->{$this->intermediateName};
87
	}
88
89
	public function offsetSet($name, $value) {
90
		list($relatedField, $valueField, $mapper) = $this->getOtherFieldNameInfo();
91
		if ($this->autoTraverse) $this->offsetSetAutotraverse($value, $relatedField, $valueField);
92
		else if ($this->doUpdateInterMapper($value, $relatedField, $valueField)) {
93
            $record = $value;
94
			$record->{$this->parentField} = $value->{$this->intermediateName}->{$this->localField};
95
			$record->$valueField = $this->object->{$relatedField};
96
			$this->intermediateMapper[] = $record;
97
		}
98
	}
99
100
    private function doUpdateInterMapper($record, $relatedField, $valueField) {
101
        return !(isset($record->{$this->parentField}) && isset($record->{$this->intermediateName}) &&
102
            isset($record->$valueField) && isset($this->object->{$relatedField}) &&
103
            $record->{$this->parentField} == $record->{$this->intermediateName}->{$this->localField} &&
104
            $record->$valueField == $this->object->{$relatedField});
105
    }
106
107
    private function offsetSetAutotraverse($value, $relatedField, $valueField) {
108
        $record = new \stdClass;
109
        $record->{$this->parentField} =  $value->{$this->localField};
110
        $record->$valueField = $this->object->{$relatedField};
111
        $this->intermediateMapper[] = $record;
112
    }
113
114
	public function offsetUnset($id) {
115
		//$this->relation->mapper->filter([$relatedField => $this->object->$valueField, $this->relation->parentField => $id])->delete();
116
	}
117
118
	public function delete() {
119
		$this->getResults()->delete();
120
	}
121
}
122