protected function isValidFieldname(FieldStorageConfig $field_storage, FieldableEntityInterface $entity)
 {
     $comment_field_name_ok = FALSE;
     if ($field_storage->getTargetEntityTypeId() !== 'comment') {
         return TRUE;
     }
     $field_name = $field_storage->get('field_name');
     // Check if the 'comment' field name exists on the 'commented' entity type.
     // @todo: Still not waterproof. You could have a field on a non-relevant entity_type.
     foreach (_workflow_info_fields() as $key => $info) {
         if ($info->getName() == $field_name && $info->getTargetEntityTypeId() !== 'comment') {
             $comment_field_name_ok = TRUE;
         }
     }
     return $comment_field_name_ok;
 }
 /**
  * {@inheritdoc}
  */
 protected function blockAccess(AccountInterface $account)
 {
     /* @var $entity EntityInterface */
     if (!($entity = workflow_url_get_entity())) {
         return AccessResult::forbidden();
     }
     // Only show block on entity view page (when default operation = '').
     if ($operation = workflow_url_get_operation()) {
         return AccessResult::forbidden();
     }
     // Only show block if entity has workflow, and user has permission.
     foreach (_workflow_info_fields($entity) as $definition) {
         $type_id = $definition->getSetting('workflow_type');
         if ($account->hasPermission("access {$type_id} workflow_transition form")) {
             return AccessResult::allowed();
         }
     }
     return AccessResult::forbidden();
 }
Beispiel #3
0
 /**
  * Returns the number of entities with this state.
  *
  * @return int
  *   Counted number.
  *
  * @todo: add $options to select on entity type, etc.
  */
 public function count()
 {
     $count = 0;
     $sid = $this->id();
     foreach ($fields = _workflow_info_fields() as $field_info) {
         $field_name = $field_info->getName();
         $query = \Drupal::entityQuery($field_info->getTargetEntityTypeId());
         // @see #2285983 for using SQLite on D7.
         $count += $query->condition($field_name, $sid, '=')->count()->execute();
     }
     return $count;
 }
 /**
  * Determines if the column 'Field name' must be shown.
  *
  * @param EntityInterface $entity
  *
  * @return bool
  */
 protected function showColumnFieldname(EntityInterface $entity)
 {
     if (is_null($this->show_column_fieldname)) {
         // @todo: also remove when field_name is set in route??
         if (count(_workflow_info_fields($entity)) > 1) {
             $this->show_column_fieldname = TRUE;
         }
     }
     return $this->show_column_fieldname;
 }
 /**
  * Returns the number of entities with this state.
  *
  * @return int
  *   Counted number.
  *
  * @todo: add $options to select on entity type, etc.
  */
 public function count()
 {
     $sid = $this->sid;
     // Get the numbers for Workflow Node.
     $result = db_select('workflow_node', 'wn')->fields('wn')->condition('sid', $sid, '=')->execute();
     $count = count($result->fetchAll());
     // @see #2285983 for using SQLite.
     // Get the numbers for Workflow Field.
     $fields = _workflow_info_fields();
     foreach ($fields as $field_name => $field_map) {
         if ($field_map['type'] == 'workflow') {
             $query = new EntityFieldQuery();
             $query->fieldCondition($field_name, 'value', $sid, '=')->count();
             // We only need the count.
             $result = $query->execute();
             $count += $result;
         }
     }
     return $count;
 }
 /**
  * {@inheritdoc}
  */
 public static function executeTransitionsOfEntity(EntityInterface $entity)
 {
     // Avoid this hook on workflow objects.
     if (in_array($entity->getEntityTypeId(), ['workflow_type', 'workflow_state', 'workflow_config_transition', 'workflow_transition', 'workflow_scheduled_transition'])) {
         return;
     }
     foreach (_workflow_info_fields($entity) as $field_info) {
         $field_name = $field_info->getName();
         /* @var $transition WorkflowTransitionInterface */
         $transition = $entity->{$field_name}->__get('workflow_transition');
         if ($transition) {
             if ($entity->getEntityTypeId() !== 'comment') {
                 // We come from Content edit page, from widget.
                 // Set the just-saved entity explicitly. Not necessary for update,
                 // but upon insert, the old version didn't have an ID, yet.
                 $transition->setTargetEntity($entity);
             }
             $transition->execute();
         } else {
             // We come from WorkflowTransitionForm, which explicitly save the entity.
             // The transition is executed by the form.
         }
     }
 }
