1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace DcGeneral\DataDefinition\ModelRelationship;
14:
15: use DcGeneral\Exception\DcGeneralInvalidArgumentException;
16: use DcGeneral\Exception\DcGeneralRuntimeException;
17:
18: 19: 20: 21: 22:
23: class ParentChildCondition
24: extends AbstractCondition
25: implements ParentChildConditionInterface
26: {
27: 28: 29: 30: 31:
32: protected $filter;
33:
34: 35: 36: 37: 38:
39: protected $inverseFilter;
40:
41: 42: 43: 44: 45:
46: protected $setOn;
47:
48: 49: 50: 51: 52:
53: protected $sourceProvider;
54:
55: 56: 57: 58: 59:
60: protected $destinationProvider;
61:
62: 63: 64:
65: public function setFilterArray($value)
66: {
67: $this->filter = $value;
68:
69: return $this;
70: }
71:
72: 73: 74:
75: public function getFilterArray()
76: {
77: return $this->filter;
78: }
79:
80: 81: 82:
83: public function setSetters($value)
84: {
85: $this->setOn = $value;
86:
87: return $this;
88: }
89:
90: 91: 92:
93: public function getSetters()
94: {
95: return $this->setOn;
96: }
97:
98: 99: 100:
101: public function setInverseFilterArray($value)
102: {
103: $this->inverseFilter = $value;
104:
105: return $this;
106: }
107:
108: 109: 110:
111: public function getInverseFilterArray()
112: {
113: return $this->inverseFilter;
114: }
115:
116: 117: 118:
119: public function setSourceName($value)
120: {
121: $this->sourceProvider = $value;
122:
123: return $this;
124: }
125:
126: 127: 128:
129: public function getSourceName()
130: {
131: return $this->sourceProvider;
132: }
133:
134: 135: 136:
137: public function setDestinationName($value)
138: {
139: $this->destinationProvider = $value;
140:
141: return $this;
142: }
143:
144: 145: 146:
147: public function getDestinationName()
148: {
149: return $this->destinationProvider;
150: }
151:
152: 153: 154: 155: 156:
157: public function getFilter($objParent)
158: {
159: if (!$objParent)
160: {
161: throw new DcGeneralInvalidArgumentException('No parent model passed.');
162: }
163:
164: $arrResult = array();
165: foreach ($this->getFilterArray() as $arrRule)
166: {
167: $arrApplied = array(
168: 'operation' => $arrRule['operation'],
169: );
170:
171: if (isset($arrRule['local']))
172: {
173: $arrApplied['property'] = $arrRule['local'];
174: }
175:
176: if (isset($arrRule['remote']))
177: {
178: $arrApplied['value'] = $objParent->getProperty($arrRule['remote']);
179: }
180:
181: if (isset($arrRule['remote_value']))
182: {
183: $arrApplied['value'] = $arrRule['remote_value'];
184: }
185:
186: if (isset($arrRule['value']))
187: {
188: $arrApplied['value'] = $arrRule['value'];
189: }
190:
191: $arrResult[] = $arrApplied;
192: }
193:
194: return $arrResult;
195: }
196:
197: 198: 199: 200: 201:
202: public function applyTo($objParent, $objChild)
203: {
204: $setters = $this->getSetters();
205:
206: if (empty($setters) || !is_array($setters))
207: {
208: throw new DcGeneralRuntimeException(sprintf(
209: 'No relationship setter defined from %s to %s.',
210: $this->getSourceName(),
211: $this->getDestinationName()
212: ));
213: }
214:
215: foreach ($setters as $setter)
216: {
217: if (!(is_array($setter)
218: && (count($setter) == 2)
219: && isset($setter['to_field'])
220: && (isset($setter['from_field']) || isset($setter['value']))
221: ))
222: {
223: throw new DcGeneralRuntimeException(sprintf(
224: 'Invalid relationship setter entry: %s',
225: var_export($setter, true)
226: ));
227: }
228:
229: if (isset($setter['from_field']))
230: {
231: $objChild->setProperty($setter['to_field'], $objParent->getProperty($setter['from_field']));
232: }
233: else
234: {
235: $objChild->setProperty($setter['to_field'], $setter['value']);
236: }
237: }
238: }
239:
240: 241: 242: 243: 244:
245: public function copyFrom($sourceModel, $destinationModel)
246: {
247: $setters = $this->getSetters();
248:
249: if (empty($setters) || !is_array($setters))
250: {
251: throw new DcGeneralRuntimeException(sprintf(
252: 'No relationship setter defined from %s to %s.',
253: $this->getSourceName(),
254: $this->getDestinationName()
255: ));
256: }
257:
258: foreach ($setters as $setter)
259: {
260: if (!(is_array($setter)
261: && (count($setter) == 2)
262: && isset($setter['to_field'])
263: && (isset($setter['from_field']) || isset($setter['value']))
264: ))
265: {
266: throw new DcGeneralRuntimeException(sprintf(
267: 'Invalid relationship setter entry: %s',
268: var_export($setter, true)
269: ));
270: }
271:
272: if (isset($setter['from_field']))
273: {
274: $destinationModel->setProperty($setter['to_field'], $sourceModel->getProperty($setter['to_field']));
275: }
276: else
277: {
278: $destinationModel->setProperty($setter['to_field'], $setter['value']);
279: }
280: }
281: }
282:
283: 284: 285:
286: public function getInverseFilterFor($objChild)
287: {
288: $arrResult = array();
289: foreach ($this->getInverseFilterArray() as $arrRule)
290: {
291: $arrApplied = array(
292: 'operation' => $arrRule['operation'],
293: );
294:
295: if (isset($arrRule['remote']))
296: {
297: $arrApplied['property'] = $arrRule['remote'];
298: }
299:
300: if (isset($arrRule['local']))
301: {
302: $arrApplied['value'] = $objChild->getProperty($arrRule['local']);
303: }
304:
305: if (isset($arrRule['value']))
306: {
307: $arrApplied['value'] = $arrRule['value'];
308: }
309:
310: $arrResult[] = $arrApplied;
311: }
312:
313: return $arrResult;
314: }
315:
316: 317: 318:
319: public function matches($objParent, $objChild)
320: {
321: $filter = array();
322: foreach ($this->getFilterArray() as $arrRule)
323: {
324: $arrApplied = array(
325: 'operation' => $arrRule['operation'],
326: );
327:
328: if (isset($arrRule['local']))
329: {
330: $arrApplied['property'] = $objChild->getProperty($arrRule['local']);
331: }
332:
333: if (isset($arrRule['remote']))
334: {
335: $arrApplied['value'] = $arrRule['remote'];
336: }
337:
338: if (isset($arrRule['remote_value']))
339: {
340: $arrApplied['value'] = $arrRule['remote_value'];
341: }
342:
343: if (isset($arrRule['value']))
344: {
345: $arrApplied['value'] = $arrRule['value'];
346: }
347:
348: $filter[] = $arrApplied;
349: }
350:
351: return $this->checkCondition($objParent, $filter);
352: }
353: }
354:
355:
356:
357:
358: