Skip to content

Commit

Permalink
Implementing "no Itemid" behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
Hackwar committed Jan 3, 2015
1 parent 2ae969b commit 5d3eb6c
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 0 deletions.
110 changes: 110 additions & 0 deletions libraries/cms/component/router/rules/nomenu.php
@@ -0,0 +1,110 @@
<?php
/**
* @package Joomla.Libraries
* @subpackage Component
*
* @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/

/**
* Rule to process URLs without a menu item
*
* @since 3.4
*/
class JComponentRouterRulesNomenu implements JComponentRouterRulesInterface
{
/**
* Router this rule belongs to
*
* @var JComponentRouterAdvanced
* @since 3.4
*/
protected $router;

/**
* Class constructor.
*
* @param JComponentRouterAdvanced $router Router this rule belongs to
*
* @since 3.4
*/
public function __construct(JComponentRouterAdvanced $router)
{
$this->router = $router;
}

/**
* Dummymethod to fullfill the interface requirements
*
* @param array &$query The query array to process
*
* @return void
*
* @since 3.4
* @codeCoverageIgnore
*/
public function preprocess(&$query)
{
}

/**
* Parse a menu-less URL
*
* @param array &$segments The URL segments to parse
* @param array &$vars The vars that result from the segments
*
* @return void
*
* @since 3.4
*/
public function parse(&$segments, &$vars)
{
$active = $this->router->menu->getActive();

if (!is_object($active))
{
$views = $this->router->getViews();

if (isset($views[$segments[0]]))
{
$vars['view'] = array_shift($segments);

if (isset($views[$vars['view']]->key) && isset($segments[0]))
{
$vars[$views[$vars['view']]->key] = preg_replace('/-/', ':', array_shift($segments), 1);
}
}
}
}

/**
* Build a menu-less URL
*
* @param array &$query The vars that should be converted
* @param array &$segments The URL segments to create
*
* @return void
*
* @since 3.4
*/
public function build(&$query, &$segments)
{
if (!isset($query['Itemid']) && isset($query['view']))
{
$views = $this->router->getViews();
if (isset($views[$query['view']]))
{
$segments[] = $query['view'];

if ($views[$query['view']]->key)
{
$key = $views[$query['view']]->key;
$segments[] = str_replace(':', '-', $query[$key]);
unset($query[$views[$query['view']]->key]);
}
unset($query['view']);
}
}
}
}
@@ -0,0 +1,163 @@
<?php
/**
* @package Joomla.UnitTest
* @subpackage Component
*
* @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/

require_once __DIR__ . '/stubs/JComponentRouterRulesNomenuInspector.php';
require_once __DIR__ . '/../stubs/JComponentRouterAdvancedInspector.php';

/**
* Test class for JComponentRouterRulesMenu.
*
* @package Joomla.UnitTest
* @subpackage Component
* @since 3.4
*/
class JComponentRouterRulesNomenuTest extends TestCase {

/**
* Object under test
*
* @var JComponentRouterRulesMenu
* @since 3.4
*/
protected $object;

/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*
* @return void
*
* @since 3.4
*/
protected function setUp()
{
parent::setUp();

$app = TestMockApplication::create($this);
$router = new JComponentRouterAdvancedInspector($app, $app->getMenu());
$router->set('name', 'content');
$categories = new JComponentRouterViewconfiguration('categories');
$categories->setKey('id');
$router->registerView($categories);
$category = new JComponentRouterViewconfiguration('category');
$category->setKey('id')->setParent($categories)->setNestable()->addLayout('blog');
$router->registerView($category);
$article = new JComponentRouterViewconfiguration('article');
$article->setKey('id')->setParent($category, 'catid');
$router->registerView($article);
$archive = new JComponentRouterViewconfiguration('archive');
$router->registerView($archive);
$featured = new JComponentRouterViewconfiguration('featured');
$router->registerView($featured);
$form = new JComponentRouterViewconfiguration('form');
$router->registerView($form);

$this->object = new JComponentRouterRulesNomenuInspector($router);
}

/**
* Tests the __construct() method
*
* @return void
*
* @since 3.4
*/
public function testConstruct()
{
$this->assertInstanceOf('JComponentRouterRulesNomenu', $this->object);
$this->assertInstanceOf('JComponentRouterAdvanced', $this->object->get('router'));
}

/**
* Tests the parse() method
*
* @return void
*
* @since 3.4
*/
public function testParse()
{
// Check if a false view is properly rejected
$segments = array('falseview');
$vars = array('option' => 'com_content');
$this->object->parse($segments, $vars);
$this->assertEquals(array('falseview'), $segments);
$this->assertEquals(array('option' => 'com_content'), $vars);

// Check if a single view is properly parsed
$segments = array('featured');
$vars = array('option' => 'com_content');
$this->object->parse($segments, $vars);
$this->assertEquals(array(), $segments);
$this->assertEquals(array('option' => 'com_content', 'view' => 'featured'), $vars);

// Check if a view with ID is properly parsed
$segments = array('category', '23-the-question');
$vars = array('option' => 'com_content');
$this->object->parse($segments, $vars);
$this->assertEquals(array(), $segments);
$this->assertEquals(array('option' => 'com_content', 'view' => 'category', 'id' => '23:the-question'), $vars);

// Check if a view that normally has an ID but which is missing is properly parsed
$segments = array('category');
$vars = array('option' => 'com_content');
$this->object->parse($segments, $vars);
$this->assertEquals(array(), $segments);
$this->assertEquals(array('option' => 'com_content', 'view' => 'category'), $vars);

// Test if the rule is properly skipped when a menu item is set
$router = $this->object->get('router');
$router->menu->expects($this->any())
->method('getActive')
->will($this->returnValue(new stdClass()));
$segments = array('article', '42:the-answer');
$vars = array('option' => 'com_content');
$this->object->parse($segments, $vars);
$this->assertEquals(array('article', '42:the-answer'), $segments);
$this->assertEquals(array('option' => 'com_content'), $vars);
}

/**
* Tests the build() method
*
* @return void
*
* @since 3.4
*/
public function testBuild()
{
// Test if the rule is properly skipped if an Itemid is set
$query = array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '23');
$segments = array();
$this->object->build($query, $segments);
$this->assertEquals(array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '23'), $query);
$this->assertEquals(array(), $segments);

