[TASK] Rework conjunction dependent loop to a single foreach
[TYPO3CMS/Extensions/powermailCond.git] / Classes / Domain / Model / Condition.php
1 <?php
2 namespace In2code\PowermailCond\Domain\Model;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2015 in2code.de
8 * Alex Kellner <alexander.kellner@in2code.de>,
9 * Oliver Eglseder <oliver.eglseder@in2code.de>
10 *
11 * All rights reserved
12 *
13 * This script is part of the TYPO3 project. The TYPO3 project is
14 * free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * The GNU General Public License can be found at
20 * http://www.gnu.org/copyleft/gpl.html.
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use In2code\Powermail\Domain\Model\Field;
31 use In2code\Powermail\Domain\Model\Form;
32 use In2code\Powermail\Domain\Model\Page;
33 use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
34
35 /**
36 * Condition Model
37 *
38 * @package powermail_cond
39 * @license http://www.gnu.org/licenses/lgpl.html
40 * GNU Lesser General Public License, version 3 or later
41 */
42 class Condition extends AbstractEntity {
43
44 const CONJUNCTION_OR = 'OR';
45 const CONJUNCTION_AND = 'AND';
46 const ACTION_HIDE = 0;
47 const ACTION_UN_HIDE = 1;
48
49 /**
50 * @var array
51 */
52 protected static $actionNumberMap = array(
53 self::ACTION_HIDE => 'hide',
54 self::ACTION_UN_HIDE => 'un_hide',
55 );
56
57 /**
58 * @var \In2code\Powermail\Domain\Repository\FieldRepository
59 * @inject
60 */
61 protected $fieldRepository;
62
63 /**
64 * @var \In2code\Powermail\Domain\Repository\PageRepository
65 * @inject
66 */
67 protected $pageRepository;
68
69 /**
70 * @var string
71 */
72 protected $title = '';
73
74 /**
75 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\In2code\PowermailCond\Domain\Model\Rule>
76 */
77 protected $rules = NULL;
78
79 /**
80 * @var string
81 */
82 protected $targetField = '';
83
84 /**
85 * 0 hide
86 * 1 unhide
87 *
88 * @var int
89 */
90 protected $actions = 0;
91
92 /**
93 * @var string
94 */
95 protected $filterSelectField = '';
96
97 /**
98 * "OR"
99 * "AND"
100 *
101 * @var string
102 */
103 protected $conjunction = '';
104
105 /**
106 * @var \In2code\Powermail\Domain\Model\Form
107 */
108 protected $form = '';
109
110 /**
111 * @return string
112 */
113 public function getTitle() {
114 return $this->title;
115 }
116
117 /**
118 * @param string $title
119 * @return Condition
120 */
121 public function setTitle($title) {
122 $this->title = $title;
123 return $this;
124 }
125
126 /**
127 * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
128 */
129 public function getRules() {
130 return $this->rules;
131 }
132
133 /**
134 * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $rules
135 * @return Condition
136 */
137 public function setRules($rules) {
138 $this->rules = $rules;
139 return $this;
140 }
141
142 /**
143 * @return Field|Page|NULL
144 */
145 public function getTargetField() {
146 $targetField = $this->targetField;
147 if (is_numeric($targetField)) {
148 return $this->fieldRepository->findByUid((int) $targetField);
149 }
150 if (stristr($targetField, 'fieldset:')) {
151 return $this->pageRepository->findByUid((int) trim($targetField, 'fieldset:'));
152 }
153 return NULL;
154 }
155
156 /**
157 * @param string $targetField
158 * @return Condition
159 */
160 public function setTargetField($targetField) {
161 $this->targetField = $targetField;
162 return $this;
163 }
164
165 /**
166 * @return int
167 */
168 public function getActions() {
169 return $this->actions;
170 }
171
172 /**
173 * @param int $actions
174 * @return Condition
175 */
176 public function setActions($actions) {
177 $this->actions = $actions;
178 return $this;
179 }
180
181 /**
182 * @return string
183 */
184 public function getFilterSelectField() {
185 return $this->filterSelectField;
186 }
187
188 /**
189 * @param string $filterSelectField
190 * @return Condition
191 */
192 public function setFilterSelectField($filterSelectField) {
193 $this->filterSelectField = $filterSelectField;
194 return $this;
195 }
196
197 /**
198 * @return string
199 */
200 public function getConjunction() {
201 return $this->conjunction;
202 }
203
204 /**
205 * @param string $conjunction
206 * @return Condition
207 */
208 public function setConjunction($conjunction) {
209 $this->conjunction = $conjunction;
210 return $this;
211 }
212
213 /**
214 * @return Form
215 */
216 public function getForm() {
217 return $this->form;
218 }
219
220 /**
221 * @param Form $form
222 * @return Condition
223 */
224 public function setForm($form) {
225 $this->form = $form;
226 return $this;
227 }
228
229 /**
230 * @param Form $form
231 * @return bool
232 */
233 public function applies(Form $form) {
234 // If conjunction is or set $isOr to TRUE
235 $isOr = ($this->conjunction === self::CONJUNCTION_OR);
236
237 /** @var Rule $rule */
238 foreach ($this->rules as $rule) {
239 if ($rule->applies($form)) {
240 if ($isOr === TRUE) {
241 // if it is
242 // the first matching rule in an OR conjunction return TRUE
243 return TRUE;
244 }
245 } elseif ($isOr === FALSE) {
246 // if it is the first NOT matching rule in an AND conjunction return FALSE
247 return FALSE;
248 }
249 }
250 return ($isOr !== TRUE);
251 }
252
253 /**
254 * @param Form $form
255 * @param array $arguments
256 * @return array
257 */
258 public function apply(Form $form, array $arguments) {
259 if (strpos($this->targetField, 'fieldset') !== FALSE) {
260 $pageUid = (int) substr($this->targetField, 9);
261 /** @var Page $page */
262 foreach ($form->getPages() as $page) {
263 if ($page->getUid() === $pageUid) {
264
265 /** @var Field $field */
266 foreach ($page->getFields() as $field) {
267 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
268 'action' => self::$actionNumberMap[$this->actions],
269 'matchingCondition' => $this->getUid(),
270 );
271 }
272
273 $arguments['todo_page'][$form->getUid()][$page->getUid()] = array(
274 'action' => self::$actionNumberMap[$this->actions],
275 'matchingCondition' => $this->getUid(),
276 );
277 break;
278 }
279 }
280 } else {
281 /** @var Page $page */
282 foreach ($form->getPages() as $page) {
283 /** @var Field $field */
284 foreach ($page->getFields() as $field) {
285 if ($field->getUid() === (int) $this->targetField) {
286 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
287 'action' => self::$actionNumberMap[$this->actions],
288 'matchingCondition' => $this->getUid(),
289 );
290 break;
291 }
292 }
293 }
294 }
295 return $arguments;
296 }
297
298 /**
299 * @param Form $form
300 * @param array $arguments
301 * @return array
302 */
303 public function negate(Form $form, array $arguments) {
304
305 if (strpos($this->targetField, 'fieldset') !== FALSE) {
306 $pageUid = (int) substr($this->targetField, 9);
307 /** @var Page $page */
308 foreach ($form->getPages() as $page) {
309 if ($page->getUid() === $pageUid) {
310
311 /** @var Field $field */
312 foreach ($page->getFields() as $field) {
313 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
314 'action' => $this->getNegatedActionString(),
315 'matchingCondition' => $this->getUid(),
316 );
317 }
318
319 $arguments['todo_page'][$form->getUid()][$page->getUid()] = array(
320 'action' => $this->getNegatedActionString(),
321 'matchingCondition' => $this->getUid(),
322 );
323 break;
324 }
325 }
326 } else {
327 /** @var Page $page */
328 foreach ($form->getPages() as $page) {
329 /** @var Field $field */
330 foreach ($page->getFields() as $field) {
331 if ($field->getUid() === (int) $this->targetField) {
332 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
333 'action' => $this->getNegatedActionString(),
334 'matchingCondition' => $this->getUid(),
335 );
336 break;
337 }
338 }
339 }
340 }
341 return $arguments;
342 }
343
344 /**
345 * @return array
346 */
347 protected function getNegatedActionString() {
348 if ($this->actions === self::ACTION_HIDE) {
349 return self::getActionNumberMap(self::ACTION_UN_HIDE);
350 } elseif ($this->actions === self::ACTION_UN_HIDE) {
351 return self::getActionNumberMap(self::ACTION_HIDE);
352 }
353 }
354
355 /**
356 * @param int|NULL $action
357 * @return array
358 */
359 static public function getActionNumberMap($action = NULL) {
360 if ($action !== NULL) {
361 return self::$actionNumberMap[$action];
362 }
363 return self::$actionNumberMap;
364 }
365 }