/**
  * @return array
  */
 public function getDynamicTypeValueDropDownArray()
 {
     $data = array();
     WorkflowUtil::resolveNegativeDurationAsDistanceFromPointData($data, false);
     $data[0] = Zurmo::t('WorkflowsModule', '0 days');
     WorkflowUtil::resolvePositiveDurationAsDistanceFromPointData($data, false);
     return $data;
 }
 /**
  * @return array
  */
 public function getTimeTriggerAttributeDataAndLabels()
 {
     $dataAndLabels = array();
     if ($this->moduleClassName != null) {
         $moduleClassName = $this->moduleClassName;
         $dataAndLabels = WorkflowUtil::resolveDataAndLabelsForTimeTriggerAvailableAttributes($moduleClassName, $moduleClassName::getPrimaryModelName(), $this->type);
     }
     return $dataAndLabels;
 }
 /**
  * @param EmailMessageForWorkflowForm $emailMessageForWorkflowForm
  * @param RedBeanModel $model
  * @param User $triggeredByUser
  */
 public static function processOnWorkflowMessageInQueueJob(EmailMessageForWorkflowForm $emailMessageForWorkflowForm, RedBeanModel $model, User $triggeredByUser)
 {
     try {
         if ($emailMessageForWorkflowForm->getEmailMessageRecipientFormsCount() > 0) {
             $helper = new WorkflowEmailMessageProcessingHelper($emailMessageForWorkflowForm, $model, $triggeredByUser);
             $helper->process();
         }
     } catch (Exception $e) {
         WorkflowUtil::handleProcessingException($e, 'application.modules.workflows.utils.WorkflowEmailMessagesUtil.processOnWorkflowMessageInQueueJob');
     }
 }
/**
 * Zikula_View function to display the available workflow actions for the current item state.
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @return string HTML code with the available workflow actions for the current item state.
 */
