Skip to content

Commit

Permalink
sm-107 Альтернативная реализация модуля через preDispatch
Browse files Browse the repository at this point in the history
  • Loading branch information
Malofeykin Andrey committed Dec 9, 2015
1 parent bb99a34 commit 55bc1bf
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 61 deletions.
10 changes: 4 additions & 6 deletions Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
namespace OldTown\Workflow\ZF2\PreDispatch;


use OldTown\Workflow\ZF2\Service\Workflow;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\EventManager\EventInterface;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\Feature\BootstrapListenerInterface;
use Zend\ModuleManager\Feature\DependencyIndicatorInterface;
use OldTown\Workflow\ZF2\PreDispatch\Listener\InjectTypeResolver;
use OldTown\Workflow\ZF2\PreDispatch\Listener\WorkflowDispatchListener;


/**
Expand Down Expand Up @@ -60,10 +59,9 @@ public function onBootstrap(EventInterface $e)
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);

/** @var Workflow $workflowService */
$workflowService = $e->getApplication()->getServiceManager()->get(Workflow::class);
$listener = $e->getApplication()->getServiceManager()->get(InjectTypeResolver::class);
$workflowService->getEventManager()->attach($listener);
/** @var WorkflowDispatchListener $injectWorkflowListener */
$injectWorkflowListener = $e->getApplication()->getServiceManager()->get(WorkflowDispatchListener::class);
$eventManager->attach($injectWorkflowListener);
}


Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
* [ServiceTypeResolver](./src/TypeResolver/ServiceTypeResolver.php) - резолвер добавляет поддержку новго типа "service"(сервисы ZF2)

