get('entity.manager'), $container->get('entity_type.bundle.info'), $container->get('datetime.time'), $container->get('element_info'), $container->get('logger.factory')->get('entityqueue') ); } /** * Constructs a EntitySubqueueForm. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info * The entity type bundle service. * @param \Drupal\Component\Datetime\TimeInterface $time * The time service. * @param \Drupal\Core\Render\ElementInfoManagerInterface $element_info * The element info manager. * @param \Psr\Log\LoggerInterface $logger * A logger instance. */ public function __construct(EntityManagerInterface $entity_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, TimeInterface $time, ElementInfoManagerInterface $element_info, LoggerInterface $logger) { parent::__construct($entity_manager, $entity_type_bundle_info, $time); $this->elementInfo = $element_info; $this->logger = $logger; } /** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { // Reverse the items in the admin form if the queue uses the 'Reverse order // in admin view' option. if ($this->entity->getQueue()->getReverseInAdmin()) { $subqueue_items = $this->entity->get('items'); $items_values = $subqueue_items->getValue(); $subqueue_items->setValue(array_reverse($items_values)); } $form = parent::form($form, $form_state); $form['#title'] = $this->t('Edit subqueue %label', ['%label' => $this->entity->label()]); // Since the form has ajax buttons, the $wrapper_id will change each time // one of those buttons is clicked. Therefore the whole form has to be // replaced, otherwise the buttons will have the old $wrapper_id and will // only work on the first click. if ($form_state->has('subqueue_form_wrapper_id')) { $wrapper_id = $form_state->get('subqueue_form_wrapper_id'); } else { $wrapper_id = Html::getUniqueId($this->getFormId() . '-wrapper'); } $form_state->set('subqueue_form_wrapper_id', $wrapper_id); $form['#prefix'] = '
'; $form['#suffix'] = '
'; // @todo Use the 'Machine name' field widget when // https://www.drupal.org/node/2685749 is committed. $element_info = $this->elementInfo->getInfo('machine_name'); $form['name'] = [ '#type' => 'machine_name', '#default_value' => $this->entity->id(), '#source_field' => 'title', '#process' => array_merge([[get_class($this), 'processMachineNameSource']], $element_info['#process']), '#machine_name' => [ 'exists' => '\Drupal\entityqueue\Entity\EntitySubqueue::load', ], '#disabled' => !$this->entity->isNew(), '#weight' => -5, '#access' => !$this->entity->getQueue()->getHandlerPlugin()->hasAutomatedSubqueues(), ]; return $form; } /** * Form API callback: Sets the 'source' property of a machine_name element. * * This method is assigned as a #process callback in formElement() method. */ public static function processMachineNameSource($element, FormStateInterface $form_state, $form) { $source_field_state = WidgetBase::getWidgetState($form['#parents'], $element['#source_field'], $form_state); // Hide the field widget if the source field is not configured properly or // if it doesn't exist in the form. if (empty($element['#source_field']) || empty($source_field_state['array_parents'])) { $element['#access'] = FALSE; } else { $source_field_element = NestedArray::getValue($form_state->getCompleteForm(), $source_field_state['array_parents']); $element['#machine_name']['source'] = $source_field_element[0]['value']['#array_parents']; } return $element; } /** * {@inheritdoc} */ protected function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); $actions['reverse'] = [ '#type' => 'submit', '#value' => $this->t('Reverse'), '#submit' => ['::submitAction'], '#op' => 'reverse', '#ajax' => [ 'callback' => '::subqueueActionAjaxForm', 'wrapper' => $form_state->get('subqueue_form_wrapper_id'), ], ]; $actions['shuffle'] = [ '#type' => 'submit', '#value' => $this->t('Shuffle'), '#submit' => ['::submitAction'], '#op' => 'shuffle', '#ajax' => [ 'callback' => '::subqueueActionAjaxForm', 'wrapper' => $form_state->get('subqueue_form_wrapper_id'), ], ]; $actions['clear'] = [ '#type' => 'submit', '#value' => $this->t('Clear'), '#submit' => ['::submitAction'], '#op' => 'clear', '#ajax' => [ 'callback' => '::subqueueActionAjaxForm', 'wrapper' => $form_state->get('subqueue_form_wrapper_id'), ], ]; return $actions; } /** * Submit callback for the 'reverse', 'shuffle' and 'clear' actions. */ public static function submitAction(array &$form, FormStateInterface $form_state) { $trigger = $form_state->getTriggeringElement(); $op = $trigger['#op']; // Check if we have a form element for the 'items' field. $path = array_merge($form['#parents'], ['items']); $key_exists = NULL; NestedArray::getValue($form_state->getValues(), $path, $key_exists); if ($key_exists) { // Remove any user input for the 'items' element in order to allow the // values set below to be applied. $user_input = $form_state->getUserInput(); NestedArray::setValue($user_input, $path, NULL); $form_state->setUserInput($user_input); $entity = $form_state->getFormObject()->getEntity(); $items_widget = $form_state->getFormObject()->getFormDisplay($form_state)->getRenderer('items'); $subqueue_items = $entity->get('items'); $items_widget->extractFormValues($subqueue_items, $form, $form_state); $items_values = $subqueue_items->getValue(); // Revert the effect of the 'Reverse order in admin view' option. if ($entity->getQueue()->getReverseInAdmin()) { $items_values = array_reverse($items_values); } switch ($op) { case 'reverse': $subqueue_items->setValue(array_reverse($items_values)); break; case 'shuffle': shuffle($items_values); $subqueue_items->setValue($items_values); break; case 'clear': $subqueue_items->setValue(NULL); break; } // Handle 'inline_entity_form' widgets separately because they have a // custom form state storage for the current state of the referenced // entities. if (\Drupal::moduleHandler()->moduleExists('inline_entity_form') && $items_widget instanceof InlineEntityFormBase) { $items_form_element = NestedArray::getValue($form, $path); $ief_id = $items_form_element['widget']['#ief_id']; $entities = $form_state->get(['inline_entity_form', $ief_id, 'entities']); if (isset($entities)) { $form_state->set(['inline_entity_form', $ief_id, 'entities'], []); switch ($op) { case 'reverse': $entities = array_reverse($entities); break; case 'shuffle': shuffle($entities); break; case 'clear': $entities = []; break; } foreach ($entities as $delta => $item) { $item['_weight'] = $delta; $form_state->set(['inline_entity_form', $ief_id, 'entities', $delta], $item); } } } $form_state->getFormObject()->setEntity($entity); $form_state->setRebuild(); } } /** * AJAX callback; Returns the entire form element. */ public static function subqueueActionAjaxForm(array &$form, FormStateInterface $form_state) { return $form; } /** * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $subqueue = $this->entity; // Revert the effect of the 'Reverse order in admin view' option. if ($subqueue->getQueue()->getReverseInAdmin()) { $subqueue_items = $subqueue->get('items'); $items_values = $subqueue_items->getValue(); $subqueue_items->setValue(array_reverse($items_values)); } $status = $subqueue->save(); $edit_link = $subqueue->toLink($this->t('Edit'), 'edit-form')->toString(); if ($status == SAVED_UPDATED) { drupal_set_message($this->t('The entity subqueue %label has been updated.', ['%label' => $subqueue->label()])); $this->logger->notice('The entity subqueue %label has been updated.', ['%label' => $subqueue->label(), 'link' => $edit_link]); } else { drupal_set_message($this->t('The entity subqueue %label has been added.', ['%label' => $subqueue->label()])); $this->logger->notice('The entity subqueue %label has been added.', ['%label' => $subqueue->label(), 'link' => $edit_link]); } $queue = $subqueue->getQueue(); if ($queue->getHandlerPlugin()->supportsMultipleSubqueues()) { $form_state->setRedirectUrl($queue->toUrl('subqueue-list')); } else { $form_state->setRedirectUrl($queue->toUrl('collection')); } } }