group-8.x-1.x-dev/src/Hook/FormHooks.php

src/Hook/FormHooks.php
<?php

declare(strict_types=1);

namespace Drupal\group\Hook;

use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\Core\Render\Element;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\group\Entity\GroupInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Form hook implementations for Group.
 */
final class FormHooks {

  use StringTranslationTrait;

  public function __construct(
    protected PrivateTempStoreFactory $privateTempStoreFactory,
    protected RequestStack $requestStack,
    TranslationInterface $translation,
  ) {
    $this->stringTranslation = $translation;
  }

  /**
   * Implements hook_form_FORM_ID_alter().
   */
  #[Hook('form_block_form_alter')]
  public function formBlockFormAlter(array &$form, FormStateInterface $form_state, string $form_id): void {
    if (isset($form['visibility']['group_type'])) {
      $form['visibility_tabs']['#attached']['library'][] = 'group/block';
      $form['visibility']['group_type']['#title'] = $this->t('Group types');
      $form['visibility']['group_type']['negate']['#type'] = 'value';
      $form['visibility']['group_type']['negate']['#title_display'] = 'invisible';
      $form['visibility']['group_type']['negate']['#value'] = $form['visibility']['group_type']['negate']['#default_value'];
    }
  }

  /**
   * Implements hook_form_alter().
   */
  #[Hook('form_alter')]
  public function formAlter(array &$form, FormStateInterface $form_state, string $form_id): void {
    // GroupRelationshipController::createForm() tends to load entity forms for
    // adding entities to a group. We need to add or alter the submit handlers
    // of those forms for the process to work properly.
    if ($form_state->has('group_wizard') && $form_state->get('group_wizard_id') == 'group_entity') {
      if ($wizard = $form_state->get('group_wizard')) {
        $store = $this->privateTempStoreFactory->get($form_state->get('group_wizard_id'));
        $store_id = $form_state->get('store_id');

        // Bail out if we are on step 2 of the wizard. We only want to alter the
        // submit handlers for the first step or if we are not in a wizard.
        if ($store->get("$store_id:step") === 2) {
          return;
        }
      }

      $actions = $form['actions'] ?? [];
      foreach (Element::children($actions) as $name) {
        // Remove preview button as it redirects back to the wrong form.
        if ($name == 'preview') {
          unset($form['actions'][$name]);
          continue;
        }

        // Skip buttons without submit handlers.
        if (empty($form['actions'][$name]['#submit'])) {
          continue;
        }

        // Skip buttons that do not properly build and save an entity.
        $submit = $form['actions'][$name]['#submit'];
        if (!in_array('::submitForm', $submit) || !in_array('::save', $submit)) {
          continue;
        }

        // If we are using the wizard, we need to substitute the entity save
        // handler in order to add the entity to the private temp store.
        if ($wizard) {
          foreach ($submit as $key => $handler) {
            if ($handler == '::save') {
              $form['actions'][$name]['#submit'][$key] = [$this, 'groupRelationshipWizardStore'];
            }
          }
        }
        // Otherwise, we can simply add our submit handler and be done with it.
        else {
          $form['actions'][$name]['#submit'][] = [$this, 'groupRelationshipEntitySubmit'];
        }
      }

      // If we are using the wizard, we also add a cancel button to step 1.
      if ($wizard) {
        $form['actions']['cancel'] = [
          '#type' => 'submit',
          '#value' => t('Cancel'),
          '#submit' => [[$this, 'groupRelationshipWizardCancel']],
          '#limit_validation_errors' => [],
        ];
      }
    }
  }

  /**
   * Stores a content entity from the wizard step 1 in the temp store.
   *
   * @see ::formAlter()
   * @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm()
   */
  public function groupRelationshipWizardStore(array $form, FormStateInterface $form_state): void {
    $form_object = $form_state->getFormObject();
    assert($form_object instanceof EntityFormInterface);

    // Store the unsaved entity in the temp store.
    $store = $this->privateTempStoreFactory->get($form_state->get('group_wizard_id'));
    $store_id = $form_state->get('store_id');
    $store->set("$store_id:entity", $form_object->getEntity());
    $store->set("$store_id:step", 2);

    // Disable any URL-based redirect until the final step.
    $request = $this->requestStack->getCurrentRequest();
    $form_state->setRedirect('<current>', [], ['query' => $request->query->all()]);
    $request->query->remove('destination');
  }

  /**
   * Cancels the wizard for relationship creation.
   *
   * @see ::formAlter()
   * @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm()
   */
  public function groupRelationshipWizardCancel(array $form, FormStateInterface $form_state): void {
    $store = $this->privateTempStoreFactory->get($form_state->get('group_wizard_id'));
    $store_id = $form_state->get('store_id');
    $store->delete("$store_id:entity");
    $store->delete("$store_id:step");

    $group = $form_state->get('group');
    assert($group instanceof GroupInterface);

    // Redirect to the group page if no destination was set in the URL.
    $form_state->setRedirect('entity.group.canonical', ['group' => $group->id()]);
  }

  /**
   * Adds a newly saved entity to a group.
   *
   * @see ::formAlter()
   * @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm()
   */
  public function groupRelationshipEntitySubmit(array $form, FormStateInterface $form_state): void {
    $form_object = $form_state->getFormObject();
    assert($form_object instanceof EntityFormInterface);
    $entity = $form_object->getEntity();

    $group = $form_state->get('group');
    assert($group instanceof GroupInterface);
    $group->addRelationship($entity, $form_state->get('group_relation'));

    // This submit handler is only called when creating new content within a
    // group without using the 2-step wizard. We can therefore safely assume the
    // user wants to see the entity itself and not the relationship. This only
    // applies if there was no "destination" query argument.
    if ($entity->access('view')) {
      $form_state->setRedirectUrl($entity->toUrl());
    }
    elseif ($group->access('view')) {
      $form_state->setRedirectUrl($group->toUrl());
    }
    else {
      $form_state->setRedirect('<front>');
    }
  }

}

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

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