Example #1
0
 /**
  * {@inheritDoc}
  */
 public function load(ObjectManager $manager)
 {
     $entityManager = $this->container->get('doctrine')->getManager();
     // first definition
     $firstDefinition = new ProcessDefinition();
     $firstDefinition->setName(self::FIRST_DEFINITION)->setLabel(self::FIRST_DEFINITION)->setRelatedEntity('Test\\Entity')->setExecutionOrder(10);
     $updateTrigger = new ProcessTrigger();
     $updateTrigger->setDefinition($firstDefinition)->setEvent(ProcessTrigger::EVENT_UPDATE)->setField(self::UPDATE_TRIGGER_FIELD);
     $entityManager->persist($firstDefinition);
     $entityManager->persist($updateTrigger);
     // second definition
     $secondDefinition = new ProcessDefinition();
     $secondDefinition->setName(self::SECOND_DEFINITION)->setLabel(self::SECOND_DEFINITION)->setRelatedEntity('Test\\Entity')->setExecutionOrder(20);
     $createTrigger = new ProcessTrigger();
     $createTrigger->setDefinition($secondDefinition)->setEvent(ProcessTrigger::EVENT_CREATE);
     $deleteTrigger = new ProcessTrigger();
     $deleteTrigger->setDefinition($secondDefinition)->setEvent(ProcessTrigger::EVENT_DELETE);
     $entityManager->persist($secondDefinition);
     $entityManager->persist($createTrigger);
     $entityManager->persist($deleteTrigger);
     // disabled definition
     $disabledDefinition = new ProcessDefinition();
     $disabledDefinition->setName(self::DISABLED_DEFINITION)->setLabel(self::DISABLED_DEFINITION)->setRelatedEntity('Test\\Entity')->setExecutionOrder(30)->setEnabled(false);
     $createTrigger = new ProcessTrigger();
     $createTrigger->setDefinition($disabledDefinition)->setEvent(ProcessTrigger::EVENT_CREATE);
     $entityManager->persist($disabledDefinition);
     $entityManager->persist($createTrigger);
     $entityManager->flush();
 }
 /**
  * @param array $configuration
  * @param ProcessDefinition $definition
  * @return ProcessTrigger
  * @throws InvalidParameterException
  */
 public function buildProcessTrigger(array $configuration, ProcessDefinition $definition)
 {
     $this->assertConfigurationOptions($configuration, array('event'));
     $event = $configuration['event'];
     if (!in_array($event, ProcessTrigger::getAllowedEvents())) {
         throw new InvalidParameterException(sprintf('Event "%s" is not allowed', $event));
     }
     $field = $this->getConfigurationOption($configuration, 'field', null);
     $priority = $this->getConfigurationOption($configuration, 'priority', Job::PRIORITY_DEFAULT);
     $queued = $this->getConfigurationOption($configuration, 'queued', false);
     $timeShift = $this->getConfigurationOption($configuration, 'time_shift', null);
     if ($timeShift && !is_int($timeShift) && !$timeShift instanceof \DateInterval) {
         throw new InvalidParameterException('Time shift parameter must be either integer or DateInterval');
     }
     if ($field && $event != ProcessTrigger::EVENT_UPDATE) {
         throw new InvalidParameterException('Field is only allowed for update event');
     }
     $trigger = new ProcessTrigger();
     $trigger->setEvent($event)->setField($field)->setPriority($priority)->setQueued($queued)->setDefinition($definition);
     if ($timeShift instanceof \DateInterval) {
         $trigger->setTimeShiftInterval($timeShift);
     } else {
         $trigger->setTimeShift($timeShift);
     }
     return $trigger;
 }
