Commit 2d3d33b4 authored by catch's avatar catch

Issue #2261181 by damiankloip, dawehner: Fixed Always pass in the request into the view executable.

parent 5f62e929
......@@ -9,8 +9,6 @@
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Default argument plugin to extract a node.
......@@ -24,49 +22,13 @@
*/
class Node extends ArgumentDefaultPluginBase {
/**
* The request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* Constructs a new Node instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('request')
);
}
/**
* {@inheritdoc}
*/
public function getArgument() {
if (($node = $this->request->attributes->get('node')) && $node instanceof NodeInterface) {
if (($node = $this->view->getRequest()->attributes->get('node')) && $node instanceof NodeInterface) {
return $node->id();
}
}
}
......@@ -14,7 +14,6 @@
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\display\PathPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouteCollection;
......@@ -79,13 +78,6 @@ class RestExport extends PathPluginBase {
*/
protected $contentNegotiation;
/**
* The request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* Constructs a Drupal\rest\Plugin\ResourceBase object.
*
......@@ -103,13 +95,10 @@ class RestExport extends PathPluginBase {
* The form error helper.
* @param \Drupal\Core\ContentNegotiation $content_negotiation
* The content negotiation library.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteProviderInterface $route_provider, StateInterface $state, FormErrorInterface $form_error, ContentNegotiation $content_negotiation, Request $request) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteProviderInterface $route_provider, StateInterface $state, FormErrorInterface $form_error, ContentNegotiation $content_negotiation) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $route_provider, $state, $form_error);
$this->contentNegotiation = $content_negotiation;
$this->request = $request;
}
/**
......@@ -123,8 +112,7 @@ public static function create(ContainerInterface $container, array $configuratio
$container->get('router.route_provider'),
$container->get('state'),
$container->get('form_validator'),
$container->get('content_negotiation'),
$container->get('request')
$container->get('content_negotiation')
);
}
......@@ -134,7 +122,7 @@ public static function create(ContainerInterface $container, array $configuratio
public function initDisplay(ViewExecutable $view, array &$display, array &$options = NULL) {
parent::initDisplay($view, $display, $options);
$request_content_type = $this->contentNegotiation->getContentType($this->request);
$request_content_type = $this->contentNegotiation->getContentType($this->view->getRequest());
// Only use the requested content type if it's not 'html'. If it is then
// default to 'json' to aid debugging.
// @todo Remove the need for this when we have better content negotiation.
......@@ -142,7 +130,7 @@ public function initDisplay(ViewExecutable $view, array &$display, array &$optio
$this->setContentType($request_content_type);
}
$this->setMimeType($this->request->getMimeType($this->contentType));
$this->setMimeType($this->view->getRequest()->getMimeType($this->contentType));
}
/**
......
......@@ -24,42 +24,6 @@
*/
class Tid extends ArgumentDefaultPluginBase {
/**
* The request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* Constructs a new Tid instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('request')
);
}
/**
* Overrides \Drupal\views\Plugin\views\Plugin\views\PluginBase::init().
*/
......@@ -166,7 +130,7 @@ public function getArgument() {
// Load default argument from node.
if (!empty($this->options['node'])) {
// Just check, if a node could be detected.
if (($node = $this->request->attributes->has('node')) && $node instanceof NodeInterface) {
if (($node = $this->view->getRequest()->attributes->has('node')) && $node instanceof NodeInterface) {
$taxonomy = array();
foreach ($node->getFieldDefinitions() as $field) {
if ($field->getType() == 'taxonomy_term_reference') {
......
......@@ -23,43 +23,6 @@
*/
class User extends ArgumentDefaultPluginBase {
/**
* The request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* Constructs a default argument User object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('request')
);
}
/**
* {@inheritdoc}
*/
......@@ -87,16 +50,16 @@ public function buildOptionsForm(&$form, &$form_state) {
public function getArgument() {
// If there is a user object in the current route.
if ($this->request->attributes->has('user')) {
$user = $this->request->attributes->get('user');
if ($this->view->getRequest()->attributes->has('user')) {
$user = $this->view->getRequest()->attributes->get('user');
if ($user instanceof UserInterface) {
return $user->id();
}
}
// If option to use node author; and node in current route.
if (!empty($this->options['user']) && $this->request->attributes->has('node')) {
$node = $this->request->attributes->get('node');
if (!empty($this->options['user']) && $this->view->getRequest()->attributes->has('node')) {
$node = $this->view->getRequest()->attributes->get('node');
if ($node instanceof NodeInterface) {
return $node->getOwnerId();
}
......
......@@ -44,44 +44,8 @@ class Date extends Formula {
*/
protected $argFormat = 'Y-m-d';
/**
* The request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
var $option_name = 'default_argument_date';
/**
* Constructs a new Date instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('request')
);
}
/**
* Add an option to set the default value to the current date.
*/
......@@ -101,7 +65,7 @@ public function getDefaultArgument($raw = FALSE) {
return date($this->argFormat, REQUEST_TIME);
}
elseif (!$raw && in_array($this->options['default_argument_type'], array('node_created', 'node_changed'))) {
$node = $this->request->attributes->get('node');
$node = $this->view->getRequest()->attributes->get('node');
if (!($node instanceof NodeInterface)) {
return parent::getDefaultArgument();
......
......@@ -23,13 +23,6 @@
*/
class Raw extends ArgumentDefaultPluginBase {
/**
* The request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The alias manager.
*
......@@ -46,15 +39,12 @@ class Raw extends ArgumentDefaultPluginBase {
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
* @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
* The alias manager.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request, AliasManagerInterface $alias_manager) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, AliasManagerInterface $alias_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request;
$this->aliasManager = $alias_manager;
}
......@@ -66,7 +56,6 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration,
$plugin_id,
$plugin_definition,
$container->get('request'),
$container->get('path.alias_manager.cached')
);
}
......@@ -99,7 +88,7 @@ public function buildOptionsForm(&$form, &$form_state) {
}
public function getArgument() {
$path = $this->request->attributes->get('_system_path');
$path = $this->view->getRequest()->attributes->get('_system_path');
if ($this->options['use_alias']) {
$path = $this->aliasManager->getAliasByPath($path);
}
......
......@@ -297,10 +297,9 @@ public function generateResultsKey() {
'langcode' => \Drupal::languageManager()->getCurrentLanguage()->id,
'base_url' => $GLOBALS['base_url'],
);
$request = \Drupal::request();
foreach (array('exposed_info', 'page', 'sort', 'order', 'items_per_page', 'offset') as $key) {
if ($request->query->has($key)) {
$key_data[$key] = $request->query->get($key);
if ($this->view->getRequest()->query->has($key)) {
$key_data[$key] = $this->view->getRequest()->query->get($key);
}
}
......
......@@ -893,8 +893,7 @@ public function getHandlers($type) {
// @todo Remove dependency on Request object
// https://drupal.org/node/2059003.
try {
$request = \Drupal::request();
if ($request->request->get('form_id') && isset($this->view->temporary_options[$type][$id])) {
if ($this->view->getRequest()->request->get('form_id') && isset($this->view->temporary_options[$type][$id])) {
$info = $this->view->temporary_options[$type][$id];
}
}
......
......@@ -1485,7 +1485,7 @@ public function getRenderTokens($item) {
}
// Get flattened set of tokens for any array depth in query parameters.
$tokens += $this->getTokenValuesRecursive(\Drupal::request()->query->all());
$tokens += $this->getTokenValuesRecursive($this->view->getRequest()->query->all());
// Now add replacements for our fields.
foreach ($this->view->display_handler->getHandlers('field') as $field => $handler) {
......
......@@ -211,7 +211,7 @@ public function validateOptionsForm(&$form, &$form_state) {
public function query() {
if ($this->itemsPerPageExposed()) {
$query = \Drupal::request()->query;
$query = $this->view->getRequest()->query;
$items_per_page = $query->get('items_per_page');
if ($items_per_page > 0) {
$this->options['items_per_page'] = $items_per_page;
......@@ -221,7 +221,7 @@ public function query() {
}
}
if ($this->isOffsetExposed()) {
$query = \Drupal::request()->query;
$query = $this->view->getRequest()->query;
$offset = $query->get('offset');
if (isset($offset) && $offset >= 0) {
$this->options['offset'] = $offset;
......@@ -265,7 +265,7 @@ public function setCurrentPage($number = NULL) {
// Fill in missing values in the global page array, in case the global page
// array hasn't been initialized before.
$page = \Drupal::request()->query->get('page');
$page = $this->view->getRequest()->query->get('page');
$page = isset($page) ? explode(',', $page) : array();
for ($i = 0; $i <= $this->options['id'] || $i < count($pager_page_array); $i++) {
......
......@@ -60,29 +60,6 @@ class Table extends StylePluginBase {
*/
public $order;
/**
* Contains the current request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('request'));
}
/**
* Constructs a Table object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request;
}
protected function defineOptions() {
$options = parent::defineOptions();
......@@ -104,7 +81,7 @@ protected function defineOptions() {
* {@inheritdoc}
*/
public function buildSort() {
$order = $this->request->query->get('order');
$order = $this->view->getRequest()->query->get('order');
if (!isset($order) && ($this->options['default'] == -1 || empty($this->view->field[$this->options['default']]))) {
return TRUE;
}
......@@ -122,7 +99,7 @@ public function buildSort() {
* Add our actual sort criteria
*/
public function buildSortPost() {
$query = $this->request->query;
$query = $this->view->getRequest()->query;
$order = $query->get('order');
if (!isset($order)) {
// check for a 'default' clicksort. If there isn't one, exit gracefully.
......
......@@ -47,8 +47,7 @@ public function testTable() {
// Test the buildSort() method.
$request = new Request();
$this->container->enterScope('request');
$this->container->set('request', $request);
$view->setRequest($request);
$style_plugin->options['override'] = FALSE;
......@@ -70,8 +69,7 @@ public function testTable() {
// Test the buildSortPost() method.
$request = new Request();
$this->container->enterScope('request');
$this->container->set('request', $request);
$view->setRequest($request);
// Setup no valid default.
$this->prepareView($view);
......@@ -130,7 +128,6 @@ public function testTable() {
// Excluded field to make sure its wrapping td doesn't show.
$this->prepareView($view);
$style_plugin = $view->style_plugin;
$view->field['name']->options['exclude'] = TRUE;
$output = $view->preview();
$output = drupal_render($output);
......
......@@ -366,8 +366,7 @@ protected function assertViewDestroy($view) {
$reflection = new \ReflectionClass($view);
$defaults = $reflection->getDefaultProperties();
// The storage and user should remain.
unset($defaults['storage']);
unset($defaults['user']);
unset($defaults['storage'], $defaults['user'], $defaults['request']);
foreach ($defaults as $property => $default) {
$this->assertIdentical($this->getProtectedProperty($view, $property), $default);
......
......@@ -1506,6 +1506,7 @@ public function attachDisplays() {
foreach ($this->display_handler->getAttachedDisplays() as $id) {
// Create a clone for the attachments to manipulate. 'static' refers to the current class name.
$cloned_view = new static($this->storage, $this->user);
$cloned_view->setRequest($this->getRequest());
$this->displayHandlers->get($id)->attachTo($cloned_view, $this->current_display);
}
$this->is_attachment = FALSE;
......@@ -1786,8 +1787,8 @@ public function destroy() {
$defaults = $reflection->getDefaultProperties();
// The external dependencies should not be reset. This is not generated by
// the execution of a view.
unset($defaults['storage']);
unset($defaults['user']);
unset($defaults['storage'], $defaults['user'], $defaults['request']);
foreach ($defaults as $property => $default) {
$this->{$property} = $default;
}
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Session\AccountInterface;
use Drupal\views\ViewStorageInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Defines the cache backend factory.
......@@ -22,14 +23,24 @@ class ViewExecutableFactory {
*/
protected $user;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* Constructs a new ViewExecutableFactory
*
* @param \Drupal\Core\Session\AccountInterface $user
* The current user.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
*/
public function __construct(AccountInterface $user) {
public function __construct(AccountInterface $user, RequestStack $request_stack) {
$this->user = $user;
$this->requestStack = $request_stack;
}
/**
......@@ -42,7 +53,9 @@ public function __construct(AccountInterface $user) {
* A ViewExecutable instance.
*/
public function get(ViewStorageInterface $view) {
return new ViewExecutable($view, $this->user);
$view = new ViewExecutable($view, $this->user);
$view->setRequest($this->requestStack->getCurrentRequest());
return $view;
}
}
......@@ -40,12 +40,15 @@ public function testGetArgument() {
->getMock();
$request = new Request(array(), array(), array('_system_path' => 'test/example'));
$view->expects($this->any())
->method('getRequest')
->will($this->returnValue($request));
$alias_manager = $this->getMock('Drupal\Core\Path\AliasManagerInterface');
$alias_manager->expects($this->never())
->method('getAliasByPath');
// Don't use aliases.
$raw = new Raw(array(), 'raw', array(), $request, $alias_manager);
$raw = new Raw(array(), 'raw', array(), $alias_manager);
$options = array(
'use_alias' => FALSE,
'index' => 0,
......@@ -53,7 +56,7 @@ public function testGetArgument() {
$raw->init($view, $display_plugin, $options);
$this->assertEquals('test', $raw->getArgument());
$raw = new Raw(array(), 'raw', array(), $request, $alias_manager);
$raw = new Raw(array(), 'raw', array(), $alias_manager);
$options = array(
'use_alias' => FALSE,
'index' => 1,
......@@ -68,7 +71,7 @@ public function testGetArgument() {
->with($this->equalTo('test/example'))
->will($this->returnValue('other/example'));
$raw = new Raw(array(), 'raw', array(), $request, $alias_manager);
$raw = new Raw(array(), 'raw', array(), $alias_manager);
$options = array(
'use_alias' => TRUE,
'index' => 0,
......@@ -76,7 +79,7 @@ public function testGetArgument() {
$raw->init($view, $display_plugin, $options);
$this->assertEquals('other', $raw->getArgument());
$raw = new Raw(array(), 'raw', array(), $request, $alias_manager);
$raw = new Raw(array(), 'raw', array(), $alias_manager);
$options = array(
'use_alias' => TRUE,
'index' => 1,
......
<?php
/**
* @file
* Contains \Drupal\views\Tests\VIewExecutableFactoryTest.
*/
namespace Drupal\views\Tests;
use Drupal\Tests\UnitTestCase;
use Drupal\views\ViewExecutableFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Tests the ViewExecutableFactory class.
*
* @coversDefaultClass \Drupal\views\ViewExecutableFactory
*/
class ViewExecutableFactoryTest extends UnitTestCase {
/**
* The mock user object.
*
* @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $user;
/**
* The mock request stack object.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The mock view entity.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $view;
/**
* The ViewExecutableFactory class under test.
*
* @var \Drupal\views\ViewExecutableFactory
*/
protected $viewExecutableFactory;
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'View executable factory test',
'description' => 'Tests methods on the \Drupal\views\ViewExecutableFactory class',
'group' => 'Views',
);
}
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->user = $this->getMock('Drupal\Core\Session\AccountInterface');
$this->requestStack = new RequestStack();
$this->view = $this->getMock('Drupal\views\ViewStorageInterface');
$this->viewExecutableFactory = new ViewExecutableFactory($this->user, $this->requestStack);
}
/**
* Tests the get method.
*
* @covers ::get
*/
public function testGet() {
$request_1 = new Request();
$request_2 = new Request();
$this->requestStack->push($request_1);
$executable = $this->viewExecutableFactory->get($this->view);
$this->assertInstanceOf('Drupal\views\ViewExecutable', $executable);
$this->assertSame($executable->getRequest(), $request_1);
$this->assertSame($executable->getUser(), $this->user);
// Call get() again to ensure a new executable is created with the other
// request object.
$this->requestStack->push($request_2);