Валидация дескриптора

@return void
@throws InvalidWorkflowDescriptorException
776271
public function validate()
    {
        $commonActions = $this->getCommonActions();
        $actions = $this->getActions();
        $hasActions = $this->hasActions;

        if ($hasActions && 0 === count($commonActions) && 0 === $actions->count()) {
            $stepName = (string)$this->getName();
            $errMsg = sprintf('Шаг %s должен содержать одни действие или одно общее действие', $stepName);
            throw new InvalidWorkflowDescriptorException($errMsg);
        }

        if (-1 === $this->getId()) {
            $errMsg = 'В качестве id шага нельзя использовать -1, так как это зарезериврованное значение';
            throw new InvalidWorkflowDescriptorException($errMsg);
        }

        $preFunctions = $this->getPreFunctions();
        $postFunctions = $this->getPostFunctions();
        $actions = $this->getActions();
        $permissions = $this->getPermissions();

        ValidationHelper::validate($preFunctions);
        ValidationHelper::validate($postFunctions);
        ValidationHelper::validate($actions);
        ValidationHelper::validate($permissions);

        $workflowDescriptor = $this->getParent();
        if (!$workflowDescriptor instanceof WorkflowDescriptor) {
            $errMsg = sprintf('Родительский элемент для шага должен реализовывать %s', WorkflowDescriptor::class);
            throw new InvalidWorkflowDescriptorException($errMsg);
        }
        foreach ($commonActions as $actionId) {
            try {
                $commonActionReference = $workflowDescriptor->getCommonAction($actionId);

                if (null === $commonActionReference) {
                    $stepName = (string)$this->getName();
                    $errMsg = sprintf('Common-action %s указанное для шага %s не существует', $actionId, $stepName);
                    throw new InvalidWorkflowDescriptorException($errMsg);
                }
            } catch (\Exception $e) {
                $actionIdStr = (string)$actionId;
                $errMsg = sprintf('Некорректный id для common-action: id %s', $actionIdStr);
                throw  new InvalidWorkflowDescriptorException($errMsg, $e->getCode(), $e);
            }
        }
    }
56309
public function getWorkflow($name)
    {
        $workflow = $this->factory->getWorkflow($name);

        if (!$workflow instanceof WorkflowDescriptor) {
            $errMsg = 'Unknown workflow name';
            throw new Exception\InvalidWorkflowDescriptorException($errMsg);
        }

        return $workflow;
    }
795267
function removeThis( $remove_childs = false )
    {
        $db = eZDB::instance();
        $db->begin();
        if ( is_array( $remove_childs ) )
        {
            foreach( $remove_childs as $event )
            {
                $event->remove();
            }
        }
        else if ( $remove_childs )
        {
            eZPersistentObject::removeObject( eZWorkflowEvent::definition(),
                                              array( "workflow_id" => $this->ID,
                                                     "version" => $this->Version ) );
        }

        $this->remove();
        $db->commit();
    }