Beispiel #7
0
 /**
  * {@inheritdoc}
  */
 public function isDeletable()
 {
     $is_deletable = FALSE;
     // May not be deleted if assigned to a Field.
     foreach ($fields = _workflow_info_fields() as $field_info) {
         if ($field_info->getSetting('workflow_type') == $this->id()) {
             return FALSE;
         }
     }
     // D8-port: This is deleted, since it is only for D7's workflow_node.
     // // May not be deleted if a State is assigned to a state.
     // foreach ($this->getStates(TRUE) as $state) {
     //   if ($state->count()) {
     //     return $is_deletable;
     //   }
     // }
     $is_deletable = TRUE;
     return $is_deletable;
 }
Beispiel #8
0
 /**
  * Returns if the Workflow may be deleted.
  *
  * @return bool $is_deletable
  *   TRUE if a Workflow may safely be deleted.
  */
 public function isDeletable()
 {
     $is_deletable = FALSE;
     // May not be deleted if a TypeMap exists.
     if ($this->getTypeMap()) {
         return $is_deletable;
     }
     // May not be deleted if assigned to a Field.
     foreach (_workflow_info_fields() as $field) {
         if ($field['settings']['wid'] == $this->wid) {
             return $is_deletable;
         }
     }
     // May not be deleted if a State is assigned to a state.
     foreach ($this->getStates(TRUE) as $state) {
         if ($state->count()) {
             return $is_deletable;
         }
     }
     $is_deletable = TRUE;
     return $is_deletable;
 }
