Index: trunk/extensions/SideBarMenu/test/MenuParserTest.php |
— | — | @@ -0,0 +1,214 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class MenuParserTest extends MediaWikiTestCase |
| 5 | +{ |
| 6 | + |
| 7 | + public function testValidInputWhenNull(){ |
| 8 | + $this->assertFalse(MenuParser::isValidInput(null)); |
| 9 | + } |
| 10 | + |
| 11 | + public function testValidInputWhenEmpty(){ |
| 12 | + $this->assertFalse(MenuParser::isValidInput("")); |
| 13 | + } |
| 14 | + |
| 15 | + public function testValidInput(){ |
| 16 | + $this->assertTrue(MenuParser::isValidInput("+MenuItem")); |
| 17 | + } |
| 18 | + |
| 19 | + public function testIsRoot(){ |
| 20 | + $isRoot = MenuParser::isRoot("MenuItem"); |
| 21 | + $this->assertTrue($isRoot); |
| 22 | + } |
| 23 | + |
| 24 | + public function testIsNotRoot(){ |
| 25 | + $isRoot = MenuParser::isRoot("*MenuItem"); |
| 26 | + $this->assertFalse($isRoot); |
| 27 | + } |
| 28 | + |
| 29 | + public function testGetLevelWhenNull(){ |
| 30 | + $this->assertEquals(0,MenuParser::getLevel(null)); |
| 31 | + } |
| 32 | + |
| 33 | + public function testGetLevelWhenEmpty(){ |
| 34 | + $this->assertEquals(0,MenuParser::getLevel("")); |
| 35 | + } |
| 36 | + |
| 37 | + public function testGetLevelWhenValidButNoStars(){ |
| 38 | + $this->assertEquals(0,MenuParser::getLevel("")); |
| 39 | + } |
| 40 | + |
| 41 | + public function testGetLevelWithValid(){ |
| 42 | + $this->assertEquals(3,MenuParser::getLevel("***MenuItem")); |
| 43 | + } |
| 44 | + |
| 45 | + public function testGetExpandedParameterWhenNoneSupplied(){ |
| 46 | + //default is false |
| 47 | + $this->assertFalse(MenuParser::getExpandedParameter("MenuItem")); |
| 48 | + } |
| 49 | + |
| 50 | + public function testGetExpandedParameterWhenNotExpanded(){ |
| 51 | + $this->assertFalse(MenuParser::getExpandedParameter("-MenuItem")); |
| 52 | + } |
| 53 | + |
| 54 | + public function testGetExpandedParameterWhenExpanded(){ |
| 55 | + $this->assertTrue(MenuParser::getExpandedParameter("+MenuItem")); |
| 56 | + } |
| 57 | + |
| 58 | + public function testGetTextParameter(){ |
| 59 | + $this->assertEquals("MenuItem",MenuParser::getTextParameter("+***MenuItem")); |
| 60 | + $this->assertEquals("+MenuItem",MenuParser::getTextParameter("+***+MenuItem")); |
| 61 | + $this->assertEquals("MenuItem",MenuParser::getTextParameter("-MenuItem")); |
| 62 | + $this->assertEquals("MenuItem",MenuParser::getTextParameter("-*MenuItem")); |
| 63 | + $this->assertEquals("MenuItem",MenuParser::getTextParameter("MenuItem")); |
| 64 | + $this->assertEquals("+*MenuItem",MenuParser::getTextParameter("+***+*MenuItem")); |
| 65 | + } |
| 66 | + |
| 67 | + public function testGetMenuItemWhenInputIsNull(){ |
| 68 | + $this->setExpectedException('InvalidArgumentException'); |
| 69 | + $this->assertNull(MenuParser::getMenuItem(null)); |
| 70 | + } |
| 71 | + |
| 72 | + public function testGetMenuItemWhenInputIsEmpty(){ |
| 73 | + $this->setExpectedException('InvalidArgumentException'); |
| 74 | + $this->assertNull(MenuParser::getMenuItem("")); |
| 75 | + } |
| 76 | + |
| 77 | + public function testGetMenuItemWhenInputIsValid(){ |
| 78 | + $data = "MenuItem"; |
| 79 | + $menuItem = MenuParser::getMenuItem($data); |
| 80 | + $this->assertNotNull($menuItem); |
| 81 | + $this->assertEquals($data,$menuItem->getText()); |
| 82 | + $this->assertFalse($menuItem->isExpanded()); //false is default |
| 83 | + } |
| 84 | + |
| 85 | + public function testGetMenuItemWhenInputIsValidAndExpandIsSet(){ |
| 86 | + $text = "MenuItem"; |
| 87 | + $data = "+".$text; |
| 88 | + $menuItem = MenuParser::getMenuItem($data); |
| 89 | + $this->assertNotNull($menuItem); |
| 90 | + $this->assertEquals($text,$menuItem->getText()); |
| 91 | + $this->assertTrue($menuItem->isExpanded()); //false is default |
| 92 | + } |
| 93 | + |
| 94 | + public function testParseDataIntoHierarchicalArray(){ |
| 95 | + $data = "MenuItem"; |
| 96 | + $array = MenuParser::parseDataIntoHierarchicalArray($data); |
| 97 | + $this->assertNotNull($array); |
| 98 | + $this->assertEquals($data,$array[0]); |
| 99 | + } |
| 100 | + |
| 101 | + public function testParseDataIntoHierarchicalArrayWithSubLevel(){ |
| 102 | + $lines = array("MenuItem","*SubMenuItem"); |
| 103 | + $data = join("\n",$lines); |
| 104 | + $array = MenuParser::parseDataIntoHierarchicalArray($data); |
| 105 | + $this->assertNotNull($array); |
| 106 | + $this->assertArrayHasKey($lines[0],$array); |
| 107 | + $this->assertEquals( |
| 108 | + array( |
| 109 | + 'MenuItem' => array( |
| 110 | + '*SubMenuItem' |
| 111 | + ) |
| 112 | + ),$array |
| 113 | + ); |
| 114 | + } |
| 115 | + |
| 116 | + public function testParseDataIntoHierarchicalArrayWithSeveralSubLevels(){ |
| 117 | + $lines = array("MenuItem","*SubMenuItem","*SubMenuItem2","**SubMenuItemOf2"); |
| 118 | + $data = join("\n",$lines); |
| 119 | + $array = MenuParser::parseDataIntoHierarchicalArray($data); |
| 120 | + $this->assertNotNull($array); |
| 121 | + $this->assertEquals( |
| 122 | + array( |
| 123 | + 'MenuItem' => array( |
| 124 | + '*SubMenuItem', |
| 125 | + '*SubMenuItem2' => array( |
| 126 | + '**SubMenuItemOf2' |
| 127 | + ) |
| 128 | + ) |
| 129 | + ),$array |
| 130 | + ); |
| 131 | + } |
| 132 | + |
| 133 | + public function testParseDataIntoHierarchicalArrayWithSubLevelAndBack(){ |
| 134 | + $lines = array("MenuItem","*SubMenuItem","MenuItem2"); |
| 135 | + $data = join("\n",$lines); |
| 136 | + $array = MenuParser::parseDataIntoHierarchicalArray($data); |
| 137 | + $this->assertNotNull($array); |
| 138 | + $this->assertEquals( |
| 139 | + array( |
| 140 | + 'MenuItem' => array( |
| 141 | + '*SubMenuItem' |
| 142 | + ), |
| 143 | + 'MenuItem2' |
| 144 | + ),$array |
| 145 | + ); |
| 146 | + } |
| 147 | + |
| 148 | + public function testParseDataIntoHierarchicalArrayWithSubLevelAndBackSeveralLevels(){ |
| 149 | + $lines = array("MenuItem","*SubMenuItem1","**SubMenuItem2","***SubMenuItem3","MenuItem2"); |
| 150 | + $data = join("\n",$lines); |
| 151 | + $array = MenuParser::parseDataIntoHierarchicalArray($data); |
| 152 | + $this->assertNotNull($array); |
| 153 | + $this->assertEquals( |
| 154 | + array( |
| 155 | + 'MenuItem' => array( |
| 156 | + '*SubMenuItem1' => array( |
| 157 | + '**SubMenuItem2' => array( |
| 158 | + '***SubMenuItem3' |
| 159 | + ) |
| 160 | + ) |
| 161 | + ), |
| 162 | + 'MenuItem2' |
| 163 | + ),$array |
| 164 | + ); |
| 165 | + } |
| 166 | + |
| 167 | + |
| 168 | + public function testGetMenuWithInvalidInput(){ |
| 169 | + $this->assertNull(MenuParser::getMenuTree(null)); |
| 170 | + $this->assertNull(MenuParser::getMenuTree("")); |
| 171 | + } |
| 172 | + |
| 173 | + public function testGetMenuWithValidInput(){ |
| 174 | + $menu = MenuParser::getMenuTree("MenuItem"); |
| 175 | + $this->assertNotNull($menu); |
| 176 | + $this->assertTrue($menu->isRoot()); |
| 177 | + $this->assertEquals(1,sizeof($menu->getChildren())); |
| 178 | + |
| 179 | + $children = $menu->getChildren(); |
| 180 | + $this->assertEquals("MenuItem",$children[0]->getText()); |
| 181 | + } |
| 182 | + |
| 183 | + public function testGetMenuWithValidComplexInput(){ |
| 184 | + $data = array( |
| 185 | + 'MenuItem1', |
| 186 | + '*SubMenuItem1', |
| 187 | + '*SubMenuItem2', |
| 188 | + '*SubMenuItem3', |
| 189 | + '**SubMenuItem1Of1', |
| 190 | + '**SubMenuItem2Of1', |
| 191 | + 'MenuItem2', |
| 192 | + '*SubMenuItem1OfMenuItem2' |
| 193 | + ); |
| 194 | + $menu = MenuParser::getMenuTree(join("\n",$data)); |
| 195 | + $this->assertNotNull($menu); |
| 196 | + $this->assertEquals(2,sizeof($menu->getChildren())); |
| 197 | + |
| 198 | + } |
| 199 | + |
| 200 | + public function testGetMenuWithSeveralLineBreaks(){ |
| 201 | + $data = array( |
| 202 | + '', |
| 203 | + 'MenuItem1', |
| 204 | + '', |
| 205 | + '' |
| 206 | + ); |
| 207 | + $menu = MenuParser::getMenuTree(join("\n",$data)); |
| 208 | + $this->assertNotNull($menu); |
| 209 | + $this->assertEquals(1,sizeof($menu->getChildren())); |
| 210 | + |
| 211 | + $children = $menu->getChildren(); |
| 212 | + $this->assertEquals("MenuItem1",$children[0]->getText()); |
| 213 | + |
| 214 | + } |
| 215 | +} |
Index: trunk/extensions/SideBarMenu/test/MenuItemTest.php |
— | — | @@ -0,0 +1,104 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class MenuItemTest extends MediaWikiTestCase |
| 5 | +{ |
| 6 | + private $menuItem; |
| 7 | + |
| 8 | + protected function setUp() |
| 9 | + { |
| 10 | + $this->menuItem = new MenuItem(); |
| 11 | + } |
| 12 | + |
| 13 | + public function testIsRoot(){ |
| 14 | + $this->assertTrue($this->menuItem->isRoot()); |
| 15 | + } |
| 16 | + |
| 17 | + public function testIsNotRoot(){ |
| 18 | + $this->menuItem->setParent(new MenuItem()); |
| 19 | + $this->assertFalse($this->menuItem->isRoot()); |
| 20 | + } |
| 21 | + |
| 22 | + public function testGetLevelWhenRoot(){ |
| 23 | + $this->assertEquals(0,$this->menuItem->getLevel()); |
| 24 | + } |
| 25 | + |
| 26 | + public function testGetLevelWhenChild(){ |
| 27 | + $this->menuItem->setParent(new MenuItem()); |
| 28 | + $this->assertEquals(1,$this->menuItem->getLevel()); |
| 29 | + } |
| 30 | + |
| 31 | + public function testGetLevelWhenSeveralChildren(){ |
| 32 | + $prev = $this->menuItem; |
| 33 | + for($x = 0; $x < 10; $x++){ |
| 34 | + $child = new MenuItem(); |
| 35 | + $child->setParent($prev); |
| 36 | + $prev = $child; |
| 37 | + |
| 38 | + } |
| 39 | + $this->assertEquals(10,$prev->getLevel()); |
| 40 | + } |
| 41 | + |
| 42 | + public function testAddChildAlsoAddsParent(){ |
| 43 | + $child = new MenuItem(); |
| 44 | + $this->menuItem->addChild($child); |
| 45 | + $this->assertContains($child,$this->menuItem->getChildren()); |
| 46 | + $this->assertEquals($child->getParent(),$this->menuItem); |
| 47 | + } |
| 48 | + |
| 49 | + public function testAddSameChildSeveralTimes(){ |
| 50 | + $child = new MenuItem(); |
| 51 | + for($x = 0; $x < 3; $x++){ |
| 52 | + $this->menuItem->addChild($child); |
| 53 | + } |
| 54 | + $this->assertEquals(1,sizeof($this->menuItem->getChildren())); |
| 55 | + } |
| 56 | + |
| 57 | + public function testAddParentAlsoAddsChild(){ |
| 58 | + $parent = new MenuItem(); |
| 59 | + $this->menuItem->setParent($parent); |
| 60 | + $this->assertContains($this->menuItem,$parent->getChildren()); |
| 61 | + } |
| 62 | + |
| 63 | + public function testToHTMLOnRootMenuItem(){ |
| 64 | + $html = $this->menuItem->toHTML(); |
| 65 | + $this->assertEquals("",$html); |
| 66 | + } |
| 67 | + |
| 68 | + public function testToHTMLOnProperMenuItem(){ |
| 69 | + $menuItemChild = new MenuItem(); |
| 70 | + $menuItemChild->setText("MenuItem1"); |
| 71 | + $this->menuItem->addChild($menuItemChild); |
| 72 | + $html = $this->menuItem->toHTML(); |
| 73 | + $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); |
| 74 | + } |
| 75 | + |
| 76 | + public function testToHTMLOnSeveralMenuItems(){ |
| 77 | + $menuItemChild1 = new MenuItem(); |
| 78 | + $menuItemChild1->setText("MenuItem1"); |
| 79 | + $menuItemChild2 = new MenuItem(); |
| 80 | + $menuItemChild2->setText("MenuItem2"); |
| 81 | + |
| 82 | + $this->menuItem->addChild($menuItemChild1); |
| 83 | + $this->menuItem->addChild($menuItemChild2); |
| 84 | + |
| 85 | + $html = $this->menuItem->toHTML(); |
| 86 | + $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); |
| 87 | + } |
| 88 | + |
| 89 | + public function testToHTMLOnSeveralMenuItemsWithSublevels(){ |
| 90 | + $menuItemChild1 = new MenuItem(); |
| 91 | + $menuItemChild1->setText("MenuItem1"); |
| 92 | + $menuItemChild2 = new MenuItem(); |
| 93 | + $menuItemChild2->setText("MenuItem2"); |
| 94 | + |
| 95 | + $this->menuItem->addChild($menuItemChild1); |
| 96 | + $this->menuItem->addChild($menuItemChild2); |
| 97 | + |
| 98 | + $subLevel1 = new MenuItem(); |
| 99 | + $subLevel1->setText("SubMenuItem1"); |
| 100 | + $subLevel1->setParent($menuItemChild2); |
| 101 | + |
| 102 | + $html = $this->menuItem->toHTML(); |
| 103 | + $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); |
| 104 | + } |
| 105 | +} |
Index: trunk/extensions/SideBarMenu/SideBarMenu.body.php |
Index: trunk/extensions/SideBarMenu/SideBarMenu.i18n.php |
Index: trunk/extensions/SideBarMenu/SideBarMenu.php |
— | — | @@ -0,0 +1,63 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +if (!defined('MEDIAWIKI')) { |
| 5 | + die('Not an entry point.'); |
| 6 | +} |
| 7 | + |
| 8 | +$wgExtensionCredits['parserhook'][] = array( |
| 9 | + 'path' => __FILE__, |
| 10 | + 'name' => 'SideBarMenu', |
| 11 | + 'version' => 0.1, |
| 12 | + 'author' => 'Kim Eik', |
| 13 | + 'url' => 'https://www.mediawiki.org/wiki/Extension:SideBarMenu', |
| 14 | + 'descriptionmsg' => 'A simple sidebar menu parser which creates collapsable/expandable menus and sub-menus.' |
| 15 | +); |
| 16 | + |
| 17 | + |
| 18 | +// Specify the function that will initialize the parser function. |
| 19 | +$wgHooks['ParserFirstCallInit'][] = 'init'; |
| 20 | + |
| 21 | +// Specify the function that will register the magic words for the parser function. |
| 22 | +$wgHooks['LanguageGetMagic'][] = 'registerMagicWords'; |
| 23 | + |
| 24 | +// Sepcify phpunit tests |
| 25 | +$wgHooks['UnitTestsList'][] = 'registerUnitTests'; |
| 26 | + |
| 27 | +//Autoload |
| 28 | +$wgMyExtensionIncludes = dirname(__FILE__) . '/includes'; |
| 29 | +## Special page class |
| 30 | +$wgAutoloadClasses['MenuParser'] = $wgMyExtensionIncludes . '/MenuParser.php'; |
| 31 | +$wgAutoloadClasses['MenuItem'] = $wgMyExtensionIncludes . '/MenuItem.php'; |
| 32 | + |
| 33 | + |
| 34 | +function init(&$parser){ |
| 35 | + $parser->setHook('sidebarmenu','renderFromTag'); |
| 36 | + return true; |
| 37 | +} |
| 38 | + |
| 39 | +function registerMagicWords(&$magicWords, $langCode){ |
| 40 | + $magicWords['sidebarmenu'] = array(0,'sidebarmenu'); |
| 41 | + return true; |
| 42 | +} |
| 43 | + |
| 44 | +function renderFromTag( $input, array $args, Parser $parser, PPFrame $frame ){ |
| 45 | + try{ |
| 46 | + $menuHTML = MenuParser::getMenuTree($input)->toHTML(); |
| 47 | + return $parser->recursiveTagParse($menuHTML,$frame); |
| 48 | + }catch(Exception $x){ |
| 49 | + wfDebug("An error occured during parsing of: '$input' caught exception: $x"); |
| 50 | + return "FATAL ERROR: Could not parse the following input:</br><pre>$input</pre>"; |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +function registerUnitTests( &$files ) { |
| 55 | + $testDir = dirname( __FILE__ ) . '/test/'; |
| 56 | + $testFiles = scandir($testDir); |
| 57 | + foreach($testFiles as $testFile){ |
| 58 | + $absoluteFile = $testDir . $testFile; |
| 59 | + if(is_file($absoluteFile)){ |
| 60 | + $files[] = $absoluteFile; |
| 61 | + } |
| 62 | + } |
| 63 | + return true; |
| 64 | +} |
Index: trunk/extensions/SideBarMenu/includes/MenuParser.php |
— | — | @@ -0,0 +1,123 @@ |
| 2 | +<?php |
| 3 | +class MenuParser { |
| 4 | + |
| 5 | + public static function isRoot($line) |
| 6 | + { |
| 7 | + return !self::startsWith($line, '*'); |
| 8 | + } |
| 9 | + |
| 10 | + public static function isValidInput($data) |
| 11 | + { |
| 12 | + return !(is_null($data) || strlen($data) == 0); |
| 13 | + } |
| 14 | + |
| 15 | + |
| 16 | + public static function getLevel($line) |
| 17 | + { |
| 18 | + return substr_count($line, '*'); |
| 19 | + } |
| 20 | + |
| 21 | + public static function getExpandedParameter($line) |
| 22 | + { |
| 23 | + if (self::startsWith($line, '+')) { |
| 24 | + return true; |
| 25 | + } else { |
| 26 | + return false; |
| 27 | + } |
| 28 | + } |
| 29 | + |
| 30 | + public static function getTextParameter($line) |
| 31 | + { |
| 32 | + return preg_filter("/\+|\-?\**(.*)/", "$1", $line); |
| 33 | + } |
| 34 | + |
| 35 | + |
| 36 | + public static function getMenuTree($data){ |
| 37 | + if(self::isValidInput($data)){ |
| 38 | + $data = self::cleanupData($data); |
| 39 | + $root = new MenuItem(); |
| 40 | + $root->setExpanded(true); |
| 41 | + $arrayData = self::parseDataIntoHierarchicalArray($data); |
| 42 | + self::addChildrenToMenuItemFromArrayData($root,$arrayData); |
| 43 | + return $root; |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + |
| 48 | + public static function getMenuItem($line) |
| 49 | + { |
| 50 | + $line = trim($line); |
| 51 | + if(self::isValidInput($line)){ |
| 52 | + $menuItem = new MenuItem(); |
| 53 | + $menuItem->setExpanded(self::getExpandedParameter($line)); |
| 54 | + $menuItem->setText(self::getTextParameter($line)); |
| 55 | + return $menuItem; |
| 56 | + }else{ |
| 57 | + throw new InvalidArgumentException(); |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + public static function parseDataIntoHierarchicalArray($data) |
| 62 | + { |
| 63 | + $rootArray = array(); |
| 64 | + $prevArray = &$rootArray; |
| 65 | + $prevLevel = 0; |
| 66 | + $levelArray[0] = &$rootArray; |
| 67 | + foreach(preg_split("/\n/",$data) as $line){ |
| 68 | + $level = self::getLevel($line); |
| 69 | + if($level == $prevLevel){ |
| 70 | + $levelArray[$level][] = $line; |
| 71 | + }else if($level-1 == $prevLevel){ |
| 72 | + //child of previous line |
| 73 | + $parent = array_pop($levelArray[$level-1]); |
| 74 | + $levelArray[$level-1][$parent][] = $line; |
| 75 | + $levelArray[$level] = &$levelArray[$level-1][$parent]; |
| 76 | + }else if($level < $prevLevel){ |
| 77 | + //back some levels |
| 78 | + $levelArray[$level][] = $line; |
| 79 | + }else{ |
| 80 | + //syntax error |
| 81 | + throw new InvalidArgumentException(); |
| 82 | + } |
| 83 | + $prevLevel = $level; |
| 84 | + } |
| 85 | + return $rootArray; |
| 86 | + } |
| 87 | + |
| 88 | + public static function addChildrenToMenuItemFromArrayData(&$rootMenuItem,$arrayData) |
| 89 | + { |
| 90 | + foreach ($arrayData as $key => $val) { |
| 91 | + if (is_string($key)) { |
| 92 | + $menuItem = self::getMenuItem($key); |
| 93 | + $rootMenuItem->addChild($menuItem); |
| 94 | + self::addChildrenToMenuItemFromArrayData($menuItem,$val); |
| 95 | + } else { |
| 96 | + $menuItem = self::getMenuItem($val); |
| 97 | + $rootMenuItem->addChild($menuItem); |
| 98 | + } |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + private static function startsWith($haystack, $needle) |
| 103 | + { |
| 104 | + $length = strlen($needle); |
| 105 | + return (substr($haystack, 0, $length) === $needle); |
| 106 | + } |
| 107 | + |
| 108 | + private static function cleanupData($data){ |
| 109 | + for($x = 0; $x < 2; $x++){ |
| 110 | + $data = self::removeLineBreaksFromStartOfString($data); |
| 111 | + $data = strrev($data); |
| 112 | + } |
| 113 | + return $data; |
| 114 | + } |
| 115 | + |
| 116 | + private static function removeLineBreaksFromStartOfString($data) |
| 117 | + { |
| 118 | + while (self::startsWith($data, "\n")) { |
| 119 | + $data = substr($data, 1); |
| 120 | + } |
| 121 | + return $data; |
| 122 | + } |
| 123 | + |
| 124 | +} |
\ No newline at end of file |
Index: trunk/extensions/SideBarMenu/includes/MenuItem.php |
— | — | @@ -0,0 +1,99 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class MenuItem |
| 5 | +{ |
| 6 | + private $expanded; |
| 7 | + private $children = array(); |
| 8 | + private $parent = null; |
| 9 | + private $text; |
| 10 | + |
| 11 | + public function setExpanded($expanded) |
| 12 | + { |
| 13 | + $this->expanded = $expanded; |
| 14 | + } |
| 15 | + |
| 16 | + public function isExpanded() |
| 17 | + { |
| 18 | + return $this->expanded; |
| 19 | + } |
| 20 | + |
| 21 | + public function setText($link) |
| 22 | + { |
| 23 | + $this->text = $link; |
| 24 | + } |
| 25 | + |
| 26 | + public function getText() |
| 27 | + { |
| 28 | + return $this->text; |
| 29 | + } |
| 30 | + |
| 31 | + public function addChild(MenuItem $child) |
| 32 | + { |
| 33 | + if(!in_array($child,$this->children)){ |
| 34 | + $this->children[] = $child; |
| 35 | + $child->setParent($this); |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + public function getChildren() |
| 40 | + { |
| 41 | + return $this->children; |
| 42 | + } |
| 43 | + |
| 44 | + public function hasChildren() |
| 45 | + { |
| 46 | + return sizeof($this->children) > 0; |
| 47 | + } |
| 48 | + |
| 49 | + public function setParent(MenuItem $parent) |
| 50 | + { |
| 51 | + if($this->parent !== $parent){ |
| 52 | + $this->parent = $parent; |
| 53 | + $parent->addChild($this); |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + public function getParent() |
| 58 | + { |
| 59 | + return $this->parent; |
| 60 | + } |
| 61 | + |
| 62 | + public function isRoot(){ |
| 63 | + return is_null($this->parent); |
| 64 | + } |
| 65 | + |
| 66 | + public function getLevel(){ |
| 67 | + if($this->isRoot()){ |
| 68 | + return 0; |
| 69 | + }else{ |
| 70 | + return 1+$this->getParent()->getLevel(); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + public function toHTML() |
| 75 | + { |
| 76 | + $output = ""; |
| 77 | + if($this->isRoot()){ |
| 78 | + $output .= $this->childrenToHTML(); |
| 79 | + }else{ |
| 80 | + $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>"; |
| 81 | + $output .= $this->childrenToHTML(); |
| 82 | + $output .= "</li>"; |
| 83 | + } |
| 84 | + |
| 85 | + return $output; |
| 86 | + } |
| 87 | + |
| 88 | + private function childrenToHTML() |
| 89 | + { |
| 90 | + if($this->hasChildren()){ |
| 91 | + $output = "<ul class=\"sidebar-menu sidebar-menu-".$this->getLevel()."\">"; |
| 92 | + foreach ($this->getChildren() as $child) { |
| 93 | + $output .= $child->toHTML(); |
| 94 | + } |
| 95 | + $output .= "</ul>"; |
| 96 | + return $output; |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | +} |
Index: trunk/extensions/SideBarMenu/README |
— | — | @@ -0,0 +1,4 @@ |
| 2 | +== INSTALL == |
| 3 | +1. Copy SideBarMenu to /path/to/mediawiki/extension/ |
| 4 | +2. append "require_once( "$IP/extensions/SideBarMenu/SideBarMenu.php" );" to LocalSettings.php |
| 5 | + |