Skip to content

Instantly share code, notes, and snippets.

@fahad19
Created November 23, 2011 02:34
Show Gist options
  • Save fahad19/1387751 to your computer and use it in GitHub Desktop.
Save fahad19/1387751 to your computer and use it in GitHub Desktop.
Admin navigation management in Lithium PHP framework
<?php
/**
* Navigation class for storing admin panel menu.
*
* @author Fahad Ibnay Heylaal <contact@fahad19.com>
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace core\storage;
use core\util\Set;
/**
* Navigation
*
* Class for managing admin panel navigation.
*/
class Navigation extends \lithium\core\StaticObject {
/**
* Stores admin navigation information like:
*
* $_data = array(
* 'contents' => array( // unique top level alias
* 'title' => 'Link Title',
* 'link' => '#', // string or an array
* 'weight' => 0, // for ordering
* 'access' => array('*'), // roles
* 'children' => array(
* 'list' => array(
* 'title' => 'List',
* 'link' => '#',
* 'weight' => 5,
* ),
* ),
* ),
* );
*
* @var array
*/
protected static $_data = array();
/**
* Add items to navigation
*
* @param string $path Dot separated path in the array. See \lithium\util\Set::insert().
* @param array $options Information to be inserted in the given path.
* @return void
*/
public static function add($path, $options) {
if (!strstr($path, '.')) {
static::$_data[$path] = $options;
} else {
static::$_data = Set::insert(static::$_data, $path, $options);
}
}
/**
* Removes given path from navigation.
*
* @param string $path Dot separated path in the array. See \lithium\util\Set::insert().
* @return void
*/
public static function remove($path) {
static::$_data = Set::remove(static::$_data, $path);
}
/**
* Returns navigation information
*
* @return array
*/
public static function getData() {
return Set::order(static::$_data);
}
/**
* Deletes all navigation information, mainly for test cases.
*
* @return void
*/
public static function clearData() {
static::$_data = array();
}
}
?>
<?php
/**
* Test case for Navigation class
*
* @author Fahad Ibnay Heylaal <contact@fahad19.com>
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace core\tests\cases\storage;
use lithium\util\Set;
use core\storage\Navigation;
class NavigationTest extends \lithium\test\Unit {
public function setUp() {
Navigation::clearData();
}
public function testAdd() {
$usersNav = array(
'title' => 'Users',
'link' => '#',
);
Navigation::add('users', $usersNav);
$expected = array('users' => $usersNav);
$this->assertEqual($expected, Navigation::getData());
$menusNav = array(
'title' => 'Menus',
'link' => '#',
);
Navigation::add('menus', $menusNav);
$expected = array('users' => $usersNav, 'menus' => $menusNav);
$this->assertEqual($expected, Navigation::getData());
Navigation::add('users.children.create', array('title' => 'Create'));
$expected = array('users' => array_merge($usersNav, array('children' => array('create' => array('title' => 'Create')))), 'menus' => $menusNav);
$this->assertEqual($expected, Navigation::getData());
}
public function testRemove() {
Navigation::add('users', array('title' => 'Users'));
Navigation::remove('users');
$this->assertEqual(array(), Navigation::getData());
}
}
?>
<?php
/**
* Extended Set class
*
* @author Fahad Ibnay Heylaal <contact@fahad19.com>
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace core\util;
class Set extends \lithium\util\Set {
/**
* Orders nested array based on array key.
*
* @param array $data
* @param string $key
* @return array
*/
public static function order($data, $key = 'weight') {
$output = array();
if (!$data) {
return $output;
}
$flat = static::flatten($data);
$flatWeight = array();
foreach ($flat AS $k => $v) {
if (strstr($k, $key)) {
$flatWeight[$k] = $v;
}
}
asort($flatWeight);
foreach ($flatWeight AS $path => $weight) {
$pathE = explode('.', $path);
$depth = count($pathE);
unset($pathE[$depth - 1]);
$currentPath = implode('.', $pathE);
$output = self::insert($output, $currentPath, self::find($data, $currentPath));
}
$output = self::merge($output, self::diff($data, $output));
return $output;
}
/**
* Checks if a particular path is set in an array, and returns the value
*
* @param mixed $data Data to check on.
* @param mixed $path A dot-delimited string.
* @return mixed value if path is found, `false` otherwise.
*/
public static function find($data, $path = null) {
if (!$path) {
return $data;
}
$path = is_array($path) ? $path : explode('.', $path);
foreach ($path as $i => $key) {
if (is_numeric($key) && intval($key) > 0 || $key === '0') {
$key = intval($key);
}
if ($i === count($path) - 1) {
if (is_array($data) && isset($data[$key])) {
return $data[$key];
}
} else {
if (!is_array($data) || !isset($data[$key])) {
return false;
}
$data =& $data[$key];
}
}
}
/**
* Searches for a value in the array and returns dot separated path.
*
* @param mixed $data Data to check on.
* @param mixed $value Value to search for.
* @param string $key Limit search by key.
* @return mixed Dot separated path if value is found, `false` otherwise.
*/
public static function findPath($data, $value, $key = null) {
$flatData = static::flatten($data);
foreach ($flatData AS $k => $v) {
if (!$key && $v == $value) {
return $k;
} elseif ($key && $key == $k && $value == $v) {
return $k;
}
}
return false;
}
}
?>
<?php
/**
* Test case for Set class
*
* @author Fahad Ibnay Heylaal <contact@fahad19.com>
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace core\tests\cases\util;
use core\util\Set;
class SetTest extends \lithium\test\Unit {
public function setUp() {
}
public function testOrder() {
$data = array(
'group1' => array(
'key1' => array('foo' => 'bar', 'weight' => 5),
'key2' => array('hello' => 'world', 'weight' => 1),
),
'group2' => array(
'key1' => array('foo' => 'bar', 'weight' => 1),
'key2' => array('hello' => 'world', 'weight' => 2),
),
'group3' => array('apple', 'orange', 'blackberry'),
);
$expected = array(
'group1' => array(
'key2' => array('hello' => 'world', 'weight' => 1),
'key1' => array('foo' => 'bar', 'weight' => 5),
),
'group2' => array(
'key1' => array('foo' => 'bar', 'weight' => 1),
'key2' => array('hello' => 'world', 'weight' => 2),
),
'group3' => array('apple', 'orange', 'blackberry'),
);
$this->assertEqual(Set::order($data, 'weight'), $expected);
}
public function testFindPath() {
$data = array(
'group1' => array(
'white' => 'board',
'black' => 'pen',
'yellow' => 'highlighter',
),
);
$result = Set::findPath($data, 'pen');
$expected = 'group1.black';
$this->assertEqual($result, $expected);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment