diff --git a/core/modules/views/lib/Drupal/views/DisplayArray.php b/core/modules/views/lib/Drupal/views/DisplayArray.php new file mode 100644 index 0000000..146942e --- /dev/null +++ b/core/modules/views/lib/Drupal/views/DisplayArray.php @@ -0,0 +1,159 @@ +view->storage->display. + * + * @var array + */ + protected $displayIDs; + + /** + * Constructs a DisplayArray object. + * + * @param \Drupal\views\ViewExecutable + * The view which has this displays attached. + */ + public function __construct(ViewExecutable $view) { + $this->view = $view; + + $this->initializeDisplay('default'); + + $this->displayIDs = array_keys($this->view->storage->display); + } + + /** + * Destructs a DisplayArray object. + */ + public function __destruct() { + foreach ($this->displayHandlers as $display_id => $display) { + $display->destroy(); + unset($this->displayHandlers[$display_id]); + } + } + + /** + * Initializes a single display and stores the result in $this->displayHandlers. + * + * @param string $display_id + * The name of the display to initialize. + */ + protected function initializeDisplay($display_id) { + // If the display was initialize before just return. + if (isset($this->displayHandlers[$display_id])) { + return; + } + + // Retrieve and initialize the new display handler with data. + $this->displayHandlers[$display_id] = views_get_plugin('display', $this->view->storage->display[$display_id]['display_plugin']); + $this->displayHandlers[$display_id]->init($this->view, $this->view->storage->display[$display_id]); + // If this is not the default display handler, let it know which is since + // it may well utilize some data from the default. + if ($display_id != 'default') { + $this->displayHandlers[$display_id]->default_display = $this->displayHandlers['default']; + } + } + + /** + * Implements \ArrayAccess::offsetExists(). + */ + public function offsetExists($offset) { + return isset($this->displayHandlers[$offset]) || isset($this->view->storage->display[$offset]); + } + + /** + * Implements \ArrayAccess::offsetGet(). + */ + public function offsetGet($offset) { + if (!isset($this->displayHandlers[$offset])) { + $this->initializeDisplay($offset); + } + return $this->displayHandlers[$offset]; + } + + /** + * Implements \ArrayAccess::offsetSet(). + */ + public function offsetSet($offset, $value) { + $this->displayHandlers[$offset] = $value; + } + + /** + * Implements \ArrayAccess::offsetUnset(). + */ + public function offsetUnset($offset) { + unset($this->displayHandlers[$offset]); + } + + /** + * Implements \Iterator::current(). + */ + public function current() { + return current($this->displayIDs); + } + + /** + * Implements \Iterator::next(). + */ + public function next() { + // If we do an actual iteration over the elements, let's initialize all + // displays. + $display_id = next($this->displayIDs); + return $this->offsetGet($display_id); + } + + /** + * Implements \Iterator::key(). + */ + public function key() { + return key($this->displayIDs); + } + + /** + * Implements \Iterator::valid(). + */ + public function valid() { + $display_id = key($this->displayIDs); + return $display_id !== NULL && $display_id !== FALSE; + } + + /** + * Implements \Iterator::rewind(). + */ + public function rewind() { + reset($this->displayHandlers); + } + + /** + * Implements \Countable::count(). + */ + public function count() { + return count($this->view->storage->display); + } + +} diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php index 9fb3fbc..a2d7f8a 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php @@ -8,6 +8,7 @@ namespace Drupal\views\Tests; use Drupal\views\ViewExecutable; +use Drupal\views\DisplayArray; use Drupal\views\Plugin\views\display\DefaultDisplay; use Drupal\views\Plugin\views\display\Page; @@ -120,8 +121,7 @@ public function testDisplays() { // Tests Drupal\views\ViewExecutable::initDisplay(). $view->initDisplay(); - $count = count($view->displayHandlers); - $this->assertEqual($count, 3, format_string('Make sure all display handlers got instantiated (@count of @count_expected)', array('@count' => $count, '@count_expected' => 3))); + $this->assertTrue($view->displayHandlers instanceof DisplayArray, 'The displayHandlers property has the right class.'); // Tests the classes of the instances. $this->assertTrue($view->displayHandlers['default'] instanceof DefaultDisplay); $this->assertTrue($view->displayHandlers['page'] instanceof Page); diff --git a/core/modules/views/lib/Drupal/views/ViewExecutable.php b/core/modules/views/lib/Drupal/views/ViewExecutable.php index 36aaee8..725519d 100644 --- a/core/modules/views/lib/Drupal/views/ViewExecutable.php +++ b/core/modules/views/lib/Drupal/views/ViewExecutable.php @@ -574,21 +574,8 @@ public function initDisplay() { return TRUE; } - // Instantiate all displays - foreach (array_keys($this->storage->display) as $id) { - $this->displayHandlers[$id] = views_get_plugin('display', $this->storage->display[$id]['display_plugin']); - if (!empty($this->displayHandlers[$id])) { - // Initialize the new display handler with data. - $this->displayHandlers[$id]->init($this, $this->storage->display[$id]); - // If this is NOT the default display handler, let it know which is - // since it may well utilize some data from the default. - // This assumes that the 'default' handler is always first. It always - // is. Make sure of it. - if ($id != 'default') { - $this->displayHandlers[$id]->default_display =& $this->displayHandlers['default']; - } - } - } + // Initialize the display cache array. + $this->displayHandlers = new DisplayArray($this); $this->current_display = 'default'; $this->display_handler = $this->displayHandlers['default']; @@ -1827,12 +1814,7 @@ public function cloneView() { * collected. */ public function destroy() { - foreach (array_keys($this->displayHandlers) as $display_id) { - if (isset($this->displayHandlers[$display_id])) { - $this->displayHandlers[$display_id]->destroy(); - unset($this->displayHandlers[$display_id]); - } - } + unset($this->displayHandlers); foreach ($this::viewsHandlerTypes() as $type => $info) { if (isset($this->$type)) { @@ -2208,7 +2190,7 @@ public function setItemOption($display_id, $type, $id, $option, $value) { * @return Drupal\views\Plugin\views\display\DisplayPluginBase * A reference to the new handler object. */ - public function &newDisplay($id) { + public function newDisplay($id) { // Create a handler. $this->displayHandlers[$id] = views_get_plugin('display', $this->storage->display[$id]['display_plugin']); if (empty($this->displayHandlers[$id])) { diff --git a/core/modules/views/lib/Drupal/views/ViewStorage.php b/core/modules/views/lib/Drupal/views/ViewStorage.php index d4ae36c..be9f881 100644 --- a/core/modules/views/lib/Drupal/views/ViewStorage.php +++ b/core/modules/views/lib/Drupal/views/ViewStorage.php @@ -324,7 +324,7 @@ protected function generateDisplayId($plugin_id) { * @return Drupal\views\Plugin\views\display\DisplayPluginBase * A reference to the new handler object. */ - public function &newDisplay($plugin_id = 'page', $title = NULL, $id = NULL) { + public function newDisplay($plugin_id = 'page', $title = NULL, $id = NULL) { $id = $this->addDisplay($plugin_id, $title, $id); return $this->getExecutable()->newDisplay($id); }