/** * * Performs an action * * @param mixed $actionName * @param array $formData * @throws \Exception */ public function performAction($actionName, $formData = []) { //store the current action data $this->setActionData($formData); \Pimcore::getEventManager()->trigger("workflowmanagement.preAction", $this, ['actionName' => $actionName]); //refresh the local copy after the event $formData = $this->getActionData(); $actionConfig = $this->workflow->getActionConfig($actionName, $this->getElementStatus()); $additional = $formData['additional']; //setup event listeners $this->registerActionEvents($actionConfig); //setup an array to hold the additional data that is not saved via a setterFn $actionNoteData = []; //process each field in the additional fields configuration if (isset($actionConfig['additionalFields']) && is_array($actionConfig['additionalFields'])) { foreach ($actionConfig['additionalFields'] as $additionalFieldConfig) { /** * Additional Field example * [ 'name' => 'dateLastContacted', 'fieldType' => 'date', 'label' => 'Date of Conversation', 'required' => true, 'setterFn' => '' ] */ $fieldName = $additionalFieldConfig['name']; //check required if ($additionalFieldConfig['required'] && empty($additional[$fieldName])) { throw new \Exception("Workflow::performAction, fieldname [{$fieldName}] required for action [{$actionName}]"); } //work out whether or not to set the value directly to the object or to add it to the note data if (!empty($additionalFieldConfig['setterFn'])) { $setter = $additionalFieldConfig['setterFn']; try { //todo check here that the setter is being called on an Object //TODO check that the field has a fieldType, (i.e if a workflow config has getter then the field should only be a pimcore tag and therefore 'fieldType' rather than 'type'. //otherwise we could be erroneously setting pimcore fields $additional[$fieldName] = Workflow\Service::getDataFromEditmode($additional[$fieldName], $additionalFieldConfig['fieldType']); $this->element->{$setter}($additional[$fieldName]); } catch (\Exception $e) { Logger::error($e->getMessage()); throw new \Exception("Workflow::performAction, cannot set fieldname [{$fieldName}] using setter [{$setter}] in action [{$actionName}]"); } } else { $actionNoteData[] = Workflow\Service::createNoteData($additionalFieldConfig, $additional[$fieldName]); } } } //save the old state and status in the form so that we can reference it later $formData['oldState'] = $this->getElementState(); $formData['oldStatus'] = $this->getElementStatus(); if ($this->element instanceof Concrete || $this->element instanceof Document\PageSnippet) { if (!$this->workflow->getAllowUnpublished() || in_array($this->getElementStatus(), $this->workflow->getPublishedStatuses())) { $this->element->setPublished(true); if ($this->element instanceof Concrete) { $this->element->setOmitMandatoryCheck(false); } $task = 'publish'; } else { $this->element->setPublished(false); if ($this->element instanceof Concrete) { $this->element->setOmitMandatoryCheck(true); } $task = 'unpublish'; } } else { //all other elements do not support published or unpublished $task = "publish"; } try { $response = \Pimcore::getEventManager()->trigger("workflowmanagement.action.before", $this, ['actionConfig' => $actionConfig, 'data' => $formData]); //todo add some support to stop the action given the result from the event $this->element->setUserModification($this->user->getId()); if ($task === "publish" && $this->element->isAllowed("publish") || $task === "unpublish" && $this->element->isAllowed("unpublish")) { $this->element->save(); } elseif ($this->element instanceof Concrete || $this->element instanceof Document\PageSnippet) { $this->element->saveVersion(); } else { throw new \Exception("Operation not allowed for this element"); } //transition the element $this->setElementState($formData['newState']); $this->setElementStatus($formData['newStatus']); // record a note against the object to show the transition $decorator = new Workflow\Decorator($this->workflow); $description = $formData['notes']; // create a note for this action $note = Workflow\Service::createActionNote($this->element, $decorator->getNoteType($actionName, $formData), $decorator->getNoteTitle($actionName, $formData), $description, $actionNoteData); //notify users if (isset($actionConfig['notificationUsers']) && is_array($actionConfig['notificationUsers'])) { Workflow\Service::sendEmailNotification($actionConfig['notificationUsers'], $note); } \Pimcore::getEventManager()->trigger("workflowmanagement.action.success", $this, ['actionConfig' => $actionConfig, 'data' => $formData]); } catch (\Exception $e) { \Pimcore::getEventManager()->trigger("workflowmanagement.action.failure", $this, ['actionConfig' => $actionConfig, 'data' => $formData, 'exception' => $e]); } $this->unregisterActionEvents(); \Pimcore::getEventManager()->trigger("workflowmanagement.postAction", $this, ['actionName' => $actionName]); }