diff --git a/core/core.services.yml b/core/core.services.yml index 50808416da73d0065ec7344c55246945d47afaa8..3768035310b3962800cad0a5d7cdb73e77ada81a 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -280,6 +280,9 @@ services: path.alias_manager: class: Drupal\Core\Path\AliasManager arguments: ['@path.alias_storage', '@path.alias_whitelist', '@language_manager', '@cache.data'] + path.current: + class: Drupal\Core\Path\CurrentPathStack + arguments: ['@request_stack'] http_client: class: Drupal\Core\Http\Client tags: @@ -537,7 +540,7 @@ services: arguments: ['@current_route_match'] router.route_provider: class: Drupal\Core\Routing\RouteProvider - arguments: ['@database', '@router.builder', '@state'] + arguments: ['@database', '@router.builder', '@state', '@path.current'] tags: - { name: event_subscriber } - { name: backend_overridable } @@ -548,6 +551,7 @@ services: - { name: 'event_subscriber' } router.matcher.final_matcher: class: Drupal\Core\Routing\UrlMatcher + arguments: ['@path.current'] router.matcher: class: Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher arguments: ['@router.route_provider'] @@ -840,7 +844,7 @@ services: class: Drupal\Core\EventSubscriber\PathSubscriber tags: - { name: event_subscriber } - arguments: ['@path.alias_manager', '@path_processor_manager'] + arguments: ['@path.alias_manager', '@path_processor_manager', '@path.current'] finish_response_subscriber: class: Drupal\Core\EventSubscriber\FinishResponseSubscriber tags: diff --git a/core/includes/theme.inc b/core/includes/theme.inc index b99fc6c9999dea8f5c91683f796d0bc04763d8d6..6627118af9a2f4244f65c6dbead9acd65e40db02 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1315,8 +1315,8 @@ function template_preprocess_html(&$variables) { $variables['root_path'] = FALSE; } else { - $system_path = \Drupal::request()->attributes->get('_system_path'); - $variables['root_path'] = explode('/', $system_path)[0]; + $system_path = \Drupal::service('path.current')->getPath(); + $variables['root_path'] = explode('/', $system_path)[1]; } $site_config = \Drupal::config('system.site'); diff --git a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php index f757aa7ee1b7c2e5cf9c4fc91d3b78c86fb4667e..a98bf57119d65bcffee0cc24f8d153cbea7dab4c 100644 --- a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php @@ -7,6 +7,7 @@ namespace Drupal\Core\EventSubscriber; +use Drupal\Core\Url; use Drupal\Core\Utility\Error; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; @@ -69,7 +70,7 @@ protected function getHandledFormats() { * The event to process. */ public function on403(GetResponseForExceptionEvent $event) { - $this->makeSubrequest($event, 'system/403', Response::HTTP_FORBIDDEN); + $this->makeSubrequest($event, Url::fromRoute('system.403')->toString(), Response::HTTP_FORBIDDEN); } /** @@ -79,7 +80,7 @@ public function on403(GetResponseForExceptionEvent $event) { * The event to process. */ public function on404(GetResponseForExceptionEvent $event) { - $this->makeSubrequest($event, 'system/404', Response::HTTP_NOT_FOUND); + $this->makeSubrequest($event, Url::fromRoute('system.404')->toString(), Response::HTTP_NOT_FOUND); } /** @@ -87,24 +88,26 @@ public function on404(GetResponseForExceptionEvent $event) { * * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event * The event to process - * @param string $path - * The path to which to make a subrequest for this error message. + * @param string $url + * The path/url to which to make a subrequest for this error message. * @param int $status_code * The status code for the error being handled. */ - protected function makeSubrequest(GetResponseForExceptionEvent $event, $path, $status_code) { + protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code) { $request = $event->getRequest(); - // @todo Remove dependency on the internal _system_path attribute: - // https://www.drupal.org/node/2293523. - $system_path = $request->attributes->get('_system_path'); + if (!($url && $url[0] == '/')) { + $url = $request->getBasePath() . '/' . $url; + } + + $current_url = $request->getBasePath() . $request->getPathInfo(); - if ($path && $path != $system_path) { + if ($url != $request->getBasePath() . '/' && $url != $current_url) { if ($request->getMethod() === 'POST') { - $sub_request = Request::create($request->getBaseUrl() . '/' . $path, 'POST', ['destination' => $system_path, '_exception_statuscode' => $status_code] + $request->request->all(), $request->cookies->all(), [], $request->server->all()); + $sub_request = Request::create($url, 'POST', $this->drupalGetDestination() + ['_exception_statuscode' => $status_code] + $request->request->all(), $request->cookies->all(), [], $request->server->all()); } else { - $sub_request = Request::create($request->getBaseUrl() . '/' . $path, 'GET', $request->query->all() + ['destination' => $system_path, '_exception_statuscode' => $status_code], $request->cookies->all(), [], $request->server->all()); + $sub_request = Request::create($url, 'GET', $request->query->all() + $this->drupalGetDestination() + ['_exception_statuscode' => $status_code], $request->cookies->all(), [], $request->server->all()); } try { @@ -130,4 +133,11 @@ protected function makeSubrequest(GetResponseForExceptionEvent $event, $path, $s } } + /** + * Wraps drupal_get_destination(). + */ + protected function drupalGetDestination() { + return drupal_get_destination(); + } + } diff --git a/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php index 3d421763aac032aa7ab585b206804f6bb9f059be..eba6e7c1af056f3a118fa4cd8ef07dfdf0bfcd45 100644 --- a/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php @@ -45,9 +45,7 @@ public function __construct(LoggerChannelFactoryInterface $logger) { */ public function on403(GetResponseForExceptionEvent $event) { $request = $event->getRequest(); - // @todo Remove dependency on the internal _system_path attribute: - // https://www.drupal.org/node/2293523. - $this->logger->get('access denied')->warning(String::checkPlain($request->attributes->get('_system_path'))); + $this->logger->get('access denied')->warning(String::checkPlain($request->getRequestUri())); } /** @@ -58,9 +56,7 @@ public function on403(GetResponseForExceptionEvent $event) { */ public function on404(GetResponseForExceptionEvent $event) { $request = $event->getRequest(); - // @todo Remove dependency on the internal _system_path attribute: - // https://www.drupal.org/node/2293523. - $this->logger->get('page not found')->warning(String::checkPlain($request->attributes->get('_system_path'))); + $this->logger->get('page not found')->warning(String::checkPlain($request->getRequestUri())); } /** diff --git a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php index 472b31c9f544eded95952439af45a8d44b622c28..ec244841886f4442316fbc8dc1c3e082a7b51fc6 100644 --- a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php @@ -8,6 +8,7 @@ namespace Drupal\Core\EventSubscriber; use Drupal\Core\Path\AliasManagerInterface; +use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; @@ -34,9 +35,25 @@ class PathSubscriber implements EventSubscriberInterface { */ protected $pathProcessor; - public function __construct(AliasManagerInterface $alias_manager, InboundPathProcessorInterface $path_processor) { + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + + /** + * Constructs a new PathSubscriber instance. + * + * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager + * @param \Drupal\Core\PathProcessor\InboundPathProcessorInterface $path_processor + * @param \Drupal\Core\Path\CurrentPathStack $current_path + * The current path. + */ + public function __construct(AliasManagerInterface $alias_manager, InboundPathProcessorInterface $path_processor, CurrentPathStack $current_path) { $this->aliasManager = $alias_manager; $this->pathProcessor = $path_processor; + $this->currentPath = $current_path; } /** @@ -49,7 +66,7 @@ public function onKernelRequestConvertPath(GetResponseEvent $event) { $request = $event->getRequest(); $path = trim($request->getPathInfo(), '/'); $path = $this->pathProcessor->processInbound($path, $request); - $request->attributes->set('_system_path', $path); + $this->currentPath->setPath('/' . $path, $request); // Set the cache key on the alias manager cache decorator. if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) { diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php index f2c888def7a709dc6965ae6727e5b6dbd2ae7056..a9bd0acd0151bfc3eef0dcc05fb6924d51e610d2 100644 --- a/core/lib/Drupal/Core/Form/FormSubmitter.php +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php @@ -137,12 +137,7 @@ public function redirectForm(FormStateInterface $form_state) { // If no redirect was specified, redirect to the current path. elseif ($redirect === NULL) { $request = $this->requestStack->getCurrentRequest(); - // @todo Remove dependency on the internal _system_path attribute: - // https://www.drupal.org/node/2293521. - $url = $this->urlGenerator->generateFromPath($request->attributes->get('_system_path'), array( - 'query' => $request->query->all(), - 'absolute' => TRUE, - )); + $url = $this->urlGenerator->generateFromRoute('<current>', [], ['query' => $request->query->all(), 'absolute' => TRUE]); } if ($url) { diff --git a/core/lib/Drupal/Core/Path/CurrentPathStack.php b/core/lib/Drupal/Core/Path/CurrentPathStack.php new file mode 100644 index 0000000000000000000000000000000000000000..d7abdb182a0607fc318235223a3cbbb4e8e7f055 --- /dev/null +++ b/core/lib/Drupal/Core/Path/CurrentPathStack.php @@ -0,0 +1,84 @@ +<?php + +/** + * @file + * Contains \Drupal\Core\Path\CurrentPathStack. + */ + +namespace Drupal\Core\Path; +use Symfony\Component\HttpFoundation\RequestStack; + +/** + * Represents the current path for the current request. + * + * Note: You should not rely on paths but rather on route names / parameters or + * other indicators like context. For some fundamental parts, like routing or + * path processing, there is unfortunately no way around dealing with paths. + */ +class CurrentPathStack { + + /** + * Static cache of paths. + * + * @var \SplObjectStorage + */ + protected $paths; + + /** + * The request stack. + * + * @var \Symfony\Component\HttpFoundation\RequestStack + */ + protected $requestStack; + + /** + * Constructs a new CurrentPathStack instance. + * + * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack + * The request stack. + */ + public function __construct(RequestStack $request_stack) { + $this->requestStack = $request_stack; + $this->paths = new \SplObjectStorage(); + } + + /** + * Returns the path of the current request. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * (optional) The request. + * + * @return string + * Returns the path, without leading slashes. + */ + public function getPath($request = NULL) { + if (!isset($request)) { + $request = $this->requestStack->getCurrentRequest(); + } + if (!isset($this->paths[$request])) { + $this->paths[$request] = $request->getPathInfo(); + } + + return $this->paths[$request]; + } + + /** + * Sets the current path. + * + * @param string $path + * The path. + * @param \Symfony\Component\HttpFoundation\Request $request + * (optional) The request. + * + * @return $this + */ + public function setPath($path, $request = NULL) { + if (!isset($request)) { + $request = $this->requestStack->getCurrentRequest(); + } + $this->paths[$request] = $path; + + return $this; + } + +} diff --git a/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php b/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php index e4bc705df714b5f9f5bd1f2271c5cdac25602a1b..1a00b211b062978e03d62a0b3788f22169116423 100644 --- a/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php +++ b/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php @@ -36,12 +36,18 @@ public function __construct(RouteMatchInterface $route_match) { * {@inheritdoc} */ public function processOutbound($route_name, Route $route, array &$parameters) { - if (($route_name === '<current>') && ($current_route = $this->routeMatch->getRouteObject())) { - $route->setPath($current_route->getPath()); - $route->setRequirements($current_route->getRequirements()); - $route->setOptions($current_route->getOptions()); - $route->setDefaults($current_route->getDefaults()); - $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all()); + if ($route_name === '<current>') { + if ($current_route = $this->routeMatch->getRouteObject()) { + $route->setPath($current_route->getPath()); + $route->setRequirements($current_route->getRequirements()); + $route->setOptions($current_route->getOptions()); + $route->setDefaults($current_route->getDefaults()); + $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all()); + } + else { + // If we have no current route match available, point to the frontpage. + $route->setPath('/'); + } } } diff --git a/core/lib/Drupal/Core/Routing/RouteProvider.php b/core/lib/Drupal/Core/Routing/RouteProvider.php index 26ff91d8f2dd49e1a1948f1823da403470bd3ab2..58e390f2e445e6f636a6118bdcd1d0826d773145 100644 --- a/core/lib/Drupal/Core/Routing/RouteProvider.php +++ b/core/lib/Drupal/Core/Routing/RouteProvider.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Routing; use Drupal\Component\Utility\String; +use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\State\StateInterface; use Symfony\Cmf\Component\Routing\PagedRouteCollection; use Symfony\Cmf\Component\Routing\PagedRouteProviderInterface; @@ -59,6 +60,13 @@ class RouteProvider implements RouteProviderInterface, PagedRouteProviderInterfa */ protected $routes = array(); + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + /** * Constructs a new PathMatcher. * @@ -68,14 +76,17 @@ class RouteProvider implements RouteProviderInterface, PagedRouteProviderInterfa * The route builder. * @param \Drupal\Core\State\StateInterface $state * The state. + * @param \Drupal\Core\Path\CurrentPathStack $current_path + * THe current path. * @param string $table * The table in the database to use for matching. */ - public function __construct(Connection $connection, RouteBuilderInterface $route_builder, StateInterface $state, $table = 'router') { + public function __construct(Connection $connection, RouteBuilderInterface $route_builder, StateInterface $state, CurrentPathStack $current_path, $table = 'router') { $this->connection = $connection; $this->routeBuilder = $route_builder; $this->state = $state; $this->tableName = $table; + $this->currentPath = $current_path; } /** @@ -104,24 +115,9 @@ public function __construct(Connection $connection, RouteBuilderInterface $route * @todo Should this method's found routes also be included in the cache? */ public function getRouteCollectionForRequest(Request $request) { + $path = $this->currentPath->getPath($request); - // The '_system_path' has language prefix stripped and path alias resolved, - // whereas getPathInfo() returns the requested path. In Drupal, the request - // always contains a system_path attribute, but this component may get - // adopted by non-Drupal projects. Some unit tests also skip initializing - // '_system_path'. - // @todo Consider abstracting this to a separate object. - if ($request->attributes->has('_system_path')) { - // _system_path never has leading or trailing slashes. - $path = '/' . $request->attributes->get('_system_path'); - } - else { - // getPathInfo() always has leading slash, and might or might not have a - // trailing slash. - $path = rtrim($request->getPathInfo(), '/'); - } - - $collection = $this->getRoutesByPath($path); + $collection = $this->getRoutesByPath(rtrim($path, '/')); // Try rebuilding the router if it is necessary. if (!$collection->count() && $this->routeBuilder->rebuildIfNeeded()) { diff --git a/core/lib/Drupal/Core/Routing/UrlMatcher.php b/core/lib/Drupal/Core/Routing/UrlMatcher.php index a7ed9e8dd0409f819bf7300631f234567b2d478d..dbd95d35f532c9da85f9f42905bcc77561686a00 100644 --- a/core/lib/Drupal/Core/Routing/UrlMatcher.php +++ b/core/lib/Drupal/Core/Routing/UrlMatcher.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Routing; +use Drupal\Core\Path\CurrentPathStack; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\RouteCollection; use Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher as BaseUrlMatcher; @@ -16,29 +17,33 @@ */ class UrlMatcher extends BaseUrlMatcher { + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + /** * Constructs a new UrlMatcher. * * The parent class has a constructor we need to skip, so just override it * with a no-op. + * + * @param \Drupal\Core\Path\CurrentPathStack $current_path + * The current path. */ - public function __construct() {} + public function __construct(CurrentPathStack $current_path) { + $this->currentPath = $current_path; + } public function finalMatch(RouteCollection $collection, Request $request) { $this->routes = $collection; $context = new RequestContext(); $context->fromRequest($request); $this->setContext($context); - if ($request->attributes->has('_system_path')) { - // _system_path never has leading or trailing slashes. - $path = '/' . $request->attributes->get('_system_path'); - } - else { - // getPathInfo() always has leading slash, and might or might not have a - // trailing slash. - $path = rtrim($request->getPathInfo(), '/'); - } - return $this->match($path); + + return $this->match($this->currentPath->getPath($request)); } } diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php index 6080d6b8f2a8c8cff612821e1f7d7fb7da799744..9af26384a3a9b952faedf74506c35e5250ea1c45 100644 --- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php +++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php @@ -14,6 +14,7 @@ use Drupal\Core\Controller\TitleResolverInterface; use Drupal\Core\Link; use Drupal\Core\ParamConverter\ParamNotConvertedException; +use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\Routing\RequestContext; use Drupal\Core\Routing\RouteMatch; @@ -99,8 +100,10 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { * The title resolver service. * @param \Drupal\Core\Session\AccountInterface $current_user * The current user object. + * @param \Drupal\Core\Path\CurrentPathStack $current_path + * The current path. */ - public function __construct(RequestContext $context, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactoryInterface $config_factory, TitleResolverInterface $title_resolver, AccountInterface $current_user) { + public function __construct(RequestContext $context, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactoryInterface $config_factory, TitleResolverInterface $title_resolver, AccountInterface $current_user, CurrentPathStack $current_path) { $this->context = $context; $this->accessManager = $access_manager; $this->router = $router; @@ -108,6 +111,7 @@ public function __construct(RequestContext $context, AccessManagerInterface $acc $this->config = $config_factory->get('system.site'); $this->titleResolver = $title_resolver; $this->currentUser = $current_user; + $this->currentPath = $current_path; } /** @@ -191,7 +195,7 @@ protected function getRequestForPath($path, array $exclude) { // This resolves to the front page, which we already add. return NULL; } - $request->attributes->set('_system_path', $processed); + $this->currentPath->setPath('/' . $processed, $request); // Attempt to match this path to provide a fully built request. try { $request->attributes->add($this->router->matchRequest($request)); diff --git a/core/modules/system/src/Plugin/Condition/RequestPath.php b/core/modules/system/src/Plugin/Condition/RequestPath.php index a5f56139d1b205075623af0d8879933bf286587d..a309c5840cf3bfcf3236de3bea21277e3cc07e59 100644 --- a/core/modules/system/src/Plugin/Condition/RequestPath.php +++ b/core/modules/system/src/Plugin/Condition/RequestPath.php @@ -11,6 +11,7 @@ use Drupal\Core\Condition\ConditionPluginBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Path\AliasManagerInterface; +use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\Path\PathMatcherInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; @@ -48,6 +49,13 @@ class RequestPath extends ConditionPluginBase implements ContainerFactoryPluginI */ protected $requestStack; + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + /** * Constructs a RequestPath condition plugin. * @@ -57,6 +65,8 @@ class RequestPath extends ConditionPluginBase implements ContainerFactoryPluginI * The path matcher service. * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * The request stack. + * @param \Drupal\Core\Path\CurrentPathStack $current_path + * The current path. * @param array $configuration * A configuration array containing information about the plugin instance. * @param string $plugin_id @@ -64,11 +74,12 @@ class RequestPath extends ConditionPluginBase implements ContainerFactoryPluginI * @param array $plugin_definition * The plugin implementation definition. */ - public function __construct(AliasManagerInterface $alias_manager, PathMatcherInterface $path_matcher, RequestStack $request_stack, array $configuration, $plugin_id, array $plugin_definition) { + public function __construct(AliasManagerInterface $alias_manager, PathMatcherInterface $path_matcher, RequestStack $request_stack, CurrentPathStack $current_path, array $configuration, $plugin_id, array $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->aliasManager = $alias_manager; $this->pathMatcher = $path_matcher; $this->requestStack = $request_stack; + $this->currentPath = $current_path; } /** @@ -79,6 +90,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('path.alias_manager'), $container->get('path.matcher'), $container->get('request_stack'), + $container->get('path.current'), $configuration, $plugin_id, $plugin_definition); @@ -141,9 +153,7 @@ public function evaluate() { $request = $this->requestStack->getCurrentRequest(); // Compare the lowercase path alias (if any) and internal path. - // @todo Remove dependency on the internal _system_path attribute: - // https://www.drupal.org/node/2293581. - $path = $request->attributes->get('_system_path'); + $path = trim($this->currentPath->getPath($request), '/'); $path_alias = Unicode::strtolower($this->aliasManager->getAliasByPath($path)); return $this->pathMatcher->matchPath($path_alias, $pages) || (($path != $path_alias) && $this->pathMatcher->matchPath($path, $pages)); diff --git a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php index a80e50fe492fac0205f53726aa8bd3c04b600fc7..8d6cb65846fcf28af1d1a2f7f01da5a64a5b694f 100644 --- a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php +++ b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php @@ -217,6 +217,11 @@ private function formSubmitHelper($form, $edit) { $form['#token'] = FALSE; $edit['form_id'] = $form_id; + + // Disable page redirect for forms submitted programmatically. This is a + // solution to skip the redirect step (there are no pages, then the redirect + // isn't possible). + $form_state->disableRedirect(); $form_state->setUserInput($edit); $form_state->setFormObject(new StubForm($form_id, $form)); diff --git a/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php b/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php index c1d4b2ac76b97ba341ee2b4e375c58fdb26d9f16..45011f8e48249fa07dc1a18a42e99ad52a458d28 100644 --- a/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php +++ b/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Plugin\Condition; +use Drupal\Core\Path\CurrentPathStack; use Drupal\simpletest\KernelTestBase; use Drupal\system\Tests\Routing\MockAliasManager; use Symfony\Component\HttpFoundation\Request; @@ -48,6 +49,13 @@ class RequestPathTest extends KernelTestBase { */ public static $modules = array('system', 'user', 'field', 'path'); + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack|\PHPUnit_Framework_MockObject_MockObject + */ + protected $currentPath; + /** * {@inheritdoc} */ @@ -65,6 +73,9 @@ protected function setUp() { // Set the test request stack in the container. $this->requestStack = new RequestStack(); $this->container->set('request_stack', $this->requestStack); + + $this->currentPath = new CurrentPathStack($this->requestStack); + $this->container->set('path.current', $this->currentPath); } /** @@ -78,7 +89,6 @@ public function testConditions() { $pages = "my/pass/page\r\nmy/pass/page2\r\nfoo"; $request = Request::create('/my/pass/page2'); - $request->attributes->set('_system_path', 'my/pass/page2'); $this->requestStack->push($request); /* @var \Drupal\system\Plugin\Condition\RequestPath $condition */ @@ -91,7 +101,7 @@ public function testConditions() { $this->assertEqual($condition->summary(), 'Return true on the following pages: my/pass/page, my/pass/page2, foo', 'The condition summary matches for a standard path'); // Test an aliased path. - $request->attributes->set('_system_path', 'my/aliased/page'); + $this->currentPath->setPath('/my/aliased/page', $request); $this->requestStack->pop(); $this->requestStack->push($request); @@ -102,7 +112,7 @@ public function testConditions() { // Test a wildcard path. $this->aliasManager->addAlias('my/pass/page3', 'my/pass/page3'); - $request->attributes->set('_system_path', 'my/pass/page3'); + $this->currentPath->setPath('/my/pass/page3', $request); $this->requestStack->pop(); $this->requestStack->push($request); @@ -112,9 +122,9 @@ public function testConditions() { $this->assertEqual($condition->summary(), 'Return true on the following pages: my/pass/*', 'The condition summary matches for a wildcard path'); // Test a missing path. - $request->attributes->set('_system_path', 'my/fail/page4'); $this->requestStack->pop(); $this->requestStack->push($request); + $this->currentPath->setPath('/my/fail/page4', $request); $condition->setConfig('pages', 'my/pass/*'); diff --git a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php index d21d834d87ed694d835a0ebe807a7bab71bb5f18..d8e8606b639f5ba2a126a0503b8e1615d033971f 100644 --- a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php +++ b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php @@ -96,6 +96,20 @@ public function testProcessOutbound() { $request_stack->push($request); $request_context->fromRequest($request); $this->assertEqual('/node/add', \Drupal::url('<current>')); + + // Test request without a found route. This happens for example on an + // not found exception page. + $server = [ + 'SCRIPT_NAME' => '/index.php', + 'SCRIPT_FILENAME' => \Drupal::root() . '/index.php', + 'SERVER_NAME' => 'http://www.example.com', + ]; + $request = Request::create('/invalid-path', 'GET', [], [], [], $server); + + $request_stack->push($request); + $request_context->fromRequest($request); + // In case we have no routing, the current route should point to the front. + $this->assertEqual('/', \Drupal::url('<current>')); } } diff --git a/core/modules/system/src/Tests/Routing/RouteProviderTest.php b/core/modules/system/src/Tests/Routing/RouteProviderTest.php index 6ba9f9743cd12ef96e8a955407c229a6853f5f63..080936be11012f72c6494c13c7777efe128ff075 100644 --- a/core/modules/system/src/Tests/Routing/RouteProviderTest.php +++ b/core/modules/system/src/Tests/Routing/RouteProviderTest.php @@ -8,9 +8,11 @@ namespace Drupal\system\Tests\Routing; use Drupal\Core\KeyValueStore\KeyValueMemoryFactory; +use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\State\State; use Drupal\simpletest\KernelTestBase; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -49,11 +51,19 @@ class RouteProviderTest extends KernelTestBase { */ protected $state; + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + protected function setUp() { parent::setUp(); $this->fixtures = new RoutingFixtures(); $this->routeBuilder = new NullRouteBuilder(); $this->state = new State(new KeyValueMemoryFactory()); + $this->currentPath = new CurrentPathStack(new RequestStack()); } protected function tearDown() { @@ -68,7 +78,7 @@ protected function tearDown() { public function testCandidateOutlines() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $parts = array('node', '5', 'edit'); @@ -91,7 +101,7 @@ public function testCandidateOutlines() { */ function testExactPathMatch() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -115,7 +125,7 @@ function testExactPathMatch() { */ function testOutlinePathMatch() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -144,7 +154,7 @@ function testOutlinePathMatch() { */ function testOutlinePathMatchTrailingSlash() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -173,7 +183,7 @@ function testOutlinePathMatchTrailingSlash() { */ function testOutlinePathMatchDefaults() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -211,7 +221,7 @@ function testOutlinePathMatchDefaults() { */ function testOutlinePathMatchDefaultsCollision() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -250,7 +260,7 @@ function testOutlinePathMatchDefaultsCollision() { */ function testOutlinePathMatchDefaultsCollision2() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -289,7 +299,7 @@ function testOutlinePathMatchDefaultsCollision2() { */ public function testOutlinePathMatchZero() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -324,7 +334,7 @@ public function testOutlinePathMatchZero() { */ function testOutlinePathNoMatch() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -345,11 +355,11 @@ function testOutlinePathNoMatch() { } /** - * Confirms that _system_path attribute overrides request path. + * Ensures a path set on the current path services overrides the request one. */ - function testSystemPathMatch() { + function testCurrentPath() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -358,7 +368,7 @@ function testSystemPathMatch() { $dumper->dump(); $request = Request::create('/path/one', 'GET'); - $request->attributes->set('_system_path', 'path/two'); + $this->currentPath->setPath('/path/two', $request); $routes_by_pattern = $provider->getRoutesByPattern('/path/two'); $routes = $provider->getRouteCollectionForRequest($request); @@ -374,7 +384,7 @@ function testSystemPathMatch() { */ protected function testRouteByName() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); @@ -409,7 +419,7 @@ protected function testRouteByName() { */ public function testGetRoutesByPatternWithLongPatterns() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); // This pattern has only 3 parts, so we will get candidates, but no routes, @@ -467,7 +477,7 @@ public function testGetRoutesByPatternWithLongPatterns() { */ public function testGetRoutesPaged() { $connection = Database::getConnection(); - $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, $this->currentPath, 'test_routes'); $this->fixtures->createTables($connection); $dumper = new MatcherDumper($connection, $this->state, 'test_routes'); diff --git a/core/modules/system/system.services.yml b/core/modules/system/system.services.yml index 2a21015d33687a6b8921a3c7e25d216a9e2b3a56..223f442ab16caf2e8759886cd62ca664adf84720 100644 --- a/core/modules/system/system.services.yml +++ b/core/modules/system/system.services.yml @@ -12,7 +12,7 @@ services: arguments: ['@module_handler', '@entity.manager', '@request_stack', '@menu.link_tree', '@menu.active_trail'] system.breadcrumb.default: class: Drupal\system\PathBasedBreadcrumbBuilder - arguments: ['@router.request_context', '@access_manager', '@router', '@path_processor_manager', '@config.factory', '@title_resolver', '@current_user'] + arguments: ['@router.request_context', '@access_manager', '@router', '@path_processor_manager', '@config.factory', '@title_resolver', '@current_user', '@path.current'] tags: - { name: breadcrumb_builder, priority: 0 } path_processor.files: diff --git a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php index b4e4393a8b0185db49c84f45e3ff62e632bb1f56..788f35acee2928eddcb9521b7d7d3ccdd1536371 100644 --- a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php +++ b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php @@ -8,6 +8,7 @@ namespace Drupal\theme_test\EventSubscriber; use Drupal\Core\Url; +use Drupal\Core\Routing\RouteMatchInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -24,6 +25,21 @@ class ThemeTestSubscriber implements EventSubscriberInterface { */ protected $container; + /** + * The current route match. + * + * @var \Drupal\Core\Routing\RouteMatchInterface + */ + protected $currentRouteMatch; + + /** + * Constructs a new ThemeTestSubscriber. + * + * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match + */ + public function __construct(RouteMatchInterface $current_route_match) { + $this->currentRouteMatch = $current_route_match; + } /** * Generates themed output early in a page request. @@ -31,9 +47,7 @@ class ThemeTestSubscriber implements EventSubscriberInterface { * @see \Drupal\system\Tests\Theme\ThemeEarlyInitializationTest::testRequestListener() */ public function onRequest(GetResponseEvent $event) { - $request = $event->getRequest(); - $current_path = $request->attributes->get('_system_path'); - if ($current_path == 'theme-test/request-listener') { + if ($this->currentRouteMatch->getRouteName() === 'theme_test.request_listener') { // First, force the theme registry to be rebuilt on this page request. // This allows us to test a full initialization of the theme system in // the code below. @@ -56,9 +70,13 @@ public function onRequest(GetResponseEvent $event) { * Ensures that the theme registry was not initialized. */ public function onView(GetResponseEvent $event) { - $request = $event->getRequest(); - $current_path = $request->attributes->get('_system_path'); - if (strpos($current_path, 'user/autocomplete') === 0) { + $current_route = $this->currentRouteMatch->getRouteName(); + $user_autcomplete_route = array( + 'user.autocomplete', + 'user.autocomplete_anonymous', + ); + + if (in_array($current_route, $user_autcomplete_route)) { if ($this->container->initialized('theme.registry')) { throw new \Exception('registry initialized'); } diff --git a/core/modules/system/tests/modules/theme_test/theme_test.services.yml b/core/modules/system/tests/modules/theme_test/theme_test.services.yml index 69fd3ca7005764b3b11c653eb88a2b145ec238c8..add8b4cec3a24aa387b4464fdbb9f1d3c0009400 100644 --- a/core/modules/system/tests/modules/theme_test/theme_test.services.yml +++ b/core/modules/system/tests/modules/theme_test/theme_test.services.yml @@ -1,6 +1,7 @@ services: theme_test.subscriber: class: Drupal\theme_test\EventSubscriber\ThemeTestSubscriber + arguments: [@current_route_match] tags: - { name: event_subscriber } diff --git a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php index fb530299c40f10d585592f6adab54c29b790933d..68e1abf1f19672dd0542ea1311efe1a5e227600e 100644 --- a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php +++ b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php @@ -76,6 +76,13 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { */ protected $pathProcessor; + /** + * The mocked current path. + * + * @var \Drupal\Core\Path\CurrentPathStack|\PHPUnit_Framework_MockObject_MockObject + */ + protected $currentPath; + /** * {@inheritdoc} * @@ -94,6 +101,10 @@ protected function setUp() { $this->accessManager = $this->getMock('\Drupal\Core\Access\AccessManagerInterface'); $this->titleResolver = $this->getMock('\Drupal\Core\Controller\TitleResolverInterface'); $this->currentUser = $this->getMock('Drupal\Core\Session\AccountInterface'); + $this->currentPath = $this->getMockBuilder('Drupal\Core\Path\CurrentPathStack') + ->disableOriginalConstructor() + ->getMock(); + $this->builder = new TestPathBasedBreadcrumbBuilder( $this->context, $this->accessManager, @@ -101,7 +112,8 @@ protected function setUp() { $this->pathProcessor, $config_factory, $this->titleResolver, - $this->currentUser + $this->currentUser, + $this->currentPath ); $this->builder->setStringTranslation($this->getStringTranslationStub()); diff --git a/core/modules/views/src/Controller/ViewAjaxController.php b/core/modules/views/src/Controller/ViewAjaxController.php index e938ef81b623a1141286210173fa23d72b1b93b1..536e10a14600f30a6f50d0f425a25cb4a2dd5fdd 100644 --- a/core/modules/views/src/Controller/ViewAjaxController.php +++ b/core/modules/views/src/Controller/ViewAjaxController.php @@ -12,6 +12,7 @@ use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\Render\RendererInterface; use Drupal\views\Ajax\ScrollTopCommand; use Drupal\views\Ajax\ViewAjaxResponse; @@ -47,6 +48,13 @@ class ViewAjaxController implements ContainerInjectionInterface { */ protected $renderer; + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + /** * Constructs a ViewAjaxController object. * @@ -56,11 +64,14 @@ class ViewAjaxController implements ContainerInjectionInterface { * The factory to load a view executable with. * @param \Drupal\Core\Render\RendererInterface $renderer * The renderer. + * @param \Drupal\Core\Path\CurrentPathStack $current_path + * The current path. */ - public function __construct(EntityStorageInterface $storage, ViewExecutableFactory $executable_factory, RendererInterface $renderer) { + public function __construct(EntityStorageInterface $storage, ViewExecutableFactory $executable_factory, RendererInterface $renderer, CurrentPathStack $current_path) { $this->storage = $storage; $this->executableFactory = $executable_factory; $this->renderer = $renderer; + $this->currentPath = $current_path; } /** @@ -70,7 +81,8 @@ public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager')->getStorage('view'), $container->get('views.executable'), - $container->get('renderer') + $container->get('renderer'), + $container->get('path.current') ); } @@ -123,7 +135,7 @@ public function ajaxView(Request $request) { $response->setView($view); // Fix the current path for paging. if (!empty($path)) { - $request->attributes->set('_system_path', $path); + $this->currentPath->setPath('/' . $path, $request); } // Add all POST data, because AJAX is always a post and many things, diff --git a/core/modules/views/src/Plugin/views/argument_default/Raw.php b/core/modules/views/src/Plugin/views/argument_default/Raw.php index 9d194e5d6fac2477468293fb24359745e2860eaf..4239c50e2f5e5896d062f2412ae73cdbdc6833c4 100644 --- a/core/modules/views/src/Plugin/views/argument_default/Raw.php +++ b/core/modules/views/src/Plugin/views/argument_default/Raw.php @@ -9,6 +9,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Path\AliasManagerInterface; +use Drupal\Core\Path\CurrentPathStack; use Drupal\views\Plugin\CacheablePluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -32,6 +33,13 @@ class Raw extends ArgumentDefaultPluginBase implements CacheablePluginInterface */ protected $aliasManager; + /** + * The current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + /** * Constructs a Raw object. * @@ -43,11 +51,14 @@ class Raw extends ArgumentDefaultPluginBase implements CacheablePluginInterface * The plugin implementation definition. * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager * The alias manager. + * @param \Drupal\Core\Path\CurrentPathStack $current_path + * The current path. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, AliasManagerInterface $alias_manager) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, AliasManagerInterface $alias_manager, CurrentPathStack $current_path) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->aliasManager = $alias_manager; + $this->currentPath = $current_path; } /** @@ -58,7 +69,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('path.alias_manager') + $container->get('path.alias_manager'), + $container->get('path.current') ); } @@ -91,9 +103,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } public function getArgument() { - // @todo Remove dependency on the internal _system_path attribute: - // https://www.drupal.org/node/2293581. - $path = $this->view->getRequest()->attributes->get('_system_path'); + $path = trim($this->currentPath->getPath($this->view->getRequest()), '/'); if ($this->options['use_alias']) { $path = $this->aliasManager->getAliasByPath($path); } diff --git a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php index 7e09cb49ae5f09e4f4a04cb6df17b3937a7b1f88..61e475b6a11b92cd384fc7178aac735dd66f846d 100644 --- a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php +++ b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php @@ -40,6 +40,13 @@ class ViewAjaxControllerTest extends UnitTestCase { */ protected $viewAjaxController; + /** + * The mocked current path. + * + * @var \Drupal\Core\Path\CurrentPathStack|\PHPUnit_Framework_MockObject_MockObject + */ + protected $currentPath; + protected function setUp() { $this->viewStorage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); $this->executableFactory = $this->getMockBuilder('Drupal\views\ViewExecutableFactory') @@ -52,8 +59,11 @@ protected function setUp() { $elements['#attached'] = []; return isset($elements['#markup']) ? $elements['#markup'] : ''; })); + $this->currentPath = $this->getMockBuilder('Drupal\Core\Path\CurrentPathStack') + ->disableOriginalConstructor() + ->getMock(); - $this->viewAjaxController = new ViewAjaxController($this->viewStorage, $this->executableFactory, $this->renderer); + $this->viewAjaxController = new ViewAjaxController($this->viewStorage, $this->executableFactory, $this->renderer, $this->currentPath); } /** diff --git a/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php b/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php index 2d1df0ee2ae879588c6a33eae45549dc48a288db..f50b928f4d8969eb37b1435bcc523174453ff0a5 100644 --- a/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php @@ -7,9 +7,11 @@ namespace Drupal\Tests\views\Unit\Plugin\argument_default; +use Drupal\Core\Path\CurrentPathStack; use Drupal\Tests\UnitTestCase; use Drupal\views\Plugin\views\argument_default\Raw; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; /** * @coversDefaultClass \Drupal\views\Plugin\views\argument_default\Raw @@ -29,8 +31,10 @@ public function testGetArgument() { $display_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase') ->disableOriginalConstructor() ->getMock(); + $current_path = new CurrentPathStack(new RequestStack()); - $request = new Request(array(), array(), array('_system_path' => 'test/example')); + $request = new Request(); + $current_path->setPath('/test/example', $request); $view->expects($this->any()) ->method('getRequest') ->will($this->returnValue($request)); @@ -39,7 +43,7 @@ public function testGetArgument() { ->method('getAliasByPath'); // Don't use aliases. - $raw = new Raw(array(), 'raw', array(), $alias_manager); + $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); $options = array( 'use_alias' => FALSE, 'index' => 0, @@ -47,7 +51,7 @@ public function testGetArgument() { $raw->init($view, $display_plugin, $options); $this->assertEquals('test', $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager); + $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); $options = array( 'use_alias' => FALSE, 'index' => 1, @@ -62,7 +66,7 @@ public function testGetArgument() { ->with($this->equalTo('test/example')) ->will($this->returnValue('other/example')); - $raw = new Raw(array(), 'raw', array(), $alias_manager); + $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); $options = array( 'use_alias' => TRUE, 'index' => 0, @@ -70,7 +74,7 @@ public function testGetArgument() { $raw->init($view, $display_plugin, $options); $this->assertEquals('other', $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager); + $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); $options = array( 'use_alias' => TRUE, 'index' => 1, diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php index 1de4249cf7037389b54c6e189959537f7ec538d4..5b73c85f819b9d8df6e3a3d71f433c53bd70d563 100644 --- a/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php +++ b/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php @@ -60,7 +60,7 @@ class CustomPageExceptionHtmlSubscriberTest extends UnitTestCase { /** * The tested custom page exception subscriber. * - * @var \Drupal\Core\EventSubscriber\CustomPageExceptionHtmlSubscriber + * @var \Drupal\Core\EventSubscriber\CustomPageExceptionHtmlSubscriber|\Drupal\Tests\Core\EventSubscriber\TestCustomPageExceptionHtmlSubscriber */ protected $customPageSubscriber; @@ -73,7 +73,7 @@ protected function setUp() { $this->aliasManager = $this->getMock('Drupal\Core\Path\AliasManagerInterface'); $this->kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'); $this->logger = $this->getMock('Psr\Log\LoggerInterface'); - $this->customPageSubscriber = new CustomPageExceptionHtmlSubscriber($this->configFactory, $this->aliasManager, $this->kernel, $this->logger); + $this->customPageSubscriber = new TestCustomPageExceptionHtmlSubscriber($this->configFactory, $this->aliasManager, $this->kernel, $this->logger); // You can't create an exception in PHP without throwing it. Store the // current error_log, and disable it temporarily. @@ -124,7 +124,6 @@ public function testHandleWithGetRequest() { $this->setupStubAliasManager(); $request = Request::create('/test', 'GET', array('name' => 'druplicon', 'pass' => '12345')); - $request->attributes->set('_system_path', 'test'); $this->kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) { return new Response($request->getMethod() . ' ' . UrlHelper::buildQuery($request->query->all())); @@ -139,3 +138,14 @@ public function testHandleWithGetRequest() { } } + +class TestCustomPageExceptionHtmlSubscriber extends CustomPageExceptionHtmlSubscriber { + + /** + * {@inheritdoc} + */ + protected function drupalGetDestination() { + return ['destination' => 'test']; + } + +} diff --git a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php index ff2b2cd3a0858fe9dd1f9ec4ae85fc6b11641326..4e7e85ca65bd815ebb44b3d0ce01784462797e3d 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php @@ -102,17 +102,20 @@ public function providerTestHandleFormSubmissionWithResponses() { */ public function testRedirectWithNull() { $form_submitter = $this->getFormSubmitter(); - $this->urlGenerator->expects($this->once()) - ->method('generateFromPath') - ->with(NULL, array('query' => array(), 'absolute' => TRUE)) - ->willReturn('<front>'); $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface'); $form_state->expects($this->once()) ->method('getRedirect') ->willReturn(NULL); + + $this->urlGenerator->expects($this->once()) + ->method('generateFromRoute') + ->with('<current>', [], ['query' => [], 'absolute' => TRUE]) + ->willReturn('http://localhost/test-path'); + $redirect = $form_submitter->redirectForm($form_state); - $this->assertSame('<front>', $redirect->getTargetUrl()); + // If we have no redirect, we redirect to the current URL. + $this->assertSame('http://localhost/test-path', $redirect->getTargetUrl()); $this->assertSame(303, $redirect->getStatusCode()); } @@ -234,7 +237,7 @@ public function testExecuteSubmitHandlers() { */ protected function getFormSubmitter() { $request_stack = new RequestStack(); - $request_stack->push(new Request()); + $request_stack->push(Request::create('/test-path')); return $this->getMockBuilder('Drupal\Core\Form\FormSubmitter') ->setConstructorArgs(array($request_stack, $this->urlGenerator)) ->setMethods(array('batchGet', 'drupalInstallationAttempted'))