Example #3
0
 /**
  * @param string $message
  * @param ProcessTrigger $trigger
  * @param ProcessData $data
  */
 public function debug($message, ProcessTrigger $trigger, ProcessData $data)
 {
     if ($this->logger) {
         $context = array('definition' => $trigger->getDefinition()->getName(), 'event' => $trigger->getEvent(), 'entityId' => $this->doctrineHelper->getSingleEntityIdentifier($data['data'], false));
         $this->logger->debug($message, $context);
     }
 }
 public function testPostFlush()
 {
     $serializedData = 'serializedData';
     $processDefinition = new ProcessDefinition();
     $processDefinition->setRelatedEntity(self::TEST_CLASS);
     $processTrigger = new ProcessTrigger();
     $processTrigger->setDefinition($processDefinition);
     $processData = new ProcessData();
     $processData->set('test', 'value');
     $processJob = new ProcessJob();
     $processJob->setProcessTrigger($processTrigger)->setData($processData);
     $unitOfWork = $this->getMockBuilder('Doctrine\\ORM\\UnitOfWork')->disableOriginalConstructor()->getMock();
     $unitOfWork->expects($this->at(0))->method('getScheduledEntityInsertions')->will($this->returnValue(array($processJob)));
     $unitOfWork->expects($this->at(1))->method('getScheduledEntityUpdates')->will($this->returnValue(array($processJob)));
     $entityId = 1;
     $entityHash = ProcessJob::generateEntityHash(self::TEST_CLASS, $entityId);
     $this->serializer->expects($this->exactly(2))->method('serialize')->with($processJob->getData(), 'json', array('processJob' => $processJob))->will($this->returnCallback(function () use($processJob, $entityId, $serializedData) {
         $processJob->setEntityId($entityId);
         return $serializedData;
     }));
     $entityManager = $this->getMockBuilder('Doctrine\\ORM\\EntityManager')->disableOriginalConstructor()->getMock();
     $entityManager->expects($this->any())->method('getUnitOfWork')->will($this->returnValue($unitOfWork));
     $entityManager->expects($this->once())->method('flush');
     $this->listener->onFlush(new OnFlushEventArgs($entityManager));
     $this->listener->postFlush(new PostFlushEventArgs($entityManager));
     $this->assertEquals($serializedData, $processJob->getSerializedData());
     $this->assertEquals($entityId, $processJob->getEntityId());
     $this->assertEquals($entityHash, $processJob->getEntityHash());
     $this->assertFalse($processJob->getData()->isModified());
 }
