You are here

class ReadOnlyFormSubscriber in Configuration Read-only mode 8

Check if the given form should be read-only.

Hierarchy

Expanded class hierarchy of ReadOnlyFormSubscriber

1 string reference to 'ReadOnlyFormSubscriber'
config_readonly.services.yml in ./config_readonly.services.yml
config_readonly.services.yml
1 service uses ReadOnlyFormSubscriber
config_readonly_form_subscriber in ./config_readonly.services.yml
Drupal\config_readonly\EventSubscriber\ReadOnlyFormSubscriber

File

src/EventSubscriber/ReadOnlyFormSubscriber.php, line 17

Namespace

Drupal\config_readonly\EventSubscriber
View source
class ReadOnlyFormSubscriber implements EventSubscriberInterface {
  use ConfigReadonlyWhitelistTrait;

  /**
   * ReadOnlyFormSubscriber constructor.
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler to invoke hooks.
   */
  public function __construct(ModuleHandlerInterface $module_handler) {
    $this
      ->setModuleHandler($module_handler);
  }

  /**
   * Form ids to mark as read only.
   *
   * @var array
   */
  protected $readOnlyFormIds = [
    'config_single_import_form',
    'system_modules',
    'system_modules_uninstall',
    'user_admin_permissions',
  ];

  /**
   * {@inheritdoc}
   */
  public function onFormAlter(ReadOnlyFormEvent $event) {

    // Check if the form is a ConfigFormBase or a ConfigEntityListBuilder.
    $form_object = $event
      ->getFormState()
      ->getFormObject();
    $mark_form_read_only = $form_object instanceof ConfigFormBase || $form_object instanceof ConfigEntityListBuilder;
    if (!$mark_form_read_only) {
      $mark_form_read_only = in_array($form_object
        ->getFormId(), $this->readOnlyFormIds);
    }

    // Check if the form is an EntityFormInterface and entity is a config
    // entity.
    if (!$mark_form_read_only && $form_object instanceof EntityFormInterface) {
      $entity = $form_object
        ->getEntity();
      $mark_form_read_only = $entity instanceof ConfigEntityInterface;
    }

    // Don't block particular patterns.
    if ($mark_form_read_only && $form_object instanceof EntityFormInterface) {
      $entity = $form_object
        ->getEntity();
      $name = $entity
        ->getConfigDependencyName();
      if ($this
        ->matchesWhitelistPattern($name)) {
        $mark_form_read_only = FALSE;
      }
    }
    if ($mark_form_read_only && $form_object instanceof ConfigFormBase) {

      // Get the editable configuration names.
      $editable_config = $this
        ->getEditableConfigNames($form_object);

      // If all editable config is in the whitelist, do not block the form.
      if ($editable_config == array_filter($editable_config, [
        $this,
        'matchesWhitelistPattern',
      ])) {
        $mark_form_read_only = FALSE;
      }
    }
    if ($mark_form_read_only) {
      $event
        ->markFormReadOnly();
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events = [];
    $events[ReadOnlyFormEvent::NAME][] = [
      'onFormAlter',
      200,
    ];
    return $events;
  }

  /**
   * Get the editable configuration names.
   *
   * @param \Drupal\Core\Form\ConfigFormBase $form
   *   The configuration form.
   *
   * @return array
   *   An array of configuration object names that are editable if called in
   *   conjunction with the trait's config() method.
   *
   * @see \Drupal\Core\Form\ConfigFormBaseTrait::getEditableConfigNames()
   */
  protected function getEditableConfigNames(ConfigFormBase $form) {

    // Use reflection to work around getEditableConfigNames() as protected.
    // @todo Review in 9.x for API change.
    // @see https://www.drupal.org/node/2095289
    $reflection = new \ReflectionMethod(get_class($form), 'getEditableConfigNames');
    $reflection
      ->setAccessible(TRUE);
    return $reflection
      ->invoke($form);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ConfigReadonlyWhitelistTrait::$moduleHandler protected property The module handler.
ConfigReadonlyWhitelistTrait::$patterns protected property An array to store the whitelist ignore patterns.
ConfigReadonlyWhitelistTrait::getWhitelistPatterns protected function Get whitelist patterns.
ConfigReadonlyWhitelistTrait::matchesWhitelistPattern protected function Check if the given name matches any whitelist pattern.
ConfigReadonlyWhitelistTrait::setModuleHandler protected function Set the module handler.
ReadOnlyFormSubscriber::$readOnlyFormIds protected property Form ids to mark as read only.
ReadOnlyFormSubscriber::getEditableConfigNames protected function Get the editable configuration names.
ReadOnlyFormSubscriber::getSubscribedEvents public static function Returns an array of event names this subscriber wants to listen to.
ReadOnlyFormSubscriber::onFormAlter public function
ReadOnlyFormSubscriber::__construct public function ReadOnlyFormSubscriber constructor.