Merge branch 'MDL-30616-master-7' of git://git.luns.net.uk/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 13 Mar 2012 22:40:39 +0000 (23:40 +0100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 13 Mar 2012 22:40:39 +0000 (23:40 +0100)
1  2 
course/lib.php

diff --combined course/lib.php
@@@ -389,7 -389,8 +389,7 @@@ function print_log($course, $user=0, $d
  
          // If $log->url has been trimmed short by the db size restriction
          // code in add_to_log, keep a note so we don't add a link to a broken url
 -        $tl=textlib_get_instance();
 -        $brokenurl=($tl->strlen($log->url)==100 && $tl->substr($log->url,97)=='...');
 +        $brokenurl=(textlib::strlen($log->url)==100 && textlib::substr($log->url,97)=='...');
  
          $row = array();
          if ($course->id == SITEID) {
@@@ -1340,18 -1341,6 +1340,18 @@@ function course_set_display($courseid, 
      return $display;
  }
  
 +/**
 + * Set highlighted section. Only one section can be highlighted at the time.
 + *
 + * @param int $courseid course id
 + * @param int $marker highlight section with this number, 0 means remove higlightin
 + * @return void
 + */
 +function course_set_marker($courseid, $marker) {
 +    global $DB;
 +    $DB->set_field("course", "marker", $marker, array('id' => $courseid));
 +}
 +
  /**
   * For a given course section, marks it visible or hidden,
   * and does the same for every activity in that section
@@@ -1446,6 -1435,8 +1446,6 @@@ function print_section($course, $sectio
          $initialised = true;
      }
  
 -    $tl = textlib_get_instance();
 -
      $modinfo = get_fast_modinfo($course);
      $completioninfo = new completion_info($course);
  
              // Avoid unnecessary duplication: if e.g. a forum name already
              // includes the word forum (or Forum, etc) then it is unhelpful
              // to include that in the accessible description that is added.
 -            if (false !== strpos($tl->strtolower($instancename),
 -                    $tl->strtolower($altname))) {
 +            if (false !== strpos(textlib::strtolower($instancename),
 +                    textlib::strtolower($altname))) {
                  $altname = '';
              }
              // File type after name, for alphabetic lists (screen reader).
                  }
                  if ($completionicon) {
                      $imgsrc = $OUTPUT->pix_url('i/completion-'.$completionicon);
 -                    $imgalt = s(get_string('completion-alt-'.$completionicon, 'completion'));
 +                    $imgalt = s(get_string('completion-alt-'.$completionicon, 'completion', $mod->name));
                      if ($completion == COMPLETION_TRACKING_MANUAL && !$isediting) {
 -                        $imgtitle = s(get_string('completion-title-'.$completionicon, 'completion'));
 +                        $imgtitle = s(get_string('completion-title-'.$completionicon, 'completion', $mod->name));
                          $newstate =
                              $completiondata->completionstate==COMPLETION_COMPLETE
                              ? COMPLETION_INCOMPLETE
                          echo "
  <form class='togglecompletion$extraclass' method='post' action='".$CFG->wwwroot."/course/togglecompletion.php'><div>
  <input type='hidden' name='id' value='{$mod->id}' />
 +<input type='hidden' name='modulename' value='".s($mod->name)."' />
  <input type='hidden' name='sesskey' value='".sesskey()."' />
  <input type='hidden' name='completionstate' value='$newstate' />
  <input type='image' src='$imgsrc' alt='$imgalt' title='$imgtitle' />
@@@ -1816,65 -1806,49 +1816,49 @@@ function print_section_add_menus($cours
          return false;
      }
  
-     $urlbase = "/course/mod.php?id=$course->id&section=$section&sesskey=".sesskey().'&add=';
+     // Retrieve all modules with associated metadata
+     $modules = get_module_metadata($course, $modnames);
  
+     // We'll sort resources and activities into two lists
      $resources = array();
      $activities = array();
  
-     foreach($modnames as $modname=>$modnamestr) {
-         if (!course_allowed_module($course, $modname)) {
-             continue;
-         }
+     // We need to add the section section to the link for each module
+     $sectionlink = '&section=' . $section;
  
-         $libfile = "$CFG->dirroot/mod/$modname/lib.php";
-         if (!file_exists($libfile)) {
-             continue;
-         }
-         include_once($libfile);
-         $gettypesfunc =  $modname.'_get_types';
-         if (function_exists($gettypesfunc)) {
+     foreach ($modules as $module) {
+         if (isset($module->types)) {
+             // This module has a subtype
              // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
-             if ($types = $gettypesfunc()) {
-                 $menu = array();
-                 $atype = null;
-                 $groupname = null;
-                 foreach($types as $type) {
-                     if ($type->typestr === '--') {
-                         continue;
-                     }
-                     if (strpos($type->typestr, '--') === 0) {
-                         $groupname = str_replace('--', '', $type->typestr);
-                         continue;
-                     }
-                     $type->type = str_replace('&amp;', '&', $type->type);
-                     if ($type->modclass == MOD_CLASS_RESOURCE) {
-                         $atype = MOD_CLASS_RESOURCE;
-                     }
-                     $menu[$urlbase.$type->type] = $type->typestr;
+             $subtypes = array();
+             foreach ($module->types as $subtype) {
+                 $subtypes[$subtype->link . $sectionlink] = $subtype->title;
+             }
+             // Sort module subtypes into the list
+             if (!empty($module->title)) {
+                 // This grouping has a name
+                 if ($module->archetype == MOD_CLASS_RESOURCE) {
+                     $resources[] = array($module->title=>$subtypes);
+                 } else {
+                     $activities[] = array($module->title=>$subtypes);
                  }
-                 if (!is_null($groupname)) {
-                     if ($atype == MOD_CLASS_RESOURCE) {
-                         $resources[] = array($groupname=>$menu);
-                     } else {
-                         $activities[] = array($groupname=>$menu);
-                     }
+             } else {
+                 // This grouping does not have a name
+                 if ($module->archetype == MOD_CLASS_RESOURCE) {
+                     $resources = array_merge($resources, $subtypes);
                  } else {
-                     if ($atype == MOD_CLASS_RESOURCE) {
-                         $resources = array_merge($resources, $menu);
-                     } else {
-                         $activities = array_merge($activities, $menu);
-                     }
+                     $activities = array_merge($activities, $subtypes);
                  }
              }
          } else {
-             $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
-             if ($archetype == MOD_ARCHETYPE_RESOURCE) {
-                 $resources[$urlbase.$modname] = $modnamestr;
-             } else if ($archetype === MOD_ARCHETYPE_SYSTEM) {
+             // This module has no subtypes
+             if ($module->archetype == MOD_ARCHETYPE_RESOURCE) {
+                 $resources[$module->link . $sectionlink] = $module->title;
+             } else if ($module->archetype === MOD_ARCHETYPE_SYSTEM) {
                  // System modules cannot be added by user, do not add to dropdown
              } else {
-                 // all other archetypes are considered activity
-                 $activities[$urlbase.$modname] = $modnamestr;
+                 $activities[$module->link . $sectionlink] = $module->title;
              }
          }
      }
      }
  }
  
+ /**
+  * Retrieve all metadata for the requested modules
+  *
+  * @param object $course The Course
+  * @param array $modnames An array containing the list of modules and their
+  * names
+  * @return array A list of stdClass objects containing metadata about each
+  * module
+  */
+ function get_module_metadata($course, $modnames) {
+     global $CFG, $OUTPUT;
+     // get_module_metadata will be called once per section on the page and courses may show
+     // different modules to one another
+     static $modlist = array();
+     if (!isset($modlist[$course->id])) {
+         $modlist[$course->id] = array();
+     }
+     $return = array();
+     $urlbase = "/course/mod.php?id=$course->id&sesskey=".sesskey().'&add=';
+     foreach($modnames as $modname => $modnamestr) {
+         if (!course_allowed_module($course, $modname)) {
+             continue;
+         }
+         if (isset($modlist[$modname])) {
+             // This module is already cached
+             $return[$modname] = $modlist[$course->id][$modname];
+             continue;
+         }
+         // Include the module lib
+         $libfile = "$CFG->dirroot/mod/$modname/lib.php";
+         if (!file_exists($libfile)) {
+             continue;
+         }
+         include_once($libfile);
+         // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
+         $gettypesfunc =  $modname.'_get_types';
+         if (function_exists($gettypesfunc)) {
+             if ($types = $gettypesfunc()) {
+                 $group = new stdClass();
+                 $group->name = $modname;
+                 $group->icon = $OUTPUT->pix_icon('icon', '', $modname, array('class' => 'icon'));
+                 foreach($types as $type) {
+                     if ($type->typestr === '--') {
+                         continue;
+                     }
+                     if (strpos($type->typestr, '--') === 0) {
+                         $group->title = str_replace('--', '', $type->typestr);
+                         continue;
+                     }
+                     // Set the Sub Type metadata
+                     $subtype = new stdClass();
+                     $subtype->title = $type->typestr;
+                     $subtype->type = str_replace('&amp;', '&', $type->type);
+                     $subtype->name = preg_replace('/.*type=/', '', $subtype->type);
+                     $subtype->archetype = $type->modclass;
+                     // The group archetype should match the subtype archetypes and all subtypes
+                     // should have the same archetype
+                     $group->archetype = $subtype->archetype;
+                     if (get_string_manager()->string_exists('help' . $subtype->name, $modname)) {
+                         $subtype->help = get_string('help' . $subtype->name, $modname);
+                     }
+                     $subtype->link = $urlbase . $type->type;
+                     $group->types[] = $subtype;
+                 }
+                 $modlist[$course->id][$modname] = $group;
+             }
+         } else {
+             $module = new stdClass();
+             $module->title = get_string('modulename', $modname);
+             $module->name = $modname;
+             $module->link = $urlbase . $modname;
+             $module->icon = $OUTPUT->pix_icon('icon', '', $module->name, array('class' => 'icon'));
+             if (get_string_manager()->string_exists('modulename_help', $modname)) {
+                 $module->help = get_string('modulename_help', $modname);
+             }
+             $module->archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
+             $modlist[$course->id][$modname] = $module;
+         }
+         $return[$modname] = $modlist[$course->id][$modname];
+     }
+     return $return;
+ }
  /**
   * Return the course category context for the category with id $categoryid, except
   * that if $categoryid is 0, return the system context.
@@@ -2882,10 -2946,9 +2956,10 @@@ function delete_mod_from_section($mod, 
  /**
   * Moves a section up or down by 1. CANNOT BE USED DIRECTLY BY AJAX!
   *
 - * @param object $course
 - * @param int $section
 + * @param object $course course object
 + * @param int $section Section number (not id!!!)
   * @param int $move (-1 or 1)
 + * @return boolean true if section moved successfully
   */
  function move_section($course, $section, $move) {
  /// Moves a whole course section up and down within the course
      $DB->set_field("course_sections", "section", $sectiondest, array("id"=>$sectionrecord->id));
      $DB->set_field("course_sections", "section", $section, array("id"=>$sectiondestrecord->id));
  
 +    // Update highlighting if the move affects highlighted section
 +    if ($course->marker == $section) {
 +        course_set_marker($course->id, $sectiondest);
 +    } elseif ($course->marker == $sectiondest) {
 +        course_set_marker($course->id, $section);
 +    }
 +
      // if the focus is on the section that is being moved, then move the focus along
      if (course_get_display($course->id) == $section) {
          course_set_display($course->id, $sectiondest);