Example #5
0
 /**
  * @param bool $hasLogger
  * @dataProvider debugDataProvider
  */
 public function testDebug($hasLogger)
 {
     $doctrineHelper = $this->getMockBuilder('Oro\\Bundle\\EntityBundle\\ORM\\DoctrineHelper')->disableOriginalConstructor()->getMock();
     $definitionName = 'test_definition';
     $definition = new ProcessDefinition();
     $definition->setName($definitionName);
     $triggerEvent = ProcessTrigger::EVENT_UPDATE;
     $trigger = new ProcessTrigger();
     $trigger->setEvent($triggerEvent)->setDefinition($definition);
     $entity = new \stdClass();
     $entityId = 1;
     $data = new ProcessData(array('data' => $entity));
     $message = 'Test debug message';
     $context = array('definition' => $definitionName, 'event' => $triggerEvent, 'entityId' => $entityId);
     if ($hasLogger) {
         $doctrineHelper->expects($this->once())->method('getSingleEntityIdentifier')->with($entity, false)->will($this->returnValue($entityId));
         $logger = $this->getMock('Psr\\Log\\LoggerInterface');
         $logger->expects($this->once())->method('debug')->with($message, $context);
     } else {
         $doctrineHelper->expects($this->never())->method('getSingleEntityIdentifier');
         $logger = null;
     }
     $processLogger = new ProcessLogger($doctrineHelper, $logger);
     $processLogger->debug($message, $trigger, $data);
 }
 public function testEqualTriggers()
 {
     $definition = $this->entityManager->find('OroWorkflowBundle:ProcessDefinition', LoadProcessEntities::FIRST_DEFINITION);
     $trigger = $this->repository->findOneBy(array('definition' => $definition));
     // test equal (existing) trigger
     $equalTrigger = new ProcessTrigger();
     $equalTrigger->setDefinition($definition)->setEvent(ProcessTrigger::EVENT_UPDATE)->setField(LoadProcessEntities::UPDATE_TRIGGER_FIELD);
     $this->assertEquals($trigger, $this->repository->findEqualTrigger($equalTrigger));
     $this->assertTrue($this->repository->isEqualTriggerExists($equalTrigger));
     // test not equal (not existing) trigger
     $notEqualTrigger = new ProcessTrigger();
     $notEqualTrigger->setDefinition($definition)->setEvent(ProcessTrigger::EVENT_CREATE);
     $this->assertNull($this->repository->findEqualTrigger($notEqualTrigger));
     $this->assertFalse($this->repository->isEqualTriggerExists($notEqualTrigger));
 }
 /**
  * @param ArrayNodeDefinition $nodeDefinition
  * @return ArrayNodeDefinition
  *
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  */
 public function addTriggerNodes(ArrayNodeDefinition $nodeDefinition)
 {
     $nodeDefinition->children()->enumNode('event')->defaultNull()->values(ProcessTrigger::getAllowedEvents())->end()->scalarNode('field')->defaultNull()->end()->integerNode('priority')->defaultValue(Job::PRIORITY_DEFAULT)->end()->booleanNode('queued')->defaultFalse()->end()->scalarNode('time_shift')->defaultNull()->validate()->always(function ($value) {
         // if value is an integer value
         $integerValue = filter_var($value, FILTER_VALIDATE_INT);
         if (false !== $integerValue) {
             return $integerValue;
         }
         // if value is DateInterval spec
         try {
             return ProcessTrigger::convertDateIntervalToSeconds(new \DateInterval($value));
         } catch (\Exception $e) {
             throw new \LogicException(sprintf('Time shift "%s" is not compatible with DateInterval', $value));
         }
     })->end()->end()->scalarNode('cron')->defaultNull()->validate()->always(function ($value) {
         if ($value !== null) {
             // validate expression string
             CronExpression::factory($value);
         }
         return $value;
     })->end()->end()->end()->validate()->always(function ($data) {
         if ($data['event'] && $data['cron']) {
             throw new \LogicException('Only one child node "event" or "cron" must be configured.');
         }
         if ($data['cron'] && ($data['field'] || $data['queued'] || $data['time_shift'])) {
             throw new \LogicException('Nodes "field", "queued" and "time_shift" are only allowed with event node.');
         }
         if ($data['field'] && $data['event'] !== ProcessTrigger::EVENT_UPDATE) {
             throw new \LogicException('Field is only allowed for update event');
         }
         return $data;
     })->end();
     return $nodeDefinition;
 }
 /**
  * {@inheritDoc}
  */
 public function load(ObjectManager $manager)
 {
     foreach ($this->definitions as $name => $config) {
         $definition = new ProcessDefinition();
         $definition->setName($name)->setLabel($name)->setRelatedEntity($config['related_entity'])->setExecutionOrder($config['execution_order'])->setEnabled($config['enabled']);
         $this->definitions[$name] = $definition;
         $manager->persist($definition);
     }
     foreach ($this->triggers as $key => $config) {
         $trigger = new ProcessTrigger();
         $trigger->setDefinition($this->definitions[$config['definition']])->setEvent($config['event'])->setField($config['field'])->setCron($config['cron']);
         $manager->persist($trigger);
         $this->addReference($key, $trigger);
     }
     $manager->flush();
 }
 /**
  * @param array $expected
  * @param ProcessDefinition $definition
  * @param ProcessTrigger $trigger
  */
 protected function assertProcessTrigger(array $expected, ProcessDefinition $definition, ProcessTrigger $trigger)
 {
     $this->assertEquals($expected['event'], $trigger->getEvent());
     $this->assertEquals($expected['field'], $trigger->getField());
     $this->assertEquals($expected['queued'], $trigger->isQueued());
     $this->assertEquals($expected['priority'], $trigger->getPriority());
     $this->assertSame($expected['time_shift'], $trigger->getTimeShift());
     $this->assertSame($expected['cron'], $trigger->getCron());
     $this->assertSame($definition, $trigger->getDefinition());
 }
 /**
  * Schedules EmailBody for processing.
  *
  * @param EmailBody $emailBody
  */
 protected function scheduleProcess(EmailBody $emailBody)
 {
     /*
      * Retrieve all process definitions to trigger
      */
     $definitions = $this->processStorage->getService()->getProcessDefinitionNames();
     $definitions = $this->getDefinitionRepository()->findBy(['name' => $definitions]);
     /*
      * Trigger process definitions with provided data
      */
     foreach ($definitions as $definition) {
         $trigger = new ProcessTrigger();
         $trigger->setDefinition($definition);
         $data = new ProcessData();
         $data->set('data', $emailBody);
         $this->handler->handleTrigger($trigger, $data);
     }
 }
 /**
  * Schedules EmailBody for processing.
  *
  * @param EmailBody $emailBody
  */
 protected function scheduleProcess(EmailBody $emailBody)
 {
     /*
      * Retrieve all process definitions to trigger
      */
     $definitions = $this->processStorage->getService()->getProcessDefinitionNames();
     $definitions = $this->getDefinitionRepository()->findBy(['name' => $definitions]);
     /*
      * Trigger process definitions with provided data
      */
     foreach ($definitions as $definition) {
         $trigger = new ProcessTrigger();
         //id must be unique otherwise in cache will be saved and runned first definition with id = null
         $trigger->setId($definition->getName());
         $trigger->setDefinition($definition);
         $data = new ProcessData();
         $data->set('data', $emailBody);
         $this->handler->handleTrigger($trigger, $data);
     }
 }
