All Data Structures Functions Variables Pages
TriggerForWorkflowForm.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
41  {
46  const RELATION_FILTER_ANY = 'RelationFilterAny';
47 
52  public $currencyIdForValue;
53 
57  public $value;
58 
63  public $secondValue;
64 
73  public $thirdValueDurationInterval;
74 
83  public $thirdValueDurationType;
84 
90  public $stringifiedModelForValue;
91 
97  public $valueType;
98 
105  public $relationFilter = self::RELATION_FILTER_ANY;
106 
110  private $_operator;
111 
115  private $_availableOperatorsType;
116 
120  public static function getType()
121  {
122  return static::TYPE_TRIGGERS;
123  }
124 
128  public function attributeNames()
129  {
130  return array_merge(parent::attributeNames(), array('operator'));
131  }
132 
138  public function __set($name, $value)
139  {
140  parent::__set($name, $value);
141  if ($name == 'attributeIndexOrDerivedType')
142  {
143  $this->_availableOperatorsType = null;
144  }
145  }
146 
151  public function setOperator($value)
152  {
153  if (!in_array($value, OperatorRules::availableTypes()) && $value != null)
154  {
155  throw new NotSupportedException();
156  }
157  $this->_operator = $value;
158  }
159 
163  public function getOperator()
164  {
165  return $this->_operator;
166  }
167 
171  public function rules()
172  {
173  return array_merge(parent::rules(), array(
174  array('operator', 'type', 'type' => 'string'),
175  array('operator', 'validateOperator'),
176  array('value', 'safe'),
177  array('value', 'validateValue'),
178  array('relationFilter', 'type', 'type' => 'string'),
179  array('relationFilter', 'validateRelationFilter'),
180  array('secondValue', 'safe'),
181  array('secondValue', 'validateSecondValue'),
182  array('currencyIdForValue', 'safe'),
183  array('stringifiedModelForValue', 'safe'),
184  array('valueType', 'type', 'type' => 'string'),
185  array('valueType', 'validateValueType'),
186  array('thirdValueDurationInterval', 'safe'),
187  array('thirdValueDurationInterval', 'validateThirdValue'),
188  array('thirdValueDurationType', 'type', 'type' => 'string'),
189  ));
190  }
191 
195  public function validateOperator()
196  {
197  if ($this->getAvailableOperatorsType() != null && $this->operator == null)
198  {
199  $this->addError('operator', Zurmo::t('ZurmoModule', 'Operator cannot be blank.'));
200  return false;
201  }
202  }
203 
207  public function validateRelationFilter()
208  {
209  if ($this->relationFilter == self::RELATION_FILTER_ANY)
210  {
211  return true;
212  }
213  $this->addError('relationFilter', Zurmo::t('WorkflowsModule', 'Invalid Relation Filter'));
214  return false;
215  return true;
216  }
217 
221  public function validateValue()
222  {
223  if ((in_array($this->operator, self::getOperatorsWhereValueIsRequired()) ||
224  in_array($this->valueType, self::getValueTypesWhereValueIsRequired()) ||
225  ($this->getValueElementType() == 'MixedDateTypesForWorkflow' && $this->valueType == null)) &&
226  $this->value == null)
227  {
228  $this->addError('value', Zurmo::t('Core', 'Value cannot be blank.'));
229  }
230  $passedValidation = true;
231  $rules = array();
232  if (!is_array($this->value))
233  {
234  $this->resolveAndValidateValueData($rules, $passedValidation, 'value');
235  }
236  else
237  {
238  //Assume array has only string values
239  foreach ($this->value as $subValue)
240  {
241  if (!is_string($subValue))
242  {
243  $this->addError('value', Zurmo::t('Core', 'Value must be a string.'));
244  $passedValidation = false;
245  }
246  }
247  }
248  return $passedValidation;
249  }
250 
257  public function validateSecondValue()
258  {
259  $passedValidation = true;
260  $rules = array();
261  if (!is_array($this->secondValue))
262  {
263  if (in_array($this->operator, self::getOperatorsWhereSecondValueIsRequired()) ||
264  in_array($this->valueType, self::getValueTypesWhereSecondValueIsRequired()))
265  {
266  $rules[] = array('secondValue', 'required');
267  }
268  $this->resolveAndValidateValueData($rules, $passedValidation, 'secondValue');
269  }
270  else
271  {
272  throw new NotSupportedException();
273  }
274  return $passedValidation;
275  }
276 
286  public function validateThirdValue()
287  {
288  $passedValidation = true;
289 
290  if (in_array($this->valueType, self::getValueTypesWhereThirdValueIsRequired()))
291  {
292  $rules = array();
293  $rules[] = array('thirdValueDurationInterval', 'type', 'type' => 'integer');
294  $rules[] = array('thirdValueDurationInterval', 'numerical', 'min' => 0);
295  $rules[] = array('thirdValueDurationInterval', 'required');
296  $this->resolveAndValidateValueData($rules, $passedValidation, 'thirdValueDurationInterval', false);
297  $rules = array();
298  $rules[] = array('thirdValueDurationType', 'required');
299  $this->resolveAndValidateValueData($rules, $passedValidation, 'thirdValueDurationType', false);
300  }
301  return $passedValidation;
302  }
303 
307  public function validateValueType()
308  {
309  if ($this->getValueElementType() == 'MixedDateTypesForWorkflow' && $this->valueType == null)
310  {
311  $this->addError('valueType', Zurmo::t('ZurmoModule', 'Type cannot be blank.'));
312  return false;
313  }
314  }
315 
319  public function hasAvailableOperatorsType()
320  {
321  if ($this->getAvailableOperatorsType() != null)
322  {
323  return true;
324  }
325  return false;
326  }
327 
332  public function getOperatorValuesAndLabels()
333  {
334  if ($this->attributeIndexOrDerivedType == null)
335  {
336  throw new NotSupportedException();
337  }
338  $type = $this->getAvailableOperatorsType();
339  $data = array();
342  {
343  $data[OperatorRules::TYPE_BECOMES] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_BECOMES);
344  $data[OperatorRules::TYPE_WAS] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_WAS);
345  $data[OperatorRules::TYPE_CHANGES] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_CHANGES);
346  $data[OperatorRules::TYPE_DOES_NOT_CHANGE] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_DOES_NOT_CHANGE);
347  }
349  {
350  $data[OperatorRules::TYPE_DOES_NOT_CHANGE] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_DOES_NOT_CHANGE);
351  }
353  $type == ModelAttributeToOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_DROPDOWN &&
354  $this->getValueElementType() != 'StaticMultiSelectDropDownForWorkflow')
355  {
356  $data[OperatorRules::TYPE_BECOMES_ONE_OF] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_BECOMES_ONE_OF);
357  $data[OperatorRules::TYPE_WAS_ONE_OF] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_WAS_ONE_OF);
358  }
359  if ($type != ModelAttributeToWorkflowOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_BOOLEAN &&
360  $type != ModelAttributeToWorkflowOperatorTypeUtil::AVAILABLE_OPERATORS_TYPE_CURRENCY_VALUE)
361  {
362  $data[OperatorRules::TYPE_IS_EMPTY] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_IS_EMPTY);
363  $data[OperatorRules::TYPE_IS_NOT_EMPTY] = OperatorRules::getTranslatedTypeLabel(OperatorRules::TYPE_IS_NOT_EMPTY);
364  }
365  return $data;
366  }
367 
372  public function getValueElementType()
373  {
374  if ($this->attributeIndexOrDerivedType == null)
375  {
376  throw new NotSupportedException();
377  }
379  return $modelToWorkflowAdapter->getTriggerValueElementType($this->getResolvedAttribute());
380  }
381 
387  public function getValueEvaluationType()
388  {
389  if ($this->attributeIndexOrDerivedType == null)
390  {
391  throw new NotSupportedException();
392  }
394  return $modelToWorkflowAdapter->getDisplayElementType($this->getResolvedAttribute());
395  }
396 
401  public function getCustomFieldDataAndLabels()
402  {
403  $modelClassName = $this->getResolvedAttributeModelClassName();
404  $attribute = $this->getResolvedAttribute();
405  $model = new $modelClassName();
406  if ($model->isAttribute($attribute))
407  {
408  $dataAndLabels = CustomFieldDataUtil::
409  getDataIndexedByDataAndTranslatedLabelsByLanguage($model->{$attribute}->data, Yii::app()->language);
410  return $dataAndLabels;
411  }
412  else
413  {
414  throw new NotSupportedException();
415  }
416  }
417 
423  public function isTrueByModel(RedBeanModel $model)
424  {
425  return true;
426  }
427 
436  public function resolveNewTimeStampForThirdValueDuration($initialTimeStamp)
437  {
438  assert('is_int($initialTimeStamp)');
439  if ($this->valueType ==
440  MixedDateTypesTriggerForWorkflowFormAttributeMappingRules::TYPE_AT_LEAST_X_AFTER_TRIGGERED_DATE ||
441  $this->valueType ==
442  MixedDateTypesTriggerForWorkflowFormAttributeMappingRules::TYPE_LESS_THAN_X_AFTER_TRIGGERED_DATE)
443  {
444  $durationSign = TimeDurationUtil::DURATION_SIGN_POSITIVE;
445  }
446  else
447  {
448  $durationSign = TimeDurationUtil::DURATION_SIGN_NEGATIVE;
449  }
450  return TimeDurationUtil::resolveNewTimeStampForDuration($initialTimeStamp, (int)$this->thirdValueDurationInterval,
451  $durationSign, $this->thirdValueDurationType);
452  }
453 
458  protected function getAvailableOperatorsType()
459  {
460  if ($this->attributeIndexOrDerivedType == null)
461  {
462  throw new NotSupportedException();
463  }
464  if ($this->_availableOperatorsType != null)
465  {
466  return $this->_availableOperatorsType;
467  }
468  $modelToWorkflowAdapter = $this->makeResolvedAttributeModelRelationsAndAttributesToWorkflowAdapter();
469  $availableOperatorsType = $modelToWorkflowAdapter->getAvailableOperatorsType($this->getResolvedAttribute());
470  $this->_availableOperatorsType = $availableOperatorsType;
471  return $availableOperatorsType;
472  }
473 
477  protected static function getValueTypesWhereValueIsRequired()
478  {
480  }
481 
485  protected static function getValueTypesWhereSecondValueIsRequired()
486  {
488  }
489 
493  protected static function getOperatorsWhereValueIsRequired()
494  {
495  return OperatorRules::getOperatorsWhereValueIsRequired();
496  }
497 
501  protected static function getOperatorsWhereSecondValueIsRequired()
502  {
503  return OperatorRules:: getOperatorsWhereSecondValueIsRequired();
504  }
505 
509  protected static function getValueTypesWhereThirdValueIsRequired()
510  {
512  }
513 
519  private function createValueValidatorsByRules(Array $rules)
520  {
521  $validators = new CList;
522  foreach ($rules as $rule)
523  {
524  if (isset($rule[0], $rule[1]))
525  {
526  if ($rule[1] != 'unique')
527  {
528  $validators->add(CValidator::createValidator($rule[1], $this, $rule[0], array_slice($rule, 2)));
529  }
530  }
531  else
532  {
533  throw new CException(Zurmo::t('WorkflowsModule', '{class} has an invalid validation rule. The rule must specify ' .
534  'attributes to be validated and the validator name.' ,
535  array('{class}' => get_class($this))));
536  }
537  }
538  return $validators;
539  }
540 
547  private function resolveAndValidateValueData(Array $rules, & $passedValidation, $ruleAttributeName,
548  $getTriggerRulesByAttribute = true)
549  {
550  if ($getTriggerRulesByAttribute)
551  {
552  $modelToWorkflowAdapter = $this->makeResolvedAttributeModelRelationsAndAttributesToWorkflowAdapter();
553  $rules = array_merge($rules, $modelToWorkflowAdapter->getTriggerRulesByAttribute(
554  $this->getResolvedAttribute(), $ruleAttributeName));
555  }
556  $validators = $this->createValueValidatorsByRules($rules);
557  foreach ($validators as $validator)
558  {
559  $validated = $validator->validate($this);
560  if (!$validated)
561  {
562  $passedValidation = false;
563  }
564  }
565  }
566 
571  {
572  $modelClassName = $this->modelClassName;
573  if (( $this->workflowType == Workflow::TYPE_ON_SAVE &&
574  $this->getAttribute() != null) ||
575  ($this->getAttribute() == null &&
576  $this->getAttributeAndRelationData()) == 2 &&
577  $modelClassName::isOwnedRelation($this->getResolvedRealAttributeNameForPenultimateRelation()))
578  {
579  return true;
580  }
581  return false;
582  }
583 
588  {
589  $modelClassName = $this->modelClassName;
590  if (( $this->workflowType == Workflow::TYPE_BY_TIME &&
591  $this->getAttribute() != null) ||
592  ($this->getAttribute() == null &&
593  $this->getAttributeAndRelationData()) == 2 &&
594  $modelClassName::isOwnedRelation($this->getResolvedRealAttributeNameForPenultimateRelation()))
595  {
596  return true;
597  }
598  return false;
599  }
600  }
601 ?>
static getDataIndexedByDataAndTranslatedLabelsByLanguage(CustomFieldData $customFieldData, $language)
isTrueByModel(RedBeanModel $model)
resolveNewTimeStampForThirdValueDuration($initialTimeStamp)
static resolveNewTimeStampForDuration($initialTimeStamp, $durationInterval, $durationSign, $durationType)
Generated on Sat Mar 28 2020 07:10:45