Пример #1
0
 /**
  * {@inheritdoc}
  */
 public static function executeScheduledTransitionsBetween($start = 0, $end = 0)
 {
     $clear_cache = FALSE;
     // If the time now is greater than the time to execute a transition, do it.
     foreach (WorkflowScheduledTransition::loadBetween($start, $end) as $scheduled_transition) {
         $field_name = $scheduled_transition->getFieldName();
         $entity = $scheduled_transition->getTargetEntity();
         // Make sure transition is still valid: the entity must still be in
         // the state it was in, when the transition was scheduled.
         // Scheduling on comments is a testing error, and leads to 'recoverable error'.
         $current_sid = '';
         if ($entity && $entity->getEntityTypeId() !== 'comment') {
             $current_sid = workflow_node_current_state($entity, $field_name);
         }
         if ($current_sid && $current_sid == $scheduled_transition->getFromSid()) {
             // If user didn't give a comment, create one.
             $comment = $scheduled_transition->getComment();
             if (empty($comment)) {
                 $scheduled_transition->addDefaultComment();
             }
             // Do transition. Force it because user who scheduled was checked.
             // The scheduled transition is not scheduled anymore, and is also deleted from DB.
             // A watchdog message is created with the result.
             $scheduled_transition->schedule(FALSE);
             $scheduled_transition->force(TRUE);
             workflow_execute_transition($scheduled_transition, TRUE);
             if (!$field_name) {
                 $clear_cache = TRUE;
             }
         } else {
             // Entity is not in the same state it was when the transition
             // was scheduled. Defer to the entity's current state and
             // abandon the scheduled transition.
             $scheduled_transition->delete();
         }
     }
     if ($clear_cache) {
         // Clear the cache so that if the transition resulted in a entity
         // being published, the anonymous user can see it.
         Cache::invalidateTags(array('rendered'));
     }
 }
