access_policy-1.0.x-dev/src/Plugin/access_policy/AccessRuleWidget/EntityField.php
src/Plugin/access_policy/AccessRuleWidget/EntityField.php
<?php namespace Drupal\access_policy\Plugin\access_policy\AccessRuleWidget; use Drupal\access_policy\AccessPolicySelectionInterface; use Drupal\Core\Entity\Entity\EntityFormDisplay; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\WidgetPluginManager; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Embedded entity field access rule widget. * * Renders the entity field on the access tab. * * @AccessRuleWidget( * id = "entity_field", * label = @Translation("Entity field"), * description = @Translation("Shows the field on the access tab.") * ) */ class EntityField extends AccessRuleWidgetBase implements ContainerFactoryPluginInterface { /** * The field widget plugin manager. * * @var \Drupal\Core\Field\WidgetPluginManager */ protected $widgetPluginManager; /** * The access policy selection service. * * @var \Drupal\access_policy\AccessPolicySelectionInterface */ protected $accessPolicySelection; /** * {@inheritdoc} */ public static function defaultWidgetSettings() { return [ 'hide_original_field' => TRUE, 'field_widget' => NULL, ]; } /** * Constructs a new EntityField access rule widget. * * @param array $configuration * A configuration array containing information about the plugin instance. * @param string $plugin_id * The plugin_id for the plugin instance. * @param mixed $plugin_definition * The plugin implementation definition. * @param \Drupal\Core\Field\WidgetPluginManager $widget_plugin_manager * The field widget plugin manager. * @param \Drupal\access_policy\AccessPolicySelectionInterface $policy_selection * The policy selection service. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, WidgetPluginManager $widget_plugin_manager, AccessPolicySelectionInterface $policy_selection) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->widgetPluginManager = $widget_plugin_manager; $this->accessPolicySelection = $policy_selection; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('plugin.manager.field.widget'), $container->get('access_policy.selection') ); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { // Get the widget options based on field type. $field_type = $this->definition->getFieldType(); $options = $this->widgetPluginManager->getOptions($field_type); $form['field_widget'] = [ '#title' => $this->t('Field widget display'), '#type' => 'select', '#default_value' => $this->getWidgetSetting('field_widget'), '#options' => $options, ]; $form['hide_original_field'] = [ '#type' => 'checkbox', '#title' => $this->t('Hide original field widget'), '#default_value' => $this->getWidgetSetting('hide_original_field'), '#description' => $this->t('Hide the field widget on the edit form. Warning: This is a global setting. All instances of this field will be affected regardless of policy assigned.'), ]; return $form; } /** * {@inheritdoc} */ public function buildForm($form, $form_state) { $field_name = $this->definition->getFieldName(); $entity = $this->getEntity(); $is_default_translation = $entity->isDefaultTranslation(); if (!$is_default_translation) { $entity = $entity->getUntranslated(); } $items = $entity->get($field_name); $items->filterEmptyItems(); $widget = $this->getFieldWidget($field_name, $form, $form_state); $widget_form = $widget->form($items, $form, $form_state); $is_disabled = FALSE; if (!$is_default_translation) { $is_disabled = TRUE; } // Disable the widget if the access policy selection field is also disabled. if (!$this->accessPolicySelection->isPolicyFieldEnabled($entity->getEntityTypeId())) { $is_disabled = TRUE; } if ($is_disabled) { $widget_form['widget']['#disabled'] = TRUE; } return $widget_form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $field_name = $this->definition->getFieldName(); $value = $form_state->getValue($field_name); // Normally this is handled by WidgetBase however it also makes a lot of // other assumptions about the form which are not true in this case. if (isset($value['add_more'])) { unset($value['add_more']); } $widget = $this->getFieldWidget($field_name, $form, $form_state); $value = $widget->massageFormValues($value, $form, $form_state); $entity = $this->getEntity(); $entity->set($field_name, $value); $entity->save(); } /** * Get the field widget for the field. * * @param string $field_name * The field name. * @param array $form * The current form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. * * @return \Drupal\Core\Field\PluginSettingsInterface|null * A widget or formatter plugin. */ protected function getFieldWidget($field_name, array &$form, FormStateInterface $form_state) { $entity = $this->getEntity(); $new_form_display = EntityFormDisplay::create([ 'targetEntityType' => $entity->getEntityTypeId(), 'bundle' => $entity->bundle(), 'mode' => 'default', ]); $options = []; if (!empty($this->getWidgetSetting('field_widget'))) { $options['type'] = $this->getWidgetSetting('field_widget'); } $new_form_display->setComponent($field_name, $options); $widget = $new_form_display->getRenderer($field_name); $new_form_display->buildForm($entity, $form, $form_state); return $widget; } /** * {@inheritdoc} */ public function buildEntity(EntityInterface $entity, $form, FormStateInterface $form_state) { // If the current access policy is not the same as this one then remove // any associated field data. $field_name = $this->definition->getFieldName(); if ($this->getWidgetSetting('hide_original_field') && $entity->hasField($field_name)) { $access_policies = $entity->get('access_policy')->referencedEntities(); $is_selected = FALSE; foreach ($access_policies as $policy) { if ($policy->id() == $this->definition->getAccessPolicy()) { $is_selected = TRUE; } } if (!$is_selected) { $entity->set($field_name, NULL); } } } }