// Test if a false view is properly not treated
$query = array('option' => 'com_content', 'view' => 'falseview', 'id' => '42:the-answer');
$segments = array();
$this->object->build($query, $segments);
$this->assertEquals(array('option' => 'com_content', 'view' => 'falseview', 'id' => '42:the-answer'), $query);
$this->assertEquals(array(), $segments);

// Test if a single view without identifier is properly build
$query = array('option' => 'com_content', 'view' => 'featured');
$segments = array();
$this->object->build($query, $segments);
$this->assertEquals(array('option' => 'com_content'), $query);
$this->assertEquals(array('featured'), $segments);

// Test if a single view with identifier is properly build
$query = array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer');
$segments = array();
$this->object->build($query, $segments);
$this->assertEquals(array('option' => 'com_content'), $query);
$this->assertEquals(array('article', '42-the-answer'), $segments);
}
}
@@ -0,0 +1,47 @@
<?php
/**
* @package Joomla.UnitTest
* @subpackage Component
*
* @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/

/**
* Inspector for JComponentRouterRulesNomenu
*
* @package Joomla.UnitTest
* @subpackage Component
* @since 3.4
*/
class JComponentRouterRulesNomenuInspector extends JComponentRouterRulesNomenu
{
/**
* Gets an attribute of the object
*
* @param string $key Attributename to return
*
* @return mixed Attributes of the object
*
* @since 3.4
*/
public function get($key)
{
return $this->$key;
}

/**
* Sets an attribute of the object
*
* @param string $key Attributename to return
* @param mixed $value Value to be set
*
* @return void
*
* @since 3.4
*/
public function set($key, $value)
{
$this->$key = $value;
}
}

0 comments on commit 5d3eb6c

Please sign in to comment.