Пример #2
0
 /**
  * Saves the entity.
  * Mostly, you'd better use WorkflowTransitionInterface::execute();
  *
  * {@inheritdoc}
  */
 public function save()
 {
     // return parent::save();
     // Avoid custom actions for subclass WorkflowScheduledTransition.
     if ($this->isScheduled()) {
         return parent::save();
     }
     if ($this->getEntityTypeId() != 'workflow_transition') {
         return parent::save();
     }
     $transition = $this;
     $entity_type = $transition->getTargetEntityTypeId();
     $entity_id = $transition->getTargetEntityId();
     $field_name = $transition->getFieldName();
     // Remove any scheduled state transitions.
     foreach (WorkflowScheduledTransition::loadMultipleByProperties($entity_type, [$entity_id], [], $field_name) as $scheduled_transition) {
         /* @var WorkflowTransitionInterface $scheduled_transition */
         $scheduled_transition->delete();
     }
     // Check for no transition.
     if ($this->getFromSid() == $this->getToSid()) {
         if (!$this->getComment()) {
             // Write comment into history though.
             return SAVED_UPDATED;
         }
     }
     $hid = $this->id();
     if (!$hid) {
         // Insert the transition. Make sure it hasn't already been inserted.
         // @todo: Allow a scheduled transition per revision.
         // @todo: Allow a state per language version (langcode).
         $found_transition = self::loadByProperties($entity_type, $entity_id, [], $field_name);
         if ($found_transition && $found_transition->getTimestamp() == REQUEST_TIME && $found_transition->getToSid() == $this->getToSid()) {
             return SAVED_UPDATED;
         } else {
             return parent::save();
         }
     } else {
         // Update the transition.
         return parent::save();
     }
 }
 /**
  * Implements ContentEntityForm::copyFormValuesToEntity(), and is called from:
  * - WorkflowTransitionForm::buildEntity()
  * - WorkflowDefaultWidget
  *
  * N.B. in contrary to ContentEntityForm::copyFormValuesToEntity(),
  * - parameter 1 is returned as result, to be able to create a new Transition object.
  * - parameter 3 is not $form_state (from Form), but an $item array (from Widget).
  *
  * @param \Drupal\Core\Entity\EntityInterface $entity
  * @param array $form
  * @param array $item
  *
  * @return \Drupal\workflow\Entity\WorkflowTransitionInterface
  */
 public static function copyFormItemValuesToEntity(EntityInterface $entity, array $form, array $item)
 {
     /**
      * Input
      */
     $user = workflow_current_user();
     // @todo #2287057: verify if submit() really is only used for UI. If not, $user must be passed.
     /* @var $transition WorkflowTransitionInterface */
     $transition = $entity;
     /**
      * Derived input
      */
     // Make sure we have subset ['workflow_scheduled_date_time']
     if (isset($item['to_sid'])) {
         // In WorkflowTransitionForm, we receive the complete $form_state.
         // Remember, the workflow_scheduled element is not set on 'add' page.
         $scheduled = !empty($item['workflow_scheduling']['scheduled']);
         $schedule_values = $scheduled ? $item['workflow_scheduling']['date_time'] : [];
     } else {
         $entity_id = $transition->getTargetEntityId();
         drupal_set_message(t('Error: content !id has no workflow attached. The data is not saved.', array('!id' => $entity_id)), 'error');
         // The new state is still the previous state.
         return $transition;
     }
     // Get user input from element.
     $to_sid = $item['to_sid'];
     $comment = $item['comment'];
     $force = FALSE;
     // @todo D8: add the VBO use case.
     //    // Determine if the transition is forced.
     //    // This can be set by a 'workflow_vbo action' in an additional form element.
     //     $force = isset($form_state['input']['workflow_force']) ? $form_state['input']['workflow_force'] : FALSE;
     //    if (!$entity) {
     //      // E.g., on VBO form.
     //    }
     // @todo D8-port: add below exception.
     /*
         // Extract the data from $items, depending on the type of widget.
         // @todo D8: use MassageFormValues($item, $form, $form_state).
         $old_sid = workflow_node_previous_state($entity, $entity_type, $field_name);
         if (!$old_sid) {
           // At this moment, $old_sid should have a value. If the content does not
           // have a state yet, old_sid contains '(creation)' state. But if the
           // content is not associated to a workflow, old_sid is now 0. This may
           // happen in workflow_vbo, if you assign a state to non-relevant nodes.
           $entity_id = entity_id($entity_type, $entity);
           drupal_set_message(t('Error: content !id has no workflow attached. The data is not saved.', array('!id' => $entity_id)), 'error');
           // The new state is still the previous state.
           $new_sid = $old_sid;
           return $new_sid;
         }
     */
     $timestamp = REQUEST_TIME;
     if ($scheduled) {
         // Fetch the (scheduled) timestamp to change the state.
         // Override $timestamp.
         $scheduled_date_time = implode(' ', array($schedule_values['workflow_scheduled_date'], $schedule_values['workflow_scheduled_hour']));
         $timezone = $schedule_values['workflow_scheduled_timezone'];
         $old_timezone = date_default_timezone_get();
         date_default_timezone_set($timezone);
         $timestamp = strtotime($scheduled_date_time);
         date_default_timezone_set($old_timezone);
         if (!$timestamp) {
             // Time should have been validated in form/widget.
             $timestamp = REQUEST_TIME;
         }
     }
     /**
      * Process
      */
     /*
      * Create a new ScheduledTransition.
      */
     if ($scheduled) {
         $transition_entity = $transition->getTargetEntity();
         $field_name = $transition->getFieldName();
         $from_sid = $transition->getFromSid();
         /* @var $transition WorkflowTransitionInterface */
         $transition = WorkflowScheduledTransition::create([$from_sid, 'field_name' => $field_name]);
         $transition->setTargetEntity($transition_entity);
         $transition->setValues($to_sid, $user->id(), $timestamp, $comment);
     }
     if (!$transition->isExecuted()) {
         // Set new values.
         // When editing an existing Transition, only comments may change.
         $transition->set('to_sid', $to_sid);
         $transition->setOwner($user);
         $transition->setTimestamp($timestamp);
         $transition->schedule($scheduled);
         $transition->force($force);
     }
     $transition->setComment($comment);
     // Explicitely set $entity in case of ScheduleTransition. It is now returned as parameter, not result.
     $entity = $transition;
     return $transition;
 }