You are here

class ContentLockSettingsForm in Content locking (anti-concurrent editing) 8

Same name and namespace in other branches
  1. 8.2 src/Form/ContentLockSettingsForm.php \Drupal\content_lock\Form\ContentLockSettingsForm

Class ContentLockSettingsForm.

@package Drupal\content_lock\Form

Hierarchy

Expanded class hierarchy of ContentLockSettingsForm

1 string reference to 'ContentLockSettingsForm'
content_lock.routing.yml in ./content_lock.routing.yml
content_lock.routing.yml

File

src/Form/ContentLockSettingsForm.php, line 20

Namespace

Drupal\content_lock\Form
View source
class ContentLockSettingsForm extends ConfigFormBase {

  /**
   * The entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Drupal\Core\Extension\ModuleHandlerInterface module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * {@inheritdoc}
   */
  public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entityTypeManager, ModuleHandlerInterface $module_handler) {
    parent::__construct($config_factory);
    $this->entityTypeManager = $entityTypeManager;
    $this->moduleHandler = $module_handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('config.factory'), $container
      ->get('entity_type.manager'), $container
      ->get('module_handler'));
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'content_lock.settings',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'content_lock_settings_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this
      ->config('content_lock.settings');
    $form['general'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Verbose'),
      '#open' => TRUE,
      '#tree' => TRUE,
      '#process' => [
        [
          get_class($this),
          'formProcessMergeParent',
        ],
      ],
      '#weight' => 0,
    ];
    $form['general']['verbose'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Enable this option to display a message to the user when they lock a content item by editing it.'),
      '#description' => $this
        ->t('Users trying to edit a content locked still see the content lock message.'),
      '#default_value' => $config
        ->get('verbose'),
      '#return_value' => 1,
      '#empty' => 0,
    ];
    $form['entities'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Entity type protected'),
      '#open' => TRUE,
      '#tree' => TRUE,
      '#process' => [
        [
          get_class($this),
          'formProcessMergeParent',
        ],
      ],
      '#weight' => 1,
    ];
    $definitions = $this->entityTypeManager
      ->getDefinitions();
    $entity_types = [];
    $selected_entity_types = [];
    foreach ($definitions as $definition) {
      if ($definition instanceof ContentEntityTypeInterface) {
        $entity_types[$definition
          ->id()] = $definition
          ->getLabel();
        if (!empty($config
          ->get('types.' . $definition
          ->id()))) {
          $selected_entity_types[] = $definition
            ->id();
        }
      }
    }
    $form['entities']['entity_types'] = [
      '#type' => 'checkboxes',
      '#title' => 'Protected entity types',
      '#options' => $entity_types,
      '#default_value' => $selected_entity_types,
      '#attributes' => [
        'class' => [
          'content-lock-entity-types',
        ],
      ],
    ];
    foreach ($definitions as $definition) {
      if ($definition instanceof ContentEntityTypeInterface) {
        $form['entities'][$definition
          ->id()] = [
          '#type' => 'container',
          '#title' => $definition
            ->getLabel(),
          '#theme' => 'content_lock_settings_entities',
          '#states' => [
            'visible' => [
              ':input[name="entity_types[' . $definition
                ->id() . ']"]' => [
                'checked' => TRUE,
              ],
            ],
          ],
          '#attributes' => [
            'class' => [
              $definition
                ->id(),
            ],
          ],
        ];
        $options = [
          '*' => $this
            ->t('All'),
        ];
        if ($definition
          ->getBundleEntityType()) {
          $bundles = $this->entityTypeManager
            ->getStorage($definition
            ->getBundleEntityType())
            ->loadMultiple();
          foreach ($bundles as $bundle) {
            $options[$bundle
              ->id()] = $bundle
              ->label();
          }
        }
        else {
          $options[$definition
            ->id()] = $definition
            ->getLabel();
        }
        $form['entities'][$definition
          ->id()]['bundles'] = [
          '#type' => 'checkboxes',
          '#title' => $definition
            ->getBundleLabel() ?: $definition
            ->getLabel(),
          '#description' => $this
            ->t('Select the bundles on which enable content lock'),
          '#options' => $options,
          '#default_value' => $config
            ->get('types.' . $definition
            ->id()) ?: [],
          '#attributes' => [
            'class' => [
              'content-lock-entity-settings',
            ],
          ],
        ];
        $form['entities'][$definition
          ->id()]['settings']['translation_lock'] = [
          '#type' => 'checkbox',
          '#title' => $this
            ->t('Lock only on entity translation level.'),
          '#default_value' => in_array($definition
            ->id(), $config
            ->get('types_translation_lock') ?: []),
          '#description' => $this
            ->t('Activating this options allows users to edit multiple translations concurrently'),
        ];
        if (!$this->moduleHandler
          ->moduleExists('conflict')) {
          $form['entities'][$definition
            ->id()]['settings']['translation_lock'] = [
            '#disabled' => TRUE,
            '#default_value' => FALSE,
            '#description' => $this
              ->t('To allow editing multiple translations concurrently you need to install %module', [
              '%module' => $this
                ->getLinkGenerator()
                ->generate('Conflict', Url::fromUri('https://www.drupal.org/project/conflict')),
            ]),
          ] + $form['entities'][$definition
            ->id()]['settings']['translation_lock'];
        }
        $form['entities'][$definition
          ->id()]['settings']['js_lock'] = [
          '#type' => 'checkbox',
          '#title' => $this
            ->t('Lock form using JS.'),
          '#default_value' => in_array($definition
            ->id(), $config
            ->get('types_js_lock') ?: []),
          '#description' => $this
            ->t('Activating this options activates the lock when the user is on the form. This helps if modules interacting with form without a user interacting with the form, like the prefetch_cache module.'),
        ];
        if (!empty($definition
          ->getHandlerClasses()['form'])) {
          $form['entities'][$definition
            ->id()]['settings']['form_op_lock'] = [
            '#tree' => 1,
          ];
          $form['entities'][$definition
            ->id()]['settings']['form_op_lock']['mode'] = [
            '#type' => 'radios',
            '#title' => $this
              ->t('Lock only on entity form operation level.'),
            '#options' => [
              ContentLock::FORM_OP_MODE_DISABLED => $this
                ->t('Disabled'),
              ContentLock::FORM_OP_MODE_WHITELIST => $this
                ->t('Enable lock for selected form operations'),
              ContentLock::FORM_OP_MODE_BLACKLIST => $this
                ->t('Disable lock for selected form operations'),
            ],
            '#default_value' => $config
              ->get('form_op_lock.' . $definition
              ->id() . '.mode') ?: ContentLock::FORM_OP_MODE_DISABLED,
            '#description' => $this
              ->t('Activating this options allows users to edit different entity forms concurrently'),
          ];
          $form_ops = array_keys($definition
            ->getHandlerClasses()['form']);
          $form_ops = array_combine($form_ops, $form_ops);
          $form['entities'][$definition
            ->id()]['settings']['form_op_lock']['values'] = [
            '#type' => 'checkboxes',
            '#title' => $this
              ->t('Form operations'),
            '#options' => $form_ops,
            '#default_value' => (array) $config
              ->get('form_op_lock.' . $definition
              ->id() . '.values'),
            '#states' => [
              'invisible' => [
                ':input[name="' . $definition
                  ->id() . '[settings][form_op_lock][mode]"]' => [
                  'value' => ContentLock::FORM_OP_MODE_DISABLED,
                ],
              ],
            ],
          ];
        }
      }
    }
    $form['#attached']['library'][] = 'content_lock/drupal.content_lock.settings';
    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);
    $content_lock = $this
      ->config('content_lock.settings');
    $definitions = $this->entityTypeManager
      ->getDefinitions();
    foreach ($definitions as $definition) {
      if ($definition instanceof ContentEntityTypeInterface) {
        if ($form_state
          ->getValue($definition
          ->id())) {
          $content_lock
            ->set('types.' . $definition
            ->id(), $this
            ->removeEmptyValue($form_state
            ->getValue([
            $definition
              ->id(),
            'bundles',
          ])));
          $translation_lock = (bool) $form_state
            ->getValue([
            $definition
              ->id(),
            'settings',
            'translation_lock',
          ]);
          $types_translation_lock = $content_lock
            ->get('types_translation_lock') ?: [];
          if ($translation_lock && !in_array($definition
            ->id(), $types_translation_lock)) {
            $types_translation_lock[] = $definition
              ->id();
          }
          elseif (!$translation_lock && in_array($definition
            ->id(), $types_translation_lock)) {
            $types_translation_lock = array_diff($types_translation_lock, [
              $definition
                ->id(),
            ]);
          }
          $content_lock
            ->set('types_translation_lock', $types_translation_lock);
          $js_lock = (bool) $form_state
            ->getValue([
            $definition
              ->id(),
            'settings',
            'js_lock',
          ]);
          $types_js_lock = $content_lock
            ->get('types_js_lock') ?: [];
          if ($js_lock && !in_array($definition
            ->id(), $types_js_lock)) {
            $types_js_lock[] = $definition
              ->id();
          }
          elseif (!$js_lock && in_array($definition
            ->id(), $types_js_lock)) {
            $types_js_lock = array_diff($types_js_lock, [
              $definition
                ->id(),
            ]);
          }
          $content_lock
            ->set('types_js_lock', $types_js_lock);
          $content_lock
            ->set('form_op_lock.' . $definition
            ->id() . '.mode', $form_state
            ->getValue([
            $definition
              ->id(),
            'settings',
            'form_op_lock',
            'mode',
          ]));
          $content_lock
            ->set('form_op_lock.' . $definition
            ->id() . '.values', $this
            ->removeEmptyValue((array) $form_state
            ->getValue([
            $definition
              ->id(),
            'settings',
            'form_op_lock',
            'values',
          ])));
        }
      }
    }
    $content_lock
      ->set('verbose', $form_state
      ->getValue('verbose'))
      ->save();
  }

  /**
   * Helper function to filter empty value in an array.
   *
   * @param array $array
   *   The array to check for empty values.
   *
   * @return array
   *   The array without empty values.
   */
  protected function removeEmptyValue(array $array) {
    return array_filter($array, function ($value) {
      return !empty($value);
    });
  }

  /**
   * Merge elements to the level up.
   *
   * Render API callback: Moves entity_reference specific Form API elements
   * (i.e. 'handler_settings') up a level for easier processing values.
   *
   * @param array $element
   *   The array to filter.
   *
   * @return array
   *   The array filtered.
   *
   * @see _entity_reference_field_settings_process()
   */
  public static function formProcessMergeParent(array $element) {
    $parents = $element['#parents'];
    array_pop($parents);
    $element['#parents'] = $parents;
    return $element;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ConfigFormBaseTrait::config protected function Retrieves a configuration object.
ContentLockSettingsForm::$entityTypeManager protected property The entity type manager service.
ContentLockSettingsForm::$moduleHandler protected property Drupal\Core\Extension\ModuleHandlerInterface module handler.
ContentLockSettingsForm::buildForm public function Form constructor. Overrides ConfigFormBase::buildForm
ContentLockSettingsForm::create public static function Instantiates a new instance of this class. Overrides ConfigFormBase::create
ContentLockSettingsForm::formProcessMergeParent public static function Merge elements to the level up.
ContentLockSettingsForm::getEditableConfigNames protected function Gets the configuration names that will be editable. Overrides ConfigFormBaseTrait::getEditableConfigNames
ContentLockSettingsForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
ContentLockSettingsForm::removeEmptyValue protected function Helper function to filter empty value in an array.
ContentLockSettingsForm::submitForm public function Form submission handler. Overrides ConfigFormBase::submitForm
ContentLockSettingsForm::__construct public function Constructs a \Drupal\system\ConfigFormBase object. Overrides ConfigFormBase::__construct
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 1
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::configFactory protected function Gets the config factory for this form. 1
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
FormBase::validateForm public function Form validation handler. Overrides FormInterface::validateForm 62
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.