diff --git a/core/modules/views/lib/Drupal/views/DisplayBag.php b/core/modules/views/lib/Drupal/views/DisplayBag.php index 72023f3..6e7a75b 100644 --- a/core/modules/views/lib/Drupal/views/DisplayBag.php +++ b/core/modules/views/lib/Drupal/views/DisplayBag.php @@ -7,6 +7,7 @@ namespace Drupal\views; +use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Component\Plugin\PluginBag; use Drupal\Component\Plugin\PluginManagerInterface; @@ -77,7 +78,16 @@ protected function initializePlugin($display_id) { // Retrieve and initialize the new display handler with data. $display = &$this->view->storage->getDisplay($display_id); - $this->pluginInstances[$display_id] = $this->manager->createInstance($display['display_plugin']); + + try { + $this->pluginInstances[$display_id] = $this->manager->createInstance($display['display_plugin']); + } + // Catch any plugin exceptions that are thrown. So we can fail nicely if a + // display plugin isn't found. + catch (PluginException $e) { + $message = $e->getMessage(); + drupal_set_message(t('!message', array('!message' => $message)), 'warning'); + } if (empty($this->pluginInstances[$display_id])) { // Provide a 'default' handler as an emergency. This won't work well but // it will keep things from crashing. diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php index 4ccd11d..8d6e2eb 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php @@ -19,14 +19,14 @@ class DisplayTest extends PluginTestBase { * * @var array */ - public static $testViews = array('test_filter_groups', 'test_get_attach_displays', 'test_view'); + public static $testViews = array('test_filter_groups', 'test_get_attach_displays', 'test_view', 'test_display_invalid'); /** * Modules to enable. * * @var array */ - public static $modules = array('views_ui'); + public static $modules = array('views_ui', 'node'); public static function getInfo() { return array( @@ -143,4 +143,28 @@ public function testGetAttachedDisplays() { $this->assertEqual($view->display_handler->getAttachedDisplays(), array()); } + /** + * Tests an invalid display plugin. + */ + public function testInvalidDisplayPlugin() { + $this->drupalGet('test_display_invalid'); + $this->assertResponse(200); + + // Change the page plugin id to an invalid one. Bypass the entity system + // so no menu rebuild was executed (so the path is still available). + $config = config('views.view.test_display_invalid'); + $config->set('display.page_1.display_plugin', 'invalid'); + $config->save(); + + $this->drupalGet('test_display_invalid'); + $this->assertResponse(200); + $this->assertText(t('The plugin (invalid) did not specify an instance class.')); + + // Rebuild the menu, and ensure that the path is not accessible anymore. + menu_router_rebuild(); + + $this->drupalGet('test_display_invalid'); + $this->assertResponse(404); + } + } diff --git a/core/modules/views/tests/views_test_config/test_views/views.view.test_display_invalid.yml b/core/modules/views/tests/views_test_config/test_views/views.view.test_display_invalid.yml new file mode 100644 index 0000000..39a4c6d --- /dev/null +++ b/core/modules/views/tests/views_test_config/test_views/views.view.test_display_invalid.yml @@ -0,0 +1,30 @@ +api_version: '3.0' +base_table: node +core: '8' +description: '' +status: '1' +display: + default: + display_options: + row: + type: fields + fields: + id: + id: nid + table: node + field: nid + plugin_id: numeric + display_plugin: default + display_title: Master + id: default + position: '0' + page_1: + display_options: + path: test_display_invalid + display_plugin: page + display_title: Page + id: page_1 + position: '0' +human_name: '' +id: test_display_invalid +tag: ''