association-1.0.0-alpha2/src/Plugin/Association/LandingPage/AssociatedEntity.php

src/Plugin/Association/LandingPage/AssociatedEntity.php
<?php

namespace Drupal\association\Plugin\Association\LandingPage;

use Drupal\association\Attribute\AssociationLandingPage;
use Drupal\association\Entity\AssociationInterface;
use Drupal\association\Entity\AssociationTypeInterface;
use Drupal\association\Plugin\AssociationPluginFormInterface;
use Drupal\association\Plugin\LandingPagePluginBase;
use Drupal\association\Plugin\LandingPagePluginInterface;
use Drupal\association\Plugin\PluginFieldSettingsInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

/**
 * Plugin to manage an associated entity as the association landing page.
 */
#[AssociationLandingPage(
  id: 'associated_entity',
  label: new TranslatableMarkup('Associated Content'),
  description: new TranslatableMarkup('Select an associated entity to use as the landing page.'),
)]
class AssociatedEntity extends LandingPagePluginBase implements LandingPagePluginInterface, AssociationPluginFormInterface, PluginFieldSettingsInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface {

  /**
   * The association_link entity storage handler.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected EntityStorageInterface $assocLinkStorage;

  /**
   * Creates a new instance of the AssociatedEntity landing page plugin.
   *
   * @param array $configuration
   *   The landing page plugin configuration.
   * @param string $plugin_id
   *   The plugin identifier.
   * @param mixed $plugin_definition
   *   The landing page plugin definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->assocLinkStorage = $entity_type_manager->getStorage('association_link');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function trustedCallbacks() {
    return [
      'preRenderEmptyMessage',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return [
      'tags' => [],
      'allow_fallback' => FALSE,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getPage(AssociationInterface $association): ?EntityInterface {
    $settings = $association->getPageSettings();
    if (!empty($settings['page'])) {
      /** @var \Drupal\association\Entity\AssociatedEntityInterface $rel */
      $rel = $this->assocLinkStorage->load($settings['page']);

      // If this association_link exists and belongs to the association,
      // return the target entity.
      if ($rel && $rel->getAssociation()->id() == $association->id()) {
        return $rel->getTarget();
      }
    }

    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getPageUrl(AssociationInterface $association, ?EntityInterface $page): Url {
    try {
      if ($page) {
        return $page->toUrl();
      }
    }
    catch (EntityMalformedException | UndefinedLinkTemplateException) {
      // Selected entity doesn't a canonical page link.
    }

    return Url::fromRoute('<nolink>');
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state, AssociationTypeInterface $association_type = NULL): array {
    $form['tags'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Select content types allowed to be set as the landing page'),
      '#options' => $association_type->getBehavior()->getTags(),
      '#default_value' => $this->configuration['tags'],
      '#description' => $this->t('Leaving this blank allows all the content is allowed for the homepage. Keep in mind that these options rely on your behavior settings so you may not see all current options until after you save your behavior changes.'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['tags'] = array_filter($form_state->getValue('tags'));
  }

  /**
   * {@inheritdoc}
   */
  public function buildSettingsForm(AssociationInterface $association, array $settings, FormStateInterface $form_state): array {
    $elements = [];

    // Unable to select landing page content for an association which hasn't
    // been created yet and would not have any content at this point.
    if (!$association->isNew() && $association->id()) {
      // Find all candidates for the landing page to select from.
      $query = $this->assocLinkStorage
        ->getQuery()
        ->accessCheck(TRUE)
        ->condition('association', $association->id());

      // If limited to certain tags, filter only matching entities.
      $config = $this->getConfiguration();
      if (!empty($config['tags'])) {
        $query->condition('tag', $config['tags'], 'IN');
      }

      $ids = $query->execute();
    }

    if (!empty($ids)) {
      $options = [];
      foreach ($this->assocLinkStorage->loadMultiple($ids) as $link) {
        $options[$link->id()] = $link->label();
      }

      $elements['page'] = [
        '#type' => 'select',
        '#title' => $this->t('Select landing page'),
        '#required' => TRUE,
        '#options' => $options,
        '#default_value' => $settings['page'] ?? NULL,
      ];
    }
    else {
      $elements['#association_id'] = $association->id();
      $elements['#pre_render'][] = static::class . '::preRenderEmptyMessage';
    }

    return $elements;
  }

  /**
   * {@inheritdoc}
   */
  public function validateSettings(AssociationInterface $association, array $values, Constraint $constraint, ExecutionContextInterface $context): void {
    if (!empty($values['page'])) {
      /** @var \Drupal\association\Entity\AssociationLink|null $link */
      $link = $this->assocLinkStorage->load($values['page']);

      if (!$link) {
        $context->addViolation('Selected content does not exist or is invalid.');
      }
      elseif ($link->getAssociation()->id() != $association->id()) {
        $context->addViolation('Selected content "@label" does not belong to the target association.', [
          '@label' => $link->label(),
        ]);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function processValues(AssociationInterface $association, array $values, array &$form, FormStateInterface $form_state): array {
    foreach ($values as &$value) {
      if (!empty($value['settings']['page'])) {
        $value['settings']['page'] = intval($value['settings']['page']);
      }
    }

    return $values;
  }

  /**
   * FAPI pre_render callback to produce a static no options warning.
   *
   * Creating the warning during the pre_render allows us to create a message
   * to render that doesn't get form processed.
   *
   * @param array $element
   *   The form elements to process.
   *
   * @return array
   *   The updated form elements.
   */
  public static function preRenderEmptyMessage(array $element) {
    $manageUrl = Url::fromRoute('entity.association.manage', [
      'association' => $element['#association_id'],
    ]);

    if ($manageUrl->access()) {
      $message = new TranslatableMarkup('<p>No associated content is available for the landing page.</p><p>Create some association content on the <a href="@link">Manage Content</a> administration page and return here to set one of them as the landing page.</p>', [
        '@link' => $manageUrl->toString(),
      ]);
    }
    else {
      $message = new TranslatableMarkup('<p>No associated content is available to use as the landing page.</p>');
    }

    $element['message'] = ['#markup' => $message];
    return $element;
  }

}

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

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