function test_grade_category_fetch()
 {
     $grade_category = new grade_category();
     $this->assertTrue(method_exists($grade_category, 'fetch'));
     $grade_category = grade_category::fetch(array('id' => $this->grade_categories[0]->id));
     $this->assertEqual($this->grade_categories[0]->id, $grade_category->id);
     $this->assertEqual($this->grade_categories[0]->fullname, $grade_category->fullname);
 }
 /**
  * Adds a grade category and moves the specified item into it.
  * Uses locks to prevent race conditions (see MDL-37055).
  */
 public function execute()
 {
     $customdata = $this->get_custom_data();
     // Get lock timeout.
     $timeout = 5;
     // A namespace for the locks.
     $locktype = 'block_mhaairs_add_category';
     // Resource key - course id and category name.
     $resource = "course: {$customdata->courseid}; catname: {$customdata->catname}";
     // Get an instance of the currently configured lock_factory.
     $lockfactory = \core\lock\lock_config::get_lock_factory($locktype);
     // Open a lock.
     $lock = $lockfactory->get_lock($resource, $timeout);
     // Add the category.
     $catparams = array('fullname' => $customdata->catname, 'courseid' => $customdata->courseid);
     if (!($category = \grade_category::fetch($catparams))) {
         // If the category does not exist we create it.
         $gradeaggregation = get_config('core', 'grade_aggregation');
         if ($gradeaggregation === false) {
             $gradeaggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2;
         }
         // Parent category is automatically added(created) during insert.
         $catparams['hidden'] = false;
         $catparams['aggregation'] = $gradeaggregation;
         try {
             $category = new \grade_category($catparams, false);
             $category->id = $category->insert();
         } catch (Exception $e) {
             // Must release the locks.
             $lock->release();
             // Rethrow to reschedule task.
             throw $e;
         }
     }
     // Release locks.
     $lock->release();
     // Add the item to the category.
     $gitem = \grade_item::fetch(array('id' => $customdata->itemid));
     $gitem->categoryid = $category->id;
     $gitem->update();
 }
Exemple #3
0
 /**
  * Recursive function for building the table holding the grade categories and items,
  * with CSS indentation and styles.
  *
  * @param array   $element The current tree element being rendered
  * @param boolean $totals Whether or not to print category grade items (category totals)
  * @param array   $parents An array of parent categories for the current element (used for indentation and row classes)
  *
  * @return string HTML
  */
 public function build_html_tree($element, $totals, $parents, $level, &$row_count)
 {
     global $CFG, $COURSE, $PAGE, $OUTPUT;
     $object = $element['object'];
     $eid = $element['eid'];
     $object->name = $this->gtree->get_element_header($element, true, true, true, true);
     $object->stripped_name = $this->gtree->get_element_header($element, false, false, false);
     $is_category_item = false;
     if ($element['type'] == 'categoryitem' || $element['type'] == 'courseitem') {
         $is_category_item = true;
     }
     $rowclasses = array();
     foreach ($parents as $parent_eid) {
         $rowclasses[] = $parent_eid;
     }
     $moveaction = '';
     $actionsmenu = new action_menu();
     $actionsmenu->initialise_js($PAGE);
     $actionsmenu->set_menu_trigger(get_string('edit'));
     $actionsmenu->set_owner_selector('grade-item-' . $eid);
     $actionsmenu->set_alignment(action_menu::TL, action_menu::BL);
     if (!$is_category_item && ($icon = $this->gtree->get_edit_icon($element, $this->gpr, true))) {
         $actionsmenu->add($icon);
     }
     if ($this->show_calculations && ($icon = $this->gtree->get_calculation_icon($element, $this->gpr, true))) {
         $actionsmenu->add($icon);
     }
     if ($element['type'] == 'item' or $element['type'] == 'category' and $element['depth'] > 1) {
         if ($this->element_deletable($element)) {
             $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'delete', 'eid' => $eid, 'sesskey' => sesskey()));
             $icon = new action_menu_link_secondary($aurl, new pix_icon('t/delete', get_string('delete')), get_string('delete'));
             $actionsmenu->add($icon);
         }
         $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'moveselect', 'eid' => $eid, 'sesskey' => sesskey()));
         $moveaction .= $OUTPUT->action_icon($aurl, new pix_icon('t/move', get_string('move')));
     }
     if ($icon = $this->gtree->get_hiding_icon($element, $this->gpr, true)) {
         $actionsmenu->add($icon);
     }
     if ($icon = $this->gtree->get_reset_icon($element, $this->gpr, true)) {
         $actionsmenu->add($icon);
     }
     $actions = $OUTPUT->render($actionsmenu);
     $returnrows = array();
     $root = false;
     $id = required_param('id', PARAM_INT);
     /// prepare move target if needed
     $last = '';
     /// print the list items now
     if ($this->moving == $eid) {
         // do not diplay children
         $cell = new html_table_cell();
         $cell->colspan = 12;
         $cell->attributes['class'] = $element['type'] . ' moving column-name level' . ($level + 1) . ' level' . ($level % 2 ? 'even' : 'odd');
         $cell->text = $object->name . ' (' . get_string('move') . ')';
         return array(new html_table_row(array($cell)));
     }
     if ($element['type'] == 'category') {
         $level++;
         $this->categories[$object->id] = $object->stripped_name;
         $category = grade_category::fetch(array('id' => $object->id));
         $item = $category->get_grade_item();
         // Add aggregation coef input if not a course item and if parent category has correct aggregation type
         $dimmed = $item->is_hidden() ? 'dimmed_text' : '';
         // Before we print the category's row, we must find out how many rows will appear below it (for the filler cell's rowspan)
         $aggregation_position = grade_get_setting($COURSE->id, 'aggregationposition', $CFG->grade_aggregationposition);
         $category_total_data = null;
         // Used if aggregationposition is set to "last", so we can print it last
         $html_children = array();
         $row_count = 0;
         foreach ($element['children'] as $child_el) {
             $moveto = null;
             if (empty($child_el['object']->itemtype)) {
                 $child_el['object']->itemtype = false;
             }
             if (($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') && !$totals) {
                 continue;
             }
             $child_eid = $child_el['eid'];
             $first = '';
             if ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
                 $first = array('first' => 1);
                 $child_eid = $eid;
             }
             if ($this->moving && $this->moving != $child_eid) {
                 $strmove = get_string('move');
                 $strmovehere = get_string('movehere');
                 $actions = $moveaction = '';
                 // no action icons when moving
                 $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'move', 'eid' => $this->moving, 'moveafter' => $child_eid, 'sesskey' => sesskey()));
                 if ($first) {
                     $aurl->params($first);
                 }
                 $cell = new html_table_cell();
                 $cell->colspan = 12;
                 $cell->attributes['class'] = 'movehere level' . ($level + 1) . ' level' . ($level % 2 ? 'even' : 'odd');
                 $icon = new pix_icon('movehere', $strmovehere, null, array('class' => 'movetarget'));
                 $cell->text = $OUTPUT->action_icon($aurl, $icon);
                 $moveto = new html_table_row(array($cell));
             }
             $newparents = $parents;
             $newparents[] = $eid;
             $row_count++;
             $child_row_count = 0;
             // If moving, do not print course and category totals, but still print the moveto target box
             if ($this->moving && ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category')) {
                 $html_children[] = $moveto;
             } elseif ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
                 // We don't build the item yet because we first need to know the deepest level of categories (for category/name colspans)
                 $category_total_item = $this->build_html_tree($child_el, $totals, $newparents, $level, $child_row_count);
                 if (!$aggregation_position) {
                     $html_children = array_merge($html_children, $category_total_item);
                 }
             } else {
                 $html_children = array_merge($html_children, $this->build_html_tree($child_el, $totals, $newparents, $level, $child_row_count));
                 if (!empty($moveto)) {
                     $html_children[] = $moveto;
                 }
                 if ($this->moving) {
                     $row_count++;
                 }
             }
             $row_count += $child_row_count;
             // If the child is a category, increment row_count by one more (for the extra coloured row)
             if ($child_el['type'] == 'category') {
                 $row_count++;
             }
         }
         // Print category total at the end if aggregation position is "last" (1)
         if (!empty($category_total_item) && $aggregation_position) {
             $html_children = array_merge($html_children, $category_total_item);
         }
         // Determine if we are at the root
         if (isset($element['object']->grade_item) && $element['object']->grade_item->is_course_item()) {
             $root = true;
         }
         $levelclass = "level{$level} level" . ($level % 2 ? 'odd' : 'even');
         $courseclass = '';
         if ($level == 1) {
             $courseclass = 'coursecategory';
         }
         $row = new html_table_row();
         $row->id = 'grade-item-' . $eid;
         $row->attributes['class'] = $courseclass . ' category ' . $dimmed;
         foreach ($rowclasses as $class) {
             $row->attributes['class'] .= ' ' . $class;
         }
         $headercell = new html_table_cell();
         $headercell->header = true;
         $headercell->scope = 'row';
         $headercell->attributes['title'] = $object->stripped_name;
         $headercell->attributes['class'] = 'cell column-rowspan rowspan ' . $levelclass;
         $headercell->rowspan = $row_count + 1;
         $row->cells[] = $headercell;
         foreach ($this->columns as $column) {
             if (!($this->moving && $column->hide_when_moving)) {
                 $row->cells[] = $column->get_category_cell($category, $levelclass, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'moveaction' => $moveaction, 'eid' => $eid));
             }
         }
         $returnrows[] = $row;
         $returnrows = array_merge($returnrows, $html_children);
         // Print a coloured row to show the end of the category across the table
         $endcell = new html_table_cell();
         $endcell->colspan = 19 - $level;
         $endcell->attributes['class'] = 'emptyrow colspan ' . $levelclass;
         $returnrows[] = new html_table_row(array($endcell));
     } else {
         // Dealing with a grade item
         $item = grade_item::fetch(array('id' => $object->id));
         $element['type'] = 'item';
         $element['object'] = $item;
         $categoryitemclass = '';
         if ($item->itemtype == 'category') {
             $categoryitemclass = 'categoryitem';
         }
         if ($item->itemtype == 'course') {
             $categoryitemclass = 'courseitem';
         }
         $dimmed = $item->is_hidden() ? "dimmed_text" : "";
         $gradeitemrow = new html_table_row();
         $gradeitemrow->id = 'grade-item-' . $eid;
         $gradeitemrow->attributes['class'] = $categoryitemclass . ' item ' . $dimmed;
         foreach ($rowclasses as $class) {
             $gradeitemrow->attributes['class'] .= ' ' . $class;
         }
         foreach ($this->columns as $column) {
             if (!($this->moving && $column->hide_when_moving)) {
                 $gradeitemrow->cells[] = $column->get_item_cell($item, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'element' => $element, 'eid' => $eid, 'moveaction' => $moveaction, 'itemtype' => $object->itemtype));
             }
         }
         $returnrows[] = $gradeitemrow;
     }
     return $returnrows;
 }
