diff --git a/core/modules/tour/lib/Drupal/tour/Entity/Tour.php b/core/modules/tour/lib/Drupal/tour/Entity/Tour.php index 7008a9b..1dd37ad 100644 --- a/core/modules/tour/lib/Drupal/tour/Entity/Tour.php +++ b/core/modules/tour/lib/Drupal/tour/Entity/Tour.php @@ -10,6 +10,7 @@ use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\tour\TipsBag; use Drupal\tour\TourInterface; +use Symfony\Component\HttpFoundation\ParameterBag; /** * Defines the configured tour entity. @@ -85,10 +86,12 @@ public function __construct(array $values, $entity_type) { /** * {@inheritdoc} */ - public function getPaths() { - return $this->paths; + public function getRoutes() { + return $this->routes; } + + /** * {@inheritdoc} */ @@ -130,4 +133,32 @@ public function getExportProperties() { return $properties; } + /** + * {@inheritdoc} + */ + public function matchRoute($route_name, ParameterBag $route_params) { + static $keyed_routes; + if (!isset($keyed_routes)) { + $keyed_routes = array(); + foreach ($this->routes as $route) { + $keyed_routes[$route['route_name']] = isset($route['route_params']) ? $route['route_params'] : array(); + } + } + if (!isset($keyed_routes[$route_name])) { + // We don't know about this route. + return FALSE; + } + if (empty($keyed_routes[$route_name])) { + // We don't need to worry about route params, the route name is enough. + return TRUE; + } + foreach ($keyed_routes[$route_name] as $key => $value) { + // If a required param is missing or doesn't match, return FALSE. + if (!$route_params->has($key) || $route_params->get($key) !== $value) { + return FALSE; + } + } + return TRUE; + } + } diff --git a/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php b/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php index 9f426e4..7a26ef4 100644 --- a/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php +++ b/core/modules/tour/lib/Drupal/tour/Tests/TourTest.php @@ -130,7 +130,7 @@ public function testTourFunctionality() { 'label' => 'Tour test english', 'langcode' => 'en', 'routes' => array( - 'tour_test.1', + array('route_name' => 'tour_test.1'), ), 'tips' => array( 'tour-test-1' => array( @@ -173,5 +173,25 @@ public function testTourFunctionality() { // Test hook_tour_alter(). $this->assertText('Altered by hook_tour_tips_alter'); + + // Navigate to tour-test-3 and verify the tour_test_1 tip is found with + // appropriate classes. + $this->drupalGet('tour-test-3/foo'); + $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./h2[contains(., :text)]]', array( + ':classes' => 'tip-module-tour-test tip-type-text tip-tour-test-1', + ':data_id' => 'tour-test-1', + ':text' => 'The first tip', + )); + $this->assertEqual(count($elements), 1, 'Found English variant of tip 1.'); + + // Navigate to tour-test-3 and verify the tour_test_1 tip is not found with + // appropriate classes. + $this->drupalGet('tour-test-3/bar'); + $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./h2[contains(., :text)]]', array( + ':classes' => 'tip-module-tour-test tip-type-text tip-tour-test-1', + ':data_id' => 'tour-test-1', + ':text' => 'The first tip', + )); + $this->assertEqual(count($elements), 0, 'Found English variant of tip 1.'); } } diff --git a/core/modules/tour/lib/Drupal/tour/TourInterface.php b/core/modules/tour/lib/Drupal/tour/TourInterface.php index d5e4135..7813201 100644 --- a/core/modules/tour/lib/Drupal/tour/TourInterface.php +++ b/core/modules/tour/lib/Drupal/tour/TourInterface.php @@ -8,6 +8,7 @@ namespace Drupal\tour; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Symfony\Component\HttpFoundation\ParameterBag; /** * Provides an interface defining a tour entity. @@ -15,12 +16,25 @@ interface TourInterface extends ConfigEntityInterface { /** - * The paths that this tour will appear on. + * The routes that this tour will appear on. * * @return array - * Returns array of paths for the tour. + * Returns array of routes for the tour. */ - public function getPaths(); + public function getRoutes(); + + /** + * Whether the tour matches a given set of route parameters. + * + * @param string $route_name + * The route name the parameters are for. + * @param \Symfony\Component\HttpFoundation\ParameterBag $route_params + * Parameter bag of raw route params. + * + * @return bool + * TRUE if the tour matches the route parameters. + */ + public function matchRoute($route_name, ParameterBag $route_params); /** * Returns tip plugin. diff --git a/core/modules/tour/tests/tour_test/config/tour.tour.tour-test-2.yml b/core/modules/tour/tests/tour_test/config/tour.tour.tour-test-2.yml index 425789f..0b93fa6 100644 --- a/core/modules/tour/tests/tour_test/config/tour.tour.tour-test-2.yml +++ b/core/modules/tour/tests/tour_test/config/tour.tour.tour-test-2.yml @@ -3,7 +3,7 @@ module: tour_test label: Tour test english langcode: en routes: - - tour_test.2 + - { route_name: tour_test.2 } tips: tour-test-2: id: tour-test-2 diff --git a/core/modules/tour/tests/tour_test/config/tour.tour.tour-test.yml b/core/modules/tour/tests/tour_test/config/tour.tour.tour-test.yml index 5b8ba2b..54e2bfe 100644 --- a/core/modules/tour/tests/tour_test/config/tour.tour.tour-test.yml +++ b/core/modules/tour/tests/tour_test/config/tour.tour.tour-test.yml @@ -3,7 +3,8 @@ module: tour_test label: Tour test english langcode: en routes: - - tour_test.1 + - { route_name: tour_test.1 } + - { route_name: tour_test.3, route_params: { locale: foo } } tips: tour-test-1: id: tour-test-1 diff --git a/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php b/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php index 126be87..30e1602 100644 --- a/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php +++ b/core/modules/tour/tests/tour_test/lib/Drupal/tour_test/Controller/TourTestController.php @@ -23,8 +23,15 @@ public static function create(ContainerInterface $container) { /** * Outputs some content for testing tours. + * + * @param string $locale + * (optional) Dummy locale variable for testing routing parameters. Defaults + * to 'foo'. + * + * @return array + * Array of markup. */ - public function tourTest1() { + public function tourTest1($locale = 'foo') { return array( 'tip-1' => array( '#type' => 'container', diff --git a/core/modules/tour/tests/tour_test/tour_test.routing.yml b/core/modules/tour/tests/tour_test/tour_test.routing.yml index 32f934d..5e4d254 100644 --- a/core/modules/tour/tests/tour_test/tour_test.routing.yml +++ b/core/modules/tour/tests/tour_test/tour_test.routing.yml @@ -18,3 +18,12 @@ tour_test.2: _content: '\Drupal\tour_test\Controller\TourTestController::tourTest2' requirements: _access: 'TRUE' + +tour_test.3: + path: '/tour-test-3/{locale}' + defaults: + locale: 'foo' + _content: '\Drupal\tour_test\Controller\TourTestController::tourTest1' + requirements: + _access: 'TRUE' + diff --git a/core/modules/tour/tour.module b/core/modules/tour/tour.module index af7ffc3..77fd0ea 100644 --- a/core/modules/tour/tour.module +++ b/core/modules/tour/tour.module @@ -110,12 +110,22 @@ function tour_preprocess_page(&$variables) { } // Load all of the items and match on route name. - $route_name = \Drupal::request()->attributes->get(RouteObjectInterface::ROUTE_NAME); + $request = \Drupal::request(); + $route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME); + $results = \Drupal::entityQuery('tour') - ->condition('routes.*', $route_name) + ->condition('routes.*.route_name', $route_name) ->execute(); if (!empty($results) && $tours = entity_load_multiple('tour', array_keys($results))) { - $variables['page']['help']['tour'] = entity_view_multiple($tours, 'full'); + foreach ($tours as $id => $tour) { + // Match on params. + if (!$tour->matchRoute($route_name, $request->attributes->get('_raw_variables'))) { + unset($tours[$id]); + } + } + if (!empty($tours)) { + $variables['page']['help']['tour'] = entity_view_multiple($tours, 'full'); + } } } diff --git a/core/modules/views_ui/config/tour.tour.views-ui.yml b/core/modules/views_ui/config/tour.tour.views-ui.yml index 8e2ec3e..98637b6 100644 --- a/core/modules/views_ui/config/tour.tour.views-ui.yml +++ b/core/modules/views_ui/config/tour.tour.views-ui.yml @@ -4,8 +4,8 @@ module: views_ui label: 'Views ui' langcode: en routes: - - views_ui.edit - - views_ui.edit_display + - { route_name: views_ui.edit } + - { route_name: views_ui.edit_display } tips: views-ui-active-display: id: views-ui-active-display