Example #12
0
 public function testSetGetEntityIdAndHash()
 {
     $entityClass = 'Test\\Entity';
     $entityId = 12;
     $definition = new ProcessDefinition();
     $definition->setRelatedEntity($entityClass);
     $trigger = new ProcessTrigger();
     $trigger->setDefinition($definition);
     $this->entity->setProcessTrigger($trigger);
     $this->assertNull($this->entity->getEntityId());
     $this->assertNull($this->entity->getEntityHash());
     $this->entity->setEntityId($entityId);
     $this->assertEquals($entityId, $this->entity->getEntityId());
     $this->assertEquals(ProcessJob::generateEntityHash($entityClass, $entityId), $this->entity->getEntityHash());
     $this->entity->setEntityId(null);
     $this->assertNull($this->entity->getEntityId());
     $this->assertNull($this->entity->getEntityHash());
 }
 /**
  * @param string $event
  * @return ProcessJob
  */
 protected function createProcessJob($event)
 {
     $definition = new ProcessDefinition();
     $definition->setRelatedEntity('Test\\Entity');
     $trigger = new ProcessTrigger();
     $trigger->setDefinition($definition)->setEvent($event);
     $job = new ProcessJob();
     $job->setProcessTrigger($trigger);
     return $job;
 }
 /**
  * @param \PHPUnit_Framework_MockObject_MockObject $entityManager
  * @param array $expected
  * @param int $callOrder
  */
 protected function assertJMSJobPersist($entityManager, array $expected, $callOrder)
 {
     $entityManager->expects($this->at($callOrder))->method('persist')->with($this->isInstanceOf('JMS\\JobQueueBundle\\Entity\\Job'))->will($this->returnCallback(function (Job $jmsJob) use($expected) {
         $this->assertEquals(ExecuteProcessJobCommand::NAME, $jmsJob->getCommand());
         $this->assertEquals($expected['commandArgs'], $jmsJob->getArgs());
         $this->assertEquals($expected['priority'], $jmsJob->getPriority());
         $timeShiftInterval = ProcessTrigger::convertSecondsToDateInterval($expected['timeShift']);
         $executeAfter = new \DateTime('now', new \DateTimeZone('UTC'));
         $executeAfter->add($timeShiftInterval);
         $this->assertLessThanOrEqual($executeAfter, $jmsJob->getExecuteAfter());
     }));
 }
Example #15
0
 /**
  * @param ProcessTrigger $trigger
  * @return ProcessTrigger
  */
 public function import(ProcessTrigger $trigger)
 {
     $this->setEvent($trigger->getEvent())->setField($trigger->getField())->setPriority($trigger->getPriority())->setQueued($trigger->isQueued())->setTimeShift($trigger->getTimeShift())->setDefinition($trigger->getDefinition());
     return $this;
 }
 /**
  * @param array $data
  */
 protected function prepareRegistryForBuild(array $data)
 {
     // generate triggers
     $triggers = array();
     foreach ($data as $entityClass => $events) {
         $definition = new ProcessDefinition();
         $definition->setRelatedEntity($entityClass);
         foreach ($events as $event) {
             $trigger = new ProcessTrigger();
             $trigger->setDefinition($definition)->setEvent($event);
             $triggers[] = $trigger;
         }
     }
     // set mocks
     $triggerClass = 'OroWorkflowBundle:ProcessTrigger';
     $repository = $this->getMockBuilder('Oro\\Bundle\\WorkflowBundle\\Entity\\Repository\\ProcessTriggerRepository')->disableOriginalConstructor()->getMock();
     $repository->expects($this->any())->method('findAllWithDefinitions')->will($this->returnValue($triggers));
     $entityManager = $this->getMockBuilder('Doctrine\\ORM\\EntityManager')->disableOriginalConstructor()->getMock();
     $entityManager->expects($this->any())->method('getRepository')->with($triggerClass)->will($this->returnValue($repository));
     $this->registry->expects($this->any())->method('getManagerForClass')->with($triggerClass)->will($this->returnValue($entityManager));
 }
 /**
  * @param string $event
  * @param string $cron
  * @throws InvalidParameterException
  */
 protected function validateEventAndCronParameters($event, $cron)
 {
     if ($cron && $event) {
         throw new InvalidParameterException('Only one parameter "event" or "cron" must be configured.');
     }
     if (!$cron && !in_array($event, ProcessTrigger::getAllowedEvents(), true)) {
         throw new InvalidParameterException(sprintf('Event "%s" is not allowed', $event));
     }
 }