443169
protected function execute(InputInterface $input, OutputInterface $output)
    {
        if (!$input->getOption('delete') && !$input->getOption('info')) {
            throw new \InvalidArgumentException('You must specify whether you want to --delete or --info the specified workflow.');
        }

        $workflowService = $this->getWorkflowService();
        $workflowNameOrPath = $input->getArgument('workflow');

        if ($input->getOption('info')) {
            $output->writeln('');

            $workflow = $workflowService->getWorkflow($workflowNameOrPath);
            if ($workflow == null) {
                throw new \InvalidArgumentException(sprintf('The workflow "%s" does not exist in the database table.', $workflowNameOrPath));
            }

            switch ($workflow->status) {
                case Migration::STATUS_DONE:
                    $status = '<info>executed</info>';
                    break;
                case Migration::STATUS_STARTED:
                    $status = '<comment>execution started</comment>';
                    break;
                case Migration::STATUS_TODO:
                    // bold to-migrate!
                    $status = '<error>not executed</error>';
                    break;
                case Migration::STATUS_SKIPPED:
                    $status = '<comment>skipped</comment>';
                    break;
                case Migration::STATUS_PARTIALLY_DONE:
                    $status = '<comment>partially executed</comment>';
                    break;
                case Migration::STATUS_SUSPENDED:
                    $status = '<comment>suspended</comment>';
                    break;
                case Migration::STATUS_FAILED:
                    $status = '<error>failed</error>';
                    break;
            }

            $output->writeln('<info>Workflow: ' . $workflow->name . '</info>');
            $output->writeln('Status: ' . $status);
            $output->writeln('Executed on: <info>' . ($workflow->executionDate != null ? date("Y-m-d H:i:s", $workflow->executionDate) : '--'). '</info>');
            $output->writeln('Execution notes: <info>' . $workflow->executionError . '</info>');
            $output->writeln('Signal: <info>' . $workflow->signalName . '</info>');

            if ($workflow->status == Migration::STATUS_SUSPENDED) {
                /// @todo decode the suspension context: date, step, ...
            }

            $output->writeln('Definition path: <info>' . $workflow->path . '</info>');
            $output->writeln('Definition md5: <info>' . $workflow->md5 . '</info>');

            if ($workflow->path != '') {
                // q: what if we have a loader which does not work with is_file? We could probably remove this check...
                if (is_file($workflow->path)) {
                    try {
                        $workflowDefinitionCollection = $workflowService->getWorkflowsDefinitions(array($workflow->path));
                        if (count($workflowDefinitionCollection)) {
                            $workflowDefinition = reset($workflowDefinitionCollection);
                            $workflowDefinition = $workflowService->parseWorkflowDefinition($workflowDefinition);

                            if ($workflowDefinition->status != MigrationDefinition::STATUS_PARSED) {
                                $output->writeln('Definition error: <error>' . $workflowDefinition->parsingError . '</error>');
                            }

                            if (md5($workflowDefinition->rawDefinition) != $workflow->md5) {
                                $output->writeln('Notes: <comment>The workflow definition file has now a different checksum</comment>');
                            }

                            $output->writeln('Switch User: <info>' . (($workflowDefinition->runAs === false) ? '-' : $workflowDefinition->runAs) . '</info>');
                            $output->writeln('Use transaction: <info>' . ($workflowDefinition->useTransaction ? 'Y' : 'N') . '</info>');

                        } else {
                            $output->writeln('Definition error: <error>The workflow definition file can not be loaded</error>');
                        }
                    } catch (\Exception $e) {
                        /// @todo one day we should be able to limit the kind of exceptions we have to catch here...
                        $output->writeln('Definition parsing error: <error>' . $e->getMessage() . '</error>');
                    }
                } else {
                    $output->writeln('Definition error: <error>The workflow definition file can not be found any more</error>');
                }
            }

            $output->writeln('');
            return;
        }

        // ask user for confirmation to make changes
        if ($input->isInteractive() && !$input->getOption('no-interaction')) {
            $dialog = $this->getHelperSet()->get('dialog');
            if (!$dialog->askConfirmation(
                $output,
                '<question>Careful, the database will be modified. Do you want to continue Y/N ?</question>',
                false
            )
            ) {
                $output->writeln('<error>Workflow change cancelled!</error>');
                return 0;
            }
        }

        if ($input->getOption('delete')) {
            $workflow = $workflowService->getWorkflow($workflowNameOrPath);
            if ($workflow == null) {
                throw new \InvalidArgumentException(sprintf('The workflow "%s" does not exist in the database table.', $workflowNameOrPath));
            }

            $workflowService->deleteWorkflow($workflow);

            return;
        }
    }
792442
public function edit()
    {
        if (!userHasPermission('admin:invoice:customer:edit')) {
            unauthorised();
        }

        $oCustomerModel = Factory::model('Customer', 'nails/module-invoice');
        $oUri           = Factory::service('Uri');

        $itemId             = (int) $oUri->segment(5);
        $this->data['item'] = $oCustomerModel->getById(
            $itemId,
            ['expand' => $oCustomerModel::EXPAND_ALL]
        );

        if (empty($this->data['item'])) {
            show404();
        }

        // --------------------------------------------------------------------------

        $oInput = Factory::service('Input');
        if ($oInput->post()) {

            try {

                $this->formValidation();

                if (!$oCustomerModel->update($itemId, $this->prepPostData())) {
                    throw new NailsException('Failed to update item. ' . $oCustomerModel->lastError(), 1);
                }

                $oSession = Factory::service('Session', 'nails/module-auth');
                $oSession->setFlashData('success', 'Item updated successfully.');
                redirect('admin/invoice/customer');

            } catch (\Exception $e) {
                $this->data['error'] = $e->getMessage();
            }
        }

        // --------------------------------------------------------------------------

        $this->data['page']->title = 'Edit customer';
        Helper::loadView('edit');
    }
1170650
protected function loadWorkflow(WorkflowConfig $c, $validate = true)
    {
        $validate = (boolean)$validate;
        try {
            $c->descriptor = WorkflowLoader::load($c->url, $validate);
        } catch (\Exception $e) {
            $errMsg = "Некорректный дескрипторв workflow: {$c->url}";
            throw new FactoryException($errMsg, $e->getCode(), $e);
        }
    }
905149
public function validate()
    {
        $preFunctions = $this->getPreFunctions();
        $postFunctions = $this->getPostFunctions();
        $validators = $this->getValidators();

        ValidationHelper::validate($preFunctions);
        ValidationHelper::validate($postFunctions);
        ValidationHelper::validate($validators);

        $split = $this->getSplit();
        $join = $this->getJoin();

        $parent = $this->getParent();
        if ((null === $split) && (null === $join) && !($parent instanceof ActionDescriptor && ($parent->isFinish()))) {
            $errMsg = '';
            $id = (integer)$this->getId();
            if (is_numeric($id)) {
                $errMsg .= sprintf('#%s:', $id);
            }
            $errMsg .= 'Если не указано значение атрибутов split или join, необходимо указать';

            if (!$this->hasStep) {
                $errMsg .= ' id следующего шага';
                throw new InvalidWorkflowDescriptorException($errMsg);
            }

            $status = $this->getStatus();
            if (!$status) {
                $errMsg .= ' статус';
                throw new InvalidWorkflowDescriptorException($errMsg);
            }
        }
    }
731085
public function writeXml(DOMDocument $dom = null)
    {
        if (null === $dom) {
            $errMsg = 'Не передан DOMDocument';
            throw new InvalidWriteWorkflowException($errMsg);
        }
        $descriptor = $dom->createElement('join');

        if (!$this->hasId()) {
            $errMsg = 'Отсутствует атрибут id';
            throw new InvalidDescriptorException($errMsg);
        }
        $id =  $this->getId();
        $descriptor->setAttribute('id', $id);

        $conditions = $this->getConditions();
        foreach ($conditions as $condition) {
            $conditionElement = $condition->writeXml($dom);
            if (null !== $conditionElement) {
                $descriptor->appendChild($conditionElement);
            }
        }

        $result = $this->getResult();

        if (null !== $result) {
            $resultElement = $result->writeXml($dom);
            $descriptor->appendChild($resultElement);
        }

        return $descriptor;
    }
737214
public function onAfterDelete()
    {
        parent::onAfterDelete();
        $wfActionInstances = WorkflowActionInstance::get()
            /** @skipUpgrade */
            ->leftJoin('WorkflowInstance', '"WorkflowInstance"."ID" = "WorkflowActionInstance"."WorkflowID"')
            ->where(sprintf('"BaseActionID" = %d AND ("WorkflowStatus" IN (\'Active\',\'Paused\'))', $this->ID));
        foreach ($wfActionInstances as $wfActionInstance) {
            $wfInstances = WorkflowInstance::get()->filter('CurrentActionID', $wfActionInstance->ID);
            foreach ($wfInstances as $wfInstance) {
                $wfInstance->Groups()->removeAll();
                $wfInstance->Users()->removeAll();
                $wfInstance->delete();
            }
            $wfActionInstance->delete();
        }
        // Delete outbound transitions
        $transitions = WorkflowTransition::get()->filter('ActionID', $this->ID);
        foreach ($transitions as $transition) {
            $transition->Groups()->removeAll();
            $transition->Users()->removeAll();
            $transition->delete();
        }
    }
11967
public function writeXml(DOMDocument $dom = null)
    {
        if (null === $dom) {
            $errMsg = 'Не передан DOMDocument';
            throw new InvalidWriteWorkflowException($errMsg);
        }
        $descriptor = $dom->createElement('step');

        if (!$this->hasId()) {
            $errMsg = 'Отсутствует атрибут id';
            throw new InvalidDescriptorException($errMsg);
        }
        $id = $this->getId();
        $descriptor->setAttribute('id', $id);

        $name = (string)$this->getName();
        $name = trim($name);
        if (strlen($name) > 0) {
            $nameEncode = XmlUtil::encode($name);
            $descriptor->setAttribute('name', $nameEncode);
        }


        $metaAttributes = $this->getMetaAttributes();
        $baseMeta = $dom->createElement('meta');
        foreach ($metaAttributes as $metaAttributeName => $metaAttributeValue) {
            $metaAttributeNameEncode = XmlUtil::encode($metaAttributeName);
            $metaAttributeValueEnEncode = XmlUtil::encode($metaAttributeValue);

            $metaElement = clone $baseMeta;
            $metaElement->setAttribute('name', $metaAttributeNameEncode);
            $metaValueElement = $dom->createTextNode($metaAttributeValueEnEncode);
            $metaElement->appendChild($metaValueElement);

            $descriptor->appendChild($metaElement);
        }


        $preFunctions = $this->getPreFunctions();
        if ($preFunctions->count() > 0) {
            $preFunctionsElement = $dom->createElement('pre-functions');
            foreach ($preFunctions as $function) {
                $functionElement = $function->writeXml($dom);
                $preFunctionsElement->appendChild($functionElement);
            }

            $descriptor->appendChild($preFunctionsElement);
        }


        $permissions = $this->getPermissions();
        if ($permissions->count() > 0) {
            $permissionsElement = $dom->createElement('external-permissions');
            foreach ($permissions as $permission) {
                $permissionElement = $permission->writeXml($dom);
                $permissionsElement->appendChild($permissionElement);
            }

            $descriptor->appendChild($permissionsElement);
        }

        $actions = $this->getActions();
        $commonActions = $this->getCommonActions();

        if ($actions->count() > 0 || count($commonActions) > 0) {
            $actionsElement = $dom->createElement('actions');

            $commonActionElementBase = $dom->createElement('common-action');
            foreach ($commonActions as $commonActionId) {
                $commonActionElement = clone $commonActionElementBase;
                $commonActionElement->setAttribute('id', $commonActionId);

                $actionsElement->appendChild($commonActionElement);
            }

            foreach ($actions as $action) {
                if (!$action->isCommon()) {
                    $actionElement = $action->writeXml($dom);
                    $actionsElement->appendChild($actionElement);
                }
            }

            $descriptor->appendChild($actionsElement);
        }

        $postFunctions = $this->getPostFunctions();
        if ($postFunctions->count() > 0) {
            $postFunctionsElement = $dom->createElement('post-functions');
            foreach ($postFunctions as $function) {
                $functionElement = $function->writeXml($dom);
                $postFunctionsElement->appendChild($functionElement);
            }

            $descriptor->appendChild($postFunctionsElement);
        }


        return $descriptor;
    }