При создание нового объекта менеджера workflow, модулем [old-town/workflow-zf2](https://github.com/old-town/workflow-zf2)
бросается событие workflow.manager.create. Обработка этого события осуществляется [InjectTypeResolver](./src/Listener/InjectTypeResolver.php).
бросается событие workflow.manager.create. Обработка этого события осуществляется [WorkflowDispatchListener](./src/Listener/WorkflowDispatchListener.php).
Обработчик:

* Создает [ChainTypeResolver](./src/TypeResolver/ChainTypeResolver.php)
* Добавляет в него TypeResolver установленный в менеджер workflow.
* [InjectTypeResolver](./src/Listener/InjectTypeResolver.php) с помощью своего EventManager'а бросает собыите inject.workflow.type.resolver,
* [WorkflowDispatchListener](./src/Listener/WorkflowDispatchListener.php) с помощью своего EventManager'а бросает собыите inject.workflow.type.resolver,
обработчики данного события должны вернуть объект TypeResolver, который в последствие будет добавлен в ChainTypeResolver
* Обработчки сам подписан на событие inject.workflow.type.resolver, в обработчике возвращается [ServiceTypeResolver](./src/TypeResolver/ServiceTypeResolver.php)
* Устанавливает в workflow в качестве резолвера [ChainTypeResolver](./src/TypeResolver/ChainTypeResolver.php)
Expand Down
5 changes: 4 additions & 1 deletion config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
*/
namespace OldTown\Workflow\ZF2\PreDispatch;

use OldTown\Workflow\ZF2\PreDispatch\Listener\WorkflowDispatchListenerFactory;
use OldTown\Workflow\ZF2\PreDispatch\Options\ModuleOptions;
use OldTown\Workflow\ZF2\PreDispatch\Options\ModuleOptionsFactory;;
use OldTown\Workflow\ZF2\PreDispatch\Options\ModuleOptionsFactory;
use OldTown\Workflow\ZF2\PreDispatch\Listener\WorkflowDispatchListener;

return [
'service_manager' => [
Expand All @@ -15,6 +17,7 @@
],
'factories' => [
ModuleOptions::class => ModuleOptionsFactory::class,
WorkflowDispatchListener::class => WorkflowDispatchListenerFactory::class
],
'abstract_factories' => [

Expand Down
23 changes: 23 additions & 0 deletions config/router.config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/**
* @link https://github.com/old-town/workflow-zf2-preDispatch
* @author Malofeykin Andrey <and-rey2@yandex.ru>
*/
namespace OldTown\Workflow\ZF2\PreDispatch;

return [
'router' => [
'routes' => [
'workflow' => [
'child_routes' => [
'dispatch' => [
'type' => 'Literal',
'options' => [
'route' => 'dispatch/'
],
]
],
]
]
]
];
15 changes: 15 additions & 0 deletions src/Listener/Exception/InvalidWorkflowNameException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* @link https://github.com/old-town/workflow-zf2-preDispatch
* @author Malofeykin Andrey <and-rey2@yandex.ru>
*/
namespace OldTown\Workflow\ZF2\PreDispatch\Listener\Exception;

/**
* Class InvalidWorkflowNameException
*
* @package OldTown\Workflow\ZF2\PreDispatch\Listener\Exception
*/
class InvalidWorkflowNameException extends InvalidArgumentException
{
}
15 changes: 15 additions & 0 deletions src/Listener/Exception/WorkflowDispatchException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* @link https://github.com/old-town/workflow-zf2-preDispatch
* @author Malofeykin Andrey <and-rey2@yandex.ru>
*/
namespace OldTown\Workflow\ZF2\PreDispatch\Listener\Exception;

/**
* Class WorkflowDispatchException
*
* @package OldTown\Workflow\ZF2\PreDispatch\Listener\Exception
*/
class WorkflowDispatchException extends RuntimeException
{
}
47 changes: 0 additions & 47 deletions src/Listener/InjectTypeResolver.php

This file was deleted.

194 changes: 194 additions & 0 deletions src/Listener/WorkflowDispatchListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
<?php
/**
* @link https://github.com/old-town/workflow-zf2-preDispatch
* @author Malofeykin Andrey <and-rey2@yandex.ru>
*/
namespace OldTown\Workflow\ZF2\PreDispatch\Listener;


use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerAwareTrait;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Controller\AbstractController;
use Zend\Mvc\Router\RouteMatch;
use OldTown\Workflow\ZF2\Service\Workflow as WorkflowService;
use OldTown\Workflow\Spi\WorkflowEntryInterface;


/**
* Class InjectTypeResolver
*
* @package OldTown\Workflow\ZF2\PreDispatch\Listener
*/
class WorkflowDispatchListener extends AbstractListenerAggregate
{
use EventManagerAwareTrait;

/**
* @var string
*/
const TRANSITION_RESULT = 'transitionResult';

/**
* @var WorkflowService
*/
protected $workflowService;

/**
* @param array $options
*/
public function __construct(array $options = [])
{
call_user_func_array([$this, 'init'], $options);
}

/**
* @param WorkflowService $workflowService
*/
protected function init(WorkflowService $workflowService)
{
$this->setWorkflowService($workflowService);
}

/**
* @param EventManagerInterface $events
*/
public function attach(EventManagerInterface $events)
{
$events->getSharedManager()->attach(AbstractController::class, MvcEvent::EVENT_DISPATCH, [$this, 'onDispatchWorkflow'], 80);
}

/**
* @param MvcEvent $e
*
* @throws Exception\InvalidArgumentException
* @throws Exception\WorkflowDispatchException
*/
public function onDispatchWorkflow(MvcEvent $e)
{
$routeMatch = $e->getRouteMatch();

if (!$routeMatch instanceof RouteMatch || 0 !== strpos($routeMatch->getMatchedRouteName(), 'workflow/dispatch/')) {
return;
}

$workflowManagerName = $routeMatch->getParam('workflowManagerName', null);
if (null === $workflowManagerName) {
$errMsg = 'Param managerName not found';
throw new Exception\InvalidArgumentException($errMsg);
}

$workflowActionName = $routeMatch->getParam('workflowActionName', null);
if (null === $workflowActionName) {
$errMsg = 'Param actionName not found';
throw new Exception\InvalidArgumentException($errMsg);
}


$workflowName = $routeMatch->getParam('workflowName', null);
$entryId = $routeMatch->getParam('entryId', null);

if (null === $workflowName && null === $entryId) {
$errMsg = 'workflowName and entryId not found';
throw new Exception\InvalidArgumentException($errMsg);
}

try {
if (null !== $entryId) {
if (null !== $workflowName) {
$this->validateWorkflowParams($workflowManagerName, $workflowName, $entryId);
}
$result = $this->doAction($workflowManagerName, $workflowActionName, $entryId);
} else {
$result = $this->initialize($workflowManagerName, $workflowActionName, $workflowName);
}
} catch (\Exception $e) {
throw new Exception\WorkflowDispatchException($e->getMessage(), $e->getCode(), $e);
}

$e->setParam(static::TRANSITION_RESULT, $result);
}


/**
* @param $workflowManagerName
* @param $workflowActionName
* @param $entryId
*
* @return WorkflowService\TransitionResultInterface
*
* @throws \OldTown\Workflow\ZF2\Service\Exception\DoActionException
*/
public function doAction($workflowManagerName, $workflowActionName, $entryId)
{
return $this->getWorkflowService()->doAction($workflowManagerName, $entryId, $workflowActionName);
}


/**
* @param $workflowManagerName
* @param $workflowActionName
* @param $workflowName
*
* @return WorkflowService\TransitionResultInterface
* @throws \OldTown\Workflow\ZF2\Service\Exception\InvalidInitializeWorkflowEntryException
*/
public function initialize($workflowManagerName, $workflowActionName, $workflowName)
{
return $this->getWorkflowService()->initialize($workflowManagerName, $workflowName, $workflowActionName);
}

/**
* @param $workflowManagerName
* @param $workflowName
* @param $entryId
*
* @throws \OldTown\Workflow\ZF2\PreDispatch\Listener\Exception\RuntimeException
* @throws \OldTown\Workflow\ZF2\PreDispatch\Listener\Exception\InvalidWorkflowNameException
*/
public function validateWorkflowParams($workflowManagerName, $workflowName, $entryId)
{
try {
$entry = $this->getWorkflowService()
->getWorkflowManager($workflowManagerName)
->getConfiguration()
->getWorkflowStore()
->findEntry($entryId);

if (!$entry instanceof WorkflowEntryInterface) {
$errMsg = 'Invalid workflow entry';
throw new Exception\RuntimeException($errMsg);
}
} catch (\Exception $e) {
throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e);
}

if ($workflowName !== $entry->getWorkflowName()) {
$errMsg = sprintf('Invalid workflow name %s. Expected: %s', $workflowName, $entry->getWorkflowName());
throw new Exception\InvalidWorkflowNameException($errMsg);
}
}

/**
* @return WorkflowService
*/
public function getWorkflowService()
{
return $this->workflowService;
}

/**
* @param WorkflowService $workflowService
*
* @return $this
*/
public function setWorkflowService(WorkflowService $workflowService)
{
$this->workflowService = $workflowService;

return $this;
}


}
Loading

0 comments on commit 55bc1bf

Please sign in to comment.