# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/admin/settings/appearance.php
--- moodle/admin/settings/appearance.php Base (1.58)
+++ moodle/admin/settings/appearance.php Locally Modified (Based On 1.58)
@@ -77,6 +77,7 @@
     $temp = new admin_settingpage('navigation', get_string('navigation'));
     $temp->add(new admin_setting_configcheckbox('navshowcategories', get_string('navshowcategories', 'admin'), get_string('confignavshowcategories', 'admin'), 1));
     $temp->add(new admin_setting_configcheckbox('navshowallcourses', get_string('navshowallcourses', 'admin'), get_string('confignavshowallcourses', 'admin'), 0));
+    $temp->add(new admin_setting_configtext('navcourselimit',get_string('navcourselimit','admin'),get_string('confignavcourselimit', 'admin'),20,PARAM_INT));
     $ADMIN->add('appearance', $temp);
 
 /* TODO: reimplement editor settings and preferences, editors are now full plugins ;-)
Index: moodle/admin/settings/users.php
--- moodle/admin/settings/users.php Base (1.56)
+++ moodle/admin/settings/users.php Locally Modified (Based On 1.56)
@@ -188,6 +188,14 @@
                 get_string('extrauserselectorfields', 'admin'), get_string('configextrauserselectorfields', 'admin'), array('email' => '1'),
                 array('email' => get_string('email'), 'idnumber' => get_string('idnumber'), 'username' => get_string('username'), )));
     }
+
+    $choices = array(
+        HOMEPAGE_SITE => get_string('site'),
+        HOMEPAGE_MY => get_string('mymoodle', 'admin'),
+        HOMEPAGE_USER => get_string('userpreference', 'admin')
+    );
+    $temp->add(new admin_setting_configselect('defaulthomepage', get_string('defaulthomepage', 'admin'), get_string('configdefaulthomepage', 'admin'), HOMEPAGE_SITE, $choices));
+
     $ADMIN->add('roles', $temp);
 
     if (is_siteadmin()) {
Index: moodle/blocks/navigation/renderer.php
--- moodle/blocks/navigation/renderer.php Base (1.5)
+++ moodle/blocks/navigation/renderer.php Locally Modified (Based On 1.5)
@@ -26,7 +26,7 @@
             }
             $content = $item->get_content();
             $title = $item->get_title();
-            $isbranch = (empty($expansionlimit) || $item->type != $expansionlimit) && ($item->children->count() > 0 || ($item->nodetype == navigation_node::NODETYPE_BRANCH && $item->children->count()==0 && isloggedin()));
+            $isbranch = ($item->type != $expansionlimit && ($item->children->count() > 0 || ($item->nodetype == navigation_node::NODETYPE_BRANCH && $item->children->count()==0 && (isloggedin() || $item->type <= navigation_node::TYPE_CATEGORY))));
             $hasicon = (!$isbranch && $item->icon instanceof renderable);
 
             if ($hasicon) {
Index: moodle/index.php
--- moodle/index.php Base (1.252)
+++ moodle/index.php Locally Modified (Based On 1.252)
@@ -42,6 +42,9 @@
         user_accesstime_log();
     }
 
+    $PAGE->set_url('/');
+    $PAGE->set_course($SITE);
+
 /// If the site is currently under maintenance, then print a message
     if (!empty($CFG->maintenance_enabled) and !has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
         print_maintenance_message();
@@ -51,13 +54,17 @@
         if (moodle_needs_upgrading()) {
             redirect($CFG->wwwroot .'/'. $CFG->admin .'/index.php');
         }
-    } else if (!empty($CFG->mymoodleredirect)) {    // Redirect logged-in users to My Moodle overview if required
-        if (isloggedin() && !isguestuser()) {
-            redirect($CFG->wwwroot .'/my/index.php');
+    } else if (get_home_page() != HOMEPAGE_SITE) {
+        // Redirect logged-in users to My Moodle overview if required
+        if (optional_param('setdefaulthome', false, PARAM_BOOL)) {
+            set_user_preference('user_home_page_preference', HOMEPAGE_SITE);
+        } else if ($CFG->defaulthomepage == HOMEPAGE_MY && optional_param('redirect', true, PARAM_BOOL)) {
+            redirect($CFG->wwwroot .'/my/');
+        } else if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_USER) {
+            $PAGE->settingsnav->get('usercurrentsettings')->add(get_string('makethismyhome'), new moodle_url('/', array('setdefaulthome'=>true)), navigation_node::TYPE_SETTING);
         }
     }
 
-
     if (get_moodle_cookie() == '') {
         set_moodle_cookie('nobody');   // To help search for cookies on login page
     }
@@ -67,10 +74,7 @@
     }
 
     $PAGE->set_pagetype('site-index');
-    $PAGE->set_course($SITE);
-
     $PAGE->set_other_editing_capability('moodle/course:manageactivities');
-    $PAGE->set_url('/');
     $PAGE->set_docs_path('');
     $PAGE->set_pagelayout('frontpage');
     $editing = $PAGE->user_is_editing();
Index: moodle/lang/en/admin.php
--- moodle/lang/en/admin.php Base (1.90)
+++ moodle/lang/en/admin.php Locally Modified (Based On 1.90)
@@ -173,6 +173,7 @@
 $string['configdebugvalidators'] = 'Enable if you want to have links to external validator servers in page footer. You may need to create new user with username <em>w3cvalidator</em>, and enable guest access. These changes may allow unauthorized access to server, do not enable on production sites!';
 $string['configdefaultallowedmodules'] = 'For the courses which fall into the above category, which modules do you want to allow by default <b>when the course is created</b>?';
 $string['configdefaultcourseroleid'] = 'Users who enrol in a course will be automatically assigned this role.';
+$string['configdefaulthomepage'] = 'This determines the home page for logged in users';
 $string['configdefaultrequestcategory'] = 'Courses requested by users will be automatically placed in this category.';
 $string['configdefaultrequestedcategory'] = 'Default category to put courses that were requested into, if they\'re approved.';
 $string['configdefaultuserroleid'] = 'All logged in users will be given the capabilities of the role you specify here, at the site level, in ADDITION to any other roles they may have been given.  The default is the Authenticated user role (or Guest role in older versions).  Note that this will not conflict with other roles they have, it just ensures that all users have capabilities that are not assignable at the course level (eg post blog entries, manage own calendar, etc).';
@@ -265,6 +266,7 @@
 $string['configmycoursesperpage'] = 'Maximum number of courses to display in any list of a user\'s own courses';
 $string['configmymoodleredirect'] = 'This setting forces redirects to /my on login for non-admins and replaces the top level site navigation with /my';
 $string['configmypagelocked'] = 'This setting prevents the default page from being edited by any non-admins';
+$string['confignavcourselimit'] = 'Limits the number of courses shown to the user when they are either not logged in or are not enrolled in any courses.';
 $string['confignavshowallcourses'] = 'Setting this ensures that all courses a user is registered in are shown on the navigation at all times. By default once a user browses to a course only that course is shown on the navigation.';
 $string['confignavshowcategories'] = 'Show course categories in the navigation bar and navigation blocks';
 $string['confignodefaultuserrolelists'] = 'This setting prevents all users from being returned from the database from deprecated calls of get_course_user, etc., for the site course if the default role provides that access. Check this, if you suffer a performance hit.';
@@ -420,6 +422,7 @@
 $string['debugvalidators'] = 'Show validator links';
 $string['defaultallowedmodules'] = 'Default allowed modules';
 $string['defaultcourseroleid'] = 'Default role for users in a course';
+$string['defaulthomepage'] = 'Default home page for users';
 $string['defaulthtmleditor'] = 'Default HTML editor';
 $string['defaultrequestcategory'] = 'Default category for course requests';
 $string['defaultsettinginfo'] = 'Default: {$a}';
@@ -691,6 +694,7 @@
 $string['mysql416bypassed'] = 'However, if your site is using iso-8859-1 (latin) languages ONLY, you may continue using your currently installed MySQL 4.1.12 (or higher).';
 $string['mysql416required'] = 'MySQL 4.1.16 is the minimum version required for Moodle 1.6 in order to guarantee that all data can be converted to UTF-8 in the future.';
 $string['navigationupgrade'] = 'This upgrade introduces two new navigation blocks that will replace these blocks: Administration, Courses, Activities and Participants.  If you had set any special permissions on those blocks you should check to make sure everything is behaving as you want it.';
+$string['navcourselimit'] = 'Course limit';
 $string['navshowallcourses'] = 'Show all users courses';
 $string['navshowcategories'] = 'Show course categories';
 $string['nobookmarksforuser'] = 'You do not have any bookmarks.';
@@ -974,6 +978,7 @@
 $string['userbulk'] = 'Bulk user actions';
 $string['userdeleted'] = 'User deleted';
 $string['userlist'] = 'Browse list of users';
+$string['userpreference'] = 'User preference';
 $string['userpolicies'] = 'User policies';
 $string['userrenamed'] = 'User renamed';
 $string['users'] = 'Users';
Index: moodle/lang/en/moodle.php
--- moodle/lang/en/moodle.php Base (1.517)
+++ moodle/lang/en/moodle.php Locally Modified (Based On 1.517)
@@ -1025,6 +1025,7 @@
 $string['mailteachers'] = 'Inform teachers';
 $string['makeafolder'] = 'Make a folder';
 $string['makeeditable'] = 'If you make \'{$a}\' editable by the web server process (eg apache) then you could edit this file directly from this page';
+$string['makethismyhome'] = 'Make this my default home page';
 $string['manageblocks'] = 'Blocks';
 $string['managecourses'] = 'Manage courses';
 $string['managedatabase'] = 'Database';
@@ -1578,8 +1579,10 @@
 $string['siteerrors'] = 'Site errors';
 $string['sitefiles'] = 'Site files';
 $string['sitefilesused'] = 'Site files used in this course';
+$string['sitehome'] = 'Site home';
 $string['sitelogs'] = 'Site logs';
 $string['sitenews'] = 'Site news';
+$string['sitepages'] = 'Site pages';
 $string['sitepartlist'] = 'You do not have the required permissions to view the participants list';
 $string['sitepartlist0'] = 'You must be a site teacher to be allowed to see the site participants list';
 $string['sitepartlist1'] = 'You must be a teacher to be allowed to see the site participants list';
Index: moodle/lib/ajax/getnavbranch.php
--- moodle/lib/ajax/getnavbranch.php Base (1.9)
+++ moodle/lib/ajax/getnavbranch.php Locally Modified (Based On 1.9)
@@ -40,6 +40,8 @@
     // This identifies the block instance requesting AJAX extension
     $instanceid = optional_param('instance', null, PARAM_INT);
 
+    $PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
+
     // Create a global nav object
     $navigation = new global_navigation_for_ajax($PAGE);
 
@@ -68,9 +70,13 @@
     // Create a navigation object to use, we can't guarantee PAGE will be complete
 
     $expandable = $navigation->initialise($branchtype, $branchid);
+    if (!isloggedin() || isguestuser()) {
+        $navigation->set_expansion_limit(navigation_node::TYPE_COURSE);
+    } else {
     if (isset($block) && !empty($block->config->expansionlimit)) {
         $navigation->set_expansion_limit($block->config->expansionlimit);
     }
+    }
     if (isset($block)) {
         $block->trim($navigation, $trimmode, $trimlength, ceil($trimlength/2));
     }
Index: moodle/lib/moodlelib.php
--- moodle/lib/moodlelib.php Base (1.1369)
+++ moodle/lib/moodlelib.php Locally Modified (Based On 1.1369)
@@ -394,6 +394,18 @@
  */
 define('EXTERNAL_TOKEN_EMBEDDED', 1);
 
