diff --git a/core/includes/path.inc b/core/includes/path.inc index dcf8ec0..82f884e 100644 --- a/core/includes/path.inc +++ b/core/includes/path.inc @@ -43,7 +43,8 @@ function drupal_is_front_page() { * \Drupal\Core\Path\PathMatcherInterface::matchPath() instead. */ function drupal_match_path($path, $patterns) { - return \Drupal::service('path_matcher')->matchPath($path, $patterns); + $patterns_array = preg_split('/(\r\n?|\n)/', $patterns); + return \Drupal::service('path_matcher')->matchPath($path, $patterns_array); } /** diff --git a/core/lib/Drupal/Core/Path/PathMatcher.php b/core/lib/Drupal/Core/Path/PathMatcher.php index 62aecc8..6aa4b57 100644 --- a/core/lib/Drupal/Core/Path/PathMatcher.php +++ b/core/lib/Drupal/Core/Path/PathMatcher.php @@ -41,8 +41,10 @@ public function __construct(ConfigFactory $config_factory) { /** * {@inheritdoc} */ - public function matchPath($path, $patterns) { - if (!isset($this->regexes[$patterns])) { + public function matchPath($path, array $patterns) { + // Convert array of patterns to a string with regex 'or'. + $pattern_string = implode("\n", $patterns); + if (!isset($this->regexes[$pattern_string])) { // Convert path settings to a regular expression. // Therefore replace newlines with a logical or, /* with asterisks and the // with the frontpage. @@ -56,9 +58,9 @@ public function matchPath($path, $patterns) { '.*', '\1' . preg_quote($this->frontPage, '/') . '\2', ); - $patterns_quoted = preg_quote($patterns, '/'); - $this->regexes[$patterns] = '/^(' . preg_replace($to_replace, $replacements, $patterns_quoted) . ')$/'; + $patterns_quoted = preg_quote($pattern_string, '/'); + $this->regexes[$pattern_string] = '/^(' . preg_replace($to_replace, $replacements, $patterns_quoted) . ')$/'; } - return (bool) preg_match($this->regexes[$patterns], $path); + return (bool) preg_match($this->regexes[$pattern_string], $path); } } diff --git a/core/lib/Drupal/Core/Path/PathMatcherInterface.php b/core/lib/Drupal/Core/Path/PathMatcherInterface.php index 9acf45f..091ef8f 100644 --- a/core/lib/Drupal/Core/Path/PathMatcherInterface.php +++ b/core/lib/Drupal/Core/Path/PathMatcherInterface.php @@ -17,12 +17,12 @@ * * @param string $path * The path to match. - * @param string $patterns - * String containing a set of patterns separated by \n, \r or \r\n. + * @param string[] $patterns + * A set of patterns. * * @return bool * TRUE if the path matches a pattern, FALSE otherwise. */ - public function matchPath($path, $patterns); + public function matchPath($path, array $patterns); } diff --git a/core/modules/system/lib/Drupal/system/Plugin/Core/Condition/RequestPath.php b/core/modules/system/lib/Drupal/system/Plugin/Core/Condition/RequestPath.php index fcc40a1..c1e5ef9 100644 --- a/core/modules/system/lib/Drupal/system/Plugin/Core/Condition/RequestPath.php +++ b/core/modules/system/lib/Drupal/system/Plugin/Core/Condition/RequestPath.php @@ -141,10 +141,12 @@ public function evaluate() { // Convert path to lowercase. This allows comparison of the same path // with different case. Ex: /Page, /page, /PAGE. $pages = Unicode::strtolower($this->configuration['pages']); + + $patterns = preg_split('/(\r\n?|\n)/', $pages); // Compare the lowercase path alias (if any) and internal path. $path = $this->request->attributes->get('system_path'); $path_alias = Unicode::strtolower($this->aliasManager->getPathAlias($path)); - return $this->pathMatcher->matchPath($path_alias, $pages) || (($path != $path_alias) && $this->pathMatcher->matchPath($path, $pages)); + return $this->pathMatcher->matchPath($path_alias, $patterns) || (($path != $path_alias) && $this->pathMatcher->matchPath($path, $patterns)); } /** diff --git a/core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php b/core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php new file mode 100644 index 0000000..b293b71 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php @@ -0,0 +1,83 @@ + 'Path Matcher tests', + 'description' => 'Tests that path matching is working properly.', + 'group' => 'Path', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + // Create a stub config factory with all config settings that will be + // checked during this test. + $config_factory_stub = $this->getConfigFactoryStub( + array( + 'system.site' => array( + 'page.front' => 'user', + ), + ) + ); + $this->pathMatcher = new PathMatcher($config_factory_stub); + $this->patterns = "my/pass/page\r\nmy/pass/page2\r\nfoo"; + } + + /** + * Test that standard paths works with multiple patterns. + */ + public function testPathsMultiplePatterns() { + $patterns = array('my/pass/page', 'my/pass/page2', 'foo'); + $this->assertTrue($this->pathMatcher->matchPath('my/pass/page', $patterns), 'The path my/pass/page matches.'); + $this->assertTrue($this->pathMatcher->matchPath('my/pass/page2', $patterns), 'The path my/pass/page2 matches.'); + } + + /** + * Test paths match against wildcards. + */ + public function testWildcardPath() { + $patterns = array('my/pass/*'); + $this->assertTrue($this->pathMatcher->matchPath('my/pass/page3', $patterns), 'The path my/pass/page3 matches.'); + } + + /** + * Test a missing path does not match. + */ + public function testNoMatchPath() { + $patterns = array('my/pass/page', 'my/pass/page2', 'foo'); + $this->assertFalse($this->pathMatcher->matchPath('my/pass/page4', $patterns), 'The path my/pass/page4 does not match.'); + } + +}