6d348b9d841cb07068a246341c01248c52a9730f
[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
242 // if it is the first matching rule in an OR conjunction return TRUE
243 return TRUE;
244 }
245 } elseif ($isOr === FALSE) {
246
247 // if it is the first NOT matching rule in an AND conjunction return FALSE
248 return FALSE;
249 }
250 }
251 // if OR and no field matched return TRUE
252 // if AND and no field matched NOT return FALSE
253 return ($isOr !== TRUE);
254 }
255
256 /**
257 * @param Form $form
258 * @param array $arguments
259 * @return array
260 */
261 public function apply(Form $form, array $arguments) {
262 if (strpos($this->targetField, 'fieldset') !== FALSE) {
263 $pageUid = (int) substr($this->targetField, 9);
264 /** @var Page $page */
265 foreach ($form->getPages() as $page) {
266 if ($page->getUid() === $pageUid) {
267
268 /** @var Field $field */
269 foreach ($page->getFields() as $field) {
270 $action = self::$actionNumberMap[$this->actions];
271 if ($action === 'hide') {
272 $arguments['old_alues'][$form->getUid()][$page->getUid()][$field->getMarker()] = $field->getText();
273 $field->setText('');
274 } elseif ($action === 'un_hide') {
275 if (!empty($arguments['old_alues'][$form->getUid()][$page->getUid()][$field->getMarker()])) {
276 $field->setText($arguments['old_alues'][$form->getUid()][$page->getUid()][$field->getMarker()]);
277 }
278 }
279 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
280 'action' => $action,
281 'matchingCondition' => $this->getUid(),
282 );
283 }
284
285 $arguments['todo_page'][$form->getUid()][$page->getUid()] = array(
286 'action' => self::$actionNumberMap[$this->actions],
287 'matchingCondition' => $this->getUid(),
288 );
289 break;
290 }
291 }
292 } else {
293 /** @var Page $page */
294 foreach ($form->getPages() as $page) {
295 /** @var Field $field */
296 foreach ($page->getFields() as $field) {
297 if ($field->getUid() === (int) $this->targetField) {
298 $action = self::$actionNumberMap[$this->actions];
299 if ($action === 'hide') {
300 $arguments['old_alues'][$form->getUid()][$page->getUid()][$field->getMarker()] = $field->getText();
301 $field->setText('');
302 } elseif ($action === 'un_hide') {
303 if (!empty($arguments['old_alues'][$form->getUid()][$page->getUid()][$field->getMarker()])) {
304 $field->setText($arguments['old_alues'][$form->getUid()][$page->getUid()][$field->getMarker()]);
305 }
306 }
307 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
308 'action' => $action,
309 'matchingCondition' => $this->getUid(),
310 );
311 break;
312 }
313 }
314 }
315 }
316 return $arguments;
317 }
318
319 /**
320 * @param Form $form
321 * @param array $arguments
322 * @return array
323 */
324 public function negate(Form $form, array $arguments) {
325
326 if (strpos($this->targetField, 'fieldset') !== FALSE) {
327 $pageUid = (int) substr($this->targetField, 9);
328 /** @var Page $page */
329 foreach ($form->getPages() as $page) {
330 if ($page->getUid() === $pageUid) {
331
332 /** @var Field $field */
333 foreach ($page->getFields() as $field) {
334 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
335 'action' => $this->getNegatedActionString(),
336 'matchingCondition' => $this->getUid(),
337 );
338 }
339
340 $arguments['todo_page'][$form->getUid()][$page->getUid()] = array(
341 'action' => $this->getNegatedActionString(),
342 'matchingCondition' => $this->getUid(),
343 );
344 break;
345 }
346 }
347 } else {
348 /** @var Page $page */
349 foreach ($form->getPages() as $page) {
350 /** @var Field $field */
351 foreach ($page->getFields() as $field) {
352 if ($field->getUid() === (int) $this->targetField) {
353 $arguments['todo_field'][$form->getUid()][$page->getUid()][$field->getMarker()] = array(
354 'action' => $this->getNegatedActionString(),
355 'matchingCondition' => $this->getUid(),
356 );
357 break;
358 }
359 }
360 }
361 }
362 return $arguments;
363 }
364
365 /**
366 * @return array
367 */
368 protected function getNegatedActionString() {
369 if ($this->actions === self::ACTION_HIDE) {
370 return self::getActionNumberMap(self::ACTION_UN_HIDE);
371 } elseif ($this->actions === self::ACTION_UN_HIDE) {
372 return self::getActionNumberMap(self::ACTION_HIDE);
373 }
374 }
375
376 /**
377 * @param int|NULL $action
378 * @return array
379 */
380 static public function getActionNumberMap($action = NULL) {
381 if ($action !== NULL) {
382 return self::$actionNumberMap[$action];
383 }
384 return self::$actionNumberMap;
385 }
386 }