Added support for course format and local course settings pages

From: Brandon Turner <brandont@thinkwell.com>

The course administration navigation now allows multiple settings pages.
Course formats and local plugins can add a settings page to the course
administration navigation by implementing a
  xxx_extend_course_settings
function in their lib.php file.  The function should add a navigation node
for their settings page, for example:

    function mylocalplugin_extend_course_settings($course, $settingsnode) {
        $url = new moodle_url('/local/mylocalplugin/coursesettings.php', array('id'=>$course->id));
        $settingsnode->add(get_string('settings', 'local_mylocalplugin'), $url, navigation_node::TYPE_SETTING);
    }

This only adds a convenient hook into the course admin navigation.  The
format/local plugin must still implement a form and database storage for their
settings.
---
 course/edit.php       |    5 +++--
 lang/en/moodle.php    |    1 +
 lib/navigationlib.php |   45 ++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/course/edit.php b/course/edit.php
index b487132..fddc1ea 100644
--- a/course/edit.php
+++ b/course/edit.php
@@ -32,7 +32,6 @@ $categoryid = optional_param('category', 0, PARAM_INT); // course category - can
 $returnto = optional_param('returnto', 0, PARAM_ALPHANUM); // generic navigation return page switch
 
 $PAGE->set_pagelayout('admin');
-$PAGE->set_url('/course/edit.php');
 
 // basic access control checks
 if ($id) { // editing course
@@ -41,6 +40,7 @@ if ($id) { // editing course
         print_error('cannoteditsiteform');
     }
 
+    $PAGE->set_url('/course/edit.php', array('id' => $id));
     $course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
     require_login($course);
     $category = $DB->get_record('course_categories', array('id'=>$course->category), '*', MUST_EXIST);
@@ -49,6 +49,7 @@ if ($id) { // editing course
     $PAGE->url->param('id',$id);
 
 } else if ($categoryid) { // creating new course in this category
+    $PAGE->set_url('/course/edit.php', array('category' => $categoryid));
     $course = null;
     require_login();
     $category = $DB->get_record('course_categories', array('id'=>$categoryid), '*', MUST_EXIST);
@@ -58,6 +59,7 @@ if ($id) { // editing course
     $PAGE->set_context($catcontext);
 
 } else {
+    $PAGE->set_url('/course/edit.php');
     require_login();
     print_error('needcoursecategroyid');
 }
@@ -158,7 +160,6 @@ $stradministration = get_string("administration");
 $strcategories = get_string("categories");
 
 if (!empty($course->id)) {
-    $PAGE->navbar->add($streditcoursesettings);
     $title = $streditcoursesettings;
     $fullname = $course->fullname;
 } else {
diff --git a/lang/en/moodle.php b/lang/en/moodle.php
index b6776b6..0768fa0 100644
--- a/lang/en/moodle.php
+++ b/lang/en/moodle.php
@@ -966,6 +966,7 @@ $string['lookback'] = 'Look back';
 $string['mailadmins'] = 'Inform admins';
 $string['mailstudents'] = 'Inform students';
 $string['mailteachers'] = 'Inform teachers';
+$string['main'] = 'Main';
 $string['makeafolder'] = 'Create 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';
diff --git a/lib/navigationlib.php b/lib/navigationlib.php
index 5438bac..361cdf5 100644
--- a/lib/navigationlib.php
+++ b/lib/navigationlib.php
@@ -2825,9 +2825,8 @@ class settings_navigation extends navigation_node {
                 // $this->add_course_editing_links($course);
             }
 
-            // Add the course settings link
-            $url = new moodle_url('/course/edit.php', array('id'=>$course->id));
-            $coursenode->add(get_string('editsettings'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', ''));
+            // Add the course settings link(s)
+            $this->add_course_settings_links($course, $coursenode);
 
             // Add the course completion settings link
             if ($CFG->enablecompletion && $course->enablecompletion) {
@@ -3046,6 +3045,46 @@ class settings_navigation extends navigation_node {
         }
     }
 
+    protected function add_course_settings_links($course, $coursenode) {
+        global $CFG;
+
+        // Main settings link
+        $url = new moodle_url('/course/edit.php', array('id'=>$course->id));
+        $settingsnode = $coursenode->add(get_string('editsettings'), $url, self::TYPE_CONTAINER);
+        $settingsnode->add(get_string('main'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', ''));
+
+        // Give the current course format a chance to include some course settings if it wants
+        if ($course->format) {
+            $function = $course->format.'_extend_course_settings';
+            if (!function_exists($function)) {
+                $formatlib = $CFG->dirroot.'/course/format/'.$course->format.'/lib.php';
+                if (file_exists($formatlib)) {
+                    require_once($formatlib);
+                }
+            }
+            if (function_exists($function)) {
+                $function($course, $settingsnode);
+            }
+        }
+
+        // Give the local plugins a chance to include some course settings if they want
+        foreach (get_plugin_list('local') as $plugin => $plugindir) {
+            // $CFG->dirroot'/local/'.$plugin.'/lib.php' included in initialise function
+            $function = $plugin.'_extend_course_settings';
+            if (function_exists($function)) {
+                $function($course, $settingsnode);
+            }
+        }
+
+        // If the main settings link is the only settings link, display it as
+        // a normal setting not a container
+        if($settingsnode->children->count() == 1)
+        {
+            $settingsnode->remove();
+            $coursenode->add(get_string('editsettings'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', ''));
+        }
+    }
+
     /**
      * This function calls the module function to inject module settings into the
      * settings navigation tree.