Exemple #4
0
 function validation($data, $files)
 {
     global $COURSE;
     $gradeitem = false;
     if ($data['id']) {
         $gradecategory = grade_category::fetch(array('id' => $data['id']));
         $gradeitem = $gradecategory->load_grade_item();
     }
     $errors = parent::validation($data, $files);
     if (array_key_exists('grade_item_gradetype', $data) and $data['grade_item_gradetype'] == GRADE_TYPE_SCALE) {
         if (empty($data['grade_item_scaleid'])) {
             $errors['grade_item_scaleid'] = get_string('missingscale', 'grades');
         }
     }
     if (array_key_exists('grade_item_grademin', $data) and array_key_exists('grade_item_grademax', $data)) {
         if (($data['grade_item_grademax'] != 0 or $data['grade_item_grademin'] != 0) and ($data['grade_item_grademax'] == $data['grade_item_grademin'] or $data['grade_item_grademax'] < $data['grade_item_grademin'])) {
             $errors['grade_item_grademin'] = get_string('incorrectminmax', 'grades');
             $errors['grade_item_grademax'] = get_string('incorrectminmax', 'grades');
         }
     }
     if ($data['id'] && $gradeitem->has_overridden_grades()) {
         if ($gradeitem->gradetype == GRADE_TYPE_VALUE) {
             if (grade_floats_different($data['grade_item_grademin'], $gradeitem->grademin) || grade_floats_different($data['grade_item_grademax'], $gradeitem->grademax)) {
                 if (empty($data['grade_item_rescalegrades'])) {
                     $errors['grade_item_rescalegrades'] = get_string('mustchooserescaleyesorno', 'grades');
                 }
             }
         }
     }
     return $errors;
 }
 /**
  * Saves a gradebook (a set of grade items and scores related to a course),
  * also creates the categories based on the item type
  *
  * @param object $gradebook an object with at least course_id and items set
  * items should contain grade_items (courseid. categoryid, name, scores)
  * scores should contain grade_grade (user_id, score)
  * @return stdClass the saved gradebook with all items and scores in the same structure,
  * errors are recorded as grade_item->errors and score->error
  * @throws InvalidArgumentException
  */
 public static function save_gradebook($gradebook)
 {
     global $CFG;
     if (!$gradebook) {
         throw new InvalidArgumentException("gradebook must be set");
     }
     if (!isset($gradebook->course_id)) {
         throw new InvalidArgumentException("gradebook->course_id must be set");
     }
     if (!isset($gradebook->items) || empty($gradebook->items)) {
         throw new InvalidArgumentException("gradebook->items must be set and include items");
     }
     $gb_saved = new stdClass();
     $gb_saved->items = array();
     $gb_saved->course_id = $gradebook->course_id;
     $course = self::get_course($gradebook->course_id);
     if (!$course) {
         throw new InvalidArgumentException("No course found with course_id ({$gradebook->course_id})");
     }
     $gb_saved->course = $course;
     // extra permissions check on gradebook manage/update
     $user_id = self::require_user();
     if (class_exists('context_course')) {
         // for Moodle 2.2+
         $context = context_course::instance($course->id);
     } else {
         /** @noinspection PhpDeprecationInspection */
         $context = get_context_instance(CONTEXT_COURSE, $course->id);
         // deprecated
     }
     if (!$context || !has_capability('moodle/grade:manage', $context, $user_id)) {
         throw new InvalidArgumentException("User ({$user_id}) cannot manage the gradebook in course id={$course->id} (" . var_export($course, true) . "), context: " . var_export($context, true));
     }
     // attempt to get the default iclicker category first
     $default_iclicker_category = grade_category::fetch(array('courseid' => $gradebook->course_id, 'fullname' => self::GRADE_CATEGORY_NAME));
     $default_iclicker_category_id = $default_iclicker_category ? $default_iclicker_category->id : null;
     //echo "\n\nGRADEBOOK: ".var_export($gradebook);
     // iterate through and save grade items by calling other method
     if (!empty($gradebook->items)) {
         $saved_items = array();
         $number = 0;
         foreach ($gradebook->items as $grade_item) {
             // check for this category
             $item_category_name = self::GRADE_CATEGORY_NAME;
             if (!empty($grade_item->type) && self::GRADE_CATEGORY_NAME != $grade_item->type) {
                 $item_category_name = $grade_item->type;
                 $item_category = grade_category::fetch(array('courseid' => $gradebook->course_id, 'fullname' => $item_category_name));
                 if (!$item_category) {
                     // create the category
                     $params = array('courseid' => $gradebook->course_id, 'fullname' => $item_category_name);
                     $grade_category = new grade_category($params, false);
                     // Use default aggregation type.
                     $grade_category->aggregation = $CFG->grade_aggregation;
                     $grade_category->insert(self::GRADE_LOCATION_STR);
                     $item_category_id = $grade_category->id;
                 } else {
                     $item_category_id = $item_category->id;
                 }
             } else {
                 // use default
                 if (!$default_iclicker_category_id) {
                     // create the category
                     $params = array('courseid' => $gradebook->course_id, 'fullname' => self::GRADE_CATEGORY_NAME);
                     $grade_category = new grade_category($params, false);
                     // Use default aggregation type.
                     $grade_category->aggregation = $CFG->grade_aggregation;
                     $grade_category->insert(self::GRADE_LOCATION_STR);
                     $default_iclicker_category_id = $grade_category->id;
                 }
                 $item_category_id = $default_iclicker_category_id;
             }
             $grade_item->categoryid = $item_category_id;
             $grade_item->typename = $item_category_name;
             $grade_item->courseid = $gradebook->course_id;
             $grade_item->item_number = $number;
             $saved_grade_item = self::save_grade_item($grade_item);
             $saved_items[] = $saved_grade_item;
             $number++;
         }
         $gb_saved->items = $saved_items;
     }
     $gb_saved->default_category_id = $default_iclicker_category_id;
     //echo "\n\nRESULT: ".var_export($gb_saved);
     return $gb_saved;
 }
Exemple #6
0
 /**
  * Return the course level grade_category object
  *
  * @param int $courseid The Course ID
  * @return grade_category Returns the course level grade_category instance
  */
 public static function fetch_course_category($courseid)
 {
     if (empty($courseid)) {
         debugging('Missing course id!');
         return false;
     }
     // course category has no parent
     if ($course_category = grade_category::fetch(array('courseid' => $courseid, 'parent' => null))) {
         return $course_category;
     }
     // create a new one
     $course_category = new grade_category();
     $course_category->insert_course_category($courseid);
     return $course_category;
 }
