You are here

class SocialGroupSelectorWidget in Open Social 10.0.x

Same name and namespace in other branches
  1. 8.9 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  2. 8 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  3. 8.2 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  4. 8.3 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  5. 8.4 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  6. 8.5 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  7. 8.6 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  8. 8.7 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  9. 8.8 modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  10. 10.3.x modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  11. 10.1.x modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget
  12. 10.2.x modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php \Drupal\social_group\Plugin\Field\FieldWidget\SocialGroupSelectorWidget

A widget to select a group when creating an entity in a group.

Plugin annotation


@FieldWidget(
  id = "social_group_selector_widget",
  label = @Translation("Social group select list"),
  field_types = {
    "entity_reference",
    "list_integer",
    "list_float",
    "list_string"
  },
  multiple_values = TRUE
)

Hierarchy

Expanded class hierarchy of SocialGroupSelectorWidget

File

modules/social_features/social_group/src/Plugin/Field/FieldWidget/SocialGroupSelectorWidget.php, line 39

Namespace

Drupal\social_group\Plugin\Field\FieldWidget
View source
class SocialGroupSelectorWidget extends OptionsSelectWidget implements ContainerFactoryPluginInterface {
  protected $configFactory;
  protected $moduleHander;
  protected $currentUser;
  protected $pluginManager;
  protected $entityTypeManager;
  protected $userManager;

  /**
   * Creates a SocialGroupSelectorWidget instance.
   *
   * {@inheritdoc}
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, ConfigFactoryInterface $configFactory, AccountProxyInterface $currentUser, ModuleHandler $moduleHandler, GroupContentEnablerManager $pluginManager, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
    $this->configFactory = $configFactory;
    $this->moduleHander = $moduleHandler;
    $this->currentUser = $currentUser;
    $this->pluginManager = $pluginManager;
    $this->entityTypeManager = $entity_type_manager;
    $this->userManager = $entity_type_manager
      ->getStorage('user');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['third_party_settings'], $container
      ->get('config.factory'), $container
      ->get('current_user'), $container
      ->get('module_handler'), $container
      ->get('plugin.manager.group_content_enabler'), $container
      ->get('entity_type.manager'));
  }

  /**
   * Returns the array of options for the widget.
   *
   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
   *   The entity for which to return options.
   *
   * @return array
   *   The array of options for the widget.
   */
  protected function getOptions(FieldableEntityInterface $entity) {

    // Must be a node.
    if ($entity
      ->getEntityTypeId() !== 'node') {

      // We only handle nodes. When using this widget on other content types,
      // we simply return the normal options.
      return parent::getOptions($entity);
    }

    // Get the bundle fron the node.
    $entity_type = $entity
      ->bundle();

    /** @var \Drupal\user\Entity\User $account */
    $account = $this->userManager
      ->load($this->currentUser
      ->id());

    // If the user can administer content and groups, we allow them to
    // override this. Otherwise we stick to the original owner.
    if (!$account
      ->hasPermission('administer nodes') && !$account
      ->hasPermission('manage all groups')) {
      $account = $entity
        ->getOwner();
    }

    // Limit the settable options for the current user account.
    $options = $this->fieldDefinition
      ->getFieldStorageDefinition()
      ->getOptionsProvider($this->column, $entity)
      ->getSettableOptions($account);

    // Check for each group type if the content type is installed.
    foreach ($options as $key => $optgroup) {

      // Groups are in the array below.
      if (is_array($optgroup)) {

        // Loop through the groups.
        foreach ($optgroup as $gid => $title) {

          // If the group exists.
          if ($group = Group::load($gid)) {

            // Load all installed plugins for this group type.
            $plugin_ids = $this->pluginManager
              ->getInstalledIds($group
              ->getGroupType());

            // If the bundle is not installed,
            // then unset the entire optiongroup (=group type).
            if (!in_array('group_node:' . $entity_type, $plugin_ids)) {
              unset($options[$key]);
            }
          }

          // We need to check only one of each group type,
          // so break out the second each.
          break;
        }
      }
    }

    // Remove groups the user does not have create access to.
    if (!$account
      ->hasPermission('manage all groups')) {
      $options = $this
        ->removeGroupsWithoutCreateAccess($options, $account, $entity);
    }

    // Add an empty option if the widget needs one.
    if ($empty_label = $this
      ->getEmptyLabel()) {
      $options = [
        '_none' => $empty_label,
      ] + $options;
    }
    $module_handler = $this->moduleHander;
    $context = [
      'fieldDefinition' => $this->fieldDefinition,
      'entity' => $entity,
    ];
    $module_handler
      ->alter('options_list', $options, $context);
    array_walk_recursive($options, [
      $this,
      'sanitizeLabel',
    ]);
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);
    $element['#suffix'] = '<div id="group-selection-result"></div>';
    $element['#ajax'] = [
      'callback' => __CLASS__ . '::validateGroupSelection',
      'effect' => 'fade',
      'event' => 'change',
    ];

