diff --git a/Builder.php b/Builder.php new file mode 100644 index 0000000..c57ad9d --- /dev/null +++ b/Builder.php @@ -0,0 +1,294 @@ + + * @license https://opensource.org/licenses/MIT MIT + * @version GIT: 1.0.0 + * @link http://sleepymustache.com + */ + +namespace Module\Navigation; + +use Sleepy\Core\Hook; +use Sleepy\Core\Module; + +/** + * Creates a Navigation UL based on a JSON file + * + * Uses JSON to structure navigation pages and attributes. It can detect what page + * is active and assign classes to them for special treatment. + * + * ### Usage + * + * + * $topNavData = '{ + * "pages": [ + * { + * "title": "Nav 1", + * "link": "/nav1/" + * }, { + * "title": "Nav 2", + * "link": "/nav2/", + * "pages": [ + * { + * "title": "Subnav 1", + * "link": "/downloads/fpo.pdf", + * "target": "_blank" + * } + * ] + * } + * ] + * }'; + * + * $topNav = new \Module\Navigation\Builder($topNavData); + * + * // In body somewhere... + * + * + * + * ### Changelog + * # Version 2.0 + * * Converted to 2.x API + * + * # Version 1.4 + * * Now automatically sets $_SERVER["SCRIPT_NAME"] as current page + * * Added multiple hook points for manipulating navigations + * + * ## Version 1.2 + * * Added a track parameter + * + * @category Navigation + * @package Module\Navigation + * @author Jaime Rodriguez + * @license https://opensource.org/licenses/MIT MIT + * @link http://sleepymustache.com + */ +class Builder extends Module +{ + /** + * The array of hooks this module attaches to + * + * @var mixed[] + */ + public $hooks = []; + + /** + * Use this string to determine currently active page + * + * @var string + * @private + */ + private $_current; + + /** + * Navigation data + * + * @var mixed[] + * @private + */ + private $_data; + + /** + * Level + * + * @var int + * @private + */ + private $_level = 0; + + /** + * Constructor + * + * @param string $json json data containing the Navigation data + */ + public function __construct($json="") + { + if (!is_object($json)) { + if (class_exists("\Sleepy\Hook")) { + $json = \Sleepy\Hook::addFilter("navigation_raw_json", $json); + } + + $json = json_decode($json); + } + + if (class_exists("\Sleepy\Hook")) { + $json = \Sleepy\Hook::addFilter("navigation_rendered_json", $json); + } + + $this->data = $json; + $this->setCurrent($_SERVER["SCRIPT_NAME"]); + } + + /** + * Is this page or its children an active page? + * + * @param object $page An object containing page data + * + * @return int 0=none;1=active;2=activeChild + * @private + */ + private function hasActive($page) + { + // are there subpages? check those too... + if (isset($page->pages)) { + foreach ($page->pages as $subPage) { + if ($this->hasActive($subPage)) { + return 2; + } + } + } + + // can we find a match? + if (substr($page->link, strlen($page->link) * -1) === $this->current) { + if (class_exists("\Sleepy\Hook")) { + \Sleepy\Hook::addAction("navigation_has_active"); + } + + return 1; + } + + // no match... + if (class_exists("\Sleepy\Hook")) { + \Sleepy\Hook::addAction("navigation_no_active"); + } + + return 0; + } + + /** + * Renders the $pages as an unordered list + * + * @param object $pages the page data + * + * @return string The string containing the unordered list + */ + private function _renderNav($pages, $class="") + { + $this->_level = $this->_level + 1; + $buffer = array(); + + if ($this->_level > 1) { + $class = "submenu " . $class; + } else { + $class = "menu " . $class; + } + + $class = trim($class); + $buffer[] = ""; + + return implode("", $buffer); + } + + /** + * Renders the Navigation + * @return string The rendered navigation + */ + public function show($class="") + { + $toggle = ""; + $rendered = $toggle . $this->_renderNav($this->data->pages, $class); + + if (class_exists("\Sleepy\Hook")) { + $rendered = \Sleepy\Hook::addFilter("navigation_rendered", $rendered); + } + + return $rendered; + } + + /** + * Sets the current page search string + * @param string $string A string used to determine if a page is current + */ + public function setCurrent($string) + { + $this->current = str_replace( + @URLBASE, + "/", + str_replace("index.php", "", $string) + ); + + if (class_exists("\Sleepy\Hook")) { + $this->current = \Sleepy\Hook::addFilter("navigation_current_page", $this->current); + } + } +} diff --git a/README.md b/README.md index e790f30..11fbc2d 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Creates a Navigation UL based on a JSON file. Uses JSON to structure navigation ### Version 1.4 -* Now automatically sets $_SERVER['SCRIPT_NAME'] as current page +* Now automatically sets $_SERVER["SCRIPT_NAME"] as current page * Added multiple hook points for manipulating navigations ### Version 1.2 diff --git a/class.navigation.php b/class.navigation.php deleted file mode 100644 index 624ba56..0000000 --- a/class.navigation.php +++ /dev/null @@ -1,226 +0,0 @@ - - * $topNavData = '{ - * "pages": [ - * { - * "title": "Nav 1", - * "link": "/nav1/" - * }, { - * "title": "Nav 2", - * "link": "/nav2/", - * "pages": [ - * { - * "title": "Subnav 1", - * "link": "/downloads/fpo.pdf", - * "target": "_blank" - * } - * ] - * } - * ] - * }'; - * - * $topNav = new \Module\Navigation\Builder($topNavData); - * - * // In body somewhere... - * - * - * - * ### Changelog - * # Version 1.4 - * * Now automatically sets $_SERVER['SCRIPT_NAME'] as current page - * * Added multiple hook points for manipulating navigations - * - * ## Version 1.2 - * * Added a track parameter - * - * @date June 16, 2014 - * @author Jaime A. Rodriguez - * @version 1.1 - * @license http://opensource.org/licenses/MIT - */ -class Builder { - /** - * string Use this string to determine currently active page - * @private - */ - private $current; - - /** - * mixed Navigation data - */ - private $data; - - /** - * mixed Level - */ - private $_level = 0; - - /** - * Constructor - * @param string $json json data containing the Navigation data - */ - public function __construct($json='') { - if (!is_object($json)) { - if (class_exists('\Sleepy\Hook')) { - $json = \Sleepy\Hook::addFilter('navigation_raw_json', $json); - } - - $json = json_decode($json); - } - - if (class_exists('\Sleepy\Hook')) { - $json = \Sleepy\Hook::addFilter('navigation_rendered_json', $json); - } - - $this->data = $json; - $this->setCurrent($_SERVER['SCRIPT_NAME']); - } - - /** - * Is this page or its children an active page? - * @param object $page An object containing page data - * @return int 0=none;1=active;2=activeChild - * @private - */ - private function hasActive($page) { - // are there subpages? check those too... - if (isset($page->pages)) { - foreach ($page->pages as $subPage) { - if ($this->hasActive($subPage)) { - return 2; - } - } - } - - // can we find a match? - if (substr($page->link, strlen($page->link) * -1) === $this->current) { - if (class_exists('\Sleepy\Hook')) { - \Sleepy\Hook::addAction('navigation_has_active'); - } - - return 1; - } - - // no match... - if (class_exists('\Sleepy\Hook')) { - \Sleepy\Hook::addAction('navigation_no_active'); - } - - return 0; - } - - /** - * Renders the $pages as an unordered list - * @param object $pages the page data - * @return string The string containing the unordered list - */ - private function renderNav($pages, $class="") { - $this->_level = $this->_level + 1; - $buffer = array(); - - if ($this->_level > 1) { - $class = "submenu " . $class; - } else { - $class = "menu " . $class; - } - - $class = trim($class); - - $buffer[] = ""; - - return implode("", $buffer); - } - - /** - * Renders the Navigation - * @return string The rendered navigation - */ - public function show($class="") { - $rendered = $this->renderNav($this->data->pages, $class); - - if (class_exists('\Sleepy\Hook')) { - $rendered = \Sleepy\Hook::addFilter('navigation_rendered', $rendered); - } - - return $rendered; - } - - /** - * Sets the current page search string - * @param string $string A string used to determine if a page is current - */ - public function setCurrent($string) { - $this->current = str_replace(@URLBASE, "/", str_replace("index.php", "", $string)); - - if (class_exists('\Sleepy\Hook')) { - $this->current = \Sleepy\Hook::addFilter('navigation_current_page', $this->current); - } - } -} \ No newline at end of file diff --git a/navigation_test.php b/navigation_test.php deleted file mode 100644 index 2f02abe..0000000 --- a/navigation_test.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @version 1.8 - * @license http://opensource.org/licenses/MIT - */ -class TestOfNavigation extends UnitTestCase { - function setUp() { - $this->nav = new \Module\Navigation\Builder('{ - "pages": [ - { - "title": "1", - "target": "_blank", - "link": "1.html", - "pages": [ - { - "title": "1.1", - "link": "1.1.html" - }, { - "title": "1.2", - "link": "1.2.html" - } - ] - }, { - "id": "second", - "title": "2", - "link": "2.html", - "class": "second" - } - ] - }'); - } - - function testNav() { - $nav = $this->nav->show(); - $this->assertEqual($nav,''); - } - - function testTarget() { - $nav = $this->nav->show(); - $this->assertEqual($nav,''); - } - - function testActive() { - $this->nav->setCurrent('1.html'); - $nav = $this->nav->show(); - $this->assertEqual($nav,''); - } - - function testSubActive() { - $this->nav->setCurrent('1.1.html'); - $nav = $this->nav->show(); - $this->assertEqual($nav,''); - } -} \ No newline at end of file diff --git a/tests/BuilderTest.php b/tests/BuilderTest.php new file mode 100644 index 0000000..2b7aa52 --- /dev/null +++ b/tests/BuilderTest.php @@ -0,0 +1,166 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +require_once dirname(__FILE__) . "/../../../sleepy/core/Loader.php"; + +use PHPUnit\Framework\TestCase; +use Sleepy\Core\SM; +use Sleepy\Core\Hook; +use Sleepy\Core\Loader; +use Module\Navigation\Builder; + +Loader::register(); +Loader::addNamespace("Sleepy", dirname(__FILE__) . "/../../../sleepy"); +Loader::addNamespace("Sleepy\Core", dirname(__FILE__) . "/../../../sleepy/core"); +Loader::addNamespace("Module", dirname(__FILE__) . "/../../../modules"); + +require_once dirname(__FILE__) . "/../../../../settings.php"; + +/** + * Builder Unit Test + * + * @category Test + * @package Module\Navigation + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class BuilderTest extends TestCase +{ + /** + * Setup method + * + * @return void + */ + public function setUp() : void + { + $this->nav = new \Module\Navigation\Builder( + '{ + "pages": [ + { + "title": "1", + "target": "_blank", + "link": "1.html", + "pages": [ + { + "title": "1.1", + "link": "1.1.html" + }, { + "title": "1.2", + "link": "1.2.html" + } + ] + }, { + "id": "second", + "title": "2", + "link": "2.html", + "class": "second" + } + ] + }' + ); + } + + /** + * Test if Actions work + * + * @return void + */ + public function testNav() : void + { + $nav = $this->nav->show(); + $this->assertEquals( + $nav, + implode( + [ + '' + ] + ) + ); + } + + /** + * Test if Targets works + * + * @return void + */ + public function testTarget() : void + { + $nav = $this->nav->show(); + $this->assertEquals( + $nav, + implode( + [ + '' + ] + ) + ); + } + + /** + * Test if Active works + * + * @return void + */ + public function testActive() : void + { + $this->nav->setCurrent('1.html'); + $nav = $this->nav->show(); + $this->assertEquals( + $nav, + implode( + [ + '' + ] + ) + ); + } + + /** + * Test if SubActive works + * + * @return void + */ + public function testSubActive() : void + { + $this->nav->setCurrent('1.1.html'); + $nav = $this->nav->show(); + $this->assertEquals( + $nav, + implode( + [ + '' + ] + ) + ); + } +} \ No newline at end of file