2009-08-28 08:47:31 +00:00
< ? php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains classes used to manage the navigation structures in Moodle
* and was introduced as part of the changes occuring in Moodle 2.0
*
2010-07-25 13:35:05 +00:00
* @ since 2.0
* @ package core
2009-08-28 08:47:31 +00:00
* @ subpackage navigation
2010-07-25 13:35:05 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2009-08-28 08:47:31 +00:00
*/
2010-07-25 13:35:05 +00:00
defined ( 'MOODLE_INTERNAL' ) || die ();
2009-10-12 05:39:32 +00:00
/**
2009-10-23 04:23:57 +00:00
* The name that will be used to separate the navigation cache within SESSION
2009-10-12 05:39:32 +00:00
*/
define ( 'NAVIGATION_CACHE_NAME' , 'navigation' );
2009-08-28 08:47:31 +00:00
/**
* This class is used to represent a node in a navigation tree
*
* This class is used to represent a node in a navigation tree within Moodle ,
* the tree could be one of global navigation , settings navigation , or the navbar .
* Each node can be one of two types either a Leaf ( default ) or a branch .
* When a node is first created it is created as a leaf , when / if children are added
* the node then becomes a branch .
*
* @ package moodlecore
2009-10-19 03:29:48 +00:00
* @ subpackage navigation
2009-08-28 08:47:31 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2010-04-19 06:30:30 +00:00
class navigation_node implements renderable {
/** @var int Used to identify this node a leaf (default) 0 */
2010-02-18 05:57:20 +00:00
const NODETYPE_LEAF = 0 ;
2010-04-19 06:30:30 +00:00
/** @var int Used to identify this node a branch, happens with children 1 */
2009-08-28 08:47:31 +00:00
const NODETYPE_BRANCH = 1 ;
2010-04-19 06:30:30 +00:00
/** @var null Unknown node type null */
2009-08-28 08:47:31 +00:00
const TYPE_UNKNOWN = null ;
2010-04-19 06:30:30 +00:00
/** @var int System node type 0 */
const TYPE_ROOTNODE = 0 ;
/** @var int System node type 1 */
const TYPE_SYSTEM = 1 ;
/** @var int Category node type 10 */
2009-08-28 08:47:31 +00:00
const TYPE_CATEGORY = 10 ;
2010-04-19 06:30:30 +00:00
/** @var int Course node type 20 */
2009-08-28 08:47:31 +00:00
const TYPE_COURSE = 20 ;
2010-04-19 06:30:30 +00:00
/** @var int Course Structure node type 30 */
2010-02-18 05:57:20 +00:00
const TYPE_SECTION = 30 ;
2010-04-19 06:30:30 +00:00
/** @var int Activity node type, e.g. Forum, Quiz 40 */
2009-08-28 08:47:31 +00:00
const TYPE_ACTIVITY = 40 ;
2010-04-19 06:30:30 +00:00
/** @var int Resource node type, e.g. Link to a file, or label 50 */
2009-08-28 08:47:31 +00:00
const TYPE_RESOURCE = 50 ;
2010-04-19 06:30:30 +00:00
/** @var int A custom node type, default when adding without specifing type 60 */
2009-08-28 08:47:31 +00:00
const TYPE_CUSTOM = 60 ;
2010-04-19 06:30:30 +00:00
/** @var int Setting node type, used only within settings nav 70 */
2009-08-28 08:47:31 +00:00
const TYPE_SETTING = 70 ;
2010-04-19 06:30:30 +00:00
/** @var int Setting node type, used only within settings nav 80 */
2010-02-18 05:57:20 +00:00
const TYPE_USER = 80 ;
2010-04-19 06:30:30 +00:00
/** @var int Setting node type, used for containers of no importance 90 */
const TYPE_CONTAINER = 90 ;
2009-08-28 08:47:31 +00:00
/** @var int Parameter to aid the coder in tracking [optional] */
public $id = null ;
/** @var string|int The identifier for the node, used to retrieve the node */
public $key = null ;
/** @var string The text to use for the node */
public $text = null ;
/** @var string Short text to use if requested [optional] */
public $shorttext = null ;
/** @var string The title attribute for an action if one is defined */
public $title = null ;
/** @var string A string that can be used to build a help button */
public $helpbutton = null ;
2010-04-19 06:30:30 +00:00
/** @var moodle_url|action_link|null An action for the node (link) */
2009-08-28 08:47:31 +00:00
public $action = null ;
2010-02-14 09:29:44 +00:00
/** @var pix_icon The path to an icon to use for this node */
2009-08-28 08:47:31 +00:00
public $icon = null ;
/** @var int See TYPE_* constants defined for this class */
public $type = self :: TYPE_UNKNOWN ;
/** @var int See NODETYPE_* constants defined for this class */
public $nodetype = self :: NODETYPE_LEAF ;
/** @var bool If set to true the node will be collapsed by default */
public $collapse = false ;
/** @var bool If set to true the node will be expanded by default */
public $forceopen = false ;
2010-04-19 06:30:30 +00:00
/** @var array An array of CSS classes for the node */
2009-08-28 08:47:31 +00:00
public $classes = array ();
2010-04-19 06:30:30 +00:00
/** @var navigation_node_collection An array of child nodes */
2009-08-28 08:47:31 +00:00
public $children = array ();
/** @var bool If set to true the node will be recognised as active */
public $isactive = false ;
2010-04-19 06:30:30 +00:00
/** @var bool If set to true the node will be dimmed */
2009-08-28 08:47:31 +00:00
public $hidden = false ;
/** @var bool If set to false the node will not be displayed */
public $display = true ;
/** @var bool If set to true then an HR will be printed before the node */
public $preceedwithhr = false ;
/** @var bool If set to true the the navigation bar should ignore this node */
public $mainnavonly = false ;
/** @var bool If set to true a title will be added to the action no matter what */
public $forcetitle = false ;
2011-06-23 11:29:26 +08:00
/** @var navigation_node A reference to the node parent, you should never set this directly you should always call set_parent */
2010-04-19 06:30:30 +00:00
public $parent = null ;
2010-04-23 04:21:33 +00:00
/** @var bool Override to not display the icon even if one is provided **/
public $hideicon = false ;
2009-08-28 08:47:31 +00:00
/** @var array */
2009-09-10 03:50:51 +00:00
protected $namedtypes = array ( 0 => 'system' , 10 => 'category' , 20 => 'course' , 30 => 'structure' , 40 => 'activity' , 50 => 'resource' , 60 => 'custom' , 70 => 'setting' , 80 => 'user' );
2009-08-28 08:47:31 +00:00
/** @var moodle_url */
protected static $fullmeurl = null ;
2010-02-22 07:57:35 +00:00
/** @var bool toogles auto matching of active node */
public static $autofindactive = true ;
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Constructs a new navigation_node
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param array | string $properties Either an array of properties or a string to use
* as the text for the node
2009-08-28 08:47:31 +00:00
*/
public function __construct ( $properties ) {
if ( is_array ( $properties )) {
2010-04-19 06:30:30 +00:00
// Check the array for each property that we allow to set at construction.
// text - The main content for the node
// shorttext - A short text if required for the node
// icon - The icon to display for the node
// type - The type of the node
// key - The key to use to identify the node
// parent - A reference to the nodes parent
// action - The action to attribute to this node, usually a URL to link to
2009-08-28 08:47:31 +00:00
if ( array_key_exists ( 'text' , $properties )) {
$this -> text = $properties [ 'text' ];
}
if ( array_key_exists ( 'shorttext' , $properties )) {
$this -> shorttext = $properties [ 'shorttext' ];
}
2010-05-05 05:59:57 +00:00
if ( ! array_key_exists ( 'icon' , $properties )) {
$properties [ 'icon' ] = new pix_icon ( 'i/navigationitem' , 'moodle' );
}
$this -> icon = $properties [ 'icon' ];
if ( $this -> icon instanceof pix_icon ) {
if ( empty ( $this -> icon -> attributes [ 'class' ])) {
$this -> icon -> attributes [ 'class' ] = 'navicon' ;
} else {
$this -> icon -> attributes [ 'class' ] .= ' navicon' ;
2010-02-19 02:24:26 +00:00
}
2009-08-28 08:47:31 +00:00
}
if ( array_key_exists ( 'type' , $properties )) {
$this -> type = $properties [ 'type' ];
} else {
$this -> type = self :: TYPE_CUSTOM ;
}
if ( array_key_exists ( 'key' , $properties )) {
$this -> key = $properties [ 'key' ];
}
2010-04-19 06:30:30 +00:00
// This needs to happen last because of the check_if_active call that occurs
if ( array_key_exists ( 'action' , $properties )) {
$this -> action = $properties [ 'action' ];
if ( is_string ( $this -> action )) {
$this -> action = new moodle_url ( $this -> action );
}
if ( self :: $autofindactive ) {
$this -> check_if_active ();
}
}
2011-06-23 11:29:26 +08:00
if ( array_key_exists ( 'parent' , $properties )) {
$this -> set_parent ( $properties [ 'parent' ]);
}
2009-08-28 08:47:31 +00:00
} else if ( is_string ( $properties )) {
$this -> text = $properties ;
}
if ( $this -> text === null ) {
throw new coding_exception ( 'You must set the text for the node when you create it.' );
}
2010-04-19 06:30:30 +00:00
// Default the title to the text
2009-08-28 08:47:31 +00:00
$this -> title = $this -> text ;
2010-04-19 06:30:30 +00:00
// Instantiate a new navigation node collection for this nodes children
$this -> children = new navigation_node_collection ();
2009-08-28 08:47:31 +00:00
}
2009-09-10 02:19:12 +00:00
/**
2010-04-19 06:30:30 +00:00
* Checks if this node is the active node .
2009-10-19 04:27:10 +00:00
*
2010-04-19 06:30:30 +00:00
* This is determined by comparing the action for the node against the
* defined URL for the page . A match will see this node marked as active .
2009-10-19 04:27:10 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param int $strength One of URL_MATCH_EXACT , URL_MATCH_PARAMS , or URL_MATCH_BASE
* @ return bool
2009-08-28 08:47:31 +00:00
*/
2009-09-23 06:05:36 +00:00
public function check_if_active ( $strength = URL_MATCH_EXACT ) {
global $FULLME , $PAGE ;
2010-04-19 06:30:30 +00:00
// Set fullmeurl if it hasn't already been set
2009-08-28 08:47:31 +00:00
if ( self :: $fullmeurl == null ) {
2009-09-23 06:05:36 +00:00
if ( $PAGE -> has_set_url ()) {
2010-04-19 06:30:30 +00:00
self :: override_active_url ( new moodle_url ( $PAGE -> url ));
2009-09-23 06:05:36 +00:00
} else {
2010-04-19 06:30:30 +00:00
self :: override_active_url ( new moodle_url ( $FULLME ));
2009-08-28 08:47:31 +00:00
}
}
2009-09-23 06:05:36 +00:00
2010-04-19 06:30:30 +00:00
// Compare the action of this node against the fullmeurl
2009-09-23 06:05:36 +00:00
if ( $this -> action instanceof moodle_url && $this -> action -> compare ( self :: $fullmeurl , $strength )) {
2009-08-28 08:47:31 +00:00
$this -> make_active ();
return true ;
}
return false ;
}
2010-04-19 06:30:30 +00:00
2009-08-28 08:47:31 +00:00
/**
2010-08-05 08:17:27 +00:00
* This sets the URL that the URL of new nodes get compared to when locating
* the active node .
*
* The active node is the node that matches the URL set here . By default this
* is either $PAGE -> url or if that hasn ' t been set $FULLME .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param moodle_url $url The url to use for the fullmeurl .
*/
public static function override_active_url ( moodle_url $url ) {
2010-08-06 16:12:31 +00:00
// Clone the URL, in case the calling script changes their URL later.
self :: $fullmeurl = new moodle_url ( $url );
2010-04-19 06:30:30 +00:00
}
/**
2011-05-23 17:34:17 +01:00
* Creates a navigation node , ready to add it as a child using add_node
* function . ( The created node needs to be added before you can use it . )
2010-04-19 06:30:30 +00:00
* @ param string $text
* @ param moodle_url | action_link $action
* @ param int $type
* @ param string $shorttext
* @ param string | int $key
* @ param pix_icon $icon
* @ return navigation_node
2009-08-28 08:47:31 +00:00
*/
2011-05-23 17:34:17 +01:00
public static function create ( $text , $action = null , $type = self :: TYPE_CUSTOM ,
$shorttext = null , $key = null , pix_icon $icon = null ) {
2010-04-19 06:30:30 +00:00
// Properties array used when creating the new navigation node
$itemarray = array (
'text' => $text ,
'type' => $type
);
// Set the action if one was provided
2009-08-28 08:47:31 +00:00
if ( $action !== null ) {
$itemarray [ 'action' ] = $action ;
}
2010-04-19 06:30:30 +00:00
// Set the shorttext if one was provided
2009-08-28 08:47:31 +00:00
if ( $shorttext !== null ) {
$itemarray [ 'shorttext' ] = $shorttext ;
}
2010-04-19 06:30:30 +00:00
// Set the icon if one was provided
2009-08-28 08:47:31 +00:00
if ( $icon !== null ) {
$itemarray [ 'icon' ] = $icon ;
}
2010-04-19 06:30:30 +00:00
// Set the key
2009-08-28 08:47:31 +00:00
$itemarray [ 'key' ] = $key ;
2011-05-23 17:34:17 +01:00
// Construct and return
return new navigation_node ( $itemarray );
}
/**
* Adds a navigation node as a child of this node .
*
* @ param string $text
* @ param moodle_url | action_link $action
* @ param int $type
* @ param string $shorttext
* @ param string | int $key
* @ param pix_icon $icon
* @ return navigation_node
*/
public function add ( $text , $action = null , $type = self :: TYPE_CUSTOM , $shorttext = null , $key = null , pix_icon $icon = null ) {
// Create child node
$childnode = self :: create ( $text , $action , $type , $shorttext , $key , $icon );
// Add the child to end and return
return $this -> add_node ( $childnode );
}
/**
* Adds a navigation node as a child of this one , given a $node object
* created using the create function .
* @ param navigation_node $childnode Node to add
* @ param int | string $key The key of a node to add this before . If not
* specified , adds at end of list
* @ return navigation_node The added node
*/
public function add_node ( navigation_node $childnode , $beforekey = null ) {
// First convert the nodetype for this node to a branch as it will now have children
if ( $this -> nodetype !== self :: NODETYPE_BRANCH ) {
$this -> nodetype = self :: NODETYPE_BRANCH ;
}
2010-04-19 06:30:30 +00:00
// Set the parent to this node
2011-06-23 11:29:26 +08:00
$childnode -> set_parent ( $this );
2011-05-23 17:34:17 +01:00
// Default the key to the number of children if not provided
if ( $childnode -> key === null ) {
$childnode -> key = $this -> children -> count ();
}
2010-04-19 06:30:30 +00:00
// Add the child using the navigation_node_collections add method
2011-05-23 17:34:17 +01:00
$node = $this -> children -> add ( $childnode , $beforekey );
// If added node is a category node or the user is logged in and it's a course
// then mark added node as a branch (makes it expandable by AJAX)
$type = $childnode -> type ;
2009-09-04 07:41:21 +00:00
if (( $type == self :: TYPE_CATEGORY ) || ( isloggedin () && $type == self :: TYPE_COURSE )) {
2010-04-19 06:30:30 +00:00
$node -> nodetype = self :: NODETYPE_BRANCH ;
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
// If this node is hidden mark it's children as hidden also
2009-08-28 08:47:31 +00:00
if ( $this -> hidden ) {
2010-04-19 06:30:30 +00:00
$node -> hidden = true ;
2009-08-28 08:47:31 +00:00
}
2011-05-23 17:34:17 +01:00
// Return added node (reference returned by $this->children->add()
2010-04-19 06:30:30 +00:00
return $node ;
2009-08-28 08:47:31 +00:00
}
2011-06-18 16:23:53 +01:00
/**
* Return a list of all the keys of all the child nodes .
* @ return array the keys .
*/
public function get_children_key_list () {
return $this -> children -> get_key_list ();
}
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Searches for a node of the given type with the given key .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* This searches this node plus all of its children , and their children ....
* If you know the node you are looking for is a child of this node then please
* use the get method instead .
*
* @ param int | string $key The key of the node we are looking for
* @ param int $type One of navigation_node :: TYPE_ *
* @ return navigation_node | false
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function find ( $key , $type ) {
return $this -> children -> find ( $key , $type );
}
/**
* Get ths child of this node that has the given key + ( optional ) type .
*
* If you are looking for a node and want to search all children + thier children
* then please use the find method instead .
*
* @ param int | string $key The key of the node we are looking for
* @ param int $type One of navigation_node :: TYPE_ *
* @ return navigation_node | false
*/
public function get ( $key , $type = null ) {
return $this -> children -> get ( $key , $type );
}
/**
* Removes this node .
*
* @ return bool
*/
public function remove () {
return $this -> parent -> children -> remove ( $this -> key , $this -> type );
}
/**
* Checks if this node has or could have any children
*
* @ return bool Returns true if it has children or could have ( by AJAX expansion )
*/
public function has_children () {
return ( $this -> nodetype === navigation_node :: NODETYPE_BRANCH || $this -> children -> count () > 0 );
}
/**
* Marks this node as active and forces it open .
2010-08-05 08:17:27 +00:00
*
* Important : If you are here because you need to mark a node active to get
* the navigation to do what you want have you looked at { @ see navigation_node :: override_active_url ()} ?
* You can use it to specify a different URL to match the active navigation node on
* rather than having to locate and manually mark a node active .
2010-04-19 06:30:30 +00:00
*/
public function make_active () {
$this -> isactive = true ;
$this -> add_class ( 'active_tree_node' );
$this -> force_open ();
if ( $this -> parent !== null ) {
$this -> parent -> make_inactive ();
}
}
/**
* Marks a node as inactive and recusised back to the base of the tree
* doing the same to all parents .
*/
public function make_inactive () {
$this -> isactive = false ;
$this -> remove_class ( 'active_tree_node' );
if ( $this -> parent !== null ) {
$this -> parent -> make_inactive ();
2009-08-28 08:47:31 +00:00
}
}
/**
2010-04-19 06:30:30 +00:00
* Forces this node to be open and at the same time forces open all
* parents until the root node .
2009-11-01 11:31:16 +00:00
*
2010-04-19 06:30:30 +00:00
* Recursive .
*/
public function force_open () {
$this -> forceopen = true ;
if ( $this -> parent !== null ) {
$this -> parent -> force_open ();
}
}
/**
* Adds a CSS class to this node .
*
* @ param string $class
* @ return bool
2009-08-28 08:47:31 +00:00
*/
public function add_class ( $class ) {
if ( ! in_array ( $class , $this -> classes )) {
$this -> classes [] = $class ;
}
return true ;
}
/**
2010-04-19 06:30:30 +00:00
* Removes a CSS class from this node .
2009-08-28 08:47:31 +00:00
*
* @ param string $class
2010-04-19 06:30:30 +00:00
* @ return bool True if the class was successfully removed .
2009-08-28 08:47:31 +00:00
*/
public function remove_class ( $class ) {
if ( in_array ( $class , $this -> classes )) {
$key = array_search ( $class , $this -> classes );
if ( $key !== false ) {
unset ( $this -> classes [ $key ]);
return true ;
}
}
return false ;
}
/**
2010-04-19 06:30:30 +00:00
* Sets the title for this node and forces Moodle to utilise it .
* @ param string $title
*/
public function title ( $title ) {
$this -> title = $title ;
$this -> forcetitle = true ;
}
/**
* Resets the page specific information on this node if it is being unserialised .
*/
public function __wakeup (){
$this -> forceopen = false ;
$this -> isactive = false ;
$this -> remove_class ( 'active_tree_node' );
}
/**
* Checks if this node or any of its children contain the active node .
2010-05-30 22:56:29 +00:00
*
2010-04-19 06:30:30 +00:00
* Recursive .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return bool
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function contains_active_node () {
if ( $this -> isactive ) {
2009-08-28 08:47:31 +00:00
return true ;
} else {
2010-04-19 06:30:30 +00:00
foreach ( $this -> children as $child ) {
if ( $child -> isactive || $child -> contains_active_node ()) {
return true ;
}
}
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
return false ;
2009-08-28 08:47:31 +00:00
}
/**
2010-04-19 06:30:30 +00:00
* Finds the active node .
*
* Searches this nodes children plus all of the children for the active node
* and returns it if found .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* Recursive .
*
* @ return navigation_node | false
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function find_active_node () {
if ( $this -> isactive ) {
return $this ;
} else {
2009-08-28 08:47:31 +00:00
foreach ( $this -> children as & $child ) {
2010-04-19 06:30:30 +00:00
$outcome = $child -> find_active_node ();
if ( $outcome !== false ) {
return $outcome ;
2009-08-28 08:47:31 +00:00
}
}
}
2010-04-19 06:30:30 +00:00
return false ;
2009-08-28 08:47:31 +00:00
}
2010-05-19 07:57:00 +00:00
/**
* Searches all children for the best matching active node
* @ return navigation_node | false
*/
public function search_for_active_node () {
if ( $this -> check_if_active ( URL_MATCH_BASE )) {
return $this ;
} else {
foreach ( $this -> children as & $child ) {
$outcome = $child -> search_for_active_node ();
if ( $outcome !== false ) {
return $outcome ;
}
}
}
return false ;
}
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Gets the content for this node .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param bool $shorttext If true shorttext is used rather than the normal text
* @ return string
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function get_content ( $shorttext = false ) {
2009-08-28 08:47:31 +00:00
if ( $shorttext && $this -> shorttext !== null ) {
2010-04-19 06:30:30 +00:00
return format_string ( $this -> shorttext );
2009-08-28 08:47:31 +00:00
} else {
2010-04-19 06:30:30 +00:00
return format_string ( $this -> text );
2009-10-14 09:27:07 +00:00
}
2010-04-19 06:30:30 +00:00
}
2009-10-14 09:27:07 +00:00
2010-04-19 06:30:30 +00:00
/**
* Gets the title to use for this node .
2010-05-30 22:56:29 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return string
*/
public function get_title () {
2010-05-12 08:10:59 +00:00
if ( $this -> forcetitle || $this -> action != null ){
2010-04-19 06:30:30 +00:00
return $this -> title ;
} else {
2010-02-11 18:50:55 +00:00
return '' ;
}
2009-08-28 08:47:31 +00:00
}
2009-11-01 11:31:16 +00:00
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Gets the CSS class to add to this node to describe its type
2010-05-30 22:56:29 +00:00
*
2009-08-28 08:47:31 +00:00
* @ return string
*/
public function get_css_type () {
if ( array_key_exists ( $this -> type , $this -> namedtypes )) {
return 'type_' . $this -> namedtypes [ $this -> type ];
}
return 'type_unknown' ;
}
/**
2010-04-19 06:30:30 +00:00
* Finds all nodes that are expandable by AJAX
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param array $expandable An array by reference to populate with expandable nodes .
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function find_expandable ( array & $expandable ) {
foreach ( $this -> children as & $child ) {
2010-12-23 16:55:52 +08:00
if ( $child -> nodetype == self :: NODETYPE_BRANCH && $child -> children -> count () == 0 && $child -> display ) {
2010-04-19 06:30:30 +00:00
$child -> id = 'expandable_branch_' . ( count ( $expandable ) + 1 );
$this -> add_class ( 'canexpand' );
2010-12-23 16:55:52 +08:00
$expandable [] = array ( 'id' => $child -> id , 'key' => $child -> key , 'type' => $child -> type );
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
$child -> find_expandable ( $expandable );
2009-08-28 08:47:31 +00:00
}
}
2010-04-21 09:44:16 +00:00
2010-05-13 09:57:43 +00:00
/**
* Finds all nodes of a given type ( recursive )
*
* @ param int $type On of navigation_node :: TYPE_ *
* @ return array
*/
2010-04-21 09:44:16 +00:00
public function find_all_of_type ( $type ) {
$nodes = $this -> children -> type ( $type );
foreach ( $this -> children as & $node ) {
$childnodes = $node -> find_all_of_type ( $type );
$nodes = array_merge ( $nodes , $childnodes );
}
return $nodes ;
}
2010-05-21 03:15:48 +00:00
/**
* Removes this node if it is empty
*/
public function trim_if_empty () {
if ( $this -> children -> count () == 0 ) {
$this -> remove ();
}
}
/**
* Creates a tab representation of this nodes children that can be used
* with print_tabs to produce the tabs on a page .
*
* call_user_func_array ( 'print_tabs' , $node -> get_tabs_array ());
*
* @ param array $inactive
* @ param bool $return
* @ return array Array ( tabs , selected , inactive , activated , return )
*/
public function get_tabs_array ( array $inactive = array (), $return = false ) {
$tabs = array ();
$rows = array ();
$selected = null ;
$activated = array ();
foreach ( $this -> children as $node ) {
$tabs [] = new tabobject ( $node -> key , $node -> action , $node -> get_content (), $node -> get_title ());
if ( $node -> contains_active_node ()) {
if ( $node -> children -> count () > 0 ) {
$activated [] = $node -> key ;
foreach ( $node -> children as $child ) {
if ( $child -> contains_active_node ()) {
$selected = $child -> key ;
}
$rows [] = new tabobject ( $child -> key , $child -> action , $child -> get_content (), $child -> get_title ());
}
} else {
$selected = $node -> key ;
}
}
}
return array ( array ( $tabs , $rows ), $selected , $inactive , $activated , $return );
}
2011-06-23 11:29:26 +08:00
/**
* Sets the parent for this node and if this node is active ensures that the tree is properly
* adjusted as well .
*
* @ param navigation_node $parent
*/
public function set_parent ( navigation_node $parent ) {
// Set the parent (thats the easy part)
$this -> parent = $parent ;
// Check if this node is active (this is checked during construction)
if ( $this -> isactive ) {
// Force all of the parent nodes open so you can see this node
$this -> parent -> force_open ();
// Make all parents inactive so that its clear where we are.
$this -> parent -> make_inactive ();
}
}
2010-04-19 06:30:30 +00:00
}
2009-08-28 08:47:31 +00:00
2010-04-19 06:30:30 +00:00
/**
* Navigation node collection
*
* This class is responsible for managing a collection of navigation nodes .
* It is required because a node ' s unique identifier is a combination of both its
* key and its type .
*
* Originally an array was used with a string key that was a combination of the two
* however it was decided that a better solution would be to use a class that
* implements the standard IteratorAggregate interface .
*
* @ package moodlecore
* @ subpackage navigation
* @ copyright 2010 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
class navigation_node_collection implements IteratorAggregate {
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* A multidimensional array to where the first key is the type and the second
* key is the nodes key .
* @ var array
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
protected $collection = array ();
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* An array that contains references to nodes in the same order they were added .
* This is maintained as a progressive array .
* @ var array
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
protected $orderedcollection = array ();
2009-11-04 07:23:19 +00:00
/**
2010-04-19 06:30:30 +00:00
* A reference to the last node that was added to the collection
* @ var navigation_node
2009-11-04 07:23:19 +00:00
*/
2010-04-19 06:30:30 +00:00
protected $last = null ;
2009-10-14 09:08:43 +00:00
/**
2010-04-19 06:30:30 +00:00
* The total number of items added to this array .
* @ var int
2009-10-14 09:08:43 +00:00
*/
2010-04-19 06:30:30 +00:00
protected $count = 0 ;
2011-06-18 16:23:53 +01:00
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Adds a navigation node to the collection
2009-08-28 08:47:31 +00:00
*
2011-05-23 17:34:17 +01:00
* @ param navigation_node $node Node to add
* @ param string $beforekey If specified , adds before a node with this key ,
* otherwise adds at end
* @ return navigation_node Added node
2009-08-28 08:47:31 +00:00
*/
2011-05-23 17:34:17 +01:00
public function add ( navigation_node $node , $beforekey = null ) {
2010-04-19 06:30:30 +00:00
global $CFG ;
$key = $node -> key ;
$type = $node -> type ;
2011-05-23 17:34:17 +01:00
2010-04-19 06:30:30 +00:00
// First check we have a 2nd dimension for this type
if ( ! array_key_exists ( $type , $this -> orderedcollection )) {
$this -> orderedcollection [ $type ] = array ();
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
// Check for a collision and report if debugging is turned on
if ( $CFG -> debug && array_key_exists ( $key , $this -> orderedcollection [ $type ])) {
debugging ( 'Navigation node intersect: Adding a node that already exists ' . $key , DEBUG_DEVELOPER );
2009-08-28 08:47:31 +00:00
}
2011-05-23 17:34:17 +01:00
// Find the key to add before
$newindex = $this -> count ;
$last = true ;
if ( $beforekey !== null ) {
foreach ( $this -> collection as $index => $othernode ) {
if ( $othernode -> key === $beforekey ) {
$newindex = $index ;
$last = false ;
break ;
}
}
if ( $newindex === $this -> count ) {
debugging ( 'Navigation node add_before: Reference node not found ' . $beforekey .
2011-06-18 16:23:53 +01:00
', options: ' . implode ( ' ' , $this -> get_key_list ()), DEBUG_DEVELOPER );
2011-05-23 17:34:17 +01:00
}
}
// Add the node to the appropriate place in the by-type structure (which
// is not ordered, despite the variable name)
2010-04-19 06:30:30 +00:00
$this -> orderedcollection [ $type ][ $key ] = $node ;
2011-05-23 17:34:17 +01:00
if ( ! $last ) {
// Update existing references in the ordered collection (which is the
// one that isn't called 'ordered') to shuffle them along if required
for ( $oldindex = $this -> count ; $oldindex > $newindex ; $oldindex -- ) {
$this -> collection [ $oldindex ] = $this -> collection [ $oldindex - 1 ];
}
}
2010-04-19 06:30:30 +00:00
// Add a reference to the node to the progressive collection.
2011-05-23 17:34:17 +01:00
$this -> collection [ $newindex ] = & $this -> orderedcollection [ $type ][ $key ];
2010-04-19 06:30:30 +00:00
// Update the last property to a reference to this new node.
$this -> last = & $this -> orderedcollection [ $type ][ $key ];
2011-05-30 10:05:59 +08:00
2011-05-23 17:34:17 +01:00
// Reorder the array by index if needed
if ( ! $last ) {
ksort ( $this -> collection );
}
2010-04-19 06:30:30 +00:00
$this -> count ++ ;
// Return the reference to the now added node
2011-05-23 17:34:17 +01:00
return $node ;
2009-08-28 08:47:31 +00:00
}
2011-06-18 16:23:53 +01:00
/**
* Return a list of all the keys of all the nodes .
* @ return array the keys .
*/
public function get_key_list () {
$keys = array ();
foreach ( $this -> collection as $node ) {
$keys [] = $node -> key ;
}
return $keys ;
}
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Fetches a node from this collection .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param string | int $key The key of the node we want to find .
* @ param int $type One of navigation_node :: TYPE_ *.
* @ return navigation_node | null
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function get ( $key , $type = null ) {
if ( $type !== null ) {
// If the type is known then we can simply check and fetch
if ( ! empty ( $this -> orderedcollection [ $type ][ $key ])) {
return $this -> orderedcollection [ $type ][ $key ];
}
} else {
// Because we don't know the type we look in the progressive array
foreach ( $this -> collection as $node ) {
if ( $node -> key === $key ) {
return $node ;
2009-08-28 08:47:31 +00:00
}
}
}
return false ;
}
2011-06-18 16:23:53 +01:00
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Searches for a node with matching key and type .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* This function searches both the nodes in this collection and all of
* the nodes in each collection belonging to the nodes in this collection .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* Recursive .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param string | int $key The key of the node we want to find .
* @ param int $type One of navigation_node :: TYPE_ *.
* @ return navigation_node | null
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function find ( $key , $type = null ) {
if ( $type !== null && array_key_exists ( $type , $this -> orderedcollection ) && array_key_exists ( $key , $this -> orderedcollection [ $type ])) {
return $this -> orderedcollection [ $type ][ $key ];
} else {
$nodes = $this -> getIterator ();
// Search immediate children first
foreach ( $nodes as & $node ) {
2010-07-23 02:59:13 +00:00
if ( $node -> key === $key && ( $type === null || $type === $node -> type )) {
2010-04-19 06:30:30 +00:00
return $node ;
2009-10-13 02:39:05 +00:00
}
2010-04-19 06:30:30 +00:00
}
// Now search each childs children
foreach ( $nodes as & $node ) {
$result = $node -> children -> find ( $key , $type );
if ( $result !== false ) {
return $result ;
2009-10-13 02:39:05 +00:00
}
2009-08-28 08:47:31 +00:00
}
}
return false ;
}
2009-10-13 02:39:05 +00:00
/**
2010-04-19 06:30:30 +00:00
* Fetches the last node that was added to this collection
2010-05-30 22:56:29 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return navigation_node
2009-10-13 02:39:05 +00:00
*/
2010-04-19 06:30:30 +00:00
public function last () {
return $this -> last ;
}
2011-06-18 16:23:53 +01:00
2010-04-19 06:30:30 +00:00
/**
* Fetches all nodes of a given type from this collection
*/
public function type ( $type ) {
if ( ! array_key_exists ( $type , $this -> orderedcollection )) {
$this -> orderedcollection [ $type ] = array ();
2009-10-13 02:39:05 +00:00
}
2010-04-19 06:30:30 +00:00
return $this -> orderedcollection [ $type ];
2009-10-13 02:39:05 +00:00
}
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Removes the node with the given key and type from the collection
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param string | int $key
* @ param int $type
* @ return bool
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function remove ( $key , $type = null ) {
$child = $this -> get ( $key , $type );
if ( $child !== false ) {
foreach ( $this -> collection as $colkey => $node ) {
if ( $node -> key == $key && $node -> type == $type ) {
unset ( $this -> collection [ $colkey ]);
break ;
}
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
unset ( $this -> orderedcollection [ $child -> type ][ $child -> key ]);
$this -> count -- ;
return true ;
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
return false ;
2009-08-28 08:47:31 +00:00
}
2009-08-31 03:58:17 +00:00
/**
2010-04-19 06:30:30 +00:00
* Gets the number of nodes in this collection
2011-06-24 16:42:41 +08:00
*
* This option uses an internal count rather than counting the actual options to avoid
* a performance hit through the count function .
*
2010-04-19 06:30:30 +00:00
* @ return int
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function count () {
2011-06-24 16:42:41 +08:00
return $this -> count ;
2009-08-28 08:47:31 +00:00
}
/**
2010-04-19 06:30:30 +00:00
* Gets an array iterator for the collection .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* This is required by the IteratorAggregator interface and is used by routines
* such as the foreach loop .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return ArrayIterator
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function getIterator () {
return new ArrayIterator ( $this -> collection );
2009-08-28 08:47:31 +00:00
}
}
/**
* The global navigation class used for ... the global navigation
*
* This class is used by PAGE to store the global navigation for the site
* and is then used by the settings nav and navbar to save on processing and DB calls
*
* See
* < ul >
* < li >< b > { @ link lib / pagelib . php } </ b > { @ link moodle_page :: initialise_theme_and_output ()} < li >
* < li >< b > { @ link lib / ajax / getnavbranch . php } </ b > Called by ajax < li >
* </ ul >
*
* @ package moodlecore
2009-10-19 03:29:48 +00:00
* @ subpackage navigation
2009-08-28 08:47:31 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
class global_navigation extends navigation_node {
2010-04-19 06:30:30 +00:00
/**
* The Moodle page this navigation object belongs to .
* @ var moodle_page
*/
protected $page ;
2009-08-28 08:47:31 +00:00
/** @var bool */
protected $initialised = false ;
2010-04-19 06:30:30 +00:00
/** @var array */
protected $mycourses = array ();
/** @var array */
protected $rootnodes = array ();
2009-08-28 08:47:31 +00:00
/** @var bool */
2010-04-19 06:30:30 +00:00
protected $showemptysections = false ;
2011-08-29 13:45:04 +12:00
/** @var bool */
protected $showcategories = null ;
2010-04-19 06:30:30 +00:00
/** @var array */
2009-12-23 01:22:48 +00:00
protected $extendforuser = array ();
2010-04-19 06:30:30 +00:00
/** @var navigation_cache */
protected $cache ;
/** @var array */
protected $addedcourses = array ();
2011-06-24 16:42:41 +08:00
/** @var array */
protected $addedcategories = array ();
2010-04-21 09:44:16 +00:00
/** @var int */
protected $expansionlimit = 0 ;
2011-04-15 18:04:45 +08:00
/** @var int */
2011-05-03 15:41:34 +08:00
protected $useridtouseforparentchecks = 0 ;
2010-04-21 09:44:16 +00:00
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Constructs a new global navigation
*
* @ param moodle_page $page The page this navigation object belongs to
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function __construct ( moodle_page $page ) {
2010-05-13 09:57:43 +00:00
global $CFG , $SITE , $USER ;
2010-04-19 06:30:30 +00:00
2009-08-28 08:47:31 +00:00
if ( during_initial_install ()) {
2010-04-19 06:30:30 +00:00
return ;
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
2010-05-13 09:57:43 +00:00
if ( get_home_page () == HOMEPAGE_SITE ) {
// We are using the site home for the root element
$properties = array (
'key' => 'home' ,
'type' => navigation_node :: TYPE_SYSTEM ,
'text' => get_string ( 'home' ),
'action' => new moodle_url ( '/' )
);
} else {
// We are using the users my moodle for the root element
$properties = array (
'key' => 'myhome' ,
'type' => navigation_node :: TYPE_SYSTEM ,
'text' => get_string ( 'myhome' ),
'action' => new moodle_url ( '/my/' )
);
2010-04-22 07:42:04 +00:00
}
2010-05-13 09:57:43 +00:00
// Use the parents consturctor.... good good reuse
2010-04-19 06:30:30 +00:00
parent :: __construct ( $properties );
// Initalise and set defaults
$this -> page = $page ;
2009-08-28 08:47:31 +00:00
$this -> forceopen = true ;
2009-10-12 05:39:32 +00:00
$this -> cache = new navigation_cache ( NAVIGATION_CACHE_NAME );
2009-08-28 08:47:31 +00:00
}
2011-04-15 18:04:45 +08:00
/**
* Mutator to set userid to allow parent to see child ' s profile
* page navigation . See MDL - 25805 for initial issue . Linked to it
* is an issue explaining why this is a REALLY UGLY HACK thats not
* for you to use !
*
2011-07-04 16:42:55 +02:00
* @ param int $userid userid of profile page that parent wants to navigate around .
2011-04-15 18:04:45 +08:00
*/
2011-05-03 15:41:34 +08:00
public function set_userid_for_parent_checks ( $userid ) {
$this -> useridtouseforparentchecks = $userid ;
2011-04-15 18:04:45 +08:00
}
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Initialises the navigation object .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* This causes the navigation object to look at the current state of the page
* that it is associated with and then load the appropriate content .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* This should only occur the first time that the navigation structure is utilised
* which will normally be either when the navbar is called to be displayed or
* when a block makes use of it .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return bool
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function initialise () {
2010-05-13 09:57:43 +00:00
global $CFG , $SITE , $USER , $DB ;
2010-04-19 06:30:30 +00:00
// Check if it has alread been initialised
2009-08-28 08:47:31 +00:00
if ( $this -> initialised || during_initial_install ()) {
return true ;
}
2010-06-10 07:47:59 +00:00
$this -> initialised = true ;
2010-04-19 06:30:30 +00:00
// Set up the five base root nodes. These are nodes where we will put our
// content and are as follows:
// site: Navigation for the front page.
// myprofile: User profile information goes here.
// mycourses: The users courses get added here.
// courses: Additional courses are added here.
// users: Other users information loaded here.
$this -> rootnodes = array ();
2010-05-13 09:57:43 +00:00
if ( get_home_page () == HOMEPAGE_SITE ) {
2010-05-14 02:55:46 +00:00
// The home element should be my moodle because the root element is the site
2010-06-03 08:11:46 +00:00
if ( isloggedin () && ! isguestuser ()) { // Makes no sense if you aren't logged in
2011-06-24 16:42:41 +08:00
$this -> rootnodes [ 'home' ] = $this -> add ( get_string ( 'myhome' ), new moodle_url ( '/my/' ), self :: TYPE_SETTING , null , 'home' );
2010-05-14 02:55:46 +00:00
}
2010-05-13 09:57:43 +00:00
} else {
// The home element should be the site because the root node is my moodle
2011-06-24 16:42:41 +08:00
$this -> rootnodes [ 'home' ] = $this -> add ( get_string ( 'sitehome' ), new moodle_url ( '/' ), self :: TYPE_SETTING , null , 'home' );
2010-05-13 09:57:43 +00:00
if ( $CFG -> defaulthomepage == HOMEPAGE_MY ) {
// We need to stop automatic redirection
$this -> rootnodes [ 'home' ] -> action -> param ( 'redirect' , '0' );
}
}
2010-04-19 06:30:30 +00:00
$this -> rootnodes [ 'site' ] = $this -> add_course ( $SITE );
2011-06-24 16:42:41 +08:00
$this -> rootnodes [ 'myprofile' ] = $this -> add ( get_string ( 'myprofile' ), null , self :: TYPE_USER , null , 'myprofile' );
2010-04-19 06:30:30 +00:00
$this -> rootnodes [ 'mycourses' ] = $this -> add ( get_string ( 'mycourses' ), null , self :: TYPE_ROOTNODE , null , 'mycourses' );
$this -> rootnodes [ 'courses' ] = $this -> add ( get_string ( 'courses' ), null , self :: TYPE_ROOTNODE , null , 'courses' );
$this -> rootnodes [ 'users' ] = $this -> add ( get_string ( 'users' ), null , self :: TYPE_ROOTNODE , null , 'users' );
// Fetch all of the users courses.
2010-05-13 09:57:43 +00:00
$limit = 20 ;
if ( ! empty ( $CFG -> navcourselimit )) {
$limit = $CFG -> navcourselimit ;
}
2011-06-24 16:42:41 +08:00
$mycourses = enrol_get_my_courses ( NULL , 'visible DESC,sortorder ASC' , $limit );
$showallcourses = ( count ( $mycourses ) == 0 || ! empty ( $CFG -> navshowallcourses ));
2011-08-29 13:45:04 +12:00
$showcategories = ( $showallcourses && $this -> show_categories ());
2011-11-29 11:01:50 +13:00
$issite = ( $this -> page -> course -> id == SITEID );
2011-06-24 16:42:41 +08:00
$ismycourse = ( array_key_exists ( $this -> page -> course -> id , $mycourses ));
2010-05-14 06:41:44 +00:00
2010-04-19 06:30:30 +00:00
// Check if any courses were returned.
2011-06-24 16:42:41 +08:00
if ( count ( $mycourses ) > 0 ) {
2010-04-19 06:30:30 +00:00
// Add all of the users courses to the navigation
2011-06-24 16:42:41 +08:00
foreach ( $mycourses as $course ) {
$course -> coursenode = $this -> add_course ( $course , false , true );
2010-04-19 06:30:30 +00:00
}
2010-05-13 09:57:43 +00:00
}
2011-06-24 16:42:41 +08:00
if ( $showallcourses ) {
2010-05-14 06:41:44 +00:00
// Load all courses
$this -> load_all_courses ();
2010-04-19 06:30:30 +00:00
}
2010-07-23 02:38:59 +00:00
// We always load the frontpage course to ensure it is available without
// JavaScript enabled.
$frontpagecourse = $this -> load_course ( $SITE );
$this -> add_front_page_course_essentials ( $frontpagecourse , $SITE );
2011-11-29 11:01:50 +13:00
$this -> load_course_sections ( $SITE , $frontpagecourse );
2010-07-23 02:38:59 +00:00
2010-08-05 02:22:48 +00:00
$canviewcourseprofile = true ;
2011-11-29 11:01:50 +13:00
if ( ! $issite ) {
// Next load context specific content into the navigation
switch ( $this -> page -> context -> contextlevel ) {
case CONTEXT_SYSTEM :
// This has already been loaded we just need to map the variable
$coursenode = $frontpagecourse ;
$this -> load_all_categories ( null , $showcategories );
2010-10-11 07:43:51 +00:00
break ;
2011-11-29 11:01:50 +13:00
case CONTEXT_COURSECAT :
// This has already been loaded we just need to map the variable
$coursenode = $frontpagecourse ;
$this -> load_all_categories ( $this -> page -> context -> instanceid , $showcategories );
break ;
case CONTEXT_BLOCK :
case CONTEXT_COURSE :
// Load the course associated with the page into the navigation
$course = $this -> page -> course ;
if ( $showcategories && ! $ismycourse ) {
$this -> load_all_categories ( $course -> category , $showcategories );
2011-04-15 18:04:45 +08:00
}
2011-11-29 11:01:50 +13:00
$coursenode = $this -> load_course ( $course );
2011-04-15 18:04:45 +08:00
2011-11-29 11:01:50 +13:00
// If the course wasn't added then don't try going any further.
if ( ! $coursenode ) {
2011-04-15 18:04:45 +08:00
$canviewcourseprofile = false ;
break ;
}
2011-06-24 16:42:41 +08:00
2011-11-29 11:01:50 +13:00
// If the user is not enrolled then we only want to show the
// course node and not populate it.
2011-06-24 16:42:41 +08:00
2011-11-29 11:01:50 +13:00
// Not enrolled, can't view, and hasn't switched roles
if ( ! can_access_course ( $course )) {
// TODO: very ugly hack - do not force "parents" to enrol into course their child is enrolled in,
// this hack has been propagated from user/view.php to display the navigation node. (MDL-25805)
$isparent = false ;
if ( $this -> useridtouseforparentchecks ) {
if ( $this -> useridtouseforparentchecks != $USER -> id ) {
$usercontext = get_context_instance ( CONTEXT_USER , $this -> useridtouseforparentchecks , MUST_EXIST );
if ( $DB -> record_exists ( 'role_assignments' , array ( 'userid' => $USER -> id , 'contextid' => $usercontext -> id ))
and has_capability ( 'moodle/user:viewdetails' , $usercontext )) {
$isparent = true ;
}
}
}
2010-08-05 02:22:48 +00:00
2011-11-29 11:01:50 +13:00
if ( ! $isparent ) {
$coursenode -> make_active ();
$canviewcourseprofile = false ;
break ;
}
}
// Add the essentials such as reports etc...
$this -> add_course_essentials ( $coursenode , $course );
if ( $this -> format_display_course_content ( $course -> format )) {
// Load the course sections
$sections = $this -> load_course_sections ( $course , $coursenode );
}
if ( ! $coursenode -> contains_active_node () && ! $coursenode -> search_for_active_node ()) {
$coursenode -> make_active ();
}
2011-07-13 13:39:29 +08:00
break ;
2011-11-29 11:01:50 +13:00
case CONTEXT_MODULE :
$course = $this -> page -> course ;
$cm = $this -> page -> cm ;
2011-07-13 13:39:29 +08:00
2011-11-29 11:01:50 +13:00
if ( $showcategories && ! $ismycourse ) {
$this -> load_all_categories ( $course -> category , $showcategories );
}
2010-08-05 02:22:48 +00:00
2011-11-29 11:01:50 +13:00
// Load the course associated with the page into the navigation
$coursenode = $this -> load_course ( $course );
// If the course wasn't added then don't try going any further.
if ( ! $coursenode ) {
$canviewcourseprofile = false ;
break ;
}
// If the user is not enrolled then we only want to show the
// course node and not populate it.
if ( ! can_access_course ( $course )) {
$coursenode -> make_active ();
$canviewcourseprofile = false ;
break ;
}
$this -> add_course_essentials ( $coursenode , $course );
// Load the course sections into the page
$sections = $this -> load_course_sections ( $course , $coursenode );
if ( $course -> id != SITEID ) {
// Find the section for the $CM associated with the page and collect
// its section number.
if ( isset ( $cm -> sectionnum )) {
$cm -> sectionnumber = $cm -> sectionnum ;
} else {
foreach ( $sections as $section ) {
if ( $section -> id == $cm -> section ) {
$cm -> sectionnumber = $section -> section ;
break ;
}
2011-01-26 10:29:16 +00:00
}
2010-04-19 06:30:30 +00:00
}
2011-11-29 11:01:50 +13:00
// Load all of the section activities for the section the cm belongs to.
if ( isset ( $cm -> sectionnumber ) and ! empty ( $sections [ $cm -> sectionnumber ])) {
list ( $sectionarray , $activityarray ) = $this -> generate_sections_and_activities ( $course );
$activities = $this -> load_section_activities ( $sections [ $cm -> sectionnumber ] -> sectionnode , $cm -> sectionnumber , $activityarray );
} else {
$activities = array ();
if ( $activity = $this -> load_stealth_activity ( $coursenode , get_fast_modinfo ( $course ))) {
// "stealth" activity from unavailable section
$activities [ $cm -> id ] = $activity ;
}
}
2010-10-13 18:51:37 +00:00
} else {
$activities = array ();
2011-11-29 11:01:50 +13:00
$activities [ $cm -> id ] = $coursenode -> get ( $cm -> id , navigation_node :: TYPE_ACTIVITY );
2010-10-13 18:51:37 +00:00
}
2011-11-29 11:01:50 +13:00
if ( ! empty ( $activities [ $cm -> id ])) {
// Finally load the cm specific navigaton information
$this -> load_activity ( $cm , $course , $activities [ $cm -> id ]);
// Check if we have an active ndoe
if ( ! $activities [ $cm -> id ] -> contains_active_node () && ! $activities [ $cm -> id ] -> search_for_active_node ()) {
// And make the activity node active.
$activities [ $cm -> id ] -> make_active ();
}
} else {
//TODO: something is wrong, what to do? (Skodak)
2010-10-13 18:51:37 +00:00
}
2011-11-29 11:01:50 +13:00
break ;
case CONTEXT_USER :
2011-12-02 12:31:12 +13:00
$course = $this -> page -> course ;
2011-11-29 11:01:50 +13:00
if ( $showcategories && ! $ismycourse ) {
2011-06-24 16:42:41 +08:00
$this -> load_all_categories ( $course -> category , $showcategories );
}
2010-04-19 06:30:30 +00:00
// Load the course associated with the user into the navigation
$coursenode = $this -> load_course ( $course );
2011-07-13 13:39:29 +08:00
// If the course wasn't added then don't try going any further.
if ( ! $coursenode ) {
$canviewcourseprofile = false ;
break ;
}
2010-08-05 02:22:48 +00:00
// If the user is not enrolled then we only want to show the
// course node and not populate it.
2011-10-29 09:45:54 +02:00
if ( ! can_access_course ( $course )) {
2010-08-05 02:22:48 +00:00
$coursenode -> make_active ();
$canviewcourseprofile = false ;
break ;
}
2010-04-19 06:30:30 +00:00
$this -> add_course_essentials ( $coursenode , $course );
$sections = $this -> load_course_sections ( $course , $coursenode );
2011-11-29 11:01:50 +13:00
break ;
}
2011-12-06 13:32:59 +13:00
} else {
// We need to check if the user is viewing a front page module.
// If so then there is potentially more content to load yet for that
// module.
if ( $this -> page -> context -> contextlevel == CONTEXT_MODULE ) {
$activitynode = $this -> rootnodes [ 'site' ] -> get ( $this -> page -> cm -> id , navigation_node :: TYPE_ACTIVITY );
if ( $activitynode ) {
$this -> load_activity ( $this -> page -> cm , $this -> page -> course , $activitynode );
}
}
2009-08-28 08:47:31 +00:00
}
2009-12-23 01:22:48 +00:00
2010-05-14 06:41:44 +00:00
$limit = 20 ;
if ( ! empty ( $CFG -> navcourselimit )) {
$limit = $CFG -> navcourselimit ;
}
if ( $showcategories ) {
$categories = $this -> find_all_of_type ( self :: TYPE_CATEGORY );
foreach ( $categories as & $category ) {
if ( $category -> children -> count () >= $limit ) {
$url = new moodle_url ( '/course/category.php' , array ( 'id' => $category -> key ));
$category -> add ( get_string ( 'viewallcourses' ), $url , self :: TYPE_SETTING );
}
}
} else if ( $this -> rootnodes [ 'courses' ] -> children -> count () >= $limit ) {
$this -> rootnodes [ 'courses' ] -> add ( get_string ( 'viewallcoursescategories' ), new moodle_url ( '/course/index.php' ), self :: TYPE_SETTING );
}
2010-04-19 06:30:30 +00:00
// Load for the current user
$this -> load_for_user ();
2010-08-05 02:22:48 +00:00
if ( $this -> page -> context -> contextlevel >= CONTEXT_COURSE && $this -> page -> context -> instanceid != SITEID && $canviewcourseprofile ) {
2010-05-17 05:38:59 +00:00
$this -> load_for_user ( null , true );
}
2009-12-23 01:22:48 +00:00
// Load each extending user into the navigation.
foreach ( $this -> extendforuser as $user ) {
2011-02-13 16:17:47 +01:00
if ( $user -> id != $USER -> id ) {
2009-12-23 01:22:48 +00:00
$this -> load_for_user ( $user );
}
}
2010-04-27 09:26:42 +00:00
// Give the local plugins a chance to include some navigation if they want.
foreach ( get_list_of_plugins ( 'local' ) as $plugin ) {
if ( ! file_exists ( $CFG -> dirroot . '/local/' . $plugin . '/lib.php' )) {
continue ;
}
require_once ( $CFG -> dirroot . '/local/' . $plugin . '/lib.php' );
$function = $plugin . '_extends_navigation' ;
if ( function_exists ( $function )) {
$function ( $this );
}
}
2010-04-19 06:30:30 +00:00
// Remove any empty root nodes
foreach ( $this -> rootnodes as $node ) {
2010-05-13 09:57:43 +00:00
// Dont remove the home node
if ( $node -> key !== 'home' && ! $node -> has_children ()) {
2010-04-19 06:30:30 +00:00
$node -> remove ();
}
}
2010-05-19 07:57:00 +00:00
if ( ! $this -> contains_active_node ()) {
$this -> search_for_active_node ();
}
2010-04-19 06:30:30 +00:00
// If the user is not logged in modify the navigation structure as detailed
2011-07-04 11:21:48 +08:00
// in {@link http://docs.moodle.org/dev/Navigation_2.0_structure}
2010-04-19 06:30:30 +00:00
if ( ! isloggedin ()) {
$activities = clone ( $this -> rootnodes [ 'site' ] -> children );
$this -> rootnodes [ 'site' ] -> remove ();
$children = clone ( $this -> children );
$this -> children = new navigation_node_collection ();
foreach ( $activities as $child ) {
$this -> children -> add ( $child );
}
foreach ( $children as $child ) {
$this -> children -> add ( $child );
}
}
2009-08-28 08:47:31 +00:00
return true ;
}
2011-08-29 13:45:04 +12:00
/**
* Returns true is courses should be shown within categories on the navigation .
*
* @ return bool
*/
protected function show_categories () {
global $CFG , $DB ;
if ( $this -> showcategories === null ) {
$this -> showcategories = ! empty ( $CFG -> navshowcategories ) && $DB -> count_records ( 'course_categories' ) > 1 ;
}
return $this -> showcategories ;
}
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Checks the course format to see whether it wants the navigation to load
* additional information for the course .
*
* This function utilises a callback that can exist within the course format lib . php file
* The callback should be a function called :
* callback_ { formatname } _display_content ()
* It doesn ' t get any arguments and should return true if additional content is
* desired . If the callback doesn ' t exist we assume additional content is wanted .
*
* @ param string $format The course format
* @ return bool
*/
protected function format_display_course_content ( $format ) {
global $CFG ;
$formatlib = $CFG -> dirroot . '/course/format/' . $format . '/lib.php' ;
if ( file_exists ( $formatlib )) {
require_once ( $formatlib );
$displayfunc = 'callback_' . $format . '_display_content' ;
if ( function_exists ( $displayfunc ) && ! $displayfunc ()) {
return $displayfunc ();
}
}
return true ;
}
/**
* Loads of the the courses in Moodle into the navigation .
*
2011-06-24 16:42:41 +08:00
* @ global moodle_database $DB
2010-05-13 09:57:43 +00:00
* @ param string | array $categoryids Either a string or array of category ids to load courses for
2010-04-19 06:30:30 +00:00
* @ return array An array of navigation_node
*/
2010-05-13 09:57:43 +00:00
protected function load_all_courses ( $categoryids = null ) {
global $CFG , $DB , $USER ;
if ( $categoryids !== null ) {
if ( is_array ( $categoryids )) {
2011-06-24 16:42:41 +08:00
list ( $categoryselect , $params ) = $DB -> get_in_or_equal ( $categoryids , SQL_PARAMS_NAMED , 'catid' );
2010-05-13 09:57:43 +00:00
} else {
2011-06-24 16:42:41 +08:00
$categoryselect = '= :categoryid' ;
$params = array ( 'categoryid' , $categoryids );
2010-05-13 09:57:43 +00:00
}
2011-06-24 16:42:41 +08:00
$params [ 'siteid' ] = SITEID ;
$categoryselect = ' AND c.category ' . $categoryselect ;
2010-05-13 09:57:43 +00:00
} else {
2011-06-24 16:42:41 +08:00
$params = array ( 'siteid' => SITEID );
$categoryselect = '' ;
}
2010-04-19 06:30:30 +00:00
list ( $ccselect , $ccjoin ) = context_instance_preload_sql ( 'c.id' , CONTEXT_COURSE , 'ctx' );
2011-06-24 16:42:41 +08:00
list ( $courseids , $courseparams ) = $DB -> get_in_or_equal ( array_keys ( $this -> addedcourses ) + array ( SITEID ), SQL_PARAMS_NAMED , 'lcourse' , false );
$sql = " SELECT c.id, c.sortorder, c.visible, c.fullname, c.shortname, c.category, cat.path AS categorypath $ccselect
FROM { course } c
$ccjoin
LEFT JOIN { course_categories } cat ON cat . id = c . category
WHERE c . id { $courseids } { $categoryselect }
ORDER BY c . sortorder ASC " ;
2010-05-13 09:57:43 +00:00
$limit = 20 ;
if ( ! empty ( $CFG -> navcourselimit )) {
$limit = $CFG -> navcourselimit ;
}
2011-06-24 16:42:41 +08:00
$courses = $DB -> get_records_sql ( $sql , $params + $courseparams , 0 , $limit );
2010-05-13 09:57:43 +00:00
2010-04-19 06:30:30 +00:00
$coursenodes = array ();
foreach ( $courses as $course ) {
context_instance_preload ( $course );
$coursenodes [ $course -> id ] = $this -> add_course ( $course );
}
return $coursenodes ;
}
2010-05-13 09:57:43 +00:00
/**
* Loads all categories ( top level or if an id is specified for that category )
*
2011-06-24 16:42:41 +08:00
* @ param int $categoryid The category id to load or null / 0 to load all base level categories
* @ param bool $showbasecategories If set to true all base level categories will be loaded as well
* as the requested category and any parent categories .
2010-05-13 09:57:43 +00:00
* @ return void
*/
2011-06-24 16:42:41 +08:00
protected function load_all_categories ( $categoryid = null , $showbasecategories = false ) {
2010-05-13 09:57:43 +00:00
global $DB ;
2011-06-24 16:42:41 +08:00
// Check if this category has already been loaded
if ( $categoryid !== null && array_key_exists ( $categoryid , $this -> addedcategories ) && $this -> addedcategories [ $categoryid ] -> children -> count () > 0 ) {
return $this -> addedcategories [ $categoryid ];
}
$coursestoload = array ();
if ( empty ( $categoryid )) { // can be 0
// We are going to load all of the first level categories (categories without parents)
2011-07-13 09:58:42 +08:00
$categories = $DB -> get_records ( 'course_categories' , array ( 'parent' => '0' ), 'sortorder ASC, id ASC' );
2011-06-24 16:42:41 +08:00
} else if ( array_key_exists ( $categoryid , $this -> addedcategories )) {
// The category itself has been loaded already so we just need to ensure its subcategories
// have been loaded
list ( $sql , $params ) = $DB -> get_in_or_equal ( array_keys ( $this -> addedcategories ), SQL_PARAMS_NAMED , 'parent' , false );
if ( $showbasecategories ) {
// We need to include categories with parent = 0 as well
$sql = " SELECT *
FROM { course_categories } cc
WHERE ( parent = : categoryid OR parent = 0 ) AND
parent { $sql }
2011-07-13 09:58:42 +08:00
ORDER BY depth DESC , sortorder ASC , id ASC " ;
2011-06-24 16:42:41 +08:00
} else {
$sql = " SELECT *
FROM { course_categories } cc
WHERE parent = : categoryid AND
parent { $sql }
2011-07-13 09:58:42 +08:00
ORDER BY depth DESC , sortorder ASC , id ASC " ;
2011-06-24 16:42:41 +08:00
}
$params [ 'categoryid' ] = $categoryid ;
$categories = $DB -> get_records_sql ( $sql , $params );
if ( count ( $categories ) == 0 ) {
// There are no further categories that require loading.
return ;
}
2010-05-13 09:57:43 +00:00
} else {
2011-06-24 16:42:41 +08:00
// This category hasn't been loaded yet so we need to fetch it, work out its category path
// and load this category plus all its parents and subcategories
2011-06-27 15:11:28 +08:00
$category = $DB -> get_record ( 'course_categories' , array ( 'id' => $categoryid ), 'path' , MUST_EXIST );
2011-06-24 16:42:41 +08:00
$coursestoload = explode ( '/' , trim ( $category -> path , '/' ));
list ( $select , $params ) = $DB -> get_in_or_equal ( $coursestoload );
2010-05-13 09:57:43 +00:00
$select = 'id ' . $select . ' OR parent ' . $select ;
2011-06-24 16:42:41 +08:00
if ( $showbasecategories ) {
$select .= ' OR parent = 0' ;
}
2010-05-13 09:57:43 +00:00
$params = array_merge ( $params , $params );
$categories = $DB -> get_records_select ( 'course_categories' , $select , $params , 'sortorder' );
}
2011-06-24 16:42:41 +08:00
// Now we have an array of categories we need to add them to the navigation.
while ( ! empty ( $categories )) {
$category = reset ( $categories );
if ( array_key_exists ( $category -> id , $this -> addedcategories )) {
// Do nothing
} else if ( $category -> parent == '0' ) {
$this -> add_category ( $category , $this -> rootnodes [ 'courses' ]);
} else if ( array_key_exists ( $category -> parent , $this -> addedcategories )) {
$this -> add_category ( $category , $this -> addedcategories [ $category -> parent ]);
2010-05-13 09:57:43 +00:00
} else {
2011-06-24 16:42:41 +08:00
// This category isn't in the navigation and niether is it's parent (yet).
// We need to go through the category path and add all of its components in order.
$path = explode ( '/' , trim ( $category -> path , '/' ));
foreach ( $path as $catid ) {
if ( ! array_key_exists ( $catid , $this -> addedcategories )) {
// This category isn't in the navigation yet so add it.
$subcategory = $categories [ $catid ];
2011-07-13 09:58:42 +08:00
if ( $subcategory -> parent == '0' ) {
// Yay we have a root category - this likely means we will now be able
// to add categories without problems.
$this -> add_category ( $subcategory , $this -> rootnodes [ 'courses' ]);
} else if ( array_key_exists ( $subcategory -> parent , $this -> addedcategories )) {
2011-06-24 16:42:41 +08:00
// The parent is in the category (as we'd expect) so add it now.
$this -> add_category ( $subcategory , $this -> addedcategories [ $subcategory -> parent ]);
// Remove the category from the categories array.
unset ( $categories [ $catid ]);
} else {
// We should never ever arrive here - if we have then there is a bigger
// problem at hand.
2011-07-04 16:42:55 +02:00
throw new coding_exception ( 'Category path order is incorrect and/or there are missing categories' );
2011-06-24 16:42:41 +08:00
}
2010-05-13 09:57:43 +00:00
}
}
}
2011-06-24 16:42:41 +08:00
// Remove the category from the categories array now that we know it has been added.
unset ( $categories [ $category -> id ]);
2010-05-13 09:57:43 +00:00
}
2011-06-24 16:42:41 +08:00
// Check if there are any categories to load.
if ( count ( $coursestoload ) > 0 ) {
$this -> load_all_courses ( $coursestoload );
2010-05-13 09:57:43 +00:00
}
}
/**
* Adds a structured category to the navigation in the correct order / place
*
2011-06-24 16:42:41 +08:00
* @ param stdClass $category
2010-05-30 22:56:29 +00:00
* @ param navigation_node $parent
2010-05-13 09:57:43 +00:00
*/
2011-06-24 16:42:41 +08:00
protected function add_category ( stdClass $category , navigation_node $parent ) {
if ( array_key_exists ( $category -> id , $this -> addedcategories )) {
2011-10-29 09:59:49 +02:00
return ;
2011-06-24 16:42:41 +08:00
}
$url = new moodle_url ( '/course/category.php' , array ( 'id' => $category -> id ));
2011-08-30 17:48:46 +12:00
$context = get_context_instance ( CONTEXT_COURSECAT , $category -> id );
$categoryname = format_string ( $category -> name , true , array ( 'context' => $context ));
$categorynode = $parent -> add ( $categoryname , $url , self :: TYPE_CATEGORY , $categoryname , $category -> id );
2011-06-24 16:42:41 +08:00
if ( empty ( $category -> visible )) {
if ( has_capability ( 'moodle/category:viewhiddencategories' , get_system_context ())) {
$categorynode -> hidden = true ;
} else {
$categorynode -> display = false ;
2010-09-15 06:02:02 +00:00
}
2010-05-13 09:57:43 +00:00
}
2011-06-24 16:42:41 +08:00
$this -> addedcategories [ $category -> id ] = & $categorynode ;
2010-05-13 09:57:43 +00:00
}
2010-04-19 06:30:30 +00:00
/**
* Loads the given course into the navigation
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param stdClass $course
* @ return navigation_node
*/
protected function load_course ( stdClass $course ) {
if ( $course -> id == SITEID ) {
2011-06-24 16:42:41 +08:00
return $this -> rootnodes [ 'site' ];
} else if ( array_key_exists ( $course -> id , $this -> addedcourses )) {
return $this -> addedcourses [ $course -> id ];
2010-04-19 06:30:30 +00:00
} else {
2011-06-24 16:42:41 +08:00
return $this -> add_course ( $course );
2010-04-19 06:30:30 +00:00
}
}
/**
* Loads all of the courses section into the navigation .
*
* This function utilisies a callback that can be implemented within the course
* formats lib . php file to customise the navigation that is generated at this
* point for the course .
*
* By default ( if not defined ) the method { @ see load_generic_course_sections } is
* called instead .
*
* @ param stdClass $course Database record for the course
* @ param navigation_node $coursenode The course node within the navigation
* @ return array Array of navigation nodes for the section with key = section id
*/
protected function load_course_sections ( stdClass $course , navigation_node $coursenode ) {
global $CFG ;
$structurefile = $CFG -> dirroot . '/course/format/' . $course -> format . '/lib.php' ;
$structurefunc = 'callback_' . $course -> format . '_load_content' ;
if ( function_exists ( $structurefunc )) {
return $structurefunc ( $this , $course , $coursenode );
} else if ( file_exists ( $structurefile )) {
require_once $structurefile ;
if ( function_exists ( $structurefunc )) {
return $structurefunc ( $this , $course , $coursenode );
} else {
2010-04-23 07:17:21 +00:00
return $this -> load_generic_course_sections ( $course , $coursenode );
2010-04-19 06:30:30 +00:00
}
} else {
2010-04-23 07:17:21 +00:00
return $this -> load_generic_course_sections ( $course , $coursenode );
2010-04-19 06:30:30 +00:00
}
}
2011-06-24 16:42:41 +08:00
/**
* Generates an array of sections and an array of activities for the given course .
*
* This method uses the cache to improve performance and avoid the get_fast_modinfo call
*
* @ param stdClass $course
* @ return array Array ( $sections , $activities )
*/
protected function generate_sections_and_activities ( stdClass $course ) {
global $CFG ;
require_once ( $CFG -> dirroot . '/course/lib.php' );
if ( ! $this -> cache -> cached ( 'course_sections_' . $course -> id ) || ! $this -> cache -> cached ( 'course_activites_' . $course -> id )) {
$modinfo = get_fast_modinfo ( $course );
$sections = array_slice ( get_all_sections ( $course -> id ), 0 , $course -> numsections + 1 , true );
$activities = array ();
foreach ( $sections as $key => $section ) {
$sections [ $key ] -> hasactivites = false ;
if ( ! array_key_exists ( $section -> section , $modinfo -> sections )) {
continue ;
}
foreach ( $modinfo -> sections [ $section -> section ] as $cmid ) {
$cm = $modinfo -> cms [ $cmid ];
if ( ! $cm -> uservisible ) {
continue ;
}
$activity = new stdClass ;
$activity -> section = $section -> section ;
$activity -> name = $cm -> name ;
$activity -> icon = $cm -> icon ;
$activity -> iconcomponent = $cm -> iconcomponent ;
$activity -> id = $cm -> id ;
$activity -> hidden = ( ! $cm -> visible );
$activity -> modname = $cm -> modname ;
$activity -> nodetype = navigation_node :: NODETYPE_LEAF ;
2011-10-06 19:32:27 +13:00
$activity -> onclick = $cm -> get_on_click ();
2011-06-24 16:42:41 +08:00
$url = $cm -> get_url ();
if ( ! $url ) {
$activity -> url = null ;
$activity -> display = false ;
} else {
$activity -> url = $cm -> get_url () -> out ();
$activity -> display = true ;
if ( self :: module_extends_navigation ( $cm -> modname )) {
$activity -> nodetype = navigation_node :: NODETYPE_BRANCH ;
}
}
$activities [ $cmid ] = $activity ;
$sections [ $key ] -> hasactivites = true ;
}
}
$this -> cache -> set ( 'course_sections_' . $course -> id , $sections );
$this -> cache -> set ( 'course_activites_' . $course -> id , $activities );
} else {
$sections = $this -> cache -> { 'course_sections_' . $course -> id };
$activities = $this -> cache -> { 'course_activites_' . $course -> id };
}
return array ( $sections , $activities );
}
2010-04-19 06:30:30 +00:00
/**
* Generically loads the course sections into the course ' s navigation .
*
* @ param stdClass $course
* @ param navigation_node $coursenode
2011-06-24 16:42:41 +08:00
* @ param string $courseformat The course format
2010-04-19 06:30:30 +00:00
* @ return array An array of course section nodes
*/
2010-04-23 07:17:21 +00:00
public function load_generic_course_sections ( stdClass $course , navigation_node $coursenode , $courseformat = 'unknown' ) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
global $CFG , $DB , $USER ;
require_once ( $CFG -> dirroot . '/course/lib.php' );
2010-05-30 22:56:29 +00:00
2011-06-24 16:42:41 +08:00
list ( $sections , $activities ) = $this -> generate_sections_and_activities ( $course );
2010-04-23 07:17:21 +00:00
$namingfunction = 'callback_' . $courseformat . '_get_section_name' ;
$namingfunctionexists = ( function_exists ( $namingfunction ));
2011-07-28 15:20:01 +08:00
2011-06-24 16:42:41 +08:00
$viewhiddensections = has_capability ( 'moodle/course:viewhiddensections' , $this -> page -> context );
2010-05-30 22:56:29 +00:00
2011-07-28 15:20:01 +08:00
$urlfunction = 'callback_' . $courseformat . '_get_section_url' ;
if ( empty ( $CFG -> navlinkcoursesections ) || ! function_exists ( $urlfunction )) {
$urlfunction = null ;
}
$keyfunction = 'callback_' . $courseformat . '_request_key' ;
$key = course_get_display ( $course -> id );
if ( defined ( 'AJAX_SCRIPT' ) && AJAX_SCRIPT == '0' && function_exists ( $keyfunction ) && $this -> page -> url -> compare ( new moodle_url ( '/course/view.php' ), URL_MATCH_BASE )) {
$key = optional_param ( $keyfunction (), $key , PARAM_INT );
}
2010-06-08 06:21:25 +00:00
$navigationsections = array ();
2011-06-24 16:42:41 +08:00
foreach ( $sections as $sectionid => $section ) {
2010-06-08 06:21:25 +00:00
$section = clone ( $section );
2010-04-19 06:30:30 +00:00
if ( $course -> id == SITEID ) {
2011-06-24 16:42:41 +08:00
$this -> load_section_activities ( $coursenode , $section -> section , $activities );
2010-04-19 06:30:30 +00:00
} else {
2011-06-24 16:42:41 +08:00
if (( ! $viewhiddensections && ! $section -> visible ) || ( ! $this -> showemptysections && ! $section -> hasactivites )) {
2010-04-19 06:30:30 +00:00
continue ;
}
2010-04-23 07:17:21 +00:00
if ( $namingfunctionexists ) {
$sectionname = $namingfunction ( $course , $section , $sections );
2010-04-19 06:30:30 +00:00
} else {
2010-04-23 07:17:21 +00:00
$sectionname = get_string ( 'section' ) . ' ' . $section -> section ;
2010-04-19 06:30:30 +00:00
}
2011-07-28 15:20:01 +08:00
2010-10-21 09:43:31 +00:00
$url = null ;
2011-07-28 15:20:01 +08:00
if ( ! empty ( $urlfunction )) {
$url = $urlfunction ( $course -> id , $section -> section );
}
2010-04-19 06:30:30 +00:00
$sectionnode = $coursenode -> add ( $sectionname , $url , navigation_node :: TYPE_SECTION , null , $section -> id );
$sectionnode -> nodetype = navigation_node :: NODETYPE_BRANCH ;
$sectionnode -> hidden = ( ! $section -> visible );
2011-07-28 15:20:01 +08:00
if ( $key != '0' && $section -> section != '0' && $section -> section == $key && $this -> page -> context -> contextlevel != CONTEXT_MODULE && $section -> hasactivites ) {
$sectionnode -> make_active ();
2011-06-24 16:42:41 +08:00
$this -> load_section_activities ( $sectionnode , $section -> section , $activities );
2010-04-19 06:30:30 +00:00
}
$section -> sectionnode = $sectionnode ;
2010-06-08 06:21:25 +00:00
$navigationsections [ $sectionid ] = $section ;
2010-04-19 06:30:30 +00:00
}
}
2010-06-08 06:21:25 +00:00
return $navigationsections ;
2010-04-19 06:30:30 +00:00
}
/**
* Loads all of the activities for a section into the navigation structure .
*
2011-06-24 16:42:41 +08:00
* @ todo 2.2 - $activities should always be an array and we should no longer check for it being a
* course_modinfo object
*
2010-04-19 06:30:30 +00:00
* @ param navigation_node $sectionnode
* @ param int $sectionnumber
2011-01-26 10:29:16 +00:00
* @ param course_modinfo $modinfo Object returned from { @ see get_fast_modinfo ()}
2010-04-19 06:30:30 +00:00
* @ return array Array of activity nodes
*/
2011-06-24 16:42:41 +08:00
protected function load_section_activities ( navigation_node $sectionnode , $sectionnumber , $activities ) {
2011-10-06 19:32:27 +13:00
// A static counter for JS function naming
static $legacyonclickcounter = 0 ;
2010-04-19 06:30:30 +00:00
2011-06-24 16:42:41 +08:00
if ( $activities instanceof course_modinfo ) {
debugging ( 'global_navigation::load_section_activities argument 3 should now recieve an array of activites. See that method for an example.' , DEBUG_DEVELOPER );
list ( $sections , $activities ) = $this -> generate_sections_and_activities ( $activities -> course );
}
2010-04-19 06:30:30 +00:00
2011-06-24 16:42:41 +08:00
$activitynodes = array ();
foreach ( $activities as $activity ) {
if ( $activity -> section != $sectionnumber ) {
2010-04-19 06:30:30 +00:00
continue ;
}
2011-06-24 16:42:41 +08:00
if ( $activity -> icon ) {
$icon = new pix_icon ( $activity -> icon , get_string ( 'modulename' , $activity -> modname ), $activity -> iconcomponent );
2010-04-19 06:30:30 +00:00
} else {
2011-06-24 16:42:41 +08:00
$icon = new pix_icon ( 'icon' , get_string ( 'modulename' , $activity -> modname ), $activity -> modname );
2010-04-19 06:30:30 +00:00
}
2011-10-06 19:32:27 +13:00
// Prepare the default name and url for the node
$activityname = format_string ( $activity -> name , true , array ( 'context' => get_context_instance ( CONTEXT_MODULE , $activity -> id )));
$action = new moodle_url ( $activity -> url );
// Check if the onclick property is set (puke!)
if ( ! empty ( $activity -> onclick )) {
// Increment the counter so that we have a unique number.
$legacyonclickcounter ++ ;
// Generate the function name we will use
$functionname = 'legacy_activity_onclick_handler_' . $legacyonclickcounter ;
$propogrationhandler = '' ;
// Check if we need to cancel propogation. Remember inline onclick
// events would return false if they wanted to prevent propogation and the
// default action.
if ( strpos ( $activity -> onclick , 'return false' )) {
$propogrationhandler = 'e.halt();' ;
}
// Decode the onclick - it has already been encoded for display (puke)
$onclick = htmlspecialchars_decode ( $activity -> onclick );
// Build the JS function the click event will call
$jscode = " function { $functionname } (e) { $propogrationhandler $onclick } " ;
$this -> page -> requires -> js_init_code ( $jscode );
// Override the default url with the new action link
$action = new action_link ( $action , $activityname , new component_action ( 'click' , $functionname ));
}
$activitynode = $sectionnode -> add ( $activityname , $action , navigation_node :: TYPE_ACTIVITY , null , $activity -> id , $icon );
2011-06-24 16:42:41 +08:00
$activitynode -> title ( get_string ( 'modulename' , $activity -> modname ));
$activitynode -> hidden = $activity -> hidden ;
$activitynode -> display = $activity -> display ;
$activitynode -> nodetype = $activity -> nodetype ;
$activitynodes [ $activity -> id ] = $activitynode ;
2010-04-19 06:30:30 +00:00
}
2011-06-24 16:42:41 +08:00
return $activitynodes ;
2010-04-19 06:30:30 +00:00
}
2010-10-13 18:51:37 +00:00
/**
* Loads a stealth module from unavailable section
* @ param navigation_node $coursenode
* @ param stdClass $modinfo
* @ return navigation_node or null if not accessible
*/
protected function load_stealth_activity ( navigation_node $coursenode , $modinfo ) {
if ( empty ( $modinfo -> cms [ $this -> page -> cm -> id ])) {
return null ;
}
$cm = $modinfo -> cms [ $this -> page -> cm -> id ];
if ( ! $cm -> uservisible ) {
return null ;
}
if ( $cm -> icon ) {
$icon = new pix_icon ( $cm -> icon , get_string ( 'modulename' , $cm -> modname ), $cm -> iconcomponent );
} else {
$icon = new pix_icon ( 'icon' , get_string ( 'modulename' , $cm -> modname ), $cm -> modname );
}
2011-01-26 10:29:16 +00:00
$url = $cm -> get_url ();
2010-10-13 18:51:37 +00:00
$activitynode = $coursenode -> add ( format_string ( $cm -> name ), $url , navigation_node :: TYPE_ACTIVITY , null , $cm -> id , $icon );
$activitynode -> title ( get_string ( 'modulename' , $cm -> modname ));
$activitynode -> hidden = ( ! $cm -> visible );
2011-01-26 10:29:16 +00:00
if ( ! $url ) {
// Don't show activities that don't have links!
2010-10-13 18:51:37 +00:00
$activitynode -> display = false ;
2011-06-24 16:42:41 +08:00
} else if ( self :: module_extends_navigation ( $cm -> modname )) {
2010-10-13 18:51:37 +00:00
$activitynode -> nodetype = navigation_node :: NODETYPE_BRANCH ;
}
return $activitynode ;
}
2010-04-19 06:30:30 +00:00
/**
* Loads the navigation structure for the given activity into the activities node .
*
* This method utilises a callback within the modules lib . php file to load the
* content specific to activity given .
*
* The callback is a method : { modulename } _extend_navigation ()
* Examples :
* * { @ see forum_extend_navigation ()}
* * { @ see workshop_extend_navigation ()}
*
2011-02-07 12:16:13 +08:00
* @ param cm_info | stdClass $cm
2010-04-19 06:30:30 +00:00
* @ param stdClass $course
* @ param navigation_node $activity
* @ return bool
*/
2011-01-26 10:29:16 +00:00
protected function load_activity ( $cm , stdClass $course , navigation_node $activity ) {
2010-04-19 06:30:30 +00:00
global $CFG , $DB ;
2011-02-13 16:17:47 +01:00
2011-02-07 12:16:13 +08:00
// make sure we have a $cm from get_fast_modinfo as this contains activity access details
if ( ! ( $cm instanceof cm_info )) {
$modinfo = get_fast_modinfo ( $course );
$cm = $modinfo -> get_cm ( $cm -> id );
}
2010-04-19 06:30:30 +00:00
$activity -> make_active ();
$file = $CFG -> dirroot . '/mod/' . $cm -> modname . '/lib.php' ;
$function = $cm -> modname . '_extend_navigation' ;
if ( file_exists ( $file )) {
require_once ( $file );
if ( function_exists ( $function )) {
$activtyrecord = $DB -> get_record ( $cm -> modname , array ( 'id' => $cm -> instance ), '*' , MUST_EXIST );
$function ( $activity , $course , $activtyrecord , $cm );
return true ;
}
}
$activity -> nodetype = navigation_node :: NODETYPE_LEAF ;
return false ;
}
/**
2011-11-03 18:48:20 +01:00
* Loads user specific information into the navigation in the appropriate place .
2010-04-19 06:30:30 +00:00
*
* If no user is provided the current user is assumed .
*
* @ param stdClass $user
2011-11-03 18:48:20 +01:00
* @ param bool $forceforcontext probably force something to be loaded somewhere ( ask SamH if not sure what this means )
2010-04-19 06:30:30 +00:00
* @ return bool
2009-12-23 01:22:48 +00:00
*/
2010-05-17 05:38:59 +00:00
protected function load_for_user ( $user = null , $forceforcontext = false ) {
2010-04-19 06:30:30 +00:00
global $DB , $CFG , $USER ;
2010-03-31 07:41:31 +00:00
2009-12-23 01:22:48 +00:00
if ( $user === null ) {
// We can't require login here but if the user isn't logged in we don't
// want to show anything
2010-06-03 08:11:46 +00:00
if ( ! isloggedin () || isguestuser ()) {
2009-12-23 01:22:48 +00:00
return false ;
}
$user = $USER ;
} else if ( ! is_object ( $user )) {
// If the user is not an object then get them from the database
2011-06-24 16:42:41 +08:00
list ( $select , $join ) = context_instance_preload_sql ( 'u.id' , CONTEXT_USER , 'ctx' );
$sql = " SELECT u.* $select FROM { user} u $join WHERE u.id = :userid " ;
$user = $DB -> get_record_sql ( $sql , array ( 'userid' => ( int ) $user ), MUST_EXIST );
context_instance_preload ( $user );
2009-12-23 01:22:48 +00:00
}
2010-08-26 06:23:14 +00:00
$iscurrentuser = ( $user -> id == $USER -> id );
2010-02-18 05:57:20 +00:00
$usercontext = get_context_instance ( CONTEXT_USER , $user -> id );
2009-12-23 01:22:48 +00:00
// Get the course set against the page, by default this will be the site
2010-04-19 06:30:30 +00:00
$course = $this -> page -> course ;
$baseargs = array ( 'id' => $user -> id );
2011-02-13 16:17:47 +01:00
if ( $course -> id != SITEID && ( ! $iscurrentuser || $forceforcontext )) {
2011-06-24 16:42:41 +08:00
$coursenode = $this -> load_course ( $course );
2009-12-23 01:22:48 +00:00
$baseargs [ 'course' ] = $course -> id ;
2010-04-19 06:30:30 +00:00
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id );
2009-12-23 01:22:48 +00:00
$issitecourse = false ;
2009-08-28 08:47:31 +00:00
} else {
2009-12-23 01:22:48 +00:00
// Load all categories and get the context for the system
2010-02-18 05:57:20 +00:00
$coursecontext = get_context_instance ( CONTEXT_SYSTEM );
2009-12-23 01:22:48 +00:00
$issitecourse = true ;
}
// Create a node to add user information under.
2010-05-17 05:38:59 +00:00
if ( $iscurrentuser && ! $forceforcontext ) {
2010-04-19 06:30:30 +00:00
// If it's the current user the information will go under the profile root node
$usernode = $this -> rootnodes [ 'myprofile' ];
2011-07-27 10:16:48 +08:00
$course = get_site ();
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id );
$issitecourse = true ;
2009-12-23 01:22:48 +00:00
} else {
if ( ! $issitecourse ) {
// Not the current user so add it to the participants node for the current course
2010-04-19 06:30:30 +00:00
$usersnode = $coursenode -> get ( 'participants' , navigation_node :: TYPE_CONTAINER );
2010-08-17 02:07:30 +00:00
$userviewurl = new moodle_url ( '/user/view.php' , $baseargs );
2009-12-23 01:22:48 +00:00
} else {
// This is the site so add a users node to the root branch
2010-04-19 06:30:30 +00:00
$usersnode = $this -> rootnodes [ 'users' ];
2011-07-03 10:52:32 +01:00
if ( has_capability ( 'moodle/course:viewparticipants' , $coursecontext )) {
$usersnode -> action = new moodle_url ( '/user/index.php' , array ( 'id' => $course -> id ));
}
2010-08-17 02:07:30 +00:00
$userviewurl = new moodle_url ( '/user/profile.php' , $baseargs );
2009-12-23 01:22:48 +00:00
}
2010-08-27 01:44:25 +00:00
if ( ! $usersnode ) {
// We should NEVER get here, if the course hasn't been populated
// with a participants node then the navigaiton either wasn't generated
// for it (you are missing a require_login or set_context call) or
// you don't have access.... in the interests of no leaking informatin
// we simply quit...
return false ;
}
2009-12-23 01:22:48 +00:00
// Add a branch for the current user
2010-08-17 02:07:30 +00:00
$usernode = $usersnode -> add ( fullname ( $user , true ), $userviewurl , self :: TYPE_USER , null , $user -> id );
2010-04-19 06:30:30 +00:00
2010-07-13 02:35:31 +00:00
if ( $this -> page -> context -> contextlevel == CONTEXT_USER && $user -> id == $this -> page -> context -> instanceid ) {
$usernode -> make_active ();
}
2009-12-23 01:22:48 +00:00
}
// If the user is the current user or has permission to view the details of the requested
// user than add a view profile link.
2010-02-18 05:57:20 +00:00
if ( $iscurrentuser || has_capability ( 'moodle/user:viewdetails' , $coursecontext ) || has_capability ( 'moodle/user:viewdetails' , $usercontext )) {
2010-05-17 05:38:59 +00:00
if ( $issitecourse || ( $iscurrentuser && ! $forceforcontext )) {
2010-05-04 13:04:35 +00:00
$usernode -> add ( get_string ( 'viewprofile' ), new moodle_url ( '/user/profile.php' , $baseargs ));
} else {
$usernode -> add ( get_string ( 'viewprofile' ), new moodle_url ( '/user/view.php' , $baseargs ));
}
2009-12-23 01:22:48 +00:00
}
2011-10-06 14:00:13 +13:00
if ( ! empty ( $CFG -> navadduserpostslinks )) {
// Add nodes for forum posts and discussions if the user can view either or both
// There are no capability checks here as the content of the page is based
// purely on the forums the current user has access too.
$forumtab = $usernode -> add ( get_string ( 'forumposts' , 'forum' ));
$forumtab -> add ( get_string ( 'posts' , 'forum' ), new moodle_url ( '/mod/forum/user.php' , $baseargs ));
$forumtab -> add ( get_string ( 'discussions' , 'forum' ), new moodle_url ( '/mod/forum/user.php' , array_merge ( $baseargs , array ( 'mode' => 'discussions' ))));
}
2009-12-23 01:22:48 +00:00
2010-04-23 04:05:16 +00:00
// Add blog nodes
if ( ! empty ( $CFG -> bloglevel )) {
2011-06-24 16:42:41 +08:00
if ( ! $this -> cache -> cached ( 'userblogoptions' . $user -> id )) {
require_once ( $CFG -> dirroot . '/blog/lib.php' );
// Get all options for the user
$options = blog_get_options_for_user ( $user );
$this -> cache -> set ( 'userblogoptions' . $user -> id , $options );
} else {
$options = $this -> cache -> { 'userblogoptions' . $user -> id };
}
2010-04-23 04:05:16 +00:00
if ( count ( $options ) > 0 ) {
$blogs = $usernode -> add ( get_string ( 'blogs' , 'blog' ), null , navigation_node :: TYPE_CONTAINER );
2011-11-30 11:22:13 +08:00
foreach ( $options as $type => $option ) {
if ( $type == " rss " ) {
$blogs -> add ( $option [ 'string' ], $option [ 'link' ], settings_navigation :: TYPE_SETTING , null , null , new pix_icon ( 'i/rss' , '' ));
} else {
$blogs -> add ( $option [ 'string' ], $option [ 'link' ]);
}
2010-04-23 04:05:16 +00:00
}
}
}
2010-07-13 02:35:31 +00:00
if ( ! empty ( $CFG -> messaging )) {
$messageargs = null ;
if ( $USER -> id != $user -> id ) {
$messageargs = array ( 'id' => $user -> id );
}
$url = new moodle_url ( '/message/index.php' , $messageargs );
$usernode -> add ( get_string ( 'messages' , 'message' ), $url , self :: TYPE_SETTING , null , 'messages' );
2010-06-25 08:20:16 +00:00
}
2011-03-31 14:44:35 +01:00
$context = get_context_instance ( CONTEXT_USER , $USER -> id );
if ( $iscurrentuser && has_capability ( 'moodle/user:manageownfiles' , $context )) {
2010-07-19 13:21:16 +00:00
$url = new moodle_url ( '/user/files.php' );
$usernode -> add ( get_string ( 'myfiles' ), $url , self :: TYPE_SETTING );
2010-07-12 09:39:47 +00:00
}
2009-12-23 01:22:48 +00:00
// Add a node to view the users notes if permitted
2010-02-18 05:57:20 +00:00
if ( ! empty ( $CFG -> enablenotes ) && has_any_capability ( array ( 'moodle/notes:manage' , 'moodle/notes:view' ), $coursecontext )) {
2010-04-19 06:30:30 +00:00
$url = new moodle_url ( '/notes/index.php' , array ( 'user' => $user -> id ));
if ( $coursecontext -> instanceid ) {
$url -> param ( 'course' , $coursecontext -> instanceid );
}
$usernode -> add ( get_string ( 'notes' , 'notes' ), $url );
2009-12-23 01:22:48 +00:00
}
2011-11-03 21:28:22 +01:00
// Add reports node
2011-11-03 18:48:20 +01:00
$reporttab = $usernode -> add ( get_string ( 'activityreports' ));
$reports = get_plugin_list_with_function ( 'report' , 'extend_navigation_user' , 'lib.php' );
foreach ( $reports as $reportfunction ) {
$reportfunction ( $reporttab , $user , $course );
}
2011-11-03 21:28:22 +01:00
$anyreport = has_capability ( 'moodle/user:viewuseractivitiesreport' , $usercontext );
if ( $anyreport || ( $course -> showreports && $iscurrentuser && $forceforcontext )) {
// Add grade hardcoded grade report if necessary
2010-05-04 13:04:35 +00:00
$gradeaccess = false ;
if ( has_capability ( 'moodle/grade:viewall' , $coursecontext )) {
//ok - can view all course grades
2009-12-23 01:22:48 +00:00
$gradeaccess = true ;
2010-05-04 13:04:35 +00:00
} else if ( $course -> showgrades ) {
if ( $iscurrentuser && has_capability ( 'moodle/grade:view' , $coursecontext )) {
//ok - can view own grades
$gradeaccess = true ;
} else if ( has_capability ( 'moodle/grade:viewall' , $usercontext )) {
// ok - can view grades of this user - parent most probably
$gradeaccess = true ;
} else if ( $anyreport ) {
// ok - can view grades of this user - parent most probably
$gradeaccess = true ;
}
}
if ( $gradeaccess ) {
2011-11-03 21:28:22 +01:00
$reporttab -> add ( get_string ( 'grade' ), new moodle_url ( '/course/user.php' , array ( 'mode' => 'grade' , 'id' => $course -> id )));
2009-12-23 01:22:48 +00:00
}
}
2011-11-03 21:28:22 +01:00
// Check the number of nodes in the report node... if there are none remove the node
2011-11-03 18:48:20 +01:00
$reporttab -> trim_if_empty ();
2009-12-23 01:22:48 +00:00
// If the user is the current user add the repositories for the current user
2010-07-30 09:32:51 +00:00
$hiddenfields = array_flip ( explode ( ',' , $CFG -> hiddenuserfields ));
2009-12-23 01:22:48 +00:00
if ( $iscurrentuser ) {
2011-06-24 16:42:41 +08:00
if ( ! $this -> cache -> cached ( 'contexthasrepos' . $usercontext -> id )) {
require_once ( $CFG -> dirroot . '/repository/lib.php' );
$editabletypes = repository :: get_editable_types ( $usercontext );
$haseditabletypes = ! empty ( $editabletypes );
unset ( $editabletypes );
$this -> cache -> set ( 'contexthasrepos' . $usercontext -> id , $haseditabletypes );
} else {
$haseditabletypes = $this -> cache -> { 'contexthasrepos' . $usercontext -> id };
}
if ( $haseditabletypes ) {
2010-03-20 15:02:15 +00:00
$usernode -> add ( get_string ( 'repositories' , 'repository' ), new moodle_url ( '/repository/manage_instances.php' , array ( 'contextid' => $usercontext -> id )));
2009-12-23 01:22:48 +00:00
}
2010-07-30 09:32:51 +00:00
} else if ( $course -> id == SITEID && has_capability ( 'moodle/user:viewdetails' , $usercontext ) && ( ! in_array ( 'mycourses' , $hiddenfields ) || has_capability ( 'moodle/user:viewhiddendetails' , $coursecontext ))) {
// Add view grade report is permitted
$reports = get_plugin_list ( 'gradereport' );
arsort ( $reports ); // user is last, we want to test it first
$userscourses = enrol_get_users_courses ( $user -> id );
$userscoursesnode = $usernode -> add ( get_string ( 'courses' ));
2010-08-02 13:33:19 +00:00
2010-07-30 09:32:51 +00:00
foreach ( $userscourses as $usercourse ) {
$usercoursecontext = get_context_instance ( CONTEXT_COURSE , $usercourse -> id );
2011-09-07 11:46:28 +12:00
$usercourseshortname = format_string ( $usercourse -> shortname , true , array ( 'context' => $usercoursecontext ));
$usercoursenode = $userscoursesnode -> add ( $usercourseshortname , new moodle_url ( '/user/view.php' , array ( 'id' => $user -> id , 'course' => $usercourse -> id )), self :: TYPE_CONTAINER );
2010-07-30 09:32:51 +00:00
$gradeavailable = has_capability ( 'moodle/grade:viewall' , $usercoursecontext );
if ( ! $gradeavailable && ! empty ( $usercourse -> showgrades ) && is_array ( $reports ) && ! empty ( $reports )) {
foreach ( $reports as $plugin => $plugindir ) {
if ( has_capability ( 'gradereport/' . $plugin . ':view' , $usercoursecontext )) {
//stop when the first visible plugin is found
$gradeavailable = true ;
break ;
2010-08-05 02:44:03 +00:00
}
2010-07-30 09:32:51 +00:00
}
}
if ( $gradeavailable ) {
$url = new moodle_url ( '/grade/report/index.php' , array ( 'id' => $usercourse -> id ));
$usercoursenode -> add ( get_string ( 'grades' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/grades' , '' ));
}
// Add a node to view the users notes if permitted
if ( ! empty ( $CFG -> enablenotes ) && has_any_capability ( array ( 'moodle/notes:manage' , 'moodle/notes:view' ), $usercoursecontext )) {
$url = new moodle_url ( '/notes/index.php' , array ( 'user' => $user -> id , 'course' => $usercourse -> id ));
$usercoursenode -> add ( get_string ( 'notes' , 'notes' ), $url , self :: TYPE_SETTING );
}
2011-10-29 09:45:54 +02:00
if ( can_access_course ( $usercourse , $user -> id )) {
2010-07-30 09:32:51 +00:00
$usercoursenode -> add ( get_string ( 'entercourse' ), new moodle_url ( '/course/view.php' , array ( 'id' => $usercourse -> id )), self :: TYPE_SETTING , null , null , new pix_icon ( 'i/course' , '' ));
}
2011-11-03 18:48:20 +01:00
$reporttab = $usercoursenode -> add ( get_string ( 'activityreports' ));
$reports = get_plugin_list_with_function ( 'report' , 'extend_navigation_user' , 'lib.php' );
foreach ( $reports as $reportfunction ) {
$reportfunction ( $reporttab , $user , $usercourse );
}
$reporttab -> trim_if_empty ();
2010-07-30 09:32:51 +00:00
}
2009-12-23 01:22:48 +00:00
}
return true ;
}
/**
2010-04-19 06:30:30 +00:00
* This method simply checks to see if a given module can extend the navigation .
2009-08-28 08:47:31 +00:00
*
2011-06-24 16:42:41 +08:00
* TODO : A shared caching solution should be used to save details on what extends navigation
*
2009-08-28 08:47:31 +00:00
* @ param string $modname
* @ return bool
*/
2011-06-24 16:42:41 +08:00
protected static function module_extends_navigation ( $modname ) {
2009-08-28 08:47:31 +00:00
global $CFG ;
2011-06-24 16:42:41 +08:00
static $extendingmodules = array ();
if ( ! array_key_exists ( $modname , $extendingmodules )) {
$extendingmodules [ $modname ] = false ;
$file = $CFG -> dirroot . '/mod/' . $modname . '/lib.php' ;
if ( file_exists ( $file )) {
$function = $modname . '_extend_navigation' ;
require_once ( $file );
$extendingmodules [ $modname ] = ( function_exists ( $function ));
2009-08-28 08:47:31 +00:00
}
}
2011-06-24 16:42:41 +08:00
return $extendingmodules [ $modname ];
2009-08-28 08:47:31 +00:00
}
/**
2010-04-19 06:30:30 +00:00
* Extends the navigation for the given user .
2010-05-30 22:56:29 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param stdClass $user A user from the database
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function extend_for_user ( $user ) {
$this -> extendforuser [] = $user ;
2010-06-10 07:29:02 +00:00
}
/**
* Returns all of the users the navigation is being extended for
*
* @ return array
*/
public function get_extending_users () {
return $this -> extendforuser ;
2009-08-28 08:47:31 +00:00
}
/**
2010-04-19 06:30:30 +00:00
* Adds the given course to the navigation structure .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param stdClass $course
* @ return navigation_node
2009-08-28 08:47:31 +00:00
*/
2011-06-24 16:42:41 +08:00
public function add_course ( stdClass $course , $forcegeneric = false , $ismycourse = false ) {
2010-05-13 09:57:43 +00:00
global $CFG ;
2011-02-13 16:17:47 +01:00
2011-06-24 16:42:41 +08:00
// We found the course... we can return it now :)
if ( ! $forcegeneric && array_key_exists ( $course -> id , $this -> addedcourses )) {
return $this -> addedcourses [ $course -> id ];
}
2011-09-07 11:46:28 +12:00
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id );
2011-06-24 16:42:41 +08:00
if ( $course -> id != SITEID && ! $course -> visible ) {
if ( is_role_switched ( $course -> id )) {
// user has to be able to access course in order to switch, let's skip the visibility test here
2011-09-07 11:46:28 +12:00
} else if ( ! has_capability ( 'moodle/course:viewhiddencourses' , $coursecontext )) {
2011-06-24 16:42:41 +08:00
return false ;
2011-02-13 16:17:47 +01:00
}
2009-08-28 08:47:31 +00:00
}
2010-05-13 09:57:43 +00:00
$issite = ( $course -> id == SITEID );
2011-06-24 16:42:41 +08:00
$ismycourse = ( $ismycourse && ! $forcegeneric );
2011-09-07 11:46:28 +12:00
$shortname = format_string ( $course -> shortname , true , array ( 'context' => $coursecontext ));
2010-05-13 09:57:43 +00:00
if ( $issite ) {
2010-04-19 06:30:30 +00:00
$parent = $this ;
2010-05-13 09:57:43 +00:00
$url = null ;
2011-07-27 13:22:34 +08:00
if ( empty ( $CFG -> usesitenameforsitepages )) {
$shortname = get_string ( 'sitepages' );
}
2010-05-13 09:57:43 +00:00
} else if ( $ismycourse ) {
2010-04-19 06:30:30 +00:00
$parent = $this -> rootnodes [ 'mycourses' ];
$url = new moodle_url ( '/course/view.php' , array ( 'id' => $course -> id ));
2009-12-23 01:22:48 +00:00
} else {
2010-04-19 06:30:30 +00:00
$parent = $this -> rootnodes [ 'courses' ];
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/course/view.php' , array ( 'id' => $course -> id ));
2009-08-28 08:47:31 +00:00
}
2010-05-13 09:57:43 +00:00
2011-06-27 15:11:28 +08:00
if ( ! $ismycourse && ! $issite && ! empty ( $course -> category )) {
2011-08-29 13:45:04 +12:00
if ( $this -> show_categories ()) {
2011-06-27 15:11:28 +08:00
// We need to load the category structure for this course
$this -> load_all_categories ( $course -> category );
}
if ( array_key_exists ( $course -> category , $this -> addedcategories )) {
$parent = $this -> addedcategories [ $course -> category ];
// This could lead to the course being created so we should check whether it is the case again
if ( ! $forcegeneric && array_key_exists ( $course -> id , $this -> addedcourses )) {
return $this -> addedcourses [ $course -> id ];
}
2010-05-13 09:57:43 +00:00
}
}
2010-06-28 01:50:50 +00:00
$coursenode = $parent -> add ( $shortname , $url , self :: TYPE_COURSE , $shortname , $course -> id );
2010-04-19 06:30:30 +00:00
$coursenode -> nodetype = self :: NODETYPE_BRANCH ;
$coursenode -> hidden = ( ! $course -> visible );
2011-09-06 13:40:44 +12:00
$coursenode -> title ( format_string ( $course -> fullname , true , array ( 'context' => get_context_instance ( CONTEXT_COURSE , $course -> id ))));
2011-06-24 16:42:41 +08:00
if ( ! $forcegeneric ) {
$this -> addedcourses [ $course -> id ] = & $coursenode ;
}
2010-05-13 09:57:43 +00:00
if ( $ismycourse && ! empty ( $CFG -> navshowallcourses )) {
// We need to add this course to the general courses node as well as the
// my courses node, rerun the function with the kill param
$genericcourse = $this -> add_course ( $course , true );
if ( $genericcourse -> isactive ) {
$genericcourse -> make_inactive ();
$genericcourse -> collapse = true ;
if ( $genericcourse -> parent && $genericcourse -> parent -> type == self :: TYPE_CATEGORY ) {
$parent = $genericcourse -> parent ;
while ( $parent && $parent -> type == self :: TYPE_CATEGORY ) {
$parent -> collapse = true ;
$parent = $parent -> parent ;
}
}
}
}
2011-06-24 16:42:41 +08:00
2010-04-19 06:30:30 +00:00
return $coursenode ;
2009-08-28 08:47:31 +00:00
}
/**
2010-04-19 06:30:30 +00:00
* Adds essential course nodes to the navigation for the given course .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* This method adds nodes such as reports , blogs and participants
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param navigation_node $coursenode
* @ param stdClass $course
2009-08-28 08:47:31 +00:00
* @ return bool
*/
2011-07-13 13:39:29 +08:00
public function add_course_essentials ( $coursenode , stdClass $course ) {
2010-04-19 06:30:30 +00:00
global $CFG ;
2009-08-28 08:47:31 +00:00
2010-05-13 09:57:43 +00:00
if ( $course -> id == SITEID ) {
2010-04-19 06:30:30 +00:00
return $this -> add_front_page_course_essentials ( $coursenode , $course );
2009-08-28 08:47:31 +00:00
}
2011-07-13 13:39:29 +08:00
if ( $coursenode == false || ! ( $coursenode instanceof navigation_node ) || $coursenode -> get ( 'participants' , navigation_node :: TYPE_CONTAINER )) {
2010-04-19 06:30:30 +00:00
return true ;
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
//Participants
if ( has_capability ( 'moodle/course:viewparticipants' , $this -> page -> context )) {
$participants = $coursenode -> add ( get_string ( 'participants' ), new moodle_url ( '/user/index.php?id=' . $course -> id ), self :: TYPE_CONTAINER , get_string ( 'participants' ), 'participants' );
$currentgroup = groups_get_course_group ( $course , true );
if ( $course -> id == SITEID ) {
$filterselect = '' ;
} else if ( $course -> id && ! $currentgroup ) {
$filterselect = $course -> id ;
} else {
$filterselect = $currentgroup ;
}
$filterselect = clean_param ( $filterselect , PARAM_INT );
2011-03-20 13:34:51 +01:00
if (( $CFG -> bloglevel == BLOG_GLOBAL_LEVEL or ( $CFG -> bloglevel == BLOG_SITE_LEVEL and ( isloggedin () and ! isguestuser ())))
and has_capability ( 'moodle/blog:view' , get_context_instance ( CONTEXT_SYSTEM ))) {
2010-04-19 06:30:30 +00:00
$blogsurls = new moodle_url ( '/blog/index.php' , array ( 'courseid' => $filterselect ));
$participants -> add ( get_string ( 'blogs' , 'blog' ), $blogsurls -> out ());
}
if ( ! empty ( $CFG -> enablenotes ) && ( has_capability ( 'moodle/notes:manage' , $this -> page -> context ) || has_capability ( 'moodle/notes:view' , $this -> page -> context ))) {
$participants -> add ( get_string ( 'notes' , 'notes' ), new moodle_url ( '/notes/index.php' , array ( 'filtertype' => 'course' , 'filterselect' => $filterselect )));
}
2010-05-25 03:34:08 +00:00
} else if ( count ( $this -> extendforuser ) > 0 || $this -> page -> course -> id == $course -> id ) {
2010-04-19 06:30:30 +00:00
$participants = $coursenode -> add ( get_string ( 'participants' ), null , self :: TYPE_CONTAINER , get_string ( 'participants' ), 'participants' );
}
// View course reports
if ( has_capability ( 'moodle/site:viewreports' , $this -> page -> context )) { // basic capability for listing of reports
2011-11-02 09:53:49 +01:00
$reportnav = $coursenode -> add ( get_string ( 'reports' ), null , self :: TYPE_CONTAINER , null , null , new pix_icon ( 'i/stats' , '' ));
$coursereports = get_plugin_list ( 'coursereport' ); // deprecated
2010-04-19 06:30:30 +00:00
foreach ( $coursereports as $report => $dir ) {
$libfile = $CFG -> dirroot . '/course/report/' . $report . '/lib.php' ;
if ( file_exists ( $libfile )) {
require_once ( $libfile );
$reportfunction = $report . '_report_extend_navigation' ;
if ( function_exists ( $report . '_report_extend_navigation' )) {
$reportfunction ( $reportnav , $course , $this -> page -> context );
2009-08-28 08:47:31 +00:00
}
}
}
2011-11-02 09:53:49 +01:00
$reports = get_plugin_list_with_function ( 'report' , 'extend_navigation_course' , 'lib.php' );
foreach ( $reports as $reportfunction ) {
$reportfunction ( $reportnav , $course , $this -> page -> context );
}
2009-08-28 08:47:31 +00:00
}
return true ;
}
2010-08-05 02:44:03 +00:00
/**
* This generates the the structure of the course that won ' t be generated when
* the modules and sections are added .
*
* Things such as the reports branch , the participants branch , blogs ... get
* added to the course node by this method .
*
* @ param navigation_node $coursenode
* @ param stdClass $course
* @ return bool True for successfull generation
*/
2010-04-19 06:30:30 +00:00
public function add_front_page_course_essentials ( navigation_node $coursenode , stdClass $course ) {
global $CFG ;
2009-08-28 08:47:31 +00:00
2010-09-10 03:13:45 +00:00
if ( $coursenode == false || $coursenode -> get ( 'frontpageloaded' , navigation_node :: TYPE_CUSTOM )) {
2010-04-19 06:30:30 +00:00
return true ;
2009-12-23 01:22:48 +00:00
}
2010-09-10 03:13:45 +00:00
// Hidden node that we use to determine if the front page navigation is loaded.
// This required as there are not other guaranteed nodes that may be loaded.
$coursenode -> add ( 'frontpageloaded' , null , self :: TYPE_CUSTOM , null , 'frontpageloaded' ) -> display = false ;
2010-04-19 06:30:30 +00:00
//Participants
2010-10-06 06:50:36 +00:00
if ( has_capability ( 'moodle/course:viewparticipants' , get_system_context ())) {
2010-04-19 06:30:30 +00:00
$coursenode -> add ( get_string ( 'participants' ), new moodle_url ( '/user/index.php?id=' . $course -> id ), self :: TYPE_CUSTOM , get_string ( 'participants' ), 'participants' );
}
2010-05-30 22:56:29 +00:00
2010-10-05 02:38:40 +00:00
$filterselect = 0 ;
2010-05-01 14:33:07 +00:00
// Blogs
2011-03-20 13:34:51 +01:00
if ( ! empty ( $CFG -> bloglevel )
and ( $CFG -> bloglevel == BLOG_GLOBAL_LEVEL or ( $CFG -> bloglevel == BLOG_SITE_LEVEL and ( isloggedin () and ! isguestuser ())))
and has_capability ( 'moodle/blog:view' , get_context_instance ( CONTEXT_SYSTEM ))) {
$blogsurls = new moodle_url ( '/blog/index.php' , array ( 'courseid' => $filterselect ));
$coursenode -> add ( get_string ( 'blogs' , 'blog' ), $blogsurls -> out ());
2009-08-28 08:47:31 +00:00
}
2010-05-01 14:33:07 +00:00
// Notes
2010-04-19 06:30:30 +00:00
if ( ! empty ( $CFG -> enablenotes ) && ( has_capability ( 'moodle/notes:manage' , $this -> page -> context ) || has_capability ( 'moodle/notes:view' , $this -> page -> context ))) {
$coursenode -> add ( get_string ( 'notes' , 'notes' ), new moodle_url ( '/notes/index.php' , array ( 'filtertype' => 'course' , 'filterselect' => $filterselect )));
}
2010-05-01 14:33:07 +00:00
// Tags
if ( ! empty ( $CFG -> usetags ) && isloggedin ()) {
2010-04-19 06:30:30 +00:00
$coursenode -> add ( get_string ( 'tags' , 'tag' ), new moodle_url ( '/tag/search.php' ));
2009-08-28 08:47:31 +00:00
}
2009-10-14 09:08:43 +00:00
2011-10-06 12:13:13 +13:00
if ( isloggedin ()) {
// Calendar
$calendarurl = new moodle_url ( '/calendar/view.php' , array ( 'view' => 'month' ));
$coursenode -> add ( get_string ( 'calendar' , 'calendar' ), $calendarurl , self :: TYPE_CUSTOM , null , 'calendar' );
}
2009-10-14 09:08:43 +00:00
2010-04-19 06:30:30 +00:00
// View course reports
if ( has_capability ( 'moodle/site:viewreports' , $this -> page -> context )) { // basic capability for listing of reports
2011-11-02 09:53:49 +01:00
$reportnav = $coursenode -> add ( get_string ( 'reports' ), null , self :: TYPE_CONTAINER , null , null , new pix_icon ( 'i/stats' , '' ));
$coursereports = get_plugin_list ( 'coursereport' ); // deprecated
2010-04-19 06:30:30 +00:00
foreach ( $coursereports as $report => $dir ) {
$libfile = $CFG -> dirroot . '/course/report/' . $report . '/lib.php' ;
if ( file_exists ( $libfile )) {
require_once ( $libfile );
$reportfunction = $report . '_report_extend_navigation' ;
if ( function_exists ( $report . '_report_extend_navigation' )) {
$reportfunction ( $reportnav , $course , $this -> page -> context );
}
2009-10-14 09:08:43 +00:00
}
}
2011-11-02 09:53:49 +01:00
$reports = get_plugin_list_with_function ( 'report' , 'extend_navigation_course' , 'lib.php' );
foreach ( $reports as $reportfunction ) {
$reportfunction ( $reportnav , $course , $this -> page -> context );
}
2009-10-14 09:08:43 +00:00
}
2010-04-19 06:30:30 +00:00
return true ;
2009-10-14 09:08:43 +00:00
}
2009-11-04 07:23:19 +00:00
2010-04-19 06:30:30 +00:00
/**
* Clears the navigation cache
*/
public function clear_cache () {
$this -> cache -> clear ();
2009-11-04 07:23:19 +00:00
}
2010-04-21 09:44:16 +00:00
2010-08-05 02:44:03 +00:00
/**
* Sets an expansion limit for the navigation
*
* The expansion limit is used to prevent the display of content that has a type
* greater than the provided $type .
*
* Can be used to ensure things such as activities or activity content don ' t get
* shown on the navigation .
* They are still generated in order to ensure the navbar still makes sense .
*
* @ param int $type One of navigation_node :: TYPE_ *
* @ return < type >
*/
2010-04-21 09:44:16 +00:00
public function set_expansion_limit ( $type ) {
$nodes = $this -> find_all_of_type ( $type );
foreach ( $nodes as & $node ) {
2010-07-01 03:33:16 +00:00
// We need to generate the full site node
if ( $type == self :: TYPE_COURSE && $node -> key == SITEID ) {
continue ;
}
2010-04-21 09:44:16 +00:00
foreach ( $node -> children as & $child ) {
2010-07-01 03:33:16 +00:00
// We still want to show course reports and participants containers
// or there will be navigation missing.
if ( $type == self :: TYPE_COURSE && $child -> type === self :: TYPE_CONTAINER ) {
continue ;
}
2010-04-21 09:44:16 +00:00
$child -> display = false ;
}
}
return true ;
}
2010-08-05 02:44:03 +00:00
/**
* Attempts to get the navigation with the given key from this nodes children .
*
* This function only looks at this nodes children , it does NOT look recursivily .
* If the node can ' t be found then false is returned .
*
* If you need to search recursivily then use the { @ see find ()} method .
*
* Note : If you are trying to set the active node { @ see navigation_node :: override_active_url ()}
* may be of more use to you .
*
* @ param string | int $key The key of the node you wish to receive .
* @ param int $type One of navigation_node :: TYPE_ *
* @ return navigation_node | false
*/
2010-06-10 07:47:59 +00:00
public function get ( $key , $type = null ) {
2010-06-11 04:25:22 +00:00
if ( ! $this -> initialised ) {
$this -> initialise ();
}
2010-06-10 07:55:38 +00:00
return parent :: get ( $key , $type );
2010-06-10 07:47:59 +00:00
}
2010-08-05 02:44:03 +00:00
/**
* Searches this nodes children and thier children to find a navigation node
* with the matching key and type .
*
* This method is recursive and searches children so until either a node is
* found of there are no more nodes to search .
*
* If you know that the node being searched for is a child of this node
* then use the { @ see get ()} method instead .
*
* Note : If you are trying to set the active node { @ see navigation_node :: override_active_url ()}
* may be of more use to you .
*
* @ param string | int $key The key of the node you wish to receive .
* @ param int $type One of navigation_node :: TYPE_ *
* @ return navigation_node | false
*/
2010-06-10 07:47:59 +00:00
public function find ( $key , $type ) {
2010-06-11 04:25:22 +00:00
if ( ! $this -> initialised ) {
$this -> initialise ();
}
2010-06-10 07:55:38 +00:00
return parent :: find ( $key , $type );
2010-06-10 07:47:59 +00:00
}
2009-08-28 08:47:31 +00:00
}
/**
* The limited global navigation class used for the AJAX extension of the global
* navigation class .
*
* The primary methods that are used in the global navigation class have been overriden
* to ensure that only the relevant branch is generated at the root of the tree .
* This can be done because AJAX is only used when the backwards structure for the
* requested branch exists .
* This has been done only because it shortens the amounts of information that is generated
* which of course will speed up the response time .. because no one likes laggy AJAX .
*
* @ package moodlecore
2009-10-19 03:29:48 +00:00
* @ subpackage navigation
2009-08-28 08:47:31 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2010-02-18 05:57:20 +00:00
class global_navigation_for_ajax extends global_navigation {
2010-04-19 06:30:30 +00:00
2010-08-27 02:09:07 +00:00
protected $branchtype ;
protected $instanceid ;
2010-04-19 06:30:30 +00:00
/** @var array */
protected $expandable = array ();
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Constructs the navigation for use in AJAX request
*/
2010-06-11 04:25:22 +00:00
public function __construct ( $page , $branchtype , $id ) {
2010-05-13 09:57:43 +00:00
$this -> page = $page ;
2010-04-19 06:30:30 +00:00
$this -> cache = new navigation_cache ( NAVIGATION_CACHE_NAME );
$this -> children = new navigation_node_collection ();
2010-08-27 02:09:07 +00:00
$this -> branchtype = $branchtype ;
$this -> instanceid = $id ;
$this -> initialise ();
2010-04-19 06:30:30 +00:00
}
/**
* Initialise the navigation given the type and id for the branch to expand .
2009-08-28 08:47:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return array The expandable nodes
2009-08-28 08:47:31 +00:00
*/
2010-08-27 02:09:07 +00:00
public function initialise () {
global $CFG , $DB , $SITE ;
2010-02-18 05:57:20 +00:00
2009-08-28 08:47:31 +00:00
if ( $this -> initialised || during_initial_install ()) {
2009-09-10 02:19:12 +00:00
return $this -> expandable ;
2009-08-28 08:47:31 +00:00
}
2010-06-11 04:25:22 +00:00
$this -> initialised = true ;
$this -> rootnodes = array ();
2011-06-24 16:42:41 +08:00
$this -> rootnodes [ 'site' ] = $this -> add_course ( $SITE );
2010-06-11 04:25:22 +00:00
$this -> rootnodes [ 'courses' ] = $this -> add ( get_string ( 'courses' ), null , self :: TYPE_ROOTNODE , null , 'courses' );
2010-02-18 05:57:20 +00:00
// Branchtype will be one of navigation_node::TYPE_*
2010-08-27 02:09:07 +00:00
switch ( $this -> branchtype ) {
2010-05-13 09:57:43 +00:00
case self :: TYPE_CATEGORY :
2010-08-27 02:09:07 +00:00
$this -> load_all_categories ( $this -> instanceid );
2010-05-13 09:57:43 +00:00
$limit = 20 ;
if ( ! empty ( $CFG -> navcourselimit )) {
$limit = ( int ) $CFG -> navcourselimit ;
}
2010-08-27 02:09:07 +00:00
$courses = $DB -> get_records ( 'course' , array ( 'category' => $this -> instanceid ), 'sortorder' , '*' , 0 , $limit );
2010-05-13 09:57:43 +00:00
foreach ( $courses as $course ) {
$this -> add_course ( $course );
}
break ;
2010-02-18 05:57:20 +00:00
case self :: TYPE_COURSE :
2010-08-27 02:09:07 +00:00
$course = $DB -> get_record ( 'course' , array ( 'id' => $this -> instanceid ), '*' , MUST_EXIST );
2010-02-18 05:57:20 +00:00
require_course_login ( $course );
2010-05-17 05:38:59 +00:00
$this -> page -> set_context ( get_context_instance ( CONTEXT_COURSE , $course -> id ));
2010-04-19 06:30:30 +00:00
$coursenode = $this -> add_course ( $course );
$this -> add_course_essentials ( $coursenode , $course );
if ( $this -> format_display_course_content ( $course -> format )) {
$this -> load_course_sections ( $course , $coursenode );
}
2009-08-28 08:47:31 +00:00
break ;
2010-02-18 05:57:20 +00:00
case self :: TYPE_SECTION :
2010-04-19 06:30:30 +00:00
$sql = ' SELECT c .* , cs . section AS sectionnumber
2010-02-18 05:57:20 +00:00
FROM { course } c
LEFT JOIN { course_sections } cs ON cs . course = c . id
WHERE cs . id = ? ' ;
2010-08-27 02:09:07 +00:00
$course = $DB -> get_record_sql ( $sql , array ( $this -> instanceid ), MUST_EXIST );
2010-02-18 05:57:20 +00:00
require_course_login ( $course );
2010-05-17 05:38:59 +00:00
$this -> page -> set_context ( get_context_instance ( CONTEXT_COURSE , $course -> id ));
2010-04-19 06:30:30 +00:00
$coursenode = $this -> add_course ( $course );
$this -> add_course_essentials ( $coursenode , $course );
$sections = $this -> load_course_sections ( $course , $coursenode );
2011-06-24 16:42:41 +08:00
list ( $sectionarray , $activities ) = $this -> generate_sections_and_activities ( $course );
$this -> load_section_activities ( $sections [ $course -> sectionnumber ] -> sectionnode , $course -> sectionnumber , $activities );
2009-08-28 08:47:31 +00:00
break ;
2010-02-18 05:57:20 +00:00
case self :: TYPE_ACTIVITY :
2011-03-21 10:22:28 +08:00
$sql = " SELECT c.*
FROM { course } c
JOIN { course_modules } cm ON cm . course = c . id
WHERE cm . id = : cmid " ;
$params = array ( 'cmid' => $this -> instanceid );
$course = $DB -> get_record_sql ( $sql , $params , MUST_EXIST );
2011-02-07 12:16:13 +08:00
$modinfo = get_fast_modinfo ( $course );
$cm = $modinfo -> get_cm ( $this -> instanceid );
2010-02-18 05:57:20 +00:00
require_course_login ( $course , true , $cm );
2010-05-17 05:38:59 +00:00
$this -> page -> set_context ( get_context_instance ( CONTEXT_MODULE , $cm -> id ));
2010-04-19 06:30:30 +00:00
$coursenode = $this -> load_course ( $course );
2010-05-20 06:01:00 +00:00
if ( $course -> id == SITEID ) {
$modulenode = $this -> load_activity ( $cm , $course , $coursenode -> find ( $cm -> id , self :: TYPE_ACTIVITY ));
} else {
2011-03-21 10:22:28 +08:00
$sections = $this -> load_course_sections ( $course , $coursenode );
2011-06-24 16:42:41 +08:00
list ( $sectionarray , $activities ) = $this -> generate_sections_and_activities ( $course );
$activities = $this -> load_section_activities ( $sections [ $cm -> sectionnum ] -> sectionnode , $cm -> sectionnum , $activities );
2010-05-20 06:01:00 +00:00
$modulenode = $this -> load_activity ( $cm , $course , $activities [ $cm -> id ]);
}
2009-08-28 08:47:31 +00:00
break ;
2010-02-18 05:57:20 +00:00
default :
2010-04-19 06:30:30 +00:00
throw new Exception ( 'Unknown type' );
2010-02-18 05:57:20 +00:00
return $this -> expandable ;
2009-08-28 08:47:31 +00:00
}
2010-07-28 05:34:09 +00:00
if ( $this -> page -> context -> contextlevel == CONTEXT_COURSE && $this -> page -> context -> instanceid != SITEID ) {
$this -> load_for_user ( null , true );
}
2010-02-18 05:57:20 +00:00
$this -> find_expandable ( $this -> expandable );
return $this -> expandable ;
2010-06-11 04:25:22 +00:00
}
2010-08-05 02:44:03 +00:00
/**
* Returns an array of expandable nodes
* @ return array
*/
2010-06-11 04:25:22 +00:00
public function get_expandable () {
return $this -> expandable ;
2009-08-28 08:47:31 +00:00
}
}
/**
* Navbar class
*
* This class is used to manage the navbar , which is initialised from the navigation
* object held by PAGE
*
* @ package moodlecore
2009-10-19 03:29:48 +00:00
* @ subpackage navigation
2009-08-28 08:47:31 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
class navbar extends navigation_node {
/** @var bool */
protected $initialised = false ;
/** @var mixed */
protected $keys = array ();
/** @var null|string */
protected $content = null ;
2010-04-19 06:30:30 +00:00
/** @var moodle_page object */
2009-08-28 08:47:31 +00:00
protected $page ;
/** @var bool */
2009-09-08 08:43:44 +00:00
protected $ignoreactive = false ;
/** @var bool */
2009-08-28 08:47:31 +00:00
protected $duringinstall = false ;
2009-12-23 01:22:48 +00:00
/** @var bool */
protected $hasitems = false ;
2010-04-19 06:30:30 +00:00
/** @var array */
protected $items ;
/** @var array */
public $children = array ();
2010-05-05 03:27:22 +00:00
/** @var bool */
public $includesettingsbase = false ;
2009-08-28 08:47:31 +00:00
/**
* The almighty constructor
2010-04-19 06:30:30 +00:00
*
* @ param moodle_page $page
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function __construct ( moodle_page $page ) {
2010-02-18 05:57:20 +00:00
global $CFG ;
2009-08-28 08:47:31 +00:00
if ( during_initial_install ()) {
$this -> duringinstall = true ;
return false ;
}
$this -> page = $page ;
$this -> text = get_string ( 'home' );
$this -> shorttext = get_string ( 'home' );
$this -> action = new moodle_url ( $CFG -> wwwroot );
$this -> nodetype = self :: NODETYPE_BRANCH ;
$this -> type = self :: TYPE_SYSTEM ;
}
/**
* Quick check to see if the navbar will have items in .
*
* @ return bool Returns true if the navbar will have items , false otherwise
*/
public function has_items () {
if ( $this -> duringinstall ) {
return false ;
2009-12-23 01:22:48 +00:00
} else if ( $this -> hasitems !== false ) {
return true ;
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
$this -> page -> navigation -> initialise ( $this -> page );
2009-09-23 06:05:36 +00:00
2009-12-23 01:22:48 +00:00
$activenodefound = ( $this -> page -> navigation -> contains_active_node () ||
2010-04-19 06:30:30 +00:00
$this -> page -> settingsnav -> contains_active_node ());
2009-09-23 06:05:36 +00:00
2010-04-19 06:30:30 +00:00
$outcome = ( count ( $this -> children ) > 0 || ( ! $this -> ignoreactive && $activenodefound ));
2009-12-23 01:22:48 +00:00
$this -> hasitems = $outcome ;
2009-09-23 06:05:36 +00:00
return $outcome ;
2009-09-08 08:43:44 +00:00
}
2010-04-19 06:30:30 +00:00
/**
* Turn on / off ignore active
*
* @ param bool $setting
*/
2009-09-08 08:43:44 +00:00
public function ignore_active ( $setting = true ) {
$this -> ignoreactive = ( $setting );
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
public function get ( $key , $type = null ) {
foreach ( $this -> children as & $child ) {
if ( $child -> key === $key && ( $type == null || $type == $child -> type )) {
return $child ;
}
}
return false ;
}
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Returns an array of navigation_node ' s that make up the navbar .
2010-05-30 22:56:29 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return array
2009-08-28 08:47:31 +00:00
*/
2010-04-19 06:30:30 +00:00
public function get_items () {
$items = array ();
2009-08-28 08:47:31 +00:00
// Make sure that navigation is initialised
2009-12-23 01:22:48 +00:00
if ( ! $this -> has_items ()) {
2010-04-19 06:30:30 +00:00
return $items ;
2009-12-23 01:22:48 +00:00
}
2010-04-19 06:30:30 +00:00
if ( $this -> items !== null ) {
return $this -> items ;
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
if ( count ( $this -> children ) > 0 ) {
// Add the custom children
$items = array_reverse ( $this -> children );
}
2009-11-01 11:31:16 +00:00
2010-04-19 06:30:30 +00:00
$navigationactivenode = $this -> page -> navigation -> find_active_node ();
$settingsactivenode = $this -> page -> settingsnav -> find_active_node ();
2010-03-22 03:04:00 +00:00
2009-08-28 08:47:31 +00:00
// Check if navigation contains the active node
2010-03-22 03:04:00 +00:00
if ( ! $this -> ignoreactive ) {
2010-05-30 22:56:29 +00:00
2010-04-19 06:30:30 +00:00
if ( $navigationactivenode && $settingsactivenode ) {
2010-03-22 03:04:00 +00:00
// Parse a combined navigation tree
2010-04-19 06:30:30 +00:00
while ( $settingsactivenode && $settingsactivenode -> parent !== null ) {
if ( ! $settingsactivenode -> mainnavonly ) {
$items [] = $settingsactivenode ;
}
$settingsactivenode = $settingsactivenode -> parent ;
}
2010-05-05 03:27:22 +00:00
if ( ! $this -> includesettingsbase ) {
// Removes the first node from the settings (root node) from the list
array_pop ( $items );
}
2010-04-19 06:30:30 +00:00
while ( $navigationactivenode && $navigationactivenode -> parent !== null ) {
if ( ! $navigationactivenode -> mainnavonly ) {
$items [] = $navigationactivenode ;
}
$navigationactivenode = $navigationactivenode -> parent ;
2010-03-22 03:04:00 +00:00
}
2010-04-19 06:30:30 +00:00
} else if ( $navigationactivenode ) {
2010-03-22 03:04:00 +00:00
// Parse the navigation tree to get the active node
2010-04-19 06:30:30 +00:00
while ( $navigationactivenode && $navigationactivenode -> parent !== null ) {
if ( ! $navigationactivenode -> mainnavonly ) {
$items [] = $navigationactivenode ;
}
$navigationactivenode = $navigationactivenode -> parent ;
}
} else if ( $settingsactivenode ) {
2010-03-22 03:04:00 +00:00
// Parse the settings navigation to get the active node
2010-04-19 06:30:30 +00:00
while ( $settingsactivenode && $settingsactivenode -> parent !== null ) {
if ( ! $settingsactivenode -> mainnavonly ) {
$items [] = $settingsactivenode ;
}
$settingsactivenode = $settingsactivenode -> parent ;
}
2010-03-22 03:04:00 +00:00
}
2009-08-28 08:47:31 +00:00
}
2010-02-18 06:42:29 +00:00
2010-04-19 06:30:30 +00:00
$items [] = new navigation_node ( array (
'text' => $this -> page -> navigation -> text ,
'shorttext' => $this -> page -> navigation -> shorttext ,
'key' => $this -> page -> navigation -> key ,
'action' => $this -> page -> navigation -> action
));
2010-02-18 06:42:29 +00:00
2010-04-19 06:30:30 +00:00
$this -> items = array_reverse ( $items );
return $this -> items ;
2009-08-28 08:47:31 +00:00
}
2010-02-18 05:57:20 +00:00
2009-08-28 08:47:31 +00:00
/**
2010-04-19 06:30:30 +00:00
* Add a new navigation_node to the navbar , overrides parent :: add
2009-08-28 08:47:31 +00:00
*
* This function overrides { @ link navigation_node :: add ()} so that we can change
* the way nodes get added to allow us to simply call add and have the node added to the
* end of the navbar
*
* @ param string $text
* @ param string | moodle_url $action
2009-09-04 08:43:49 +00:00
* @ param int $type
* @ param string | int $key
* @ param string $shorttext
2009-08-28 08:47:31 +00:00
* @ param string $icon
2010-04-19 06:30:30 +00:00
* @ return navigation_node
2009-08-28 08:47:31 +00:00
*/
2010-02-14 09:29:44 +00:00
public function add ( $text , $action = null , $type = self :: TYPE_CUSTOM , $shorttext = null , $key = null , pix_icon $icon = null ) {
2010-04-19 06:30:30 +00:00
if ( $this -> content !== null ) {
debugging ( 'Nav bar items must be printed before $OUTPUT->header() has been called' , DEBUG_DEVELOPER );
}
2010-05-30 22:56:29 +00:00
2010-04-19 06:30:30 +00:00
// Properties array used when creating the new navigation node
$itemarray = array (
'text' => $text ,
'type' => $type
);
// Set the action if one was provided
if ( $action !== null ) {
$itemarray [ 'action' ] = $action ;
}
// Set the shorttext if one was provided
if ( $shorttext !== null ) {
$itemarray [ 'shorttext' ] = $shorttext ;
}
// Set the icon if one was provided
if ( $icon !== null ) {
$itemarray [ 'icon' ] = $icon ;
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
// Default the key to the number of children if not provided
if ( $key === null ) {
$key = count ( $this -> children );
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
// Set the key
$itemarray [ 'key' ] = $key ;
// Set the parent to this node
$itemarray [ 'parent' ] = $this ;
// Add the child using the navigation_node_collections add method
$this -> children [] = new navigation_node ( $itemarray );
return $this ;
2009-08-28 08:47:31 +00:00
}
}
/**
* Class used to manage the settings option for the current page
*
* This class is used to manage the settings options in a tree format ( recursively )
* and was created initially for use with the settings blocks .
*
* @ package moodlecore
2009-10-19 03:29:48 +00:00
* @ subpackage navigation
2009-08-28 08:47:31 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
class settings_navigation extends navigation_node {
/** @var stdClass */
protected $context ;
2010-04-19 06:30:30 +00:00
/** @var moodle_page */
2009-08-28 08:47:31 +00:00
protected $page ;
2010-04-19 06:30:30 +00:00
/** @var string */
2010-02-22 07:57:35 +00:00
protected $adminsection ;
2010-05-13 09:57:43 +00:00
/** @var bool */
protected $initialised = false ;
2010-05-17 05:38:59 +00:00
/** @var array */
protected $userstoextendfor = array ();
2011-06-24 16:42:41 +08:00
/** @var navigation_cache **/
protected $cache ;
2010-05-13 09:57:43 +00:00
2009-08-28 08:47:31 +00:00
/**
* Sets up the object with basic settings and preparse it for use
2010-05-30 22:56:29 +00:00
*
2010-04-19 06:30:30 +00:00
* @ param moodle_page $page
2009-08-28 08:47:31 +00:00
*/
2010-02-18 05:57:20 +00:00
public function __construct ( moodle_page & $page ) {
2009-08-28 08:47:31 +00:00
if ( during_initial_install ()) {
return false ;
}
$this -> page = $page ;
// Initialise the main navigation. It is most important that this is done
// before we try anything
$this -> page -> navigation -> initialise ();
// Initialise the navigation cache
2009-10-12 05:39:32 +00:00
$this -> cache = new navigation_cache ( NAVIGATION_CACHE_NAME );
2010-04-19 06:30:30 +00:00
$this -> children = new navigation_node_collection ();
2009-08-28 08:47:31 +00:00
}
/**
* Initialise the settings navigation based on the current context
*
* This function initialises the settings navigation tree for a given context
* by calling supporting functions to generate major parts of the tree .
2010-04-19 06:30:30 +00:00
*
2009-08-28 08:47:31 +00:00
*/
public function initialise () {
2011-01-27 15:54:11 +08:00
global $DB , $SESSION ;
2010-03-31 07:41:31 +00:00
2009-08-28 08:47:31 +00:00
if ( during_initial_install ()) {
return false ;
2010-05-13 09:57:43 +00:00
} else if ( $this -> initialised ) {
return true ;
2009-08-28 08:47:31 +00:00
}
$this -> id = 'settingsnav' ;
$this -> context = $this -> page -> context ;
2010-03-22 03:04:00 +00:00
$context = $this -> context ;
if ( $context -> contextlevel == CONTEXT_BLOCK ) {
$this -> load_block_settings ();
2011-10-14 12:48:00 +02:00
$context = $context -> get_parent_context ();
2010-03-22 03:04:00 +00:00
}
switch ( $context -> contextlevel ) {
2009-08-28 08:47:31 +00:00
case CONTEXT_SYSTEM :
2010-03-22 03:04:00 +00:00
if ( $this -> page -> url -> compare ( new moodle_url ( '/admin/settings.php' , array ( 'section' => 'frontpagesettings' )))) {
$this -> load_front_page_settings (( $context -> id == $this -> context -> id ));
}
2009-08-28 08:47:31 +00:00
break ;
case CONTEXT_COURSECAT :
2010-03-22 03:04:00 +00:00
$this -> load_category_settings ();
2009-08-28 08:47:31 +00:00
break ;
case CONTEXT_COURSE :
2010-03-22 03:04:00 +00:00
if ( $this -> page -> course -> id != SITEID ) {
$this -> load_course_settings (( $context -> id == $this -> context -> id ));
2009-08-28 08:47:31 +00:00
} else {
2010-03-22 03:04:00 +00:00
$this -> load_front_page_settings (( $context -> id == $this -> context -> id ));
2009-08-28 08:47:31 +00:00
}
break ;
case CONTEXT_MODULE :
2010-03-22 03:04:00 +00:00
$this -> load_module_settings ();
$this -> load_course_settings ();
2009-08-28 08:47:31 +00:00
break ;
case CONTEXT_USER :
2010-03-22 03:04:00 +00:00
if ( $this -> page -> course -> id != SITEID ) {
$this -> load_course_settings ();
2009-08-28 08:47:31 +00:00
}
break ;
}
2010-04-19 06:30:30 +00:00
$settings = $this -> load_user_settings ( $this -> page -> course -> id );
2011-01-27 15:54:11 +08:00
if ( isloggedin () && ! isguestuser () && ( ! property_exists ( $SESSION , 'load_navigation_admin' ) || $SESSION -> load_navigation_admin )) {
$admin = $this -> load_administration_settings ();
$SESSION -> load_navigation_admin = ( $admin -> has_children ());
} else {
$admin = false ;
}
2010-03-22 03:04:00 +00:00
2010-04-19 06:30:30 +00:00
if ( $context -> contextlevel == CONTEXT_SYSTEM && $admin ) {
$admin -> force_open ();
} else if ( $context -> contextlevel == CONTEXT_USER && $settings ) {
$settings -> force_open ();
2010-03-22 03:04:00 +00:00
}
2009-08-28 08:47:31 +00:00
// Check if the user is currently logged in as another user
if ( session_is_loggedinas ()) {
// Get the actual user, we need this so we can display an informative return link
$realuser = session_get_realuser ();
// Add the informative return to original user link
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/course/loginas.php' , array ( 'id' => $this -> page -> course -> id , 'return' => 1 , 'sesskey' => sesskey ()));
2010-02-14 09:29:44 +00:00
$this -> add ( get_string ( 'returntooriginaluser' , 'moodle' , fullname ( $realuser , true )), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 't/left' , '' ));
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
foreach ( $this -> children as $key => $node ) {
if ( $node -> nodetype != self :: NODETYPE_BRANCH || $node -> children -> count () === 0 ) {
$node -> remove ();
}
}
2010-05-13 09:57:43 +00:00
$this -> initialised = true ;
2009-08-28 08:47:31 +00:00
}
/**
* Override the parent function so that we can add preceeding hr ' s and set a
* root node class against all first level element
*
* It does this by first calling the parent ' s add method { @ link navigation_node :: add ()}
2009-11-01 11:31:16 +00:00
* and then proceeds to use the key to set class and hr
2009-08-28 08:47:31 +00:00
*
* @ param string $text
2009-09-04 03:12:01 +00:00
* @ param sting | moodle_url $url
2009-08-28 08:47:31 +00:00
* @ param string $shorttext
* @ param string | int $key
* @ param int $type
* @ param string $icon
2010-04-19 06:30:30 +00:00
* @ return navigation_node
2009-08-28 08:47:31 +00:00
*/
2010-02-14 09:29:44 +00:00
public function add ( $text , $url = null , $type = null , $shorttext = null , $key = null , pix_icon $icon = null ) {
2010-04-19 06:30:30 +00:00
$node = parent :: add ( $text , $url , $type , $shorttext , $key , $icon );
$node -> add_class ( 'root_node' );
return $node ;
2009-08-28 08:47:31 +00:00
}
2009-09-16 07:52:36 +00:00
/**
* This function allows the user to add something to the start of the settings
* navigation , which means it will be at the top of the settings navigation block
*
* @ param string $text
* @ param sting | moodle_url $url
* @ param string $shorttext
* @ param string | int $key
* @ param int $type
* @ param string $icon
2010-04-19 06:30:30 +00:00
* @ return navigation_node
2009-09-16 07:52:36 +00:00
*/
2010-02-14 09:29:44 +00:00
public function prepend ( $text , $url = null , $type = null , $shorttext = null , $key = null , pix_icon $icon = null ) {
2009-09-16 07:52:36 +00:00
$children = $this -> children ;
2010-05-03 07:11:17 +00:00
$childrenclass = get_class ( $children );
$this -> children = new $childrenclass ;
2010-04-19 06:30:30 +00:00
$node = $this -> add ( $text , $url , $type , $shorttext , $key , $icon );
foreach ( $children as $child ) {
$this -> children -> add ( $child );
2009-09-16 07:52:36 +00:00
}
2010-04-19 06:30:30 +00:00
return $node ;
2009-09-16 07:52:36 +00:00
}
2009-08-28 08:47:31 +00:00
/**
* Load the site administration tree
*
* This function loads the site administration tree by using the lib / adminlib library functions
*
2010-04-19 06:30:30 +00:00
* @ param navigation_node $referencebranch A reference to a branch in the settings
2009-08-28 08:47:31 +00:00
* navigation tree
2010-04-19 06:30:30 +00:00
* @ param part_of_admin_tree $adminbranch The branch to add , if null generate the admin
2009-08-28 08:47:31 +00:00
* tree and start at the beginning
* @ return mixed A key to access the admin tree by
*/
2010-02-10 01:12:59 +00:00
protected function load_administration_settings ( navigation_node $referencebranch = null , part_of_admin_tree $adminbranch = null ) {
2010-02-18 05:57:20 +00:00
global $CFG ;
2010-02-10 01:12:59 +00:00
2009-08-28 08:47:31 +00:00
// Check if we are just starting to generate this navigation.
if ( $referencebranch === null ) {
2010-02-10 01:12:59 +00:00
2010-02-22 07:57:35 +00:00
// Require the admin lib then get an admin structure
2010-02-10 01:12:59 +00:00
if ( ! function_exists ( 'admin_get_root' )) {
require_once ( $CFG -> dirroot . '/lib/adminlib.php' );
}
$adminroot = admin_get_root ( false , false );
2010-02-22 07:57:35 +00:00
// This is the active section identifier
$this -> adminsection = $this -> page -> url -> param ( 'section' );
2010-03-31 07:41:31 +00:00
2010-02-22 07:57:35 +00:00
// Disable the navigation from automatically finding the active node
navigation_node :: $autofindactive = false ;
2010-04-19 06:30:30 +00:00
$referencebranch = $this -> add ( get_string ( 'administrationsite' ), null , self :: TYPE_SETTING , null , 'root' );
2010-02-10 01:12:59 +00:00
foreach ( $adminroot -> children as $adminbranch ) {
$this -> load_administration_settings ( $referencebranch , $adminbranch );
}
2010-02-22 07:57:35 +00:00
navigation_node :: $autofindactive = true ;
2010-02-10 01:12:59 +00:00
2010-02-22 07:57:35 +00:00
// Use the admin structure to locate the active page
2010-04-19 06:30:30 +00:00
if ( ! $this -> contains_active_node () && $current = $adminroot -> locate ( $this -> adminsection , true )) {
$currentnode = $this ;
while (( $pathkey = array_pop ( $current -> path )) !== null && $currentnode ) {
$currentnode = $currentnode -> get ( $pathkey );
}
if ( $currentnode ) {
$currentnode -> make_active ();
2009-08-28 08:47:31 +00:00
}
2010-05-05 06:28:47 +00:00
} else {
$this -> scan_for_active_node ( $referencebranch );
2010-02-10 01:12:59 +00:00
}
2010-04-19 06:30:30 +00:00
return $referencebranch ;
2009-10-20 03:31:19 +00:00
} else if ( $adminbranch -> check_access ()) {
2009-08-28 08:47:31 +00:00
// We have a reference branch that we can access and is not hidden `hurrah`
// Now we need to display it and any children it may have
$url = null ;
$icon = null ;
if ( $adminbranch instanceof admin_settingpage ) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/admin/settings.php' , array ( 'section' => $adminbranch -> name ));
2009-08-28 08:47:31 +00:00
} else if ( $adminbranch instanceof admin_externalpage ) {
$url = $adminbranch -> url ;
}
// Add the branch
2010-04-19 06:30:30 +00:00
$reference = $referencebranch -> add ( $adminbranch -> visiblename , $url , self :: TYPE_SETTING , null , $adminbranch -> name , $icon );
2009-10-20 03:31:19 +00:00
if ( $adminbranch -> is_hidden ()) {
2010-02-22 07:57:35 +00:00
if (( $adminbranch instanceof admin_externalpage || $adminbranch instanceof admin_settingpage ) && $adminbranch -> name == $this -> adminsection ) {
$reference -> add_class ( 'hidden' );
} else {
$reference -> display = false ;
}
2009-10-20 03:31:19 +00:00
}
2009-08-28 08:47:31 +00:00
// Check if we are generating the admin notifications and whether notificiations exist
if ( $adminbranch -> name === 'adminnotifications' && admin_critical_warnings_present ()) {
$reference -> add_class ( 'criticalnotification' );
}
// Check if this branch has children
if ( $reference && isset ( $adminbranch -> children ) && is_array ( $adminbranch -> children ) && count ( $adminbranch -> children ) > 0 ) {
foreach ( $adminbranch -> children as $branch ) {
// Generate the child branches as well now using this branch as the reference
2009-08-29 11:15:27 +00:00
$this -> load_administration_settings ( $reference , $branch );
2009-08-28 08:47:31 +00:00
}
} else {
2010-02-14 09:29:44 +00:00
$reference -> icon = new pix_icon ( 'i/settings' , '' );
2009-08-28 08:47:31 +00:00
}
}
}
2010-05-05 06:28:47 +00:00
/**
* This function recursivily scans nodes until it finds the active node or there
* are no more nodes .
* @ param navigation_node $node
*/
protected function scan_for_active_node ( navigation_node $node ) {
if ( ! $node -> check_if_active () && $node -> children -> count () > 0 ) {
foreach ( $node -> children as & $child ) {
$this -> scan_for_active_node ( $child );
}
}
}
2010-04-19 06:30:30 +00:00
/**
* Gets a navigation node given an array of keys that represent the path to
* the desired node .
*
* @ param array $path
* @ return navigation_node | false
*/
protected function get_by_path ( array $path ) {
$node = $this -> get ( array_shift ( $path ));
foreach ( $path as $key ) {
$node -> get ( $key );
}
return $node ;
}
2009-08-28 08:47:31 +00:00
/**
* Generate the list of modules for the given course .
*
* @ param stdClass $course The course to get modules for
*/
protected function get_course_modules ( $course ) {
global $CFG ;
$mods = $modnames = $modnamesplural = $modnamesused = array ();
// This function is included when we include course/lib.php at the top
// of this file
get_all_mods ( $course -> id , $mods , $modnames , $modnamesplural , $modnamesused );
$resources = array ();
$activities = array ();
foreach ( $modnames as $modname => $modnamestr ) {
if ( ! course_allowed_module ( $course , $modname )) {
continue ;
}
$libfile = " $CFG->dirroot /mod/ $modname /lib.php " ;
if ( ! file_exists ( $libfile )) {
continue ;
}
include_once ( $libfile );
$gettypesfunc = $modname . '_get_types' ;
if ( function_exists ( $gettypesfunc )) {
$types = $gettypesfunc ();
foreach ( $types as $type ) {
if ( ! isset ( $type -> modclass ) || ! isset ( $type -> typestr )) {
debugging ( 'Incorrect activity type in ' . $modname );
continue ;
}
if ( $type -> modclass == MOD_CLASS_RESOURCE ) {
$resources [ html_entity_decode ( $type -> type )] = $type -> typestr ;
} else {
$activities [ html_entity_decode ( $type -> type )] = $type -> typestr ;
}
}
} else {
$archetype = plugin_supports ( 'mod' , $modname , FEATURE_MOD_ARCHETYPE , MOD_ARCHETYPE_OTHER );
if ( $archetype == MOD_ARCHETYPE_RESOURCE ) {
$resources [ $modname ] = $modnamestr ;
} else {
// all other archetypes are considered activity
$activities [ $modname ] = $modnamestr ;
}
}
}
2011-06-24 16:42:41 +08:00
return array ( $resources , $activities );
2009-08-28 08:47:31 +00:00
}
/**
* This function loads the course settings that are available for the user
*
2010-03-22 03:04:00 +00:00
* @ param bool $forceopen If set to true the course node will be forced open
2010-04-19 06:30:30 +00:00
* @ return navigation_node | false
2009-08-28 08:47:31 +00:00
*/
2010-03-22 03:04:00 +00:00
protected function load_course_settings ( $forceopen = false ) {
2011-06-24 16:42:41 +08:00
global $CFG ;
2009-08-28 08:47:31 +00:00
$course = $this -> page -> course ;
2010-03-31 07:41:31 +00:00
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id );
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// note: do not test if enrolled or viewing here because we need the enrol link in Course administration section
2009-08-28 08:47:31 +00:00
2010-04-19 06:30:30 +00:00
$coursenode = $this -> add ( get_string ( 'courseadministration' ), null , self :: TYPE_COURSE , null , 'courseadmin' );
if ( $forceopen ) {
$coursenode -> force_open ();
}
2009-11-01 11:31:16 +00:00
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/course:update' , $coursecontext )) {
2009-08-28 08:47:31 +00:00
// Add the turn on/off settings
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/course/view.php' , array ( 'id' => $course -> id , 'sesskey' => sesskey ()));
2009-08-28 08:47:31 +00:00
if ( $this -> page -> user_is_editing ()) {
$url -> param ( 'edit' , 'off' );
$editstring = get_string ( 'turneditingoff' );
} else {
$url -> param ( 'edit' , 'on' );
$editstring = get_string ( 'turneditingon' );
}
2010-02-14 09:29:44 +00:00
$coursenode -> add ( $editstring , $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/edit' , '' ));
2009-08-28 08:47:31 +00:00
if ( $this -> page -> user_is_editing ()) {
2010-06-11 05:33:50 +00:00
// Removed as per MDL-22732
// $this->add_course_editing_links($course);
2009-08-28 08:47:31 +00:00
}
// Add the course settings link
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/course/edit.php' , array ( 'id' => $course -> id ));
2010-07-09 08:20:39 +00:00
$coursenode -> add ( get_string ( 'editsettings' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/settings' , '' ));
2010-04-30 03:06:22 +00:00
// Add the course completion settings link
if ( $CFG -> enablecompletion && $course -> enablecompletion ) {
$url = new moodle_url ( '/course/completion.php' , array ( 'id' => $course -> id ));
$coursenode -> add ( get_string ( 'completion' , 'completion' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/settings' , '' ));
}
2009-08-28 08:47:31 +00:00
}
2009-11-01 11:31:16 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// add enrol nodes
enrol_add_course_navigation ( $coursenode , $course );
// Manage filters
if ( has_capability ( 'moodle/filter:manage' , $coursecontext ) && count ( filter_get_available_in_context ( $coursecontext )) > 0 ) {
$url = new moodle_url ( '/filter/manage.php' , array ( 'contextid' => $coursecontext -> id ));
$coursenode -> add ( get_string ( 'filters' , 'admin' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/filter' , '' ));
2009-08-28 08:47:31 +00:00
}
// Add view grade report is permitted
$reportavailable = false ;
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/grade:viewall' , $coursecontext )) {
2009-08-28 08:47:31 +00:00
$reportavailable = true ;
} else if ( ! empty ( $course -> showgrades )) {
$reports = get_plugin_list ( 'gradereport' );
if ( is_array ( $reports ) && count ( $reports ) > 0 ) { // Get all installed reports
arsort ( $reports ); // user is last, we want to test it first
foreach ( $reports as $plugin => $plugindir ) {
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'gradereport/' . $plugin . ':view' , $coursecontext )) {
2009-08-28 08:47:31 +00:00
//stop when the first visible plugin is found
$reportavailable = true ;
break ;
}
}
}
}
if ( $reportavailable ) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/grade/report/index.php' , array ( 'id' => $course -> id ));
2010-05-03 07:11:17 +00:00
$gradenode = $coursenode -> add ( get_string ( 'grades' ), $url , self :: TYPE_SETTING , null , 'grades' , new pix_icon ( 'i/grades' , '' ));
2009-08-28 08:47:31 +00:00
}
// Add outcome if permitted
2010-03-31 07:41:31 +00:00
if ( ! empty ( $CFG -> enableoutcomes ) && has_capability ( 'moodle/course:update' , $coursecontext )) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/grade/edit/outcome/course.php' , array ( 'id' => $course -> id ));
2010-05-20 07:35:44 +00:00
$coursenode -> add ( get_string ( 'outcomes' , 'grades' ), $url , self :: TYPE_SETTING , null , 'outcomes' , new pix_icon ( 'i/outcomes' , '' ));
2009-08-28 08:47:31 +00:00
}
// Backup this course
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext )) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/backup/backup.php' , array ( 'id' => $course -> id ));
2010-05-20 07:35:44 +00:00
$coursenode -> add ( get_string ( 'backup' ), $url , self :: TYPE_SETTING , null , 'backup' , new pix_icon ( 'i/backup' , '' ));
2009-08-28 08:47:31 +00:00
}
// Restore to this course
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/restore:restorecourse' , $coursecontext )) {
2010-07-22 07:48:02 +00:00
$url = new moodle_url ( '/backup/restorefile.php' , array ( 'contextid' => $coursecontext -> id ));
2010-05-20 07:35:44 +00:00
$coursenode -> add ( get_string ( 'restore' ), $url , self :: TYPE_SETTING , null , 'restore' , new pix_icon ( 'i/restore' , '' ));
2009-08-28 08:47:31 +00:00
}
// Import data from other courses
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/restore:restoretargetimport' , $coursecontext )) {
2010-08-17 02:07:30 +00:00
$url = new moodle_url ( '/backup/import.php' , array ( 'id' => $course -> id ));
2010-05-20 07:35:44 +00:00
$coursenode -> add ( get_string ( 'import' ), $url , self :: TYPE_SETTING , null , 'import' , new pix_icon ( 'i/restore' , '' ));
2009-08-28 08:47:31 +00:00
}
2010-05-01 05:05:55 +00:00
// Publish course on a hub
if ( has_capability ( 'moodle/course:publish' , $coursecontext )) {
$url = new moodle_url ( '/course/publish/index.php' , array ( 'id' => $course -> id ));
2010-05-20 07:35:44 +00:00
$coursenode -> add ( get_string ( 'publish' ), $url , self :: TYPE_SETTING , null , 'publish' , new pix_icon ( 'i/publish' , '' ));
2010-05-01 05:05:55 +00:00
}
2009-08-28 08:47:31 +00:00
// Reset this course
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/course:reset' , $coursecontext )) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/course/reset.php' , array ( 'id' => $course -> id ));
2010-02-14 09:29:44 +00:00
$coursenode -> add ( get_string ( 'reset' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/return' , '' ));
2009-08-28 08:47:31 +00:00
}
2010-05-21 03:15:48 +00:00
// Questions
require_once ( $CFG -> dirroot . '/question/editlib.php' );
question_extend_settings_navigation ( $coursenode , $coursecontext ) -> trim_if_empty ();
2009-08-28 08:47:31 +00:00
2011-06-24 16:42:41 +08:00
if ( has_capability ( 'moodle/course:update' , $coursecontext )) {
// Repository Instances
if ( ! $this -> cache -> cached ( 'contexthasrepos' . $coursecontext -> id )) {
require_once ( $CFG -> dirroot . '/repository/lib.php' );
$editabletypes = repository :: get_editable_types ( $coursecontext );
$haseditabletypes = ! empty ( $editabletypes );
unset ( $editabletypes );
$this -> cache -> set ( 'contexthasrepos' . $coursecontext -> id , $haseditabletypes );
} else {
$haseditabletypes = $this -> cache -> { 'contexthasrepos' . $coursecontext -> id };
}
if ( $haseditabletypes ) {
$url = new moodle_url ( '/repository/manage_instances.php' , array ( 'contextid' => $coursecontext -> id ));
$coursenode -> add ( get_string ( 'repositories' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/repository' , '' ));
}
2009-08-28 08:47:31 +00:00
}
// Manage files
2010-09-03 19:14:33 +00:00
if ( $course -> legacyfiles == 2 and has_capability ( 'moodle/course:managefiles' , $coursecontext )) {
2010-08-02 13:33:19 +00:00
// hidden in new courses and courses where legacy files were turned off
2010-08-30 08:22:14 +00:00
$url = new moodle_url ( '/files/index.php' , array ( 'contextid' => $coursecontext -> id ));
2010-08-02 13:33:19 +00:00
$coursenode -> add ( get_string ( 'courselegacyfiles' ), $url , self :: TYPE_SETTING , null , 'coursefiles' , new pix_icon ( 'i/files' , '' ));
2009-08-28 08:47:31 +00:00
}
// Switch roles
$roles = array ();
$assumedrole = $this -> in_alternative_role ();
2011-06-24 16:42:41 +08:00
if ( $assumedrole !== false ) {
2009-08-28 08:47:31 +00:00
$roles [ 0 ] = get_string ( 'switchrolereturn' );
}
2010-05-11 05:28:59 +00:00
if ( has_capability ( 'moodle/role:switchroles' , $coursecontext )) {
$availableroles = get_switchable_roles ( $coursecontext );
2009-08-28 08:47:31 +00:00
if ( is_array ( $availableroles )) {
foreach ( $availableroles as $key => $role ) {
2011-02-13 16:17:47 +01:00
if ( $assumedrole == ( int ) $key ) {
2009-08-28 08:47:31 +00:00
continue ;
}
$roles [ $key ] = $role ;
}
}
}
if ( is_array ( $roles ) && count ( $roles ) > 0 ) {
2010-04-19 06:30:30 +00:00
$switchroles = $this -> add ( get_string ( 'switchroleto' ));
2009-08-28 08:47:31 +00:00
if (( count ( $roles ) == 1 && array_key_exists ( 0 , $roles )) || $assumedrole !== false ) {
2010-04-19 06:30:30 +00:00
$switchroles -> force_open ();
2009-08-28 08:47:31 +00:00
}
$returnurl = $this -> page -> url ;
$returnurl -> param ( 'sesskey' , sesskey ());
2011-06-24 16:42:41 +08:00
foreach ( $roles as $key => $name ) {
$url = new moodle_url ( '/course/switchrole.php' , array ( 'id' => $course -> id , 'sesskey' => sesskey (), 'switchrole' => $key , 'returnurl' => $returnurl -> out ( false )));
2010-04-19 06:30:30 +00:00
$switchroles -> add ( $name , $url , self :: TYPE_SETTING , null , $key , new pix_icon ( 'i/roles' , '' ));
2009-08-28 08:47:31 +00:00
}
}
// Return we are done
2010-04-19 06:30:30 +00:00
return $coursenode ;
2009-08-28 08:47:31 +00:00
}
2010-06-11 05:33:50 +00:00
/**
2010-07-22 09:43:30 +00:00
* Adds branches and links to the settings navigation to add course activities
2010-06-11 05:33:50 +00:00
* and resources .
*
* @ param stdClass $course
*/
protected function add_course_editing_links ( $course ) {
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
global $CFG ;
require_once ( $CFG -> dirroot . '/course/lib.php' );
2010-06-11 05:33:50 +00:00
// Add `add` resources|activities branches
$structurefile = $CFG -> dirroot . '/course/format/' . $course -> format . '/lib.php' ;
if ( file_exists ( $structurefile )) {
require_once ( $structurefile );
2010-09-08 08:44:16 +00:00
$requestkey = call_user_func ( 'callback_' . $course -> format . '_request_key' );
$formatidentifier = optional_param ( $requestkey , 0 , PARAM_INT );
2010-06-11 05:33:50 +00:00
} else {
2010-09-08 08:44:16 +00:00
$requestkey = get_string ( 'section' );
$formatidentifier = optional_param ( $requestkey , 0 , PARAM_INT );
2010-06-11 05:33:50 +00:00
}
$sections = get_all_sections ( $course -> id );
$addresource = $this -> add ( get_string ( 'addresource' ));
$addactivity = $this -> add ( get_string ( 'addactivity' ));
if ( $formatidentifier !== 0 ) {
$addresource -> force_open ();
$addactivity -> force_open ();
}
2011-06-24 16:42:41 +08:00
$this -> get_course_modules ( $course );
2010-06-11 05:33:50 +00:00
$textlib = textlib_get_instance ();
foreach ( $sections as $section ) {
if ( $formatidentifier !== 0 && $section -> section != $formatidentifier ) {
continue ;
}
2010-09-08 08:44:16 +00:00
$sectionurl = new moodle_url ( '/course/view.php' , array ( 'id' => $course -> id , $requestkey => $section -> section ));
2010-06-11 05:33:50 +00:00
if ( $section -> section == 0 ) {
$sectionresources = $addresource -> add ( get_string ( 'course' ), $sectionurl , self :: TYPE_SETTING );
$sectionactivities = $addactivity -> add ( get_string ( 'course' ), $sectionurl , self :: TYPE_SETTING );
} else {
2010-09-08 08:44:16 +00:00
$sectionname = get_section_name ( $course , $section );
$sectionresources = $addresource -> add ( $sectionname , $sectionurl , self :: TYPE_SETTING );
$sectionactivities = $addactivity -> add ( $sectionname , $sectionurl , self :: TYPE_SETTING );
2010-06-11 05:33:50 +00:00
}
foreach ( $resources as $value => $resource ) {
$url = new moodle_url ( '/course/mod.php' , array ( 'id' => $course -> id , 'sesskey' => sesskey (), 'section' => $section -> section ));
$pos = strpos ( $value , '&type=' );
if ( $pos !== false ) {
$url -> param ( 'add' , $textlib -> substr ( $value , 0 , $pos ));
$url -> param ( 'type' , $textlib -> substr ( $value , $pos + 6 ));
} else {
$url -> param ( 'add' , $value );
}
$sectionresources -> add ( $resource , $url , self :: TYPE_SETTING );
}
$subbranch = false ;
foreach ( $activities as $activityname => $activity ) {
if ( $activity === '--' ) {
$subbranch = false ;
continue ;
}
if ( strpos ( $activity , '--' ) === 0 ) {
$subbranch = $sectionactivities -> add ( trim ( $activity , '-' ));
continue ;
}
$url = new moodle_url ( '/course/mod.php' , array ( 'id' => $course -> id , 'sesskey' => sesskey (), 'section' => $section -> section ));
$pos = strpos ( $activityname , '&type=' );
if ( $pos !== false ) {
$url -> param ( 'add' , $textlib -> substr ( $activityname , 0 , $pos ));
$url -> param ( 'type' , $textlib -> substr ( $activityname , $pos + 6 ));
} else {
$url -> param ( 'add' , $activityname );
}
if ( $subbranch !== false ) {
$subbranch -> add ( $activity , $url , self :: TYPE_SETTING );
} else {
$sectionactivities -> add ( $activity , $url , self :: TYPE_SETTING );
}
}
}
}
2009-08-28 08:47:31 +00:00
/**
* This function calls the module function to inject module settings into the
* settings navigation tree .
*
* This only gets called if there is a corrosponding function in the modules
* lib file .
*
* For examples mod / forum / lib . php ::: forum_extend_settings_navigation ()
*
2010-04-19 06:30:30 +00:00
* @ return navigation_node | false
2009-08-28 08:47:31 +00:00
*/
protected function load_module_settings () {
2010-02-18 05:57:20 +00:00
global $CFG ;
2009-10-15 06:37:45 +00:00
if ( ! $this -> page -> cm && $this -> context -> contextlevel == CONTEXT_MODULE && $this -> context -> instanceid ) {
2010-03-22 03:04:00 +00:00
$cm = get_coursemodule_from_id ( false , $this -> context -> instanceid , 0 , false , MUST_EXIST );
2010-02-18 05:57:20 +00:00
$this -> page -> set_cm ( $cm , $this -> page -> course );
2009-10-15 06:37:45 +00:00
}
2010-07-21 02:53:52 +00:00
$file = $CFG -> dirroot . '/mod/' . $this -> page -> activityname . '/lib.php' ;
if ( file_exists ( $file )) {
require_once ( $file );
}
MDL-23318 Consistent usage of 'pluginadministration' string for the Settings block
AMOS BEGIN
MOV [assignmentadministration,mod_assignment],[pluginadministration,mod_assignment]
MOV [dataadministration,mod_data],[pluginadministration,mod_data]
MOV [feedbackadministration,mod_feedback],[pluginadministration,mod_feedback]
MOV [folderadministration,mod_folder],[pluginadministration,mod_folder]
MOV [forumadministration,mod_forum],[pluginadministration,mod_forum]
MOV [glossaryadministration,mod_glossary],[pluginadministration,mod_glossary]
MOV [chatadministration,mod_chat],[pluginadministration,mod_chat]
MOV [choiceadministration,mod_choice],[pluginadministration,mod_choice]
MOV [imscpadministration,mod_imscp],[pluginadministration,mod_imscp]
MOV [labeladministration,mod_label],[pluginadministration,mod_label]
MOV [lessonadministration,mod_lesson],[pluginadministration,mod_lesson]
MOV [pageadministration,mod_page],[pluginadministration,mod_page]
MOV [quizadministration,mod_quiz],[pluginadministration,mod_quiz]
MOV [resourceadministration,mod_resource],[pluginadministration,mod_resource]
MOV [scormadministration,mod_scorm],[pluginadministration,mod_scorm]
MOV [surveyadministration,mod_survey],[pluginadministration,mod_survey]
MOV [urladministration,mod_url],[pluginadministration,mod_url]
MOV [wikiadministration,mod_wiki],[pluginadministration,mod_wiki]
MOV [workshopadministration,mod_workshop],[pluginadministration,mod_workshop]
AMOS END
2010-08-17 17:35:12 +00:00
$modulenode = $this -> add ( get_string ( 'pluginadministration' , $this -> page -> activityname ));
2010-04-19 06:30:30 +00:00
$modulenode -> force_open ();
2010-03-31 07:41:31 +00:00
2010-03-22 03:04:00 +00:00
// Settings for the module
if ( has_capability ( 'moodle/course:manageactivities' , $this -> page -> cm -> context )) {
$url = new moodle_url ( '/course/modedit.php' , array ( 'update' => $this -> page -> cm -> id , 'return' => true , 'sesskey' => sesskey ()));
2011-06-18 16:24:31 +01:00
$modulenode -> add ( get_string ( 'editsettings' ), $url , navigation_node :: TYPE_SETTING , null , 'modedit' );
2010-03-22 03:04:00 +00:00
}
// Assign local roles
if ( count ( get_assignable_roles ( $this -> page -> cm -> context )) > 0 ) {
$url = new moodle_url ( '/' . $CFG -> admin . '/roles/assign.php' , array ( 'contextid' => $this -> page -> cm -> context -> id ));
2011-06-18 16:24:31 +01:00
$modulenode -> add ( get_string ( 'localroles' , 'role' ), $url , self :: TYPE_SETTING , null , 'roleassign' );
2010-03-22 03:04:00 +00:00
}
// Override roles
if ( has_capability ( 'moodle/role:review' , $this -> page -> cm -> context ) or count ( get_overridable_roles ( $this -> page -> cm -> context )) > 0 ) {
$url = new moodle_url ( '/' . $CFG -> admin . '/roles/permissions.php' , array ( 'contextid' => $this -> page -> cm -> context -> id ));
2011-06-18 16:24:31 +01:00
$modulenode -> add ( get_string ( 'permissions' , 'role' ), $url , self :: TYPE_SETTING , null , 'roleoverride' );
2010-03-22 03:04:00 +00:00
}
// Check role permissions
if ( has_any_capability ( array ( 'moodle/role:assign' , 'moodle/role:safeoverride' , 'moodle/role:override' , 'moodle/role:assign' ), $this -> page -> cm -> context )) {
$url = new moodle_url ( '/' . $CFG -> admin . '/roles/check.php' , array ( 'contextid' => $this -> page -> cm -> context -> id ));
2011-06-18 16:24:31 +01:00
$modulenode -> add ( get_string ( 'checkpermissions' , 'role' ), $url , self :: TYPE_SETTING , null , 'rolecheck' );
2010-03-22 03:04:00 +00:00
}
// Manage filters
if ( has_capability ( 'moodle/filter:manage' , $this -> page -> cm -> context ) && count ( filter_get_available_in_context ( $this -> page -> cm -> context )) > 0 ) {
$url = new moodle_url ( '/filter/manage.php' , array ( 'contextid' => $this -> page -> cm -> context -> id ));
2011-06-18 16:24:31 +01:00
$modulenode -> add ( get_string ( 'filters' , 'admin' ), $url , self :: TYPE_SETTING , null , 'filtermanage' );
2010-03-22 03:04:00 +00:00
}
2011-11-03 20:52:00 +01:00
// Add reports
$reports = get_plugin_list_with_function ( 'report' , 'extend_navigation_module' , 'lib.php' );
foreach ( $reports as $reportfunction ) {
$reportfunction ( $modulenode , $this -> page -> cm );
2010-05-10 09:02:09 +00:00
}
2010-05-04 04:00:03 +00:00
// Add a backup link
$featuresfunc = $this -> page -> activityname . '_supports' ;
2010-10-01 06:22:08 +00:00
if ( function_exists ( $featuresfunc ) && $featuresfunc ( FEATURE_BACKUP_MOODLE2 ) && has_capability ( 'moodle/backup:backupactivity' , $this -> page -> cm -> context )) {
2010-05-04 04:00:03 +00:00
$url = new moodle_url ( '/backup/backup.php' , array ( 'id' => $this -> page -> cm -> course , 'cm' => $this -> page -> cm -> id ));
2011-06-18 16:24:31 +01:00
$modulenode -> add ( get_string ( 'backup' ), $url , self :: TYPE_SETTING , null , 'backup' );
2010-05-04 04:00:03 +00:00
}
2010-11-02 02:29:21 +00:00
// Restore this activity
$featuresfunc = $this -> page -> activityname . '_supports' ;
if ( function_exists ( $featuresfunc ) && $featuresfunc ( FEATURE_BACKUP_MOODLE2 ) && has_capability ( 'moodle/restore:restoreactivity' , $this -> page -> cm -> context )) {
$url = new moodle_url ( '/backup/restorefile.php' , array ( 'contextid' => $this -> page -> cm -> context -> id ));
2011-06-18 16:24:31 +01:00
$modulenode -> add ( get_string ( 'restore' ), $url , self :: TYPE_SETTING , null , 'restore' );
2010-11-02 02:29:21 +00:00
}
2011-10-03 21:57:16 +02:00
// Allow the active advanced grading method plugin to append its settings
$featuresfunc = $this -> page -> activityname . '_supports' ;
if ( function_exists ( $featuresfunc ) && $featuresfunc ( FEATURE_ADVANCED_GRADING ) && has_capability ( 'moodle/grade:managegradingforms' , $this -> page -> cm -> context )) {
require_once ( $CFG -> dirroot . '/grade/grading/lib.php' );
$gradingman = get_grading_manager ( $this -> page -> cm -> context , $this -> page -> activityname );
$gradingman -> extend_settings_navigation ( $this , $modulenode );
}
2010-02-18 05:57:20 +00:00
$function = $this -> page -> activityname . '_extend_settings_navigation' ;
2009-08-28 08:47:31 +00:00
if ( ! function_exists ( $function )) {
2010-04-19 06:30:30 +00:00
return $modulenode ;
2009-08-28 08:47:31 +00:00
}
2010-03-22 03:04:00 +00:00
$function ( $this , $modulenode );
// Remove the module node if there are no children
if ( empty ( $modulenode -> children )) {
2010-04-19 06:30:30 +00:00
$modulenode -> remove ();
2010-03-22 03:04:00 +00:00
}
2010-04-19 06:30:30 +00:00
return $modulenode ;
2009-08-28 08:47:31 +00:00
}
/**
* Loads the user settings block of the settings nav
2009-11-01 11:31:16 +00:00
*
2009-08-28 08:47:31 +00:00
* This function is simply works out the userid and whether we need to load
2009-11-01 11:31:16 +00:00
* just the current users profile settings , or the current user and the user the
2009-08-28 08:47:31 +00:00
* current user is viewing .
2009-11-01 11:31:16 +00:00
*
2009-08-28 08:47:31 +00:00
* This function has some very ugly code to work out the user , if anyone has
* any bright ideas please feel free to intervene .
*
* @ param int $courseid The course id of the current course
2010-04-19 06:30:30 +00:00
* @ return navigation_node | false
2009-08-28 08:47:31 +00:00
*/
protected function load_user_settings ( $courseid = SITEID ) {
2010-03-22 03:04:00 +00:00
global $USER , $FULLME , $CFG ;
2009-08-28 08:47:31 +00:00
if ( isguestuser () || ! isloggedin ()) {
return false ;
}
2010-05-30 22:56:29 +00:00
2010-06-10 07:29:02 +00:00
$navusers = $this -> page -> navigation -> get_extending_users ();
if ( count ( $this -> userstoextendfor ) > 0 || count ( $navusers ) > 0 ) {
2010-05-17 05:38:59 +00:00
$usernode = null ;
foreach ( $this -> userstoextendfor as $userid ) {
2010-06-10 08:18:18 +00:00
if ( $userid == $USER -> id ) {
continue ;
}
2010-05-17 05:38:59 +00:00
$node = $this -> generate_user_settings ( $courseid , $userid , 'userviewingsettings' );
if ( is_null ( $usernode )) {
$usernode = $node ;
}
}
2010-06-10 07:29:02 +00:00
foreach ( $navusers as $user ) {
2010-06-10 08:18:18 +00:00
if ( $user -> id == $USER -> id ) {
continue ;
}
2010-06-10 07:29:02 +00:00
$node = $this -> generate_user_settings ( $courseid , $user -> id , 'userviewingsettings' );
if ( is_null ( $usernode )) {
$usernode = $node ;
}
}
2010-03-22 03:04:00 +00:00
$this -> generate_user_settings ( $courseid , $USER -> id );
2009-08-28 08:47:31 +00:00
} else {
2010-04-19 06:30:30 +00:00
$usernode = $this -> generate_user_settings ( $courseid , $USER -> id );
2009-08-28 08:47:31 +00:00
}
2010-04-19 06:30:30 +00:00
return $usernode ;
2009-08-28 08:47:31 +00:00
}
2010-08-05 02:44:03 +00:00
/**
* Extends the settings navigation for the given user .
*
* Note : This method gets called automatically if you call
* $PAGE -> navigation -> extend_for_user ( $userid )
*
* @ param int $userid
*/
2010-05-17 05:38:59 +00:00
public function extend_for_user ( $userid ) {
global $CFG ;
if ( ! in_array ( $userid , $this -> userstoextendfor )) {
$this -> userstoextendfor [] = $userid ;
if ( $this -> initialised ) {
$this -> generate_user_settings ( $this -> page -> course -> id , $userid , 'userviewingsettings' );
$children = array ();
foreach ( $this -> children as $child ) {
$children [] = $child ;
}
array_unshift ( $children , array_pop ( $children ));
$this -> children = new navigation_node_collection ();
foreach ( $children as $child ) {
$this -> children -> add ( $child );
}
}
}
}
2009-08-28 08:47:31 +00:00
/**
* This function gets called by { @ link load_user_settings ()} and actually works out
* what can be shown / done
*
2011-06-24 16:42:41 +08:00
* @ global moodle_database $DB
2009-08-28 08:47:31 +00:00
* @ param int $courseid The current course ' id
* @ param int $userid The user id to load for
* @ param string $gstitle The string to pass to get_string for the branch title
2010-04-19 06:30:30 +00:00
* @ return navigation_node | false
2009-08-28 08:47:31 +00:00
*/
protected function generate_user_settings ( $courseid , $userid , $gstitle = 'usercurrentsettings' ) {
2010-02-18 05:57:20 +00:00
global $DB , $CFG , $USER , $SITE ;
2009-08-28 08:47:31 +00:00
2010-02-18 05:57:20 +00:00
if ( $courseid != SITEID ) {
if ( ! empty ( $this -> page -> course -> id ) && $this -> page -> course -> id == $courseid ) {
$course = $this -> page -> course ;
} else {
2011-06-24 16:42:41 +08:00
list ( $select , $join ) = context_instance_preload_sql ( 'c.id' , CONTEXT_COURSE , 'ctx' );
$sql = " SELECT c.* $select FROM { course} c $join WHERE c.id = :courseid " ;
$course = $DB -> get_record_sql ( $sql , array ( 'courseid' => $courseid ), MUST_EXIST );
context_instance_preload ( $course );
2010-02-18 05:57:20 +00:00
}
} else {
$course = $SITE ;
2009-08-28 08:47:31 +00:00
}
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id ); // Course context
2010-02-18 05:57:20 +00:00
$systemcontext = get_system_context ();
2009-08-28 08:47:31 +00:00
$currentuser = ( $USER -> id == $userid );
2010-03-31 07:41:31 +00:00
2009-08-28 08:47:31 +00:00
if ( $currentuser ) {
$user = $USER ;
$usercontext = get_context_instance ( CONTEXT_USER , $user -> id ); // User context
} else {
2011-06-24 16:42:41 +08:00
list ( $select , $join ) = context_instance_preload_sql ( 'u.id' , CONTEXT_USER , 'ctx' );
$sql = " SELECT u.* $select FROM { user} u $join WHERE u.id = :userid " ;
$user = $DB -> get_record_sql ( $sql , array ( 'userid' => $userid ), IGNORE_MISSING );
if ( ! $user ) {
2009-08-28 08:47:31 +00:00
return false ;
}
2011-06-24 16:42:41 +08:00
context_instance_preload ( $user );
2009-08-28 08:47:31 +00:00
// Check that the user can view the profile
2011-06-24 16:42:41 +08:00
$usercontext = get_context_instance ( CONTEXT_USER , $user -> id ); // User context
$canviewuser = has_capability ( 'moodle/user:viewdetails' , $usercontext );
if ( $course -> id == SITEID ) {
if ( $CFG -> forceloginforprofiles && ! has_coursecontact_role ( $user -> id ) && ! $canviewuser ) { // Reduce possibility of "browsing" userbase at site level
2009-08-28 08:47:31 +00:00
// Teachers can browse and be browsed at site level. If not forceloginforprofiles, allow access (bug #4366)
return false ;
}
} else {
2011-06-24 16:42:41 +08:00
$canviewusercourse = has_capability ( 'moodle/user:viewdetails' , $coursecontext );
$canaccessallgroups = has_capability ( 'moodle/site:accessallgroups' , $coursecontext );
2011-10-29 09:45:54 +02:00
if (( ! $canviewusercourse && ! $canviewuser ) || ! can_access_course ( $course , $user -> id )) {
2009-08-28 08:47:31 +00:00
return false ;
}
2011-06-24 16:42:41 +08:00
if ( ! $canaccessallgroups && groups_get_course_groupmode ( $course ) == SEPARATEGROUPS ) {
2009-08-28 08:47:31 +00:00
// If groups are in use, make sure we can see that group
return false ;
}
}
}
$fullname = fullname ( $user , has_capability ( 'moodle/site:viewfullnames' , $this -> page -> context ));
2010-06-10 07:29:02 +00:00
$key = $gstitle ;
if ( $gstitle != 'usercurrentsettings' ) {
$key .= $userid ;
}
2009-08-28 08:47:31 +00:00
// Add a user setting branch
2010-06-10 07:29:02 +00:00
$usersetting = $this -> add ( get_string ( $gstitle , 'moodle' , $fullname ), null , self :: TYPE_CONTAINER , null , $key );
2009-08-28 08:47:31 +00:00
$usersetting -> id = 'usersettings' ;
2010-07-13 02:35:31 +00:00
if ( $this -> page -> context -> contextlevel == CONTEXT_USER && $this -> page -> context -> instanceid == $user -> id ) {
// Automatically start by making it active
$usersetting -> make_active ();
}
2009-08-28 08:47:31 +00:00
// Check if the user has been deleted
if ( $user -> deleted ) {
if ( ! has_capability ( 'moodle/user:update' , $coursecontext )) {
// We can't edit the user so just show the user deleted message
2009-09-04 08:43:49 +00:00
$usersetting -> add ( get_string ( 'userdeleted' ), null , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
} else {
// We can edit the user so show the user deleted message and link it to the profile
2010-05-04 13:04:35 +00:00
if ( $course -> id == SITEID ) {
$profileurl = new moodle_url ( '/user/profile.php' , array ( 'id' => $user -> id ));
} else {
$profileurl = new moodle_url ( '/user/view.php' , array ( 'id' => $user -> id , 'course' => $course -> id ));
}
2009-09-04 08:43:49 +00:00
$usersetting -> add ( get_string ( 'userdeleted' ), $profileurl , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
}
return true ;
}
2011-06-24 16:42:41 +08:00
$userauthplugin = false ;
if ( ! empty ( $user -> auth )) {
$userauthplugin = get_auth_plugin ( $user -> auth );
}
2009-08-28 08:47:31 +00:00
// Add the profile edit link
if ( isloggedin () && ! isguestuser ( $user ) && ! is_mnet_remote_user ( $user )) {
2010-08-12 09:44:28 +00:00
if (( $currentuser || is_siteadmin ( $USER ) || ! is_siteadmin ( $user )) && has_capability ( 'moodle/user:update' , $systemcontext )) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/user/editadvanced.php' , array ( 'id' => $user -> id , 'course' => $course -> id ));
2009-12-23 01:22:48 +00:00
$usersetting -> add ( get_string ( 'editmyprofile' ), $url , self :: TYPE_SETTING );
2010-08-12 09:44:28 +00:00
} else if (( has_capability ( 'moodle/user:editprofile' , $usercontext ) && ! is_siteadmin ( $user )) || ( $currentuser && has_capability ( 'moodle/user:editownprofile' , $systemcontext ))) {
2011-06-24 16:42:41 +08:00
if ( $userauthplugin && $userauthplugin -> can_edit_profile ()) {
$url = $userauthplugin -> edit_profile_url ();
if ( empty ( $url )) {
$url = new moodle_url ( '/user/edit.php' , array ( 'id' => $user -> id , 'course' => $course -> id ));
2010-09-03 19:14:33 +00:00
}
2011-06-24 16:42:41 +08:00
$usersetting -> add ( get_string ( 'editmyprofile' ), $url , self :: TYPE_SETTING );
2010-09-03 19:14:33 +00:00
}
2009-08-28 08:47:31 +00:00
}
}
// Change password link
2011-06-24 16:42:41 +08:00
if ( $userauthplugin && $currentuser && ! session_is_loggedinas () && ! isguestuser () && has_capability ( 'moodle/user:changeownpassword' , $systemcontext ) && $userauthplugin -> can_change_password ()) {
$passwordchangeurl = $userauthplugin -> change_password_url ();
if ( empty ( $passwordchangeurl )) {
$passwordchangeurl = new moodle_url ( '/login/change_password.php' , array ( 'id' => $course -> id ));
2009-08-28 08:47:31 +00:00
}
2011-06-24 16:42:41 +08:00
$usersetting -> add ( get_string ( " changepassword " ), $passwordchangeurl , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
}
// View the roles settings
if ( has_any_capability ( array ( 'moodle/role:assign' , 'moodle/role:safeoverride' , 'moodle/role:override' , 'moodle/role:manage' ), $usercontext )) {
2010-04-19 06:30:30 +00:00
$roles = $usersetting -> add ( get_string ( 'roles' ), null , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/admin/roles/usersroles.php' , array ( 'userid' => $user -> id , 'courseid' => $course -> id ));
2010-04-19 06:30:30 +00:00
$roles -> add ( get_string ( 'thisusersroles' , 'role' ), $url , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
$assignableroles = get_assignable_roles ( $usercontext , ROLENAME_BOTH );
if ( ! empty ( $assignableroles )) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/admin/roles/assign.php' , array ( 'contextid' => $usercontext -> id , 'userid' => $user -> id , 'courseid' => $course -> id ));
2010-04-19 06:30:30 +00:00
$roles -> add ( get_string ( 'assignrolesrelativetothisuser' , 'role' ), $url , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
}
2010-03-22 03:04:00 +00:00
if ( has_capability ( 'moodle/role:review' , $usercontext ) || count ( get_overridable_roles ( $usercontext , ROLENAME_BOTH )) > 0 ) {
$url = new moodle_url ( '/admin/roles/permissions.php' , array ( 'contextid' => $usercontext -> id , 'userid' => $user -> id , 'courseid' => $course -> id ));
2010-04-19 06:30:30 +00:00
$roles -> add ( get_string ( 'permissions' , 'role' ), $url , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
}
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/admin/roles/check.php' , array ( 'contextid' => $usercontext -> id , 'userid' => $user -> id , 'courseid' => $course -> id ));
2010-04-19 06:30:30 +00:00
$roles -> add ( get_string ( 'checkpermissions' , 'role' ), $url , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
}
// Portfolio
2009-12-23 01:22:48 +00:00
if ( $currentuser && ! empty ( $CFG -> enableportfolios ) && has_capability ( 'moodle/portfolio:export' , $systemcontext )) {
2009-12-12 11:27:07 +00:00
require_once ( $CFG -> libdir . '/portfoliolib.php' );
if ( portfolio_instances ( true , false )) {
2010-04-19 06:30:30 +00:00
$portfolio = $usersetting -> add ( get_string ( 'portfolios' , 'portfolio' ), null , self :: TYPE_SETTING );
2010-07-12 20:04:38 +00:00
$url = new moodle_url ( '/user/portfolio.php' , array ( 'courseid' => $course -> id ));
$portfolio -> add ( get_string ( 'configure' , 'portfolio' ), $url , self :: TYPE_SETTING );
$url = new moodle_url ( '/user/portfoliologs.php' , array ( 'courseid' => $course -> id ));
$portfolio -> add ( get_string ( 'logs' , 'portfolio' ), $url , self :: TYPE_SETTING );
2009-12-12 11:27:07 +00:00
}
2009-08-28 08:47:31 +00:00
}
2010-05-13 02:13:06 +00:00
$enablemanagetokens = false ;
if ( ! empty ( $CFG -> enablerssfeeds )) {
$enablemanagetokens = true ;
} else if ( ! is_siteadmin ( $USER -> id )
&& ! empty ( $CFG -> enablewebservices )
&& has_capability ( 'moodle/webservice:createtoken' , get_system_context ()) ) {
$enablemanagetokens = true ;
}
2010-01-19 08:16:57 +00:00
// Security keys
2010-05-13 02:13:06 +00:00
if ( $currentuser && $enablemanagetokens ) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/user/managetoken.php' , array ( 'sesskey' => sesskey ()));
2010-01-19 08:16:57 +00:00
$usersetting -> add ( get_string ( 'securitykeys' , 'webservice' ), $url , self :: TYPE_SETTING );
2010-01-12 10:34:52 +00:00
}
2009-08-28 08:47:31 +00:00
// Repository
2011-06-24 16:42:41 +08:00
if ( ! $currentuser && $usercontext -> contextlevel == CONTEXT_USER ) {
if ( ! $this -> cache -> cached ( 'contexthasrepos' . $usercontext -> id )) {
require_once ( $CFG -> dirroot . '/repository/lib.php' );
$editabletypes = repository :: get_editable_types ( $usercontext );
$haseditabletypes = ! empty ( $editabletypes );
unset ( $editabletypes );
$this -> cache -> set ( 'contexthasrepos' . $usercontext -> id , $haseditabletypes );
} else {
$haseditabletypes = $this -> cache -> { 'contexthasrepos' . $usercontext -> id };
}
if ( $haseditabletypes ) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/repository/manage_instances.php' , array ( 'contextid' => $usercontext -> id ));
2009-09-04 08:43:49 +00:00
$usersetting -> add ( get_string ( 'repositories' , 'repository' ), $url , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
}
}
// Messaging
2010-07-13 02:35:31 +00:00
if (( $currentuser && has_capability ( 'moodle/user:editownmessageprofile' , $systemcontext )) || ( ! isguestuser ( $user ) && has_capability ( 'moodle/user:editmessageprofile' , $usercontext ) && ! is_primary_admin ( $user -> id ))) {
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/message/edit.php' , array ( 'id' => $user -> id , 'course' => $course -> id ));
2011-07-05 15:23:37 +01:00
$usersetting -> add ( get_string ( 'editmymessage' , 'message' ), $url , self :: TYPE_SETTING );
2009-08-28 08:47:31 +00:00
}
2010-05-20 08:04:20 +00:00
// Blogs
2010-11-26 06:04:59 +00:00
if ( $currentuser && ! empty ( $CFG -> bloglevel )) {
2010-05-20 08:04:20 +00:00
$blog = $usersetting -> add ( get_string ( 'blogs' , 'blog' ), null , navigation_node :: TYPE_CONTAINER , null , 'blogs' );
$blog -> add ( get_string ( 'preferences' , 'blog' ), new moodle_url ( '/blog/preferences.php' ), navigation_node :: TYPE_SETTING );
2010-05-30 22:56:29 +00:00
if ( ! empty ( $CFG -> useexternalblogs ) && $CFG -> maxexternalblogsperuser > 0 && has_capability ( 'moodle/blog:manageexternal' , get_context_instance ( CONTEXT_SYSTEM ))) {
2010-05-20 08:04:20 +00:00
$blog -> add ( get_string ( 'externalblogs' , 'blog' ), new moodle_url ( '/blog/external_blogs.php' ), navigation_node :: TYPE_SETTING );
$blog -> add ( get_string ( 'addnewexternalblog' , 'blog' ), new moodle_url ( '/blog/external_blog_edit.php' ), navigation_node :: TYPE_SETTING );
}
}
2010-05-04 13:04:35 +00:00
// Login as ...
if ( ! $user -> deleted and ! $currentuser && ! session_is_loggedinas () && has_capability ( 'moodle/user:loginas' , $coursecontext ) && ! is_siteadmin ( $user -> id )) {
$url = new moodle_url ( '/course/loginas.php' , array ( 'id' => $course -> id , 'user' => $user -> id , 'sesskey' => sesskey ()));
$usersetting -> add ( get_string ( 'loginas' ), $url , self :: TYPE_SETTING );
}
2010-04-19 06:30:30 +00:00
return $usersetting ;
2009-08-28 08:47:31 +00:00
}
2010-03-22 03:04:00 +00:00
/**
* Loads block specific settings in the navigation
2010-03-31 07:41:31 +00:00
*
2010-04-19 06:30:30 +00:00
* @ return navigation_node
2010-03-22 03:04:00 +00:00
*/
protected function load_block_settings () {
global $CFG ;
2010-04-19 06:30:30 +00:00
$blocknode = $this -> add ( print_context_name ( $this -> context ));
$blocknode -> force_open ();
2010-03-22 03:04:00 +00:00
// Assign local roles
$assignurl = new moodle_url ( '/' . $CFG -> admin . '/roles/assign.php' , array ( 'contextid' => $this -> context -> id ));
$blocknode -> add ( get_string ( 'assignroles' , 'role' ), $assignurl , self :: TYPE_SETTING );
// Override roles
if ( has_capability ( 'moodle/role:review' , $this -> context ) or count ( get_overridable_roles ( $this -> context )) > 0 ) {
$url = new moodle_url ( '/' . $CFG -> admin . '/roles/permissions.php' , array ( 'contextid' => $this -> context -> id ));
$blocknode -> add ( get_string ( 'permissions' , 'role' ), $url , self :: TYPE_SETTING );
}
// Check role permissions
if ( has_any_capability ( array ( 'moodle/role:assign' , 'moodle/role:safeoverride' , 'moodle/role:override' , 'moodle/role:assign' ), $this -> context )) {
$url = new moodle_url ( '/' . $CFG -> admin . '/roles/check.php' , array ( 'contextid' => $this -> context -> id ));
$blocknode -> add ( get_string ( 'checkpermissions' , 'role' ), $url , self :: TYPE_SETTING );
}
2010-04-19 06:30:30 +00:00
return $blocknode ;
2010-03-22 03:04:00 +00:00
}
/**
* Loads category specific settings in the navigation
*
2010-04-19 06:30:30 +00:00
* @ return navigation_node
2010-03-22 03:04:00 +00:00
*/
protected function load_category_settings () {
global $CFG ;
2010-04-21 02:43:02 +00:00
$categorynode = $this -> add ( print_context_name ( $this -> context ));
$categorynode -> force_open ();
2010-03-22 03:04:00 +00:00
2010-11-26 06:07:46 +00:00
if ( has_any_capability ( array ( 'moodle/category:manage' , 'moodle/course:create' ), $this -> context )) {
2010-11-22 05:31:46 +00:00
$url = new moodle_url ( '/course/category.php' , array ( 'id' => $this -> context -> instanceid , 'sesskey' => sesskey ()));
if ( $this -> page -> user_is_editing ()) {
$url -> param ( 'categoryedit' , '0' );
$editstring = get_string ( 'turneditingoff' );
} else {
$url -> param ( 'categoryedit' , '1' );
$editstring = get_string ( 'turneditingon' );
}
$categorynode -> add ( $editstring , $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/edit' , '' ));
}
2010-03-22 03:04:00 +00:00
if ( $this -> page -> user_is_editing () && has_capability ( 'moodle/category:manage' , $this -> context )) {
2010-11-22 05:31:46 +00:00
$editurl = new moodle_url ( '/course/editcategory.php' , array ( 'id' => $this -> context -> instanceid ));
$categorynode -> add ( get_string ( 'editcategorythis' ), $editurl , self :: TYPE_SETTING , null , 'edit' , new pix_icon ( 'i/edit' , '' ));
$addsubcaturl = new moodle_url ( '/course/editcategory.php' , array ( 'parent' => $this -> context -> instanceid ));
$categorynode -> add ( get_string ( 'addsubcategory' ), $addsubcaturl , self :: TYPE_SETTING , null , 'addsubcat' , new pix_icon ( 'i/withsubcat' , '' ));
2010-03-22 03:04:00 +00:00
}
// Assign local roles
2010-11-11 08:58:46 +00:00
if ( has_capability ( 'moodle/role:assign' , $this -> context )) {
$assignurl = new moodle_url ( '/' . $CFG -> admin . '/roles/assign.php' , array ( 'contextid' => $this -> context -> id ));
2010-11-22 05:31:46 +00:00
$categorynode -> add ( get_string ( 'assignroles' , 'role' ), $assignurl , self :: TYPE_SETTING , null , 'roles' , new pix_icon ( 'i/roles' , '' ));
2010-11-11 08:58:46 +00:00
}
2010-03-22 03:04:00 +00:00
// Override roles
if ( has_capability ( 'moodle/role:review' , $this -> context ) or count ( get_overridable_roles ( $this -> context )) > 0 ) {
$url = new moodle_url ( '/' . $CFG -> admin . '/roles/permissions.php' , array ( 'contextid' => $this -> context -> id ));
2010-11-22 05:31:46 +00:00
$categorynode -> add ( get_string ( 'permissions' , 'role' ), $url , self :: TYPE_SETTING , null , 'permissions' , new pix_icon ( 'i/permissions' , '' ));
2010-03-22 03:04:00 +00:00
}
// Check role permissions
if ( has_any_capability ( array ( 'moodle/role:assign' , 'moodle/role:safeoverride' , 'moodle/role:override' , 'moodle/role:assign' ), $this -> context )) {
$url = new moodle_url ( '/' . $CFG -> admin . '/roles/check.php' , array ( 'contextid' => $this -> context -> id ));
2010-11-22 05:31:46 +00:00
$categorynode -> add ( get_string ( 'checkpermissions' , 'role' ), $url , self :: TYPE_SETTING , null , 'checkpermissions' , new pix_icon ( 'i/checkpermissions' , '' ));
2010-04-21 02:43:02 +00:00
}
2010-08-17 13:05:33 +00:00
// Cohorts
if ( has_capability ( 'moodle/cohort:manage' , $this -> context ) or has_capability ( 'moodle/cohort:view' , $this -> context )) {
2010-11-22 05:31:46 +00:00
$categorynode -> add ( get_string ( 'cohorts' , 'cohort' ), new moodle_url ( '/cohort/index.php' , array ( 'contextid' => $this -> context -> id )), self :: TYPE_SETTING , null , 'cohort' , new pix_icon ( 'i/cohort' , '' ));
2010-08-17 13:05:33 +00:00
}
2010-04-21 02:43:02 +00:00
// Manage filters
if ( has_capability ( 'moodle/filter:manage' , $this -> context ) && count ( filter_get_available_in_context ( $this -> context )) > 0 ) {
$url = new moodle_url ( '/filter/manage.php' , array ( 'contextid' => $this -> context -> id ));
2010-11-22 05:31:46 +00:00
$categorynode -> add ( get_string ( 'filters' , 'admin' ), $url , self :: TYPE_SETTING , null , 'filters' , new pix_icon ( 'i/filter' , '' ));
2010-03-22 03:04:00 +00:00
}
2010-04-21 02:43:02 +00:00
return $categorynode ;
2010-03-22 03:04:00 +00:00
}
2009-08-28 08:47:31 +00:00
/**
* Determine whether the user is assuming another role
*
* This function checks to see if the user is assuming another role by means of
* role switching . In doing this we compare each RSW key ( context path ) against
* the current context path . This ensures that we can provide the switching
* options against both the course and any page shown under the course .
*
* @ return bool | int The role ( int ) if the user is in another role , false otherwise
*/
protected function in_alternative_role () {
global $USER ;
if ( ! empty ( $USER -> access [ 'rsw' ]) && is_array ( $USER -> access [ 'rsw' ])) {
if ( ! empty ( $this -> page -> context ) && ! empty ( $USER -> access [ 'rsw' ][ $this -> page -> context -> path ])) {
return $USER -> access [ 'rsw' ][ $this -> page -> context -> path ];
}
foreach ( $USER -> access [ 'rsw' ] as $key => $role ) {
if ( strpos ( $this -> context -> path , $key ) === 0 ) {
return $role ;
}
}
}
return false ;
}
/**
2009-09-09 04:21:20 +00:00
* This function loads all of the front page settings into the settings navigation .
* This function is called when the user is on the front page , or $COURSE == $SITE
2010-04-19 06:30:30 +00:00
* @ return navigation_node
2009-08-28 08:47:31 +00:00
*/
2010-03-22 03:04:00 +00:00
protected function load_front_page_settings ( $forceopen = false ) {
global $SITE , $CFG ;
2009-08-28 08:47:31 +00:00
2010-03-22 03:04:00 +00:00
$course = clone ( $SITE );
2010-03-31 07:41:31 +00:00
$coursecontext = get_context_instance ( CONTEXT_COURSE , $course -> id ); // Course context
2009-08-28 08:47:31 +00:00
2010-04-19 06:30:30 +00:00
$frontpage = $this -> add ( get_string ( 'frontpagesettings' ), null , self :: TYPE_SETTING , null , 'frontpage' );
if ( $forceopen ) {
$frontpage -> force_open ();
}
2010-03-22 03:04:00 +00:00
$frontpage -> id = 'frontpagesettings' ;
2010-02-18 05:57:20 +00:00
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/course:update' , $coursecontext )) {
2009-08-28 08:47:31 +00:00
// Add the turn on/off settings
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/course/view.php' , array ( 'id' => $course -> id , 'sesskey' => sesskey ()));
2009-08-28 08:47:31 +00:00
if ( $this -> page -> user_is_editing ()) {
$url -> param ( 'edit' , 'off' );
$editstring = get_string ( 'turneditingoff' );
} else {
$url -> param ( 'edit' , 'on' );
$editstring = get_string ( 'turneditingon' );
}
2010-02-18 05:57:20 +00:00
$frontpage -> add ( $editstring , $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/edit' , '' ));
2009-08-28 08:47:31 +00:00
// Add the course settings link
2010-01-16 15:39:56 +00:00
$url = new moodle_url ( '/admin/settings.php' , array ( 'section' => 'frontpagesettings' ));
2010-07-09 08:20:39 +00:00
$frontpage -> add ( get_string ( 'editsettings' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/settings' , '' ));
2009-08-28 08:47:31 +00:00
}
2009-09-09 04:21:20 +00:00
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
// add enrol nodes
enrol_add_course_navigation ( $frontpage , $course );
// Manage filters
if ( has_capability ( 'moodle/filter:manage' , $coursecontext ) && count ( filter_get_available_in_context ( $coursecontext )) > 0 ) {
$url = new moodle_url ( '/filter/manage.php' , array ( 'contextid' => $coursecontext -> id ));
$frontpage -> add ( get_string ( 'filters' , 'admin' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/filter' , '' ));
2010-03-22 03:04:00 +00:00
}
// Backup this course
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/backup:backupcourse' , $coursecontext )) {
2010-03-22 03:04:00 +00:00
$url = new moodle_url ( '/backup/backup.php' , array ( 'id' => $course -> id ));
$frontpage -> add ( get_string ( 'backup' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/backup' , '' ));
}
// Restore to this course
2010-03-31 07:41:31 +00:00
if ( has_capability ( 'moodle/restore:restorecourse' , $coursecontext )) {
2010-08-24 03:52:52 +00:00
$url = new moodle_url ( '/backup/restorefile.php' , array ( 'contextid' => $coursecontext -> id ));
2010-03-22 03:04:00 +00:00
$frontpage -> add ( get_string ( 'restore' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/restore' , '' ));
}
// Manage questions
$questioncaps = array ( 'moodle/question:add' ,
'moodle/question:editmine' ,
'moodle/question:editall' ,
'moodle/question:viewmine' ,
'moodle/question:viewall' ,
'moodle/question:movemine' ,
'moodle/question:moveall' );
if ( has_any_capability ( $questioncaps , $this -> context )) {
$questionlink = $CFG -> wwwroot . '/question/edit.php' ;
} else if ( has_capability ( 'moodle/question:managecategory' , $this -> context )) {
$questionlink = $CFG -> wwwroot . '/question/category.php' ;
}
if ( isset ( $questionlink )) {
$url = new moodle_url ( $questionlink , array ( 'courseid' => $course -> id ));
$frontpage -> add ( get_string ( 'questions' , 'quiz' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/questions' , '' ));
}
// Manage files
2010-09-03 19:14:33 +00:00
if ( $course -> legacyfiles == 2 and has_capability ( 'moodle/course:managefiles' , $this -> context )) {
2010-08-02 13:33:19 +00:00
//hiden in new installs
2010-09-03 19:14:33 +00:00
$url = new moodle_url ( '/files/index.php' , array ( 'contextid' => $coursecontext -> id , 'itemid' => 0 , 'component' => 'course' , 'filearea' => 'legacy' ));
2010-08-02 13:33:19 +00:00
$frontpage -> add ( get_string ( 'sitelegacyfiles' ), $url , self :: TYPE_SETTING , null , null , new pix_icon ( 'i/files' , '' ));
2010-03-22 03:04:00 +00:00
}
2010-04-19 06:30:30 +00:00
return $frontpage ;
2009-08-28 08:47:31 +00:00
}
2009-10-12 05:39:32 +00:00
/**
* This function marks the cache as volatile so it is cleared during shutdown
*/
public function clear_cache () {
$this -> cache -> volatile ();
}
2009-08-28 08:47:31 +00:00
}
/**
* Simple class used to output a navigation branch in XML
*
* @ package moodlecore
2009-10-19 03:29:48 +00:00
* @ subpackage navigation
2009-08-28 08:47:31 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
2010-02-18 05:57:20 +00:00
class navigation_json {
2009-08-28 08:47:31 +00:00
/** @var array */
protected $nodetype = array ( 'node' , 'branch' );
/** @var array */
protected $expandable = array ();
/**
* Turns a branch and all of its children into XML
*
* @ param navigation_node $branch
* @ return string XML string
*/
public function convert ( $branch ) {
$xml = $this -> convert_child ( $branch );
return $xml ;
}
/**
* Set the expandable items in the array so that we have enough information
* to attach AJAX events
2010-04-19 06:30:30 +00:00
* @ param array $expandable
2009-08-28 08:47:31 +00:00
*/
public function set_expandable ( $expandable ) {
foreach ( $expandable as $node ) {
2010-12-23 11:21:07 +08:00
$this -> expandable [ $node [ 'key' ] . ':' . $node [ 'type' ]] = $node ;
2009-08-28 08:47:31 +00:00
}
}
/**
* Recusively converts a child node and its children to XML for output
*
* @ param navigation_node $child The child to convert
* @ param int $depth Pointlessly used to track the depth of the XML structure
2010-04-19 06:30:30 +00:00
* @ return string JSON
2009-08-28 08:47:31 +00:00
*/
protected function convert_child ( $child , $depth = 1 ) {
if ( ! $child -> display ) {
return '' ;
}
$attributes = array ();
$attributes [ 'id' ] = $child -> id ;
2010-02-18 05:57:20 +00:00
$attributes [ 'name' ] = $child -> text ;
2009-08-28 08:47:31 +00:00
$attributes [ 'type' ] = $child -> type ;
$attributes [ 'key' ] = $child -> key ;
$attributes [ 'class' ] = $child -> get_css_type ();
2010-02-19 02:24:26 +00:00
if ( $child -> icon instanceof pix_icon ) {
$attributes [ 'icon' ] = array (
'component' => $child -> icon -> component ,
'pix' => $child -> icon -> pix ,
);
foreach ( $child -> icon -> attributes as $key => $value ) {
if ( $key == 'class' ) {
$attributes [ 'icon' ][ 'classes' ] = explode ( ' ' , $value );
} else if ( ! array_key_exists ( $key , $attributes [ 'icon' ])) {
$attributes [ 'icon' ][ $key ] = $value ;
}
}
} else if ( ! empty ( $child -> icon )) {
$attributes [ 'icon' ] = ( string ) $child -> icon ;
}
2009-08-28 08:47:31 +00:00
if ( $child -> forcetitle || $child -> title !== $child -> text ) {
$attributes [ 'title' ] = htmlentities ( $child -> title );
}
2010-05-13 09:57:43 +00:00
if ( array_key_exists ( $child -> key . ':' . $child -> type , $this -> expandable )) {
2009-08-28 08:47:31 +00:00
$attributes [ 'expandable' ] = $child -> key ;
2010-05-13 09:57:43 +00:00
$child -> add_class ( $this -> expandable [ $child -> key . ':' . $child -> type ][ 'id' ]);
2009-08-28 08:47:31 +00:00
}
2009-10-14 09:08:43 +00:00
2009-08-28 08:47:31 +00:00
if ( count ( $child -> classes ) > 0 ) {
$attributes [ 'class' ] .= ' ' . join ( ' ' , $child -> classes );
}
if ( is_string ( $child -> action )) {
$attributes [ 'link' ] = $child -> action ;
} else if ( $child -> action instanceof moodle_url ) {
$attributes [ 'link' ] = $child -> action -> out ();
}
$attributes [ 'hidden' ] = ( $child -> hidden );
2010-04-19 06:30:30 +00:00
$attributes [ 'haschildren' ] = ( $child -> children -> count () > 0 || $child -> type == navigation_node :: TYPE_CATEGORY );
2009-08-28 08:47:31 +00:00
2011-06-27 15:11:28 +08:00
if ( $child -> children -> count () > 0 ) {
2010-02-18 05:57:20 +00:00
$attributes [ 'children' ] = array ();
2009-08-28 08:47:31 +00:00
foreach ( $child -> children as $subchild ) {
2010-02-18 05:57:20 +00:00
$attributes [ 'children' ][] = $this -> convert_child ( $subchild , $depth + 1 );
2009-08-28 08:47:31 +00:00
}
}
2010-02-18 05:57:20 +00:00
if ( $depth > 1 ) {
return $attributes ;
} else {
return json_encode ( $attributes );
}
2009-08-28 08:47:31 +00:00
}
}
/**
* The cache class used by global navigation and settings navigation to cache bits
* and bobs that are used during their generation .
*
* It is basically an easy access point to session with a bit of smarts to make
* sure that the information that is cached is valid still .
*
* Example use :
* < code php >
* if ( ! $cache -> viewdiscussion ()) {
* // Code to do stuff and produce cachable content
* $cache -> viewdiscussion = has_capability ( 'mod/forum:viewdiscussion' , $coursecontext );
* }
* $content = $cache -> viewdiscussion ;
* </ code >
*
* @ package moodlecore
2009-10-19 03:29:48 +00:00
* @ subpackage navigation
2009-08-28 08:47:31 +00:00
* @ copyright 2009 Sam Hemelryk
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
*/
class navigation_cache {
/** @var int */
protected $creation ;
/** @var array */
protected $session ;
/** @var string */
protected $area ;
/** @var int */
protected $timeout ;
/** @var stdClass */
protected $currentcontext ;
/** @var int */
const CACHETIME = 0 ;
/** @var int */
const CACHEUSERID = 1 ;
/** @var int */
const CACHEVALUE = 2 ;
2009-10-12 05:39:32 +00:00
/** @var null|array An array of navigation cache areas to expire on shutdown */
public static $volatilecaches ;
2009-11-01 11:31:16 +00:00
2009-08-28 08:47:31 +00:00
/**
* Contructor for the cache . Requires two arguments
*
* @ param string $area The string to use to segregate this particular cache
* it can either be unique to start a fresh cache or if you want
* to share a cache then make it the string used in the original
* cache
* @ param int $timeout The number of seconds to time the information out after
*/
2011-06-24 16:42:41 +08:00
public function __construct ( $area , $timeout = 1800 ) {
2009-08-28 08:47:31 +00:00
$this -> creation = time ();
$this -> area = $area ;
2011-06-24 16:42:41 +08:00
$this -> timeout = time () - $timeout ;
if ( rand ( 0 , 100 ) === 0 ) {
$this -> garbage_collection ();
2009-08-28 08:47:31 +00:00
}
2011-06-24 16:42:41 +08:00
}
2009-08-28 08:47:31 +00:00
2011-06-24 16:42:41 +08:00
/**
* Used to set up the cache within the SESSION .
*
* This is called for each access and ensure that we don ' t put anything into the session before
* it is required .
*/
protected function ensure_session_cache_initialised () {
global $SESSION ;
if ( empty ( $this -> session )) {
if ( ! isset ( $SESSION -> navcache )) {
$SESSION -> navcache = new stdClass ;
}
if ( ! isset ( $SESSION -> navcache -> { $this -> area })) {
$SESSION -> navcache -> { $this -> area } = array ();
}
$this -> session = & $SESSION -> navcache -> { $this -> area };
2009-08-28 08:47:31 +00:00
}
}
/**
* Magic Method to retrieve something by simply calling using = cache -> key
*
* @ param mixed $key The identifier for the information you want out again
* @ return void | mixed Either void or what ever was put in
*/
public function __get ( $key ) {
if ( ! $this -> cached ( $key )) {
return ;
}
$information = $this -> session [ $key ][ self :: CACHEVALUE ];
return unserialize ( $information );
}
/**
* Magic method that simply uses { @ link set ();} to store something in the cache
*
* @ param string | int $key
* @ param mixed $information
*/
public function __set ( $key , $information ) {
$this -> set ( $key , $information );
}
2009-10-12 05:39:32 +00:00
2009-08-28 08:47:31 +00:00
/**
* Sets some information against the cache ( session ) for later retrieval
*
* @ param string | int $key
* @ param mixed $information
*/
public function set ( $key , $information ) {
global $USER ;
2011-06-24 16:42:41 +08:00
$this -> ensure_session_cache_initialised ();
2009-08-28 08:47:31 +00:00
$information = serialize ( $information );
$this -> session [ $key ] = array ( self :: CACHETIME => time (), self :: CACHEUSERID => $USER -> id , self :: CACHEVALUE => $information );
}
/**
* Check the existence of the identifier in the cache
*
* @ param string | int $key
* @ return bool
*/
public function cached ( $key ) {
global $USER ;
2011-06-24 16:42:41 +08:00
$this -> ensure_session_cache_initialised ();
2009-08-28 08:47:31 +00:00
if ( ! array_key_exists ( $key , $this -> session ) || ! is_array ( $this -> session [ $key ]) || $this -> session [ $key ][ self :: CACHEUSERID ] != $USER -> id || $this -> session [ $key ][ self :: CACHETIME ] < $this -> timeout ) {
return false ;
}
return true ;
}
2009-09-08 08:49:12 +00:00
/**
* Compare something to it ' s equivilant in the cache
*
* @ param string $key
* @ param mixed $value
* @ param bool $serialise Whether to serialise the value before comparison
* this should only be set to false if the value is already
* serialised
* @ return bool If the value is the same false if it is not set or doesn ' t match
*/
2011-06-24 16:42:41 +08:00
public function compare ( $key , $value , $serialise = true ) {
2009-09-08 08:49:12 +00:00
if ( $this -> cached ( $key )) {
if ( $serialise ) {
$value = serialize ( $value );
}
if ( $this -> session [ $key ][ self :: CACHEVALUE ] === $value ) {
return true ;
}
}
return false ;
}
2009-08-28 08:47:31 +00:00
/**
2009-10-19 03:29:48 +00:00
* Wipes the entire cache , good to force regeneration
2009-08-28 08:47:31 +00:00
*/
public function clear () {
2011-06-24 16:42:41 +08:00
global $SESSION ;
unset ( $SESSION -> navcache );
$this -> session = null ;
2009-08-28 08:47:31 +00:00
}
/**
* Checks all cache entries and removes any that have expired , good ole cleanup
*/
protected function garbage_collection () {
2011-06-24 16:42:41 +08:00
if ( empty ( $this -> session )) {
return true ;
}
2009-08-28 08:47:31 +00:00
foreach ( $this -> session as $key => $cachedinfo ) {
if ( is_array ( $cachedinfo ) && $cachedinfo [ self :: CACHETIME ] < $this -> timeout ) {
unset ( $this -> session [ $key ]);
}
}
}
2009-10-12 05:39:32 +00:00
/**
* Marks the cache as being volatile ( likely to change )
*
* Any caches marked as volatile will be destroyed at the on shutdown by
* { @ link navigation_node :: destroy_volatile_caches ()} which is registered
* as a shutdown function if any caches are marked as volatile .
*
* @ param bool $setting True to destroy the cache false not too
*/
public function volatile ( $setting = true ) {
if ( self :: $volatilecaches === null ) {
self :: $volatilecaches = array ();
register_shutdown_function ( array ( 'navigation_cache' , 'destroy_volatile_caches' ));
}
if ( $setting ) {
self :: $volatilecaches [ $this -> area ] = $this -> area ;
} else if ( array_key_exists ( $this -> area , self :: $volatilecaches )) {
unset ( self :: $volatilecaches [ $this -> area ]);
}
}
/**
* Destroys all caches marked as volatile
*
* This function is static and works in conjunction with the static volatilecaches
* property of navigation cache .
* Because this function is static it manually resets the cached areas back to an
* empty array .
*/
public static function destroy_volatile_caches () {
global $SESSION ;
if ( is_array ( self :: $volatilecaches ) && count ( self :: $volatilecaches ) > 0 ) {
foreach ( self :: $volatilecaches as $area ) {
$SESSION -> navcache -> { $area } = array ();
}
2010-09-15 08:32:15 +00:00
} else {
$SESSION -> navcache = new stdClass ;
2009-10-12 05:39:32 +00:00
}
}
2010-05-14 02:55:46 +00:00
}