1259993
public function writeXml(DOMDocument $dom = null)
    {
        if (null === $dom) {
            $errMsg = 'Не передан DOMDocument';
            throw new InvalidWriteWorkflowException($errMsg);
        }
        $conditions = $this->getConditionsDescriptor();

        $list = $conditions->getConditions();

        if (0 === $list->count()) {
            return null;
        }

        $descriptor = $dom->createElement('restrict-to');
        try {
            $conditionsDescriptor = $conditions->writeXml($dom);
        } catch (\Exception $e) {
            $errMsg  = 'Ошибка сохранения workflow';
            throw new InvalidWriteWorkflowException($errMsg, $e->getCode(), $e);
        }

        $descriptor->appendChild($conditionsDescriptor);

        return $descriptor;
    }
1280754
public function saveWorkflowDescriptor($workflowName, WorkflowDescriptor $descriptor, $replace)
    {
        $success = $this->getConfiguration()->saveWorkflow($workflowName, $descriptor, $replace);

        return $success;
    }
672504
public function main(){
        
        if(is_null($this->getDomain())){
            throw new \BuildException('the domain property is required');
        }

        if(is_null($this->getName())){
            throw new \BuildException('the name property is required');
        }

        if(is_null($this->getVersion())){
            throw new \BuildException('the version property is required');
        }

        if(is_null($this->getTasklist())){
            throw new \BuildException('the tasklist property is required');
        }

        try {
            $workflow = $this->getService()->describeWorkflowType([
                'domain' => $this->getDomain(),
                'workflowType' => [
                    'name' => $this->getName(),
                    'version' => $this->getVersion()
                ]
            ]);

            if ($workflow->get('typeInfo')['status'] != 'REGISTERED') {
                throw new \BuildException('the workflow "' . $this->getName() . '" is no more available');
            }

            $this->log('The workflow "' . $this->getName() . '" already exists');
        } catch (SwfException $e) {
            $this->log('Creating "' . $this->getName() . '" v.' . $this->getVersion() . ' workflow');

            $params = [
                'domain' => $this->getDomain(),
                'name' => $this->getName(),
                'version' => $this->getVersion(),
                'description' => $this->getDescription(),
                'defaultTaskStartToCloseTimeout' => $this->getTaskStartToCloseTimeout() ?: 'NONE',
                'defaultExecutionStartToCloseTimeout' => $this->getExecutionStartToCloseTimeout() ?: 'NONE',
                'defaultTaskList' => [
                    'name' => $this->getTasklist()
                ]
            ];

            if ($this->getChildPolicy()) {
                $params['defaultChildPolicy'] = $this->getChildPolicy();
            }

            $this->getService()->registerWorkflowType($params);

            $this->log('"' . $this->getName() . '" v.' . $this->getVersion() . ' workflow successfully created');
        }
    }
708916
public function init()
    {
        parent::init();

        if (empty($this->id)) {
            $this->id = $this->getId();
        }

        if ($this->modelClass == null) {
            throw new InvalidConfigException('Param "modelClass" must be contain model name');
        }

        if (null == $this->behaviorName) {
            throw new InvalidConfigException("No 'behaviorName' supplied on action initialization.");
        }

        if (null == $this->advancedUpdateRoute && ($controller = Yii::$app->controller)) {
            $this->advancedUpdateRoute = "{$controller->id}/update";
        }

        if ($this->formFieldsCallable == null) {
            $this->formFieldsCallable = function ($form, $model) {
                /** @var ActiveForm $form */
                echo $form->field($model, $this->nameAttribute);
            };
        }

        /** @var ActiveRecord|TreeInterface $model */
        $model = $this->modelClass;

        /** @var ActiveRecord[]|TreeInterface[] $rootNodes */
        $rootNodes = $model::find()->roots()->all();

        if (!empty($rootNodes[0])) {
            /** @var ActiveRecord|TreeInterface $items */
            $items = $rootNodes[0]->populateTree();
            $this->_items = $this->prepareItems($items);
        }
    }
1303393
public function writeXml(DOMDocument $dom = null)
    {
        if (null === $dom) {
            $errMsg = 'Не передан DOMDocument';
            throw new InvalidWriteWorkflowException($errMsg);
        }
        $descriptor = $dom->createElement('register');


        if ($this->hasId()) {
            $id = $this->getId();
            $descriptor->setAttribute('id', $id);
        }

        $variableName = $this->getVariableName();
        if (null === $variableName) {
            $errMsg = 'Некорректное значение для атрибута variable-name';
            throw new InvalidDescriptorException($errMsg);
        }
        $descriptor->setAttribute('variable-name', $variableName);

        $type = $this->getType();
        if (null === $type) {
            $errMsg = 'Некорректное значение для атрибута type';
            throw new InvalidDescriptorException($errMsg);
        }

        $descriptor->setAttribute('type', $type);

        $this->writeArgs($descriptor);

        return $descriptor;
    }
1095925
public function onCheckRunWorkflowHandler(WorkflowDispatchEventInterface $e)
    {
        $metadata = $e->getMetadata();
        if (!$metadata->getFlagHasConditions()) {
            return null;
        }

        try {
            $conditions = $metadata->getConditions();

            $validatorManager = $this->getValidatorManager();

            /** @var ValidatorChain $validatorChains */
            $validatorChains = $validatorManager->get(ValidatorChain::class);
        } catch (\Exception $e) {
            throw new Exception\PrepareDataException($e->getMessage(), $e->getCode(), $e);
        }



        $mvcEvent = $e->getMvcEvent();
        $controller = $mvcEvent->getTarget();
        if (!$controller instanceof AbstractController) {
            $controller = null;
        }


        foreach ($conditions as $condition) {
            try {
                $type = $condition->getType();
                $handler = $condition->getHandler();
                switch ($type) {
                    case 'method': {
                        if (null === $controller) {
                            $errMsg = 'Controller not specified';
                            throw new Exception\CheckRunWorkflowEventException($errMsg);
                        }
                        $callback = [$controller, $handler];

                        /** @var ValidatorInterface $callbackValidator */
                        $callbackValidator = $validatorManager->get('callback', $callback);

                        $validatorChains->attach($callbackValidator);

                        break;
                    }
                    case 'service': {
                        $validatorParams = $condition->getParams();

                        /** @var ValidatorInterface $validator */
                        $validator = $validatorManager->get($handler, $validatorParams);

                        $validatorChains->attach($validator);

                        break;
                    }
                    default: {
                        $errMsg = sprintf('Preparing data for Workflow will fail. Unknown handler type %s.', $type);
                        throw new Exception\PrepareDataException($errMsg);
                    }
                }
            } catch (\Exception $e) {
                throw new Exception\PrepareDataException($e->getMessage(), $e->getCode(), $e);
            }
        }

        return $validatorChains->isValid($e);
    }
514536
public function updateEditForm(Form $form)
    {
        Requirements::javascript('symbiote/silverstripe-advancedworkflow:client/dist/js/advancedworkflow.js');
        /** @var WorkflowService $service */
        $service = singleton(WorkflowService::class);
        /** @var DataObject|WorkflowApplicable $record */
        $record = $form->getRecord();
        $active = $service->getWorkflowFor($record);

        if ($active) {
            $fields = $form->Fields();
            $current = $active->CurrentAction();
            $wfFields = $active->getWorkflowFields();

            $allowed = array_keys($wfFields->saveableFields());
            $data = [];
            foreach ($allowed as $fieldName) {
                $data[$fieldName] = $current->$fieldName;
            }

            $fields->findOrMakeTab(
                'Root.WorkflowActions',
                _t('Workflow.WorkflowActionsTabTitle', 'Workflow Actions')
            );
            $fields->addFieldsToTab('Root.WorkflowActions', $wfFields);

            $form->loadDataFrom($data);

            // Set the form to readonly if the current user doesn't have permission to edit the record, and/or it
            // is in a state that requires review
            if (!$record->canEditWorkflow() && !$fields->isReadonly()) {
                $fields->makeReadonly();
            }

            $this->owner->extend('updateWorkflowEditForm', $form);
        }
    }