From 0e6ca116faf669132946ad07c0b699096d4570da Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 30 Nov 2014 23:51:46 +0100 Subject: [PATCH 01/13] Implementing routing stages pre-, main and post-stage --- libraries/cms/router/router.php | 76 +++++++++++++++++++++++-------- libraries/cms/router/site.php | 80 ++++++++++++++++++++------------- 2 files changed, 108 insertions(+), 48 deletions(-) diff --git a/libraries/cms/router/router.php b/libraries/cms/router/router.php index decd05ffb8622..8de5160d6d33f 100644 --- a/libraries/cms/router/router.php +++ b/libraries/cms/router/router.php @@ -63,8 +63,12 @@ class JRouter * @since 1.5 */ protected $rules = array( + 'buildpreprocess' => array(), 'build' => array(), - 'parse' => array() + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => array() ); /** @@ -75,8 +79,12 @@ class JRouter * @deprecated 4.0 Will convert to $rules */ protected $_rules = array( + 'buildpreprocess' => array(), 'build' => array(), - 'parse' => array() + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => array() ); /** @@ -175,8 +183,12 @@ public static function getInstance($client, $options = array()) */ public function parse(&$uri) { + // Do the preprocess stage of the URL build process + $vars = $this->processParseRules($uri, 'preprocess'); + // Process the parsed variables based on custom defined rules - $vars = $this->_processParseRules($uri); + // This is the main parse stage + $vars += $this->_processParseRules($uri); // Parse RAW URL if ($this->_mode == JROUTER_MODE_RAW) @@ -189,6 +201,9 @@ public function parse(&$uri) { $vars += $this->_parseSefRoute($uri); } + + // Do the postprocess stage of the URL build process + $vars = $this->processParseRules($uri, 'postprocess'); return array_merge($this->getVars(), $vars); } @@ -213,8 +228,12 @@ public function build($url) // Create the URI object $uri = $this->createURI($url); + + // Do the preprocess stage of the URL build process + $this->processBuildRules($uri, 'preprocess'); - // Process the uri information based on custom defined rules + // Process the uri information based on custom defined rules. + // This is the main build stage $this->_processBuildRules($uri); // Build RAW URL @@ -228,6 +247,9 @@ public function build($url) { $this->_buildSefRoute($uri); } + + // Do the postprocess stage of the URL build process + $this->processBuildRules($uri, 'postprocess'); $this->cache[$key] = clone $uri; @@ -338,28 +360,36 @@ public function getVars() * Attach a build rule * * @param callback $callback The function to be called + * @param string $stage The stage of the build process that + * this should be added to. Possible values: + * 'preprocess', '' for the main build process, + * 'postprocess' * * @return void * * @since 1.5 */ - public function attachBuildRule($callback) + public function attachBuildRule($callback, $stage = '') { - $this->_rules['build'][] = $callback; + $this->_rules['build' . $stage][] = $callback; } /** * Attach a parse rule * * @param callback $callback The function to be called. + * @param string $stage The stage of the parse process that + * this should be added to. Possible values: + * 'preprocess', '' for the main parse process, + * 'postprocess' * * @return void * * @since 1.5 */ - public function attachParseRule($callback) + public function attachParseRule($callback, $stage = '') { - $this->_rules['parse'][] = $callback; + $this->_rules['parse' . $stage][] = $callback; } /** @@ -370,7 +400,7 @@ public function attachParseRule($callback) * @return boolean * * @since 1.5 - * @deprecated 4.0 Use parseRawRoute() instead + * @deprecated 4.0 Attach your logic as rule to the main parse stage */ protected function _parseRawRoute(&$uri) { @@ -385,6 +415,7 @@ protected function _parseRawRoute(&$uri) * @return array Array of variables * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main parse stage */ protected function parseRawRoute(&$uri) { @@ -399,7 +430,7 @@ protected function parseRawRoute(&$uri) * @return string Internal URI * * @since 1.5 - * @deprecated 4.0 Use parseSefRoute() instead + * @deprecated 4.0 Attach your logic as rule to the main parse stage */ protected function _parseSefRoute(&$uri) { @@ -414,6 +445,7 @@ protected function _parseSefRoute(&$uri) * @return array Array of variables * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main parse stage */ protected function parseSefRoute(&$uri) { @@ -428,7 +460,7 @@ protected function parseSefRoute(&$uri) * @return string Raw Route * * @since 1.5 - * @deprecated 4.0 Use buildRawRoute() instead + * @deprecated 4.0 Attach your logic as rule to the main build stage */ protected function _buildRawRoute(&$uri) { @@ -443,6 +475,7 @@ protected function _buildRawRoute(&$uri) * @return string Raw Route * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main build stage */ protected function buildRawRoute(&$uri) { @@ -456,7 +489,7 @@ protected function buildRawRoute(&$uri) * @return string The SEF route * * @since 1.5 - * @deprecated 4.0 Use buildSefRoute() instead + * @deprecated 4.0 Attach your logic as rule to the main build stage */ protected function _buildSefRoute(&$uri) { @@ -471,6 +504,7 @@ protected function _buildSefRoute(&$uri) * @return string The SEF route * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main build stage */ protected function buildSefRoute(&$uri) { @@ -494,17 +528,20 @@ protected function _processParseRules(&$uri) /** * Process the parsed router variables based on custom defined rules * - * @param JUri &$uri The URI to parse + * @param JUri &$uri The URI to parse + * @param string $stage The stage that should be processed. + * Possible values: 'preprocess', 'postprocess' + * and '' for the main parse stage * * @return array The array of processed URI variables * * @since 3.2 */ - protected function processParseRules(&$uri) + protected function processParseRules(&$uri, $stage = '') { $vars = array(); - foreach ($this->_rules['parse'] as $rule) + foreach ($this->_rules['parse' . $stage] as $rule) { $vars += call_user_func_array($rule, array(&$this, &$uri)); } @@ -530,15 +567,18 @@ protected function _processBuildRules(&$uri) /** * Process the build uri query data based on custom defined rules * - * @param JUri &$uri The URI + * @param JUri &$uri The URI + * @param string $stage The stage that should be processed. + * Possible values: 'preprocess', 'postprocess' + * and '' for the main build stage * * @return void * * @since 3.2 */ - protected function processBuildRules(&$uri) + protected function processBuildRules(&$uri, $stage = '') { - foreach ($this->_rules['build'] as $rule) + foreach ($this->_rules['build' . $stage] as $rule) { call_user_func_array($rule, array(&$this, &$uri)); } diff --git a/libraries/cms/router/site.php b/libraries/cms/router/site.php index 9d326024a96f6..532ee87799a7c 100644 --- a/libraries/cms/router/site.php +++ b/libraries/cms/router/site.php @@ -176,6 +176,7 @@ public function build($url) * @return array * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main parse stage */ protected function parseRawRoute(&$uri) { @@ -235,6 +236,7 @@ protected function parseRawRoute(&$uri) * @return string Internal URI * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main parse stage */ protected function parseSefRoute(&$uri) { @@ -415,6 +417,7 @@ protected function parseSefRoute(&$uri) * @return string Raw Route * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main build stage */ protected function buildRawRoute(&$uri) { @@ -441,7 +444,7 @@ protected function buildRawRoute(&$uri) * @return void * * @since 1.5 - * @deprecated 4.0 Use buildSefRoute() instead + * @deprecated 4.0 Attach your logic as rule to the main build stage * @codeCoverageIgnore */ protected function _buildSefRoute(&$uri) @@ -457,6 +460,7 @@ protected function _buildSefRoute(&$uri) * @return void * * @since 3.2 + * @deprecated 4.0 Attach your logic as rule to the main build stage */ protected function buildSefRoute(&$uri) { @@ -531,23 +535,29 @@ protected function buildSefRoute(&$uri) * Process the parsed router variables based on custom defined rules * * @param JUri &$uri The URI to parse + * @param string $stage The stage that should be processed. + * Possible values: 'preprocess', 'postprocess' + * and '' for the main parse stage * * @return array The array of processed URI variables * * @since 3.2 */ - protected function processParseRules(&$uri) + protected function processParseRules(&$uri, $stage = '') { // Process the attached parse rules - $vars = parent::processParseRules($uri); + $vars = parent::processParseRules($uri, $stage); - // Process the pagination support - if ($this->_mode == JROUTER_MODE_SEF) + if ($stage == '') { - if ($start = $uri->getVar('start')) + // Process the pagination support + if ($this->_mode == JROUTER_MODE_SEF) { - $uri->delVar('start'); - $vars['limitstart'] = $start; + if ($start = $uri->getVar('start')) + { + $uri->delVar('start'); + $vars['limitstart'] = $start; + } } } @@ -557,45 +567,55 @@ protected function processParseRules(&$uri) /** * Process the build uri query data based on custom defined rules * - * @param JUri &$uri The URI + * @param JUri &$uri The URI + * @param string $stage The stage that should be processed. + * Possible values: 'preprocess', 'postprocess' + * and '' for the main build stage * * @return void * * @since 3.2 + * @deprecated 4.0 The special logic should be implemented as rule */ - protected function processBuildRules(&$uri) + protected function processBuildRules(&$uri, $stage = '') { - // Make sure any menu vars are used if no others are specified - if (($this->_mode != JROUTER_MODE_SEF) && $uri->getVar('Itemid') && count($uri->getQuery(true)) == 2) + if ($stage == '') { - // Get the active menu item - $itemid = $uri->getVar('Itemid'); - $item = $this->menu->getItem($itemid); - - if ($item) + // Make sure any menu vars are used if no others are specified + if (($this->_mode != JROUTER_MODE_SEF) && $uri->getVar('Itemid') && count($uri->getQuery(true)) == 2) { - $uri->setQuery($item->query); - } + // Get the active menu item + $itemid = $uri->getVar('Itemid'); + $item = $this->menu->getItem($itemid); - $uri->setVar('Itemid', $itemid); + if ($item) + { + $uri->setQuery($item->query); + } + + $uri->setVar('Itemid', $itemid); + } } // Process the attached build rules - parent::processBuildRules($uri); + parent::processBuildRules($uri, $stage); - // Get the path data - $route = $uri->getPath(); - - if ($this->_mode == JROUTER_MODE_SEF && $route) + if ($stage == '') { - if ($limitstart = $uri->getVar('limitstart')) + // Get the path data + $route = $uri->getPath(); + + if ($this->_mode == JROUTER_MODE_SEF && $route) { - $uri->setVar('start', (int) $limitstart); - $uri->delVar('limitstart'); + if ($limitstart = $uri->getVar('limitstart')) + { + $uri->setVar('start', (int) $limitstart); + $uri->delVar('limitstart'); + } } - } - $uri->setPath($route); + $uri->setPath($route); + } } /** From 1ba01766cae3ea754ddbb345bbb690a58d72a1de Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Mon, 1 Dec 2014 09:59:56 +0100 Subject: [PATCH 02/13] Fixing codestyle, typo and unittests --- libraries/cms/router/router.php | 10 +++--- libraries/cms/router/site.php | 2 +- .../libraries/cms/router/JRouterTest.php | 34 ++++++++++++++++--- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/libraries/cms/router/router.php b/libraries/cms/router/router.php index 8de5160d6d33f..092e4ecb855c1 100644 --- a/libraries/cms/router/router.php +++ b/libraries/cms/router/router.php @@ -185,7 +185,7 @@ public function parse(&$uri) { // Do the preprocess stage of the URL build process $vars = $this->processParseRules($uri, 'preprocess'); - + // Process the parsed variables based on custom defined rules // This is the main parse stage $vars += $this->_processParseRules($uri); @@ -201,9 +201,9 @@ public function parse(&$uri) { $vars += $this->_parseSefRoute($uri); } - + // Do the postprocess stage of the URL build process - $vars = $this->processParseRules($uri, 'postprocess'); + $vars += $this->processParseRules($uri, 'postprocess'); return array_merge($this->getVars(), $vars); } @@ -228,7 +228,7 @@ public function build($url) // Create the URI object $uri = $this->createURI($url); - + // Do the preprocess stage of the URL build process $this->processBuildRules($uri, 'preprocess'); @@ -247,7 +247,7 @@ public function build($url) { $this->_buildSefRoute($uri); } - + // Do the postprocess stage of the URL build process $this->processBuildRules($uri, 'postprocess'); diff --git a/libraries/cms/router/site.php b/libraries/cms/router/site.php index 532ee87799a7c..a1f7b29aaaed4 100644 --- a/libraries/cms/router/site.php +++ b/libraries/cms/router/site.php @@ -534,7 +534,7 @@ protected function buildSefRoute(&$uri) /** * Process the parsed router variables based on custom defined rules * - * @param JUri &$uri The URI to parse + * @param JUri &$uri The URI to parse * @param string $stage The stage that should be processed. * Possible values: 'preprocess', 'postprocess' * and '' for the main parse stage diff --git a/tests/unit/suites/libraries/cms/router/JRouterTest.php b/tests/unit/suites/libraries/cms/router/JRouterTest.php index 60c31cfa2d137..36f4ab3085105 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterTest.php @@ -322,12 +322,25 @@ public function testGetVars() public function casesAttachBuildRule() { $cases = array(); - $cases[] = array(array(), array('build' => array(), 'parse' => array())); + $cases[] = array(array(), + array( + 'buildpreprocess' => array(), + 'build' => array(), + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => array() + ) + ); $callbacks = array(function (&$router, &$uri) {}); $cases[] = array($callbacks, array( + 'buildpreprocess' => array(), 'build' => $callbacks, - 'parse' => array() + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => array() ) ); @@ -367,12 +380,25 @@ public function testAttachBuildRule($callbacks, $expected) public function casesAttachParseRule() { $cases = array(); - $cases[] = array(array(), array('build' => array(), 'parse' => array())); + $cases[] = array(array(), + array( + 'buildpreprocess' => array(), + 'build' => array(), + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => array() + ) + ); $callbacks = array(function (&$router, &$uri) {}); $cases[] = array($callbacks, array( + 'buildpreprocess' => array(), 'build' => array(), - 'parse' => $callbacks + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => $callbacks, + 'parsepostprocess' => array() ) ); From 4e0234fc1e3661190461f2d13d0f793e6a807f56 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 7 Dec 2014 19:53:36 +0100 Subject: [PATCH 03/13] Checking $stage parameter when methods are called --- libraries/cms/router/router.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libraries/cms/router/router.php b/libraries/cms/router/router.php index 092e4ecb855c1..ccf37b246433b 100644 --- a/libraries/cms/router/router.php +++ b/libraries/cms/router/router.php @@ -371,6 +371,10 @@ public function getVars() */ public function attachBuildRule($callback, $stage = '') { + if (!array_key_exists('build' . $stage, $this->_rules)) { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + } + $this->_rules['build' . $stage][] = $callback; } @@ -389,6 +393,10 @@ public function attachBuildRule($callback, $stage = '') */ public function attachParseRule($callback, $stage = '') { + if (!array_key_exists('parse' . $stage, $this->_rules)) { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + } + $this->_rules['parse' . $stage][] = $callback; } @@ -539,6 +547,10 @@ protected function _processParseRules(&$uri) */ protected function processParseRules(&$uri, $stage = '') { + if (!array_key_exists('parse' . $stage, $this->_rules)) { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + } + $vars = array(); foreach ($this->_rules['parse' . $stage] as $rule) @@ -578,6 +590,10 @@ protected function _processBuildRules(&$uri) */ protected function processBuildRules(&$uri, $stage = '') { + if (!array_key_exists('build' . $stage, $this->_rules)) { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + } + foreach ($this->_rules['build' . $stage] as $rule) { call_user_func_array($rule, array(&$this, &$uri)); From 64bcedb69907bc0ac433622d7ed866b2850fe59b Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 7 Dec 2014 20:43:42 +0100 Subject: [PATCH 04/13] Codestyle --- libraries/cms/router/router.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/libraries/cms/router/router.php b/libraries/cms/router/router.php index ccf37b246433b..d5635227cc494 100644 --- a/libraries/cms/router/router.php +++ b/libraries/cms/router/router.php @@ -371,8 +371,9 @@ public function getVars() */ public function attachBuildRule($callback, $stage = '') { - if (!array_key_exists('build' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + if (!array_key_exists('build' . $stage, $this->_rules)) + { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); } $this->_rules['build' . $stage][] = $callback; @@ -393,8 +394,9 @@ public function attachBuildRule($callback, $stage = '') */ public function attachParseRule($callback, $stage = '') { - if (!array_key_exists('parse' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + if (!array_key_exists('parse' . $stage, $this->_rules)) + { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); } $this->_rules['parse' . $stage][] = $callback; @@ -547,8 +549,9 @@ protected function _processParseRules(&$uri) */ protected function processParseRules(&$uri, $stage = '') { - if (!array_key_exists('parse' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + if (!array_key_exists('parse' . $stage, $this->_rules)) + { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); } $vars = array(); @@ -590,8 +593,9 @@ protected function _processBuildRules(&$uri) */ protected function processBuildRules(&$uri, $stage = '') { - if (!array_key_exists('build' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage)); + if (!array_key_exists('build' . $stage, $this->_rules)) + { + throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); } foreach ($this->_rules['build' . $stage] as $rule) From 889587cc59cb058e42f32b4735a93450d98ca699 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 7 Dec 2014 20:46:08 +0100 Subject: [PATCH 05/13] Codestyle, second attempt --- libraries/cms/router/router.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/cms/router/router.php b/libraries/cms/router/router.php index d5635227cc494..2ecd4be2b1ee3 100644 --- a/libraries/cms/router/router.php +++ b/libraries/cms/router/router.php @@ -373,7 +373,7 @@ public function attachBuildRule($callback, $stage = '') { if (!array_key_exists('build' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); } $this->_rules['build' . $stage][] = $callback; @@ -396,7 +396,7 @@ public function attachParseRule($callback, $stage = '') { if (!array_key_exists('parse' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); } $this->_rules['parse' . $stage][] = $callback; @@ -551,7 +551,7 @@ protected function processParseRules(&$uri, $stage = '') { if (!array_key_exists('parse' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); } $vars = array(); @@ -595,7 +595,7 @@ protected function processBuildRules(&$uri, $stage = '') { if (!array_key_exists('build' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered.', $stage), __METHOD__); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); } foreach ($this->_rules['build' . $stage] as $rule) From 4ab35bc0fb29ae54cf2e2ee389801f80e3735d67 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Mon, 8 Dec 2014 13:55:08 +0100 Subject: [PATCH 06/13] Fixing typo --- libraries/cms/router/router.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/cms/router/router.php b/libraries/cms/router/router.php index 2ecd4be2b1ee3..687b9f7a8bb6f 100644 --- a/libraries/cms/router/router.php +++ b/libraries/cms/router/router.php @@ -373,7 +373,7 @@ public function attachBuildRule($callback, $stage = '') { if (!array_key_exists('build' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%s)', $stage, __METHOD__)); } $this->_rules['build' . $stage][] = $callback; @@ -396,7 +396,7 @@ public function attachParseRule($callback, $stage = '') { if (!array_key_exists('parse' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%s)', $stage, __METHOD__)); } $this->_rules['parse' . $stage][] = $callback; @@ -551,7 +551,7 @@ protected function processParseRules(&$uri, $stage = '') { if (!array_key_exists('parse' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%s)', $stage, __METHOD__)); } $vars = array(); @@ -595,7 +595,7 @@ protected function processBuildRules(&$uri, $stage = '') { if (!array_key_exists('build' . $stage, $this->_rules)) { - throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%S)', $stage, __METHOD__)); + throw new InvalidArgumentException(sprintf('The %s stage is not registered. (%s)', $stage, __METHOD__)); } foreach ($this->_rules['build' . $stage] as $rule) From e3b25009c16abfb475a00b83b67961fe4b327457 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Fri, 12 Dec 2014 15:24:56 +0100 Subject: [PATCH 07/13] Adding consts --- libraries/cms/router/router.php | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/libraries/cms/router/router.php b/libraries/cms/router/router.php index 687b9f7a8bb6f..4d0fd29345c36 100644 --- a/libraries/cms/router/router.php +++ b/libraries/cms/router/router.php @@ -11,6 +11,8 @@ /** * Set the available masks for the routing mode + * + * @deprecated 4.0 */ const JROUTER_MODE_RAW = 0; const JROUTER_MODE_SEF = 1; @@ -22,6 +24,13 @@ */ class JRouter { + /** + * Processing-stages for the router + */ + const PROCESS_BEFORE = 'preprocess'; + const PROCESS_DURING = ''; + const PROCESS_AFTER = 'postprocess'; + /** * The rewrite mode * @@ -184,7 +193,7 @@ public static function getInstance($client, $options = array()) public function parse(&$uri) { // Do the preprocess stage of the URL build process - $vars = $this->processParseRules($uri, 'preprocess'); + $vars = $this->processParseRules($uri, self::PROCESS_BEFORE); // Process the parsed variables based on custom defined rules // This is the main parse stage @@ -203,7 +212,7 @@ public function parse(&$uri) } // Do the postprocess stage of the URL build process - $vars += $this->processParseRules($uri, 'postprocess'); + $vars += $this->processParseRules($uri, self::PROCESS_AFTER); return array_merge($this->getVars(), $vars); } @@ -230,7 +239,7 @@ public function build($url) $uri = $this->createURI($url); // Do the preprocess stage of the URL build process - $this->processBuildRules($uri, 'preprocess'); + $this->processBuildRules($uri, self::PROCESS_BEFORE); // Process the uri information based on custom defined rules. // This is the main build stage @@ -249,7 +258,7 @@ public function build($url) } // Do the postprocess stage of the URL build process - $this->processBuildRules($uri, 'postprocess'); + $this->processBuildRules($uri, self::PROCESS_AFTER); $this->cache[$key] = clone $uri; @@ -369,7 +378,7 @@ public function getVars() * * @since 1.5 */ - public function attachBuildRule($callback, $stage = '') + public function attachBuildRule($callback, $stage = self::PROCESS_DURING) { if (!array_key_exists('build' . $stage, $this->_rules)) { @@ -392,7 +401,7 @@ public function attachBuildRule($callback, $stage = '') * * @since 1.5 */ - public function attachParseRule($callback, $stage = '') + public function attachParseRule($callback, $stage = self::PROCESS_DURING) { if (!array_key_exists('parse' . $stage, $this->_rules)) { @@ -547,7 +556,7 @@ protected function _processParseRules(&$uri) * * @since 3.2 */ - protected function processParseRules(&$uri, $stage = '') + protected function processParseRules(&$uri, $stage = self::PROCESS_DURING) { if (!array_key_exists('parse' . $stage, $this->_rules)) { @@ -591,7 +600,7 @@ protected function _processBuildRules(&$uri) * * @since 3.2 */ - protected function processBuildRules(&$uri, $stage = '') + protected function processBuildRules(&$uri, $stage = self::PROCESS_DURING) { if (!array_key_exists('build' . $stage, $this->_rules)) { From 5c70150ba147470063dfe1d0fd83f66d1ce2ecb2 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Mon, 29 Dec 2014 16:17:33 +0100 Subject: [PATCH 08/13] Updating unittests for JRouter to accommodate the new routing stages --- .../libraries/cms/router/JRouterTest.php | 183 ++++++++++++++++-- .../cms/router/stubs/JRouterInspector.php | 30 +++ 2 files changed, 194 insertions(+), 19 deletions(-) diff --git a/tests/unit/suites/libraries/cms/router/JRouterTest.php b/tests/unit/suites/libraries/cms/router/JRouterTest.php index 36f4ab3085105..0f3da1977478f 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterTest.php @@ -322,7 +322,7 @@ public function testGetVars() public function casesAttachBuildRule() { $cases = array(); - $cases[] = array(array(), + $cases[] = array(array(), JRouter::PROCESS_DURING, array( 'buildpreprocess' => array(), 'build' => array(), @@ -333,7 +333,7 @@ public function casesAttachBuildRule() ) ); $callbacks = array(function (&$router, &$uri) {}); - $cases[] = array($callbacks, + $cases[] = array($callbacks, JRouter::PROCESS_DURING, array( 'buildpreprocess' => array(), 'build' => $callbacks, @@ -343,6 +343,26 @@ public function casesAttachBuildRule() 'parsepostprocess' => array() ) ); + $cases[] = array($callbacks, JRouter::PROCESS_BEFORE, + array( + 'buildpreprocess' => $callbacks, + 'build' => array(), + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => array() + ) + ); + $cases[] = array($callbacks, JRouter::PROCESS_AFTER, + array( + 'buildpreprocess' => array(), + 'build' => array(), + 'buildpostprocess' => $callbacks, + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => array() + ) + ); return $cases; } @@ -351,6 +371,7 @@ public function casesAttachBuildRule() * Tests the attachBuildRule method * * @param callback $callbacks Callbacks to be attached + * @param string $stage Stage to process * @param array $expected The expected internal rules array * * @return void @@ -358,17 +379,31 @@ public function casesAttachBuildRule() * @dataProvider casesAttachBuildRule * @since 3.4 */ - public function testAttachBuildRule($callbacks, $expected) + public function testAttachBuildRule($callbacks, $stage, $expected) { $object = new JRouterInspector; foreach ($callbacks as $callback) { - $object->attachBuildRule($callback); + $object->attachBuildRule($callback, $stage); } $this->assertEquals($object->getRules(), $expected); } + + /** + * Tests the attachBuildRule() method throwing a proper exception + * + * @return void + * + * @since 3.4 + * @expectedException InvalidArgumentException + */ + public function testAttachBuildRuleException() + { + $callback = array(function (&$router, &$uri) {}); + $this->object->attachBuildRule($callback, 'wrongStage'); + } /** * Cases for testAttachParseRule @@ -380,7 +415,7 @@ public function testAttachBuildRule($callbacks, $expected) public function casesAttachParseRule() { $cases = array(); - $cases[] = array(array(), + $cases[] = array(array(), JRouter::PROCESS_DURING, array( 'buildpreprocess' => array(), 'build' => array(), @@ -391,7 +426,7 @@ public function casesAttachParseRule() ) ); $callbacks = array(function (&$router, &$uri) {}); - $cases[] = array($callbacks, + $cases[] = array($callbacks, JRouter::PROCESS_DURING, array( 'buildpreprocess' => array(), 'build' => array(), @@ -401,6 +436,26 @@ public function casesAttachParseRule() 'parsepostprocess' => array() ) ); + $cases[] = array($callbacks, JRouter::PROCESS_BEFORE, + array( + 'buildpreprocess' => array(), + 'build' => array(), + 'buildpostprocess' => array(), + 'parsepreprocess' => $callbacks, + 'parse' => array(), + 'parsepostprocess' => array() + ) + ); + $cases[] = array($callbacks, JRouter::PROCESS_AFTER, + array( + 'buildpreprocess' => array(), + 'build' => array(), + 'buildpostprocess' => array(), + 'parsepreprocess' => array(), + 'parse' => array(), + 'parsepostprocess' => $callbacks + ) + ); return $cases; } @@ -409,6 +464,7 @@ public function casesAttachParseRule() * Tests the attachParseRule method * * @param callback $callbacks Callbacks to be attached + * @param string $stage Stage to process * @param array $expected The expected internal rules array * * @return void @@ -416,18 +472,32 @@ public function casesAttachParseRule() * @dataProvider casesAttachParseRule * @since 3.4 */ - public function testAttachParseRule($callbacks, $expected) + public function testAttachParseRule($callbacks, $stage, $expected) { $object = new JRouterInspector; foreach ($callbacks as $callback) { - $object->attachParseRule($callback); + $object->attachParseRule($callback, $stage); } $this->assertEquals($object->getRules(), $expected); } + /** + * Tests the attachParseRule() method throwing a proper exception + * + * @return void + * + * @since 3.4 + * @expectedException InvalidArgumentException + */ + public function testAttachParseRuleException() + { + $callback = array(function (&$router, &$uri) {}); + $this->object->attachParseRule($callback, 'wrongStage'); + } + /** * Cases for testProcessParseRules * @@ -438,14 +508,14 @@ public function testAttachParseRule($callbacks, $expected) public function casesProcessParseRules() { $cases = array(); - $cases[] = array(array(), array()); + $cases[] = array(array(), JRouter::PROCESS_DURING, array()); $cases[] = array( array( function (&$router, &$uri) { return array('myvar' => 'myvalue'); } - ), + ), JRouter::PROCESS_DURING, array('myvar' => 'myvalue') ); $cases[] = array( @@ -458,7 +528,7 @@ function (&$router, &$uri) { return array('myvar2' => 'myvalue2'); }, - ), + ), JRouter::PROCESS_DURING, array('myvar1' => 'myvalue1', 'myvar2' => 'myvalue2') ); $cases[] = array( @@ -475,9 +545,27 @@ function (&$router, &$uri) { return array('myvar1' => 'myvalue3'); }, - ), + ), JRouter::PROCESS_DURING, array('myvar1' => 'myvalue1', 'myvar2' => 'myvalue2') ); + $cases[] = array( + array( + function (&$router, &$uri) + { + return array('stage' => 'before'); + } + ), JRouter::PROCESS_BEFORE, + array('stage' => 'before') + ); + $cases[] = array( + array( + function (&$router, &$uri) + { + return array('stage' => 'after'); + } + ), JRouter::PROCESS_AFTER, + array('stage' => 'after') + ); return $cases; } @@ -486,6 +574,7 @@ function (&$router, &$uri) * testProcessParseRules(). * * @param array $functions Callback to execute + * @param string $stage Stage to process * @param string $expected Expected return value * * @return void @@ -493,7 +582,7 @@ function (&$router, &$uri) * @dataProvider casesProcessParseRules * @since 3.4 */ - public function testProcessParseRules($functions, $expected) + public function testProcessParseRules($functions, $stage, $expected) { $myuri = 'http://localhost'; $stub = $this->getMock('JRouter', array('parseRawRoute')); @@ -501,12 +590,26 @@ public function testProcessParseRules($functions, $expected) foreach ($functions as $function) { - $stub->attachParseRule($function); + $stub->attachParseRule($function, $stage); } $this->assertEquals($stub->parse($myuri), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); } + /** + * Tests the attachParseRule() method throwing a proper exception + * + * @return void + * + * @since 3.4 + * @expectedException InvalidArgumentException + */ + public function testProcessParseRulesException() + { + $object = new JRouterInspector; + $object->runProcessParseRules(new JUri, 'wrongStage'); + } + /** * Cases for testProcessBuildRules * @@ -517,14 +620,14 @@ public function testProcessParseRules($functions, $expected) public function casesProcessBuildRules() { $cases = array(); - $cases[] = array(array(), 'index.php?var1=value1&var2=value2'); + $cases[] = array(array(), JRouter::PROCESS_DURING, 'index.php?var1=value1&var2=value2'); $cases[] = array( array( function (&$router, &$uri) { $uri->setPath('value1'); } - ), + ), JRouter::PROCESS_DURING, 'value1?var1=value1&var2=value2' ); $cases[] = array( @@ -537,7 +640,7 @@ function (&$router, &$uri) { $uri->delVar('var1'); }, - ), + ), JRouter::PROCESS_DURING, 'value1?var2=value2' ); $cases[] = array( @@ -554,9 +657,36 @@ function (&$router, &$uri) { $uri->delVar('var2'); }, - ), + ), JRouter::PROCESS_DURING, 'value1/value2' ); + $cases[] = array( + array( + function (&$router, &$uri) + { + $uri->setVar('stage', 'during'); + } + ), JRouter::PROCESS_DURING, + 'index.php?var1=value1&var2=value2&stage=during' + ); + $cases[] = array( + array( + function (&$router, &$uri) + { + $uri->setVar('stage', 'before'); + } + ), JRouter::PROCESS_BEFORE, + 'index.php?var1=value1&var2=value2&stage=before' + ); + $cases[] = array( + array( + function (&$router, &$uri) + { + $uri->setVar('stage', 'after'); + } + ), JRouter::PROCESS_AFTER, + 'index.php?var1=value1&var2=value2&stage=after' + ); return $cases; } @@ -565,6 +695,7 @@ function (&$router, &$uri) * testProcessBuildRules(). * * @param array $functions Callback to execute + * @param string $stage Stage to process * @param string $expected Expected return value * * @dataProvider casesProcessBuildRules @@ -573,7 +704,7 @@ function (&$router, &$uri) * * @since 3.4 */ - public function testProcessBuildRules($functions, $expected) + public function testProcessBuildRules($functions, $stage, $expected) { $myuri = 'index.php?var1=value1&var2=value2'; $stub = $this->getMock('JRouter', array('buildRawRoute')); @@ -588,6 +719,20 @@ public function testProcessBuildRules($functions, $expected) $this->assertEquals($juri->toString(), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); } + /** + * Tests the attachBuildRules() method throwing a proper exception + * + * @return void + * + * @since 3.4 + * @expectedException InvalidArgumentException + */ + public function testProcessBuildRulesException() + { + $object = new JRouterInspector; + $object->runProcessBuildRules(new JUri, 'wrongStage'); + } + /** * Cases for testCreateURI * diff --git a/tests/unit/suites/libraries/cms/router/stubs/JRouterInspector.php b/tests/unit/suites/libraries/cms/router/stubs/JRouterInspector.php index cab9185dd661d..e4c7745a97dea 100644 --- a/tests/unit/suites/libraries/cms/router/stubs/JRouterInspector.php +++ b/tests/unit/suites/libraries/cms/router/stubs/JRouterInspector.php @@ -84,4 +84,34 @@ public static function clearInstanceCache() unset(self::$instances[$key]); } } + + /** + * Runs the protected processParseRules() method + * + * @param JUri &$uri The URI to parse + * @param string $stage The stage that should be processed. + * + * @return mixed Array of decoded segments + * + * @since 3.4 + */ + public function runProcessParseRules(&$uri, $stage = self::PROCESS_DURING) + { + return $this->processParseRules($uri, $stage); + } + + /** + * Runs the protected processBuildRules() method + * + * @param JUri &$uri The URI to parse + * @param string $stage The stage that should be processed. + * + * @return mixed Array of decoded segments + * + * @since 3.4 + */ + public function runProcessBuildRules(&$uri, $stage = self::PROCESS_DURING) + { + return $this->processBuildRules($uri, $stage); + } } From 99e7dc6dfc20b16f3e462e2e797393d32f0b7a7c Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Tue, 30 Dec 2014 01:08:57 +0100 Subject: [PATCH 09/13] Reaching 100% coverage for unittests with this --- tests/unit/core/mock/application.php | 8 +++- tests/unit/core/mock/menu.php | 45 +++++++++++-------- .../libraries/cms/router/JRouterSiteTest.php | 21 ++++++++- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/tests/unit/core/mock/application.php b/tests/unit/core/mock/application.php index b5b0d7c3a3f5a..a91adf8d28763 100644 --- a/tests/unit/core/mock/application.php +++ b/tests/unit/core/mock/application.php @@ -32,7 +32,8 @@ public static function create($test) 'getIdentity', 'getRouter', 'getTemplate', - 'getMenu' + 'getMenu', + 'getLanguage' ); // Create the mock. @@ -52,6 +53,11 @@ public static function create($test) ->method('getMenu') ->will($test->returnValue($menu)); + $language = TestMockLanguage::create($test); + $mockObject->expects($test->any()) + ->method('getLanguage') + ->will($test->returnValue($language)); + $mockObject->input = new JInput; return $mockObject; diff --git a/tests/unit/core/mock/menu.php b/tests/unit/core/mock/menu.php index 858a7667c28fa..c22dc25816465 100644 --- a/tests/unit/core/mock/menu.php +++ b/tests/unit/core/mock/menu.php @@ -25,7 +25,7 @@ class TestMockMenu * * @since 3.4 */ - public static function create(PHPUnit_Framework_TestCase $test, $setDefault = true) + public static function create(PHPUnit_Framework_TestCase $test, $setDefault = true, $setActive = false) { // Collect all the relevant methods in JMenu (work in progress). $methods = array( @@ -70,6 +70,13 @@ public static function create(PHPUnit_Framework_TestCase $test, $setDefault = tr ->will($test->returnValueMap(self::prepareDefaultData())); } + if ($setActive) + { + $mockObject->expects($test->any()) + ->method('getActive') + ->will($test->returnValue(self::$data[$setActive])); + } + return $mockObject; } @@ -194,27 +201,27 @@ protected static function createMenuSampleData() 'parent_id' => '42', 'component' => 'com_test', 'tree' => array(42, 46), - 'query' => array('option' => 'com_test', 'view' => 'test')); + 'query' => array('option' => 'com_test', 'view' => 'test2')); - /** self::$data[47] = (object) array( + self::$data[47] = (object) array( 'id' => '47', - 'menutype' => '', - 'title' => '', - 'alias' => '', - 'route' => '', - 'link' => '', - 'type' => '', - 'level' => '', - 'language' => '', - 'access' => '', - 'params' => '', - 'home' => '', - 'component_id' => '', - 'parent_id' => '', - 'component' => '', - 'query' => array()); + 'menutype' => 'testmenu', + 'title' => 'English Test', + 'alias' => 'english-test', + 'route' => 'english-test', + 'link' => 'index.php?option=com_test&view=test2', + 'type' => 'component', + 'level' => '1', + 'language' => 'en-GB', + 'access' => '1', + 'params' => '{}', + 'home' => '0', + 'component_id' => '1000', + 'parent_id' => '0', + 'component' => 'com_test', + 'query' => array('option' => 'com_test', 'view' => 'test2')); - self::$data[48] = (object) array( + /** self::$data[48] = (object) array( 'id' => '48', 'menutype' => '', 'title' => '', diff --git a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php index ec392930faf0a..d0f29e6c89e7c 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php @@ -120,6 +120,14 @@ public function casesParse() 'REQUEST_URI' => '/joomla/index.php?var=value 10' ); + $server3 = array( + 'HTTP_HOST' => '', + 'SCRIPT_NAME' => '', + 'SCRIPT_FILENAME' => JPATH_SITE . '/cli/deletefiles.php', + 'PHP_SELF' => '', + 'REQUEST_URI' => '' + ); + $cases = array(); $cases[] = array('', JROUTER_MODE_RAW, array(), $server1, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), ''); @@ -134,6 +142,8 @@ public function casesParse() $cases[] = array('/joomla/blog/te%20st', JROUTER_MODE_RAW, array(), $server2, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'blog/te st'); $cases[] = array('/otherfolder/blog/test', JROUTER_MODE_RAW, array(), $server2, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'older/blog/test'); + $cases[] = array('/cli/deletefiles.php?var1=value1', JROUTER_MODE_RAW, array(), $server3, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), '?var1=value1'); + return $cases; } @@ -460,6 +470,8 @@ public function casesParseSefRoute() $cases[] = array('test2/sub-menu', false, array('languagefilter' => true), array('option' => 'com_test2', 'Itemid' => 44), array('option' => 'com_test2', 'Itemid' => 44)); $cases[] = array('test2/sub-menu/something', true, array('languagefilter' => true), array('testvar' => 'testvalue'), array('testvar' => 'testvalue', 'option' => 'com_test2', 'Itemid' => 44)); $cases[] = array('test2/sub-menu/something', false, array('languagefilter' => true), array('testvar' => 'testvalue'), array('option' => 'com_test2', 'Itemid' => 44, 'testvar' => 'testvalue')); + + $cases[] = array('english-test', false, array('languagefilter' => true), array('option' => 'com_test', 'view' => 'test2'), array('option' => 'com_test', 'Itemid' => '47'), 47); return $cases; } @@ -478,7 +490,7 @@ public function casesParseSefRoute() * @dataProvider casesParseSefRoute * @since 3.4 */ - public function testParseSefRoute($url, $menubool, $appConfig, $expected, $expectedGlobals) + public function testParseSefRoute($url, $menubool, $appConfig, $expected, $expectedGlobals, $activeMenu = false) { $uri = new JUri($url); $app = $this->object->getApp(); @@ -498,10 +510,15 @@ public function testParseSefRoute($url, $menubool, $appConfig, $expected, $expec if ($menubool) { - $menu = TestMockMenu::create($this, false); + $menu = TestMockMenu::create($this, false, $activeMenu); $menu->expects($this->any())->method('getDefault')->will($this->returnValue(null)); $this->object->setMenu($menu); } + else + { + $menu = TestMockMenu::create($this, true, $activeMenu); + $this->object->setMenu($menu); + } // The method should return an array of variables $vars = $this->object->runParseSefRoute($uri); From ded1d0ba6a13c727ab26b4d436b0e2a75bdf3e34 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 4 Jan 2015 16:41:11 +0100 Subject: [PATCH 10/13] Fixing position of component router preprocess stage --- libraries/cms/router/site.php | 29 +++++++- .../libraries/cms/router/JRouterSiteTest.php | 69 +++++++++++++++---- 2 files changed, 82 insertions(+), 16 deletions(-) diff --git a/libraries/cms/router/site.php b/libraries/cms/router/site.php index a1f7b29aaaed4..113732b9e100c 100644 --- a/libraries/cms/router/site.php +++ b/libraries/cms/router/site.php @@ -55,6 +55,8 @@ public function __construct($options = array(), JApplicationCms $app = null, JMe $this->app = $app ? $app : JApplicationCms::getInstance('site'); $this->menu = $menu ? $menu : $this->app->getMenu(); + + $this->attachBuildRule(array($this, 'preprocessComponentStage'), self::PROCESS_BEFORE); } /** @@ -480,7 +482,6 @@ protected function buildSefRoute(&$uri) $tmp = ''; $itemID = !empty($query['Itemid']) ? $query['Itemid'] : null; $crouter = $this->getComponentRouter($component); - $query = $crouter->preprocess($query); $parts = $crouter->build($query); $result = implode('/', $parts); $tmp = ($result != "") ? $result : ''; @@ -745,4 +746,30 @@ public function setComponentRouter($component, $router) return false; } } + + /** + * Rule to trigger the preprocess method of a component router + * + * @param JUri $uri URI to process + * + * @return void + * + * @since 3.4 + */ + public function preprocessComponentStage(JRouter &$router, JUri &$uri) + { + // Get the query data + $query = $uri->getQuery(true); + + if (!isset($query['option'])) + { + return; + } + + // Build the component route + $component = preg_replace('/[^A-Z0-9_\.-]/i', '', $query['option']); + $crouter = $this->getComponentRouter($component); + $query = $crouter->preprocess($query); + $uri->setQuery($query); + } } diff --git a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php index d0f29e6c89e7c..c5ea294b8de7c 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php @@ -577,26 +577,14 @@ public function casesBuildSefRoute() // Check if URLs without an option are returned identically $cases[] = array('index.php?var1=value1', 'index.php?var1=value1'); - // Check if URLs with an option are processed by the pre-process method - $cases[] = array('index.php?option=com_test&var1=value1', 'index.php/component/test/?var1=value1&testvar=testvalue'); - - // Check if URLs with a mangled option are processed by the pre-process method - $cases[] = array('index.php?option=com_ Tes§t&var1=value1', 'index.php/component/ Tes§t/?var1=value1&testvar=testvalue'); - - // Check if URLs with an option and some path are processed by the pre-process method and returned with the original path - $cases[] = array('test-folder?option=com_test&var1=value1', 'test-folder/component/test/?var1=value1&testvar=testvalue'); - // Check if the menu item is properly prepended - $cases[] = array('index.php?option=com_test&var1=value1&Itemid=42', 'index.php/test?var1=value1&testvar=testvalue'); + $cases[] = array('index.php?option=com_test&var1=value1&Itemid=42', 'index.php/test?var1=value1'); // Check if a non existing menu item is correctly ignored - $cases[] = array('index.php?option=com_test&var1=value1&Itemid=41', 'index.php/component/test/?var1=value1&Itemid=41&testvar=testvalue'); + $cases[] = array('index.php?option=com_test&var1=value1&Itemid=41', 'index.php/component/test/?var1=value1&Itemid=41'); // Check if a menu item with a parent is properly prepended - $cases[] = array('index.php?option=com_test&var1=value1&Itemid=46', 'index.php/test/sub-menu?var1=value1&testvar=testvalue'); - - // Component router build: Check if URLs with an option and some path are processed by the pre-process method and returned with the original path - $cases[] = array('test-folder?option=com_test2&var1=value1', 'test-folder/component/test2/router-test/another-segment?var1=value1'); + $cases[] = array('index.php?option=com_test&var1=value1&Itemid=46', 'index.php/test/sub-menu?var1=value1'); // Component router build: Check if the menu item is properly prepended $cases[] = array('index.php?option=com_test2&var1=value1&Itemid=43', 'index.php/test2/router-test/another-segment?var1=value1'); @@ -831,4 +819,55 @@ public function testSetComponentRouter() // Check if a false router is correctly rejected $this->assertFalse($this->object->setComponentRouter('com_test3', new stdClass)); } + + /** + * Cases for testPreprocessComponentStage + * + * @return array + * + * @since 3.4 + */ + public function casesPreprocessComponentStage() + { + $cases = array(); + + // Check empty URLs are returned identically + $cases[] = array('', ''); + + // Check if URLs without an option are returned identically + $cases[] = array('index.php?var1=value1', 'index.php?var1=value1'); + + // Check if URLs with an option are processed by the pre-process method + $cases[] = array('index.php?option=com_test&var1=value1', 'index.php?option=com_test&var1=value1&testvar=testvalue'); + + // Check if URLs with a mangled option are processed by the pre-process method + $cases[] = array('index.php?option=com_ Tes§t&var1=value1', 'index.php?option=com_ Tes§t&var1=value1&testvar=testvalue'); + + // Check if URLs with an option and some path are processed by the pre-process method and returned with the original path + $cases[] = array('test-folder?option=com_test&var1=value1', 'test-folder?option=com_test&var1=value1&testvar=testvalue'); + + // Component router build: Check if URLs with an option and some path are processed by the pre-process method and returned with the original path + $cases[] = array('test-folder?option=com_test2&var1=value1', 'test-folder?option=com_test2&var1=value1'); + + return $cases; + } + + /** + * testPreprocessComponentStage(). + * + * @param string $url Input URL + * @param string $expected Expected return value + * + * @dataProvider casesPreprocessComponentStage + * + * @return void + * + * @since 3.4 + */ + public function testPreprocessComponentStage($url, $expected) + { + $uri = new JUri($url); + $this->object->preprocessComponentStage($this->object, $uri); + $this->assertEquals($expected, $uri->toString()); + } } From 12c2aa57466575a7a304c76272d0c0644df36008 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 4 Jan 2015 17:08:17 +0100 Subject: [PATCH 11/13] Codestyle --- libraries/cms/router/site.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/cms/router/site.php b/libraries/cms/router/site.php index 113732b9e100c..838a7a82c5a0b 100644 --- a/libraries/cms/router/site.php +++ b/libraries/cms/router/site.php @@ -750,7 +750,8 @@ public function setComponentRouter($component, $router) /** * Rule to trigger the preprocess method of a component router * - * @param JUri $uri URI to process + * @param JRouter &$router The router calling this rule + * @param JUri &$uri URI to process * * @return void * From f72c4238fc9c523740b85506fd059e3a5647329d Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Mon, 5 Jan 2015 13:26:19 +0100 Subject: [PATCH 12/13] Fixing order of method calls in JRouterSite --- libraries/cms/router/site.php | 49 ++++++++++++++--------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/libraries/cms/router/site.php b/libraries/cms/router/site.php index 838a7a82c5a0b..49dddb25b3ca5 100644 --- a/libraries/cms/router/site.php +++ b/libraries/cms/router/site.php @@ -55,8 +55,6 @@ public function __construct($options = array(), JApplicationCms $app = null, JMe $this->app = $app ? $app : JApplicationCms::getInstance('site'); $this->menu = $menu ? $menu : $this->app->getMenu(); - - $this->attachBuildRule(array($this, 'preprocessComponentStage'), self::PROCESS_BEFORE); } /** @@ -580,7 +578,7 @@ protected function processParseRules(&$uri, $stage = '') */ protected function processBuildRules(&$uri, $stage = '') { - if ($stage == '') + if ($stage == self::PROCESS_DURING) { // Make sure any menu vars are used if no others are specified if (($this->_mode != JROUTER_MODE_SEF) && $uri->getVar('Itemid') && count($uri->getQuery(true)) == 2) @@ -601,7 +599,24 @@ protected function processBuildRules(&$uri, $stage = '') // Process the attached build rules parent::processBuildRules($uri, $stage); - if ($stage == '') + if ($stage == self::PROCESS_BEFORE) + { + // Get the query data + $query = $uri->getQuery(true); + + if (!isset($query['option'])) + { + return; + } + + // Build the component route + $component = preg_replace('/[^A-Z0-9_\.-]/i', '', $query['option']); + $router = $this->getComponentRouter($component); + $query = $router->preprocess($query); + $uri->setQuery($query); + } + + if ($stage == self::PROCESS_DURING) { // Get the path data $route = $uri->getPath(); @@ -747,30 +762,4 @@ public function setComponentRouter($component, $router) } } - /** - * Rule to trigger the preprocess method of a component router - * - * @param JRouter &$router The router calling this rule - * @param JUri &$uri URI to process - * - * @return void - * - * @since 3.4 - */ - public function preprocessComponentStage(JRouter &$router, JUri &$uri) - { - // Get the query data - $query = $uri->getQuery(true); - - if (!isset($query['option'])) - { - return; - } - - // Build the component route - $component = preg_replace('/[^A-Z0-9_\.-]/i', '', $query['option']); - $crouter = $this->getComponentRouter($component); - $query = $crouter->preprocess($query); - $uri->setQuery($query); - } } From 7eefb404a83b94948e2df6a9efed8f8c579548b2 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Mon, 5 Jan 2015 14:10:18 +0100 Subject: [PATCH 13/13] Fixing unittests --- .../libraries/cms/router/JRouterSiteTest.php | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php index c5ea294b8de7c..e509701d8b6bc 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php @@ -819,55 +819,4 @@ public function testSetComponentRouter() // Check if a false router is correctly rejected $this->assertFalse($this->object->setComponentRouter('com_test3', new stdClass)); } - - /** - * Cases for testPreprocessComponentStage - * - * @return array - * - * @since 3.4 - */ - public function casesPreprocessComponentStage() - { - $cases = array(); - - // Check empty URLs are returned identically - $cases[] = array('', ''); - - // Check if URLs without an option are returned identically - $cases[] = array('index.php?var1=value1', 'index.php?var1=value1'); - - // Check if URLs with an option are processed by the pre-process method - $cases[] = array('index.php?option=com_test&var1=value1', 'index.php?option=com_test&var1=value1&testvar=testvalue'); - - // Check if URLs with a mangled option are processed by the pre-process method - $cases[] = array('index.php?option=com_ Tes§t&var1=value1', 'index.php?option=com_ Tes§t&var1=value1&testvar=testvalue'); - - // Check if URLs with an option and some path are processed by the pre-process method and returned with the original path - $cases[] = array('test-folder?option=com_test&var1=value1', 'test-folder?option=com_test&var1=value1&testvar=testvalue'); - - // Component router build: Check if URLs with an option and some path are processed by the pre-process method and returned with the original path - $cases[] = array('test-folder?option=com_test2&var1=value1', 'test-folder?option=com_test2&var1=value1'); - - return $cases; - } - - /** - * testPreprocessComponentStage(). - * - * @param string $url Input URL - * @param string $expected Expected return value - * - * @dataProvider casesPreprocessComponentStage - * - * @return void - * - * @since 3.4 - */ - public function testPreprocessComponentStage($url, $expected) - { - $uri = new JUri($url); - $this->object->preprocessComponentStage($this->object, $uri); - $this->assertEquals($expected, $uri->toString()); - } }