Commit f97604b1 authored by Andrey Tymchuk's avatar Andrey Tymchuk Committed by Pawel Ginalski
Browse files

Issue #3271721 by WalkingDexter, gbyte: Refactor FormHelper classes

parent d08287f8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@
      $(context).find('.simple-sitemap-fieldset').drupalSetSummary(function (context) {
        let summary = '', enabledVariants = [];

        $(context).find('input:checkbox[name$="[index_now]"]').each(function () {
        $(context).find('input:checkbox[name*="simple_sitemap_index_now"]').each(function () {
          summary = (this.checked ? Drupal.t('IndexNow notification enabled') : Drupal.t('IndexNow notification disabled')) + ', ';
        });

+9 −90
Original line number Diff line number Diff line
@@ -7,9 +7,7 @@

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\simple_sitemap_engines\Entity\SimpleSitemapEngine;
use Drupal\simple_sitemap_engines\Form\FormHelper;

/**
 * Implements hook_cron().
@@ -43,106 +41,27 @@ function simple_sitemap_engines_cron() {
 * Implements hook_form_alter().
 */
function simple_sitemap_engines_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var Drupal\simple_sitemap_engines\Form\FormHelper $f */
  $f = \Drupal::service('simple_sitemap.engines.form_helper');
  if (!$f->processForm($form_state)) {
    return;
  }

  if ($f->getEntityCategory() === 'bundle' && isset($form['simple_sitemap'])) {
    $f->displayEntitySettings($form['simple_sitemap']);
    FormHelper::addSubmitHandler($form, 'simple_sitemap_engines_bundle_entity_form_submit');
  }
  elseif ($f->getEntityCategory() === 'instance') {
    $f->displayEntitySettings($form);
    FormHelper::addSubmitHandler($form, 'simple_sitemap_engines_entity_form_submit');
  }
  /** @var \Drupal\simple_sitemap_engines\Form\FormHelper $form_helper */
  $form_helper = \Drupal::service('simple_sitemap.engines.form_helper');
  $form_helper->formAlter($form, $form_state);
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function simple_sitemap_engines_form_simple_sitemap_entity_bundles_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  foreach ($form['settings'] as $bundle => &$bundle_settings) {
    /** @var Drupal\simple_sitemap_engines\Form\FormHelper $f */
    $f = \Drupal::service('simple_sitemap.engines.form_helper');
    $f->setEntityCategory('bundle')
      ->setEntityTypeId($form['entity_type_id']['#value'])
      ->setBundleName($bundle)
      ->displayEntitySettings($bundle_settings);
  }
  FormHelper::addSubmitHandler($form, 'simple_sitemap_engines_entity_bundles_form_submit');
  /** @var \Drupal\simple_sitemap_engines\Form\FormHelper $form_helper */
  $form_helper = \Drupal::service('simple_sitemap.engines.form_helper');
  $form_helper->entityBundlesFormAlter($form);
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * @todo Implement form overriding \Drupal\simple_sitemap\Form\EntitiesForm.
 */
function simple_sitemap_engines_form_simple_sitemap_entities_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var \Drupal\simple_sitemap\Entity\EntityHelper $entity_helper */
  $entity_helper = \Drupal::service('simple_sitemap.entity_helper');

  $header = &$form['sitemap_entities']['entity_types']['#header'];
  array_splice($header, 2, 0, ['index_now' => t('IndexNow')]);

  foreach(Element::children($form['sitemap_entities']['entity_types']) as $type) {
    $row = &$form['sitemap_entities']['entity_types'][$type];
    $enabled = $row['enabled']['#default_value'];
    $bundles = [];
    if ($enabled) {
      foreach (\Drupal::configFactory()->listAll("simple_sitemap_engines.bundle_settings.$type.") as $name) {
        if (\Drupal::configFactory()->get($name)->get('index_now')) {
          $name_parts = explode('.', $name);
          $bundles[] = $entity_helper->getBundleLabel($type, array_pop($name_parts));
        }
      }
    }
    array_splice($row, 2, 0, ['index_now' => [
      '#type' => 'item',
      '#input' => FALSE,
      '#markup' => $bundles
        ? '<em>' . implode(', ', $bundles) . "</em>"
        : ($enabled ? t('Excluded') : NULL),
    ]]);
  }
}

/**
 * Form submission handler called in hook_form_alter.
 */
function simple_sitemap_engines_bundle_entity_form_submit(array $form, FormStateInterface $form_state) {
  /** @var Drupal\simple_sitemap_engines\Form\FormHelper $f */
  $f = \Drupal::service('simple_sitemap.engines.form_helper');
  if (!$f->processForm($form_state)) {
    return;
  }

  \Drupal::configFactory()->getEditable(
    "simple_sitemap_engines.bundle_settings.{$f->getEntityTypeId()}.{$f->getBundleName()}"
  )->set('index_now', $form_state->getValue(['simple_sitemap', 'index_now']))->save();
}

/**
 * Form submission handler called in hook_form_alter.
 */
function simple_sitemap_engines_entity_form_submit(array $form, FormStateInterface $form_state) {
  /** @var Drupal\simple_sitemap_engines\Form\FormHelper $f */
  $f = \Drupal::service('simple_sitemap.engines.form_helper');
  if ($f->processForm($form_state)) {
    $f->getEntity()->_index_now = (bool) $form_state->getValue(['index_now']);
  }
}

/**
 * Form submission handler called in hook_form_alter.
 */
function simple_sitemap_engines_entity_bundles_form_submit(array $form, FormStateInterface $form_state) {
  foreach ($form_state->getValue('bundles') as $bundle => $settings) {
    \Drupal::configFactory()->getEditable(
    "simple_sitemap_engines.bundle_settings.{$form_state->getValue('entity_type_id')}.$bundle"
    )->set('index_now', $settings['index_now'])->save();
  }
  /** @var \Drupal\simple_sitemap_engines\Form\FormHelper $form_helper */
  $form_helper = \Drupal::service('simple_sitemap.engines.form_helper');
  $form_helper->entitiesFormAlter($form);
}

/**
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ services:
  simple_sitemap.engines.form_helper:
    class: Drupal\simple_sitemap_engines\Form\FormHelper
    parent: simple_sitemap.form_helper
    arguments:
      - '@config.factory'

  simple_sitemap.engines.path_processor:
    class: Drupal\simple_sitemap_engines\PathProcessor\IndexNowPathProcessor
+122 −76
Original line number Diff line number Diff line
@@ -2,108 +2,154 @@

namespace Drupal\simple_sitemap_engines\Form;

use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\simple_sitemap\Form\FormHelper as BaseFormHelper;
use Drupal\simple_sitemap\Entity\EntityHelper;
use Drupal\simple_sitemap\Manager\Generator;
use Drupal\simple_sitemap\Settings;
use Drupal\simple_sitemap_engines\Form\Handler\BundleEntityFormHandler;
use Drupal\simple_sitemap_engines\Form\Handler\EntityFormHandler;

/**
 * Slightly altered version of the Simple XML Sitemap form helper.
 * Slightly altered version of the base form helper.
 */
class FormHelper extends BaseFormHelper {

  protected const ENTITY_FORM_HANDLER = EntityFormHandler::class;
  protected const BUNDLE_ENTITY_FORM_HANDLER = BundleEntityFormHandler::class;

  /**
   * {@inheritdoc}
   * The configuration factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected static $allowedFormOperations = [
    'default',
    'edit',
    'add',
    'register',
    'delete',
  ];
  protected $configFactory;

  /**
   * {@inheritdoc}
   * FormHelper constructor.
   *
   * @param \Drupal\simple_sitemap\Manager\Generator $generator
   *   The sitemap generator service.
   * @param \Drupal\simple_sitemap\Settings $settings
   *   The simple_sitemap.settings service.
   * @param \Drupal\simple_sitemap\Entity\EntityHelper $entity_helper
   *   Helper class for working with entities.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   Proxy for the current user account.
   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
   *   The class resolver.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The configuration factory.
   */
  protected function userAccess(): bool {
    return \Drupal::config('simple_sitemap_engines.settings')->get('index_now_enabled')
      && ($this->currentUser->hasPermission('administer sitemap settings')
        || $this->currentUser->hasPermission('index entity on save'));
  public function __construct(
    Generator $generator,
    Settings $settings,
    EntityHelper $entity_helper,
    AccountProxyInterface $current_user,
    ClassResolverInterface $class_resolver,
    ConfigFactoryInterface $config_factory
  ) {
    parent::__construct($generator, $settings, $entity_helper, $current_user, $class_resolver);
    $this->configFactory = $config_factory;
  }

  /**
   * {@inheritdoc}
   */
  public function displayEntitySettings(array &$form_fragment): BaseFormHelper {
    $form_fragment['index_now'] = [
      '#type' => 'checkbox',
      '#title' => $this->entityCategory === 'bundle'
      ? t('Notify IndexNow search engines of changes <em>by default</em>')
      : t('Notify IndexNow search engines of changes <em>now</em>'),
      '#description' => $this->entityCategory === 'bundle'
      ? t('Send change notice to IndexNow compatible search engines right after submitting entity forms of this type.<br/>Changes include creating, deleting and updating of an entity. This setting can be overridden on the entity form.')
      : t('Send change notice to IndexNow compatible search engines right after submitting this form.'),
      '#default_value' => $this->bundleName
      ? (int) \Drupal::config("simple_sitemap_engines.bundle_settings.$this->entityTypeId.$this->bundleName")->get('index_now')
      : 0,
    ];

    if ($this->entityCategory === 'instance') {
      // If existing form entity is unpublished on load, assume it is a draft
      // and uncheck IndexNow. Check IndexNow when changing publishing status.
      if (!$this->entityIsNew()
        && $form_fragment['index_now']['#default_value']
        && isset($form_fragment['status'])
        && empty($form_fragment['status']['widget']['value']['#default_value'])) {
        $form_fragment['index_now']['#default_value'] = 0;
        $form_fragment['index_now']['#states'] = [
          'checked' => [':input[name="status[value]"]' => ['checked' => TRUE]],
        ];
  protected function formAlterAccess(): bool {
    $access = parent::formAlterAccess();

    return $this->configFactory->get('simple_sitemap_engines.settings')->get('index_now_enabled')
      && ($access || $this->currentUser->hasPermission('index entity on save'));
  }

      // If form entity is new, only check IndexNow when publishing status
      // is checked.
      if ($this->entityIsNew()
        && $form_fragment['index_now']['#default_value']
        && isset($form_fragment['status'])) {
        $form_fragment['index_now']['#states'] = [
          'checked' => [':input[name="status[value]"]' => ['checked' => TRUE]],
        ];
  /**
   * Alters the specific form (simple_sitemap_entities_form).
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   *
   * @see \Drupal\simple_sitemap\Form\EntitiesForm
   * @see simple_sitemap_engines_form_simple_sitemap_entities_form_alter()
   */
  public function entitiesFormAlter(array &$form) {
    if (!$this->formAlterAccess()) {
      return;
    }

      // Sensibly place the IndexNow checkbox.
      $form_fragment['index_now']['#group'] = 'footer';
      if (isset($form_fragment['status']['#weight'])) {
        $form_fragment['index_now']['#weight'] = $form_fragment['status']['#weight'] + 10;
    $table = &$form['sitemap_entities']['entity_types'];
    $offset = array_search('bundles', array_keys($table['#header'])) + 1;
    array_splice($table['#header'], $offset, 0, ['index_now' => $this->t('IndexNow')]);

    // Add column with IndexNow status.
    foreach (Element::children($table) as $entity_type_id) {
      $element = ['#markup' => ''];

      if ($table[$entity_type_id]['enabled']['#default_value']) {
        $bundles = [];

        foreach ($this->configFactory->listAll("simple_sitemap_engines.bundle_settings.$entity_type_id.") as $name) {
          if ($this->configFactory->get($name)->get('index_now')) {
            $name_parts = explode('.', $name);

            $bundles[] = $this->entityHelper
              ->getBundleLabel($entity_type_id, end($name_parts));
          }
      elseif (isset($form['actions']['submit']['#weight'])) {
        $form_fragment['index_now']['#weight'] = $form_fragment['actions']['submit']['#weight'] - 1;
        }

      // Remove access to IndexNow override checkbox if no verification key has
      // been added.
      if (SimplesitemapEnginesForm::getKeyLocation() === NULL) {
        $form_fragment['index_now']['#access'] = FALSE;
      }
        $element['#markup'] = $bundles
          ? '<em>' . implode(', ', $bundles) . '</em>'
          : $this->t('Excluded');
      }

    return $this;
      array_splice($table[$entity_type_id], $offset, 0, ['index_now' => $element]);
    }
  }

  /**
   * {@inheritdoc}
   * Alters the specific form (simple_sitemap_entity_bundles_form).
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   *
   * @see \Drupal\simple_sitemap\Form\EntityBundlesForm
   * @see simple_sitemap_engines_form_simple_sitemap_entity_bundles_form_alter()
   */
  public static function addSubmitHandler(array &$form, callable $callback) {
    if (isset($form['actions']['submit']['#submit'])) {
      foreach (array_keys($form['actions']) as $action) {
        if ($action !== 'preview'
          && isset($form['actions'][$action]['#type'])
          && $form['actions'][$action]['#type'] === 'submit') {
          $form['actions'][$action]['#submit'] = array_merge([$callback], $form['actions'][$action]['#submit']);
  public function entityBundlesFormAlter(array &$form) {
    if (!$this->formAlterAccess()) {
      return;
    }

    foreach ($form['settings'] as $bundle_name => &$bundle_form) {
      $bundle_form = $this->bundleSettingsForm($bundle_form, $form['entity_type_id']['#value'], $bundle_name);
      $bundle_form['simple_sitemap_index_now']['#tree'] = TRUE;
    }

    $form['#submit'][] = [$this, 'entityBundlesFormSubmit'];
  }
    // Fix for account page rendering other submit handlers not usable.
    else {
      $form['#submit'][] = $callback;

  /**
   * Form submission handler (simple_sitemap_entity_bundles_form).
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @see \Drupal\simple_sitemap\Form\EntityBundlesForm
   */
  public function entityBundlesFormSubmit(array &$form, FormStateInterface $form_state) {
    $entity_type_id = $form_state->getValue('entity_type_id');

    foreach ($form_state->getValue('bundles') as $bundle_name => $settings) {
      $this->configFactory
        ->getEditable("simple_sitemap_engines.bundle_settings.$entity_type_id.$bundle_name")
        ->set('index_now', $settings['simple_sitemap_index_now'])
        ->save();
    }
  }

+38 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\simple_sitemap_engines\Form\Handler;

use Drupal\Core\Form\FormStateInterface;
use Drupal\simple_sitemap\Form\Handler\BundleEntityFormHandlerTrait;

/**
 * Defines the handler for bundle entity forms.
 */
class BundleEntityFormHandler extends EntityFormHandlerBase {

  use BundleEntityFormHandlerTrait;

  /**
   * {@inheritdoc}
   */
  public function formAlter(array &$form, FormStateInterface $form_state) {
    if (isset($form['simple_sitemap'])) {
      parent::formAlter($form, $form_state);

      $form['simple_sitemap'] = $this->settingsForm($form['simple_sitemap']);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    $this->configFactory
      ->getEditable("simple_sitemap_engines.bundle_settings.$this->entityTypeId.$this->bundleName")
      ->set('index_now', $form_state->getValue('simple_sitemap_index_now'))
      ->save();
  }

}
Loading