Exemple #7
0
 /**
  * Determines whether the grade tree item can be displayed.
  * This is particularly targeted for grade categories that have no total (None) when rendering the grade tree.
  * It checks if the grade tree item is of type 'category', and makes sure that the category, or at least one of children,
  * can be output.
  *
  * @param array $element The grade category element.
  * @return bool True if the grade tree item can be displayed. False, otherwise.
  */
 public static function can_output_item($element)
 {
     $canoutput = true;
     if ($element['type'] === 'category') {
         $object = $element['object'];
         $category = grade_category::fetch(array('id' => $object->id));
         // Category has total, we can output this.
         if ($category->get_grade_item()->gradetype != GRADE_TYPE_NONE) {
             return true;
         }
         // Category has no total and has no children, no need to output this.
         if (empty($element['children'])) {
             return false;
         }
         $canoutput = false;
         // Loop over children and make sure at least one child can be output.
         foreach ($element['children'] as $child) {
             $canoutput = self::can_output_item($child);
             if ($canoutput) {
                 break;
             }
         }
     }
     return $canoutput;
 }
            $grade_item->update();
            grade_regrade_final_grades($courseid);
            // Grade category checkbox inputs
        } elseif (preg_match('/aggregate(onlygraded|subcats|outcomes)_original_([0-9]*)/', $key, $matches) && confirm_sesskey()) {
            $setting = optional_param('aggregate' . $matches[1] . '_' . $matches[2], null, PARAM_BOOL);
            $original_value = required_param($matches[0], PARAM_BOOL);
            $a->id = $matches[2];
            $newvalue = null;
            if ($original_value == 1 && is_null($setting)) {
                $newvalue = 0;
            } elseif ($original_value == 0 && $setting == 1) {
                $newvalue = 1;
            } else {
                continue;
            }
            $grade_category = grade_category::fetch(array('id' => $a->id, 'courseid' => $courseid));
            $grade_category->{'aggregate' . $matches[1]} = $newvalue;
            $grade_category->update();
            grade_regrade_final_grades($courseid);
        }
    }
}
// Print Table of categories and items
print_box_start('gradetreebox generalbox');
echo '<form id="gradetreeform" method="post" action="' . $returnurl . '">';
echo '<div>';
echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
// Build up an array of categories for move drop-down (by reference)
$categories = array();
$level = 0;
$row_count = 0;
Exemple #9
0
 /**
  * Return the top most course category.
  * @static
  * @return object grade_category instance for course grade
  */
 function fetch_course_category($courseid)
 {
     // course category has no parent
     if ($course_category = grade_category::fetch(array('courseid' => $courseid, 'parent' => null))) {
         return $course_category;
     }
     // create a new one
     $course_category = new grade_category();
     $course_category->insert_course_category($courseid);
     return $course_category;
 }
 /**
  * Tests the gradebookservice update grade with cases that should
  * result in success.
  *
  * @return void
  */
 public function test_update_grade_update_item()
 {
     global $DB;
     $callback = 'block_mhaairs_gradebookservice_external::update_grade';
     $this->set_user('admin');
     // CREATE/UPDATE.
     $cases = $this->get_cases('tc_update_grade');
     foreach ($cases as $case) {
         if (!empty($case->hidden)) {
             continue;
         }
         try {
             $result = call_user_func_array($callback, $case->servicedata);
             $this->assertEquals($case->result, $result);
         } catch (Exception $e) {
             $result = get_class($e);
             $this->assertEquals($case->result, $result);
             continue;
         }
         // Fetch the item.
         $giparams = array('itemtype' => 'manual', 'itemmodule' => 'mhaairs', 'iteminstance' => $case->iteminstance, 'courseid' => $this->course->id, 'itemnumber' => $case->itemnumber);
         $gitem = grade_item::fetch($giparams);
         if (is_numeric($case->result) and (int) $case->result === 0) {
             // Verify successful update.
             $this->assertInstanceOf('grade_item', $gitem);
             $maxgrade = !empty($case->item_grademax) ? (int) $case->item_grademax : 100;
             $this->assertEquals($maxgrade, $gitem->grademax);
             if (!empty($case->item_categoryid)) {
                 // Fetch the category.
                 $fetchparams = array('fullname' => $case->item_categoryid, 'courseid' => $this->course->id);
                 $category = grade_category::fetch($fetchparams);
                 $categoryid = $category->id;
                 $this->assertEquals($gitem->categoryid, $categoryid);
             }
         } else {
             // Verify failed update.
             $this->assertEquals(false, $gitem);
         }
     }
 }
 function definition_after_data()
 {
     global $CFG;
     $mform =& $this->_form;
     $checkbox_values = array(get_string('no'), get_string('yes'));
     if ($CFG->grade_aggregation != -1) {
         $agg_el =& $mform->getElement('aggregation');
         $agg_el->setValue($this->aggregation_types[$CFG->grade_aggregation]);
     }
     if ($CFG->grade_aggregateonlygraded != -1) {
         $agg_el =& $mform->getElement('aggregateonlygraded');
         $agg_el->setValue($checkbox_values[$CFG->grade_aggregateonlygraded]);
     }
     if ($CFG->grade_aggregateoutcomes != -1) {
         $agg_el =& $mform->getElement('aggregateoutcomes');
         $agg_el->setValue($checkbox_values[$CFG->grade_aggregateoutcomes]);
     }
     if ($CFG->grade_aggregatesubcats != -1) {
         $agg_el =& $mform->getElement('aggregatesubcats');
         $agg_el->setValue($checkbox_values[$CFG->grade_aggregatesubcats]);
     }
     if ($CFG->grade_keephigh != -1) {
         $agg_el =& $mform->getElement('keephigh');
         $agg_el->setValue($this->keepdrop_options[$CFG->grade_keephigh]);
     }
     if ($CFG->grade_droplow != -1) {
         $agg_el =& $mform->getElement('droplow');
         $agg_el->setValue($this->keepdrop_options[$CFG->grade_droplow]);
     }
     if ($id = $mform->getElementValue('id')) {
         $grade_category = grade_category::fetch(array('id' => $id));
         $grade_item = $grade_category->load_grade_item();
         if ($grade_item->is_calculated()) {
             // following elements are ignored when calculation formula used
             if ($mform->elementExists('aggregation')) {
                 $mform->removeElement('aggregation');
             }
             if ($mform->elementExists('keephigh')) {
                 $mform->removeElement('keephigh');
             }
             if ($mform->elementExists('droplow')) {
                 $mform->removeElement('droplow');
             }
             if ($mform->elementExists('aggregateonlygraded')) {
                 $mform->removeElement('aggregateonlygraded');
             }
             if ($mform->elementExists('aggregateoutcomes')) {
                 $mform->removeElement('aggregateoutcomes');
             }
             if ($mform->elementExists('aggregatesubcats')) {
                 $mform->removeElement('aggregatesubcats');
             }
         }
     }
 }
 public function get_category_start_date($course, $user, $category)
 {
     $itemtype = 'mod';
     $itemmodule = '';
     $iteminstance = '';
     $courseid = $course->id;
     $iteminstance = $category->iteminstance;
     $category_start_date = NULL;
     $course_category = grade_category::fetch(array('courseid' => $courseid, 'id' => $iteminstance));
     $grade_items = $course_category->get_children();
     foreach ($grade_items as $grade => $grade_value) {
         $grade_item = $grade_value["object"];
         $start_date = $this->get_activity_start_date($course, $user, $grade_item);
         if ($category_start_date > $start_date && $start_date != NULL || $category_start_date == NULL) {
             $category_start_date = $start_date;
         }
     }
     // echo $category_start_date ? $category_start_date->format('d-m-Y') : "-";
     return $category_start_date;
 }
             $grade_item->set_parent($item->categoryid);
             $grade_item->move_after_sortorder($item->sortorder);
         }
         $grade_items[] = $grade_item;
     }
 }
 // Create a grade_category to represent this module, if outcomes have been attached
 if (!empty($grade_items)) {
     // Add the module's normal grade_item as a child of this category
     $item_params = array('itemtype' => 'mod', 'itemmodule' => $fromform->modulename, 'iteminstance' => $fromform->instance, 'itemnumber' => 0, 'courseid' => $COURSE->id);
     $item = grade_item::fetch($item_params);
     // Only create the category if it will contain at least 2 items
     if ($item or count($grade_items) > 1) {
         // If we are here it means there is at least 1 outcome
         $cat_params = array('courseid' => $COURSE->id, 'fullname' => $fromform->name);
         $grade_category = grade_category::fetch($cat_params);
         if (!$grade_category) {
             $grade_category = new grade_category($cat_params);
             $grade_category->courseid = $COURSE->id;
             $grade_category->fullname = $fromform->name;
             $grade_category->insert();
         }
         $sortorder = $grade_category->sortorder;
         if ($item) {
             $item->set_parent($grade_category->id);
             $sortorder = $item->sortorder;
         }
         // Add the outcomes as children of this category
         foreach ($grade_items as $gi) {
             $gi->set_parent($grade_category->id);
             $gi->move_after_sortorder($sortorder);
Exemple #14
0
 /**
  * Recursive function for building the table holding the grade categories and items,
  * with CSS indentation and styles.
  *
  * @param array               $element The current tree element being rendered
  * @param boolean             $totals Whether or not to print category grade items (category totals)
  * @param array               $parents An array of parent categories for the current element (used for indentation and row classes)
  *
  * @return string HTML
  */
 function build_html_tree($element, $totals, $parents, &$categories, $level, &$row_count)
 {
     global $CFG, $COURSE, $USER;
     $object = $element['object'];
     $eid = $element['eid'];
     $object->name = $this->gtree->get_element_header($element, true, true, false);
     $object->stripped_name = $this->gtree->get_element_header($element, false, false, false);
     $is_category_item = false;
     if ($element['type'] == 'categoryitem' || $element['type'] == 'courseitem') {
         $is_category_item = true;
     }
     $rowclasses = '';
     foreach ($parents as $parent_eid) {
         $rowclasses .= " {$parent_eid} ";
     }
     $actions = '';
     if (!$is_category_item) {
         $actions .= $this->gtree->get_edit_icon($element, $this->gpr);
     }
     $actions .= $this->gtree->get_calculation_icon($element, $this->gpr);
     if ($element['type'] == 'item' or $element['type'] == 'category' and $element['depth'] > 1) {
         if ($this->element_deletable($element)) {
             $actions .= '<a href="index.php?id=' . $COURSE->id . '&amp;action=delete&amp;eid=' . $eid . '&amp;sesskey=' . sesskey() . '"><img src="' . $CFG->pixpath . '/t/delete.gif" class="iconsmall" alt="' . get_string('delete') . '" title="' . get_string('delete') . '"/></a>';
         }
         $actions .= '<a href="index.php?id=' . $COURSE->id . '&amp;action=moveselect&amp;eid=' . $eid . '&amp;sesskey=' . sesskey() . '"><img src="' . $CFG->pixpath . '/t/move.gif" class="iconsmall" alt="' . get_string('move') . '" title="' . get_string('move') . '"/></a>';
     }
     $actions .= $this->gtree->get_hiding_icon($element, $this->gpr);
     $actions .= $this->gtree->get_locking_icon($element, $this->gpr);
     $mode = $USER->gradeediting[$COURSE->id] ? 'advanced' : 'simple';
     $html = '';
     $root = false;
     $id = required_param('id', PARAM_INT);
     /// prepare move target if needed
     $last = '';
     /// print the list items now
     if ($this->moving == $eid) {
         // do not diplay children
         return '<tr><td colspan="12" class="' . $element['type'] . ' moving">' . $object->name . ' (' . get_string('move') . ')</td></tr>';
     }
     if ($element['type'] == 'category') {
         $level++;
         $categories[$object->id] = $object->stripped_name;
         $category = grade_category::fetch(array('id' => $object->id));
         $item = $category->get_grade_item();
         // Add aggregation coef input if not a course item and if parent category has correct aggregation type
         $dimmed = $item->is_hidden() ? " dimmed " : "";
         // Before we print the category's row, we must find out how many rows will appear below it (for the filler cell's rowspan)
         $aggregation_position = grade_get_setting($COURSE->id, 'aggregationposition', $CFG->grade_aggregationposition);
         $category_total_data = null;
         // Used if aggregationposition is set to "last", so we can print it last
         $html_children = '';
         $row_count = 0;
         foreach ($element['children'] as $child_el) {
             $moveto = '';
             if (empty($child_el['object']->itemtype)) {
                 $child_el['object']->itemtype = false;
             }
             if (($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') && !$totals) {
                 continue;
             }
             $child_eid = $child_el['eid'];
             $first = '';
             if ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
                 $first = '&amp;first=1';
                 $child_eid = $eid;
             }
             if ($this->moving && $this->moving != $child_eid) {
                 $strmove = get_string('move');
                 $strmovehere = get_string('movehere');
                 $actions = '';
                 // no action icons when moving
                 $moveto = '<tr><td colspan="12"><a href="index.php?id=' . $COURSE->id . '&amp;action=move&amp;eid=' . $this->moving . '&amp;moveafter=' . $child_eid . '&amp;sesskey=' . sesskey() . $first . '"><img class="movetarget" src="' . $CFG->wwwroot . '/pix/movehere.gif" alt="' . $strmovehere . '" title="' . s($strmovehere) . '" /></a></td></tr>';
             }
             $newparents = $parents;
             $newparents[] = $eid;
             $row_count++;
             $child_row_count = 0;
             // If moving, do not print course and category totals, but still print the moveto target box
             if ($this->moving && ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category')) {
                 $html_children .= $moveto;
             } elseif ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
                 // We don't build the item yet because we first need to know the deepest level of categories (for category/name colspans)
                 $category_total_item = $this->build_html_tree($child_el, $totals, $newparents, $categories, $level, $child_row_count);
                 if (!$aggregation_position) {
                     $html_children .= $category_total_item;
                 }
             } else {
                 $html_children .= $this->build_html_tree($child_el, $totals, $newparents, $categories, $level, $child_row_count) . $moveto;
                 if ($this->moving) {
                     $row_count++;
                 }
             }
             $row_count += $child_row_count;
             // If the child is a category, increment row_count by one more (for the extra coloured row)
             if ($child_el['type'] == 'category') {
                 $row_count++;
             }
         }
         // Print category total at the end if aggregation position is "last" (1)
         if (!empty($category_total_item) && $aggregation_position) {
             $html_children .= $category_total_item;
         }
         // now build the header
         if (isset($element['object']->grade_item) && $element['object']->grade_item->is_course_item()) {
             // Reduce width if advanced elements are not shown
             $width_style = '';
             if ($mode == 'simple') {
                 $width_style = ' style="width:auto;" ';
             }
             $html .= '<table cellpadding="5" class="generaltable" ' . $width_style . '>
                         <tr>';
             foreach ($this->columns as $column) {
                 if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
                     $html .= $column->get_header_cell();
                 }
             }
             $html .= '</tr>';
             $root = true;
         }
         $row_count_offset = 0;
         if (empty($category_total_item) && !$this->moving) {
             $row_count_offset = -1;
         }
         $levelclass = " level{$level} ";
         $html .= '
                 <tr class="category ' . $dimmed . $rowclasses . '">
                   <th scope="row" title="' . s($object->stripped_name) . '" class="cell rowspan ' . $levelclass . '" rowspan="' . ($row_count + 1 + $row_count_offset) . '"></th>';
         foreach ($this->columns as $column) {
             if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
                 $html .= $column->get_category_cell($category, $levelclass, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'eid' => $eid));
             }
         }
         $html .= '</tr>';
         $html .= $html_children;
         // Print a coloured row to show the end of the category accross the table
         $html .= '<tr><td colspan="' . (19 - $level) . '" class="colspan ' . $levelclass . '"></td></tr>';
     } else {
         // Dealing with a grade item
         $item = grade_item::fetch(array('id' => $object->id));
         $element['type'] = 'item';
         $element['object'] = $item;
         // Determine aggregation coef element
         $dimmed = $item->is_hidden() ? " dimmed_text " : "";
         $html .= '<tr class="item' . $dimmed . $rowclasses . '">';
         foreach ($this->columns as $column) {
             if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
                 $html .= $column->get_item_cell($item, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'element' => $element, 'eid' => $eid, 'itemtype' => $object->itemtype));
             }
         }
         $html .= '</tr>';
     }
     if ($root) {
         $html .= "</table>\n";
     }
     return $html;
 }
