From a8e6602c575ff9081b0fb38bb45dbd011d60f9e8 Mon Sep 17 00:00:00 2001 From: Janez Urevc Date: Sat, 17 Oct 2015 01:54:39 +0200 Subject: [PATCH] Issue #2512708 by slashrsm: Remove event subscribtions from entity browser class and move handling to form state. --- src/Controllers/StandalonePage.php | 2 +- src/Entity/EntityBrowser.php | 132 +----------------- src/EntityBrowserInterface.php | 32 ----- src/Events/EntitySelectionEvent.php | 8 +- src/Events/EventBase.php | 22 ++- src/Form/EntityBrowserForm.php | 46 ++++-- src/Kernel/Extension/EntityBrowserTest.php | 6 +- src/Plugin/EntityBrowser/Display/Modal.php | 2 +- .../SelectionDisplay/NoDisplay.php | 2 +- .../EntityBrowser/SelectionDisplay/View.php | 2 +- src/Plugin/EntityBrowser/Widget/Upload.php | 2 +- src/Plugin/EntityBrowser/Widget/View.php | 2 +- src/SelectionDisplayBase.php | 26 ++-- src/SelectionDisplayInterface.php | 8 -- src/WidgetBase.php | 13 +- .../EntityBrowser/Widget/DummyWidget.php | 2 +- 16 files changed, 93 insertions(+), 214 deletions(-) diff --git a/src/Controllers/StandalonePage.php b/src/Controllers/StandalonePage.php index 3ebfc9a..f3f8a7e 100644 --- a/src/Controllers/StandalonePage.php +++ b/src/Controllers/StandalonePage.php @@ -78,7 +78,7 @@ public function page() { $browser->addAdditionalWidgetParameters(['path_parts' => explode('/', $original_path)]); } - return $this->entityFormBuilder()->getForm($browser, 'default'); + return $this->entityFormBuilder()->getForm($browser, 'entity_browser'); } /** diff --git a/src/Entity/EntityBrowser.php b/src/Entity/EntityBrowser.php index cba19e7..88bda9e 100644 --- a/src/Entity/EntityBrowser.php +++ b/src/Entity/EntityBrowser.php @@ -29,7 +29,7 @@ * label = @Translation("Entity browser"), * handlers = { * "form" = { - * "default" = "Drupal\entity_browser\Form\EntityBrowserForm" + * "entity_browser" = "Drupal\entity_browser\Form\EntityBrowserForm" * } * }, * admin_permission = "administer entity browsers", @@ -144,20 +144,6 @@ class EntityBrowser extends ConfigEntityBase implements EntityBrowserInterface, */ protected $widgetSelectorCollection; - /** - * Currently selected entities. - * - * @var \Drupal\Core\Entity\EntityInterface[] - */ - protected $selectedEntities = []; - - /** - * Indicates selection is done. - * - * @var bool - */ - protected $selectionCompleted = FALSE; - /** * Additional widget parameters. * @@ -334,99 +320,6 @@ public function getWidgetSelector() { return $this->widgetSelectorPluginCollection()->get($this->widget_selector); } - /** - * {@inheritdoc} - */ - public function getSelectedEntities() { - return $this->selectedEntities; - } - - /** - * {@inheritdoc} - */ - public function setSelectedEntities(array $entities) { - $this->selectedEntities = $entities; - $this->getSelectionDisplay()->setSelectedEntities($this->selectedEntities); - } - - /** - * {@inheritdoc} - */ - public function addSelectedEntities(array $entities) { - $this->selectedEntities = array_merge($this->selectedEntities, $entities); - $this->getSelectionDisplay()->setSelectedEntities($this->selectedEntities); - } - - /** - * {@inheritdoc} - */ - public function postCreate(EntityStorageInterface $storage) { - parent::postCreate($storage); - $this->subscribeEvents(\Drupal::service('event_dispatcher')); - } - - /** - * {@inheritdoc} - */ - public static function postLoad(EntityStorageInterface $storage, array &$entities) { - parent::postLoad($storage, $entities); - $event_dispatcher = \Drupal::service('event_dispatcher'); - /** @var \Drupal\entity_browser\Entity\EntityBrowser $browser */ - foreach ($entities as $browser) { - $browser->subscribeEvents($event_dispatcher); - } - } - - /** - * Subscribes entity browser to events if needed. - * - * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher - */ - public function subscribeEvents(EventDispatcherInterface $event_dispatcher) { - // When entity browser gets unserialized we end up with two instances of the - // class and we must be sure only unserialized one is subscribed to events. - foreach ([Events::SELECTED, Events::DONE] as $event) { - $existing = $event_dispatcher->getListeners($event); - foreach ($existing as $listener) { - if (count($listener) == 2 && $listener[0] instanceof EntityBrowserInterface && $listener[0]->id() == $this->id()) { - $event_dispatcher->removeListener($event, $listener); - } - } - } - - $event_dispatcher->addListener(Events::SELECTED, [$this, 'onSelected']); - $event_dispatcher->addListener(Events::DONE, [$this, 'selectionCompleted']); - } - - /** - * Responds to SELECTED event. - * - * @param \Drupal\entity_browser\Events\EntitySelectionEvent $event - */ - public function onSelected(EntitySelectionEvent $event) { - if ($event->getBrowserID() == $this->id()) { - $this->addSelectedEntities($event->getEntities()); - } - } - - /** - * Responds to DONE event. - * - * @param \Drupal\entity_browser\Events\SelectionDoneEvent $event - */ - public function selectionCompleted(SelectionDoneEvent $event) { - if ($event->getBrowserID() == $this->id()) { - $this->selectionCompleted = TRUE; - } - } - - /** - * {@inheritdoc} - */ - public function isSelectionCompleted() { - return $this->selectionCompleted; - } - /** * {@inheritdoc} */ @@ -478,15 +371,6 @@ public function __sleep() { $this->display_configuration = $this->widgetSelectorPluginCollection()->getConfiguration(); $this->selection_display_configuration = $this->selectionDisplayPluginCollection()->getConfiguration(); - // For selected entites only store entity type and id. - $this->_selected_entities = []; - foreach ($this->selectedEntities as $entity) { - $this->_selected_entities[] = [ - 'type' => $entity->getEntityTypeId(), - 'id' => $entity->id(), - ]; - } - return array_diff( array_keys(get_object_vars($this)), [ @@ -498,18 +382,4 @@ public function __sleep() { ] ); } - - /** - * Re-register event listeners and load selected entities. - */ - public function __wakeup() { - $this->subscribeEvents(\Drupal::service('event_dispatcher')); - - $this->selectedEntities = []; - foreach ($this->_selected_entities as $entity) { - $this->selectedEntities[] = \Drupal::entityManager()->getStorage($entity['type'])->load($entity['id']); - } - $this->getSelectionDisplay()->setSelectedEntities($this->selectedEntities); - } - } diff --git a/src/EntityBrowserInterface.php b/src/EntityBrowserInterface.php index 432e845..37a9c8d 100644 --- a/src/EntityBrowserInterface.php +++ b/src/EntityBrowserInterface.php @@ -124,30 +124,6 @@ public function getSelectionDisplay(); */ public function getWidgetSelector(); - /** - * Returns currently selected entities. - * - * @return array - * Array of currently selected entities. - */ - public function getSelectedEntities(); - - /** - * Sets currently selected entities. - * - * @param array $entities - * Entities that are currently selected. - */ - public function setSelectedEntities(array $entities); - - /** - * Adds entities to currently selected entities. - * - * @param array $entities - * Entities to be added to the list of currently selected entities. - */ - public function addSelectedEntities(array $entities); - /** * Gets route that matches this display. * @@ -156,12 +132,4 @@ public function addSelectedEntities(array $entities); */ public function route(); - /** - * Indicates selection is done. - * - * @return bool - * Indicates selection is done. - */ - public function isSelectionCompleted(); - } diff --git a/src/Events/EntitySelectionEvent.php b/src/Events/EntitySelectionEvent.php index 420271c..0a6ea23 100644 --- a/src/Events/EntitySelectionEvent.php +++ b/src/Events/EntitySelectionEvent.php @@ -24,9 +24,13 @@ class EntitySelectionEvent extends EventBase { * * @param string $entity_browser_id * Entity browser ID. + * @param string $instance_uuid + * Entity browser instance UUID. + * @param \Drupal\Core\Entity\EntityInterface[] $entites + * Array of selected entities. */ - public function __construct($entity_browser_id, array $entities) { - parent::__construct($entity_browser_id); + public function __construct($entity_browser_id, $instance_uuid, array $entities) { + parent::__construct($entity_browser_id, $instance_uuid); $this->entities = $entities; } diff --git a/src/Events/EventBase.php b/src/Events/EventBase.php index d1fc72f..65de4c9 100644 --- a/src/Events/EventBase.php +++ b/src/Events/EventBase.php @@ -21,14 +21,24 @@ class EventBase extends Event { */ protected $entityBrowserID; + /** + * Entity browser instance UUID. + * + * @var string + */ + protected $instanceUUID; + /** * Constructs a EntitySelectionEvent object. * * @param string $entity_browser_id * Entity browser ID. + * @param string $instance_uuid + * Entity browser instance UUID. */ - public function __construct($entity_browser_id) { + public function __construct($entity_browser_id, $instance_uuid) { $this->entityBrowserID = $entity_browser_id; + $this->instanceUUID = $instance_uuid; } /** @@ -41,4 +51,14 @@ public function getBrowserID() { return $this->entityBrowserID; } + /** + * Gets the entity browser instance UUID: + * + * @return string + * Entity browser instance UUID. + */ + public function getBrowserInstanceUUID() { + return $this->instanceUUID; + } + } diff --git a/src/Form/EntityBrowserForm.php b/src/Form/EntityBrowserForm.php index dc1f2b8..708deb0 100644 --- a/src/Form/EntityBrowserForm.php +++ b/src/Form/EntityBrowserForm.php @@ -34,15 +34,22 @@ public function getFormId() { /** * {@inheritdoc} */ - public function buildForm(array $form, FormStateInterface $form_state) { + protected function init(FormStateInterface $form_state) { + parent::init($form_state); + $form_state->set(['entity_browser', 'instance_uuid'], \Drupal::service('uuid')->generate()); + $form_state->set(['entity_browser', 'selected_entities'], []); + $form_state->set(['entity_browser', 'selection_completed'], FALSE); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + parent::form($form, $form_state); + /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */ $entity_browser = $this->entity; - $form['selected_entities'] = [ - '#type' => 'value', - '#value' => array_map(function(EntityInterface $item) {return $item->id();}, $entity_browser->getSelectedEntities()), - ]; - $form['#browser_parts'] = [ 'widget_selector' => 'widget_selector', 'widget' => 'widget', @@ -99,14 +106,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $entity_browser->getSelectionDisplay()->submit($form, $form_state); } - // Save the selected entities to the form state. - $form_state->set('selected_entities', $entity_browser->getSelectedEntities()); - - if (!$entity_browser->isSelectionCompleted()) { + if (!$this->isSelectionCompleted($form_state)) { $form_state->setRebuild(); } else { - $entity_browser->getDisplay()->selectionCompleted($entity_browser->getSelectedEntities()); + $entity_browser->getDisplay()->selectionCompleted($this->getSelectedEntities($form_state)); } } @@ -140,4 +144,24 @@ protected function setCurrentWidget($widget, FormStateInterface $form_state) { $form_state->set('entity_browser_current_widget', $widget); } + /** + * Indicates selection is done. + * + * @return bool + * Indicates selection is done. + */ + protected function isSelectionCompleted(FormStateInterface $form_state) { + return (bool) $form_state->get(['entity_browser', 'selection_completed']); + } + + /** + * Returns currently selected entities. + * + * @return \Drupal\Core\Entity\EntityInterface + * Array of currently selected entities. + */ + protected function getSelectedEntities(FormStateInterface $form_state) { + return $form_state->get(['entity_browser', 'selected_entities']); + } + } diff --git a/src/Kernel/Extension/EntityBrowserTest.php b/src/Kernel/Extension/EntityBrowserTest.php index 6fe5ef2..4440464 100644 --- a/src/Kernel/Extension/EntityBrowserTest.php +++ b/src/Kernel/Extension/EntityBrowserTest.php @@ -284,7 +284,7 @@ public function testDefaultWidget() { $entity = $this->controller->load('test'); /** @var \Drupal\entity_browser\Form\EntityBrowserFormInterface $form_object */ - $form_object = $this->container->get('entity.manager')->getFormObject($entity->getEntityTypeId(), 'default'); + $form_object = $this->container->get('entity.manager')->getFormObject($entity->getEntityTypeId(), 'entity_browser'); $form_object->setEntity($entity); $form_state = new FormState(); @@ -312,7 +312,7 @@ public function testSelectedEvent() { $entity = $this->controller->load('dummy_widget'); /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */ - $form_object = $this->container->get('entity.manager')->getFormObject($entity->getEntityTypeId(), 'default'); + $form_object = $this->container->get('entity.manager')->getFormObject($entity->getEntityTypeId(), 'entity_browser'); $form_object->setEntity($entity); $form_state = new FormState(); @@ -322,7 +322,7 @@ public function testSelectedEvent() { $this->container->get('form_builder')->submitForm($form_object, $form_state); // Event should be dispatched from widget and added to list of selected entities. - $selected_entities = $entity->getSelectedEntities(); + $selected_entities = $form_state->get(['entity_browser', 'selected_entities']); $this->assertEquals($selected_entities, [$entity], 'Expected selected entities detected.'); } diff --git a/src/Plugin/EntityBrowser/Display/Modal.php b/src/Plugin/EntityBrowser/Display/Modal.php index b551b1a..b18f29e 100644 --- a/src/Plugin/EntityBrowser/Display/Modal.php +++ b/src/Plugin/EntityBrowser/Display/Modal.php @@ -220,7 +220,7 @@ public function widgetAjaxCallback(array &$form, FormStateInterface $form_state) * @return array */ public function getAjaxCommands(FormStateInterface $form_state) { - $entities = array_map(function (EntityInterface $item) {return [$item->id(), $item->uuid(), $item->getEntityTypeId()];}, $form_state->get('selected_entities')); + $entities = array_map(function (EntityInterface $item) {return [$item->id(), $item->uuid(), $item->getEntityTypeId()];}, $form_state->get(['entity_browser', 'selected_entities'])); $commands = array(); $commands[] = new SelectEntitiesCommand($this->uuid, $entities); $commands[] = new CloseDialogCommand(); diff --git a/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php b/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php index d02712a..07c3930 100644 --- a/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php +++ b/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php @@ -31,7 +31,7 @@ public function getForm(array &$original_form, FormStateInterface $form_state) { * {@inheritdoc} */ public function submit(array &$form, FormStateInterface $form_state) { - $this->selectionDone(); + $this->selectionDone($form_state); } } diff --git a/src/Plugin/EntityBrowser/SelectionDisplay/View.php b/src/Plugin/EntityBrowser/SelectionDisplay/View.php index 24430d6..74e91f9 100644 --- a/src/Plugin/EntityBrowser/SelectionDisplay/View.php +++ b/src/Plugin/EntityBrowser/SelectionDisplay/View.php @@ -69,7 +69,7 @@ public function getForm(array &$original_form, FormStateInterface $form_state) { */ public function submit(array &$form, FormStateInterface $form_state) { if ($form_state->getTriggeringElement()['#name'] == 'use_selected') { - $this->selectionDone(); + $this->selectionDone($form_state); } } diff --git a/src/Plugin/EntityBrowser/Widget/Upload.php b/src/Plugin/EntityBrowser/Widget/Upload.php index ef74704..e1cf999 100644 --- a/src/Plugin/EntityBrowser/Widget/Upload.php +++ b/src/Plugin/EntityBrowser/Widget/Upload.php @@ -62,7 +62,7 @@ public function validate(array &$form, FormStateInterface $form_state) { */ public function submit(array &$element, array &$form, FormStateInterface $form_state) { $files = $this->extractFiles($form_state); - $this->selectEntities($files); + $this->selectEntities($files, $form_state); $this->clearFormValues($element, $form_state); } diff --git a/src/Plugin/EntityBrowser/Widget/View.php b/src/Plugin/EntityBrowser/Widget/View.php index c9d785b..4e9b185 100644 --- a/src/Plugin/EntityBrowser/Widget/View.php +++ b/src/Plugin/EntityBrowser/Widget/View.php @@ -154,7 +154,7 @@ public function submit(array &$element, array &$form, FormStateInterface $form_s $entities[] = $this->entityManager->getStorage($ids[$row]['type'])->load($ids[$row]['id']); } - $this->selectEntities($entities); + $this->selectEntities($entities, $form_state); } } diff --git a/src/SelectionDisplayBase.php b/src/SelectionDisplayBase.php index 1a908e8..4879a98 100644 --- a/src/SelectionDisplayBase.php +++ b/src/SelectionDisplayBase.php @@ -41,13 +41,6 @@ abstract class SelectionDisplayBase extends PluginBase implements SelectionDispl */ protected $entityManager; - /** - * Currently selected entities. - * - * @var \Drupal\Core\Entity\EntityInterface[] - */ - protected $selectedEntities = []; - /** * Constructs widget plugin. * @@ -127,17 +120,16 @@ public function validate(array &$form, FormStateInterface $form_state) {} public function submit(array &$form, FormStateInterface $form_state) {} /** - * Marks selection as done (dispatches event). - */ - protected function selectionDone() { - $this->eventDispatcher->dispatch(Events::DONE, new SelectionDoneEvent($this->configuration['entity_browser_id'])); - } - - /** - * {@inheritdoc} + * Marks selection as done - sets value in form state and dispatches event. */ - public function setSelectedEntities(array $entities) { - $this->selectedEntities = $entities; + protected function selectionDone(FormStateInterface $form_state) { + $form_state->set(['entity_browser', 'selection_completed'], TRUE); + $this->eventDispatcher->dispatch( + Events::DONE, + new SelectionDoneEvent( + $this->configuration['entity_browser_id'], + $form_state->get(['entity_browser', 'instance_uuid']) + )); } } diff --git a/src/SelectionDisplayInterface.php b/src/SelectionDisplayInterface.php index e7c436d..b34ba96 100644 --- a/src/SelectionDisplayInterface.php +++ b/src/SelectionDisplayInterface.php @@ -59,12 +59,4 @@ public function validate(array &$form, FormStateInterface $form_state); */ public function submit(array &$form, FormStateInterface $form_state); - /** - * Sets currently selected entities. - * - * @param array $entities - * Entities that are currently selected. - */ - public function setSelectedEntities(array $entities); - } diff --git a/src/WidgetBase.php b/src/WidgetBase.php index b380c39..1fab349 100644 --- a/src/WidgetBase.php +++ b/src/WidgetBase.php @@ -191,7 +191,16 @@ public function submit(array &$element, array &$form, FormStateInterface $form_s * @param array $entities * Array of entities. */ - protected function selectEntities(array $entities) { - $this->eventDispatcher->dispatch(Events::SELECTED, new EntitySelectionEvent($this->configuration['entity_browser_id'], $entities)); + protected function selectEntities(array $entities, FormStateInterface $form_state) { + $selected_entities = &$form_state->get(['entity_browser', 'selected_entities']); + $selected_entities = array_merge($selected_entities, $entities); + + $this->eventDispatcher->dispatch( + Events::SELECTED, + new EntitySelectionEvent( + $this->configuration['entity_browser_id'], + $form_state->get(['entity_browser', 'instance_uuid']), + $entities + )); } } diff --git a/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php b/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php index 879d483..42a8fa1 100644 --- a/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php +++ b/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php @@ -45,7 +45,7 @@ public function getForm(array &$original_form, FormStateInterface $form_state, a * {@inheritdoc} */ public function submit(array &$element, array &$form, FormStateInterface $form_state) { - $this->selectEntities([$this->entity]); + $this->selectEntities([$this->entity], $form_state); } }