Skip to content

Commit

Permalink
Issue #2512708 by slashrsm: Remove event subscribtions from entity br…
Browse files Browse the repository at this point in the history
…owser class and move handling to form state.
  • Loading branch information
slashrsm committed Oct 20, 2015
1 parent 91c86a3 commit a8e6602
Show file tree
Hide file tree
Showing 16 changed files with 93 additions and 214 deletions.
2 changes: 1 addition & 1 deletion src/Controllers/StandalonePage.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

/**
Expand Down
132 changes: 1 addition & 131 deletions src/Entity/EntityBrowser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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}
*/
Expand Down Expand Up @@ -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)),
[
Expand All @@ -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);
}

}
32 changes: 0 additions & 32 deletions src/EntityBrowserInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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();

}
8 changes: 6 additions & 2 deletions src/Events/EntitySelectionEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
22 changes: 21 additions & 1 deletion src/Events/EventBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand All @@ -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;
}

}
46 changes: 35 additions & 11 deletions src/Form/EntityBrowserForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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']);
}

}
6 changes: 3 additions & 3 deletions src/Kernel/Extension/EntityBrowserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand All @@ -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.');
}

Expand Down
2 changes: 1 addition & 1 deletion src/Plugin/EntityBrowser/Display/Modal.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

}
2 changes: 1 addition & 1 deletion src/Plugin/EntityBrowser/SelectionDisplay/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
Loading

0 comments on commit a8e6602

Please sign in to comment.