// Get the db record for the block instance
$blockrecords = $DB->get_record('block_instances', array('id'=>$instanceid,'blockname'=>'global_navigation_tree'));
if ($blockrecords!=false) {
- // Instantiate a block_instance object so we can access congif
+ // Instantiate a block_instance object so we can access congif
$block = block_instance('global_navigation_tree', $blockrecords);
// Check if the expansion limit config option has been set and isn't the default [everything]
if (!empty($block->config->expansionlimit) && $block->config->expansionlimit > '0') {
// Create a navigation object to use, we can't guarantee PAGE will be complete
$expandable = $navigation->initialise($branchtype, $branchid);
+$converter = new navigation_xml();
if ($toggledisplay) {
// Toggle display of item types we dont' want to display
$navigation->toggle_type_display($navigation->expansionlimit);
+ $converter->set_expansionceiling($navigation->expansionlimit);
}
// Find the actuall branch we are looking for
$branch = $navigation->find_child($branchid, $branchtype);
}
// Prepare an XML converter for the branch
-$converter = new navigation_xml();
$converter->set_expandable($expandable);
// Set XML headers
header('Content-type: text/xml');
YAHOO.moodle.navigation.sideblockwidth = null;
YAHOO.moodle.navigation.tabpanel = null;
YAHOO.moodle.navigation.treecollection = Array();
+YAHOO.moodle.navigation.expandablebranchcount = 0;
/**
* Navigation Tree object (function) used to control a global navigation tree
try {
this.expansions[i].element = document.getElementById(this.expansions[i].id);
YAHOO.util.Event.addListener(this.expansions[i].id, 'click', this.init_load_ajax, this.expansions[i], this);
+ YAHOO.moodle.navigation.expandablebranchcount++;
} catch (err) {
this.errorlog += "attaching ajax load events: \t"+err+"\n";
}
* @return {bool}
*/
navigation_tree.prototype.add_branch = function(branchxml, target, depth) {
- var branch = new navigation_tree_branch();
+ var branch = new navigation_tree_branch(this.name);
branch.load_from_xml_node(branchxml);
if (depth>1) {
target = branch.inject_into_dom(target,this);
* @class navigation_tree_branch
* @constructor
*/
-function navigation_tree_branch() {
+function navigation_tree_branch(treename) {
+ this.treename = treename;
this.myname = null;
this.mytitle = null;
this.myclass = null;
this.mylink = null;
this.myicon = null;
this.myexpandable = null;
+ this.expansionceiling = null;
this.myhidden = false;
this.haschildren = false;
this.mychildren = false;
this.mykey = branch.getAttribute('key');
this.mytype = branch.getAttribute('type');
this.myexpandable = branch.getAttribute('expandable');
+ this.expansionceiling = branch.getAttribute('expansionceiling');
this.myhidden = (branch.getAttribute('hidden')=='true');
this.haschildren = (branch.getAttribute('haschildren')=='true');
+
+ if (this.myid && this.myid.match(/^expandable_branch_\d+$/)) {
+ YAHOO.moodle.navigation.expandablebranchcount++;
+ this.myid = 'expandable_branch_'+YAHOO.moodle.navigation.expandablebranchcount;
+ }
+
for (var i=0; i<branch.childNodes.length;i++) {
var node = branch.childNodes[i];
switch (node.nodeName.toLowerCase()) {
var branchli = document.createElement('li');
var branchp = document.createElement('p');
YAHOO.util.Dom.addClass(branchp, 'tree_item');
- if (this.myexpandable !==null || this.haschildren) {
+ if ((this.myexpandable !==null || this.haschildren) && this.expansionceiling===null) {
YAHOO.util.Dom.addClass(branchp, 'branch');
YAHOO.util.Dom.addClass(branchli, 'collapsed');
YAHOO.util.Event.addListener(branchp, 'click', gntinstance.toggleexpansion, this, gntinstance);
return $depth;
}
+ /**
+ * Finds all nodes (recursivily) that have the specified type, regardless of
+ * assumed order or position.
+ *
+ * @param int $type One of navigation_node::TYPE_*
+ * @return array An array of navigation_node references for nodes of type $type
+ */
+ public function find_children_by_type($type) {
+ $nodes = array();
+ if (count($this->children)>0) {
+ foreach ($this->children as &$child) {
+ if ($child->type === $type) {
+ $nodes[] = $child;
+ }
+ if (count($child->children)>0) {
+ $nodes = array_merge($nodes, $child->find_children_by_type($type));
+ }
+ }
+ }
+ return $nodes;
+ }
+
/**
* Toogles display of nodes and child nodes based on type
*
*
* @param array $expandable An array to fill with the HTML id's of all branches
* that can be expanded by AJAX. This is a forced reference.
+ * @param int $expansionlimit Optional/used internally can be one of navigation_node::TYPE_*
*/
- public function find_expandable(&$expandable) {
+ public function find_expandable(&$expandable, $expansionlimit = null) {
static $branchcount;
if ($branchcount==null) {
$branchcount=1;
}
- if ($this->nodetype == self::NODETYPE_BRANCH && count($this->children)==0) {
+ if ($this->nodetype == self::NODETYPE_BRANCH && count($this->children)==0 && ($expansionlimit === null || $this->type < $expansionlimit)) {
$this->id = 'expandable_branch_'.$branchcount;
+ $this->add_class('canexpand');
$branchcount++;
$expandable[] = array('id'=>$this->id,'branchid'=>$this->key,'type'=>$this->type);
- } else if ($this->nodetype==self::NODETYPE_BRANCH) {
+ } else if ($this->nodetype==self::NODETYPE_BRANCH && ($expansionlimit === null || $this->type <= $expansionlimit)) {
foreach ($this->children as $child) {
- $child->find_expandable($expandable);
+ $child->find_expandable($expandable, $expansionlimit);
}
}
}
foreach ($courses as $course) {
// If a category id has been specified and the current course is not within
// that category or one of its children then skip this course
- if ($categoryid!==0 && !preg_match('#/('.$categoryid.')(\/|$)#', $course->categorypath)) {
+ if ($categoryid!==0 && !preg_match('#/('.$categoryid.')(/|$)#', $course->categorypath)) {
continue;
}
$categorypathids = explode('/',trim($course->categorypath,' /'));
}
// Add the courses that were retrieved earlier to the
$this->add_courses($courses);
- } else {
+ } else if ($categoryid === 0) {
$keys = array();
if ($categoryid!=0) {
if (!$this->cache->cached('category'.$categoryid)) {
public function clear_cache() {
$this->cache->volatile();
}
+
+ /**
+ * Finds all expandable nodes whilst ensuring that expansion limit is respected
+ *
+ * @param array $expandable A reference to an array that will be populated as
+ * we go.
+ */
+ public function find_expandable(&$expandable) {
+ parent::find_expandable($expandable, $this->expansionlimit);
+ }
+
+ /**
+ * Loads categories that contain no courses into the structure.
+ *
+ * These categories would normally be skipped, as such this function is purely
+ * for the benefit of code external to navigationlib
+ */
+ public function load_empty_categories() {
+ $categories = array();
+ $categorynames = array();
+ $categoryparents = array();
+ make_categories_list($categorynames, $categoryparents, '', 0, $category = NULL);
+ foreach ($categorynames as $id=>$name) {
+ if (!$this->find_child($id, self::TYPE_CATEGORY)) {
+ $category = new stdClass;
+ $category->id = $id;
+ if (array_key_exists($id, $categoryparents)) {
+ $category->path = '/'.join('/',array_merge($categoryparents[$id],array($id)));
+ $name = explode('/', $name);
+ $category->name = join('/', array_splice($name, count($categoryparents[$id])));
+ } else {
+ $category->path = '/'.$id;
+ $category->name = $name;
+ }
+ $this->add_category_by_path($category);
+ }
+ }
+ }
}
/**
* @param int $instanceid
*/
protected function load_category($instanceid) {
- if (!$this->cache->cached('coursecontext'.$instanceid)) {
- $this->cache->{'coursecontext'.$instanceid} = get_context_instance(CONTEXT_COURSE, $instanceid);
+ if (!$this->cache->cached('coursecatcontext'.$instanceid)) {
+ $this->cache->{'coursecatcontext'.$instanceid} = get_context_instance(CONTEXT_COURSECAT, $instanceid);
}
- $this->context = $this->cache->{'coursecontext'.$instanceid};
+ $this->context = $this->cache->{'coursecatcontext'.$instanceid};
$this->load_categories($instanceid);
}
protected $nodetype = array('node','branch');
/** @var array */
protected $expandable = array();
+ /** @var int */
+ protected $expansionceiling = array();
/**
* Turns a branch and all of its children into XML
*
$this->expandable[(string)$node['branchid']] = $node;
}
}
+ /**
+ * Sets the upper limit for expandable nodes. Any nodes that are of the specified
+ * type or larger will not be expandable
+ *
+ * @param int $expansionceiling One of navigation_node::TYPE_*
+ */
+ public function set_expansionceiling($expansionceiling) {
+ $tihs->expansionceiling = $expansionceiling;
+ }
/**
* Recusively converts a child node and its children to XML for output
*
if (array_key_exists((string)$child->key, $this->expandable)) {
$attributes['expandable'] = $child->key;
$child->add_class($this->expandable[$child->key]['id']);
+ } else if ($child->type >= $this->expansionceiling) {
+ $attributes['expansionceiling'] = $child->key;
}
+
if (count($child->classes)>0) {
$attributes['class'] .= ' '.join(' ',$child->classes);
}