Commit b88ea073 authored by tim.plunkett's avatar tim.plunkett

Issue #1776494 by tim.plunkett: Fix failures exposed by plugin instantiation test.

parent c9139f27
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
use Drupal\Component\Plugin\Factory\DefaultFactory; use Drupal\Component\Plugin\Factory\DefaultFactory;
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
use Drupal\Core\Plugin\Discovery\CacheDecorator; use Drupal\Core\Plugin\Discovery\CacheDecorator;
use Drupal\Component\Plugin\Exception\PluginException;
class ViewsPluginManager extends PluginManagerBase { class ViewsPluginManager extends PluginManagerBase {
...@@ -36,7 +35,7 @@ public function __construct($type) { ...@@ -36,7 +35,7 @@ public function __construct($type) {
$this->type = $type; $this->type = $type;
$this->discovery = new CacheDecorator(new AnnotatedClassDiscovery('views', $this->type), 'views:' . $this->type, 'views'); $this->discovery = new CacheDecorator(new AnnotatedClassDiscovery('views', $this->type), 'views:' . $this->type, 'views');
$this->factory = new DefaultFactory($this->discovery); $this->factory = new DefaultFactory($this);
$this->coreModules = views_core_modules(); $this->coreModules = views_core_modules();
} }
...@@ -71,28 +70,8 @@ public function processDefinition(&$definition, $plugin_id) { ...@@ -71,28 +70,8 @@ public function processDefinition(&$definition, $plugin_id) {
'theme path' => $theme_path, 'theme path' => $theme_path,
'theme file' => $theme_file, 'theme file' => $theme_file,
'parent' => 'parent', 'parent' => 'parent',
'plugin_type' => $this->type,
); );
} }
/**
* Creates a plugin from an ID.
*
* @param string $plugin_id
* The plugin ID.
* @param array|false $definition
* Either the definition array, or FALSE if it needs to be loaded.
*
* @return Drupal\views\Plugin\views\PluginBase
* The plugin instance.
*/
public function createPluginFromId($plugin_id, $definition = FALSE) {
if (!$definition) {
$definition = $this->getDefinition($plugin_id);
}
if (!empty($definition)) {
$instance = $this->createInstance($plugin_id, array('type' => $this->type, 'definition' => $definition));
return $instance;
}
}
} }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace Drupal\views\Plugin\views; namespace Drupal\views\Plugin\views;
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\views\Plugin\views\PluginBase; use Drupal\views\Plugin\views\PluginBase;
use Drupal\views\View; use Drupal\views\View;
...@@ -72,8 +73,8 @@ abstract class HandlerBase extends PluginBase { ...@@ -72,8 +73,8 @@ abstract class HandlerBase extends PluginBase {
/** /**
* Constructs a Handler object. * Constructs a Handler object.
*/ */
public function __construct(array $configuration, $plugin_id) { public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery) {
parent::__construct($configuration, $plugin_id); parent::__construct($configuration, $plugin_id, $discovery);
$this->is_handler = TRUE; $this->is_handler = TRUE;
} }
...@@ -87,6 +88,7 @@ public function __construct(array $configuration, $plugin_id) { ...@@ -87,6 +88,7 @@ public function __construct(array $configuration, $plugin_id) {
* based upon the type of handler. * based upon the type of handler.
*/ */
public function init(&$view, &$options) { public function init(&$view, &$options) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$display_id = $this->view->current_display; $display_id = $this->view->current_display;
// Check to see if this handler type is defaulted. Note that // Check to see if this handler type is defaulted. Note that
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace Drupal\views\Plugin\views; namespace Drupal\views\Plugin\views;
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\Component\Plugin\PluginBase as ComponentPluginBase; use Drupal\Component\Plugin\PluginBase as ComponentPluginBase;
abstract class PluginBase extends ComponentPluginBase { abstract class PluginBase extends ComponentPluginBase {
...@@ -56,14 +57,19 @@ abstract class PluginBase extends ComponentPluginBase { ...@@ -56,14 +57,19 @@ abstract class PluginBase extends ComponentPluginBase {
/** /**
* Constructs a Plugin object. * Constructs a Plugin object.
*/ */
public function __construct(array $configuration, $plugin_id) { public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery) {
$this->configuration = $configuration; parent::__construct($configuration, $plugin_id, $discovery);
$this->plugin_id = $plugin_id;
$this->plugin_type = $configuration['type']; $this->definition = $this->discovery->getDefinition($plugin_id) + $configuration;
$this->definition = $configuration['definition'];
// @todo Change calls to $this->plugin_type to use the definition directly.
$this->plugin_type = $this->definition['plugin_type'];
// @todo Change calls to $this->real_field to use the definition directly.
if (isset($this->definition['field'])) { if (isset($this->definition['field'])) {
$this->real_field = $this->definition['field']; $this->real_field = $this->definition['field'];
} }
$this->construct(); $this->construct();
} }
...@@ -97,7 +103,6 @@ protected function defineOptions() { return array(); } ...@@ -97,7 +103,6 @@ protected function defineOptions() { return array(); }
* easily construct them with variable arguments. * easily construct them with variable arguments.
*/ */
public function construct() { public function construct() {
$this->setOptionDefaults($this->options, $this->defineOptions());
} }
protected function setOptionDefaults(&$storage, $options, $level = 0) { protected function setOptionDefaults(&$storage, $options, $level = 0) {
......
...@@ -31,6 +31,7 @@ abstract class AccessPluginBase extends PluginBase { ...@@ -31,6 +31,7 @@ abstract class AccessPluginBase extends PluginBase {
* The display handler. * The display handler.
*/ */
public function init(&$view, &$display) { public function init(&$view, &$display) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->display = &$display; $this->display = &$display;
......
...@@ -31,6 +31,7 @@ abstract class AreaPluginBase extends HandlerBase { ...@@ -31,6 +31,7 @@ abstract class AreaPluginBase extends HandlerBase {
* is empty. * is empty.
*/ */
public function init(&$view, &$options) { public function init(&$view, &$options) {
$this->setOptionDefaults($this->options, $this->defineOptions());
parent::init($view, $options); parent::init($view, $options);
if ($this->handler_type == 'empty') { if ($this->handler_type == 'empty') {
$this->options['empty'] = TRUE; $this->options['empty'] = TRUE;
......
...@@ -34,6 +34,7 @@ function get_argument() { } ...@@ -34,6 +34,7 @@ function get_argument() { }
* it is linked to. * it is linked to.
*/ */
public function init(&$view, &$argument, $options) { public function init(&$view, &$argument, $options) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->argument = &$argument; $this->argument = &$argument;
......
...@@ -27,6 +27,7 @@ abstract class ArgumentValidatorPluginBase extends PluginBase { ...@@ -27,6 +27,7 @@ abstract class ArgumentValidatorPluginBase extends PluginBase {
* it is linked to. * it is linked to.
*/ */
public function init(&$view, &$argument, $options) { public function init(&$view, &$argument, $options) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->argument = &$argument; $this->argument = &$argument;
......
...@@ -60,6 +60,7 @@ abstract class CachePluginBase extends PluginBase { ...@@ -60,6 +60,7 @@ abstract class CachePluginBase extends PluginBase {
* The display handler. * The display handler.
*/ */
public function init(&$view, &$display) { public function init(&$view, &$display) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->display = &$display; $this->display = &$display;
......
...@@ -86,6 +86,7 @@ abstract class DisplayPluginBase extends PluginBase { ...@@ -86,6 +86,7 @@ abstract class DisplayPluginBase extends PluginBase {
protected $usesAttachments = FALSE; protected $usesAttachments = FALSE;
public function init(&$view, &$display, $options = NULL) { public function init(&$view, &$display, $options = NULL) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->display = &$display; $this->display = &$display;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
abstract class DisplayExtenderPluginBase extends PluginBase { abstract class DisplayExtenderPluginBase extends PluginBase {
public function init(&$view, &$display) { public function init(&$view, &$display) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = $view; $this->view = $view;
$this->display = $display; $this->display = $display;
} }
......
...@@ -38,6 +38,7 @@ abstract class ExposedFormPluginBase extends PluginBase { ...@@ -38,6 +38,7 @@ abstract class ExposedFormPluginBase extends PluginBase {
* The display handler. * The display handler.
*/ */
public function init(&$view, &$display, $options = array()) { public function init(&$view, &$display, $options = array()) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->display = &$display; $this->display = &$display;
......
...@@ -26,11 +26,8 @@ ...@@ -26,11 +26,8 @@
*/ */
class Markup extends FieldPluginBase { class Markup extends FieldPluginBase {
/** public function init(&$view, &$options) {
* Constructor; calls to base object constructor. parent::init($view, $options);
*/
public function construct() {
parent::construct();
$this->format = $this->definition['format']; $this->format = $this->definition['format'];
......
...@@ -24,6 +24,7 @@ public function adminLabel($short = FALSE) { ...@@ -24,6 +24,7 @@ public function adminLabel($short = FALSE) {
return t('Broken/missing handler'); return t('Broken/missing handler');
} }
public function init(&$view, &$options) { }
public function defineOptions() { return array(); } public function defineOptions() { return array(); }
public function ensureMyTable() { /* No table to ensure! */ } public function ensureMyTable() { /* No table to ensure! */ }
public function query($group_by = FALSE) { /* No query to run */ } public function query($group_by = FALSE) { /* No query to run */ }
......
...@@ -34,6 +34,7 @@ abstract class LocalizationPluginBase extends PluginBase { ...@@ -34,6 +34,7 @@ abstract class LocalizationPluginBase extends PluginBase {
* The view object. * The view object.
*/ */
public function init(&$view) { public function init(&$view) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
} }
......
...@@ -40,6 +40,7 @@ abstract class PagerPluginBase extends PluginBase { ...@@ -40,6 +40,7 @@ abstract class PagerPluginBase extends PluginBase {
* The display handler. * The display handler.
*/ */
public function init(&$view, &$display, $options = array()) { public function init(&$view, &$display, $options = array()) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->display = &$display; $this->display = &$display;
......
...@@ -25,6 +25,7 @@ abstract class QueryPluginBase extends PluginBase implements QueryInterface { ...@@ -25,6 +25,7 @@ abstract class QueryPluginBase extends PluginBase implements QueryInterface {
* Constructor; Create the basic query object and fill with default values. * Constructor; Create the basic query object and fill with default values.
*/ */
public function init($base_table, $base_field, $options) { public function init($base_table, $base_field, $options) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->base_table = $base_table; $this->base_table = $base_table;
$this->base_field = $base_field; $this->base_field = $base_field;
$this->unpackOptions($this->options, $options); $this->unpackOptions($this->options, $options);
......
...@@ -48,6 +48,7 @@ abstract class RelationshipPluginBase extends HandlerBase { ...@@ -48,6 +48,7 @@ abstract class RelationshipPluginBase extends HandlerBase {
* the table they operate on. * the table they operate on.
*/ */
public function init(&$view, &$options) { public function init(&$view, &$options) {
$this->setOptionDefaults($this->options, $this->defineOptions());
parent::init($view, $options); parent::init($view, $options);
if (isset($this->definition['relationship table'])) { if (isset($this->definition['relationship table'])) {
$this->table = $this->definition['relationship table']; $this->table = $this->definition['relationship table'];
......
...@@ -42,6 +42,7 @@ abstract class RowPluginBase extends PluginBase { ...@@ -42,6 +42,7 @@ abstract class RowPluginBase extends PluginBase {
* Initialize the row plugin. * Initialize the row plugin.
*/ */
public function init(&$view, &$display, $options = NULL) { public function init(&$view, &$display, $options = NULL) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->display = &$display; $this->display = &$display;
......
...@@ -90,6 +90,7 @@ abstract class StylePluginBase extends PluginBase { ...@@ -90,6 +90,7 @@ abstract class StylePluginBase extends PluginBase {
* from at least two locations. If it's not included, look on the display. * from at least two locations. If it's not included, look on the display.
*/ */
public function init(&$view, &$display, $options = NULL) { public function init(&$view, &$display, $options = NULL) {
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = &$view; $this->view = &$view;
$this->display = &$display; $this->display = &$display;
......
...@@ -67,7 +67,7 @@ function test_views_break_phrase_string() { ...@@ -67,7 +67,7 @@ function test_views_break_phrase_string() {
$this->assertEqual($empty_stdclass, views_break_phrase_string('', $null)); $this->assertEqual($empty_stdclass, views_break_phrase_string('', $null));
$handler = views_get_handler('node', 'title', 'argument'); $handler = views_get_handler('node', 'title', 'argument');
$this->assertEqual($handler, views_break_phrase_string('', $handler)); $this->assertEqual($handler, views_break_phrase_string('', $handler), 'The views_break_phrase_string() works correctly.');
// test ors // test ors
$handler = views_break_phrase_string('word1 word2+word'); $handler = views_break_phrase_string('word1 word2+word');
...@@ -122,7 +122,7 @@ function test_views_break_phrase() { ...@@ -122,7 +122,7 @@ function test_views_break_phrase() {
$this->assertEqual($empty_stdclass, views_break_phrase('', $null)); $this->assertEqual($empty_stdclass, views_break_phrase('', $null));
$handler = views_get_handler('node', 'title', 'argument'); $handler = views_get_handler('node', 'title', 'argument');
$this->assertEqual($handler, views_break_phrase('', $handler)); $this->assertEqual($handler, views_break_phrase('', $handler), 'The views_break_phrase() function works correctly.');
// Generate three random numbers which can be used below; // Generate three random numbers which can be used below;
$n1 = rand(0, 100); $n1 = rand(0, 100);
......
...@@ -61,6 +61,9 @@ protected function enableViewsTestModule() { ...@@ -61,6 +61,9 @@ protected function enableViewsTestModule() {
} }
$query->execute(); $query->execute();
$this->checkPermissions(array(), TRUE); $this->checkPermissions(array(), TRUE);
// Reset the test view, in case it was dependent on the test data module.
$this->view = $this->getBasicView();
} }
/** /**
...@@ -403,7 +406,10 @@ protected function getBasicView() { ...@@ -403,7 +406,10 @@ protected function getBasicView() {
* A View instance. * A View instance.
*/ */
protected function createViewFromConfig($view_name) { protected function createViewFromConfig($view_name) {
module_enable(array('views_test_config')); if (!module_exists('views_test_config')) {
module_enable(array('views_test_config'));
}
$data = config("views.view.$view_name")->get(); $data = config("views.view.$view_name")->get();
$view = entity_create('view', $data); $view = entity_create('view', $data);
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
use Drupal\Core\Database\Query\AlterableInterface; use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\views\TempStore\UserTempStore; use Drupal\views\TempStore\UserTempStore;
use Drupal\views\View; use Drupal\views\View;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\views\Plugin\Type\ViewsPluginManager; use Drupal\views\Plugin\Type\ViewsPluginManager;
use Drupal\Component\Plugin\Exception\PluginException;
/** /**
* Views API version string. * Views API version string.
...@@ -1264,7 +1264,7 @@ function views_include_handlers($reset = FALSE) { ...@@ -1264,7 +1264,7 @@ function views_include_handlers($reset = FALSE) {
* The name of the table this handler is from. * The name of the table this handler is from.
* @param $field * @param $field
* The name of the field this handler is from. * The name of the field this handler is from.
* @param $key * @param $type
* The type of handler. i.e, sort, field, argument, filter, relationship * The type of handler. i.e, sort, field, argument, filter, relationship
* @param $override * @param $override
* Override the actual handler object with this class. Used for * Override the actual handler object with this class. Used for
...@@ -1274,7 +1274,7 @@ function views_include_handlers($reset = FALSE) { ...@@ -1274,7 +1274,7 @@ function views_include_handlers($reset = FALSE) {
* @return views_handler * @return views_handler
* An instance of a handler object. May be views_handler_broken. * An instance of a handler object. May be views_handler_broken.
*/ */
function views_get_handler($table, $field, $key, $override = NULL) { function views_get_handler($table, $field, $type, $override = NULL) {
static $recursion_protection = array(); static $recursion_protection = array();
$data = views_fetch_data($table, FALSE); $data = views_fetch_data($table, FALSE);
...@@ -1292,11 +1292,11 @@ function views_get_handler($table, $field, $key, $override = NULL) { ...@@ -1292,11 +1292,11 @@ function views_get_handler($table, $field, $key, $override = NULL) {
$moved = $data[$field]['moved to']; $moved = $data[$field]['moved to'];
} }
// Support conversion on handler level. // Support conversion on handler level.
if (isset($data[$field][$key]['moved to'])) { if (isset($data[$field][$type]['moved to'])) {
$moved = $data[$field][$key]['moved to']; $moved = $data[$field][$type]['moved to'];
} }
if (isset($data[$field][$key]) || !empty($moved)) { if (isset($data[$field][$type]) || !empty($moved)) {
if (!empty($moved)) { if (!empty($moved)) {
list($moved_table, $moved_field) = $moved; list($moved_table, $moved_field) = $moved;
if (!empty($recursion_protection[$moved_table][$moved_field])) { if (!empty($recursion_protection[$moved_table][$moved_field])) {
...@@ -1305,7 +1305,7 @@ function views_get_handler($table, $field, $key, $override = NULL) { ...@@ -1305,7 +1305,7 @@ function views_get_handler($table, $field, $key, $override = NULL) {
} }
$recursion_protection[$moved_table][$moved_field] = TRUE; $recursion_protection[$moved_table][$moved_field] = TRUE;
$handler = views_get_handler($moved_table, $moved_field, $key, $override); $handler = views_get_handler($moved_table, $moved_field, $type, $override);
$recursion_protection = array(); $recursion_protection = array();
if ($handler) { if ($handler) {
// store these values so we know what we were originally called. // store these values so we know what we were originally called.
...@@ -1321,16 +1321,15 @@ function views_get_handler($table, $field, $key, $override = NULL) { ...@@ -1321,16 +1321,15 @@ function views_get_handler($table, $field, $key, $override = NULL) {
// @fixme: temporary. // @fixme: temporary.
// Set up a default handler, if both handler and id is not specified. // Set up a default handler, if both handler and id is not specified.
if (empty($data[$field][$key]['handler']) && empty($data[$field][$key]['id'])) { if (empty($data[$field][$type]['handler']) && empty($data[$field][$type]['id'])) {
$data[$field][$key]['id'] = 'standard'; $data[$field][$type]['id'] = 'standard';
} }
if ($override) { if ($override) {
$data[$field][$key]['override handler'] = $override; $data[$field][$type]['override handler'] = $override;
} }
$definition = $data[$field][$key]; $definition = $data[$field][$type];
$type = $key;
foreach (array('group', 'title', 'title short', 'help', 'real field') as $key) { foreach (array('group', 'title', 'title short', 'help', 'real field') as $key) {
if (!isset($definition[$key])) { if (!isset($definition[$key])) {
// First check the field level // First check the field level
...@@ -1347,32 +1346,24 @@ function views_get_handler($table, $field, $key, $override = NULL) { ...@@ -1347,32 +1346,24 @@ function views_get_handler($table, $field, $key, $override = NULL) {
// @todo This is crazy. Find a way to remove the override functionality. // @todo This is crazy. Find a way to remove the override functionality.
$manager = new ViewsPluginManager($type); $manager = new ViewsPluginManager($type);
$plugin_id = !empty($definition['override handler']) ? $definition['override handler'] : $definition['id']; $plugin_id = !empty($definition['override handler']) ? $definition['override handler'] : $definition['id'];
// Try to use the overridden handler.
try { try {
return $manager->createPluginFromId($plugin_id, $definition); return $manager->createInstance($plugin_id, $definition);
} }
catch (PluginException $e) { catch (PluginException $e) {
return $manager->createPluginFromId($definition['id'], $definition); // If that fails, use the original handler.
try {
return $manager->createInstance($definition['id'], $definition);
}
catch (PluginException $e) {
// Deliberately empty, this case is handled generically below.
}
} }
} }
if ($handler) { // Finally, use the 'broken' handler.
return $handler; debug(t("Missing handler: @table @field @type", array('@table' => $table, '@field' => $field, '@type' => $type)));
} return views_get_plugin($type, 'broken');
// DEBUG -- identify missing handlers
debug(t("Missing handler: @table @field @key", array('@table' => $table, '@field' => $field, '@key' => $key)));
$broken = array(
'title' => t('Broken handler @table.@field', array('@table' => $table, '@field' => $field)),
'id' => 'broken',
'table' => $table,
'field' => $field,
);
// In case the manager was already initialized above, try to reuse it.
if (!isset($manager)) {
$manager = new ViewsPluginManager($key);
}
return $manager->createPluginFromId('broken');
} }
/** /**
...@@ -1442,7 +1433,7 @@ function views_fetch_plugin_names($type, $key = NULL, $base = array()) { ...@@ -1442,7 +1433,7 @@ function views_fetch_plugin_names($type, $key = NULL, $base = array()) {
*/ */
function views_get_plugin($type, $plugin_id) { function views_get_plugin($type, $plugin_id) {
$manager = new ViewsPluginManager($type); $manager = new ViewsPluginManager($type);
return $manager->createPluginFromId($plugin_id); return $manager->createInstance($plugin_id);
} }
/** /**
......