    // Unfortunately validateGroupSelection is cast as a static function
    // So I have to add this setting to the form in order to use it later on.
    $default_visibility = $this->configFactory
      ->get('entity_access_by_field.settings')
      ->get('default_visibility');
    $form['default_visibility'] = [
      '#type' => 'value',
      '#value' => $default_visibility,
    ];
    $change_group_node = $this->configFactory
      ->get('social_group.settings')
      ->get('allow_group_selection_in_node');

    /** @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $form_state
      ->getFormObject()
      ->getEntity();

    // If it is a new node lets add the current group.
    if (!$entity
      ->id()) {
      $current_group = _social_group_get_current_group();
      if (!empty($current_group) && empty($element['#default_value'])) {
        $element['#default_value'] = [
          $current_group
            ->id(),
        ];
      }
    }
    else {
      if (!$change_group_node && !$this->currentUser
        ->hasPermission('manage all groups')) {
        $element['#disabled'] = TRUE;
        $element['#description'] = t('Moving content after creation function has been disabled. In order to move this content, please contact a site manager.');
      }
    }
    return $element;
  }

  /**
   * Validate the group selection and change the visibility settings.
   *
   * @param array $form
   *   Form to process.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Form state to process.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   Response changing values of the visibility field and set status message.
   */
  public static function validateGroupSelection(array $form, FormStateInterface $form_state) {
    $ajax_response = new AjaxResponse();
    $entity = $form_state
      ->getFormObject()
      ->getEntity();
    $selected_visibility = $form_state
      ->getValue('field_content_visibility');
    if (!empty($selected_visibility)) {
      $selected_visibility = $selected_visibility['0']['value'];
    }
    if ($selected_groups = $form_state
      ->getValue('groups')) {
      foreach ($selected_groups as $selected_group_key => $selected_group) {
        $gid = $selected_group['target_id'];
        $group = Group::load($gid);
        $group_type_id = $group
          ->getGroupType()
          ->id();
        $allowed_visibility_options = social_group_get_allowed_visibility_options_per_group_type($group_type_id, NULL, $entity, $group);

        // @todo Add support for multiple groups, for now just process 1 group.
        break;
      }
    }
    else {
      $default_visibility = $form_state
        ->getValue('default_visibility');
      $allowed_visibility_options = social_group_get_allowed_visibility_options_per_group_type(NULL, NULL, $entity);
      $ajax_response
        ->addCommand(new InvokeCommand('#edit-field-content-visibility-' . $default_visibility, 'prop', [
        'checked',
        'checked',
      ]));
    }
    foreach ($allowed_visibility_options as $visibility => $allowed) {
      $ajax_response
        ->addCommand(new InvokeCommand('#edit-field-content-visibility-' . $visibility, 'addClass', [
        'js--animate-enabled-form-control',
      ]));
      if ($allowed === TRUE) {
        $ajax_response
          ->addCommand(new InvokeCommand('#edit-field-content-visibility-' . $visibility, 'removeAttr', [
          'disabled',
        ]));
        if (empty($default_visibility) || $visibility === $default_visibility) {
          $ajax_response
            ->addCommand(new InvokeCommand('#edit-field-content-visibility-' . $visibility, 'prop', [
            'checked',
            'checked',
          ]));
        }
      }
      else {
        if ($selected_visibility && $selected_visibility === $visibility) {
          $ajax_response
            ->addCommand(new InvokeCommand('#edit-field-content-visibility-' . $visibility, 'removeAttr', [
            'checked',
          ]));
        }
        $ajax_response
          ->addCommand(new InvokeCommand('#edit-field-content-visibility-' . $visibility, 'prop', [
          'disabled',
          'disabled',
        ]));
      }
      $ajax_response
        ->addCommand(new InvokeCommand('#edit-field-content-visibility-' . $visibility, 'change'));
    }
    $text = t('Changing the group may have impact on the <strong>visibility settings</strong> and may cause <strong>author/co-authors</strong> to lose access.');
    \Drupal::messenger()
      ->addStatus($text);
    $ajax_response
      ->addCommand(new HtmlCommand('#group-selection-result', $text));
    return $ajax_response;
  }