Exemple #15
0
 function definition_after_data()
 {
     global $CFG, $COURSE;
     $mform =& $this->_form;
     $somecat = new grade_category();
     foreach ($somecat->forceable as $property) {
         if ((int) $CFG->{"grade_{$property}_flag"} & 1) {
             if ($mform->elementExists($property)) {
                 if (empty($CFG->grade_hideforcedsettings)) {
                     $mform->hardFreeze($property);
                 } else {
                     if ($mform->elementExists($property)) {
                         $mform->removeElement($property);
                     }
                 }
             }
         }
     }
     if ($CFG->grade_droplow > 0) {
         if ($mform->elementExists('keephigh')) {
             $mform->removeElement('keephigh');
         }
     } else {
         if ($CFG->grade_keephigh > 0) {
             if ($mform->elementExists('droplow')) {
                 $mform->removeElement('droplow');
             }
         }
     }
     if ($id = $mform->getElementValue('id')) {
         $grade_category = grade_category::fetch(array('id' => $id));
         $grade_item = $grade_category->load_grade_item();
         // remove agg coef if not used
         if ($grade_category->is_course_category()) {
             if ($mform->elementExists('parentcategory')) {
                 $mform->removeElement('parentcategory');
             }
             if ($mform->elementExists('aggregationcoef')) {
                 $mform->removeElement('aggregationcoef');
             }
         } else {
             // if we wanted to change parent of existing category - we would have to verify there are no circular references in parents!!!
             if ($mform->elementExists('parentcategory')) {
                 $mform->hardFreeze('parentcategory');
             }
             $parent_category = $grade_category->get_parent_category();
             $parent_category->apply_forced_settings();
             if (!$parent_category->is_aggregationcoef_used()) {
                 if ($mform->elementExists('aggregationcoef')) {
                     $mform->removeElement('aggregationcoef');
                 }
             } else {
                 //fix label if needed
                 $agg_el =& $mform->getElement('aggregationcoef');
                 $aggcoef = '';
                 if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
                     $aggcoef = 'aggregationcoefweight';
                 } else {
                     if ($parent_category->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
                         $aggcoef = 'aggregationcoefextra';
                     }
                 }
                 if ($aggcoef !== '') {
                     $agg_el->setLabel(get_string($aggcoef, 'grades'));
                     $mform->setHelpButton('aggregationcoef', array('aggregationcoef', get_string('aggregationcoef', 'grades'), 'grade'), true);
                 }
             }
         }
         if ($grade_item->is_calculated()) {
             // following elements are ignored when calculation formula used
             if ($mform->elementExists('aggregation')) {
                 $mform->removeElement('aggregation');
             }
             if ($mform->elementExists('keephigh')) {
                 $mform->removeElement('keephigh');
             }
             if ($mform->elementExists('droplow')) {
                 $mform->removeElement('droplow');
             }
             if ($mform->elementExists('aggregateonlygraded')) {
                 $mform->removeElement('aggregateonlygraded');
             }
             if ($mform->elementExists('aggregateoutcomes')) {
                 $mform->removeElement('aggregateoutcomes');
             }
             if ($mform->elementExists('aggregatesubcats')) {
                 $mform->removeElement('aggregatesubcats');
             }
         }
         // If it is a course category, remove the "required" rule from the "fullname" element
         if ($grade_category->is_course_category()) {
             unset($mform->_rules['fullname']);
             $key = array_search('fullname', $mform->_required);
             unset($mform->_required[$key]);
         }
         // If it is a course category and its fullname is ?, show an empty field
         if ($grade_category->is_course_category() && $mform->getElementValue('fullname') == '?') {
             $mform->setDefault('fullname', '');
         }
     }
     // no parent header for course category
     if (!$mform->elementExists('aggregationcoef') and !$mform->elementExists('parentcategory')) {
         $mform->removeElement('headerparent');
     }
 }
Exemple #16
0
 /**
  * Sets this item's categoryid. A generic method shared by objects that have a parent id of some kind.
  *
  * @param int $parentid The ID of the new parent
  * @param bool $updateaggregationfields Whether or not to convert the aggregation fields when switching between category.
  *                          Set this to false when the aggregation fields have been updated in prevision of the new
  *                          category, typically when the item is freshly created.
  * @return bool True if success
  */
 public function set_parent($parentid, $updateaggregationfields = true)
 {
     if ($this->is_course_item() or $this->is_category_item()) {
         print_error('cannotsetparentforcatoritem');
     }
     if ($this->categoryid == $parentid) {
         return true;
     }
     // find parent and check course id
     if (!($parent_category = grade_category::fetch(array('id' => $parentid, 'courseid' => $this->courseid)))) {
         return false;
     }
     $currentparent = $this->load_parent_category();
     if ($updateaggregationfields) {
         $this->set_aggregation_fields_for_aggregation($currentparent->aggregation, $parent_category->aggregation);
     }
     $this->force_regrading();
     // set new parent
     $this->categoryid = $parent_category->id;
     $this->parent_category =& $parent_category;
     return $this->update();
 }
 /**
  * Sets this item's categoryid. A generic method shared by objects that have a parent id of some kind.
  * @param int $parentid
  * @return boolean success;
  */
 function set_parent($parentid)
 {
     if ($this->is_course_item() or $this->is_category_item()) {
         error('Can not set parent for category or course item!');
     }
     if ($this->categoryid == $parentid) {
         return true;
     }
     // find parent and check course id
     if (!($parent_category = grade_category::fetch(array('id' => $parentid, 'courseid' => $this->courseid)))) {
         return false;
     }
     // MDL-19407 If moving from a non-SWM category to a SWM category, convert aggregationcoef to 0
     $currentparent = $this->load_parent_category();
     if ($currentparent->aggregation != GRADE_AGGREGATE_WEIGHTED_MEAN2 && $parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
         $this->aggregationcoef = 0;
     }
     $this->force_regrading();
     // set new parent
     $this->categoryid = $parent_category->id;
     $this->parent_category =& $parent_category;
     return $this->update();
 }
 function quick_dump()
 {
     global $CFG;
     require_once $CFG->dirroot . '/lib/excellib.class.php';
     //        $export_tracking = $this->track_exports();
     $strgrades = get_string('grades');
     $accuratetotals = get_user_preferences('accuratepointtotals') == null ? 1 : 0;
     /// Calculate file name
     $downloadfilename = clean_filename("{$this->course->shortname} {$strgrades}.xls");
     /// Creating a workbook
     $workbook = new MoodleExcelWorkbook("-");
     /// Sending HTTP headers
     $workbook->send($downloadfilename);
     /// Adding the worksheet
     $myxls =& $workbook->add_worksheet($strgrades);
     /// Print names of all the fields
     $myxls->write_string(0, 0, get_string("firstname"));
     $myxls->write_string(0, 1, get_string("lastname"));
     $myxls->write_string(0, 2, get_string("idnumber"));
     $myxls->write_string(0, 3, get_string("email"));
     $pos = 4;
     // write out column headers
     foreach ($this->gtree->items as $grade_item) {
         //            $myxls->write_string(0, $pos++, $this->format_column_name($grade_item));
         switch ($grade_item->itemtype) {
             case 'category':
                 $grade_item->item_category = grade_category::fetch(array('id' => $grade_item->iteminstance));
                 //                        $grade_item->load_category();
                 $myxls->write_string(0, $pos++, $grade_item->item_category->fullname . ' Category total');
                 break;
             case 'course':
                 $myxls->write_string(0, $pos++, 'Course total');
                 break;
             default:
                 $myxls->write_string(0, $pos++, $grade_item->itemname);
         }
         /// add a column_feedback column
         if (isset($this->export_feedback) and $this->export_feedback) {
             //                $myxls->write_string(0, $pos++, $this->format_column_name($grade_item, true));
             $myxls->write_string(0, $pos++, $grade_item->itemname);
         }
     }
     // write out range row
     $myxls->write_string(1, 2, 'Maximum grade->');
     $pos = 4;
     foreach ($this->gtree->items as $grade_item) {
         //            $myxls->write_string(0, $pos++, $this->format_column_name($grade_item));
         $myxls->write_number(1, $pos++, $grade_item->grademax);
         //            $myxls->write_number($i,$j++,$gradestr);
         /// add a column_feedback column
         if (isset($this->export_feedback) and $this->export_feedback) {
             //                $myxls->write_string(0, $pos++, $this->format_column_name($grade_item, true));
             $myxls->write_string(1, $pos++, $grade_item->name);
         }
     }
     // write out weights row
     $myxls->write_string(2, 2, 'Weight->');
     $pos = 4;
     foreach ($this->gtree->items as $grade_item) {
         if (isset($this->gtree->parents[$grade_item->id]->id) && $this->gtree->parents[$grade_item->id]->agg == GRADE_AGGREGATE_WEIGHTED_MEAN) {
             $myxls->write_number(2, $pos++, $grade_item->aggregationcoef);
             //                $myxls->write_string(1, $pos++, format_float($grade_item->aggregationcoef,0));
         } else {
             $myxls->write_string(2, $pos++, "");
         }
         /// add a column_feedback column
         if (isset($this->export_feedback) and $this->export_feedback) {
             $myxls->write_string(2, $pos++, $grade_item->name);
         }
     }
     /// Print all the lines of data.
     $i = 2;
     //        $geub = new grade_export_update_buffer();
     //        $gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
     //        $gui->init();
     foreach ($this->users as $key => $user) {
         $i++;
         //            $user = $userdata->user;
         $myxls->write_string($i, 0, $user->firstname);
         $myxls->write_string($i, 1, $user->lastname);
         $myxls->write_string($i, 2, $user->idnumber);
         $myxls->write_string($i, 3, $user->email);
         //           $myxls->write_string($i,3,$user->institution);
         //            $myxls->write_string($i,4,$user->department);
         //            $myxls->write_string($i,3,$user->email);
         $j = 4;
         foreach ($this->gtree->items as $itemid => $item) {
             //                if ($export_tracking) {
             //                    $status = $geub->track($grade);
             //                }
             $grade = $this->grades[$key][$itemid];
             $gradeval = $grade->finalgrade;
             // if gradeeditalways then we only want the first displaytype (in case multiple displaytypes are requested)
             $gradedisplaytype = (int) substr((string) $item->get_displaytype(), 0, 1);
             // if we have an accumulated total points that's not accurately reflected in the db, then we want to display the ACCURATE number
             if ($gradedisplaytype == GRADE_DISPLAY_TYPE_REAL && isset($this->grades[$userid][$grade->itemid]->cat_item)) {
                 $items = $this->gtree->items;
                 $grade_values = $this->grades[$userid][$grade->itemid]->cat_item;
                 $grade_maxes = $this->grades[$userid][$grade->itemid]->cat_max;
                 $this_cat = $this->gtree->items[$grade->itemid]->get_item_category();
                 limit_item($this_cat, $items, $grade_values, $grade_maxes);
                 $gradeval = array_sum($grade_values);
                 $item->grademax = array_sum($grade_maxes);
             }
             // is calculating accurate totals store the earned_total for this item to its parent, if there is one
             if (!$grade->is_hidden() && $gradeval != null && $this->accuratetotals) {
                 $this->grades[$userid][$this->gtree->parents[$grade->itemid]->id]->cat_item[$grade->itemid] = $gradeval;
                 $this->grades[$userid][$this->gtree->parents[$grade->itemid]->id]->cat_max[$grade->itemid] = $grade->rawgrademax;
             }
             $gradestr = grade_format_gradevalue($gradeval, $item, true, $gradedisplaytype, null);
             /*
             		   		if ($gradedisplaytype == GRADE_DISPLAY_TYPE_REAL && $this->accuratetotals) {
                                 $gradestr = grade_format_gradevalue($grade->earned_total, $item, true, $gradedisplaytype, null);
                             } else {
                                 $gradestr = grade_format_gradevalue($grade->finalgrade, $item, true, $gradedisplaytype, null);
                             }
             */
             if (is_percentage($gradestr)) {
                 $myxls->write_number($i, $j++, $gradestr * 0.01);
                 //                    $myxls->write_number($i,$j++,substr(trim($gradestr),0,strlen(trim($gradestr))-1), array(num_format=>'Percent'));
             } else {
                 if (is_numeric($gradestr)) {
                     $myxls->write_number($i, $j++, $gradestr);
                 } else {
                     $myxls->write_string($i, $j++, $gradestr);
                 }
             }
             /*
                            // writing feedback if requested
                            if ($this->export_feedback) {
                                $myxls->write_string($i, $j++, $this->format_feedback($userdata->feedbacks[$itemid]));
                            }
             * 
             */
         }
     }
     //        $gui->close();
     //        $geub->close();
     /// Close the workbook
     $workbook->close();
     exit;
 }
