Merge branch 'MDL-39740_grade_item_idnumber_fix' of git://github.com/ashleyholman...
authorDan Poltawski <dan@moodle.com>
Wed, 9 Apr 2014 03:12:55 +0000 (11:12 +0800)
committerDan Poltawski <dan@moodle.com>
Wed, 9 Apr 2014 03:12:55 +0000 (11:12 +0800)
1  2 
lib/grade/grade_item.php

diff --combined lib/grade/grade_item.php
@@@ -437,7 -437,7 +437,7 @@@ class grade_item extends grade_object 
          }
  
          if ($this->itemtype == 'mod' and !$this->is_outcome_item()) {
-             if ($this->itemnumber === 0) {
+             if ($this->itemnumber == 0) {
                  // for activity modules, itemnumber 0 is synced with the course_modules
                  if (!$cm = get_coursemodule_from_instance($this->itemmodule, $this->iteminstance, $this->courseid)) {
                      return false;
          $this->set_sortorder($sortorder + 1);
      }
  
 +    /**
 +     * Detect duplicate grade item's sortorder and re-sort them.
 +     * Note: Duplicate sortorder will be introduced while duplicating activities or
 +     * merging two courses.
 +     *
 +     * @param int $courseid id of the course for which grade_items sortorder need to be fixed.
 +     */
 +    public static function fix_duplicate_sortorder($courseid) {
 +        global $DB;
 +
 +        $transaction = $DB->start_delegated_transaction();
 +
 +        $sql = "SELECT DISTINCT g1.id, g1.courseid, g1.sortorder
 +                    FROM {grade_items} g1
 +                    JOIN {grade_items} g2 ON g1.courseid = g2.courseid
 +                WHERE g1.sortorder = g2.sortorder AND g1.id != g2.id AND g1.courseid = :courseid
 +                ORDER BY g1.sortorder DESC, g1.id DESC";
 +
 +        // Get all duplicates in course highest sort order, and higest id first so that we can make space at the
 +        // bottom higher end of the sort orders and work down by id.
 +        $rs = $DB->get_recordset_sql($sql, array('courseid' => $courseid));
 +
 +        foreach($rs as $duplicate) {
 +            $DB->execute("UPDATE {grade_items}
 +                            SET sortorder = sortorder + 1
 +                          WHERE courseid = :courseid AND
 +                          (sortorder > :sortorder OR (sortorder = :sortorder2 AND id > :id))",
 +                array('courseid' => $duplicate->courseid,
 +                    'sortorder' => $duplicate->sortorder,
 +                    'sortorder2' => $duplicate->sortorder,
 +                    'id' => $duplicate->id));
 +        }
 +        $rs->close();
 +        $transaction->allow_commit();
 +    }
 +
      /**
       * Returns the most descriptive field for this object.
       *
  
              if ($grade_category->aggregatesubcats) {
                  // return all children excluding category items
 +                $params[] = $this->courseid;
                  $params[] = '%/' . $grade_category->id . '/%';
                  $sql = "SELECT gi.id
                            FROM {grade_items} gi
 +                          JOIN {grade_categories} gc ON gi.categoryid = gc.id
                           WHERE $gtypes
                                 $outcomes_sql
 -                               AND gi.categoryid IN (
 -                                  SELECT gc.id
 -                                    FROM {grade_categories} gc
 -                                   WHERE gc.path LIKE ?)";
 +                               AND gi.courseid = ?
 +                               AND gc.path LIKE ?";
              } else {
                  $params[] = $grade_category->id;
 +                $params[] = $this->courseid;
                  $params[] = $grade_category->id;
 +                $params[] = $this->courseid;
                  if (empty($CFG->grade_includescalesinaggregation)) {
                      $params[] = GRADE_TYPE_VALUE;
                  } else {
                            FROM {grade_items} gi
                           WHERE $gtypes
                                 AND gi.categoryid = ?
 +                               AND gi.courseid = ?
                                 $outcomes_sql
                          UNION
  
                            FROM {grade_items} gi, {grade_categories} gc
                           WHERE (gi.itemtype = 'category' OR gi.itemtype = 'course') AND gi.iteminstance=gc.id
                                 AND gc.parent = ?
 +                               AND gi.courseid = ?
                                 AND $gtypes
                                 $outcomes_sql";
              }
       * @return bool
       */
      public function can_control_visibility() {
 -        if (get_plugin_directory($this->itemtype, $this->itemmodule)) {
 +        if (core_component::get_plugin_directory($this->itemtype, $this->itemmodule)) {
              return !plugin_supports($this->itemtype, $this->itemmodule, FEATURE_CONTROLS_GRADE_VISIBILITY, false);
          }
 -        return true;
 +        return parent::can_control_visibility();
 +    }
 +
 +    /**
 +     * Used to notify the completion system (if necessary) that a user's grade
 +     * has changed, and clear up a possible score cache.
 +     *
 +     * @param bool $deleted True if grade was actually deleted
 +     */
 +    protected function notify_changed($deleted) {
 +        global $CFG;
 +
 +        // Condition code may cache the grades for conditional availability of
 +        // modules or sections. (This code should use a hook for communication
 +        // with plugin, but hooks are not implemented at time of writing.)
 +        if (!empty($CFG->enableavailability) && class_exists('\availability_grade\callbacks')) {
 +            \availability_grade\callbacks::grade_item_changed($this->courseid);
 +        }
      }
  }