function smarty_function_workflow_getactionsbystate($params, Zikula_View $view)
{
    if (!isset($params['schema'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('pnworkflow_getactionsbystate', 'schema')));
        return false;
    }
    if (!isset($params['module'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('pnworkflow_getactionsbystate', 'module')));
        return false;
    }
    if (!isset($params['state'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('pnworkflow_getactionsbystate', 'state')));
        return false;
    }
    $actions = WorkflowUtil::getActionsByState($params['schema'], $params['module'], $params['state']);
    $ak = array_keys($actions);
    $options = array();
    foreach ($ak as $action) {
        $options[] = $action;
    }
    return HtmlUtil::FormSelectMultipleSubmit($name, $options);
}
 /**
  * @see BaseJob::run()
  */
 public function run()
 {
     try {
         $originalUser = Yii::app()->user->userModel;
         Yii::app()->user->userModel = BaseControlUserConfigUtil::getUserToRunAs();
         foreach (ByTimeWorkflowInQueue::getModelsToProcess(self::$pageSize) as $byTimeWorkflowInQueue) {
             try {
                 $model = $this->resolveModel($byTimeWorkflowInQueue);
                 $this->resolveSavedWorkflowIsValid($byTimeWorkflowInQueue);
                 $this->processByTimeWorkflowInQueue($byTimeWorkflowInQueue, $model);
             } catch (NotFoundException $e) {
                 WorkflowUtil::handleProcessingException($e, 'application.modules.workflows.jobs.ByTimeWorkflowInQueueJob.run');
             }
             $byTimeWorkflowInQueue->delete();
         }
         Yii::app()->user->userModel = $originalUser;
         return true;
     } catch (MissingASuperAdministratorException $e) {
         //skip running workflow, since no super administrators are available.
         $this->errorMessage = Zurmo::t('WorkflowsModule', 'Could not process since no super administrators were found');
         return false;
     }
 }
 /**
  * @see BaseJob::run()
  */
 public function run()
 {
     try {
         $originalUser = Yii::app()->user->userModel;
         Yii::app()->user->userModel = BaseControlUserConfigUtil::getUserToRunAs();
         $processedModelsCount = 0;
         $batchSize = $this->resolveBatchSize();
         if ($batchSize != null) {
             $resolvedBatchSize = $batchSize + 1;
         } else {
             $resolvedBatchSize = null;
         }
         foreach (ByTimeWorkflowInQueue::getModelsToProcess($resolvedBatchSize) as $byTimeWorkflowInQueue) {
             if ($processedModelsCount < $batchSize || $batchSize == null) {
                 try {
                     $model = $this->resolveModel($byTimeWorkflowInQueue);
                     $this->resolveSavedWorkflowIsValid($byTimeWorkflowInQueue);
                     $this->processByTimeWorkflowInQueue($byTimeWorkflowInQueue, $model);
                 } catch (NotFoundException $e) {
                     WorkflowUtil::handleProcessingException($e, 'application.modules.workflows.jobs.ByTimeWorkflowInQueueJob.run');
                 }
                 $byTimeWorkflowInQueue->delete();
                 $processedModelsCount++;
             } else {
                 Yii::app()->jobQueue->add('ByTimeWorkflowInQueue', 5);
                 break;
             }
         }
         Yii::app()->user->userModel = $originalUser;
         return true;
     } catch (MissingASuperAdministratorException $e) {
         //skip running workflow, since no super administrators are available.
         $this->errorMessage = Zurmo::t('WorkflowsModule', 'Could not process since no super administrators were found');
         return false;
     }
 }
 /**
  * @param RedBeanModel $model
  * @param string $relation
  * @return Array of models
  */
 public static function resolveDerivedModels(RedBeanModel $model, $relation)
 {
     assert('is_string($relation)');
     $modelClassName = $model->getDerivedRelationModelClassName($relation);
     $inferredRelationName = $model->getDerivedRelationViaCastedUpModelOpposingRelationName($relation);
     return WorkflowUtil::getModelsFilteredByInferredModel($modelClassName, $inferredRelationName, (int) $model->getClassId('Item'));
 }
 /**
  * Notice the use of $modelToForgetCache. This was needed to avoid a caching issue with the following example.
  * If an opportunity fires, and a related account's opportunity is created. This new opportunity had a cached
  * model for account that was null.  So this is fixed by forgetting the new model after it is added to the account.
  * @throws FailedToSaveModelException
  * @throws NotSupportedException
  */
 protected function processCreateRelatedAction()
 {
     if ($this->action->relationFilter != ActionForWorkflowForm::RELATION_FILTER_ALL) {
         throw new NotSupportedException();
     }
     $modelClassName = get_class($this->triggeredModel);
     if ($this->triggeredModel->isADerivedRelationViaCastedUpModel($this->action->relation) && $this->triggeredModel->getDerivedRelationType($this->action->relation) == RedBeanModel::MANY_MANY) {
         foreach (WorkflowUtil::resolveDerivedModels($this->triggeredModel, $this->action->relation) as $relatedModel) {
             if ($this->resolveCreateModel($relatedModel, $this->action->relatedModelRelation)) {
                 $saved = $relatedModel->save();
                 if (!$saved) {
                     throw new FailedToSaveModelException();
                 }
             }
         }
     } elseif ($this->triggeredModel->getInferredRelationModelClassNamesForRelation(ModelRelationsAndAttributesToWorkflowAdapter::resolveRealAttributeName($this->action->relation)) != null) {
         foreach (WorkflowUtil::getInferredModelsByAtrributeAndModel($this->action->relation, $this->triggeredModel) as $relatedModel) {
             if ($this->resolveCreateModel($relatedModel, $this->action->relatedModelRelation)) {
                 $saved = $relatedModel->save();
                 if (!$saved) {
                     throw new FailedToSaveModelException();
                 }
             }
         }
     } elseif ($this->triggeredModel->{$this->action->relation} instanceof RedBeanMutableRelatedModels) {
         foreach ($this->triggeredModel->{$this->action->relation} as $relatedModel) {
             if ($this->resolveCreateModel($relatedModel, $this->action->relatedModelRelation)) {
                 $saved = $relatedModel->save();
                 if (!$saved) {
                     throw new FailedToSaveModelException();
                 }
             }
         }
     } elseif ($modelClassName::isRelationTypeAHasOneVariant($this->action->relation) && !$modelClassName::isOwnedRelation($this->action->relation)) {
         $relatedModel = $this->triggeredModel->{$this->action->relation};
         $modelToForgetCache = null;
         if ($this->resolveCreateModel($relatedModel, $this->action->relatedModelRelation, $modelToForgetCache)) {
             $saved = $relatedModel->save();
             if (!$saved) {
                 throw new FailedToSaveModelException();
             }
             if ($modelToForgetCache instanceof RedBeanModel) {
                 $modelToForgetCache->forget();
             }
         }
     } else {
         throw new NotSupportedException();
     }
 }
 /**
  * @param RedBeanModel $model
  * @param User $triggeredByUser
  * @return array
  * @throws NotSupportedException
  */
 public function makeRecipients(RedBeanModel $model, User $triggeredByUser)
 {
     $modelClassName = $this->modelClassName;
     $recipients = array();
     if ($model->isADerivedRelationViaCastedUpModel($this->relation) && $model->getDerivedRelationType($this->relation) == RedBeanModel::MANY_MANY) {
         foreach (WorkflowUtil::resolveDerivedModels($model, $this->relation) as $resolvedModel) {
             $recipients = self::resolveRecipientsAsUniquePeople($recipients, $this->resolveRecipients($resolvedModel));
         }
     } elseif ($modelClassName::getInferredRelationModelClassNamesForRelation(ModelRelationsAndAttributesToWorkflowAdapter::resolveRealAttributeName($this->relation)) != null) {
         foreach (WorkflowUtil::getInferredModelsByAtrributeAndModel($this->relation, $model) as $resolvedModel) {
             $recipients = self::resolveRecipientsAsUniquePeople($recipients, $this->resolveRecipients($resolvedModel));
         }
     } elseif ($model->{$this->relation} instanceof RedBeanMutableRelatedModels) {
         if (!$this->relationFilter == self::RELATION_FILTER_ALL) {
             throw new NotSupportedException();
         }
         foreach ($model->{$this->relation} as $resolvedModel) {
             $recipients = self::resolveRecipientsAsUniquePeople($recipients, $this->resolveRecipients($resolvedModel));
         }
     } elseif ($modelClassName::isRelationTypeAHasOneVariant($this->relation)) {
         if ($model->{$this->relation}->id > 0) {
             $recipients = $this->resolveRecipients($model->{$this->relation});
         }
     } else {
         throw new NotSupportedException();
     }
     return $recipients;
 }
 public function actionGetAvailableAttributesForTimeTrigger($type, $id = null, $isBeingCopied = false)
 {
     $postData = PostUtil::getData();
     $savedWorkflow = null;
     $workflow = null;
     $this->resolveSavedWorkflowAndWorkflowByPostData($postData, $savedWorkflow, $workflow, $type, $id, (bool) $isBeingCopied);
     $moduleClassName = $workflow->getModuleClassName();
     $modelClassName = $moduleClassName::getPrimaryModelName();
     $dataAndLabels = WorkflowUtil::resolveDataAndLabelsForTimeTriggerAvailableAttributes($moduleClassName, $modelClassName, $workflow->getType());
     echo CJSON::encode($dataAndLabels);
 }
 /**
  * @param Workflow $workflow
  * @param RedBeanModel $model
  * @throws FailedToSaveModelException
  */
 protected static function processToByTimeWorkflowInQueue(Workflow $workflow, RedBeanModel $model)
 {
     assert('$workflow->getId() > 0');
     try {
         $byTimeWorkflowInQueue = ByTimeWorkflowInQueue::resolveByWorkflowIdAndModel(SavedWorkflow::getById((int) $workflow->getId()), $model);
         $byTimeWorkflowInQueue->processDateTime = static::resolveProcessDateTimeByWorkflowAndModel($workflow, $model);
         $saved = $byTimeWorkflowInQueue->save();
         if (!$saved) {
             throw new FailedToSaveModelException();
         }
     } catch (ValueForProcessDateTimeIsNullException $e) {
         //For now just log this exception. If this exception is thrown it means a date or dateTime
         //somehow was set to empty, so we can't properly process this.
         WorkflowUtil::handleProcessingException($e, 'application.modules.workflows.utils.SavedWorkflowsUtil.processToByTimeWorkflowInQueue');
     }
 }
 /**
  * Process any workflow actions that are updates to the passed in model during the processing of any
  * ByTimeWorkflowQueue models. @see ByTimeWorkflowInQueueJob.
  * @param Workflow $workflow
  * @param RedBeanModel $model
  * @param User $triggeredByUser
  * @throws FailedToSaveModelException
  */
 public static function processOnByTimeWorkflowInQueueJob(Workflow $workflow, RedBeanModel $model, User $triggeredByUser)
 {
     foreach ($workflow->getActions() as $action) {
         try {
             $helper = new WorkflowActionProcessingHelper((int) $workflow->getId(), $workflow->getName(), $action, $model, $triggeredByUser, false);
             $helper->processUpdateSelfAction();
             $helper->processNonUpdateSelfAction();
         } catch (Exception $e) {
             WorkflowUtil::handleProcessingException($e, 'application.modules.workflows.utils.WorkflowActionsUtil.processOnByTimeWorkflowInQueueJob');
         }
     }
 }
 /**
  * @return array
  */
 public function getSendAfterDurationValuesAndLabels()
 {
     $data = array();
     WorkflowUtil::resolveSendAfterDurationData($data);
     return $data;
 }
 /**
  * @param bool $includePositiveDuration
  * @param bool $includeNegativeDuration
  * @param bool $isTimeBased
  * @param bool $includeHours
  * @return array
  * @throws NotSupportedException
  */
 protected function makeDurationValuesAndLabels($includePositiveDuration = false, $includeNegativeDuration = false, $isTimeBased = false, $includeHours = true)
 {
     assert('is_bool($includePositiveDuration)');
     assert('is_bool($includeNegativeDuration)');
     assert('is_bool($isTimeBased)');
     assert('is_bool($includeHours)');
     $data = array();
     if ($includeNegativeDuration) {
         if ($isTimeBased) {
             WorkflowUtil::resolveNegativeDurationAsDistanceFromPointData($data, $includeHours);
         } else {
             throw new NotSupportedException();
         }
     }
     if ($includePositiveDuration) {
         if ($isTimeBased) {
             WorkflowUtil::resolvePositiveDurationAsDistanceFromPointData($data, $includeHours);
         } else {
             WorkflowUtil::resolvePositiveDurationData($data, $includeHours);
         }
     }
     return $data;
 }