https://www.mediawiki.org/wiki/Special:Code/MediaWiki/113252
Revision: 113252
Author: netbrain
Date: 2012-03-07 17:31:29 +0000 (Wed, 07 Mar 2012)
Log Message:
-----------
initial import of SideBarMenu wikimedia extension
Modified Paths:
--------------
trunk/extensions/SideBarMenu/README
Added Paths:
-----------
trunk/extensions/SideBarMenu/SideBarMenu.body.php
trunk/extensions/SideBarMenu/SideBarMenu.i18n.php
trunk/extensions/SideBarMenu/SideBarMenu.php
trunk/extensions/SideBarMenu/includes/
trunk/extensions/SideBarMenu/includes/MenuItem.php
trunk/extensions/SideBarMenu/includes/MenuParser.php
trunk/extensions/SideBarMenu/test/
trunk/extensions/SideBarMenu/test/MenuItemTest.php
trunk/extensions/SideBarMenu/test/MenuParserTest.php
Modified: trunk/extensions/SideBarMenu/README
===================================================================
--- trunk/extensions/SideBarMenu/README 2012-03-07 17:31:18 UTC (rev 113251)
+++ trunk/extensions/SideBarMenu/README 2012-03-07 17:31:29 UTC (rev 113252)
@@ -0,0 +1,4 @@
+== INSTALL ==
+1. Copy SideBarMenu to /path/to/mediawiki/extension/
+2. append "require_once( "$IP/extensions/SideBarMenu/SideBarMenu.php" );" to
LocalSettings.php
+
Copied: trunk/extensions/SideBarMenu/SideBarMenu.body.php (from rev 113251,
trunk/extensions/SideBarMenu/README)
===================================================================
Copied: trunk/extensions/SideBarMenu/SideBarMenu.i18n.php (from rev 113251,
trunk/extensions/SideBarMenu/README)
===================================================================
Added: trunk/extensions/SideBarMenu/SideBarMenu.php
===================================================================
--- trunk/extensions/SideBarMenu/SideBarMenu.php
(rev 0)
+++ trunk/extensions/SideBarMenu/SideBarMenu.php 2012-03-07 17:31:29 UTC
(rev 113252)
@@ -0,0 +1,63 @@
+<?php
+
+if (!defined('MEDIAWIKI')) {
+ die('Not an entry point.');
+}
+
+$wgExtensionCredits['parserhook'][] = array(
+ 'path' => __FILE__,
+ 'name' => 'SideBarMenu',
+ 'version' => 0.1,
+ 'author' => 'Kim Eik',
+ 'url' => 'https://www.mediawiki.org/wiki/Extension:SideBarMenu',
+ 'descriptionmsg' => 'A simple sidebar menu parser which creates
collapsable/expandable menus and sub-menus.'
+);
+
+
+// Specify the function that will initialize the parser function.
+$wgHooks['ParserFirstCallInit'][] = 'init';
+
+// Specify the function that will register the magic words for the parser
function.
+$wgHooks['LanguageGetMagic'][] = 'registerMagicWords';
+
+// Sepcify phpunit tests
+$wgHooks['UnitTestsList'][] = 'registerUnitTests';
+
+//Autoload
+$wgMyExtensionIncludes = dirname(__FILE__) . '/includes';
+## Special page class
+$wgAutoloadClasses['MenuParser'] = $wgMyExtensionIncludes . '/MenuParser.php';
+$wgAutoloadClasses['MenuItem'] = $wgMyExtensionIncludes . '/MenuItem.php';
+
+
+function init(&$parser){
+ $parser->setHook('sidebarmenu','renderFromTag');
+ return true;
+}
+
+function registerMagicWords(&$magicWords, $langCode){
+ $magicWords['sidebarmenu'] = array(0,'sidebarmenu');
+ return true;
+}
+
+function renderFromTag( $input, array $args, Parser $parser, PPFrame $frame ){
+ try{
+ $menuHTML = MenuParser::getMenuTree($input)->toHTML();
+ return $parser->recursiveTagParse($menuHTML,$frame);
+ }catch(Exception $x){
+ wfDebug("An error occured during parsing of: '$input' caught
exception: $x");
+ return "FATAL ERROR: Could not parse the following
input:</br><pre>$input</pre>";
+ }
+}
+
+function registerUnitTests( &$files ) {
+ $testDir = dirname( __FILE__ ) . '/test/';
+ $testFiles = scandir($testDir);
+ foreach($testFiles as $testFile){
+ $absoluteFile = $testDir . $testFile;
+ if(is_file($absoluteFile)){
+ $files[] = $absoluteFile;
+ }
+ }
+ return true;
+}
Added: trunk/extensions/SideBarMenu/includes/MenuItem.php
===================================================================
--- trunk/extensions/SideBarMenu/includes/MenuItem.php
(rev 0)
+++ trunk/extensions/SideBarMenu/includes/MenuItem.php 2012-03-07 17:31:29 UTC
(rev 113252)
@@ -0,0 +1,99 @@
+<?php
+
+class MenuItem
+{
+ private $expanded;
+ private $children = array();
+ private $parent = null;
+ private $text;
+
+ public function setExpanded($expanded)
+ {
+ $this->expanded = $expanded;
+ }
+
+ public function isExpanded()
+ {
+ return $this->expanded;
+ }
+
+ public function setText($link)
+ {
+ $this->text = $link;
+ }
+
+ public function getText()
+ {
+ return $this->text;
+ }
+
+ public function addChild(MenuItem $child)
+ {
+ if(!in_array($child,$this->children)){
+ $this->children[] = $child;
+ $child->setParent($this);
+ }
+ }
+
+ public function getChildren()
+ {
+ return $this->children;
+ }
+
+ public function hasChildren()
+ {
+ return sizeof($this->children) > 0;
+ }
+
+ public function setParent(MenuItem $parent)
+ {
+ if($this->parent !== $parent){
+ $this->parent = $parent;
+ $parent->addChild($this);
+ }
+ }
+
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ public function isRoot(){
+ return is_null($this->parent);
+ }
+
+ public function getLevel(){
+ if($this->isRoot()){
+ return 0;
+ }else{
+ return 1+$this->getParent()->getLevel();
+ }
+ }
+
+ public function toHTML()
+ {
+ $output = "";
+ if($this->isRoot()){
+ $output .= $this->childrenToHTML();
+ }else{
+ $output .= "<li class=\"sidebar-menu-item
sidebar-menu-item-".$this->getLevel().' '.($this->isExpanded() ?
'sidebar-menu-item-expanded' : 'sidebar-menu-item-collapsed')."\"><div
class=\"sidebar-menu-item-text
sidebar-menu-item-text-".$this->getLevel()."\">".$this->getText()."</div>";
+ $output .= $this->childrenToHTML();
+ $output .= "</li>";
+ }
+
+ return $output;
+ }
+
+ private function childrenToHTML()
+ {
+ if($this->hasChildren()){
+ $output = "<ul class=\"sidebar-menu
sidebar-menu-".$this->getLevel()."\">";
+ foreach ($this->getChildren() as $child) {
+ $output .= $child->toHTML();
+ }
+ $output .= "</ul>";
+ return $output;
+ }
+ }
+
+}
Added: trunk/extensions/SideBarMenu/includes/MenuParser.php
===================================================================
--- trunk/extensions/SideBarMenu/includes/MenuParser.php
(rev 0)
+++ trunk/extensions/SideBarMenu/includes/MenuParser.php 2012-03-07
17:31:29 UTC (rev 113252)
@@ -0,0 +1,123 @@
+<?php
+class MenuParser {
+
+ public static function isRoot($line)
+ {
+ return !self::startsWith($line, '*');
+ }
+
+ public static function isValidInput($data)
+ {
+ return !(is_null($data) || strlen($data) == 0);
+ }
+
+
+ public static function getLevel($line)
+ {
+ return substr_count($line, '*');
+ }
+
+ public static function getExpandedParameter($line)
+ {
+ if (self::startsWith($line, '+')) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static function getTextParameter($line)
+ {
+ return preg_filter("/\+|\-?\**(.*)/", "$1", $line);
+ }
+
+
+ public static function getMenuTree($data){
+ if(self::isValidInput($data)){
+ $data = self::cleanupData($data);
+ $root = new MenuItem();
+ $root->setExpanded(true);
+ $arrayData = self::parseDataIntoHierarchicalArray($data);
+ self::addChildrenToMenuItemFromArrayData($root,$arrayData);
+ return $root;
+ }
+ }
+
+
+ public static function getMenuItem($line)
+ {
+ $line = trim($line);
+ if(self::isValidInput($line)){
+ $menuItem = new MenuItem();
+ $menuItem->setExpanded(self::getExpandedParameter($line));
+ $menuItem->setText(self::getTextParameter($line));
+ return $menuItem;
+ }else{
+ throw new InvalidArgumentException();
+ }
+ }
+
+ public static function parseDataIntoHierarchicalArray($data)
+ {
+ $rootArray = array();
+ $prevArray = &$rootArray;
+ $prevLevel = 0;
+ $levelArray[0] = &$rootArray;
+ foreach(preg_split("/\n/",$data) as $line){
+ $level = self::getLevel($line);
+ if($level == $prevLevel){
+ $levelArray[$level][] = $line;
+ }else if($level-1 == $prevLevel){
+ //child of previous line
+ $parent = array_pop($levelArray[$level-1]);
+ $levelArray[$level-1][$parent][] = $line;
+ $levelArray[$level] = &$levelArray[$level-1][$parent];
+ }else if($level < $prevLevel){
+ //back some levels
+ $levelArray[$level][] = $line;
+ }else{
+ //syntax error
+ throw new InvalidArgumentException();
+ }
+ $prevLevel = $level;
+ }
+ return $rootArray;
+ }
+
+ public static function
addChildrenToMenuItemFromArrayData(&$rootMenuItem,$arrayData)
+ {
+ foreach ($arrayData as $key => $val) {
+ if (is_string($key)) {
+ $menuItem = self::getMenuItem($key);
+ $rootMenuItem->addChild($menuItem);
+ self::addChildrenToMenuItemFromArrayData($menuItem,$val);
+ } else {
+ $menuItem = self::getMenuItem($val);
+ $rootMenuItem->addChild($menuItem);
+ }
+ }
+ }
+
+ private static function startsWith($haystack, $needle)
+ {
+ $length = strlen($needle);
+ return (substr($haystack, 0, $length) === $needle);
+ }
+
+ private static function cleanupData($data){
+ for($x = 0; $x < 2; $x++){
+ $data = self::removeLineBreaksFromStartOfString($data);
+ $data = strrev($data);
+ }
+ return $data;
+ }
+
+ private static function removeLineBreaksFromStartOfString($data)
+ {
+ while (self::startsWith($data, "\n")) {
+ $data = substr($data, 1);
+ }
+ return $data;
+ }
+
+}
\ No newline at end of file
Added: trunk/extensions/SideBarMenu/test/MenuItemTest.php
===================================================================
--- trunk/extensions/SideBarMenu/test/MenuItemTest.php
(rev 0)
+++ trunk/extensions/SideBarMenu/test/MenuItemTest.php 2012-03-07 17:31:29 UTC
(rev 113252)
@@ -0,0 +1,104 @@
+<?php
+
+class MenuItemTest extends MediaWikiTestCase
+{
+ private $menuItem;
+
+ protected function setUp()
+ {
+ $this->menuItem = new MenuItem();
+ }
+
+ public function testIsRoot(){
+ $this->assertTrue($this->menuItem->isRoot());
+ }
+
+ public function testIsNotRoot(){
+ $this->menuItem->setParent(new MenuItem());
+ $this->assertFalse($this->menuItem->isRoot());
+ }
+
+ public function testGetLevelWhenRoot(){
+ $this->assertEquals(0,$this->menuItem->getLevel());
+ }
+
+ public function testGetLevelWhenChild(){
+ $this->menuItem->setParent(new MenuItem());
+ $this->assertEquals(1,$this->menuItem->getLevel());
+ }
+
+ public function testGetLevelWhenSeveralChildren(){
+ $prev = $this->menuItem;
+ for($x = 0; $x < 10; $x++){
+ $child = new MenuItem();
+ $child->setParent($prev);
+ $prev = $child;
+
+ }
+ $this->assertEquals(10,$prev->getLevel());
+ }
+
+ public function testAddChildAlsoAddsParent(){
+ $child = new MenuItem();
+ $this->menuItem->addChild($child);
+ $this->assertContains($child,$this->menuItem->getChildren());
+ $this->assertEquals($child->getParent(),$this->menuItem);
+ }
+
+ public function testAddSameChildSeveralTimes(){
+ $child = new MenuItem();
+ for($x = 0; $x < 3; $x++){
+ $this->menuItem->addChild($child);
+ }
+ $this->assertEquals(1,sizeof($this->menuItem->getChildren()));
+ }
+
+ public function testAddParentAlsoAddsChild(){
+ $parent = new MenuItem();
+ $this->menuItem->setParent($parent);
+ $this->assertContains($this->menuItem,$parent->getChildren());
+ }
+
+ public function testToHTMLOnRootMenuItem(){
+ $html = $this->menuItem->toHTML();
+ $this->assertEquals("",$html);
+ }
+
+ public function testToHTMLOnProperMenuItem(){
+ $menuItemChild = new MenuItem();
+ $menuItemChild->setText("MenuItem1");
+ $this->menuItem->addChild($menuItemChild);
+ $html = $this->menuItem->toHTML();
+ $this->assertEquals('<ul class="sidebar-menu sidebar-menu-0"><li
class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div
class="sidebar-menu-item-text
sidebar-menu-item-text-1">MenuItem1</div></li></ul>',$html);
+ }
+
+ public function testToHTMLOnSeveralMenuItems(){
+ $menuItemChild1 = new MenuItem();
+ $menuItemChild1->setText("MenuItem1");
+ $menuItemChild2 = new MenuItem();
+ $menuItemChild2->setText("MenuItem2");
+
+ $this->menuItem->addChild($menuItemChild1);
+ $this->menuItem->addChild($menuItemChild2);
+
+ $html = $this->menuItem->toHTML();
+ $this->assertEquals('<ul class="sidebar-menu sidebar-menu-0"><li
class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div
class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem1</div></li><li
class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div
class="sidebar-menu-item-text
sidebar-menu-item-text-1">MenuItem2</div></li></ul>',$html);
+ }
+
+ public function testToHTMLOnSeveralMenuItemsWithSublevels(){
+ $menuItemChild1 = new MenuItem();
+ $menuItemChild1->setText("MenuItem1");
+ $menuItemChild2 = new MenuItem();
+ $menuItemChild2->setText("MenuItem2");
+
+ $this->menuItem->addChild($menuItemChild1);
+ $this->menuItem->addChild($menuItemChild2);
+
+ $subLevel1 = new MenuItem();
+ $subLevel1->setText("SubMenuItem1");
+ $subLevel1->setParent($menuItemChild2);
+
+ $html = $this->menuItem->toHTML();
+ $this->assertEquals('<ul class="sidebar-menu sidebar-menu-0"><li
class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div
class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem1</div></li><li
class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div
class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem2</div><ul
class="sidebar-menu sidebar-menu-1"><li class="sidebar-menu-item
sidebar-menu-item-2 sidebar-menu-item-collapsed"><div
class="sidebar-menu-item-text
sidebar-menu-item-text-2">SubMenuItem1</div></li></ul></li></ul>',$html);
+ }
+}
Added: trunk/extensions/SideBarMenu/test/MenuParserTest.php
===================================================================
--- trunk/extensions/SideBarMenu/test/MenuParserTest.php
(rev 0)
+++ trunk/extensions/SideBarMenu/test/MenuParserTest.php 2012-03-07
17:31:29 UTC (rev 113252)
@@ -0,0 +1,214 @@
+<?php
+
+class MenuParserTest extends MediaWikiTestCase
+{
+
+ public function testValidInputWhenNull(){
+ $this->assertFalse(MenuParser::isValidInput(null));
+ }
+
+ public function testValidInputWhenEmpty(){
+ $this->assertFalse(MenuParser::isValidInput(""));
+ }
+
+ public function testValidInput(){
+ $this->assertTrue(MenuParser::isValidInput("+MenuItem"));
+ }
+
+ public function testIsRoot(){
+ $isRoot = MenuParser::isRoot("MenuItem");
+ $this->assertTrue($isRoot);
+ }
+
+ public function testIsNotRoot(){
+ $isRoot = MenuParser::isRoot("*MenuItem");
+ $this->assertFalse($isRoot);
+ }
+
+ public function testGetLevelWhenNull(){
+ $this->assertEquals(0,MenuParser::getLevel(null));
+ }
+
+ public function testGetLevelWhenEmpty(){
+ $this->assertEquals(0,MenuParser::getLevel(""));
+ }
+
+ public function testGetLevelWhenValidButNoStars(){
+ $this->assertEquals(0,MenuParser::getLevel(""));
+ }
+
+ public function testGetLevelWithValid(){
+ $this->assertEquals(3,MenuParser::getLevel("***MenuItem"));
+ }
+
+ public function testGetExpandedParameterWhenNoneSupplied(){
+ //default is false
+ $this->assertFalse(MenuParser::getExpandedParameter("MenuItem"));
+ }
+
+ public function testGetExpandedParameterWhenNotExpanded(){
+ $this->assertFalse(MenuParser::getExpandedParameter("-MenuItem"));
+ }
+
+ public function testGetExpandedParameterWhenExpanded(){
+ $this->assertTrue(MenuParser::getExpandedParameter("+MenuItem"));
+ }
+
+ public function testGetTextParameter(){
+
$this->assertEquals("MenuItem",MenuParser::getTextParameter("+***MenuItem"));
+
$this->assertEquals("+MenuItem",MenuParser::getTextParameter("+***+MenuItem"));
+
$this->assertEquals("MenuItem",MenuParser::getTextParameter("-MenuItem"));
+
$this->assertEquals("MenuItem",MenuParser::getTextParameter("-*MenuItem"));
+
$this->assertEquals("MenuItem",MenuParser::getTextParameter("MenuItem"));
+
$this->assertEquals("+*MenuItem",MenuParser::getTextParameter("+***+*MenuItem"));
+ }
+
+ public function testGetMenuItemWhenInputIsNull(){
+ $this->setExpectedException('InvalidArgumentException');
+ $this->assertNull(MenuParser::getMenuItem(null));
+ }
+
+ public function testGetMenuItemWhenInputIsEmpty(){
+ $this->setExpectedException('InvalidArgumentException');
+ $this->assertNull(MenuParser::getMenuItem(""));
+ }
+
+ public function testGetMenuItemWhenInputIsValid(){
+ $data = "MenuItem";
+ $menuItem = MenuParser::getMenuItem($data);
+ $this->assertNotNull($menuItem);
+ $this->assertEquals($data,$menuItem->getText());
+ $this->assertFalse($menuItem->isExpanded()); //false is default
+ }
+
+ public function testGetMenuItemWhenInputIsValidAndExpandIsSet(){
+ $text = "MenuItem";
+ $data = "+".$text;
+ $menuItem = MenuParser::getMenuItem($data);
+ $this->assertNotNull($menuItem);
+ $this->assertEquals($text,$menuItem->getText());
+ $this->assertTrue($menuItem->isExpanded()); //false is default
+ }
+
+ public function testParseDataIntoHierarchicalArray(){
+ $data = "MenuItem";
+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
+ $this->assertNotNull($array);
+ $this->assertEquals($data,$array[0]);
+ }
+
+ public function testParseDataIntoHierarchicalArrayWithSubLevel(){
+ $lines = array("MenuItem","*SubMenuItem");
+ $data = join("\n",$lines);
+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
+ $this->assertNotNull($array);
+ $this->assertArrayHasKey($lines[0],$array);
+ $this->assertEquals(
+ array(
+ 'MenuItem' => array(
+ '*SubMenuItem'
+ )
+ ),$array
+ );
+ }
+
+ public function testParseDataIntoHierarchicalArrayWithSeveralSubLevels(){
+ $lines =
array("MenuItem","*SubMenuItem","*SubMenuItem2","**SubMenuItemOf2");
+ $data = join("\n",$lines);
+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
+ $this->assertNotNull($array);
+ $this->assertEquals(
+ array(
+ 'MenuItem' => array(
+ '*SubMenuItem',
+ '*SubMenuItem2' => array(
+ '**SubMenuItemOf2'
+ )
+ )
+ ),$array
+ );
+ }
+
+ public function testParseDataIntoHierarchicalArrayWithSubLevelAndBack(){
+ $lines = array("MenuItem","*SubMenuItem","MenuItem2");
+ $data = join("\n",$lines);
+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
+ $this->assertNotNull($array);
+ $this->assertEquals(
+ array(
+ 'MenuItem' => array(
+ '*SubMenuItem'
+ ),
+ 'MenuItem2'
+ ),$array
+ );
+ }
+
+ public function
testParseDataIntoHierarchicalArrayWithSubLevelAndBackSeveralLevels(){
+ $lines =
array("MenuItem","*SubMenuItem1","**SubMenuItem2","***SubMenuItem3","MenuItem2");
+ $data = join("\n",$lines);
+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
+ $this->assertNotNull($array);
+ $this->assertEquals(
+ array(
+ 'MenuItem' => array(
+ '*SubMenuItem1' => array(
+ '**SubMenuItem2' => array(
+ '***SubMenuItem3'
+ )
+ )
+ ),
+ 'MenuItem2'
+ ),$array
+ );
+ }
+
+
+ public function testGetMenuWithInvalidInput(){
+ $this->assertNull(MenuParser::getMenuTree(null));
+ $this->assertNull(MenuParser::getMenuTree(""));
+ }
+
+ public function testGetMenuWithValidInput(){
+ $menu = MenuParser::getMenuTree("MenuItem");
+ $this->assertNotNull($menu);
+ $this->assertTrue($menu->isRoot());
+ $this->assertEquals(1,sizeof($menu->getChildren()));
+
+ $children = $menu->getChildren();
+ $this->assertEquals("MenuItem",$children[0]->getText());
+ }
+
+ public function testGetMenuWithValidComplexInput(){
+ $data = array(
+ 'MenuItem1',
+ '*SubMenuItem1',
+ '*SubMenuItem2',
+ '*SubMenuItem3',
+ '**SubMenuItem1Of1',
+ '**SubMenuItem2Of1',
+ 'MenuItem2',
+ '*SubMenuItem1OfMenuItem2'
+ );
+ $menu = MenuParser::getMenuTree(join("\n",$data));
+ $this->assertNotNull($menu);
+ $this->assertEquals(2,sizeof($menu->getChildren()));
+
+ }
+
+ public function testGetMenuWithSeveralLineBreaks(){
+ $data = array(
+ '',
+ 'MenuItem1',
+ '',
+ ''
+ );
+ $menu = MenuParser::getMenuTree(join("\n",$data));
+ $this->assertNotNull($menu);
+ $this->assertEquals(1,sizeof($menu->getChildren()));
+
+ $children = $menu->getChildren();
+ $this->assertEquals("MenuItem1",$children[0]->getText());
+
+ }
+}
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs