├── sonar-project.properties ├── src └── ProcessMaker │ └── Nayra │ ├── Contracts │ ├── Bpmn │ │ ├── ParallelGatewayInterface.php │ │ ├── EndEventInterface.php │ │ ├── PropertyInterface.php │ │ ├── CancelInterface.php │ │ ├── IntermediateThrowEventInterface.php │ │ ├── DataOutputAssociationInterface.php │ │ ├── CorrelationKeyInterface.php │ │ ├── TerminateEventDefinitionInterface.php │ │ ├── ConditionedTransitionInterface.php │ │ ├── FlowCollectionInterface.php │ │ ├── ShapeCollectionInterface.php │ │ ├── ExclusiveGatewayInterface.php │ │ ├── InclusiveGatewayInterface.php │ │ ├── ProcessCollectionInterface.php │ │ ├── ArtifactCollectionInterface.php │ │ ├── DiagramCollectionInterface.php │ │ ├── DataStoreCollectionInterface.php │ │ ├── ItemAwareElementInterface.php │ │ ├── DataInputAssociationInterface.php │ │ ├── EventBasedGatewayInterface.php │ │ ├── DataOutputInterface.php │ │ ├── AssignmentInterface.php │ │ ├── FlowElementInterface.php │ │ ├── DataInputInterface.php │ │ ├── ErrorInterface.php │ │ ├── DatePeriodInterface.php │ │ ├── EventCollectionInterface.php │ │ ├── GatewayCollectionInterface.php │ │ ├── ActivityCollectionInterface.php │ │ ├── CorrelationPropertyRetrievalExpressionInterface.php │ │ ├── MessageListenerInterface.php │ │ ├── TraversableInterface.php │ │ ├── CorrelationPropertyInterface.php │ │ ├── ConnectionNodeInterface.php │ │ ├── ConditionalEventDefinitionInterface.php │ │ ├── SignalInterface.php │ │ ├── OutputSetInterface.php │ │ ├── InputSetInterface.php │ │ ├── CallActivityInterface.php │ │ ├── CallableElementInterface.php │ │ ├── LaneSetInterface.php │ │ ├── ServiceTaskInterface.php │ │ ├── StartEventInterface.php │ │ ├── ComplexBehaviorDefinitionInterface.php │ │ ├── ConnectionInterface.php │ │ ├── IntermediateCatchEventInterface.php │ │ ├── DataAssociationInterface.php │ │ ├── ObservableInterface.php │ │ ├── ItemDefinitionInterface.php │ │ ├── SignalEventDefinitionInterface.php │ │ ├── ArtifactInterface.php │ │ ├── FormalExpressionInterface.php │ │ ├── MessageInterface.php │ │ ├── ScriptTaskInterface.php │ │ ├── ParticipantInterface.php │ │ ├── ThrowEventInterface.php │ │ ├── DiagramInterface.php │ │ ├── ErrorEventDefinitionInterface.php │ │ ├── OperationInterface.php │ │ ├── LaneInterface.php │ │ ├── BoundaryEventInterface.php │ │ ├── StandardLoopCharacteristicsInterface.php │ │ ├── ShapeInterface.php │ │ ├── InputOutputSpecificationInterface.php │ │ ├── ServiceInterface.php │ │ ├── EventInterface.php │ │ ├── CollaborationInterface.php │ │ ├── TransitionInterface.php │ │ ├── GatewayInterface.php │ │ ├── MessageFlowInterface.php │ │ ├── MessageEventDefinitionInterface.php │ │ ├── CatchEventInterface.php │ │ ├── TimerEventDefinitionInterface.php │ │ ├── LoopCardinalityInterface.php │ │ ├── CollectionInterface.php │ │ └── DataStoreInterface.php │ ├── Engine │ │ ├── DemoModeInterface.php │ │ ├── EventDefinitionBusInterface.php │ │ └── JobManagerInterface.php │ ├── Repositories │ │ └── ExecutionInstanceRepositoryInterface.php │ ├── EventBusInterface.php │ └── Storage │ │ └── BpmnElementInterface.php │ ├── Bpmn │ ├── FlowTrait.php │ ├── State.php │ ├── Models │ │ ├── DataStore.php │ │ ├── Participant.php │ │ ├── Token.php │ │ ├── BoundaryEvent.php │ │ ├── StartEvent.php │ │ ├── EventCollection.php │ │ ├── FlowCollection.php │ │ ├── GatewayCollection.php │ │ ├── IntermediateCatchEvent.php │ │ ├── ActivityCollection.php │ │ ├── ArtifactCollection.php │ │ ├── DataStoreCollection.php │ │ ├── DataOutput.php │ │ ├── Error.php │ │ ├── DataInput.php │ │ ├── Artifact.php │ │ ├── Activity.php │ │ ├── ItemDefinition.php │ │ ├── OutputSet.php │ │ ├── InputSet.php │ │ ├── ParallelGateway.php │ │ ├── Signal.php │ │ ├── EventBasedGateway.php │ │ ├── Operation.php │ │ ├── ExclusiveGateway.php │ │ ├── Process.php │ │ ├── InclusiveGateway.php │ │ ├── TerminateEventDefinition.php │ │ ├── Message.php │ │ ├── IntermediateThrowEvent.php │ │ ├── EndEvent.php │ │ └── InputOutputSpecification.php │ ├── Path.php │ ├── MessageFlowTrait.php │ ├── ThrowEventTrait.php │ ├── Assignment.php │ ├── Events │ │ ├── ActivityClosedEvent.php │ │ ├── ActivityActivatedEvent.php │ │ ├── ActivityCompletedEvent.php │ │ ├── ProcessInstanceCreatedEvent.php │ │ └── ProcessInstanceCompletedEvent.php │ ├── IntermediateCatchEventTransition.php │ ├── IntermediateThrowEventTransition.php │ ├── FlowElementTrait.php │ ├── ActivityCompletedTransition.php │ ├── DataInputAssociation.php │ ├── DataOutputAssociation.php │ ├── ActivityExceptionTransition.php │ ├── CloseExceptionTransition.php │ ├── CompleteExceptionTransition.php │ ├── BoundaryInterruptActivityTransition.php │ ├── BoundaryNoInterruptActivityTransition.php │ ├── BpmnEventsTrait.php │ ├── UncaughtCancelTransition.php │ ├── Transition.php │ ├── EndTransition.php │ ├── ParallelOutputTransition.php │ ├── ExceptionTransition.php │ ├── CancelActivityTransition.php │ ├── PauseOnGatewayTransitionTrait.php │ ├── LaneSet.php │ ├── ParallelGatewayTransition.php │ ├── SkipActivityTransition.php │ ├── ObservableTrait.php │ ├── BoundaryCaughtTransition.php │ ├── Connection.php │ ├── BoundaryExceptionTransition.php │ ├── ExclusiveGatewayTransition.php │ ├── ParticipantTrait.php │ ├── Lane.php │ ├── StandardLoopCharacteristicsTrait.php │ ├── TerminateTransition.php │ ├── FormalExpressionTrait.php │ ├── DataInputTransition.php │ └── TraversableTrait.php │ ├── Exceptions │ ├── ActivityWorkException.php │ ├── InvalidSequenceFlowException.php │ ├── ElementNotImplementedException.php │ ├── NamespaceNotImplementedException.php │ ├── ElementNotFoundException.php │ └── RuntimeException.php │ ├── Engine │ ├── ExecutionInstance.php │ ├── JobManagerTrait.php │ └── DemoModeTrait.php │ └── Storage │ └── BPMNValidator.php ├── composer.json ├── .github └── workflows │ └── sonarqube.yml └── README.md /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=ProcessMaker_nayra_AYq58Vs2xYvY_isvKv_4 2 | sonar.php.coverage.reportPaths=./coverage/clover.xml 3 | sonar.sources=src 4 | sonar.tests=tests 5 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/ParallelGatewayInterface.php: -------------------------------------------------------------------------------- 1 | setId(uniqid()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/EventBasedGatewayInterface.php: -------------------------------------------------------------------------------- 1 | elements = $elements; 20 | } 21 | 22 | /** 23 | * Get the elements of the path. 24 | * 25 | * @return array 26 | */ 27 | public function getElements() 28 | { 29 | return $this->elements; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/DatePeriodInterface.php: -------------------------------------------------------------------------------- 1 | elementId = $id; 22 | parent::__construct('Element "' . $id . '" was not found'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/EventCollectionInterface.php: -------------------------------------------------------------------------------- 1 | element = $element; 21 | parent::__construct($message, $code, $previous); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/GatewayCollectionInterface.php: -------------------------------------------------------------------------------- 1 | push($element); 24 | 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/FlowCollection.php: -------------------------------------------------------------------------------- 1 | push($element); 24 | 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/TraversableInterface.php: -------------------------------------------------------------------------------- 1 | push($element); 24 | 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/IntermediateCatchEvent.php: -------------------------------------------------------------------------------- 1 | push($element); 24 | 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/ArtifactCollection.php: -------------------------------------------------------------------------------- 1 | push($element); 24 | 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/DataStoreCollection.php: -------------------------------------------------------------------------------- 1 | push($element); 24 | 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/CorrelationPropertyInterface.php: -------------------------------------------------------------------------------- 1 | $dateTime) { 25 | if ($last < $dateTime) { 26 | $nextDateTime = $dateTime; 27 | break; 28 | } 29 | } 30 | 31 | return $nextDateTime; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "processmaker/nayra", 3 | "description": "BPMN compliant engine", 4 | "version": "1.12.4", 5 | "license": "Apache-2.0", 6 | "autoload": { 7 | "psr-4": { 8 | "ProcessMaker\\": "src/ProcessMaker/" 9 | } 10 | }, 11 | "autoload-dev": { 12 | "psr-4": { 13 | "Tests\\Feature\\": "tests/Feature/", 14 | "ProcessMaker\\": [ 15 | "src/ProcessMaker/", 16 | "tests/unit/ProcessMaker/", 17 | "tests/ProcessMaker/" 18 | ] 19 | } 20 | }, 21 | "scripts": { 22 | "test": "phpunit", 23 | "coverage": "@php -d zend_extension=xdebug.so -d xdebug.mode=coverage -d xdebug.start_with_request=no vendor/bin/phpunit" 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "^9.5" 27 | } 28 | } -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/DataOutput.php: -------------------------------------------------------------------------------- 1 | getProperty(static::BPMN_PROPERTY_ITEM_SUBJECT); 23 | } 24 | 25 | /** 26 | * Get true is the data input is a collection. 27 | * 28 | * @return bool 29 | */ 30 | public function isCollection() 31 | { 32 | return $this->getProperty(static::BPMN_PROPERTY_IS_COLLECTION); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/ThrowEventTrait.php: -------------------------------------------------------------------------------- 1 | setProperty(ThrowEventInterface::BPMN_PROPERTY_EVENT_DEFINITIONS, new Collection); 21 | } 22 | 23 | /** 24 | * Get the event definitions. 25 | * 26 | * @return EventDefinitionInterface[] 27 | */ 28 | public function getEventDefinitions() 29 | { 30 | return $this->getProperty(ThrowEventInterface::BPMN_PROPERTY_EVENT_DEFINITIONS); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Assignment.php: -------------------------------------------------------------------------------- 1 | getProperty(self::BPMN_PROPERTY_FROM); 23 | } 24 | 25 | /** 26 | * Get the 'to' formal expression. 27 | * 28 | * @return FormalExpressionInterface|callable 29 | */ 30 | public function getTo() 31 | { 32 | return $this->getProperty(self::BPMN_PROPERTY_TO); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Events/ActivityClosedEvent.php: -------------------------------------------------------------------------------- 1 | activity = $activity; 32 | $this->token = $token; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Events/ActivityActivatedEvent.php: -------------------------------------------------------------------------------- 1 | activity = $activity; 32 | $this->token = $token; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Events/ActivityCompletedEvent.php: -------------------------------------------------------------------------------- 1 | activity = $activity; 32 | $this->token = $token; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/Error.php: -------------------------------------------------------------------------------- 1 | getProperty(ErrorInterface::BPMN_PROPERTY_NAME); 26 | } 27 | 28 | /** 29 | * Get the error code. 30 | * 31 | * @return string 32 | */ 33 | public function getErrorCode() 34 | { 35 | return $this->getProperty(ErrorInterface::BPMN_PROPERTY_ERROR_CODE); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/IntermediateCatchEventTransition.php: -------------------------------------------------------------------------------- 1 | getProperty(static::BPMN_PROPERTY_ITEM_SUBJECT); 24 | } 25 | 26 | /** 27 | * Get true is the data input is a collection. 28 | * 29 | * @return bool 30 | */ 31 | public function isCollection() 32 | { 33 | return $this->getProperty(static::BPMN_PROPERTY_IS_COLLECTION); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/IntermediateThrowEventTransition.php: -------------------------------------------------------------------------------- 1 | process; 26 | } 27 | 28 | /** 29 | * Set the Process of the artifact. 30 | * 31 | * @param ProcessInterface $process 32 | * @return $this 33 | */ 34 | public function setProcess(ProcessInterface $process) 35 | { 36 | $this->process = $process; 37 | 38 | return $this; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/CallableElementInterface.php: -------------------------------------------------------------------------------- 1 | process = $process; 32 | $this->instance = $instance; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/FlowElementTrait.php: -------------------------------------------------------------------------------- 1 | ownerProcess; 30 | } 31 | 32 | /** 33 | * Set the owner process. 34 | * 35 | * @param ProcessInterface $ownerProcess 36 | * 37 | * @return $this 38 | */ 39 | public function setOwnerProcess(ProcessInterface $ownerProcess) 40 | { 41 | $this->ownerProcess = $ownerProcess; 42 | 43 | return $this; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Events/ProcessInstanceCompletedEvent.php: -------------------------------------------------------------------------------- 1 | process = $process; 32 | $this->instance = $instance; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/ActivityCompletedTransition.php: -------------------------------------------------------------------------------- 1 | getStatus() === ActivityInterface::TOKEN_STATE_COMPLETED; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/ComplexBehaviorDefinitionInterface.php: -------------------------------------------------------------------------------- 1 | ActivityActivatedEvent::class, 27 | ActivityInterface::EVENT_ACTIVITY_COMPLETED => ActivityCompletedEvent::class, 28 | ActivityInterface::EVENT_ACTIVITY_CLOSED => ActivityClosedEvent::class, 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/ConnectionInterface.php: -------------------------------------------------------------------------------- 1 | properties[static::BPMN_PROPERTY_ASSIGNMENT] = new Collection; 17 | } 18 | 19 | public function getSource() 20 | { 21 | return $this->getProperty(static::BPMN_PROPERTY_SOURCES_REF); 22 | } 23 | 24 | public function getTarget() 25 | { 26 | return $this->getProperty(static::BPMN_PROPERTY_TARGET_REF); 27 | } 28 | 29 | public function getTransformation() 30 | { 31 | return $this->getProperty(static::BPMN_PROPERTY_TRANSFORMATION); 32 | } 33 | 34 | public function getAssignments() 35 | { 36 | return $this->getProperty(static::BPMN_PROPERTY_ASSIGNMENT); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/DataOutputAssociation.php: -------------------------------------------------------------------------------- 1 | properties[static::BPMN_PROPERTY_ASSIGNMENT] = new Collection; 17 | } 18 | 19 | public function getSource() 20 | { 21 | return $this->getProperty(static::BPMN_PROPERTY_SOURCES_REF); 22 | } 23 | 24 | public function getTarget() 25 | { 26 | return $this->getProperty(static::BPMN_PROPERTY_TARGET_REF); 27 | } 28 | 29 | public function getTransformation() 30 | { 31 | return $this->getProperty(static::BPMN_PROPERTY_TRANSFORMATION); 32 | } 33 | 34 | public function getAssignments() 35 | { 36 | return $this->getProperty(static::BPMN_PROPERTY_ASSIGNMENT); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/IntermediateCatchEventInterface.php: -------------------------------------------------------------------------------- 1 | getProperty(TokenInterface::BPMN_PROPERTY_EVENT_TYPE); 28 | $matchType = $eventType === ErrorInterface::class || is_a($eventType, ErrorInterface::class); 29 | 30 | return $matchType; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/ItemDefinitionInterface.php: -------------------------------------------------------------------------------- 1 | '', 26 | 'PRO_ID' => null, 27 | 'ART_TYPE' => null, 28 | 'ART_NAME' => null, 29 | 'ART_CATEGORY_REF' => null, 30 | ]; 31 | 32 | /** 33 | * Child elements. 34 | */ 35 | const ELEMENTS = [ 36 | 37 | ]; 38 | 39 | /** 40 | * Get Process of the artifact. 41 | * 42 | * @return ProcessInterface 43 | */ 44 | public function getProcess(); 45 | 46 | /** 47 | * Get Process of the artifact. 48 | * 49 | * @return ProcessInterface 50 | */ 51 | public function setProcess(ProcessInterface $process); 52 | } 53 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/CloseExceptionTransition.php: -------------------------------------------------------------------------------- 1 | setPreserveToken(true); 23 | } 24 | 25 | /** 26 | * Condition required to transit an activity in FAILING state. 27 | * 28 | * @param TokenInterface|null $token 29 | * @param ExecutionInstanceInterface|null $executionInstance 30 | * 31 | * @return bool 32 | */ 33 | public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) 34 | { 35 | return $token->getStatus() === ActivityInterface::TOKEN_STATE_CLOSED; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/CompleteExceptionTransition.php: -------------------------------------------------------------------------------- 1 | setPreserveToken(true); 23 | } 24 | 25 | /** 26 | * Condition required to transit an activity in FAILING state. 27 | * 28 | * @param TokenInterface|null $token 29 | * @param ExecutionInstanceInterface|null $executionInstance 30 | * 31 | * @return bool 32 | */ 33 | public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) 34 | { 35 | return $token->getStatus() === ActivityInterface::TOKEN_STATE_COMPLETED; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/ItemDefinition.php: -------------------------------------------------------------------------------- 1 | getProperty(ItemDefinitionInterface::BPMN_PROPERTY_ITEM_KIND); 24 | } 25 | 26 | /** 27 | * Get the concrete data structure to be used. 28 | * 29 | * @return mixed 30 | */ 31 | public function getStructure() 32 | { 33 | return $this->getProperty(ItemDefinitionInterface::BPMN_PROPERTY_STRUCTURE); 34 | } 35 | 36 | /** 37 | * Get true if the data structure represents a collection. 38 | * 39 | * @return bool 40 | */ 41 | public function isCollection() 42 | { 43 | return $this->getProperty(ItemDefinitionInterface::BPMN_PROPERTY_IS_COLLECTION); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Engine/DemoModeInterface.php: -------------------------------------------------------------------------------- 1 | getOwner(); 28 | $interrupt = false; 29 | if ($boundary instanceof BoundaryEventInterface) { 30 | $interrupt = $boundary->getCancelActivity(); 31 | } 32 | 33 | return $interrupt; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/FormalExpressionInterface.php: -------------------------------------------------------------------------------- 1 | getOwner(); 28 | $nonInterrupt = false; 29 | if ($boundary instanceof BoundaryEventInterface) { 30 | $nonInterrupt = !$boundary->getCancelActivity(); 31 | } 32 | 33 | return $nonInterrupt; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/ScriptTaskInterface.php: -------------------------------------------------------------------------------- 1 | getBpmnEventClasses(); 32 | if (isset($bpmnEvents[$event])) { 33 | $reflector = new ReflectionClass($bpmnEvents[$event]); 34 | $payload = $reflector->newInstanceArgs($arguments); 35 | } else { 36 | $payload = $arguments; 37 | } 38 | $this->getOwnerProcess()->getDispatcher()->dispatch($event, $payload); 39 | array_unshift($arguments, $event); 40 | call_user_func_array([$this, 'internalNotifyEvent'], $arguments); 41 | call_user_func_array([$this->getOwnerProcess(), 'notifyEvent'], $arguments); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/OutputSet.php: -------------------------------------------------------------------------------- 1 | setDataOutputs(new Collection); 24 | } 25 | 26 | /** 27 | * Get DataOutput elements that MAY collectively be outputted. 28 | * 29 | * @return DataOutputInterface[] 30 | */ 31 | public function getDataOutputs() 32 | { 33 | return $this->getProperty(static::BPMN_PROPERTY_DATA_OUTPUTS); 34 | } 35 | 36 | /** 37 | * Set DataOutput elements that MAY collectively be outputted. 38 | * 39 | * @param CollectionInterface $dataOutputs 40 | * 41 | * @return $this 42 | */ 43 | public function setDataOutputs(CollectionInterface $dataOutputs) 44 | { 45 | return $this->setProperty(static::BPMN_PROPERTY_DATA_OUTPUTS, $dataOutputs); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/UncaughtCancelTransition.php: -------------------------------------------------------------------------------- 1 | getOwner(); 28 | $eventType = $token->getProperty(TokenInterface::BPMN_PROPERTY_EVENT_TYPE); 29 | $eventDefinitionId = $token->getProperty(TokenInterface::BPMN_PROPERTY_EVENT_DEFINITION_CAUGHT); 30 | $matchType = $eventType === CancelInterface::class || is_a($eventType, CancelInterface::class); 31 | 32 | return $matchType && !$this->existsBoundaryFor($activity, $eventType, $eventDefinitionId); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/DiagramInterface.php: -------------------------------------------------------------------------------- 1 | '', 20 | 'PRJ_UID' => null, 21 | 'DIA_NAME' => null, 22 | 'DIA_IS_CLOSABLE' => '0', 23 | ]; 24 | 25 | /** 26 | * Child elements. 27 | */ 28 | const ELEMENTS = [ 29 | 'shapes' => ShapeInterface::TYPE, 30 | ]; 31 | 32 | /** 33 | * Get Shapes of the diagram. 34 | * 35 | * @return ShapeCollectionInterface 36 | */ 37 | public function getShapes(); 38 | 39 | /** 40 | * Get Shapes of the diagram. 41 | * 42 | * @return ShapeCollectionInterface 43 | */ 44 | public function setShapes(ShapeCollectionInterface $shapes); 45 | 46 | /** 47 | * Get Process of the diagram. 48 | * 49 | * @return ProcessInterface 50 | */ 51 | public function getProcess(); 52 | 53 | /** 54 | * Get Process of the diagram. 55 | * 56 | * @return ProcessInterface 57 | */ 58 | public function setProcess(ProcessInterface $process); 59 | } 60 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/InputSet.php: -------------------------------------------------------------------------------- 1 | setDataInputs(new Collection); 24 | } 25 | 26 | /** 27 | * Get the DataInput elements that collectively make up this data requirement. 28 | * 29 | * @return DataInputInterface[] 30 | */ 31 | public function getDataInputs() 32 | { 33 | return $this->getProperty(static::BPMN_PROPERTY_DATA_INPUTS); 34 | } 35 | 36 | /** 37 | * Set the DataInput elements that collectively make up this data requirement. 38 | * 39 | * @param CollectionInterface $dataInputs 40 | * 41 | * @return $this 42 | */ 43 | public function setDataInputs(CollectionInterface $dataInputs) 44 | { 45 | return $this->setProperty(static::BPMN_PROPERTY_DATA_INPUTS, $dataInputs); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Transition.php: -------------------------------------------------------------------------------- 1 | setPreserveToken($preserveToken); 27 | } 28 | 29 | /** 30 | * Condition required to transit the element. 31 | * 32 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface|null $token 33 | * @param \ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface|null $executionInstance 34 | * 35 | * @return bool 36 | */ 37 | public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) 38 | { 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/ParallelGateway.php: -------------------------------------------------------------------------------- 1 | id; 37 | } 38 | 39 | /** 40 | * Sets the id of the message 41 | * @param string $value 42 | */ 43 | public function setId($value) 44 | { 45 | $this->id = $value; 46 | } 47 | 48 | /** 49 | * Returns the name of the message 50 | * 51 | * @return string 52 | */ 53 | public function getName() 54 | { 55 | return $this->name; 56 | } 57 | 58 | /** 59 | * Sets the name of the signal 60 | * 61 | * @param string $value 62 | */ 63 | public function setName($value) 64 | { 65 | $this->name = $value; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/ErrorEventDefinitionInterface.php: -------------------------------------------------------------------------------- 1 | incoming()->count() > 0 39 | && $this->incoming() 40 | ->find(function ($flow) use ($instance) { 41 | return $flow->origin()->getTokens($instance)->count() === 0; 42 | }) 43 | ->count() === 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/ParallelOutputTransition.php: -------------------------------------------------------------------------------- 1 | shouldDebugTriggerThisTransition($executionInstance)) { 28 | return true; 29 | } 30 | // If debug mode is enabled, the transition is not triggered if it is not selected 31 | if ($executionInstance && $this->shouldDebugSkipThisTransition($executionInstance)) { 32 | return false; 33 | } 34 | 35 | // By default the transition is triggered 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/LaneInterface.php: -------------------------------------------------------------------------------- 1 | setPreserveToken(true); 24 | } 25 | 26 | /** 27 | * Condition required to transit the element. 28 | * 29 | * @param TokenInterface|null $token 30 | * @param ExecutionInstanceInterface|null $executionInstance 31 | * 32 | * @return bool 33 | */ 34 | public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) 35 | { 36 | return $token->getStatus() === ActivityInterface::TOKEN_STATE_FAILING; 37 | } 38 | 39 | /** 40 | * Mark token as error event. 41 | * 42 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface $token 43 | */ 44 | protected function onTokenTransit(TokenInterface $token) 45 | { 46 | $token->setProperty(TokenInterface::BPMN_PROPERTY_EVENT_TYPE, ErrorInterface::class); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/CancelActivityTransition.php: -------------------------------------------------------------------------------- 1 | setPreserveToken(true); 24 | } 25 | 26 | /** 27 | * Condition required to transit the element. 28 | * 29 | * @param TokenInterface|null $token 30 | * @param ExecutionInstanceInterface|null $executionInstance 31 | * 32 | * @return bool 33 | */ 34 | public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) 35 | { 36 | return $token->getStatus() === ActivityInterface::TOKEN_STATE_CLOSED; 37 | } 38 | 39 | /** 40 | * Mark token as cancel event. 41 | * 42 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface $token 43 | */ 44 | protected function onTokenTransit(TokenInterface $token) 45 | { 46 | $token->setProperty(TokenInterface::BPMN_PROPERTY_EVENT_TYPE, CancelInterface::class); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/StandardLoopCharacteristicsInterface.php: -------------------------------------------------------------------------------- 1 | getEngine(); 24 | $demoMode = $engine->isDemoMode(); 25 | $gateway = $this->getOwner(); 26 | return $demoMode && !$engine->getSelectedDemoFlow($gateway); 27 | } 28 | 29 | /** 30 | * Check if the gateway input has at least one token in demo mode. 31 | * 32 | * @param ExecutionInstanceInterface $executionInstance 33 | * @return bool 34 | */ 35 | function doesDemoHasAllRequiredTokens(ExecutionInstanceInterface $executionInstance) 36 | { 37 | $engine = $executionInstance->getEngine(); 38 | $demoMode = $engine->isDemoMode(); 39 | if (!$demoMode) { 40 | return false; 41 | } 42 | 43 | $withToken = $this->incoming()->find(function (Connection $flow) use ($executionInstance) { 44 | return $flow->originState()->getTokens($executionInstance)->count() > 0; 45 | }); 46 | 47 | return $withToken->count() > 0; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/ShapeInterface.php: -------------------------------------------------------------------------------- 1 | '', 20 | 'PRJ_UID' => '', 21 | 'DIA_UID' => '', 22 | 'ELEMENT_UID' => '', 23 | 'BOU_ELEMENT' => '', 24 | 'BOU_ELEMENT_TYPE' => '', 25 | 'BOU_X' => '0', 26 | 'BOU_Y' => '0', 27 | 'BOU_WIDTH' => '0', 28 | 'BOU_HEIGHT' => '0', 29 | 'BOU_REL_POSITION' => '0', 30 | 'BOU_SIZE_IDENTICAL' => '0', 31 | 'BOU_CONTAINER' => '', 32 | ]; 33 | 34 | /** 35 | * Child elements. 36 | */ 37 | const ELEMENTS = [ 38 | 39 | ]; 40 | 41 | /** 42 | * Get Process of the shape. 43 | * 44 | * @return ProcessInterface 45 | */ 46 | public function getProcess(); 47 | 48 | /** 49 | * Get Process of the shape. 50 | * 51 | * @return ProcessInterface 52 | */ 53 | public function setProcess(ProcessInterface $process); 54 | 55 | /** 56 | * Get Diagram of the shape. 57 | * 58 | * @return DiagramInterface 59 | */ 60 | public function getDiagram(); 61 | 62 | /** 63 | * Get Diagram of the shape. 64 | * 65 | * @return DiagramInterface 66 | */ 67 | public function setDiagram(DiagramInterface $diagram); 68 | } 69 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/EventBasedGateway.php: -------------------------------------------------------------------------------- 1 | getProperty(OperationInterface::BPMN_PROPERTY_IMPLEMENTATION); 26 | } 27 | 28 | /** 29 | * Get the input Message of the Operation. 30 | * 31 | * @return MessageInterface 32 | */ 33 | public function getInMessage() 34 | { 35 | return $this->getProperty(OperationInterface::BPMN_PROPERTY_IN_MESSAGE); 36 | } 37 | 38 | /** 39 | * Get the output Message of the Operation. 40 | * 41 | * @return MessageInterface 42 | */ 43 | public function getOutMessage() 44 | { 45 | return $this->getProperty(OperationInterface::BPMN_PROPERTY_OUT_MESSAGE); 46 | } 47 | 48 | /** 49 | * Get errors that the Operation may return. 50 | * 51 | * @return mixed[] 52 | */ 53 | public function getErrors() 54 | { 55 | return $this->getProperty(OperationInterface::BPMN_PROPERTY_ERRORS, new Collection); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/LaneSet.php: -------------------------------------------------------------------------------- 1 | setLanes(new Collection); 22 | } 23 | 24 | /** 25 | * Get the name of the lane set. 26 | * 27 | * @return string 28 | */ 29 | public function getName() 30 | { 31 | return $this->getProperty(self::BPMN_PROPERTY_NAME); 32 | } 33 | 34 | /** 35 | * Get the lanes of the lane set. 36 | * 37 | * @return \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface 38 | */ 39 | public function getLanes() 40 | { 41 | return $this->getProperty(self::BPMN_PROPERTY_LANE); 42 | } 43 | 44 | /** 45 | * Set the name of the lane set. 46 | * 47 | * @param string $name 48 | * 49 | * @return $this 50 | */ 51 | public function setName($name) 52 | { 53 | return $this->setProperty(self::BPMN_PROPERTY_NAME, $name); 54 | } 55 | 56 | /** 57 | * Set the lanes of the lane set. 58 | * 59 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface $lanes 60 | * 61 | * @return $this 62 | */ 63 | public function setLanes(CollectionInterface $lanes) 64 | { 65 | return $this->setProperty(self::BPMN_PROPERTY_LANE, $lanes); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/ExclusiveGateway.php: -------------------------------------------------------------------------------- 1 | createFlowTo($target, $factory, [ 39 | FlowInterface::BPMN_PROPERTY_CONDITION_EXPRESSION => $condition, 40 | FlowInterface::BPMN_PROPERTY_IS_DEFAULT => $isDefault, 41 | ]); 42 | 43 | return $this; 44 | } 45 | 46 | /** 47 | * Array map of custom event classes for the bpmn element. 48 | * 49 | * @return array 50 | */ 51 | protected function getBpmnEventClasses() 52 | { 53 | return []; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/Process.php: -------------------------------------------------------------------------------- 1 | bootElement($args); 31 | $this->setActivities(new ActivityCollection); 32 | $this->setGateways(new GatewayCollection); 33 | $this->setEvents(new EventCollection); 34 | $this->setFlows(new FlowCollection); 35 | $this->setArtifacts(new ArtifactCollection); 36 | $this->setDataStores(new DataStoreCollection); 37 | } 38 | 39 | /** 40 | * Get BPMN event classes. 41 | * 42 | * @return array 43 | */ 44 | protected function getBpmnEventClasses() 45 | { 46 | return [ 47 | static::EVENT_PROCESS_INSTANCE_COMPLETED => ProcessInstanceCompletedEvent::class, 48 | static::EVENT_PROCESS_INSTANCE_CREATED => ProcessInstanceCreatedEvent::class, 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/InputOutputSpecificationInterface.php: -------------------------------------------------------------------------------- 1 | demoMode; 34 | } 35 | 36 | /** 37 | * Set if the engine is in demo mode. 38 | * 39 | * @param bool $value 40 | */ 41 | public function setDemoMode(bool $value) 42 | { 43 | $this->demoMode = $value; 44 | } 45 | 46 | /** 47 | * Retrieves the selected flow by the user in demo mode. 48 | * 49 | * @param GatewayInterface $gateway 50 | * 51 | * @return FlowInterface|null 52 | */ 53 | public function getSelectedDemoFlow(GatewayInterface $gateway) 54 | { 55 | return $this->selectedFlow[$gateway->getId()] ?? null; 56 | } 57 | 58 | /** 59 | * Set the selected flow by the user in demo mode. 60 | * 61 | * @param GatewayInterface $gateway 62 | * @param bool $value 63 | */ 64 | public function setSelectedDemoFlow( 65 | GatewayInterface $gateway, 66 | FlowInterface $selectedFlow = null 67 | ) { 68 | $this->selectedFlow[$gateway->getId()] = $selectedFlow; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/InclusiveGateway.php: -------------------------------------------------------------------------------- 1 | createFlowTo($target, $factory, [ 40 | FlowInterface::BPMN_PROPERTY_CONDITION_EXPRESSION => $condition, 41 | FlowInterface::BPMN_PROPERTY_IS_DEFAULT => $isDefault, 42 | ]); 43 | 44 | return $this; 45 | } 46 | 47 | /** 48 | * Array map of custom event classes for the BPMN element. 49 | * 50 | * @return array 51 | */ 52 | protected function getBpmnEventClasses() 53 | { 54 | return []; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Engine/EventDefinitionBusInterface.php: -------------------------------------------------------------------------------- 1 | shouldPauseGatewayTransition($executionInstance); 28 | } 29 | 30 | /** 31 | * The Parallel Gateway is activated if there is at least one token on 32 | * each incoming Sequence Flow. 33 | * 34 | * @param \ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface $executionInstance 35 | * 36 | * @return bool 37 | */ 38 | protected function hasAllRequiredTokens(ExecutionInstanceInterface $executionInstance) 39 | { 40 | if ($this->doesDemoHasAllRequiredTokens($executionInstance)) { 41 | return true; 42 | } 43 | 44 | $incomingWithToken = $this->incoming()->find(function (Connection $flow) use ($executionInstance) { 45 | return $flow->originState()->getTokens($executionInstance)->count() > 0; 46 | }); 47 | 48 | return $incomingWithToken->count() === $this->incoming()->count() && $incomingWithToken->count() > 0; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/CollaborationInterface.php: -------------------------------------------------------------------------------- 1 | item; 45 | } 46 | 47 | /** 48 | * Allows to set the item 49 | * 50 | * @param ItemDefinitionInterface $item 51 | * 52 | * @return $this 53 | */ 54 | public function setItem(ItemDefinitionInterface $item) 55 | { 56 | $this->item = $item; 57 | 58 | return $this; 59 | } 60 | 61 | /** 62 | * Returns the id of the message 63 | * 64 | * @return string 65 | */ 66 | public function getId() 67 | { 68 | return $this->id; 69 | } 70 | 71 | /** 72 | * Sets the id of the message 73 | * @param string $value 74 | */ 75 | public function setId($value) 76 | { 77 | $this->id = $value; 78 | } 79 | 80 | /** 81 | * Returns the name of the message 82 | * 83 | * @return string 84 | */ 85 | public function getName() 86 | { 87 | return $this->name; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/GatewayInterface.php: -------------------------------------------------------------------------------- 1 | setTokensConsumedPerIncoming(-1); 27 | } 28 | 29 | /** 30 | * Condition required to transit the element. 31 | * 32 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\TokenInterface|null $token 33 | * @param \ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface|null $executionInstance 34 | * 35 | * @return bool 36 | */ 37 | public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) 38 | { 39 | $loop = $this->getOwner()->getLoopCharacteristics(); 40 | if ($loop instanceof StandardLoopCharacteristicsInterface) { 41 | $testBefore = $loop->getTestBefore(); 42 | $completed = $loop->isLoopCompleted($executionInstance, $token); 43 | // If loop is completed, then Skip Activity Transition is triggered 44 | return $testBefore && $completed; 45 | } 46 | 47 | return false; 48 | } 49 | 50 | /** 51 | * Get transition owner element 52 | * 53 | * @return ActivityInterface 54 | */ 55 | public function getOwner() 56 | { 57 | return $this->owner; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/ObservableTrait.php: -------------------------------------------------------------------------------- 1 | observers; 23 | } 24 | 25 | /** 26 | * Attach a callback to an event. 27 | * 28 | * @param string $event 29 | * @param callable $callback 30 | */ 31 | public function attachEvent($event, callable $callback) 32 | { 33 | $this->observers[$event][] = $callback; 34 | } 35 | 36 | /** 37 | * Detach a callback from an event. 38 | * 39 | * @param string $event 40 | * @param callable $callback 41 | */ 42 | public function detachEvent($event, callable $callback) 43 | { 44 | $index = array_search($callback, $this->observers[$event], true); 45 | if ($index !== false) { 46 | unset($this->observers[$event][$index]); 47 | } 48 | } 49 | 50 | /** 51 | * Notify a event to the observers. 52 | * 53 | * @param $event 54 | * @param array ...$arguments 55 | */ 56 | protected function notifyEvent($event, ...$arguments) 57 | { 58 | if (empty($this->observers[$event])) { 59 | return; 60 | } 61 | foreach ($this->observers[$event] as $callback) { 62 | call_user_func_array($callback, $arguments); 63 | } 64 | } 65 | 66 | /** 67 | * Notify an external event to the observers. 68 | * 69 | * @param $event 70 | * @param array ...$arguments 71 | */ 72 | public function notifyExternalEvent($event, ...$arguments) 73 | { 74 | $this->notifyEvent($event, ...$arguments); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/MessageFlowInterface.php: -------------------------------------------------------------------------------- 1 | getOwner(); 29 | $eventType = $token->getProperty(TokenInterface::BPMN_PROPERTY_EVENT_TYPE); 30 | $eventDefinitionId = $token->getProperty(TokenInterface::BPMN_PROPERTY_EVENT_DEFINITION_CAUGHT); 31 | 32 | return $this->existsBoundaryFor($activity, $eventType, $eventDefinitionId); 33 | } 34 | 35 | /** 36 | * Check if activity has a boundary event for the given event definition. 37 | * 38 | * @param ActivityInterface $activity 39 | * @param string $eventType 40 | * @param string $eventDefinitionId 41 | * 42 | * @return bool 43 | */ 44 | protected function existsBoundaryFor(ActivityInterface $activity, $eventType, $eventDefinitionId) 45 | { 46 | $catchException = $activity->getBoundaryEvents()->findFirst(function (BoundaryEventInterface $catch) use ($eventDefinitionId) { 47 | foreach ($catch->getEventDefinitions() as $eventDefinition) { 48 | if ($eventDefinition->getId() === $eventDefinitionId) { 49 | return true; 50 | } 51 | } 52 | }); 53 | 54 | return !empty($catchException); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Connection.php: -------------------------------------------------------------------------------- 1 | origin = $origin; 37 | $this->target = $target; 38 | } 39 | 40 | /** 41 | * Get the origin node (state or transition) of the connection. 42 | * 43 | * @return ConnectionNodeInterface Origin element 44 | */ 45 | public function origin() 46 | { 47 | return $this->origin; 48 | } 49 | 50 | /** 51 | * Get the target node (state or transition) of the connection. 52 | * 53 | * @return ConnectionNodeInterface Target element 54 | */ 55 | public function target() 56 | { 57 | return $this->target; 58 | } 59 | 60 | /** 61 | * Get the origin node of the connection as a state. 62 | * 63 | * @return StateInterface Origin element 64 | */ 65 | public function originState() 66 | { 67 | return $this->origin; 68 | } 69 | 70 | /** 71 | * Get the target node of the connection as a state. 72 | * 73 | * @return StateInterface Target element 74 | */ 75 | public function targetState() 76 | { 77 | return $this->target; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/MessageEventDefinitionInterface.php: -------------------------------------------------------------------------------- 1 | getOwner(); 31 | $eventType = $token->getProperty(TokenInterface::BPMN_PROPERTY_EVENT_TYPE); 32 | 33 | return $this->existsBoundaryErrorFor($activity, $eventType, null); 34 | } 35 | 36 | /** 37 | * Check if activity has a boundary event for the given event definition. 38 | * 39 | * @param ActivityInterface $activity 40 | * @param string $eventType 41 | * 42 | * @return bool 43 | */ 44 | protected function existsBoundaryErrorFor(ActivityInterface $activity, $eventType) 45 | { 46 | $catchException = $activity->getBoundaryEvents()->findFirst(function (BoundaryEventInterface $catch) use ($eventType) { 47 | foreach ($catch->getEventDefinitions() as $eventDefinition) { 48 | if ($eventDefinition instanceof ErrorEventDefinition) { 49 | $matchType = $eventType === ErrorInterface::class || is_a($eventType, ErrorInterface::class); 50 | 51 | return $matchType && $catch->getCancelActivity(); 52 | } 53 | } 54 | }); 55 | 56 | return !empty($catchException); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/ExclusiveGatewayTransition.php: -------------------------------------------------------------------------------- 1 | setTokensConsumedPerTransition(1); 24 | $this->setTokensConsumedPerIncoming(1); 25 | } 26 | 27 | /** 28 | * Always true because any token that arrives triggers the gateway 29 | * outgoing flow transition. 30 | * 31 | * @param TokenInterface|null $token 32 | * @param ExecutionInstanceInterface|null $executionInstance 33 | * 34 | * @return bool 35 | */ 36 | public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) 37 | { 38 | // Execution is paused if Engine is in demo mode and the gateway choose is not selected 39 | return !$this->shouldPauseGatewayTransition($executionInstance); 40 | } 41 | 42 | /** 43 | * In this gateway, one token should arrive, and every time this happens the gateway is ready to be triggered 44 | * 45 | * @param \ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface $executionInstance 46 | * 47 | * @return bool 48 | */ 49 | protected function hasAllRequiredTokens(ExecutionInstanceInterface $executionInstance) 50 | { 51 | if ($this->doesDemoHasAllRequiredTokens($executionInstance)) { 52 | return true; 53 | } 54 | 55 | $withToken = $this->incoming()->find(function (Connection $flow) use ($executionInstance) { 56 | return $flow->originState()->getTokens($executionInstance)->count() > 0; 57 | }); 58 | 59 | return $withToken->count() > 0; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/EventBusInterface.php: -------------------------------------------------------------------------------- 1 | 1, 'minimum' => 0]; 31 | $this->setProperty(ParticipantInterface::BPMN_PROPERTY_PARTICIPANT_MULTIPICITY, $default); 32 | } 33 | 34 | /** 35 | * Returns the process associated to the participant 36 | * 37 | * @return \ProcessMaker\Nayra\Contracts\Bpmn\ProcessInterface 38 | */ 39 | public function getProcess() 40 | { 41 | return $this->getProperty(ParticipantInterface::BPMN_PROPERTY_PROCESS); 42 | } 43 | 44 | /** 45 | * Set the Process that the Participant uses in the Collaboration. 46 | * 47 | * @param ProcessInterface $process 48 | * 49 | * @return $this 50 | */ 51 | public function setProcess(ProcessInterface $process) 52 | { 53 | $this->setProperty(ParticipantInterface::BPMN_PROPERTY_PROCESS, $process); 54 | $process->addProperty(ProcessInterface::BPMN_PROPERTY_PARTICIPANT, $this); 55 | 56 | return $this; 57 | } 58 | 59 | /** 60 | * Get Participant multiplicity for a given interaction. 61 | * 62 | * @return array 63 | */ 64 | public function getParticipantMultiplicity() 65 | { 66 | return $this->getProperty(ParticipantInterface::BPMN_PROPERTY_PARTICIPANT_MULTIPICITY); 67 | } 68 | 69 | /** 70 | * Set Participant multiplicity for a given interaction. 71 | * 72 | * @param array $array 73 | * 74 | * @return $this 75 | */ 76 | public function setParticipantMultiplicity(array $array) 77 | { 78 | return $this->setProperty(ParticipantInterface::BPMN_PROPERTY_PARTICIPANT_MULTIPICITY, $array); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Lane.php: -------------------------------------------------------------------------------- 1 | setFlowNodes(new Collection); 22 | $this->setChildLaneSets(new Collection); 23 | } 24 | 25 | /** 26 | * Get the name of the lane. 27 | * 28 | * @return string 29 | */ 30 | public function getName() 31 | { 32 | return $this->getProperty(self::BPMN_PROPERTY_NAME); 33 | } 34 | 35 | /** 36 | * Get the flow nodes of the lane. 37 | * 38 | * @return CollectionInterface 39 | */ 40 | public function getFlowNodes() 41 | { 42 | return $this->getProperty(self::BPMN_PROPERTY_FLOW_NODE); 43 | } 44 | 45 | /** 46 | * Get the child lanes of the lane. 47 | * 48 | * @return CollectionInterface 49 | */ 50 | public function getChildLaneSets() 51 | { 52 | return $this->getProperty(self::BPMN_PROPERTY_CHILD_LANE_SET); 53 | } 54 | 55 | /** 56 | * Set the name of the lane set. 57 | * 58 | * @param string $name 59 | * 60 | * @return $this 61 | */ 62 | public function setName($name) 63 | { 64 | return $this->setProperty(self::BPMN_PROPERTY_NAME, $name); 65 | } 66 | 67 | /** 68 | * Set the flow nodes of the lane. 69 | * 70 | * @param CollectionInterface $nodes 71 | * 72 | * @return $this 73 | */ 74 | public function setFlowNodes(CollectionInterface $nodes) 75 | { 76 | return $this->setProperty(self::BPMN_PROPERTY_FLOW_NODE, $nodes); 77 | } 78 | 79 | /** 80 | * Set the child lanes of the lane. 81 | * 82 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface $lanes 83 | * 84 | * @return $this 85 | */ 86 | public function setChildLaneSets(CollectionInterface $lanes) 87 | { 88 | return $this->setProperty(self::BPMN_PROPERTY_CHILD_LANE_SET, $lanes); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Storage/BPMNValidator.php: -------------------------------------------------------------------------------- 1 | document = $document; 33 | } 34 | 35 | /** 36 | * @param \LibXMLError object $error 37 | * 38 | * @return string 39 | */ 40 | private function libxmlDisplayError(LibXMLError $error) 41 | { 42 | $errorString = "Error $error->code (Line:{$error->line}):"; 43 | $errorString .= trim($error->message); 44 | 45 | return $errorString; 46 | } 47 | 48 | /** 49 | * @return array 50 | */ 51 | private function getLibxmlErrors() 52 | { 53 | $errors = libxml_get_errors(); 54 | $result = []; 55 | foreach ($errors as $error) { 56 | $result[] = $this->libxmlDisplayError($error); 57 | } 58 | libxml_clear_errors(); 59 | 60 | return $result; 61 | } 62 | 63 | /** 64 | * Validate Incoming Feeds against Listing Schema 65 | * 66 | * @param string $schema 67 | * 68 | * @return bool 69 | */ 70 | public function validate($schema) 71 | { 72 | $this->errors = $this->getLibxmlErrors(); 73 | $hasErrors = false; 74 | $validation = $this->document->schemaValidate($schema); 75 | if (!$validation) { 76 | $this->errors = array_merge($this->errors, $this->getLibxmlErrors()); 77 | $hasErrors = true; 78 | } 79 | 80 | return !$hasErrors; 81 | } 82 | 83 | /** 84 | * Display Error if Resource is not validated 85 | * 86 | * @return array 87 | */ 88 | public function getErrors() 89 | { 90 | return $this->errors; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/TimerEventDefinitionInterface.php: -------------------------------------------------------------------------------- 1 | setEngine($this->engine); 12 | $bpmnRepository->setFactory($this->repository); 13 | $bpmnRepository->load('files/ParallelGateway.bpmn'); 14 | ``` 15 | ![ParallelGateway diagram](/docs/diagrams/ParallelGateway.svg "ParallelGateway diagram") 16 | 17 | Get a reference to the process 18 | ``` 19 | $process = $bpmnRepository->getProcess('ParallelGateway'); 20 | ``` 21 | Create a data storage 22 | ``` 23 | $dataStore = $this->repository->createDataStore(); 24 | ``` 25 | Create a process instance 26 | ``` 27 | $instance = $this->engine->createExecutionInstance($process, $dataStore); 28 | ``` 29 | Trigger the start event 30 | ``` 31 | $start = $bpmnRepository->getStartEvent('StartEvent'); 32 | $start->start($instance); 33 | ``` 34 | ![Start Event](/docs/diagrams/ParallelGateway_1.svg "Start Event") 35 | 36 | Execute tokens and run to the next state 37 | ``` 38 | $this->engine->runToNextState(); 39 | ``` 40 | One token arrives to the first task 41 | ``` 42 | $firstTask = $bpmnRepository->getScriptTask('start'); 43 | $token = $firstTask->getTokens($instance)->item(0); 44 | ``` 45 | ![First task](/docs/diagrams/ParallelGateway_2.svg "First task") 46 | 47 | Complete the first task 48 | ``` 49 | $startActivity->complete($token); 50 | ``` 51 | Execute tokens and run to the next state 52 | ``` 53 | $this->engine->runToNextState(); 54 | ``` 55 | One token arrives to the second task and one to the third task 56 | ``` 57 | $secondTask = $bpmnRepository->getScriptTask('ScriptTask_1'); 58 | $token1 = $secondTask->getTokens($instance)->item(0); 59 | $thirdTask = $bpmnRepository->getScriptTask('ScriptTask_2'); 60 | $token2 = $thirdTask->getTokens($instance)->item(0); 61 | ``` 62 | ![Second task and third task](/docs/diagrams/ParallelGateway_3.svg "Second task and third task") 63 | 64 | 65 | ## License 66 | 67 | ProcessMaker Nayra is open-sourced software licensed under the [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) license. 68 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/StandardLoopCharacteristicsTrait.php: -------------------------------------------------------------------------------- 1 | getProperty(StandardLoopCharacteristicsInterface::BPMN_PROPERTY_TEST_BEFORE); 23 | } 24 | 25 | /** 26 | * @param bool $testBefore 27 | * 28 | * 29 | * @return static 30 | */ 31 | public function setTestBefore(bool $testBefore) 32 | { 33 | return $this->setProperty(StandardLoopCharacteristicsInterface::BPMN_PROPERTY_TEST_BEFORE, $testBefore); 34 | } 35 | 36 | /** 37 | * @return string 38 | */ 39 | public function getLoopMaximum() 40 | { 41 | return $this->getProperty(StandardLoopCharacteristicsInterface::BPMN_PROPERTY_LOOP_MAXIMUM); 42 | } 43 | 44 | /** 45 | * @param string $loopMaximum 46 | * 47 | * @return static 48 | */ 49 | public function setLoopMaximum(string $loopMaximum) 50 | { 51 | return $this->setProperty(StandardLoopCharacteristicsInterface::BPMN_PROPERTY_LOOP_MAXIMUM, $loopMaximum); 52 | } 53 | 54 | /** 55 | * @return FormalExpressionInterface 56 | */ 57 | public function getLoopCondition() 58 | { 59 | return $this->getProperty(StandardLoopCharacteristicsInterface::BPMN_PROPERTY_LOOP_CONDITION); 60 | } 61 | 62 | /** 63 | * @param FormalExpressionInterface $loopCondition 64 | * 65 | * @return static 66 | */ 67 | public function setLoopCondition(FormalExpressionInterface $loopCondition) 68 | { 69 | return $this->setProperty(StandardLoopCharacteristicsInterface::BPMN_PROPERTY_LOOP_CONDITION, $loopCondition); 70 | } 71 | 72 | /** 73 | * Should close tokens after each loop? 74 | * 75 | * @return bool 76 | */ 77 | public function shouldCloseTokensEachLoop() 78 | { 79 | return true; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/TerminateTransition.php: -------------------------------------------------------------------------------- 1 | eventDefinition->assertsRule($this->eventDefinition, $this->owner, $executionInstance); 36 | } 37 | 38 | /** 39 | * @param CollectionInterface $consumeTokens 40 | * @param ExecutionInstanceInterface $executionInstance 41 | * 42 | * @return bool 43 | */ 44 | protected function doTransit(CollectionInterface $consumeTokens, ExecutionInstanceInterface $executionInstance) 45 | { 46 | // Terminate events must close all active tokens 47 | foreach ($executionInstance->getTokens() as $token) { 48 | if ($this->assertCondition($token, $executionInstance)) { 49 | $this->eventDefinition->execute($this->eventDefinition, $this->owner, $executionInstance, $token); 50 | $token->setStatus('CLOSED'); 51 | } 52 | } 53 | 54 | return $this->doTransitTrait($consumeTokens, $executionInstance); 55 | } 56 | 57 | /** 58 | * Set the event definition that terminates the process. 59 | * 60 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\EventDefinitionInterface $eventDefinition 61 | */ 62 | public function setEventDefinition(EventDefinitionInterface $eventDefinition) 63 | { 64 | $this->eventDefinition = $eventDefinition; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/LoopCardinalityInterface.php: -------------------------------------------------------------------------------- 1 | properties[static::BPMN_PROPERTY_DATA_INPUT_ASSOCIATION] = new Collection; 32 | $this->properties[static::BPMN_PROPERTY_DATA_INPUT] = new Collection; 33 | $this->setProperty(static::BPMN_PROPERTY_EVENT_DEFINITIONS, new Collection); 34 | } 35 | 36 | /** 37 | * Get BPMN event classes. 38 | * 39 | * @return array 40 | */ 41 | protected function getBpmnEventClasses() 42 | { 43 | return []; 44 | } 45 | 46 | /** 47 | * Get data input associations. 48 | * 49 | * @return \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface 50 | */ 51 | public function getDataInputAssociations() 52 | { 53 | return $this->getProperty(static::BPMN_PROPERTY_DATA_INPUT_ASSOCIATION); 54 | } 55 | 56 | /** 57 | * Get data inputs. 58 | * 59 | * @return \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface 60 | */ 61 | public function getDataInputs() 62 | { 63 | return $this->getProperty(static::BPMN_PROPERTY_DATA_INPUT); 64 | } 65 | 66 | /** 67 | * Get event definitions. 68 | * 69 | * @return \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface 70 | */ 71 | public function getEventDefinitions() 72 | { 73 | return $this->getProperty(static::BPMN_PROPERTY_EVENT_DEFINITIONS); 74 | } 75 | 76 | /** 77 | * Get input set. 78 | * 79 | * @return \ProcessMaker\Nayra\Contracts\Bpmn\InputSetInterface 80 | */ 81 | public function getInputSet() 82 | { 83 | return $this->inputSet; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/Models/EndEvent.php: -------------------------------------------------------------------------------- 1 | properties[static::BPMN_PROPERTY_DATA_INPUT_ASSOCIATION] = new Collection(); 31 | $this->properties[static::BPMN_PROPERTY_DATA_INPUT] = new Collection; 32 | $this->setProperty(static::BPMN_PROPERTY_EVENT_DEFINITIONS, new Collection); 33 | } 34 | 35 | /** 36 | * Array map of custom event classes for the bpmn element. 37 | * 38 | * @return array 39 | */ 40 | protected function getBpmnEventClasses() 41 | { 42 | return []; 43 | } 44 | 45 | /** 46 | * @param EventDefinitionInterface $message 47 | * @param TokenInterface $token 48 | * @return \ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface[] 49 | */ 50 | public function getTargetInstances(EventDefinitionInterface $message, TokenInterface $token) 51 | { 52 | return $this->getOwnerProcess()->getInstances(); 53 | } 54 | 55 | /** 56 | * Get Data Inputs for the throw Event. 57 | * 58 | * @return DataInputInterface[] 59 | */ 60 | public function getDataInputs() 61 | { 62 | return $this->getProperty(static::BPMN_PROPERTY_DATA_INPUT); 63 | } 64 | 65 | /** 66 | * Get Data Associations of the throw Event. 67 | * 68 | * @return DataInputAssociationInterface[] 69 | */ 70 | public function getDataInputAssociations() 71 | { 72 | return $this->getProperty(static::BPMN_PROPERTY_DATA_INPUT_ASSOCIATION); 73 | } 74 | 75 | /** 76 | * Get InputSet for the throw Event. 77 | * 78 | * @return InputSetInterface 79 | */ 80 | public function getInputSet() 81 | { 82 | return $this->inputSet; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/FormalExpressionTrait.php: -------------------------------------------------------------------------------- 1 | getProperty(FormalExpressionInterface::BPMN_PROPERTY_BODY); 29 | $regexpValidDate = '/^[0-9]{4}-[0-9]{2}-[0-9]{2}[T ][0-9]{2}:[0-9]{2}(:[0-9]{2})?(?:[\+-][0-9]{2}:[0-9]{2}|Z)?/'; 30 | if (preg_match($regexpValidDate, $expression)) { 31 | $date = new DateTime($expression); 32 | 33 | return $date; 34 | } else { 35 | return null; 36 | } 37 | } 38 | 39 | /** 40 | * Get a DatePeriod if the expression is a cycle. 41 | * 42 | * Ex. R4/2018-05-01T00:00:00Z/PT1M 43 | * R/2018-05-01T00:00:00Z/PT1M/2025-10-02T00:00:00Z 44 | * 45 | * @return DatePeriod 46 | */ 47 | protected function getCycleExpression() 48 | { 49 | $expression = $this->getProperty(FormalExpressionInterface::BPMN_PROPERTY_BODY); 50 | try { 51 | //Improve Repeating intervals (R/start/interval/end) configuration 52 | if (preg_match('/^R\/([^\/]+)\/([^\/]+)\/([^\/]+)$/', $expression, $repeating)) { 53 | $cycle = new DatePeriod(new DateTime($repeating[1]), new DateInterval($repeating[2]), new DateTime($repeating[3])); 54 | } else { 55 | $cycle = new DatePeriod($expression); 56 | } 57 | } catch (Exception $e) { 58 | $cycle = false; 59 | } 60 | 61 | return $cycle; 62 | } 63 | 64 | /** 65 | * Get a DateInterval if the expression is a duration. 66 | * 67 | * @return \DateInterval 68 | */ 69 | protected function getDurationExpression() 70 | { 71 | $expression = $this->getProperty(FormalExpressionInterface::BPMN_PROPERTY_BODY); 72 | try { 73 | $duration = new DateInterval($expression); 74 | } catch (Exception $e) { 75 | $duration = false; 76 | } 77 | 78 | return $duration; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/CollectionInterface.php: -------------------------------------------------------------------------------- 1 | getProperty(self::BPMN_PROPERTY_DATA_OUTPUT); 24 | } 25 | 26 | /** 27 | * @param CollectionInterface $dataOutput 28 | * 29 | * @return static 30 | */ 31 | public function setDataOutput(CollectionInterface $dataOutput) 32 | { 33 | return $this->setProperty(self::BPMN_PROPERTY_DATA_OUTPUT, $dataOutput); 34 | } 35 | 36 | /** 37 | * @return CollectionInterface 38 | */ 39 | public function getDataInput() 40 | { 41 | return $this->getProperty(self::BPMN_PROPERTY_DATA_INPUT); 42 | } 43 | 44 | /** 45 | * @param CollectionInterface $dataInput 46 | * 47 | * @return static 48 | */ 49 | public function setDataInput(CollectionInterface $dataInput) 50 | { 51 | return $this->setProperty(self::BPMN_PROPERTY_DATA_INPUT, $dataInput); 52 | } 53 | 54 | /** 55 | * @return InputSetInterface 56 | */ 57 | public function getInputSet() 58 | { 59 | return $this->getProperty(self::BPMN_PROPERTY_DATA_INPUT_SET); 60 | } 61 | 62 | /** 63 | * @param InputSetInterface $inputSet 64 | * 65 | * @return static 66 | */ 67 | public function setInputSet(InputSetInterface $inputSet) 68 | { 69 | return $this->setProperty(self::BPMN_PROPERTY_DATA_INPUT_SET, $inputSet); 70 | } 71 | 72 | /** 73 | * @return OutputSetInterface 74 | */ 75 | public function getOutputSet() 76 | { 77 | return $this->getProperty(self::BPMN_PROPERTY_DATA_OUTPUT_SET); 78 | } 79 | 80 | /** 81 | * @param OutputSetInterface $outputSet 82 | * 83 | * @return static 84 | */ 85 | public function setOutputSet(OutputSetInterface $outputSet) 86 | { 87 | return $this->setProperty(self::BPMN_PROPERTY_DATA_OUTPUT_SET, $outputSet); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Bpmn/DataStoreInterface.php: -------------------------------------------------------------------------------- 1 | '', 20 | 'APP_TITLE' => null, 21 | 'APP_DESCRIPTION' => null, 22 | 'APP_NUMBER' => '0', 23 | 'APP_PARENT' => '0', 24 | 'APP_STATUS' => '', 25 | 'APP_STATUS_ID' => '0', 26 | 'PRO_UID' => '', 27 | 'APP_PROC_STATUS' => '', 28 | 'APP_PROC_CODE' => '', 29 | 'APP_PARALLEL' => 'NO', 30 | 'APP_INIT_USER' => '', 31 | 'APP_CUR_USER' => '', 32 | 'APP_CREATE_DATE' => null, 33 | 'APP_INIT_DATE' => null, 34 | 'APP_FINISH_DATE' => null, 35 | 'APP_UPDATE_DATE' => null, 36 | 'APP_DATA' => null, 37 | 'APP_PIN' => '', 38 | 'APP_DURATION' => '0', 39 | 'APP_DELAY_DURATION' => '0', 40 | 'APP_DRIVE_FOLDER_UID' => '', 41 | 'APP_ROUTING_DATA' => null, 42 | ]; 43 | 44 | /** 45 | * Child elements. 46 | */ 47 | const ELEMENTS = [ 48 | 49 | ]; 50 | 51 | /** 52 | * Get data from store. 53 | * 54 | * @param string $name 55 | * @param mixed $default 56 | * 57 | * @return mixed 58 | */ 59 | public function getData($name = null, $default = null); 60 | 61 | /** 62 | * Set data of the store. 63 | * 64 | * @param mixed $data 65 | * 66 | * @return $this 67 | */ 68 | public function setData($data); 69 | 70 | /** 71 | * Put data to store. 72 | * 73 | * @param string $name 74 | * @param mixed $data 75 | * 76 | * @return $this 77 | */ 78 | public function putData($name, $data); 79 | 80 | /** 81 | * Set data using dot notation. 82 | * 83 | * @param string $path Dot notation path (e.g., 'user.profile.name') 84 | * @param mixed $value Value to set 85 | * 86 | * @return $this 87 | */ 88 | public function setDotData($path, $value); 89 | 90 | /** 91 | * Get data using dot notation. 92 | * 93 | * @param string $path Dot notation path (e.g., 'user.profile.name') 94 | * @param mixed $default Default value if path doesn't exist 95 | * 96 | * @return mixed 97 | */ 98 | public function getDotData($path, $default = null); 99 | } 100 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Contracts/Storage/BpmnElementInterface.php: -------------------------------------------------------------------------------- 1 | getOwner()->getLoopCharacteristics(); 30 | if ($loop && $loop->isExecutable()) { 31 | return $loop->isDataInputValid($executionInstance, $token) && !$loop->isLoopCompleted($executionInstance, $token); 32 | } 33 | 34 | return true; 35 | } 36 | 37 | /** 38 | * Get transition owner element 39 | * 40 | * @return ActivityInterface 41 | */ 42 | public function getOwner() 43 | { 44 | return $this->owner; 45 | } 46 | 47 | /** 48 | * Activate the next state. 49 | * 50 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\ConnectionInterface $flow 51 | * @param \ProcessMaker\Nayra\Contracts\Engine\ExecutionInstanceInterface $instance 52 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface $consumeTokens 53 | * @param array $properties 54 | * @param \ProcessMaker\Nayra\Contracts\Bpmn\TransitionInterface|null $source 55 | * 56 | * @return TokenInterface 57 | */ 58 | protected function activateNextState(ConnectionInterface $flow, ExecutionInstanceInterface $instance, CollectionInterface $consumeTokens, array $properties = [], TransitionInterface $source = null) 59 | { 60 | $nextState = $flow->targetState(); 61 | $loop = $this->getOwner()->getLoopCharacteristics(); 62 | if ($loop && $loop->isExecutable()) { 63 | $loop->iterateNextState($nextState, $instance, $consumeTokens, $properties, $source); 64 | } else { 65 | $nextState->addNewToken($instance, $properties, $source); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/ProcessMaker/Nayra/Bpmn/TraversableTrait.php: -------------------------------------------------------------------------------- 1 | outgoing = new Collection; 28 | $this->incoming = new Collection; 29 | } 30 | 31 | /** 32 | * This attribute identifies the outgoing Sequence Flow of the FlowNode. 33 | * 34 | * @return Collection 35 | */ 36 | public function outgoing() 37 | { 38 | return $this->outgoing; 39 | } 40 | 41 | /** 42 | * This attribute identifies the incoming Sequence Flow of the FlowNode. 43 | * 44 | * @return Collection 45 | */ 46 | public function incoming() 47 | { 48 | return $this->incoming; 49 | } 50 | 51 | /** 52 | * @param ConnectionNodeInterface $target 53 | * 54 | * @return ConnectionInterface 55 | */ 56 | public function connectTo(ConnectionNodeInterface $target) 57 | { 58 | $flow = new Connection($this, $target); 59 | $this->outgoing()->push($flow); 60 | $target->incoming()->push($flow); 61 | 62 | return $flow; 63 | } 64 | 65 | /** 66 | * Find all the paths that complies with the $condition and $while. 67 | * 68 | * @param callable $condition 69 | * @param callable $while 70 | * @param array $path 71 | * @param array $passedthru 72 | * @param array $paths 73 | * 74 | * @return Collection 75 | */ 76 | public function paths(callable $condition, callable $while, $path = [], &$passedthru = [], &$paths = []) 77 | { 78 | $this->incoming()->find(function ($flow) use ($condition, $while, $path, &$passedthru, &$paths) { 79 | if (array_search($flow, $passedthru, true) !== false) { 80 | return; 81 | } 82 | $passedthru[] = $flow; 83 | if ($condition($flow)) { 84 | $path[] = $flow; 85 | $paths[] = new Path($path); 86 | } elseif ($while($flow)) { 87 | $path[] = $flow; 88 | $flow->origin()->paths($condition, $while, $path, $passedthru, $paths); 89 | } 90 | }); 91 | 92 | return new Collection($paths); 93 | } 94 | } 95 | --------------------------------------------------------------------------------