Exemple #19
0
    $item->aggregationcoef = $item->aggregationcoef == 0 ? 0 : 1;
} else {
    $item->aggregationcoef = format_float($item->aggregationcoef, 4);
}
if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
    $item->aggregationcoef2 = format_float($item->aggregationcoef2 * 100.0);
}
$item->cancontrolvisibility = $grade_item->can_control_visibility();
$mform = new edit_item_form(null, array('current' => $item, 'gpr' => $gpr));
if ($mform->is_cancelled()) {
    redirect($returnurl);
} else {
    if ($data = $mform->get_data(false)) {
        // This is a new item, and the category chosen is different than the default category.
        if (empty($grade_item->id) && isset($data->parentcategory) && $parent_category->id != $data->parentcategory) {
            $parent_category = grade_category::fetch(array('id' => $data->parentcategory));
        }
        // If unset, give the aggregation values a default based on parent aggregation method.
        $defaults = grade_category::get_default_aggregation_coefficient_values($parent_category->aggregation);
        if (!isset($data->aggregationcoef) || $data->aggregationcoef == '') {
            $data->aggregationcoef = $defaults['aggregationcoef'];
        }
        if (!isset($data->weightoverride)) {
            $data->weightoverride = $defaults['weightoverride'];
        }
        if (!isset($data->gradepass) || $data->gradepass == '') {
            $data->gradepass = 0;
        }
        if (!isset($data->grademin) || $data->grademin == '') {
            $data->grademin = 0;
        }
Exemple #20
0
 /**
  * Test can_output_item.
  */
 public function test_can_output_item()
 {
     $this->resetAfterTest();
     $generator = $this->getDataGenerator();
     // Course level grade category.
     $course = $generator->create_course();
     // Grade tree looks something like:
     // - Test course    (Rendered).
     $gradetree = grade_category::fetch_course_tree($course->id);
     $this->assertTrue(grade_tree::can_output_item($gradetree));
     // Add a grade category with default settings.
     $generator->create_grade_category(array('courseid' => $course->id));
     // Grade tree now looks something like:
     // - Test course n        (Rendered).
     // -- Grade category n    (Rendered).
     $gradetree = grade_category::fetch_course_tree($course->id);
     $this->assertNotEmpty($gradetree['children']);
     foreach ($gradetree['children'] as $child) {
         $this->assertTrue(grade_tree::can_output_item($child));
     }
     // Add a grade category with grade type = None.
     $nototalcategory = 'No total category';
     $nototalparams = ['courseid' => $course->id, 'fullname' => $nototalcategory, 'aggregation' => GRADE_AGGREGATE_WEIGHTED_MEAN];
     $nototal = $generator->create_grade_category($nototalparams);
     $catnototal = grade_category::fetch(array('id' => $nototal->id));
     // Set the grade type of the grade item associated to the grade category.
     $catitemnototal = $catnototal->load_grade_item();
     $catitemnototal->gradetype = GRADE_TYPE_NONE;
     $catitemnototal->update();
     // Grade tree looks something like:
     // - Test course n        (Rendered).
     // -- Grade category n    (Rendered).
     // -- No total category   (Not rendered).
     $gradetree = grade_category::fetch_course_tree($course->id);
     foreach ($gradetree['children'] as $child) {
         if ($child['object']->fullname == $nototalcategory) {
             $this->assertFalse(grade_tree::can_output_item($child));
         } else {
             $this->assertTrue(grade_tree::can_output_item($child));
         }
     }
     // Add another grade category with default settings under 'No total category'.
     $normalinnototalparams = ['courseid' => $course->id, 'fullname' => 'Normal category in no total category', 'parent' => $nototal->id];
     $generator->create_grade_category($normalinnototalparams);
     // Grade tree looks something like:
     // - Test course n                           (Rendered).
     // -- Grade category n                       (Rendered).
     // -- No total category                      (Rendered).
     // --- Normal category in no total category  (Rendered).
     $gradetree = grade_category::fetch_course_tree($course->id);
     foreach ($gradetree['children'] as $child) {
         // All children are now visible.
         $this->assertTrue(grade_tree::can_output_item($child));
         if (!empty($child['children'])) {
             foreach ($child['children'] as $grandchild) {
                 $this->assertTrue(grade_tree::can_output_item($grandchild));
             }
         }
     }
     // Add a grade category with grade type = None.
     $nototalcategory2 = 'No total category 2';
     $nototal2params = ['courseid' => $course->id, 'fullname' => $nototalcategory2, 'aggregation' => GRADE_AGGREGATE_WEIGHTED_MEAN];
     $nototal2 = $generator->create_grade_category($nototal2params);
     $catnototal2 = grade_category::fetch(array('id' => $nototal2->id));
     // Set the grade type of the grade item associated to the grade category.
     $catitemnototal2 = $catnototal2->load_grade_item();
     $catitemnototal2->gradetype = GRADE_TYPE_NONE;
     $catitemnototal2->update();
     // Add a category with no total under 'No total category'.
     $nototalinnototalcategory = 'Category with no total in no total category';
     $nototalinnototalparams = ['courseid' => $course->id, 'fullname' => $nototalinnototalcategory, 'aggregation' => GRADE_AGGREGATE_WEIGHTED_MEAN, 'parent' => $nototal2->id];
     $nototalinnototal = $generator->create_grade_category($nototalinnototalparams);
     $catnototalinnototal = grade_category::fetch(array('id' => $nototalinnototal->id));
     // Set the grade type of the grade item associated to the grade category.
     $catitemnototalinnototal = $catnototalinnototal->load_grade_item();
     $catitemnototalinnototal->gradetype = GRADE_TYPE_NONE;
     $catitemnototalinnototal->update();
     // Grade tree looks something like:
     // - Test course n                                    (Rendered).
     // -- Grade category n                                (Rendered).
     // -- No total category                               (Rendered).
     // --- Normal category in no total category           (Rendered).
     // -- No total category 2                             (Not rendered).
     // --- Category with no total in no total category    (Not rendered).
     $gradetree = grade_category::fetch_course_tree($course->id);
     foreach ($gradetree['children'] as $child) {
         if ($child['object']->fullname == $nototalcategory2) {
             $this->assertFalse(grade_tree::can_output_item($child));
         } else {
             $this->assertTrue(grade_tree::can_output_item($child));
         }
         if (!empty($child['children'])) {
             foreach ($child['children'] as $grandchild) {
                 if ($grandchild['object']->fullname == $nototalinnototalcategory) {
                     $this->assertFalse(grade_tree::can_output_item($grandchild));
                 } else {
                     $this->assertTrue(grade_tree::can_output_item($grandchild));
                 }
             }
         }
     }
 }
Exemple #21
0
 /**
  * Sets this item's categoryid. A generic method shared by objects that have a parent id of some kind.
  * @param int $parentid
  * @return boolean success;
  */
 function set_parent($parentid)
 {
     if ($this->is_course_item() or $this->is_category_item()) {
         error('Can not set parent for category or course item!');
     }
     if ($this->categoryid == $parentid) {
         return true;
     }
     // find parent and check course id
     if (!($parent_category = grade_category::fetch(array('id' => $parentid, 'courseid' => $this->courseid)))) {
         return false;
     }
     $this->force_regrading();
     // set new parent
     $this->categoryid = $parent_category->id;
     $this->parent_category =& $parent_category;
     return $this->update();
 }
 /**
  * Preprocesses the creation of a grade item. Converts gradetype text to a number.
  * @param array $data
  * @return array
  */
 protected function preprocess_grade_item($data)
 {
     global $CFG;
     require_once "{$CFG->libdir}/grade/constants.php";
     if (isset($data['gradetype'])) {
         $data['gradetype'] = constant("GRADE_TYPE_" . strtoupper($data['gradetype']));
     }
     if (!empty($data['category']) && !empty($data['courseid'])) {
         $cat = grade_category::fetch(array('fullname' => $data['category'], 'courseid' => $data['courseid']));
         if (!$cat) {
             throw new Exception('Could not resolve category with name "' . $data['category'] . '"');
         }
         unset($data['category']);
         $data['categoryid'] = $cat->id;
     }
     return $data;
 }
Exemple #23
0
 /**
  * Recurses through the entire grade tree to find and return the maximum depth of the tree.
  * This should be run only once from the root element (course category), and is used for the
  * indentation of the Name column's cells (colspan)
  *
  * @param array $element An array of values representing a grade tree's element (all grade items in this case)
  * @param int $level The level of the current recursion
  * @param int $deepest_level A value passed to each subsequent level of recursion and incremented if $level > $deepest_level
  * @return int Deepest level
  */
 function get_deepest_level($element, $level = 0, $deepest_level = 1)
 {
     $object = $element['object'];
     $level++;
     $coefstring = $element['object']->get_coefstring();
     if ($element['type'] == 'category') {
         if ($coefstring == 'aggregationcoefweight' || $coefstring == 'aggregationcoefextraweightsum' || $coefstring == 'aggregationcoefextraweight') {
             $this->uses_weight = true;
         }
         foreach ($element['children'] as $child_el) {
             if ($level > $deepest_level) {
                 $deepest_level = $level;
             }
             $deepest_level = $this->get_deepest_level($child_el, $level, $deepest_level);
         }
         $category = grade_category::fetch(array('id' => $object->id));
         $item = $category->get_grade_item();
         if ($item->gradetype == GRADE_TYPE_NONE) {
             // Add 1 more level for grade category that has no total.
             $deepest_level++;
         }
     }
     return $deepest_level;
 }
Exemple #24
0
 function definition_after_data()
 {
     global $CFG, $COURSE;
     $mform =& $this->_form;
     $somecat = new grade_category();
     foreach ($somecat->forceable as $property) {
         if ((int) $CFG->{"grade_{$property}_flag"} & 1) {
             if ($mform->elementExists($property)) {
                 if (empty($CFG->grade_hideforcedsettings)) {
                     $mform->hardFreeze($property);
                 } else {
                     if ($mform->elementExists($property)) {
                         $mform->removeElement($property);
                     }
                 }
             }
         }
     }
     if ($CFG->grade_droplow > 0) {
         if ($mform->elementExists('keephigh')) {
             $mform->removeElement('keephigh');
         }
     } else {
         if ($CFG->grade_keephigh > 0) {
             if ($mform->elementExists('droplow')) {
                 $mform->removeElement('droplow');
             }
         }
     }
     if ($id = $mform->getElementValue('id')) {
         $grade_category = grade_category::fetch(array('id' => $id));
         $grade_item = $grade_category->load_grade_item();
         // remove agg coef if not used
         if ($grade_category->is_course_category()) {
             if ($mform->elementExists('parentcategory')) {
                 $mform->removeElement('parentcategory');
             }
             if ($mform->elementExists('currentparentaggregation')) {
                 $mform->removeElement('currentparentaggregation');
             }
         } else {
             // if we wanted to change parent of existing category - we would have to verify there are no circular references in parents!!!
             if ($mform->elementExists('parentcategory')) {
                 $mform->hardFreeze('parentcategory');
             }
             $parent_cat = $grade_category->get_parent_category();
             $mform->setDefault('currentparentaggregation', $this->aggregation_options[$parent_cat->aggregation]);
         }
         if ($grade_item->is_calculated()) {
             // following elements are ignored when calculation formula used
             if ($mform->elementExists('aggregation')) {
                 $mform->removeElement('aggregation');
             }
             if ($mform->elementExists('keephigh')) {
                 $mform->removeElement('keephigh');
             }
             if ($mform->elementExists('droplow')) {
                 $mform->removeElement('droplow');
             }
             if ($mform->elementExists('aggregateonlygraded')) {
                 $mform->removeElement('aggregateonlygraded');
             }
             if ($mform->elementExists('aggregateoutcomes')) {
                 $mform->removeElement('aggregateoutcomes');
             }
             if ($mform->elementExists('aggregatesubcats')) {
                 $mform->removeElement('aggregatesubcats');
             }
         }
         // If it is a course category, remove the "required" rule from the "fullname" element
         if ($grade_category->is_course_category()) {
             unset($mform->_rules['fullname']);
             $key = array_search('fullname', $mform->_required);
             unset($mform->_required[$key]);
         }
         // If it is a course category and its fullname is ?, show an empty field
         if ($grade_category->is_course_category() && $mform->getElementValue('fullname') == '?') {
             $mform->setDefault('fullname', '');
         }
         // remove unwanted aggregation options
         if ($mform->elementExists('aggregation')) {
             $allaggoptions = array_keys($this->aggregation_options);
             $agg_el =& $mform->getElement('aggregation');
             $visible = explode(',', $CFG->grade_aggregations_visible);
             if (!is_null($grade_category->aggregation)) {
                 // current type is always visible
                 $visible[] = $grade_category->aggregation;
             }
             foreach ($allaggoptions as $type) {
                 if (!in_array($type, $visible)) {
                     $agg_el->removeOption($type);
                 }
             }
         }
     } else {
         // adding new category
         if ($mform->elementExists('currentparentaggregation')) {
             $mform->removeElement('currentparentaggregation');
         }
         // remove unwanted aggregation options
         if ($mform->elementExists('aggregation')) {
             $allaggoptions = array_keys($this->aggregation_options);
             $agg_el =& $mform->getElement('aggregation');
             $visible = explode(',', $CFG->grade_aggregations_visible);
             foreach ($allaggoptions as $type) {
                 if (!in_array($type, $visible)) {
                     $agg_el->removeOption($type);
                 }
             }
         }
     }
     // no parent header for course category
     if (!$mform->elementExists('parentcategory')) {
         $mform->removeElement('headerparent');
     }
     /// GRADE ITEM
     if ($id = $mform->getElementValue('id')) {
         $grade_category = grade_category::fetch(array('id' => $id));
         $grade_item = $grade_category->load_grade_item();
         $mform->setDefault('grade_item_hidden', (int) $grade_item->hidden);
         if ($grade_item->is_outcome_item()) {
             // we have to prevent incompatible modifications of outcomes if outcomes disabled
             $mform->removeElement('grade_item_grademax');
             $mform->removeElement('grade_item_grademin');
             $mform->removeElement('grade_item_gradetype');
             $mform->removeElement('grade_item_display');
             $mform->removeElement('grade_item_decimals');
             $mform->hardFreeze('grade_item_scaleid');
         }
         //remove the aggregation coef element if not needed
         if ($grade_item->is_course_item()) {
             if ($mform->elementExists('grade_item_aggregationcoef')) {
                 $mform->removeElement('grade_item_aggregationcoef');
             }
         } else {
             if ($grade_item->is_category_item()) {
                 $category = $grade_item->get_item_category();
                 $parent_category = $category->get_parent_category();
             } else {
                 $parent_category = $grade_item->get_parent_category();
             }
             $parent_category->apply_forced_settings();
             if (!$parent_category->is_aggregationcoef_used()) {
                 if ($mform->elementExists('grade_item_aggregationcoef')) {
                     $mform->removeElement('grade_item_aggregationcoef');
                 }
             } else {
                 $coefstring = $grade_item->get_coefstring();
                 if ($coefstring == 'aggregationcoefextrasum') {
                     // advcheckbox is not compatible with disabledIf!
                     $element =& $mform->createElement('checkbox', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
                 } else {
                     $element =& $mform->createElement('text', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
                 }
                 $mform->insertElementBefore($element, 'parentcategory');
                 $mform->addHelpButton('grade_item_aggregationcoef', $coefstring, 'grades');
             }
         }
     }
 }
Exemple #25
0
$PAGE->set_pagelayout('admin');
/// Make sure they can even access this course
if (!($course = $DB->get_record('course', array('id' => $courseid)))) {
    print_error('nocourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
// todo $PAGE->requires->js_module() should be used here instead
$PAGE->requires->js('/grade/edit/tree/functions.js');
/// return tracking object
$gpr = new grade_plugin_return(array('type' => 'edit', 'plugin' => 'tree', 'courseid' => $courseid));
$returnurl = $gpr->get_return_url(null);
// Change category aggregation if requested
if (!is_null($category) && !is_null($aggregationtype) && confirm_sesskey()) {
    if (!($grade_category = grade_category::fetch(array('id' => $category, 'courseid' => $courseid)))) {
        print_error('invalidcategoryid');
    }
    $data = new stdClass();
    $data->aggregation = $aggregationtype;
    grade_category::set_properties($grade_category, $data);
    $grade_category->update();
    grade_regrade_final_grades($courseid);
}
//first make sure we have proper final grades - we need it for locking changes
$normalisationmessage = null;
$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
grade_regrade_final_grades($courseid);
$alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
if (array_diff($originalweights, $alteredweights)) {
    $normalisationmessage = get_string('weightsadjusted', 'grades');
 function test_gradebook()
 {
     global $DB;
     $this->resetAfterTest(true);
     // reset all changes automatically after this test
     $location_str = 'manual';
     // try to get category
     $grade_category = grade_category::fetch(array('courseid' => $this->courseid, 'fullname' => $this->cat_name));
     // NOTE: grade category will not be null but it will be empty
     $this->assertFalse($grade_category);
     // create a category
     $params = new stdClass();
     $params->courseid = $this->courseid;
     $params->fullname = $this->cat_name;
     $grade_category = new grade_category($params, false);
     $this->assertTrue(method_exists($grade_category, 'insert'));
     $grade_category->insert($location_str);
     // now we will really get the category that we just made
     $grade_category_fetched = grade_category::fetch(array('courseid' => $this->courseid, 'fullname' => $this->cat_name));
     $this->assertTrue($grade_category_fetched !== false);
     $this->assertEquals($grade_category->id, $grade_category_fetched->id);
     $this->assertEquals($grade_category->courseid, $grade_category_fetched->courseid);
     $this->assertEquals($grade_category->path, $grade_category_fetched->path);
     $this->assertEquals($grade_category->fullname, $grade_category_fetched->fullname);
     $this->assertEquals($grade_category->parent, $grade_category_fetched->parent);
     // try to get grade item
     $grade_item = grade_item::fetch(array('courseid' => $this->courseid, 'categoryid' => $grade_category->id, 'itemname' => $this->item_name));
     // NOTE: grade category will not be null but it will be empty
     $this->assertFalse($grade_item);
     // create a grade item
     $grade_item = new grade_item();
     $this->assertTrue(method_exists($grade_item, 'insert'));
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $grade_category->id;
     $grade_item->idnumber = $this->item_name;
     // lookup
     $grade_item->itemname = $this->item_name;
     // display
     $grade_item->itemtype = 'blocks';
     $grade_item->itemmodule = 'iclicker';
     $grade_item->iteminfo = 'blocks/iclicker for unit testing';
     // grademax=100, grademin=0
     $grade_item->grademax = 100.0;
     $grade_item->insert($location_str);
     // now we will really get the new item
     $grade_item_fetched = grade_item::fetch(array('courseid' => $this->courseid, 'categoryid' => $grade_category->id, 'itemname' => $this->item_name));
     $this->assertTrue($grade_item_fetched !== false);
     $this->assertEquals($grade_item->id, $grade_item_fetched->id);
     $this->assertEquals($grade_item->courseid, $grade_item_fetched->courseid);
     $this->assertEquals($grade_item->categoryid, $grade_item_fetched->categoryid);
     $this->assertEquals($grade_item->itemname, $grade_item_fetched->itemname);
     // get empty grades list
     $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id));
     $this->assertFalse($all_grades);
     // add grade
     $grade_grade = new grade_grade();
     $this->assertTrue(method_exists($grade_grade, 'insert'));
     $grade_grade->itemid = $grade_item->id;
     $grade_grade->userid = $this->studentid1;
     $grade_grade->rawgrade = $this->grade_score;
     $grade_grade->insert($location_str);
     // get new grade
     $grade_grade_fetched = grade_grade::fetch(array('itemid' => $grade_item->id, 'userid' => $this->studentid1));
     $this->assertTrue($grade_grade_fetched !== false);
     $this->assertEquals($grade_grade->id, $grade_grade_fetched->id);
     $this->assertEquals($grade_grade->itemid, $grade_grade_fetched->itemid);
     $this->assertEquals($grade_grade->userid, $grade_grade_fetched->userid);
     $this->assertEquals($grade_grade->rawgrade, $grade_grade_fetched->rawgrade);
     // update the grade
     $grade_grade->rawgrade = 50;
     $result = $grade_grade->update($location_str);
     $this->assertTrue($result);
     $grade_grade_fetched = grade_grade::fetch(array('id' => $grade_grade->id));
     $this->assertTrue($grade_grade_fetched !== false);
     $this->assertEquals($grade_grade->id, $grade_grade_fetched->id);
     $this->assertEquals($grade_grade->rawgrade, $grade_grade_fetched->rawgrade);
     $this->assertEquals(50, $grade_grade_fetched->rawgrade);
     // get grades
     $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id));
     $this->assertTrue($all_grades !== false);
     $this->assertEquals(1, sizeof($all_grades));
     // add more grades
     $grade_grade2 = new grade_grade();
     $grade_grade2->itemid = $grade_item->id;
     $grade_grade2->userid = $this->studentid2;
     $grade_grade2->rawgrade = $this->grade_score;
     $grade_grade2->insert($location_str);
     // get grades
     $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id));
     $this->assertTrue($all_grades !== false);
     $this->assertEquals(2, sizeof($all_grades));
     // make sure this can run
     $result = $grade_item->regrade_final_grades();
     $this->assertTrue($result);
     // remove grades
     $this->assertTrue(method_exists($grade_grade, 'delete'));
     $result = $grade_grade->delete($location_str);
     $this->assertTrue($result);
     $result = $grade_grade2->delete($location_str);
     $this->assertTrue($result);
     // check no grades left
     $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id));
     $this->assertFalse($all_grades);
     // remove grade item
     $this->assertTrue(method_exists($grade_item, 'delete'));
     $result = $grade_item->delete($location_str);
     $this->assertTrue($result);
     // remove grade category
     $this->assertTrue(method_exists($grade_category, 'delete'));
     $result = $grade_category->delete($location_str);
     $this->assertTrue($result);
     $this->resetAfterTest();
 }