+/**
+ * The home page should be the site home
+ */
+define('HOMEPAGE_SITE', 0);
+/**
+ * The home page should be the users my page
+ */
+define('HOMEPAGE_MY', 1);
+/**
+ * The home page can be chosen by the user
+ */
+define('HOMEPAGE_USER', 2);
 
 /// PARAMETER HANDLING ////////////////////////////////////////////////////
 
@@ -9638,3 +9650,21 @@
     }
     return $mnetjumps[$user->mnethostid];
 }
+
+/**
+ * Gets the homepage to use for the current user
+ *
+ * @return int One of HOMEPAGE_*
+ */
+function get_home_page() {
+    global $CFG;
+
+    if (isloggedin() && !isguestuser() && !empty($CFG->defaulthomepage)) {
+        if ($CFG->defaulthomepage == HOMEPAGE_MY) {
+            return HOMEPAGE_MY;
+        } else {
+            return (int)get_user_preferences('user_home_page_preference', HOMEPAGE_MY);
+        }
+    }
+    return HOMEPAGE_SITE;
+}
Index: moodle/lib/navigationlib.php
--- moodle/lib/navigationlib.php Base (1.117)
+++ moodle/lib/navigationlib.php Locally Modified (Based On 1.117)
@@ -511,10 +511,14 @@
      * @param array $expandable An array by reference to populate with expandable nodes.
      */
     public function find_expandable(array &$expandable) {
-        if (!isloggedin()) {
+        $isloggedin = (isloggedin() && !isguestuser());
+        if (!$isloggedin && $this->type > self::TYPE_CATEGORY) {
             return;
         }
         foreach ($this->children as &$child) {
+            if (!$isloggedin && $child->type > self::TYPE_CATEGORY) {
+                continue;
+            }
             if ($child->nodetype == self::NODETYPE_BRANCH && $child->children->count()==0 && $child->display) {
                 $child->id = 'expandable_branch_'.(count($expandable)+1);
                 $this->add_class('canexpand');
@@ -524,6 +528,12 @@
         }
     }
 
+    /**
+     * Finds all nodes of a given type (recursive)
+     *
+     * @param int $type On of navigation_node::TYPE_*
+     * @return array
+     */
     public function find_all_of_type($type) {
         $nodes = $this->children->type($type);
         foreach ($this->children as &$node) {
@@ -765,23 +775,31 @@
      * @param moodle_page $page The page this navigation object belongs to
      */
     public function __construct(moodle_page $page) {
-        global $SITE, $USER;
+        global $CFG, $SITE, $USER;
 
         if (during_initial_install()) {
             return;
         }
 
-        // Use the parents consturctor.... good good reuse
+        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/')
         );
-        if (!isloggedin()) {
-            $properties['text'] = get_string('home');
-            $properties['action'] = new moodle_url('/');
         }
+
+        // Use the parents consturctor.... good good reuse
         parent::__construct($properties);
 
         // Initalise and set defaults
@@ -809,7 +827,7 @@
      * @return bool
      */
     public function initialise() {
-        global $CFG, $SITE, $USER;
+        global $CFG, $SITE, $USER, $DB;
         // Check if it has alread been initialised
         if ($this->initialised || during_initial_install()) {
             return true;
@@ -823,6 +841,17 @@
         // courses:     Additional courses are added here.
         // users:       Other users information loaded here.
         $this->rootnodes = array();
+        if (get_home_page() == HOMEPAGE_SITE) {
+            // The home element should be the my moolde because the root element is the site
+            $this->rootnodes['home']      = $this->add(get_string('myhome'), new moodle_url('/my/'), self::TYPE_SETTING, null, 'home');
+        } else {
+            // The home element should be the site because the root node is my moodle
+            $this->rootnodes['home']      = $this->add(get_string('sitehome'), new moodle_url('/'), self::TYPE_SETTING, null, 'home');
+            if ($CFG->defaulthomepage == HOMEPAGE_MY) {
+                // We need to stop automatic redirection
+                $this->rootnodes['home']->action->param('redirect', '0');
+            }
+        }
         $this->rootnodes['site']      = $this->add_course($SITE);
         $this->rootnodes['myprofile']   = $this->add(get_string('myprofile'), null, self::TYPE_USER, null, 'myprofile');
         $this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), null, self::TYPE_ROOTNODE, null, 'mycourses');
@@ -830,25 +859,38 @@
         $this->rootnodes['users']     = $this->add(get_string('users'), null, self::TYPE_ROOTNODE, null, 'users');
 
         // Fetch all of the users courses.
-        $this->mycourses = get_my_courses($USER->id);
+        $limit = 20;
+        if (!empty($CFG->navcourselimit)) {
+            $limit = $CFG->navcourselimit;
+        }
+
+        $this->mycourses = get_my_courses($USER->id, 'visible DESC,sortorder ASC', null, false, $limit);
         // Check if any courses were returned.
         if (count($this->mycourses) > 0) {
             // Add all of the users courses to the navigation
             foreach ($this->mycourses as &$course) {
               $course->coursenode = $this->add_course($course);
             }
-        } else {
-            // The user had no specific courses! they could be no logged in, guest
-            // or admin so load all courses instead.
-            $this->load_all_courses();
         }
 
+        $showallcourses = (count($this->mycourses) == 0 || !empty($CFG->navshowallcourses));
+        $showcategories = ($showallcourses && !empty($CFG->navshowcategories));
+
+        if ($showcategories) {
+            // Load all categories (ensures we get the base categories)
+            $this->load_all_categories();
+        }
+
         // Next load context specific content into the navigation
         switch ($this->page->context->contextlevel) {
             case CONTEXT_SYSTEM :
             case CONTEXT_COURSECAT :
                 // Load the front page course navigation
                 $this->load_course($SITE);
+                if ($showallcourses) {
+                    // Load all courses
+                    $this->load_all_courses();
+                }
                 break;
             case CONTEXT_BLOCK :
             case CONTEXT_COURSE :
@@ -927,7 +969,8 @@
 
         // Remove any empty root nodes
         foreach ($this->rootnodes as $node) {
-            if (!$node->has_children()) {
+            // Dont remove the home node
+            if ($node->key !== 'home' && !$node->has_children()) {
                 $node->remove();
             }
         }
@@ -979,18 +1022,39 @@
     /**
      * Loads of the the courses in Moodle into the navigation.
      *
+     * @param string|array $categoryids Either a string or array of category ids to load courses for
      * @return array An array of navigation_node
      */
-    protected function load_all_courses() {
-        global $DB, $USER;
+    protected function load_all_courses($categoryids=null) {
+        global $CFG, $DB, $USER;
+
+        if ($categoryids !== null) {
+            if (is_array($categoryids)) {
+                list ($select, $params) = $DB->get_in_or_equal($categoryids);
+            } else {
+                $select = '= ?';
+                $params = array($categoryids);
+            }
+            array_unshift($params, SITEID);
+            $select = ' AND c.category '.$select;
+        } else {
+            $params = array(SITEID);
+            $select = '';
+        }
+        
         list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
         $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 != :siteid
+                WHERE c.id <> ?$select
                 ORDER BY c.sortorder ASC";
-        $courses = $DB->get_records_sql($sql, array('siteid'=>SITEID));
+        $limit = 20;
+        if (!empty($CFG->navcourselimit)) {
+            $limit = $CFG->navcourselimit;
+        }
+        $courses = $DB->get_records_sql($sql, $params, 0, $limit);
+
         $coursenodes = array();
         foreach ($courses as $course) {
             context_instance_preload($course);
@@ -1000,6 +1064,85 @@
     }
 
     /**
+     * Loads all categories (top level or if an id is specified for that category)
+     *
+     * @param int $categoryid
+     * @return void
+     */
+    protected function load_all_categories($categoryid=null) {
+        global $DB;
+        if ($categoryid == null)  {
+            $categories = $DB->get_records('course_categories', array('parent'=>'0'), 'sortorder');
+        } else {
+            $category = $DB->get_record('course_categories', array('id'=>$categoryid), '*', MUST_EXIST);
+            $wantedids = explode('/', trim($category->path, '/'));
+            list($select, $params) = $DB->get_in_or_equal($wantedids);
+            $select = 'id '.$select.' OR parent '.$select;
+            $params = array_merge($params, $params);
+            $categories = $DB->get_records_select('course_categories', $select, $params, 'sortorder');
+        }
+        $structured = array();
+        $categoriestoload = array();
+        foreach ($categories as $category) {
+            if ($category->parent == '0') {
+                $structured[$category->id] = array('category'=>$category, 'children'=>array());
+            } else {
+                if ($category->parent == $categoryid) {
+                    $categoriestoload[] = $category->id;
+                }
+                $parents = array();
+                $id = $category->parent;
+                while ($id != '0') {
+                    $parents[] = $id;
+                    if (!array_key_exists($id, $categories)) {
+                        $categories[$id] = $DB->get_record('course_categories', array('id'=>$id), '*', MUST_EXIST);
+                    }
+                    $id = $categories[$id]->parent;
+                }
+                $parents = array_reverse($parents);
+                $parentref = &$structured[array_shift($parents)];
+                foreach ($parents as $parent) {
+                    if (!array_key_exists($parent, $parentref['children'])) {
+                        $parentref['children'][$parent] = array('category'=>$categories[$parent], 'children'=>array());
+                    }
+                    $parentref = &$parentref['children'][$parent];
+                }
+                if (!array_key_exists($category->id, $parentref['children'])) {
+                    $parentref['children'][$category->id] = array('category'=>$category, 'children'=>array());
+                }
+            }
+        }
+
+        foreach ($structured as $category) {
+            $this->add_category($category, $this->rootnodes['courses']);
+        }
+
+        if ($categoryid !== null && count($wantedids)) {
+            foreach ($wantedids as $catid) {
+                $this->load_all_courses($catid);
+            }
+        }
+    }
+
+    /**
+     * Adds a structured category to the navigation in the correct order/place
+     *
+     * @param object $cat
+     * @param navigation_node $parent 
+     */
+    protected function add_category($cat, navigation_node $parent) {
+        $category = $parent->get($cat['category']->id, navigation_node::TYPE_CATEGORY);
+        if (!$category) {
+            $category = $cat['category'];
+            $url = new moodle_url('/course/category.php', array('id'=>$category->id));
+            $category = $parent->add($category->name, null, self::TYPE_CATEGORY, $category->name, $category->id);
+        }
+        foreach ($cat['children'] as $child) {
+            $this->add_category($child, $category);
+        }
+    }
+
+    /**
      * Loads the given course into the navigation
      *
      * @param stdClass $course
@@ -1363,23 +1506,6 @@
         return true;
     }
 
-    private function add_my_pages($node, $subpages, $baseurl, $defaultname, $baseargs = array()) {
-        global $CFG;
-
-        foreach($subpages as $page) {
-            $name = $page->name;
-            $params = $baseargs;
-            if ($page->name == '__default') {
-                $name = $defaultname;
-            } else {
-                $params['pageid'] = $page->id;
-            }
-            $url = new moodle_url($baseurl, $params);
-
-            $node->add($name, $url, null, null, null, null, false);
-        }
-    }
-
     /**
      * This method simply checks to see if a given module can extend the navigation.
      *
@@ -1420,30 +1546,91 @@
      * @param stdClass $course
      * @return navigation_node
      */
-    public function add_course(stdClass $course) {
-        if (array_key_exists($course->id, $this->addedcourses)) {
-            return $this->addedcourses[$course->id];
-        }
-
+    public function add_course(stdClass $course, $forcegeneric = false) {
+        global $CFG;
         $canviewhidden = has_capability('moodle/course:viewhiddencourses', $this->page->context);
         if ($course->id !== SITEID && !$canviewhidden && (!$course->visible || !course_parent_visible($course))) {
             return false;
         }
 
-        if ($course->id == SITEID) {
+        $issite = ($course->id == SITEID);
+        $ismycourse = (array_key_exists($course->id, $this->mycourses) && !$forcegeneric);
+        $displaycategories = (!$ismycourse && !$issite && !empty($CFG->navshowcategories));
+
+        if ($issite) {
             $parent = $this;
-            $url = new moodle_url('/');
-        } else if (array_key_exists($course->id, $this->mycourses)) {
+            $url = null;
+            $course->shortname = get_string('sitepages');
+        } else if ($ismycourse) {
             $parent = $this->rootnodes['mycourses'];
             $url = new moodle_url('/course/view.php', array('id'=>$course->id));
         } else {
             $parent = $this->rootnodes['courses'];
             $url = new moodle_url('/course/view.php', array('id'=>$course->id));
         }
+
+        if ($displaycategories) {
+            // We need to load the category structure for this course
+            $categoryfound = false;
+            if (!empty($course->categorypath)) {
+                $categories = explode('/', trim($course->categorypath, '/'));
+                $category = $parent;
+                while ($category && $categoryid = array_shift($categories)) {
+                    $category = $category->get($categoryid, self::TYPE_CATEGORY);
+                }
+                if ($category instanceof navigation_node) {
+                    $parent = $category;
+                    $categoryfound = true;
+                }
+                if (!$categoryfound && $forcegeneric) {
+                    $this->load_all_categories($course->category);
+                    if ($category = $parent->find($course->category, self::TYPE_CATEGORY)) {
+                        $parent = $category;
+                        $categoryfound = true;
+                    }
+                }
+            } else if (!empty($course->category)) {
+                $this->load_all_categories($course->category);
+                if ($category = $parent->find($course->category, self::TYPE_CATEGORY)) {
+                    $parent = $category;
+                    $categoryfound = true;
+                }
+                if (!$categoryfound && !$forcegeneric) {
+                    $this->load_all_categories($course->category);
+                    if ($category = $parent->find($course->category, self::TYPE_CATEGORY)) {
+                        $parent = $category;
+                        $categoryfound = true;
+                    }
+                }
+            }
+        }
+
+        // We found the course... we can return it now :)
+        if ($coursenode = $parent->get($course->id, self::TYPE_COURSE)) {
+            return $coursenode;
+        }
+
         $coursenode = $parent->add($course->shortname, $url, self::TYPE_COURSE, $course->shortname, $course->id);
         $coursenode->nodetype = self::NODETYPE_BRANCH;
         $coursenode->hidden = (!$course->visible);
+        $coursenode->title($course->fullname);
         $this->addedcourses[$course->id] = &$coursenode;
+        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;
+                    }
+                }
+            }
+        }
         return $coursenode;
     }
     /**
@@ -1458,7 +1645,7 @@
     public function add_course_essentials(navigation_node $coursenode, stdClass $course) {
         global $CFG;
 
-        if ($course->id === SITEID) {
+        if ($course->id == SITEID) {
             return $this->add_front_page_course_essentials($coursenode, $course);
         }
 
@@ -1610,8 +1797,9 @@
     /**
      * Constructs the navigation for use in AJAX request
      */
-    public function __construct() {
+    public function __construct($page) {
         global $SITE;
+        $this->page = $page;
         $this->cache = new navigation_cache(NAVIGATION_CACHE_NAME);
         $this->children = new navigation_node_collection();
         $this->rootnodes = array();
@@ -1626,7 +1814,7 @@
      * @return array The expandable nodes
      */
     public function initialise($branchtype, $id) {
-        global $DB, $PAGE;
+        global $CFG, $DB, $PAGE;
 
         if ($this->initialised || during_initial_install()) {
             return $this->expandable;
@@ -1634,6 +1822,17 @@
 
         // Branchtype will be one of navigation_node::TYPE_*
         switch ($branchtype) {
+            case self::TYPE_CATEGORY :
+                $this->load_all_categories($id);
+                $limit = 20;
+                if (!empty($CFG->navcourselimit)) {
+                    $limit = (int)$CFG->navcourselimit;
+                }
+                $courses = $DB->get_records('course', array('category' => $id), 'sortorder','*', 0, $limit);
+                foreach ($courses as $course) {
+                    $this->add_course($course);
+                }
+                break;
             case self::TYPE_COURSE :
                 $course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST);
                 require_course_login($course);
@@ -1677,7 +1876,6 @@
                 throw new Exception('Unknown type');
                 return $this->expandable;
         }
-
         $this->find_expandable($this->expandable);
         return $this->expandable;
     }
@@ -1916,6 +2114,9 @@
     protected $page;
     /** @var string */
     protected $adminsection;
+    /** @var bool */
+    protected $initialised = false;
+
     /**
      * Sets up the object with basic settings and preparse it for use
      * 
@@ -1945,6 +2146,8 @@
 
         if (during_initial_install()) {
             return false;
+        } else if ($this->initialised) {
+            return true;
         }
         $this->id = 'settingsnav';
         $this->context = $this->page->context;
@@ -2007,6 +2210,7 @@
                 $node->remove();
             }
         }
+        $this->initialised = true;
     }
     /**
      * Override the parent function so that we can add preceeding hr's and set a
@@ -3088,7 +3292,7 @@
      */
     public function set_expandable($expandable) {
         foreach ($expandable as $node) {
-            $this->expandable[(string)$node['branchid']] = $node;
+            $this->expandable[$node['branchid'].':'.$node['type']] = $node;
         }
     }
     /**
@@ -3131,9 +3335,9 @@
         if ($child->forcetitle || $child->title !== $child->text) {
             $attributes['title'] = htmlentities($child->title);
         }
-        if (array_key_exists((string)$child->key, $this->expandable)) {
+        if (array_key_exists($child->key.':'.$child->type, $this->expandable)) {
             $attributes['expandable'] = $child->key;
-            $child->add_class($this->expandable[$child->key]['id']);
+            $child->add_class($this->expandable[$child->key.':'.$child->type]['id']);
         }
 
         if (count($child->classes)>0) {
Index: moodle/my/index.php
--- moodle/my/index.php Base (1.48)
+++ moodle/my/index.php Locally Modified (Based On 1.48)
@@ -81,6 +81,14 @@
 $PAGE->set_title($header);
 $PAGE->set_heading($header);
 
+if (get_home_page() != HOMEPAGE_MY) {
+    if (optional_param('setdefaulthome', false, PARAM_BOOL)) {
+        set_user_preference('user_home_page_preference', HOMEPAGE_MY);
+    } else if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_USER) {
+        $PAGE->settingsnav->get('usercurrentsettings')->add(get_string('makethismyhome'), new moodle_url('/my/', array('setdefaulthome'=>true)), navigation_node::TYPE_SETTING);
+    }
+}
+
 // Toggle the editing state and switches
 if ($PAGE->user_allowed_editing()) {
     if ($edit !== null) {             // Editing state was specified
