Merge branch 'MDL-28168-custommenu' of git://github.com/mudrd8mz/moodle

This commit is contained in:
Eloy Lafuente (stronk7)
2011-07-08 00:41:19 +02:00
3 changed files with 154 additions and 27 deletions
+45 -26
View File
@@ -2323,15 +2323,22 @@ class custom_menu_item implements renderable {
* @since Moodle 2.0
*/
class custom_menu extends custom_menu_item {
/** @var string the language we should render for, null disables multilang support */
protected $currentlanguage = null;
/**
* Creates the custom menu
* @param string $text Sets the text for this custom menu, never gets used and is optional
*
* @param string $definition the menu items definition in syntax required by {@link convert_text_to_menu_nodes()}
* @param string $language the current language code, null disables multilang support
*/
public function __construct($text='base') {
global $CFG;
parent::__construct($text);
if (!empty($CFG->custommenuitems)) {
$this->override_children(self::convert_text_to_menu_nodes($CFG->custommenuitems));
public function __construct($definition = '', $currentlanguage = null) {
$this->currentlanguage = $currentlanguage;
parent::__construct('root'); // create virtual root element of the menu
if (!empty($definition)) {
$this->override_children(self::convert_text_to_menu_nodes($definition, $currentlanguage));
}
}
@@ -2353,8 +2360,9 @@ class custom_menu extends custom_menu_item {
* then be added to a custom menu.
*
* Structure:
* text|url|title
* The number of hyphens at the start determines the depth of the item
* text|url|title|langs
* The number of hyphens at the start determines the depth of the item. The
* languages are optional, comma separated list of languages the line is for.
*
* Example structure:
* First level first item|http://www.moodle.com/
@@ -2364,16 +2372,16 @@ class custom_menu extends custom_menu_item {
* -Second level third item|http://www.moodle.com/development/
* First level second item|http://www.moodle.com/feedback/
* First level third item
* English only|http://moodle.com|English only item|en
* German only|http://moodle.de|Deutsch|de,de_du,de_kids
*
*
* @static
* @param string $text
* @param string $text the menu items definition
* @param string $language the language code, null disables multilang support
* @return array
*/
public static function convert_text_to_menu_nodes($text) {
$text = format_text($text, FORMAT_MOODLE, array(
'para' => false,
'newlines' => false,
'context' => get_system_context()));
public static function convert_text_to_menu_nodes($text, $language = null) {
$lines = explode("\n", $text);
$children = array();
$lastchild = null;
@@ -2381,27 +2389,38 @@ class custom_menu extends custom_menu_item {
$lastsort = 0;
foreach ($lines as $line) {
$line = trim($line);
$bits = explode('|', $line ,4); // name|url|title|sort
if (!array_key_exists(0, $bits) || empty($bits[0])) {
$bits = explode('|', $line, 4); // name|url|title|langs
if (!array_key_exists(0, $bits) or empty($bits[0])) {
// Every item must have a name to be valid
continue;
} else {
$bits[0] = ltrim($bits[0],'-');
}
if (!array_key_exists(1, $bits)) {
if (!array_key_exists(1, $bits) or empty($bits[1])) {
// Set the url to null
$bits[1] = null;
} else {
// Make sure the url is a moodle url
$bits[1] = new moodle_url(trim($bits[1]));
}
if (!array_key_exists(2, $bits)) {
if (!array_key_exists(2, $bits) or empty($bits[2])) {
// Set the title to null seeing as there isn't one
$bits[2] = $bits[0];
}
if (!array_key_exists(3, $bits) or empty($bits[3])) {
// The item is valid for all languages
$itemlangs = null;
} else {
$itemlangs = array_map('trim', explode(',', $bits[3]));
}
if (!empty($language) and !empty($itemlangs)) {
// check that the item is intended for the current language
if (!in_array($language, $itemlangs)) {
continue;
}
}
// Set an incremental sort order to keep it simple.
$bits[3] = $lastsort;
$lastsort = $bits[3]+1;
$lastsort++;
if (preg_match('/^(\-*)/', $line, $match) && $lastchild != null && $lastdepth !== null) {
$depth = strlen($match[1]);
if ($depth < $lastdepth) {
@@ -2411,26 +2430,26 @@ class custom_menu extends custom_menu_item {
for ($i =0; $i < $difference; $i++) {
$tempchild = $tempchild->get_parent();
}
$lastchild = $tempchild->add($bits[0], $bits[1], $bits[2], $bits[3]);
$lastchild = $tempchild->add($bits[0], $bits[1], $bits[2], $lastsort);
} else {
$depth = 0;
$lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $bits[3]);
$lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $lastsort);
$children[] = $lastchild;
}
} else if ($depth > $lastdepth) {
$depth = $lastdepth + 1;
$lastchild = $lastchild->add($bits[0], $bits[1], $bits[2], $bits[3]);
$lastchild = $lastchild->add($bits[0], $bits[1], $bits[2], $lastsort);
} else {
if ($depth == 0) {
$lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $bits[3]);
$lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $lastsort);
$children[] = $lastchild;
} else {
$lastchild = $lastchild->get_parent()->add($bits[0], $bits[1], $bits[2], $bits[3]);
$lastchild = $lastchild->get_parent()->add($bits[0], $bits[1], $bits[2], $lastsort);
}
}
} else {
$depth = 0;
$lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $bits[3]);
$lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $lastsort);
$children[] = $lastchild;
}
$lastdepth = $depth;
+1 -1
View File
@@ -2410,7 +2410,7 @@ EOD;
if (empty($CFG->custommenuitems)) {
return '';
}
$custommenu = new custom_menu();
$custommenu = new custom_menu($CFG->custommenuitems, current_language());
return $this->render_custom_menu($custommenu);
}
+108
View File
@@ -112,3 +112,111 @@ class user_picture_test extends UnitTestCase {
$this->assertEqual($returned->custom1, 'Value of custom1');
}
}
/**
* Unit tests for the custom_menu class
*/
class custom_menu_test extends UnitTestCase {
public function test_empty_menu() {
$emptymenu = new custom_menu();
$this->assertTrue($emptymenu instanceof custom_menu);
$this->assertFalse($emptymenu->has_children());
}
public function test_basic_syntax() {
$definition = <<<EOF
Moodle community|http://moodle.org
-Moodle free support|http://moodle.org/support
-Moodle development|http://moodle.org/development
--Moodle Tracker|http://tracker.moodle.org
--Moodle Docs|http://docs.moodle.org
-Moodle News|http://moodle.org/news
Moodle company
-Hosting|http://moodle.com/hosting|Commercial hosting
-Support|http://moodle.com/support|Commercial support
EOF;
$menu = new custom_menu($definition);
$this->assertTrue($menu instanceof custom_menu);
$this->assertTrue($menu->has_children());
$firstlevel = $menu->get_children();
$this->assertIsA($firstlevel, 'array');
$this->assertEqual(2, count($firstlevel));
$item = array_shift($firstlevel);
$this->assertTrue($item instanceof custom_menu_item);
$this->assertTrue($item->has_children());
$this->assertEqual(3, count($item->get_children()));
$this->assertEqual('Moodle community', $item->get_text());
$itemurl = $item->get_url();
$this->assertTrue($itemurl instanceof moodle_url);
$this->assertEqual('http://moodle.org', $itemurl->out());
$this->assertEqual($item->get_text(), $item->get_title()); // implicit title
$item = array_shift($firstlevel);
$this->assertTrue($item->has_children());
$this->assertEqual(2, count($item->get_children()));
$this->assertEqual('Moodle company', $item->get_text());
$this->assertTrue(is_null($item->get_url()));
$subitem = array_shift($item->get_children());
$this->assertFalse($subitem->has_children());
$this->assertEqual('Hosting', $subitem->get_text());
$this->assertEqual('Commercial hosting', $subitem->get_title());
}
public function test_multilang_support() {
$definition = <<<EOF
Start|http://school.info
Info
-English|http://school.info/en|Information in English|en
-Deutsch|http://school.info/de|Informationen in deutscher Sprache|de,de_du,de_kids
EOF;
// the menu without multilang support
$menu = new custom_menu($definition);
$this->assertTrue($menu->has_children());
$this->assertEqual(2, count($menu->get_children()));
$infomenu = array_pop($menu->get_children());
$this->assertTrue($infomenu->has_children());
$this->assertEqual(2, count($infomenu->get_children()));
$langspecinfo = array_shift($infomenu->get_children());
$this->assertEqual('Information in English', $langspecinfo->get_title());
// same menu for English language selected
$menu = new custom_menu($definition, 'en');
$this->assertTrue($menu->has_children());
$this->assertEqual(2, count($menu->get_children()));
$infomenu = array_pop($menu->get_children());
$this->assertTrue($infomenu->has_children());
$this->assertEqual(1, count($infomenu->get_children()));
$langspecinfo = array_shift($infomenu->get_children());
$this->assertEqual('Information in English', $langspecinfo->get_title());
// same menu for German (de_du) language selected
$menu = new custom_menu($definition, 'de_du');
$this->assertTrue($menu->has_children());
$this->assertEqual(2, count($menu->get_children()));
$infomenu = array_pop($menu->get_children());
$this->assertTrue($infomenu->has_children());
$this->assertEqual(1, count($infomenu->get_children()));
$langspecinfo = array_shift($infomenu->get_children());
$this->assertEqual('Informationen in deutscher Sprache', $langspecinfo->get_title());
// same menu for Czech language selected
$menu = new custom_menu($definition, 'cs');
$this->assertTrue($menu->has_children());
$this->assertEqual(2, count($menu->get_children()));
$infomenu = array_pop($menu->get_children());
$this->assertFalse($infomenu->has_children());
}
}