  /**
   * Remove options from the list.
   *
   * @param array $options
   *   A list of options to check.
   * @param \Drupal\user\Entity\User $account
   *   The user to check for.
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to check for.
   *
   * @return array
   *   An list of options for the field containing groups with create access.
   */
  private function removeGroupsWithoutCreateAccess(array $options, User $account, EntityInterface $entity) {
    foreach ($options as $option_category_key => $groups_in_category) {
      if (is_array($groups_in_category)) {
        foreach ($groups_in_category as $gid => $group_title) {
          if (!$this
            ->checkGroupContentCreateAccess($gid, $account, $entity)) {
            unset($options[$option_category_key][$gid]);
          }
        }

        // Remove the entire category if there are no groups for this author.
        if (empty($options[$option_category_key])) {
          unset($options[$option_category_key]);
        }
      }
      else {
        if (!$this
          ->checkGroupContentCreateAccess($option_category_key, $account, $entity)) {
          unset($options[$option_category_key]);
        }
      }
    }
    return $options;
  }

  /**
   * Check if user may create content of bundle in group.
   *
   * @param int $gid
   *   Group id.
   * @param \Drupal\user\Entity\User $account
   *   The user to check for.
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The node bundle to check for.
   *
   * @return int
   *   Either TRUE or FALSE.
   */
  private function checkGroupContentCreateAccess($gid, User $account, EntityInterface $entity) {
    $group = Group::load($gid);
    if ($group
      ->hasPermission('create group_' . $entity
      ->getEntityTypeId() . ':' . $entity
      ->bundle() . ' entity', $account)) {
      if ($group
        ->getGroupType()
        ->id() === 'public_group') {
        $config = $this->configFactory
          ->get('entity_access_by_field.settings');
        if ($config
          ->get('disable_public_visibility') === 1 && !$account
          ->hasPermission('override disabled public visibility')) {
          return FALSE;
        }
      }
      return TRUE;
    }
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
OptionsSelectWidget::getEmptyLabel protected function Returns the empty option label to add to the list of options, if any. Overrides OptionsWidgetBase::getEmptyLabel
OptionsSelectWidget::sanitizeLabel protected function Sanitizes a string label to display as an option. Overrides OptionsWidgetBase::sanitizeLabel
OptionsSelectWidget::supportsGroups protected function Indicates whether the widgets support optgroups. Overrides OptionsWidgetBase::supportsGroups
OptionsWidgetBase::$column protected property Abstract over the actual field columns, to allow different field types to reuse those widgets.
OptionsWidgetBase::getSelectedOptions protected function Determines selected options from the incoming field values.
OptionsWidgetBase::validateElement public static function Form validation handler for widget elements. 1
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 2
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginSettingsBase::$defaultSettingsMerged protected property Whether default settings have been merged into the current $settings.
PluginSettingsBase::$thirdPartySettings protected property The plugin settings injected by third party modules.
PluginSettingsBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies 6
PluginSettingsBase::defaultSettings public static function Defines the default settings for this plugin. Overrides PluginSettingsInterface::defaultSettings 42
PluginSettingsBase::getSetting public function Returns the value of a setting, or its default value if absent. Overrides PluginSettingsInterface::getSetting
PluginSettingsBase::getSettings public function Returns the array of settings, including defaults for missing settings. Overrides PluginSettingsInterface::getSettings
PluginSettingsBase::getThirdPartyProviders public function Gets the list of third parties that store information. Overrides ThirdPartySettingsInterface::getThirdPartyProviders
PluginSettingsBase::getThirdPartySetting public function Gets the value of a third-party setting. Overrides ThirdPartySettingsInterface::getThirdPartySetting
PluginSettingsBase::getThirdPartySettings public function Gets all third-party settings of a given module. Overrides ThirdPartySettingsInterface::getThirdPartySettings
PluginSettingsBase::mergeDefaults protected function Merges default settings values into $settings.
PluginSettingsBase::onDependencyRemoval public function Informs the plugin that some configuration it depends on will be deleted. Overrides PluginSettingsInterface::onDependencyRemoval 3
PluginSettingsBase::setSetting public function Sets the value of a setting for the plugin. Overrides PluginSettingsInterface::setSetting
PluginSettingsBase::setSettings public function Sets the settings for the plugin. Overrides PluginSettingsInterface::setSettings
PluginSettingsBase::setThirdPartySetting public function Sets the value of a third-party setting. Overrides ThirdPartySettingsInterface::setThirdPartySetting
PluginSettingsBase::unsetThirdPartySetting public function Unsets a third-party setting. Overrides ThirdPartySettingsInterface::unsetThirdPartySetting
SocialGroupSelectorWidget::$configFactory protected property
SocialGroupSelectorWidget::$currentUser protected property
SocialGroupSelectorWidget::$entityTypeManager protected property
SocialGroupSelectorWidget::$moduleHander protected property
SocialGroupSelectorWidget::$pluginManager protected property
SocialGroupSelectorWidget::$userManager protected property
SocialGroupSelectorWidget::checkGroupContentCreateAccess private function Check if user may create content of bundle in group.
SocialGroupSelectorWidget::create public static function Creates an instance of the plugin. Overrides WidgetBase::create
SocialGroupSelectorWidget::formElement public function Returns the form for a single field widget. Overrides OptionsSelectWidget::formElement
SocialGroupSelectorWidget::getOptions protected function Returns the array of options for the widget. Overrides OptionsWidgetBase::getOptions
SocialGroupSelectorWidget::removeGroupsWithoutCreateAccess private function Remove options from the list.
SocialGroupSelectorWidget::validateGroupSelection public static function Validate the group selection and change the visibility settings.
SocialGroupSelectorWidget::__construct public function Creates a SocialGroupSelectorWidget instance. Overrides OptionsWidgetBase::__construct
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
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.
WidgetBase::$fieldDefinition protected property The field definition.
WidgetBase::$settings protected property The widget settings. Overrides PluginSettingsBase::$settings
WidgetBase::addMoreAjax public static function Ajax callback for the "Add another item" button.
WidgetBase::addMoreSubmit public static function Submission handler for the "Add another item" button.
WidgetBase::afterBuild public static function After-build handler for field elements in a form.
WidgetBase::errorElement public function Assigns a field-level validation error to the right widget sub-element. Overrides WidgetInterface::errorElement 8
WidgetBase::extractFormValues public function Extracts field values from submitted form values. Overrides WidgetBaseInterface::extractFormValues 2
WidgetBase::flagErrors public function Reports field-level validation errors against actual form elements. Overrides WidgetBaseInterface::flagErrors 2
WidgetBase::form public function Creates a form element for a field. Overrides WidgetBaseInterface::form 3
WidgetBase::formMultipleElements protected function Special handling to create form elements for multiple values. 1
WidgetBase::formSingleElement protected function Generates the form element for a single copy of the widget.
WidgetBase::getFieldSetting protected function Returns the value of a field setting.
WidgetBase::getFieldSettings protected function Returns the array of field settings.
WidgetBase::getFilteredDescription protected function Returns the filtered field description.
WidgetBase::getWidgetState public static function Retrieves processing information about the widget from $form_state. Overrides WidgetBaseInterface::getWidgetState
WidgetBase::getWidgetStateParents protected static function Returns the location of processing information within $form_state.
WidgetBase::handlesMultipleValues protected function Returns whether the widget handles multiple values.
WidgetBase::isApplicable public static function Returns if the widget can be used for the provided field. Overrides WidgetInterface::isApplicable 4
WidgetBase::isDefaultValueWidget protected function Returns whether the widget used for default value form.
WidgetBase::massageFormValues public function Massages the form values into the format expected for field values. Overrides WidgetInterface::massageFormValues 7
WidgetBase::settingsForm public function Returns a form to configure settings for the widget. Overrides WidgetInterface::settingsForm 16
WidgetBase::settingsSummary public function Returns a short summary for the current widget settings. Overrides WidgetInterface::settingsSummary 15
WidgetBase::setWidgetState public static function Stores processing information about the widget in $form_state. Overrides WidgetBaseInterface::setWidgetState