Example #18
0
 /**
  * @param ProcessTrigger $processTrigger
  * @return Process
  */
 protected function getProcess(ProcessTrigger $processTrigger)
 {
     if (!array_key_exists($processTrigger->getId(), $this->processes)) {
         $this->processes[$processTrigger->getId()] = $this->factory->create($processTrigger->getDefinition());
     }
     return $this->processes[$processTrigger->getId()];
 }
 /**
  * @param array $ids
  * @return ProcessJob[]
  */
 protected function populateProcessJobs(array $ids)
 {
     $result = [];
     foreach ($ids as $id) {
         $process = $this->getMockBuilder('Oro\\Bundle\\WorkflowBundle\\Entity\\ProcessJob')->disableOriginalConstructor()->getMock();
         $process->expects($this->any())->method('getId')->will($this->returnValue($id));
         $definition = new ProcessDefinition();
         $definition->setName('name');
         $definition->setLabel('label');
         $processTrigger = new ProcessTrigger();
         $processTrigger->setDefinition($definition);
         $process->expects($this->any())->method('getProcessTrigger')->will($this->returnValue($processTrigger));
         $result[] = $process;
     }
     return $result;
 }
 /**
  * @param int $id
  * @return ProcessTrigger
  */
 protected function createProcessTrigger($id)
 {
     $definition = new ProcessDefinition();
     $definition->setName('name')->setLabel('label')->setRelatedEntity('\\StdClass');
     $processTrigger = new ProcessTrigger();
     $processTrigger->setDefinition($definition);
     $class = new \ReflectionClass($processTrigger);
     $prop = $class->getProperty('id');
     $prop->setAccessible(true);
     $prop->setValue($processTrigger, $id);
     return $processTrigger;
 }
 /**
  * Create JMS jobs for queued process jobs
  *
  * @param \Doctrine\ORM\EntityManager $entityManager
  */
 protected function createJobs($entityManager)
 {
     if (empty($this->queuedJobs)) {
         return;
     }
     foreach ($this->queuedJobs as $timeShift => $processJobBatch) {
         foreach ($processJobBatch as $priority => $processJobs) {
             $args = array();
             /** @var ProcessJob $processJob */
             foreach ($processJobs as $processJob) {
                 $args[] = '--id=' . $processJob->getId();
                 $this->logger->debug('Process queued', $processJob->getProcessTrigger(), $processJob->getData());
             }
             $jmsJob = new Job(ExecuteProcessJobCommand::NAME, $args, true, Job::DEFAULT_QUEUE, $priority);
             if ($timeShift) {
                 $timeShiftInterval = ProcessTrigger::convertSecondsToDateInterval($timeShift);
                 $executeAfter = new \DateTime('now', new \DateTimeZone('UTC'));
                 $executeAfter->add($timeShiftInterval);
                 $jmsJob->setExecuteAfter($executeAfter);
             }
             $entityManager->persist($jmsJob);
         }
     }
     $this->queuedJobs = array();
     $entityManager->flush();
 }
Example #22
0
 /**
  * @param ProcessTrigger $expectedEntity
  * @param ProcessTrigger $actualEntity
  * @param bool $isEquals
  */
 protected function assertProcessTriggerEntitiesEquals($expectedEntity, $actualEntity, $isEquals = true)
 {
     $method = $isEquals ? 'assertEquals' : 'assertNotEquals';
     $this->{$method}($expectedEntity->getEvent(), $actualEntity->getEvent());
     $this->{$method}($expectedEntity->getField(), $actualEntity->getField());
     $this->{$method}($expectedEntity->getPriority(), $actualEntity->getPriority());
     $this->{$method}($expectedEntity->isQueued(), $actualEntity->isQueued());
     $this->{$method}($expectedEntity->getTimeShift(), $actualEntity->getTimeShift());
     $this->{$method}($expectedEntity->getDefinition(), $actualEntity->getDefinition());
 }
 /**
  * @param ProcessTrigger $trigger
  * @return null|ProcessTrigger
  */
 public function findEqualTrigger(ProcessTrigger $trigger)
 {
     return $this->findOneBy(array('event' => $trigger->getEvent(), 'field' => $trigger->getField(), 'definition' => $trigger->getDefinition()));
 }
 /**
  * Not allow scheduling definition if it's excluded by some process.
  *
  * @param ProcessTrigger $processTrigger
  * @param ProcessData $processData
  * @return bool
  */
 public function isScheduleAllowed(ProcessTrigger $processTrigger, ProcessData $processData)
 {
     $name = $processTrigger->getDefinition()->getName();
     return !isset($this->excludeDefinitions[$name]) || $this->excludeDefinitions[$name] == 0;
 }