Beispiel #9
0
 /**
  * Implements hook_field_settings_form() -> ConfigFieldItemInterface::settingsForm().
  */
 public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data)
 {
     $element = array();
     // Create list of all Workflow types. Include an initial empty value.
     // Validate each workflow, and generate a message if not complete.
     $workflows = workflow_get_workflow_names(FALSE);
     // @todo D8: add this to WorkflowFieldConstraintValidator.
     // Set message, if no 'validated' workflows exist.
     if (count($workflows) == 1) {
         drupal_set_message(t('You must create at least one workflow before content can be
       assigned to a workflow.'), 'warning');
     }
     // Validate via annotation WorkflowFieldConstraint. Show a message for each error.
     $violation_list = $this->validate();
     foreach ($violation_list->getIterator() as $violation) {
         switch ($violation->getPropertyPath()) {
             case 'fieldnameOnComment':
                 // A 'comment' field name MUST be equal to content field name.
                 // @todo: Still not waterproof. You could have a field on a non-relevant entity_type.
                 drupal_set_message($violation->getMessage(), 'error');
                 $workflows = array();
                 break;
             default:
                 break;
         }
     }
     // Set the required workflow_type on 'comment' fields.
     // N.B. the following must BELOW the (count($workflows) == 1) snippet.
     $field_storage = $this->getFieldDefinition()->getFieldStorageDefinition();
     if (!$this->getSetting('workflow_type') && $field_storage->getTargetEntityTypeId() == 'comment') {
         $field_name = $field_storage->get('field_name');
         $workflows = array();
         foreach (_workflow_info_fields($entity = NULL, $entity_type = '', $entity_bundle = '', $field_name) as $key => $info) {
             if ($info->getName() == $field_name && $info->getTargetEntityTypeId() !== 'comment') {
                 $wid = $info->getSetting('workflow_type');
                 $workflow = Workflow::load($wid);
                 $workflows[$wid] = $workflow->label();
             }
         }
     }
     // Let the user choose between the available workflow types.
     $wid = $this->getSetting('workflow_type');
     $url = \Drupal\Core\Url::fromRoute('entity.workflow_type.collection');
     $element['workflow_type'] = array('#type' => 'select', '#title' => t('Workflow type'), '#options' => $workflows, '#default_value' => $wid, '#required' => TRUE, '#disabled' => $has_data, '#description' => t('Choose the Workflow type. Maintain workflows
      <a href=":url">here</a>.', array(':url' => $url->toString())));
     // Get a string representation to show all options.
     /*
      * Overwrite ListItemBase::storageSettingsForm().
      */
     $allowed_values = WorkflowState::loadMultiple([], $wid);
     $allowed_values_function = $this->getSetting('allowed_values_function');
     $element['allowed_values'] = array('#type' => 'textarea', '#title' => t('Allowed values for the selected Workflow type'), '#default_value' => $wid ? $this->allowedValuesString($allowed_values) : [], '#rows' => count($allowed_values), '#access' => $wid ? TRUE : FALSE, '#disabled' => TRUE, '#element_validate' => array(array(get_class($this), 'validateAllowedValues')), '#field_has_data' => $has_data, '#field_name' => $this->getFieldDefinition()->getName(), '#entity_type' => $this->getEntity()->getEntityTypeId(), '#allowed_values' => $allowed_values);
     $element['allowed_values']['#description'] = $this->allowedValuesDescription();
     return $element;
 }
 /**
  * Menu access control callback. Checks access to Workflow tab.
  *
  * This used to be D7-function workflow_tab_access($user, $entity).
  *
  * The History tab should not be used with multiple workflows per entity.
  * Use the dedicated view for this use case.
  * @todo D8: remove this in favour of View 'Workflow history per entity'.
  * @todo D8-port: make this workf for non-Node entity types.
  *
  * @param \Drupal\workflow\Controller\AccountInterface $account
  *   Run access checks for this account.
  *
  * @return \Drupal\Core\Access\AccessResult
  */
 public function historyAccess(AccountInterface $account)
 {
     static $access = array();
     $uid = $account ? $account->id() : -1;
     // TODO D8-port: make Workflow History tab happen for every entity_type.
     // @see workflow.routing.yml, workflow.links.task.yml, WorkflowTransitionListController.
     // ATM it only works for Nodes and Terms.
     // This is a hack. The Route should always pass an object.
     // On view tab, $entity is object,
     // On workflow tab, $entity is id().
     // Get the entity for this form.
     $entity = workflow_url_get_entity();
     /* @var $entity EntityInterface */
     // Figure out the $entity's bundle and id.
     $entity_type = $entity->getEntityTypeId();
     $entity_bundle = $entity->bundle();
     $entity_id = $entity ? $entity->id() : '';
     $field_name = workflow_url_get_field_name();
     if (isset($access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'])) {
         return $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'];
     }
     $access_result = AccessResult::forbidden();
     // When having multiple workflows per bundle, use Views display
     // 'Workflow history per entity' instead!
     $fields = _workflow_info_fields($entity, $entity_type, $entity_bundle, $field_name);
     if (!$fields) {
         return AccessResult::forbidden();
     } else {
         // @todo: Keep below code aligned between WorkflowState, ~Transition, ~TransitionListController
         $uid = $account ? $account->id() : -1;
         $entity_id = $entity ? $entity->id() : '';
         // Determine if user is owner of the entity.
         $is_owner = WorkflowManager::isOwner($account, $entity);
         /**
          * Determine if user has Access. Fill the cache.
          */
         // @todo: what to do with multiple workflow_fields per bundle? Use Views instead! Or introduce a setting.
         // @TODO D8-port: workflow_tab_access: use proper 'WORKFLOW_TYPE' permissions
         foreach ($fields as $definition) {
             $type_id = $definition->getSetting('workflow_type');
             if ($account->hasPermission("access any {$type_id} workflow_transion overview")) {
                 $access_result = AccessResult::allowed();
             } elseif ($is_owner && $account->hasPermission("access own {$type_id} workflow_transion overview")) {
                 $access_result = AccessResult::allowed();
             } elseif ($account->hasPermission('administer nodes')) {
                 $access_result = AccessResult::allowed();
             }
             $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'] = $access_result;
         }
     }
     return $access_result;
 }