entity_hierarchy-8.x-2.24/src/Form/HierarchyChildrenForm.php

src/Form/HierarchyChildrenForm.php
<?php

namespace Drupal\entity_hierarchy\Form;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Defines a form for re-ordering children.
 */
class HierarchyChildrenForm extends ContentEntityForm {

  const CHILD_ENTITIES_STORAGE = 'child_entities';

  /**
   * The hierarchy being displayed.
   *
   * @var \Drupal\Core\Entity\ContentEntityInterface
   */
  protected $entity;

  /**
   * Nested set storage factory.
   *
   * @var \Drupal\entity_hierarchy\Storage\NestedSetStorageFactory
   */
  protected $nestedSetStorageFactory;

  /**
   * Nested set node key factory.
   *
   * @var \Drupal\entity_hierarchy\Storage\NestedSetNodeKeyFactory
   */
  protected $nodeKeyFactory;

  /**
   * Parent candidate.
   *
   * @var \Drupal\entity_hierarchy\Information\ParentCandidateInterface
   */
  protected $parentCandidate;

  /**
   * Tree node mapper.
   *
   * @var \Drupal\entity_hierarchy\Storage\EntityTreeNodeMapperInterface
   */
  protected $entityTreeNodeMapper;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    /** @var self $instance */
    $instance = parent::create($container);
    $instance->nestedSetStorageFactory = $container->get('entity_hierarchy.nested_set_storage_factory');
    $instance->nodeKeyFactory = $container->get('entity_hierarchy.nested_set_node_factory');
    $instance->parentCandidate = $container->get('entity_hierarchy.information.parent_candidate');
    $instance->entityTreeNodeMapper = $container->get('entity_hierarchy.entity_tree_node_mapper');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function getBaseFormId() {
    // Don't show a parent form here.
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $cache = (new CacheableMetadata())->addCacheableDependency($this->entity);

    /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $fields */
    $fields = $this->parentCandidate->getCandidateFields($this->entity);
    if (!$fields) {
      throw new NotFoundHttpException();
    }
    $fieldName = $form_state->getValue('fieldname') ?: reset($fields);
    if (count($fields) === 1) {
      $form['fieldname'] = [
        '#type' => 'value',
        '#value' => $fieldName,
      ];
    }
    else {
      $form['select_field'] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => ['container-inline'],
        ],
      ];
      $form['select_field']['fieldname'] = [
        '#type' => 'select',
        '#title' => $this->t('Field'),
        '#description' => $this->t('Field to reorder children in.'),
        '#options' => array_map(function ($field_name) {
          return $this->entity->getFieldDefinitions()[$field_name]->getLabel();
        }, $fields),
        '#default_value' => $fieldName,
      ];
      $form['select_field']['update'] = [
        '#type' => 'submit',
        '#value' => $this->t('Update'),
        '#submit' => ['::updateField'],
      ];
    }
    /** @var \PNX\NestedSet\Node[] $children */
    /** @var \PNX\NestedSet\NestedSetInterface $storage */
    $storage = $this->nestedSetStorageFactory->get($fieldName, $this->entity->getEntityTypeId());
    $children = $storage->findChildren($this->nodeKeyFactory->fromEntity($this->entity));
    $childEntities = $this->entityTreeNodeMapper->loadAndAccessCheckEntitysForTreeNodes($this->entity->getEntityTypeId(), $children, $cache);
    $form_state->setTemporaryValue(self::CHILD_ENTITIES_STORAGE, $childEntities);
    $form['#attached']['library'][] = 'entity_hierarchy/entity_hierarchy.nodetypeform';
    $form['children'] = [
      '#type' => 'table',
      '#header' => [
        $this->t('Child'),
        $this->t('Type'),
        $this->t('Weight'),
        $this->t('Operations'),
      ],
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'children-order-weight',
        ],
      ],
      '#empty' => $this->t('There are no children to reorder'),
    ];

    $bundles = FALSE;

    foreach ($children as $weight => $node) {
      if (!$childEntities->contains($node)) {
        // Doesn't exist or is access hidden.
        continue;
      }
      /** @var \Drupal\Core\Entity\ContentEntityInterface $childEntity */
      $childEntity = $childEntities->offsetGet($node);
      if (!$childEntity->isDefaultRevision()) {
        // We only update default revisions here.
        continue;
      }
      $child = $node->getId();
      $form['children'][$child]['#attributes']['class'][] = 'draggable';
      $form['children'][$child]['#weight'] = $weight;
      $form['children'][$child]['title'] = $childEntity->toLink()
        ->toRenderable();
      if (!$bundles) {
        $bundles = $this->entityTypeBundleInfo->getBundleInfo($childEntity->getEntityTypeId());
      }
      $form['children'][$child]['type'] = ['#markup' => $bundles[$childEntity->bundle()]['label']];
      $form['children'][$child]['weight'] = [
        '#type' => 'weight',
        '#delta' => 50,
        '#title' => $this->t('Weight for @title', ['@title' => $childEntity->label()]),
        '#title_display' => 'invisible',
        '#default_value' => $childEntity->{$fieldName}->weight,
        // Classify the weight element for #tabledrag.
        '#attributes' => ['class' => ['children-order-weight']],
      ];
      // Operations column.
      $form['children'][$child]['operations'] = [
        '#type' => 'operations',
        '#links' => [],
      ];
      if ($childEntity->access('update') && $childEntity->hasLinkTemplate('edit-form')) {
        $form['children'][$child]['operations']['#links']['edit'] = [
          'title' => $this->t('Edit'),
          'url' => $childEntity->toUrl('edit-form'),
        ];
      }
    }

    $cache->applyTo($form);

    return $form;
  }

  /**
   * Submit handler for update field button.
   *
   * @param array $form
   *   Form array.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   Form state.
   */
  public function updateField(array $form, FormStateInterface $formState) {
    $formState->setRebuild(TRUE);
  }

  /**
   * {@inheritdoc}
   */
  protected function actions(array $form, FormStateInterface $form_state) {
    $actions = parent::actions($form, $form_state);
    $actions['submit']['#value'] = $this->t('Update child order');
    // Don't perform field validation.
    $actions['submit']['#limit_validation_errors'] = [['children'], ['fieldname']];
    unset($actions['delete']);
    // Don't show the actions links if there are no children.
    if (empty(Element::children($form['children']))) {
      unset($actions['submit']);
    }
    $fields = $this->parentCandidate->getCandidateFields($this->entity);
    $fieldName = $form_state->getValue('fieldname') ?: reset($fields);
    $entityType = $this->entity->getEntityType();
    if ($entityType->hasHandlerClass('entity_hierarchy') && ($childBundles = $this->parentCandidate->getCandidateBundles($this->entity)) && isset($childBundles[$fieldName])) {
      $handlerClass = $entityType->getHandlerClass('entity_hierarchy');
      /** @var \Drupal\entity_hierarchy\Handler\EntityHierarchyHandlerInterface $handler */
      $handler = new $handlerClass();

      $links = [];
      foreach ($childBundles[$fieldName] as $id => $info) {
        $url = $handler->getAddChildUrl($entityType, $this->entity, $id, $fieldName);
        if ($url->access()) {
          $links[$id] = [
            'title' => $this->t('Create new @bundle', ['@bundle' => $info['label']]),
            'url' => $url,
          ];
        }
      }
      if (count($links) > 1) {
        $actions['add_child'] = [
          '#type' => 'dropbutton',
          '#links' => $links,
        ];
      }
      else {
        $link = reset($links);
        $actions['add_child'] = [
          '#type' => 'link',
          '#title' => $link['title'],
          '#url' => $link['url'],
          '#attributes' => [
            'class' => ['button', 'button--primary'],
          ],
          '#weight' => -100,
        ];
      }

    }
    return $actions;
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $children = $form_state->getValue('children');
    $childEntities = $form_state->getTemporaryValue(self::CHILD_ENTITIES_STORAGE);
    $fieldName = $form_state->getValue('fieldname');
    $batch = [
      'title' => new TranslatableMarkup('Reordering children ...'),
      'operations' => [],
      'finished' => [static::class, 'finished'],
    ];
    foreach ($childEntities as $node) {
      $childEntity = $childEntities->offsetGet($node);
      if (!$childEntity->isDefaultRevision()) {
        // We don't operate on other than the default revision.
        continue;
      }
      $batch['operations'][] = [
        [static::class, 'reorder'],
        [$fieldName, $childEntity, $children[$node->getId()]['weight']],
      ];

    }
    batch_set($batch);
    return SAVED_UPDATED;
  }

  /**
   * Reorder batch callback.
   *
   * @param string $fieldName
   *   Field name.
   * @param \Drupal\Core\Entity\ContentEntityInterface $childEntity
   *   Child entity being updated.
   * @param int $weight
   *   New weight.
   */
  public static function reorder($fieldName, ContentEntityInterface $childEntity, $weight) {
    $childEntity->{$fieldName}->weight = $weight;
    $childEntity->save();
  }

  /**
   * Batch finished callback.
   */
  public static function finished() {
    \Drupal::messenger()->addMessage(new TranslatableMarkup('Updated child order.'));
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc