├── .gitignore ├── .buildpath ├── .php_cs ├── docker-compose.yml.dist ├── .github └── PULL_REQUEST_TEMPLATE.md ├── src ├── Workflow │ ├── Participant │ │ ├── ParticipantException.php │ │ ├── UserToken.php │ │ ├── UserResource.php │ │ └── SecurityParticipant.php │ └── Operation │ │ └── OperationRunnerDelegate.php ├── PHPMentorsWorkflowerBundle.php ├── Process │ ├── WorkflowContext.php │ └── ProcessFactory.php ├── DependencyInjection │ ├── Configuration.php │ ├── Compiler │ │ └── AlterDefinitionsIntoProcessAwarePass.php │ └── PHPMentorsWorkflowerExtension.php ├── Persistence │ └── DoctrineLifecycleListener.php └── Resources │ └── config │ └── services.xml ├── LICENSE ├── composer.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /.composer/ 2 | /.idea/ 3 | /.php_cs.cache 4 | /.project 5 | /.settings/ 6 | /composer.lock 7 | /composer.phar 8 | /docker-compose.yml 9 | /php-cs-fixer.phar 10 | /vendor/ 11 | *.iml 12 | -------------------------------------------------------------------------------- /.buildpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | in(__DIR__.'/src') 4 | ; 5 | 6 | return Symfony\CS\Config\Config::create() 7 | ->fixers(array('-empty_return', '-blankline_after_open_tag', 'ordered_use', '-phpdoc_no_empty_return')) 8 | ->finder($finder) 9 | ; 10 | -------------------------------------------------------------------------------- /docker-compose.yml.dist: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | app: 4 | container_name: "phpmentors.workflower-bundle.app" 5 | image: "phpmentors/php-app:php53" 6 | volumes: 7 | - ".:/var/app" 8 | environment: 9 | TERM: "xterm" 10 | TZ: "Asia/Tokyo" 11 | LANG: "ja_JP.UTF-8" 12 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | | Q | A 2 | | ------------- | --- 3 | | Branch? | master for new features / 1.2 for fixes 4 | | Bug fix? | yes/no 5 | | New feature? | yes/no 6 | | BC breaks? | yes/no 7 | | Deprecations? | yes/no 8 | | Tests pass? | yes/no 9 | | Fixed tickets | comma-separated list of tickets fixed by the PR, if any 10 | | License | BSD-2-Clause 11 | -------------------------------------------------------------------------------- /src/Workflow/Participant/ParticipantException.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Workflow\Participant; 14 | 15 | class ParticipantException extends \RuntimeException 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Workflow/Participant/UserToken.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Workflow\Participant; 14 | 15 | use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; 16 | use Symfony\Component\Security\Core\User\UserInterface; 17 | 18 | /** 19 | * @since Class available since Release 1.4.0 20 | */ 21 | class UserToken extends AbstractToken 22 | { 23 | /** 24 | * @param UserInterface $user 25 | */ 26 | public function __construct(UserInterface $user) 27 | { 28 | parent::__construct($user->getRoles()); 29 | 30 | $this->setUser($user); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function getCredentials() 37 | { 38 | return ''; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/PHPMentorsWorkflowerBundle.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle; 14 | 15 | use PHPMentors\WorkflowerBundle\DependencyInjection\Compiler\AlterDefinitionsIntoProcessAwarePass; 16 | use PHPMentors\WorkflowerBundle\DependencyInjection\PHPMentorsWorkflowerExtension; 17 | use Symfony\Component\DependencyInjection\ContainerBuilder; 18 | use Symfony\Component\HttpKernel\Bundle\Bundle; 19 | 20 | class PHPMentorsWorkflowerBundle extends Bundle 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function build(ContainerBuilder $container) 26 | { 27 | $container->addCompilerPass(new AlterDefinitionsIntoProcessAwarePass()); 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function getContainerExtension() 34 | { 35 | if ($this->extension === null) { 36 | $this->extension = new PHPMentorsWorkflowerExtension(); 37 | } 38 | 39 | return $this->extension; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2017 KUBO Atsuhiro , 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 | POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /src/Workflow/Participant/UserResource.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Workflow\Participant; 14 | 15 | use PHPMentors\Workflower\Workflow\Resource\ResourceInterface; 16 | use Symfony\Component\Security\Core\User\UserInterface; 17 | 18 | /** 19 | * @since Class available since Release 1.4.0 20 | */ 21 | class UserResource implements ResourceInterface 22 | { 23 | /** 24 | * @var mixed 25 | */ 26 | private $user; 27 | 28 | /** 29 | * @param mixed $user 30 | */ 31 | public function __construct($user) 32 | { 33 | $this->user = $user; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function getId() 40 | { 41 | if ($this->user instanceof UserInterface) { 42 | return $this->user->getUsername(); 43 | } else { 44 | return (string) $this->user; 45 | } 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function getName() 52 | { 53 | return $this->getId(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Process/WorkflowContext.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Process; 14 | 15 | use PHPMentors\Workflower\Process\WorkflowContextInterface; 16 | 17 | /** 18 | * @since Class available since Release 1.1.0 19 | */ 20 | class WorkflowContext implements WorkflowContextInterface 21 | { 22 | /** 23 | * @var int|string 24 | */ 25 | private $workflowContextId; 26 | 27 | /** 28 | * @var int|string 29 | */ 30 | private $workflowId; 31 | 32 | /** 33 | * @param int|string $workflowContextId 34 | * @param int|string $workflowId 35 | */ 36 | public function __construct($workflowContextId, $workflowId) 37 | { 38 | $this->workflowContextId = $workflowContextId; 39 | $this->workflowId = $workflowId; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function getWorkflowId() 46 | { 47 | return $this->workflowId; 48 | } 49 | 50 | /** 51 | * @return int|string 52 | */ 53 | public function getWorkflowContextId() 54 | { 55 | return $this->workflowContextId; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phpmentors/workflower-bundle", 3 | "type": "symfony-bundle", 4 | "description": "A Symfony bundle for Workflower", 5 | "keywords": ["flow", "workflow", "process", "bpm", "bpmn", "bpms", "symfony"], 6 | "license": "BSD-2-Clause", 7 | "authors": [ 8 | { 9 | "name": "KUBO Atsuhiro", 10 | "email": "kubo@iteman.jp" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.3.9", 15 | "phpmentors/workflower": "~1.2", 16 | "symfony/config": "~2.8 || ~3.0 || ~4.0", 17 | "symfony/dependency-injection": "~2.8 || ~3.0 || ~4.0", 18 | "symfony/finder": "~2.8 || ~3.0 || ~4.0", 19 | "symfony/http-kernel": "~2.8 || ~3.0 || ~4.0", 20 | "symfony/security-core": "~2.8 || ~3.0 || ~4.0", 21 | "symfony/security-bundle": "~2.8 || ~3.0 || ~4.0" 22 | }, 23 | "require-dev": { 24 | "doctrine/orm": "~2.4", 25 | "symfony/doctrine-bridge": "~2.8 || ~3.0 || ~4.0" 26 | }, 27 | "suggest": { 28 | "doctrine/orm": ">= 2.4.0 provides transparent serialization/deserialization support for entities with Doctrine ORM", 29 | "symfony/doctrine-bridge": ">=2.8.0 provides transparent serialization/deserialization support for entities with Doctrine ORM" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "PHPMentors\\WorkflowerBundle\\": "src/" 34 | } 35 | }, 36 | "extra": { 37 | "branch-alias": { 38 | "dev-master": "1.5.x-dev" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\DependencyInjection; 14 | 15 | use Symfony\Component\Config\Definition\Builder\TreeBuilder; 16 | use Symfony\Component\Config\Definition\ConfigurationInterface; 17 | 18 | class Configuration implements ConfigurationInterface 19 | { 20 | /** 21 | * {@inheritdoc} 22 | */ 23 | public function getConfigTreeBuilder() 24 | { 25 | $treeBuilder = new TreeBuilder(); 26 | $treeBuilder->root('phpmentors_workflower') 27 | ->children() 28 | ->scalarNode('serializer_service') 29 | ->defaultValue('phpmentors_workflower.php_workflow_serializer') 30 | ->end() 31 | ->arrayNode('workflow_contexts') 32 | ->prototype('array') 33 | ->children() 34 | ->scalarNode('definition_dir') 35 | ->isRequired() 36 | ->cannotBeEmpty() 37 | ->end() 38 | ->end() 39 | ->end() 40 | ->end() 41 | ->end() 42 | ; 43 | 44 | return $treeBuilder; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Process/ProcessFactory.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Process; 14 | 15 | use PHPMentors\Workflower\Process\Process; 16 | 17 | /** 18 | * @since Class available since Release 1.3.0 19 | */ 20 | class ProcessFactory 21 | { 22 | /** 23 | * @var array 24 | */ 25 | private $processes = array(); 26 | 27 | /** 28 | * @param Process $process 29 | */ 30 | public function addProcess(Process $process) 31 | { 32 | $workflowContext = $process->getWorkflowContext(); 33 | assert($workflowContext instanceof WorkflowContext); 34 | 35 | $this->processes[$workflowContext->getWorkflowContextId()][$workflowContext->getWorkflowId()] = $process; 36 | } 37 | 38 | /** 39 | * @param int|string $workflowContextId 40 | * @param int|string $workflowId 41 | * 42 | * @return Process 43 | * 44 | * @throws \InvalidArgumentException 45 | */ 46 | public function create($workflowContextId, $workflowId) 47 | { 48 | if (!array_key_exists($workflowContextId, $this->processes)) { 49 | throw new \InvalidArgumentException(sprintf('The workflow context "%s" is not found.', $workflowContextId)); 50 | } 51 | 52 | if (!array_key_exists($workflowId, $this->processes[$workflowContextId])) { 53 | throw new \InvalidArgumentException(sprintf('The workflow "%s" is not found in the context "%s".', $workflowId, $workflowContextId)); 54 | } 55 | 56 | return $this->processes[$workflowContextId][$workflowId]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Workflow/Operation/OperationRunnerDelegate.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Workflow\Operation; 14 | 15 | use PHPMentors\Workflower\Workflow\Operation\OperationalInterface; 16 | use PHPMentors\Workflower\Workflow\Operation\OperationRunnerInterface; 17 | use PHPMentors\Workflower\Workflow\Workflow; 18 | use Symfony\Component\DependencyInjection\ContainerAwareInterface; 19 | use Symfony\Component\DependencyInjection\ContainerInterface; 20 | 21 | /** 22 | * @since Class available since Release 1.2.0 23 | */ 24 | class OperationRunnerDelegate implements OperationRunnerInterface, ContainerAwareInterface 25 | { 26 | /** 27 | * @var ContainerInterface 28 | */ 29 | private $container; 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function setContainer(ContainerInterface $container = null) 35 | { 36 | $this->container = $container; 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function provideParticipant(OperationalInterface $operational, Workflow $workflow) 43 | { 44 | assert($this->container !== null); 45 | 46 | $operationRunner = $this->container->get($operational->getOperation()); 47 | assert($operationRunner instanceof OperationRunnerInterface); 48 | 49 | return $operationRunner->provideParticipant($operational, $workflow); 50 | } 51 | 52 | /** 53 | * {@inheritdoc} 54 | */ 55 | public function run(OperationalInterface $operational, Workflow $workflow) 56 | { 57 | assert($this->container !== null); 58 | 59 | $operationRunner = $this->container->get($operational->getOperation()); 60 | assert($operationRunner instanceof OperationRunnerInterface); 61 | 62 | return $operationRunner->run($operational, $workflow); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Persistence/DoctrineLifecycleListener.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Persistence; 14 | 15 | use Doctrine\ORM\Event\LifecycleEventArgs; 16 | use Doctrine\ORM\Event\PreUpdateEventArgs; 17 | use PHPMentors\Workflower\Persistence\WorkflowSerializableInterface; 18 | use PHPMentors\Workflower\Persistence\WorkflowSerializerInterface; 19 | 20 | class DoctrineLifecycleListener 21 | { 22 | /** 23 | * @var WorkflowSerializerInterface 24 | */ 25 | private $workflowSerializer; 26 | 27 | /** 28 | * @param WorkflowSerializerInterface $workflowSerializer 29 | */ 30 | public function __construct(WorkflowSerializerInterface $workflowSerializer) 31 | { 32 | $this->workflowSerializer = $workflowSerializer; 33 | } 34 | 35 | /** 36 | * @param LifecycleEventArgs $eventArgs 37 | */ 38 | public function prePersist(LifecycleEventArgs $eventArgs) 39 | { 40 | $entity = $eventArgs->getEntity(); 41 | if ($entity instanceof WorkflowSerializableInterface && $entity->getWorkflow() !== null) { 42 | $entity->setSerializedWorkflow($this->workflowSerializer->serialize($entity->getWorkflow())); 43 | } 44 | } 45 | 46 | /** 47 | * @param PreUpdateEventArgs $eventArgs 48 | */ 49 | public function preUpdate(PreUpdateEventArgs $eventArgs) 50 | { 51 | $entity = $eventArgs->getEntity(); 52 | if ($entity instanceof WorkflowSerializableInterface && $entity->getWorkflow() !== null) { 53 | $entity->setSerializedWorkflow($this->workflowSerializer->serialize($entity->getWorkflow())); 54 | } 55 | } 56 | 57 | /** 58 | * @param LifecycleEventArgs $eventArgs 59 | */ 60 | public function postLoad(LifecycleEventArgs $eventArgs) 61 | { 62 | $entity = $eventArgs->getEntity(); 63 | if ($entity instanceof WorkflowSerializableInterface && $entity->getSerializedWorkflow() !== null) { 64 | $entity->setWorkflow($this->workflowSerializer->deserialize($entity->getSerializedWorkflow())); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHPMentorsWorkflowerBundle 2 | 3 | A Symfony bundle for [Workflower](https://github.com/phpmentors-jp/workflower) 4 | 5 | [![Total Downloads](https://poser.pugx.org/phpmentors/workflower-bundle/downloads)](https://packagist.org/packages/phpmentors/workflower-bundle) 6 | [![Latest Stable Version](https://poser.pugx.org/phpmentors/workflower-bundle/v/stable)](https://packagist.org/packages/phpmentors/workflower-bundle) 7 | [![Latest Unstable Version](https://poser.pugx.org/phpmentors/workflower-bundle/v/unstable)](https://packagist.org/packages/phpmentors/workflower-bundle) 8 | 9 | ## Features 10 | 11 | * Integration with the service container by the `phpmentors_workflower.process_aware` tag 12 | * Integration with the security system for workflow participants 13 | * Transparent serialization/deserialization support for entities with Doctrine ORM 14 | * Multiple workflow contexts (which are directories where BPMN files are stored) 15 | 16 | ## Installation 17 | 18 | `PHPMentorsWorkflowerBundle` can be installed using [Composer](http://getcomposer.org/). 19 | 20 | First, add the dependency to `phpmentors/workflower-bundle` into your `composer.json` file as the following: 21 | 22 | **Stable version:** 23 | 24 | ``` 25 | composer require phpmentors/workflower-bundle "1.4.*" 26 | ``` 27 | 28 | **Development version:** 29 | 30 | ``` 31 | composer require phpmentors/workflower-bundle "~1.5@dev" 32 | ``` 33 | 34 | Second, add `PHPMentorsWorkflowerBundle` into your bundles to register in `AppKernel::registerBundles()` as the following: 35 | 36 | ```php 37 | // ... 38 | class AppKernel extends Kernel 39 | { 40 | public function registerBundles() 41 | { 42 | $bundles = array( 43 | // ... 44 | new PHPMentors\WorkflowerBundle\PHPMentorsWorkflowerBundle(), 45 | ); 46 | // ... 47 | ``` 48 | 49 | ## Configuration 50 | 51 | `app/config/config.yml:` 52 | 53 | ```yaml 54 | # ... 55 | 56 | phpmentors_workflower: 57 | serializer_service: phpmentors_workflower.base64_php_workflow_serializer # Defaults to `phpmentors_workflower.php_workflow_serializer` 58 | workflow_contexts: 59 | app: 60 | definition_dir: "%kernel.root_dir%/../src/AppBundle/Resources/config/workflower" # A directory where BPMN files for the `app` context are stored 61 | ``` 62 | 63 | ## Documentation 64 | 65 | * [Quick Start Guide](https://github.com/phpmentors-jp/workflower/blob/master/docs/quick-start-guide.md) 66 | * [Release Notes](https://github.com/phpmentors-jp/workflower-bundle/releases) 67 | 68 | ## Support 69 | 70 | If you find a bug or have a question, or want to request a feature, create an issue or pull request for it on [Issues](https://github.com/phpmentors-jp/workflower-bundle/issues). 71 | 72 | ## Copyright 73 | 74 | Copyright (c) 2015-2017 KUBO Atsuhiro, All rights reserved. 75 | 76 | ## License 77 | 78 | [The BSD 2-Clause License](http://opensource.org/licenses/BSD-2-Clause) 79 | -------------------------------------------------------------------------------- /src/DependencyInjection/Compiler/AlterDefinitionsIntoProcessAwarePass.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\DependencyInjection\Compiler; 14 | 15 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 16 | use Symfony\Component\DependencyInjection\ContainerBuilder; 17 | use Symfony\Component\DependencyInjection\Reference; 18 | 19 | class AlterDefinitionsIntoProcessAwarePass implements CompilerPassInterface 20 | { 21 | /** 22 | * {@inheritdoc} 23 | * 24 | * @throws \InvalidArgumentException 25 | */ 26 | public function process(ContainerBuilder $container) 27 | { 28 | foreach ($container->findTaggedServiceIds('phpmentors_workflower.process_aware') as $serviceId => $tagAttributes) { 29 | $class = new \ReflectionClass($container->getParameterBag()->resolveValue($container->getDefinition($serviceId)->getClass())); 30 | if (!$class->implementsInterface('PHPMentors\Workflower\Process\ProcessAwareInterface')) { 31 | throw new \InvalidArgumentException(sprintf( 32 | 'The class "%s" must implement "%s".', 33 | $class->getName(), 34 | 'PHPMentors\Workflower\Process\ProcessAwareInterface' 35 | )); 36 | } 37 | 38 | for ($i = 0; $i < count($tagAttributes); ++$i) { 39 | $this->validateTagAttribute($serviceId, 'phpmentors_workflower.process_aware', $tagAttributes[$i], 'context'); 40 | $this->validateTagAttribute($serviceId, 'phpmentors_workflower.process_aware', $tagAttributes[$i], 'workflow'); 41 | $container->getDefinition($serviceId)->addMethodCall('setProcess', array(new Reference('phpmentors_workflower.process.'.sha1($tagAttributes[$i]['context'].$tagAttributes[$i]['workflow'])))); 42 | } 43 | } 44 | } 45 | 46 | /** 47 | * @param string $serviceId 48 | * @param string $tag 49 | * @param array $attributes 50 | * @param string $attribute 51 | * 52 | * @throws \InvalidArgumentException 53 | */ 54 | private function validateTagAttribute($serviceId, $tag, array $attributes, $attribute) 55 | { 56 | if (!array_key_exists($attribute, $attributes)) { 57 | throw new \InvalidArgumentException(sprintf( 58 | 'The service "%s" must define the "%s" attribute on the "%s" tag.', 59 | $serviceId, 60 | $attribute, 61 | $tag 62 | )); 63 | } 64 | 65 | if ($attributes[$attribute] === null || $attributes[$attribute] === '') { 66 | throw new \InvalidArgumentException(sprintf( 67 | 'The value of the "%s" attribute cannot be empty on the "%s" tag.', 68 | $attribute, 69 | $tag 70 | )); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Workflow/Participant/SecurityParticipant.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\Workflow\Participant; 14 | 15 | use PHPMentors\Workflower\Workflow\Participant\ParticipantInterface; 16 | use PHPMentors\Workflower\Workflow\Resource\ResourceInterface; 17 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 18 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 19 | use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; 20 | use Symfony\Component\Security\Core\User\UserInterface; 21 | 22 | class SecurityParticipant implements ParticipantInterface 23 | { 24 | /** 25 | * @var TokenStorageInterface 26 | */ 27 | private $tokenStorage; 28 | 29 | /** 30 | * @var AccessDecisionManagerInterface 31 | * 32 | * @since Property available since Release 1.4.0 33 | */ 34 | private $accessDecisionManager; 35 | 36 | /** 37 | * @var ResourceInterface 38 | */ 39 | private $resource; 40 | 41 | /** 42 | * @param TokenStorageInterface $tokenStorage 43 | * @param AccessDecisionManagerInterface $accessDecisionManager 44 | */ 45 | public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager) 46 | { 47 | $this->tokenStorage = $tokenStorage; 48 | $this->accessDecisionManager = $accessDecisionManager; 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | public function hasRole($role) 55 | { 56 | return $this->accessDecisionManager->decide($this->resource === null ? $this->tokenStorage->getToken() : ($this->resource instanceof UserInterface ? new UserToken($this->resource) : $this->resource), array($role)); 57 | } 58 | 59 | /** 60 | * {@inheritdoc} 61 | */ 62 | public function setResource(ResourceInterface $resource) 63 | { 64 | assert($resource instanceof UserInterface || $resource instanceof TokenInterface); 65 | 66 | $this->resource = $resource; 67 | } 68 | 69 | /** 70 | * {@inheritdoc} 71 | */ 72 | public function getResource() 73 | { 74 | if ($this->resource === null) { 75 | $token = $this->tokenStorage->getToken(); 76 | if ($token === null) { 77 | return null; 78 | } 79 | 80 | $user = $token->getUser(); 81 | if ($user instanceof ResourceInterface) { 82 | return $user; 83 | } 84 | 85 | return new UserResource($user); 86 | } else { 87 | return $this->resource; 88 | } 89 | } 90 | 91 | /** 92 | * {@inheritdoc} 93 | */ 94 | public function getId() 95 | { 96 | return $this->getResource()->getId(); 97 | } 98 | 99 | /** 100 | * {@inheritdoc} 101 | */ 102 | public function getName() 103 | { 104 | return $this->getResource()->getName(); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Resources/config/services.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PHPMentors\Workflower\Persistence\Base64PhpWorkflowSerializer 6 | PHPMentors\Workflower\Definition\Bpmn2File 7 | PHPMentors\Workflower\Definition\Bpmn2WorkflowRepository 8 | PHPMentors\WorkflowerBundle\Persistence\DoctrineLifecycleListener 9 | PHPMentors\WorkflowerBundle\Workflow\Operation\OperationRunnerDelegate 10 | PHPMentors\Workflower\Persistence\PhpWorkflowSerializer 11 | PHPMentors\Workflower\Process\Process 12 | PHPMentors\WorkflowerBundle\Process\ProcessFactory 13 | PHPMentors\WorkflowerBundle\Workflow\Participant\SecurityParticipant 14 | PHPMentors\Workflower\Process\WorkItemContext 15 | PHPMentors\WorkflowerBundle\Process\WorkflowContext 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/DependencyInjection/PHPMentorsWorkflowerExtension.php: -------------------------------------------------------------------------------- 1 | , 4 | * All rights reserved. 5 | * 6 | * This file is part of PHPMentorsWorkflowerBundle. 7 | * 8 | * This program and the accompanying materials are made available under 9 | * the terms of the BSD 2-Clause License which accompanies this 10 | * distribution, and is available at http://opensource.org/licenses/BSD-2-Clause 11 | */ 12 | 13 | namespace PHPMentors\WorkflowerBundle\DependencyInjection; 14 | 15 | use PHPMentors\Workflower\Definition\Bpmn2File; 16 | use Symfony\Component\Config\FileLocator; 17 | use Symfony\Component\DependencyInjection\ChildDefinition; 18 | use Symfony\Component\DependencyInjection\ContainerBuilder; 19 | use Symfony\Component\DependencyInjection\DefinitionDecorator; 20 | use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; 21 | use Symfony\Component\DependencyInjection\Reference; 22 | use Symfony\Component\Finder\Finder; 23 | use Symfony\Component\HttpKernel\DependencyInjection\Extension; 24 | 25 | class PHPMentorsWorkflowerExtension extends Extension 26 | { 27 | /** 28 | * {@inheritdoc} 29 | */ 30 | public function load(array $configs, ContainerBuilder $container) 31 | { 32 | $config = $this->processConfiguration(new Configuration(), $configs); 33 | 34 | $loader = new XmlFileLoader($container, new FileLocator(dirname(__DIR__).'/Resources/config')); 35 | $loader->load('services.xml'); 36 | 37 | $this->transformConfigToContainer($config, $container); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function getAlias() 44 | { 45 | return 'phpmentors_workflower'; 46 | } 47 | 48 | /** 49 | * @param array $config 50 | * @param ContainerBuilder $container 51 | */ 52 | private function transformConfigToContainer(array $config, ContainerBuilder $container) 53 | { 54 | $childDefinitionClass = $this->getChildDefinitionClass(); 55 | 56 | $workflowSerializerDefinition = $container->getDefinition('phpmentors_workflower.workflow_serializer'); 57 | $container->setAlias('phpmentors_workflower.workflow_serializer', $config['serializer_service']); 58 | $container->getAlias('phpmentors_workflower.workflow_serializer')->setPublic($workflowSerializerDefinition->isPublic()); 59 | 60 | foreach ($config['workflow_contexts'] as $workflowContextId => $workflowContext) { 61 | $workflowContextIdHash = sha1($workflowContextId); 62 | $bpmn2WorkflowRepositoryDefinition = new $childDefinitionClass('phpmentors_workflower.bpmn2_workflow_repository'); 63 | $bpmn2WorkflowRepositoryServiceId = 'phpmentors_workflower.bpmn2_workflow_repository.'.$workflowContextIdHash; 64 | $container->setDefinition($bpmn2WorkflowRepositoryServiceId, $bpmn2WorkflowRepositoryDefinition); 65 | 66 | $definitionFiles = Finder::create() 67 | ->files() 68 | ->in($workflowContext['definition_dir']) 69 | ->depth('== 0') 70 | ->sortByName() 71 | ; 72 | foreach ($definitionFiles as $definitionFile) { 73 | $workflowId = Bpmn2File::getWorkflowId($definitionFile->getFilename()); 74 | $bpmn2FileDefinition = new $childDefinitionClass('phpmentors_workflower.bpmn2_file'); 75 | $bpmn2FileDefinition->setArguments(array($definitionFile->getPathname())); 76 | $bpmn2FileServiceId = 'phpmentors_workflower.bpmn2_file.'.sha1($workflowContextId.$workflowId); 77 | $container->setDefinition($bpmn2FileServiceId, $bpmn2FileDefinition); 78 | 79 | $bpmn2WorkflowRepositoryDefinition->addMethodCall('add', array(new Reference($bpmn2FileServiceId))); 80 | 81 | $workflowContextDefinition = new $childDefinitionClass('phpmentors_workflower.workflow_context'); 82 | $workflowContextDefinition->setArguments(array($workflowContextId, $workflowId)); 83 | $workflowContextServiceId = 'phpmentors_workflower.workflow_context.'.sha1($workflowContextId.$workflowId); 84 | $container->setDefinition($workflowContextServiceId, $workflowContextDefinition); 85 | 86 | $processDefinition = new $childDefinitionClass('phpmentors_workflower.process'); 87 | $processDefinition->setArguments(array( 88 | new Reference($workflowContextServiceId), 89 | new Reference($bpmn2WorkflowRepositoryServiceId), 90 | new Reference('phpmentors_workflower.operation_runner_delegate'), 91 | )); 92 | $processServiceId = 'phpmentors_workflower.process.'.sha1($workflowContextId.$workflowId); 93 | $container->setDefinition($processServiceId, $processDefinition); 94 | 95 | $container->getDefinition('phpmentors_workflower.process_factory')->addMethodCall('addProcess', array(new Reference($processServiceId))); 96 | } 97 | } 98 | } 99 | 100 | private function getChildDefinitionClass() 101 | { 102 | if (class_exists('Symfony\Component\DependencyInjection\ChildDefinition')) { 103 | return 'Symfony\Component\DependencyInjection\ChildDefinition'; 104 | } 105 | 106 | return 'Symfony\Component\DependencyInjection\DefinitionDecorator'; 107 | } 108 | } 109 | --------------------------------------------------------------------------------