/**
  * @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;
 }
 /**
  * @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;
 }
 /**
  * @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));
     }
 }