From 7bd4a361b3731e6d9401b0a35737f2e255914152 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Tue, 23 Sep 2014 02:47:47 +0000 Subject: [PATCH 01/16] MDL-18229 gradebook: Initial commit of LSUs Quick Edit Plugin Renamed to Single View in MDL-47289. --- grade/report/single_view/README.md | 21 + grade/report/single_view/classes/lib.php | 388 ++++++++++++ grade/report/single_view/classes/uilib.php | 563 ++++++++++++++++++ grade/report/single_view/db/access.php | 40 ++ grade/report/single_view/index.php | 132 ++++ grade/report/single_view/js/single_view.js | 41 ++ .../lang/en/gradereport_single_view.php | 44 ++ grade/report/single_view/lib.php | 161 +++++ .../report/single_view/screens/grade/lib.php | 193 ++++++ .../report/single_view/screens/select/lib.php | 50 ++ grade/report/single_view/screens/user/lib.php | 120 ++++ grade/report/single_view/styles.css | 27 + grade/report/single_view/version.php | 27 + 13 files changed, 1807 insertions(+) create mode 100644 grade/report/single_view/README.md create mode 100644 grade/report/single_view/classes/lib.php create mode 100644 grade/report/single_view/classes/uilib.php create mode 100755 grade/report/single_view/db/access.php create mode 100755 grade/report/single_view/index.php create mode 100644 grade/report/single_view/js/single_view.js create mode 100755 grade/report/single_view/lang/en/gradereport_single_view.php create mode 100755 grade/report/single_view/lib.php create mode 100644 grade/report/single_view/screens/grade/lib.php create mode 100644 grade/report/single_view/screens/select/lib.php create mode 100644 grade/report/single_view/screens/user/lib.php create mode 100644 grade/report/single_view/styles.css create mode 100755 grade/report/single_view/version.php diff --git a/grade/report/single_view/README.md b/grade/report/single_view/README.md new file mode 100644 index 00000000000..036ab6e05bb --- /dev/null +++ b/grade/report/single_view/README.md @@ -0,0 +1,21 @@ +LSU Single view +============== + +Single view is a simple Moodle Gradebook plugin which allows teahers to do some awesome things. + +Single view allows for editing of multiple grades for a single grade item and all grade items for a single user. + +It allows the instructor to insert an arbitrary value ofr all students for a single item (incredibly useful) or all items for a single student (less useful). + +Single view also allows for inserting an arbitrary value for all empty items, allowing you to add zero grades for empties in one step. + +It also allows for bulk overrides. + +Single view works best with the LSU Gradebook. + +Installation Instructions +============== + +1. Drop into your grade/reports folder. +2. Click Notifications. + diff --git a/grade/report/single_view/classes/lib.php b/grade/report/single_view/classes/lib.php new file mode 100644 index 00000000000..4347e47eecb --- /dev/null +++ b/grade/report/single_view/classes/lib.php @@ -0,0 +1,388 @@ +dirroot . '/grade/report/single_view/classes/uilib.php'; + +interface selectable_items { + public function description(); + + public function options(); + + public function item_type(); +} + +interface item_filtering { + public static function filter($item); +} + +abstract class single_view_screen { + var $courseid; + + var $itemid; + + var $groupid; + + var $context; + + var $page; + + var $perpage; + + function __construct($courseid, $itemid, $groupid = null) { + global $DB; + + $this->courseid = $courseid; + $this->itemid = $itemid; + $this->groupid = $groupid; + + $this->context = context_course::instance($this->courseid); + $this->course = $DB->get_record('course', array('id' => $courseid)); + + $this->page = optional_param('page', 0, PARAM_INT); + $this->perpage = optional_param('perpage', 300, PARAM_INT); + + $this->init(empty($itemid)); + } + + public function setup_structure() { + $this->structure = new grade_structure(); + $this->structure->modinfo = get_fast_modinfo($this->course); + } + + public function format_link($screen, $itemid, $display = null) { + $url = new moodle_url('/grade/report/single_view/index.php', array( + 'id' => $this->courseid, + 'item' => $screen, + 'itemid' => $itemid, + 'group' => $this->groupid + )); + + if ($display) { + return html_writer::link($url, $display); + } else { + return $url; + } + } + + public function fetch_grade_or_default($item, $userid) { + $grade = grade_grade::fetch(array( + 'itemid' => $item->id, 'userid' => $userid + )); + + if (!$grade) { + $default = new stdClass; + + $default->userid = $userid; + $default->itemid = $item->id; + $default->feedback = ''; + + $grade = new grade_grade($default, false); + } + + $grade->grade_item = $item; + + return $grade; + } + + public function make_toggle($key) { + $attrs = array('href' => '#'); + + $all = html_writer::tag('a', get_string('all'), $attrs + array( + 'class' => 'include all ' . $key + )); + + $none = html_writer::tag('a', get_string('none'), $attrs + array( + 'class' => 'include none ' . $key + )); + + return html_writer::tag('span', "$all / $none", array( + 'class' => 'inclusion_links' + )); + } + + public function make_toggle_links($key) { + return get_string($key, 'gradereport_single_view') . ' ' . + $this->make_toggle($key); + } + + public function heading() { + return get_string('pluginname', 'gradereport_single_view'); + } + + public abstract function init($self_item_is_empty = false); + + public abstract function html(); + + public function supports_paging() { + return false; + } + + public function pager() { + if (!$this->supports_paging()) { + return ''; + } + + global $OUTPUT; + + list($___, $item) = explode('single_view_', get_class($this)); + + return $OUTPUT->paging_bar( + count($this->items), $this->page, $this->perpage, + new moodle_url('/grade/report/single_view/index.php', array( + 'perpage' => $this->perpage, + 'id' => $this->courseid, + 'groupid' => $this->groupid, + 'itemid' => $this->itemid, + 'item' => $item + )) + ); + } + + public function js() { + global $PAGE; + + $module = array( + 'name' => 'gradereport_single_view', + 'fullpath' => '/grade/report/single_view/js/single_view.js', + 'requires' => array('base', 'dom', 'event', 'event-simulate', 'io-base') + ); + + $PAGE->requires->js_init_call('M.gradereport_single_view.init', array(), false, $module); + } + + public function factory() { + if (empty($this->__factory)) { + $this->__factory = new single_view_grade_ui_factory(); + } + + return $this->__factory; + } + + public function process($data) { + $warnings = array(); + + $fields = $this->definition(); + + foreach ($data as $varname => $throw) { + if (preg_match("/(\w+)_(\d+)_(\d+)/", $varname, $matches)) { + $itemid = $matches[2]; + $userid = $matches[3]; + } else { + continue; + } + + if (!in_array($matches[1], $fields)) { + continue; + } + + $grade_item = grade_item::fetch(array( + 'id' => $itemid, 'courseid' => $this->courseid + )); + + if (!$grade_item) { + continue; + } + + $grade = $this->fetch_grade_or_default($grade_item, $userid); + + $element = $this->factory()->create($matches[1])->format($grade); + + $name = $element->get_name(); + $oldname = "old$name"; + + $posted = $data->$name; + $oldvalue = $data->$oldname; + + $format = $element->determine_format(); + + if ($format->is_textbox() and trim($data->$name) === '') { + $data->$name = null; + } + + // Same value; skip + if ($oldvalue == $posted) { + continue; + } + + $msg = $element->set($posted); + + // Optional type + if (!empty($msg)) { + $warnings[] = $msg; + } + } + + // Some post-processing + $event_data = new stdClass; + $event_data->warnings = $warnings; + $event_data->post_data = $data; + $event_data->instance = $this; + + qe_events_trigger(get_class($this) . '_edited', $event_data); + + return $event_data->warnings; + } + + public function display_group_selector() { + return true; + } +} + +abstract class single_view_tablelike extends single_view_screen implements tabbable { + var $items; + + protected $headers = array(); + + protected $definition = array(); + + public abstract function format_line($item); + + public function headers() { + return $this->headers; + } + + public function set_headers($overwrite) { + $this->headers = $overwrite; + return $this; + } + + public function definition() { + return $this->definition; + } + + public function set_definition($overwrite) { + $this->definition = $overwrite; + return $this; + } + + public function get_tabindex() { + return (count($this->definition()) * $this->total) + $this->index; + } + + // Special injection for bulk operations + public function process($data) { + $bulk = $this->factory()->create('bulk_insert')->format($this->item); + + // Bulk insert messages the data to be passed in + // ie: for all grades of empty grades apply the specified value + if ($bulk->is_applied($data)) { + $filter = $bulk->get_type($data); + $insert_value = $bulk->get_insert_value($data); + + // Appropriately massage data that may not exist + if ($this->supports_paging()) { + // TODO: this only works with the grade screen... + $grade_item = grade_item::fetch(array( + 'courseid' => $this->courseid, + 'id' => $this->item->id + )); + + $null = $grade_item->gradetype == GRADE_TYPE_SCALE ? -1 : ''; + + foreach ($this->all_items as $itemid => $item) { + $field = "finalgrade_{$grade_item->id}_{$itemid}"; + if (isset($data->$field)) { + continue; + } + + $grade = grade_grade::fetch(array( + 'itemid' => $grade_item->id, + 'userid' => $itemid + )); + + $data->$field = empty($grade) ? $null : $grade->finalgrade; + $data->{"old$field"} = $data->$field; + } + } + + foreach ($data as $varname => $value) { + if (!preg_match('/^finalgrade_(\d+)_/', $varname, $matches)) { + continue; + } + + $grade_item = grade_item::fetch(array( + 'courseid' => $this->courseid, + 'id' => $matches[1] + )); + + $is_scale = ($grade_item->gradetype == GRADE_TYPE_SCALE); + + $empties = (trim($value) === '' or ($is_scale and $value == -1)); + + if ($filter == 'all' or $empties) { + $data->$varname = ($is_scale and empty($insert_value)) ? + -1 : $insert_value; + } + } + } + + return parent::process($data); + } + + public function format_definition($line, $grade) { + foreach ($this->definition() as $i => $field) { + // Table tab index + $tab = ($i * $this->total) + $this->index; + + $html = $this->factory()->create($field)->format($grade, $tab); + + if ($field == 'finalgrade' and !empty($this->structure)) { + $html .= $this->structure->get_grade_analysis_icon($grade); + } + + $line[] = $html; + } + + return $line; + } + + public function html() { + $table = new html_table(); + + $table->head = $this->headers(); + + // To be used for extra formatting + $this->index = 0; + $this->total = count($this->items); + + foreach ($this->items as $item) { + $this->index ++; + $table->data[] = $this->format_line($item); + } + + $underlying = get_class($this); + + $data = new stdClass; + $data->table = $table; + $data->instance = $this; + + qe_events_trigger($underlying . '_table_built', $data); + + $button_attr = array('class' => 'single_view_buttons submit'); + $button_html = implode(' ', $this->buttons()); + + $buttons = html_writer::tag('div', $button_html, $button_attr); + + return html_writer::tag('form', + $buttons . html_writer::table($table) . $this->bulk_insert() . $buttons, + array('method' => 'POST') + ); + } + + public function bulk_insert() { + return html_writer::tag( + 'div', + $this->factory()->create('bulk_insert')->format($this->item)->html(), + array('class' => 'single_view_bulk') + ); + } + + public function buttons() { + $save = html_writer::empty_tag('input', array( + 'type' => 'submit', + 'value' => get_string('update'), + 'tabindex' => $this->get_tabindex() + )); + + return array($save); + } +} diff --git a/grade/report/single_view/classes/uilib.php b/grade/report/single_view/classes/uilib.php new file mode 100644 index 00000000000..5faa3f983ef --- /dev/null +++ b/grade/report/single_view/classes/uilib.php @@ -0,0 +1,563 @@ +wrap("single_view_{$type}_ui"); + } +} + +class single_view_factory_class_wrap { + function __construct($class) { + $this->class = $class; + } + + function format() { + $args = func_get_args(); + + $reflect = new ReflectionClass($this->class); + return $reflect->newInstanceArgs($args); + } +} + +abstract class single_view_ui_element { + var $name; + var $value; + + function __construct($name, $value) { + $this->name = $name; + $this->value = $value; + } + + function is_checkbox() { + return false; + } + + function is_textbox() { + return false; + } + + function is_dropdown() { + return false; + } + + abstract function html(); +} + +class single_view_empty_element extends single_view_ui_element { + function __construct($msg = null) { + if (is_null($msg)) { + $this->text = get_string('notavailable', 'gradereport_single_view'); + } else { + $this->text = $msg; + } + } + + function html() { + return $this->text; + } +} + +class single_view_text_attribute extends single_view_ui_element { + var $is_disabled; + var $tabindex; + + function __construct($name, $value, $is_disabled = false, $tabindex = null) { + $this->is_disabled = $is_disabled; + $this->tabindex = $tabindex; + parent::__construct($name, $value); + } + + function is_textbox() { + return true; + } + + function html() { + $attributes = array( + 'type' => 'text', + 'name' => $this->name, + 'value' => $this->value + ); + + if (!empty($this->tabindex)) { + $attributes['tabindex'] = $this->tabindex; + } + if ($this->is_disabled) { + $attributes['disabled'] = 'DISABLED'; + } + + $hidden = array( + 'type' => 'hidden', + 'name' => 'old' . $this->name, + 'value' => $this->value + ); + + return ( + html_writer::empty_tag('input', $attributes) . + html_writer::empty_tag('input', $hidden) + ); + } +} + +class single_view_checkbox_attribute extends single_view_ui_element { + var $is_checked; + var $tabindex; + + // UCSB 2014-02-28 - add $locked to disable override checkbox when grade is locked + function __construct($name, $is_checked = false, $tabindex = null, $locked=0) { + $this->is_checked = $is_checked; + $this->tabindex = $tabindex; + $this->locked = $locked; + parent::__construct($name, 1); + } + + function is_checkbox() { + return true; + } + + function html() { + + $attributes = array( + 'type' => 'checkbox', + 'name' => $this->name, + 'value' => 1 + ); + + // UCSB fixed user should not be able to override locked grade + if ( $this->locked) { + $attributes['disabled'] = 'DISABLED'; + } + + $alt = array( + 'type' => 'hidden', + 'name' => $this->name, + 'value' => 0 + ); + + $hidden = array( + 'type' => 'hidden', + 'name' => 'old' . $this->name + ); + + if (!empty($this->tabindex)) { + $attributes['tabindex'] = $this->tabindex; + } + + if ($this->is_checked) { + $attributes['checked'] = 'CHECKED'; + $hidden['value'] = 1; + } + + return ( + html_writer::empty_tag('input', $alt) . + html_writer::empty_tag('input', $attributes) . + html_writer::empty_tag('input', $hidden) + ); + } +} + +class single_view_dropdown_attribute extends single_view_ui_element { + var $selected; + var $options; + var $is_disabled; + + function __construct($name, $options, $selected = '', $is_disabled = false, $tabindex = null) { + $this->selected = $selected; + $this->options = $options; + $this->tabindex = $tabindex; + $this->is_disabled = $is_disabled; + parent::__construct($name, $selected); + } + + function is_dropdown() { + return true; + } + + function html() { + $old = array( + 'type' => 'hidden', + 'name' => 'old' . $this->name, + 'value' => $this->selected + ); + + $attributes = array(); + if (!empty($this->tabindex)) { + $attributes['tabindex'] = $this->tabindex; + } + + if (!empty($this->is_disabled)) { + $attributes['disabled'] = 'DISABLED'; + } + + $select = html_writer::select( + $this->options, $this->name, $this->selected, false, $attributes + ); + + return ($select . html_writer::empty_tag('input', $old)); + } +} + +abstract class single_view_grade_attribute_format extends single_view_attribute_format implements unique_name, tabbable { + var $name; + + function __construct() { + $args = func_get_args(); + + $this->get_arg_or_nothing($args, 0, 'grade'); + $this->get_arg_or_nothing($args, 1, 'tabindex'); + } + + function get_name() { + return "{$this->name}_{$this->grade->itemid}_{$this->grade->userid}"; + } + + function get_tabindex() { + return isset($this->tabindex) ? $this->tabindex : null; + } + + private function get_arg_or_nothing($args, $index, $field) { + if (isset($args[$index])) { + $this->$field = $args[$index]; + } + } + + public abstract function set($value); +} + +interface unique_name { + function get_name(); +} + +interface unique_value { + function get_value(); +} + +interface be_disabled { + function is_disabled(); +} + +interface be_checked { + function is_checked(); +} + +interface tabbable { + function get_tabindex(); +} + +class single_view_bulk_insert_ui extends single_view_ui_element { + function __construct($item) { + $this->name = 'bulk_' . $item->id; + $this->applyname = $this->name_for('apply'); + $this->selectname = $this->name_for('type'); + $this->insertname = $this->name_for('value'); + } + + function is_applied($data) { + return isset($data->{$this->applyname}); + } + + function get_type($data) { + return $data->{$this->selectname}; + } + + function get_insert_value($data) { + return $data->{$this->insertname}; + } + + function html() { + $_s = function($key) { + return get_string($key, 'gradereport_single_view'); + }; + + $apply = html_writer::checkbox($this->applyname, 1, false, ' ' . $_s('bulk')); + + $insert_options = array( + 'all' => $_s('all_grades'), + 'blanks' => $_s('blanks') + ); + + $select = html_writer::select( + $insert_options, $this->selectname, 'blanks', false + ); + + $label = html_writer::tag('label', $_s('for')); + $text = new single_view_text_attribute($this->insertname, "0"); + return implode(' ', array($apply, $text->html(), $label, $select)); + } + + private function name_for($extend) { + return "{$this->name}_$extend"; + } +} + +abstract class single_view_attribute_format { + abstract function determine_format(); + + function __toString() { + return $this->determine_format()->html(); + } +} + +class single_view_finalgrade_ui extends single_view_grade_attribute_format implements unique_value, be_disabled { + + var $name = 'finalgrade'; + + function get_value() { + // Manual item raw grade support + $val = $this->grade->grade_item->is_manual_item() && (!is_null($this->grade->rawgrade)) ? + $this->grade->rawgrade : $this->grade->finalgrade; + + if ($this->grade->grade_item->scaleid) { + return $val ? (int)$val : -1; + } else { + return $val ? format_float($val, $this->grade->grade_item->get_decimals()) : ''; + } + } + + function is_disabled() { + $locked = 0; + $gradeitemlocked = 0; + $overridden = 0; +// UCSB - 2.24.2014 +// disable editing if grade item or grade score is locked +// if any of these items are set, then we will disable editing +// at some point, we might want to show the reason for the lock +// this code could be simplified, but its more readable for steve's little mind + if (!empty($this->grade->locked)) $locked = 1; + if (!empty($this->grade->grade_item->locked)) $gradeitemlocked = 1; + if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) $overridden = 1; + //$overridden = $this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden(); + return ($locked || $gradeitemlocked || $overridden); + } + + function determine_format() { + if ($this->grade->grade_item->load_scale()) { + $scale = $this->grade->grade_item->load_scale(); + + $options = array(-1 => get_string('nograde')); + + foreach ($scale->scale_items as $i => $name) { + $options[$i + 1] = $name; + } + + return new single_view_dropdown_attribute( + $this->get_name(), + $options, + $this->get_value(), + $this->is_disabled(), + $this->get_tabindex() + ); + } else { + return new single_view_text_attribute( + $this->get_name(), + $this->get_value(), + $this->is_disabled(), + $this->get_tabindex() + ); + } + } + + function set($value) { + global $DB; + + $userid = $this->grade->userid; + $grade_item = $this->grade->grade_item; + + $feedback = false; + $feedbackformat = false; + if ($grade_item->gradetype == GRADE_TYPE_SCALE) { + if ($value == -1) { + $finalgrade = null; + } else { + $finalgrade = $value; + } + } else { + $finalgrade = unformat_float($value); + } + + $errorstr = ''; + if (is_null($finalgrade)) { + // ok + } else { + $bounded = $grade_item->bounded_grade($finalgrade); + if ($bounded > $finalgrade) { + $errorstr = 'lessthanmin'; + } else if ($bounded < $finalgrade) { + $errorstr = 'morethanmax'; + } + } + + if ($errorstr) { + $user = $DB->get_record('user', array('id' => $userid), 'id, firstname, alternatename, lastname'); + $gradestr = new stdClass; + if (!empty($user->alternatename)) { + $gradestr->username = $user->alternatename . ' (' . $user->firstname . ') ' . $user->lastname; + } else { + $gradestr->username = $user->firstname . ' ' . $user->lastname; + } + $gradestr->itemname = $this->grade->grade_item->get_name(); + + $errorstr = get_string($errorstr, 'grades', $gradestr); + } + + $grade_item->update_final_grade($userid, $finalgrade, 'single_view', $feedback, FORMAT_MOODLE); + return $errorstr; + } +} + +class single_view_feedback_ui extends single_view_grade_attribute_format implements unique_value, be_disabled { + + var $name = 'feedback'; + + function get_value() { + return $this->grade->feedback ? $this->grade->feedback : ''; + } + + function is_disabled() { + $locked = 0; + $gradeitemlocked = 0; + $overridden = 0; +// UCSB - 2.24.2014 +// disable editing if grade item or grade score is locked +// if any of these items are set, then we will disable editing +// at some point, we might want to show the reason for the lock +// this code could be simplified, but its more readable for steve's little mind + if (!empty($this->grade->locked)) $locked = 1; + if (!empty($this->grade->grade_item->locked)) $gradeitemlocked = 1; + if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) $overridden = 1; + return ($locked || $gradeitemlocked || $overridden); + } + + function determine_format() { + return new single_view_text_attribute( + $this->get_name(), + $this->get_value(), + $this->is_disabled(), + $this->get_tabindex() + ); + } + + function set($value) { + $finalgrade = false; + $trimmed = trim($value); + if (empty($trimmed)) { + $feedback = NULL; + } else { + $feedback = $value; + } + + $this->grade->grade_item->update_final_grade( + $this->grade->userid, $finalgrade, 'single_view', + $feedback, FORMAT_MOODLE + ); + return false; + } +} + +// UCSB 2014-02-28 implement be_disabled to disable checkbox if grade/gradeitem is locked +class single_view_override_ui extends single_view_grade_attribute_format implements be_checked, be_disabled { + var $name = 'override'; + + function is_checked() { + return $this->grade->is_overridden(); + } + + function is_disabled() { + $locked_grade = $locked_grade_item = 0; + if ( ! empty($this->grade->locked) ) $locked_grade = 1; + if ( ! empty($this->grade->grade_item->locked) ) $locked_grade_item = 1; + return ($locked_grade || $locked_grade_item); + } + + function determine_format() { + if (!$this->grade->grade_item->is_overridable_item()) { + return new single_view_empty_element(); + } + // UCSB 2014-02-28: add param is_disabled to disable override checkbox if grade is locked + return new single_view_checkbox_attribute( + $this->get_name(), + $this->is_checked(), + null, + $this->is_disabled() + ); + } + + function set($value) { + if (empty($this->grade->id)) { + return false; + } + + $state = $value == 0 ? false : true; + + $this->grade->set_overridden($state); + $this->grade->grade_item->get_parent_category()->force_regrading(); + return false; + } +} + +class single_view_exclude_ui extends single_view_grade_attribute_format implements be_checked { + var $name = 'exclude'; + + function is_checked() { + return $this->grade->is_excluded(); + } + + function determine_format() { + return new single_view_checkbox_attribute( + $this->get_name(), + $this->is_checked() + ); + } + + function set($value) { + if (empty($this->grade->id)) { + if (empty($value)) { + return false; + } + + $grade_item = $this->grade->grade_item; + + // Fill in arbitrary grade to be excluded + $grade_item->update_final_grade( + $this->grade->userid, null, 'single_view', null, FORMAT_MOODLE + ); + + $grade_params = array( + 'userid' => $this->grade->userid, + 'itemid' => $this->grade->itemid + ); + + $this->grade = grade_grade::fetch($grade_params); + $this->grade->grade_item = $grade_item; + } + + $state = $value == 0 ? false : true; + + $this->grade->set_excluded($state); + + $this->grade->grade_item->get_parent_category()->force_regrading(); + return false; + } +} + +class single_view_range_ui extends single_view_attribute_format { + function __construct($item) { + $this->item = $item; + } + + function determine_format() { + $decimals = $this->item->get_decimals(); + + $min = format_float($this->item->grademin, $decimals); + $max = format_float($this->item->grademax, $decimals); + + return new single_view_empty_element("$min - $max"); + } +} diff --git a/grade/report/single_view/db/access.php b/grade/report/single_view/db/access.php new file mode 100755 index 00000000000..ee7fcb677d1 --- /dev/null +++ b/grade/report/single_view/db/access.php @@ -0,0 +1,40 @@ + array( + 'riskbitmask' => RISK_PERSONAL, + 'captype' => 'read', + 'contextlevel' => CONTEXT_COURSE, + 'archetypes' => array( + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + ) + ) +); + +?> diff --git a/grade/report/single_view/index.php b/grade/report/single_view/index.php new file mode 100755 index 00000000000..bb4ada2c0f1 --- /dev/null +++ b/grade/report/single_view/index.php @@ -0,0 +1,132 @@ +dirroot.'/lib/gradelib.php'; +require_once $CFG->dirroot.'/grade/lib.php'; +require_once $CFG->dirroot.'/grade/report/single_view/lib.php'; + +$courseid = required_param('id', PARAM_INT); +$groupid = optional_param('group', null, PARAM_INT); + +// Making this work with profile reports +$userid = optional_param('userid', null, PARAM_INT); + +$default_type = $userid ? 'user' : 'select'; + +$itemid = optional_param('itemid', $userid, PARAM_INT); +$itemtype = optional_param('item', $default_type, PARAM_TEXT); + +$course_params = array('id' => $courseid); + +$PAGE->set_url(new moodle_url('/grade/report/single_view/index.php', $course_params)); + +if (!$course = $DB->get_record('course', $course_params)) { + print_error('nocourseid'); +} + +if (!in_array($itemtype, grade_report_single_view::valid_screens())) { + print_error('notvalid', 'gradereport_single_view', '', $itemtype); +} + +require_login($course); + +$context = context_course::instance($course->id); + +// This is the normal requirements +require_capability('gradereport/single_view:view', $context); +require_capability('moodle/grade:viewall', $context); +require_capability('moodle/grade:edit', $context); +// End permission + +$gpr = new grade_plugin_return(array( + 'type' => 'report', + 'plugin' => 'single_view', + 'courseid' => $courseid +)); + +/// last selected report session tracking +if (!isset($USER->grade_last_report)) { + $USER->grade_last_report = array(); +} +$USER->grade_last_report[$course->id] = 'single_view'; + +grade_regrade_final_grades($courseid); + +$report = new grade_report_single_view( + $courseid, $gpr, $context, + $itemtype, $itemid, $groupid +); + +$reportname = $report->screen->heading(); + +$pluginname = get_string('pluginname', 'gradereport_single_view'); + +$report_url = new moodle_url('/grade/report/grader/index.php', $course_params); +$edit_url = new moodle_url('/grade/report/single_view/index.php', $course_params); + +$PAGE->navbar->ignore_active(true); + +$PAGE->navbar->add(get_string('courses')); +$PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', $course_params)); + +$PAGE->navbar->add(get_string('gradeadministration', 'grades')); +$PAGE->navbar->add(get_string('pluginname', 'gradereport_grader'), $report_url); + +if ($reportname != $pluginname) { + $PAGE->navbar->add($pluginname, $edit_url); + $PAGE->navbar->add($reportname); +} else { + $PAGE->navbar->add($pluginname); +} + +if ($data = data_submitted()) { + $warnings = $report->process_data($data); + + if (empty($warnings)) { + redirect($report_url); + } +} + +print_grade_page_head($course->id, 'report', 'single_view', $reportname); + +if ($report->screen->supports_paging()) { + echo $report->screen->pager(); +} + +if ($report->screen->display_group_selector()) { + echo $report->group_selector; +} + +if (!empty($warnings)) { + foreach ($warnings as $warning) { + echo $OUTPUT->notification($warning); + } +} + +echo $report->output(); + +echo $OUTPUT->footer(); + +?> diff --git a/grade/report/single_view/js/single_view.js b/grade/report/single_view/js/single_view.js new file mode 100644 index 00000000000..cfa6c0641c4 --- /dev/null +++ b/grade/report/single_view/js/single_view.js @@ -0,0 +1,41 @@ +M.gradereport_single_view = {}; + +M.gradereport_single_view.init = function(Y) { + // Make toggle links + Y.all('.include').each(function(link) { + var type = link.getAttribute('class').split(" ")[2]; + + var toggle = function(checked) { + return function(input) { + input.getDOMNode().checked = checked; + Y.Event.simulate(input.getDOMNode(), 'change'); + }; + }; + + link.on('click', function() { + Y.all('input[name^=' + type + ']').each(toggle(link.hasClass('all'))); + return false; + }); + }); + + // Override Toggle + Y.all('input[name^=override_]').each(function(input) { + input.on('change', function() { + var checked = input.getDOMNode().checked; + var names = input.getAttribute('name').split("_"); + + var itemid = names[1]; + var userid = names[2]; + + var interest = '_' + itemid + '_' + userid; + + Y.all('input[name$=' + interest + ']').filter('input[type=text]').each(function(text) { + text.getDOMNode().disabled = !checked; + }); + // deal with scales that are not text... UCSB + Y.all('select[name$=' + interest + ']').each(function(select) { + select.getDOMNode().disabled = !checked; + }); + }); + }); +}; diff --git a/grade/report/single_view/lang/en/gradereport_single_view.php b/grade/report/single_view/lang/en/gradereport_single_view.php new file mode 100755 index 00000000000..fbd53fe7a7c --- /dev/null +++ b/grade/report/single_view/lang/en/gradereport_single_view.php @@ -0,0 +1,44 @@ +dirroot . '/grade/report/lib.php'); +require_once($CFG->dirroot . '/grade/report/single_view/classes/lib.php'); + +class grade_report_single_view extends grade_report { + + public static function valid_screens() { + $screendir = dirname(__FILE__) . '/screens'; + + $is_valid = function($filename) use ($screendir) { + if (preg_match('/^\./', $filename)){ + return false; + } + + $file = $screendir . '/' . $filename; + + if (is_file($file)) { + return false; + } + + $plugin = $file . '/lib.php'; + return file_exists($plugin); + }; + + return array_filter(scandir($screendir), $is_valid); + } + + public static function classname($screen) { + $screendir = dirname(__FILE__) . '/screens/' . $screen; + + require_once $screendir . '/lib.php'; + + return 'single_view_' . $screen; + } + + public static function filters() { + $classnames = array('grade_report_single_view', 'classname'); + $classes = array_map($classnames, self::valid_screens()); + + $screens = array_filter($classes, function($screen) { + return method_exists($screen, 'filter'); + }); + + return function($item) use ($screens) { + $reduced = function($in, $screen) use ($item) { + return $in && $screen::filter($item); + }; + + return array_reduce($screens, $reduced, true); + }; + } + + function process_data($data) { + return $this->screen->process($data); + } + + function process_action($target, $action) { + } + + function _s($key, $a = null) { + return get_string($key, 'gradereport_single_view', $a); + } + + function __construct($courseid, $gpr, $context, $itemtype, $itemid, $groupid=null) { + parent::__construct($courseid, $gpr, $context); + + $class = self::classname($itemtype); + + $this->screen = new $class($courseid, $itemid, $groupid); + + // TODO update events to new model + qe_events_trigger($class . '_instantiated', $this->screen); + + // Load custom or predifined js + $this->screen->js(); + + $base = '/grade/report/single_view/index.php'; + + $id_params = array('id' => $courseid); + + $this->baseurl = new moodle_url($base, $id_params); + + $this->pbarurl = new moodle_url($base, $id_params + array( + 'item' => $itemtype, + 'itemid' => $itemid + )); + + $this->setup_groups(); + } + + function output() { + global $OUTPUT; + return $OUTPUT->box($this->screen->html()); + } +} + +function grade_report_single_view_profilereport($course, $user) { + global $CFG, $OUTPUT; + + if (!function_exists('grade_report_user_profilereport')) { + require_once $CFG->dirroot . '/grade/report/user/lib.php'; + } + + $context = context_course::instance($course->id); + + $can_use = ( + has_capability('gradereport/single_view:view', $context) and + has_capability('moodle/grade:viewall', $context) and + has_capability('moodle/grade:edit', $context) + ); + + if (!$can_use) { + grade_report_user_profilereport($course, $user); + } else { + $gpr = new grade_plugin_return(array( + 'type' => 'report', + 'plugin' => 'single_view', + 'courseid' => $course->id, + 'userid' => $user->id + )); + + $report = new grade_report_single_view($course->id, $gpr, $context, 'user', $user->id); + + echo $OUTPUT->heading($report->screen->heading()); + echo $report->output(); + } +} + +/** + * qe_events_trigger hack for using legacy events without debug screaming at us + */ +function qe_events_trigger($eventname, $eventdata) { + if (function_exists('events_trigger_legacy')) { + events_trigger_legacy($eventname, $eventdata); + } else { + events_trigger($eventname, $eventdata); + } +} diff --git a/grade/report/single_view/screens/grade/lib.php b/grade/report/single_view/screens/grade/lib.php new file mode 100644 index 00000000000..74541d8ed40 --- /dev/null +++ b/grade/report/single_view/screens/grade/lib.php @@ -0,0 +1,193 @@ +is_course_item() or $item->is_category_item() + ) + ); + } + + public function description() { + return get_string('users'); + } + + public function options() { + return array_map(function($user) { + if (!empty($user->alternatename)) { + return $user->alternatename . ' (' . $user->firstname . ') ' . $user->lastname; + } else { + return fullname($user); + } + }, $this->items); + } + + public function item_type() { + return 'user'; + } + + public function original_definition() { + $def = array('finalgrade', 'feedback'); + + if ($this->requires_extra) { + $def[] = 'override'; + } + + $def[] = 'exclude'; + + return $def; + } + + public function init($self_item_is_empty = false) { + $roleids = explode(',', get_config('moodle', 'gradebookroles')); + + $this->items = get_role_users( + $roleids, $this->context, false, '', + 'u.lastname, u.firstname', null, $this->groupid + ); + + if ($self_item_is_empty) { + return; + } + + // Only page when necessary + if (count($this->items) > $this->perpage) { + $this->requires_paging = true; + + $this->all_items = $this->items; + + $this->items = get_role_users( + $roleids, $this->context, false, '', + 'u.lastname, u.firstname', null, $this->groupid, + $this->perpage * $this->page, $this->perpage + ); + } + + global $DB; + + $params = array( + 'id' => $this->itemid, + 'courseid' => $this->courseid + ); + + $this->item = grade_item::fetch($params); + + $filter_fun = grade_report_single_view::filters(); + + $allowed = $filter_fun($this->item); + + if (empty($allowed)) { + print_error('not_allowed', 'gradereport_single_view'); + } + + $this->requires_extra = !$this->item->is_manual_item(); + + $this->setup_structure(); + + $this->set_definition($this->original_definition()); + $this->set_headers($this->original_headers()); + } + + public function original_headers() { + $headers = array( + '', + get_string('firstname') . ' (' . get_string('alternatename') . ') ' . get_string('lastname'), + get_string('range', 'grades'), + get_string('grade', 'grades'), + get_string('feedback', 'grades') + ); + + return $this->additional_headers($headers); + } + + public function format_line($item) { + global $OUTPUT; + + $grade = $this->fetch_grade_or_default($this->item, $item->id); + + // UCSB add lock icon indicator + $lockicon = ''; + + // CODE to make steve happy for his simple mind + $locked_grade = $locked_grade_item = 0; + if ( ! empty($grade->locked) ) $locked_grade = 1; + if ( ! empty($grade->grade_item->locked) ) $locked_grade_item = 1; + if ( $locked_grade || $locked_grade_item ) // check both grade and grade item + $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked') . ' '; + + if (!empty($item->alternatename)) { + $fullname = $lockicon . $item->alternatename . ' (' . $item->firstname . ') ' . $item->lastname; + } else { + $fullname = $lockicon . fullname($item); + } + + $item->imagealt = $fullname; + + $line = array( + $OUTPUT->user_picture($item), + $this->format_link('user', $item->id, $fullname), + $this->item_range() + ); + return $this->format_definition($line, $grade); + } + + public function additional_headers($headers) { + if ($this->requires_extra) { + $headers[] = $this->make_toggle_links('override'); + } + + $headers[] = $this->make_toggle_links('exclude'); + + return $headers; + } + + public function item_range() { + if (empty($this->range)) { + $this->range = $this->factory()->create('range')->format($this->item); + } + + return $this->range; + } + + public function supports_paging() { + return $this->requires_paging; + } + + public function pager() { + global $OUTPUT; + + return $OUTPUT->paging_bar( + count($this->all_items), $this->page, $this->perpage, + new moodle_url('/grade/report/single_view/index.php', array( + 'perpage' => $this->perpage, + 'id' => $this->courseid, + 'groupid' => $this->groupid, + 'itemid' => $this->itemid, + 'item' => 'grade' + )) + ); + } + + public function heading() { + return $this->item->get_name(); + } +} diff --git a/grade/report/single_view/screens/select/lib.php b/grade/report/single_view/screens/select/lib.php new file mode 100644 index 00000000000..2f769e32285 --- /dev/null +++ b/grade/report/single_view/screens/select/lib.php @@ -0,0 +1,50 @@ +item = $DB->get_record('course', array('id' => $this->courseid)); + } + + public function html() { + global $OUTPUT; + + $html = ''; + + $types = grade_report_single_view::valid_screens(); + + foreach ($types as $type) { + $class = grade_report_single_view::classname($type); + + $screen = new $class($this->courseid, null, $this->groupid); + + if (!$screen instanceof selectable_items) { + continue; + } + + $options = $screen->options(); + + if (empty($options)) { + continue; + } + + $params = array( + 'id' => $this->courseid, + 'item' => $screen->item_type(), + 'group' => $this->groupid + ); + + $url = new moodle_url('/grade/report/single_view/index.php', $params); + $html .= $OUTPUT->heading($screen->description()); + + $html .= $OUTPUT->single_select($url, 'itemid', $options); + } + + if (empty($html)) { + $OUTPUT->notification(get_string('no_screens', 'gradereport_single_view')); + } + + return $html; + } +} diff --git a/grade/report/single_view/screens/user/lib.php b/grade/report/single_view/screens/user/lib.php new file mode 100644 index 00000000000..2141641cc07 --- /dev/null +++ b/grade/report/single_view/screens/user/lib.php @@ -0,0 +1,120 @@ +get_name(); }, $this->items); + } + + public function item_type() { + return 'grade'; + } + + public function display_group_selector() { + return false; + } + + public function init($self_item_is_empty = false) { + global $DB; + + if (!$self_item_is_empty) { + $this->item = $DB->get_record('user', array('id' => $this->itemid)); + } + + $params = array('courseid' => $this->courseid); + + $seq = new grade_seq($this->courseid, true); + + $this->items = array_filter($seq->items, grade_report_single_view::filters()); + + unset($seq); + + $this->setup_structure(); + + $this->definition = array( + 'finalgrade', 'feedback', 'override', 'exclude' + ); + $this->set_headers($this->original_headers()); + } + + public function original_headers() { + return array( + '', + get_string('assessmentname', 'gradereport_single_view'), + get_string('gradecategory', 'grades'), + get_string('range', 'grades'), + get_string('grade', 'grades'), + get_string('feedback', 'grades'), + $this->make_toggle_links('override'), + $this->make_toggle_links('exclude') + ); + } + + public function format_line($item) { + global $OUTPUT; + + $grade = $this->fetch_grade_or_default($item, $this->item->id); + $lockicon = ''; + + // UCSB add lock icon indicator + $locked_grade = $locked_grade_item = 0; + if ( ! empty($grade->locked) ) $locked_grade = 1; + if ( ! empty($grade->grade_item->locked) ) $locked_grade_item = 1; + if ( $locked_grade || $locked_grade_item ) // check both grade and grade item + $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); + + $line = array( + $this->format_icon($item) . $lockicon, + $this->format_link('grade', $item->id, $item->get_name()), + $this->category($item), + $this->factory()->create('range')->format($item) + ); + + return $this->format_definition($line, $grade); + } + + private function format_icon($item) { + $element = array('type' => 'item', 'object' => $item); + return $this->structure->get_element_icon($element); + } + + private function category($item) { + if (empty($item->categoryid)) { + + if ($item->itemtype == 'course') { + return $this->course->fullname; + } + + global $DB; + + $params = array('id' => $item->iteminstance); + $elem = $DB->get_record('grade_categories', $params); + + return $elem->fullname; + } + + if (!isset($this->categories[$item->categoryid])) { + $category = $item->get_parent_category(); + + $this->categories[$category->id] = $category; + } + + return $this->categories[$item->categoryid]->get_name(); + } + + public function heading() { + if (!empty($this->item->alternatename)) { + return $this->item->alternatename . ' (' . $this->item->firstname . ') ' . $this->item->lastname; + } else { + return fullname($this->item); + } + } +} diff --git a/grade/report/single_view/styles.css b/grade/report/single_view/styles.css new file mode 100644 index 00000000000..f6b58710bc3 --- /dev/null +++ b/grade/report/single_view/styles.css @@ -0,0 +1,27 @@ +#page-grade-report-single_view-index div.generalbox { + margin: 0 20px 15px 20px; +} + +#page-grade-report-single_view-index div.generalbox div.singleselect form div { + text-align: center; +} + +#page-grade-report-single_view-index div.generalbox table.generaltable { + margin: 0 auto 15px auto; +} + +#page-grade-report-single_view-index div.generalbox form div { + text-align: center; +} + +#page-grade-report-single_view-index .single_view_buttons { + padding: 10px 0; +} + +#page-grade-report-single_view-index table.generaltable .cell { + vertical-align: middle; +} + +#page-grade-report-single_view-index div.generalbox h2 { + text-align: center; +} diff --git a/grade/report/single_view/version.php b/grade/report/single_view/version.php new file mode 100755 index 00000000000..3f6e7768306 --- /dev/null +++ b/grade/report/single_view/version.php @@ -0,0 +1,27 @@ +version = 2013081002; +$plugin->requires = 2010090501; + From 4229e9fa8df30f1310f43c73c77c273b53f41b60 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Tue, 23 Sep 2014 04:12:26 +0000 Subject: [PATCH 02/16] MDL-18229 gradebook: Added filter icons for activities and users. Corrected CSS for grades column, was far too large. --- grade/report/single_view/classes/lib.php | 1 - .../report/single_view/lang/en/gradereport_single_view.php | 2 +- grade/report/single_view/screens/grade/lib.php | 6 ++++-- grade/report/single_view/screens/user/lib.php | 4 +++- grade/report/single_view/styles.css | 4 ++++ lang/en/grades.php | 1 + 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/grade/report/single_view/classes/lib.php b/grade/report/single_view/classes/lib.php index 4347e47eecb..9b9265c7398 100644 --- a/grade/report/single_view/classes/lib.php +++ b/grade/report/single_view/classes/lib.php @@ -324,7 +324,6 @@ abstract class single_view_tablelike extends single_view_screen implements tabba $tab = ($i * $this->total) + $this->index; $html = $this->factory()->create($field)->format($grade, $tab); - if ($field == 'finalgrade' and !empty($this->structure)) { $html .= $this->structure->get_grade_analysis_icon($grade); } diff --git a/grade/report/single_view/lang/en/gradereport_single_view.php b/grade/report/single_view/lang/en/gradereport_single_view.php index fbd53fe7a7c..e3ce90beb42 100755 --- a/grade/report/single_view/lang/en/gradereport_single_view.php +++ b/grade/report/single_view/lang/en/gradereport_single_view.php @@ -27,7 +27,7 @@ $string['pluginname'] = 'Single view'; $string['single_view:view'] = 'View the '.$string['pluginname'].' report'; $string['not_allowed'] = 'Not allowed to quick edit this item'; - +$string['filtergrades'] = 'Show grades for {$a}.'; $string['no_screens'] = 'Could not find a suitable Single view screen.'; $string['exclude'] = 'Exclude'; diff --git a/grade/report/single_view/screens/grade/lib.php b/grade/report/single_view/screens/grade/lib.php index 74541d8ed40..ebfbca1fc34 100644 --- a/grade/report/single_view/screens/grade/lib.php +++ b/grade/report/single_view/screens/grade/lib.php @@ -109,7 +109,8 @@ class single_view_grade extends single_view_tablelike public function original_headers() { $headers = array( - '', + '', // for filter icon. + '', // for user picture. get_string('firstname') . ' (' . get_string('alternatename') . ') ' . get_string('lastname'), get_string('range', 'grades'), get_string('grade', 'grades'), @@ -142,7 +143,8 @@ class single_view_grade extends single_view_tablelike $item->imagealt = $fullname; - $line = array( + $line = array( + $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $fullname))), $OUTPUT->user_picture($item), $this->format_link('user', $item->id, $fullname), $this->item_range() diff --git a/grade/report/single_view/screens/user/lib.php b/grade/report/single_view/screens/user/lib.php index 2141641cc07..f472e10a791 100644 --- a/grade/report/single_view/screens/user/lib.php +++ b/grade/report/single_view/screens/user/lib.php @@ -47,7 +47,8 @@ class single_view_user extends single_view_tablelike implements selectable_items public function original_headers() { return array( - '', + '', // for filter icon. + '', // for activity icon. get_string('assessmentname', 'gradereport_single_view'), get_string('gradecategory', 'grades'), get_string('range', 'grades'), @@ -72,6 +73,7 @@ class single_view_user extends single_view_tablelike implements selectable_items $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); $line = array( + $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $item->get_name()))), $this->format_icon($item) . $lockicon, $this->format_link('grade', $item->id, $item->get_name()), $this->category($item), diff --git a/grade/report/single_view/styles.css b/grade/report/single_view/styles.css index f6b58710bc3..90b023d0f08 100644 --- a/grade/report/single_view/styles.css +++ b/grade/report/single_view/styles.css @@ -25,3 +25,7 @@ #page-grade-report-single_view-index div.generalbox h2 { text-align: center; } + +input[name^="finalgrade"] { + width: 50px; +} diff --git a/lang/en/grades.php b/lang/en/grades.php index 118d3663db4..31816c06ca4 100644 --- a/lang/en/grades.php +++ b/lang/en/grades.php @@ -654,6 +654,7 @@ $string['showrank_help'] = 'Show the position of the student in relation to the $string['showuserimage'] = 'Show user profile images'; $string['showuserimage_help'] = 'Whether to show the user\'s profile image next to the name in the grader report.'; $string['showverbose'] = 'Show {$a->category} {$a->itemmodule} {$a->itemname}'; +$string['simpleview'] = 'Single view'; $string['sitewide'] = 'Site-wide'; $string['sort'] = 'sort'; $string['sortasc'] = 'Sort in ascending order'; From 508f23f1e5d60d6d8ca0d39f6f61182aef43d672 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Tue, 23 Sep 2014 06:40:02 +0000 Subject: [PATCH 03/16] MDL-18229 gradebook: Single view navigation corrected. Usernames link to user profiles. Activities to their activity page. --- grade/report/single_view/classes/lib.php | 41 ++++++++++---- grade/report/single_view/classes/uilib.php | 54 ++++++++++++------- .../report/single_view/screens/grade/lib.php | 35 ++++++++++-- .../report/single_view/screens/select/lib.php | 23 ++++++++ grade/report/single_view/screens/user/lib.php | 32 +++++++++-- 5 files changed, 149 insertions(+), 36 deletions(-) diff --git a/grade/report/single_view/classes/lib.php b/grade/report/single_view/classes/lib.php index 9b9265c7398..b432c613a8e 100644 --- a/grade/report/single_view/classes/lib.php +++ b/grade/report/single_view/classes/lib.php @@ -1,5 +1,28 @@ . + +/** + * The gradebook simple view - base class for the table + * + * @package simple_view + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + require_once $CFG->dirroot . '/grade/report/single_view/classes/uilib.php'; interface selectable_items { @@ -53,7 +76,7 @@ abstract class single_view_screen { 'id' => $this->courseid, 'item' => $screen, 'itemid' => $itemid, - 'group' => $this->groupid + 'group' => $this->groupid, )); if ($display) { @@ -198,20 +221,20 @@ abstract class single_view_screen { $data->$name = null; } - // Same value; skip + // Same value; skip. if ($oldvalue == $posted) { continue; } $msg = $element->set($posted); - // Optional type + // Optional type. if (!empty($msg)) { $warnings[] = $msg; } } - // Some post-processing + // Some post-processing. $event_data = new stdClass; $event_data->warnings = $warnings; $event_data->post_data = $data; @@ -258,17 +281,17 @@ abstract class single_view_tablelike extends single_view_screen implements tabba return (count($this->definition()) * $this->total) + $this->index; } - // Special injection for bulk operations + // Special injection for bulk operations. public function process($data) { $bulk = $this->factory()->create('bulk_insert')->format($this->item); // Bulk insert messages the data to be passed in - // ie: for all grades of empty grades apply the specified value + // ie: for all grades of empty grades apply the specified value. if ($bulk->is_applied($data)) { $filter = $bulk->get_type($data); $insert_value = $bulk->get_insert_value($data); - // Appropriately massage data that may not exist + // Appropriately massage data that may not exist. if ($this->supports_paging()) { // TODO: this only works with the grade screen... $grade_item = grade_item::fetch(array( @@ -320,7 +343,7 @@ abstract class single_view_tablelike extends single_view_screen implements tabba public function format_definition($line, $grade) { foreach ($this->definition() as $i => $field) { - // Table tab index + // Table tab index. $tab = ($i * $this->total) + $this->index; $html = $this->factory()->create($field)->format($grade, $tab); @@ -339,7 +362,7 @@ abstract class single_view_tablelike extends single_view_screen implements tabba $table->head = $this->headers(); - // To be used for extra formatting + // To be used for extra formatting. $this->index = 0; $this->total = count($this->items); diff --git a/grade/report/single_view/classes/uilib.php b/grade/report/single_view/classes/uilib.php index 5faa3f983ef..c753eb17e2c 100644 --- a/grade/report/single_view/classes/uilib.php +++ b/grade/report/single_view/classes/uilib.php @@ -1,5 +1,28 @@ . + +/** + * The gradebook simple view - UI factory + * + * @package simple_view + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + abstract class single_view_ui_factory { public abstract function create($type); @@ -110,7 +133,6 @@ class single_view_checkbox_attribute extends single_view_ui_element { var $is_checked; var $tabindex; - // UCSB 2014-02-28 - add $locked to disable override checkbox when grade is locked function __construct($name, $is_checked = false, $tabindex = null, $locked=0) { $this->is_checked = $is_checked; $this->tabindex = $tabindex; @@ -130,7 +152,7 @@ class single_view_checkbox_attribute extends single_view_ui_element { 'value' => 1 ); - // UCSB fixed user should not be able to override locked grade + // UCSB fixed user should not be able to override locked grade. if ( $this->locked) { $attributes['disabled'] = 'DISABLED'; } @@ -310,7 +332,7 @@ class single_view_finalgrade_ui extends single_view_grade_attribute_format imple var $name = 'finalgrade'; function get_value() { - // Manual item raw grade support + // Manual item raw grade support. $val = $this->grade->grade_item->is_manual_item() && (!is_null($this->grade->rawgrade)) ? $this->grade->rawgrade : $this->grade->finalgrade; @@ -325,15 +347,14 @@ class single_view_finalgrade_ui extends single_view_grade_attribute_format imple $locked = 0; $gradeitemlocked = 0; $overridden = 0; -// UCSB - 2.24.2014 -// disable editing if grade item or grade score is locked -// if any of these items are set, then we will disable editing -// at some point, we might want to show the reason for the lock -// this code could be simplified, but its more readable for steve's little mind + /* Disable editing if grade item or grade score is locked + * if any of these items are set, then we will disable editing + * at some point, we might want to show the reason for the lock + * this code could be simplified, but its more readable for steve's little mind + */ if (!empty($this->grade->locked)) $locked = 1; if (!empty($this->grade->grade_item->locked)) $gradeitemlocked = 1; if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) $overridden = 1; - //$overridden = $this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden(); return ($locked || $gradeitemlocked || $overridden); } @@ -384,7 +405,6 @@ class single_view_finalgrade_ui extends single_view_grade_attribute_format imple $errorstr = ''; if (is_null($finalgrade)) { - // ok } else { $bounded = $grade_item->bounded_grade($finalgrade); if ($bounded > $finalgrade) { @@ -424,11 +444,11 @@ class single_view_feedback_ui extends single_view_grade_attribute_format impleme $locked = 0; $gradeitemlocked = 0; $overridden = 0; -// UCSB - 2.24.2014 -// disable editing if grade item or grade score is locked -// if any of these items are set, then we will disable editing -// at some point, we might want to show the reason for the lock -// this code could be simplified, but its more readable for steve's little mind + /* Disable editing if grade item or grade score is locked + * if any of these items are set, then we will disable editing + * at some point, we might want to show the reason for the lock + * this code could be simplified, but its more readable for steve's little mind + */ if (!empty($this->grade->locked)) $locked = 1; if (!empty($this->grade->grade_item->locked)) $gradeitemlocked = 1; if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) $overridden = 1; @@ -461,7 +481,6 @@ class single_view_feedback_ui extends single_view_grade_attribute_format impleme } } -// UCSB 2014-02-28 implement be_disabled to disable checkbox if grade/gradeitem is locked class single_view_override_ui extends single_view_grade_attribute_format implements be_checked, be_disabled { var $name = 'override'; @@ -480,7 +499,6 @@ class single_view_override_ui extends single_view_grade_attribute_format impleme if (!$this->grade->grade_item->is_overridable_item()) { return new single_view_empty_element(); } - // UCSB 2014-02-28: add param is_disabled to disable override checkbox if grade is locked return new single_view_checkbox_attribute( $this->get_name(), $this->is_checked(), @@ -524,7 +542,7 @@ class single_view_exclude_ui extends single_view_grade_attribute_format implemen $grade_item = $this->grade->grade_item; - // Fill in arbitrary grade to be excluded + // Fill in arbitrary grade to be excluded. $grade_item->update_final_grade( $this->grade->userid, null, 'single_view', null, FORMAT_MOODLE ); diff --git a/grade/report/single_view/screens/grade/lib.php b/grade/report/single_view/screens/grade/lib.php index ebfbca1fc34..2b802c9b722 100644 --- a/grade/report/single_view/screens/grade/lib.php +++ b/grade/report/single_view/screens/grade/lib.php @@ -1,5 +1,28 @@ . + +/** + * The gradebook simple view - grades view (for an activity) + * + * @package simple_view + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + class single_view_grade extends single_view_tablelike implements selectable_items, item_filtering { @@ -69,7 +92,7 @@ class single_view_grade extends single_view_tablelike return; } - // Only page when necessary + // Only page when necessary. if (count($this->items) > $this->perpage) { $this->requires_paging = true; @@ -125,14 +148,15 @@ class single_view_grade extends single_view_tablelike $grade = $this->fetch_grade_or_default($this->item, $item->id); - // UCSB add lock icon indicator + // UCSB add lock icon indicator. $lockicon = ''; - // CODE to make steve happy for his simple mind + // CODE to make steve happy for his simple mind. $locked_grade = $locked_grade_item = 0; if ( ! empty($grade->locked) ) $locked_grade = 1; if ( ! empty($grade->grade_item->locked) ) $locked_grade_item = 1; - if ( $locked_grade || $locked_grade_item ) // check both grade and grade item + // check both grade and grade item. + if ( $locked_grade || $locked_grade_item ) $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked') . ' '; if (!empty($item->alternatename)) { @@ -142,11 +166,12 @@ class single_view_grade extends single_view_tablelike } $item->imagealt = $fullname; + $url = new moodle_url("/user/view.php", array('id' => $item->id, 'course' => $this->courseid)); $line = array( $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $fullname))), $OUTPUT->user_picture($item), - $this->format_link('user', $item->id, $fullname), + html_writer::tag('a', $fullname, array('href' => $url)), $this->item_range() ); return $this->format_definition($line, $grade); diff --git a/grade/report/single_view/screens/select/lib.php b/grade/report/single_view/screens/select/lib.php index 2f769e32285..282d94fcc5a 100644 --- a/grade/report/single_view/screens/select/lib.php +++ b/grade/report/single_view/screens/select/lib.php @@ -1,5 +1,28 @@ . + +/** + * The gradebook simple view - initial view to select your search options + * + * @package simple_view + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + class single_view_select extends single_view_screen { public function init($self_item_is_empty = false) { global $DB; diff --git a/grade/report/single_view/screens/user/lib.php b/grade/report/single_view/screens/user/lib.php index f472e10a791..bf43eaa214a 100644 --- a/grade/report/single_view/screens/user/lib.php +++ b/grade/report/single_view/screens/user/lib.php @@ -1,5 +1,28 @@ . + +/** + * The gradebook simple view - grades view (for a user) + * + * @package simple_view + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + class single_view_user extends single_view_tablelike implements selectable_items { private $categories = array(); @@ -65,21 +88,22 @@ class single_view_user extends single_view_tablelike implements selectable_items $grade = $this->fetch_grade_or_default($item, $this->item->id); $lockicon = ''; - // UCSB add lock icon indicator + // UCSB add lock icon indicator. $locked_grade = $locked_grade_item = 0; if ( ! empty($grade->locked) ) $locked_grade = 1; if ( ! empty($grade->grade_item->locked) ) $locked_grade_item = 1; - if ( $locked_grade || $locked_grade_item ) // check both grade and grade item + if ( $locked_grade || $locked_grade_item ) // check both grade and grade item. $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); + $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $item->iteminstance)); + $line = array( $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $item->get_name()))), $this->format_icon($item) . $lockicon, - $this->format_link('grade', $item->id, $item->get_name()), + html_writer::tag('a', $item->get_name(), array('href' => $url)), $this->category($item), $this->factory()->create('range')->format($item) ); - return $this->format_definition($line, $grade); } From 7cdbf79dd935c3fa422c9e5567750456f03d4c34 Mon Sep 17 00:00:00 2001 From: Aparup Banerjee Date: Wed, 24 Sep 2014 13:09:38 +0800 Subject: [PATCH 04/16] MDL-47347 added basic navigation to top and bottom of gradereport_singleview Part of MDL-18229 --- grade/report/single_view/index.php | 47 +++++++++++++++++++++++++++++ grade/report/single_view/styles.css | 19 ++++++++++++ 2 files changed, 66 insertions(+) diff --git a/grade/report/single_view/index.php b/grade/report/single_view/index.php index bb4ada2c0f1..30db476a078 100755 --- a/grade/report/single_view/index.php +++ b/grade/report/single_view/index.php @@ -109,7 +109,43 @@ if ($data = data_submitted()) { } } +$graderrightnav = $graderleftnav = null; +if ($report->screen instanceof selectable_items + && class_exists($report::classname($report->screen->item_type()))) { //should be ok for user and grade for now, allows other cross singleview nav too. + + $optionkeys = array_keys($report->screen->options()); + $optionitemid = array_shift($optionkeys); //just any one thanks + + $relreport = new grade_report_single_view( + $courseid, $gpr, $context, + $report->screen->item_type(), $optionitemid, $groupid + ); + $reloptions = $relreport->screen->options(); + $reloptionssorting = array_keys($relreport->screen->options()); + + $i = array_search($itemid, $reloptionssorting); + $navparams = array('item' => $itemtype, 'id' => $courseid, 'group' => $groupid); + if ($i>0) { + $navparams['itemid'] = $reloptionssorting[$i-1]; + $link = new moodle_url('/grade/report/single_view/index.php', $navparams); + $navprev=html_writer::link($link, $reloptions[$reloptionssorting[$i-1]]); + $graderleftnav = html_writer::tag('small', $navprev, array('class' => 'itemnav previtem')); + } + if ($i 'itemnav nextitem')); + } +} + print_grade_page_head($course->id, 'report', 'single_view', $reportname); +if(!is_null($graderleftnav)) { + echo $graderleftnav; +} +if(!is_null($graderrightnav)) { + echo $graderrightnav; +} if ($report->screen->supports_paging()) { echo $report->screen->pager(); @@ -127,6 +163,17 @@ if (!empty($warnings)) { echo $report->output(); +if ($report->screen->supports_paging()) { + echo $report->screen->pager(); +} + +if(!is_null($graderleftnav)) { + echo $graderleftnav; +} +if(!is_null($graderrightnav)) { + echo $graderrightnav; +} + echo $OUTPUT->footer(); ?> diff --git a/grade/report/single_view/styles.css b/grade/report/single_view/styles.css index 90b023d0f08..c47043db76d 100644 --- a/grade/report/single_view/styles.css +++ b/grade/report/single_view/styles.css @@ -29,3 +29,22 @@ input[name^="finalgrade"] { width: 50px; } + +#page-grade-report-single_view-index #region-main h2, .paging{ + text-align: center; +} +#page-grade-report-single_view-index itemnav.previtem { + float:left; +} +#page-grade-report-single_view-index itemnav.previtem { + float:left; +} +#page-grade-report-single_view-index.dir-rtl small.previtem { + float:right; +} +#page-grade-report-single_view-index small.nextitem { + float:right; +} +#page-grade-report-single_view-index.dir-rtl small.nextitem { + float:left; +} \ No newline at end of file From 6a555b99f7bf186688421b54d6e01191230d8612 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Wed, 24 Sep 2014 13:48:56 +0800 Subject: [PATCH 05/16] MDL-18229 gradebook: Linking activities and usernames correctly. Activities to their course page and usernames to their profile page as per standard. --- grade/report/single_view/classes/lib.php | 1 + grade/report/single_view/screens/user/lib.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/grade/report/single_view/classes/lib.php b/grade/report/single_view/classes/lib.php index b432c613a8e..c679f9487a8 100644 --- a/grade/report/single_view/classes/lib.php +++ b/grade/report/single_view/classes/lib.php @@ -347,6 +347,7 @@ abstract class single_view_tablelike extends single_view_screen implements tabba $tab = ($i * $this->total) + $this->index; $html = $this->factory()->create($field)->format($grade, $tab); + if ($field == 'finalgrade' and !empty($this->structure)) { $html .= $this->structure->get_grade_analysis_icon($grade); } diff --git a/grade/report/single_view/screens/user/lib.php b/grade/report/single_view/screens/user/lib.php index bf43eaa214a..394dd447619 100644 --- a/grade/report/single_view/screens/user/lib.php +++ b/grade/report/single_view/screens/user/lib.php @@ -100,7 +100,7 @@ class single_view_user extends single_view_tablelike implements selectable_items $line = array( $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $item->get_name()))), $this->format_icon($item) . $lockicon, - html_writer::tag('a', $item->get_name(), array('href' => $url)), + html_writer::link($url, $item->get_name()), $this->category($item), $this->factory()->create('range')->format($item) ); From edd8b27923245caa4ce68fb4fcc5045658fdbb30 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Thu, 25 Sep 2014 11:01:55 +0800 Subject: [PATCH 06/16] MDL-18229 gradebook: Fix for loading activities. Was using local variable iteminstance rather than cmid. --- grade/report/single_view/screens/user/lib.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/grade/report/single_view/screens/user/lib.php b/grade/report/single_view/screens/user/lib.php index 394dd447619..d011e223631 100644 --- a/grade/report/single_view/screens/user/lib.php +++ b/grade/report/single_view/screens/user/lib.php @@ -55,6 +55,12 @@ class single_view_user extends single_view_tablelike implements selectable_items $params = array('courseid' => $this->courseid); $seq = new grade_seq($this->courseid, true); + foreach ($seq->items as $key => $item) { + if (isset($item->itemmodule)) { + list($courseid, $cmid) = get_course_and_cm_from_instance($item->iteminstance, $item->itemmodule); + $seq->items[$key]->cmid = $cmid->id; + } + } $this->items = array_filter($seq->items, grade_report_single_view::filters()); @@ -95,7 +101,7 @@ class single_view_user extends single_view_tablelike implements selectable_items if ( $locked_grade || $locked_grade_item ) // check both grade and grade item. $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); - $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $item->iteminstance)); + $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $item->cmid)); $line = array( $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $item->get_name()))), From d124a60b33826ab40bf492bf9ea089063b601cd8 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Thu, 25 Sep 2014 14:48:51 +0800 Subject: [PATCH 07/16] MDL-18229 gradebook: Renaming of Single_view to Single view --- grade/report/single_view/styles.css | 50 --------------- .../{single_view => singleview}/README.md | 0 .../classes/lib.php | 30 ++++----- .../classes/uilib.php | 64 +++++++++---------- .../{single_view => singleview}/db/access.php | 2 +- .../{single_view => singleview}/index.php | 29 +++++---- .../js/singleview.js} | 4 +- .../lang/en/gradereport_singleview.php} | 2 +- .../{single_view => singleview}/lib.php | 20 +++--- .../screens/grade/lib.php | 12 ++-- .../screens/select/lib.php | 12 ++-- .../screens/user/lib.php | 10 +-- grade/report/singleview/styles.css | 51 +++++++++++++++ .../{single_view => singleview}/version.php | 0 14 files changed, 144 insertions(+), 142 deletions(-) delete mode 100644 grade/report/single_view/styles.css rename grade/report/{single_view => singleview}/README.md (100%) rename grade/report/{single_view => singleview}/classes/lib.php (91%) rename grade/report/{single_view => singleview}/classes/uilib.php (87%) rename grade/report/{single_view => singleview}/db/access.php (97%) rename grade/report/{single_view => singleview}/index.php (85%) rename grade/report/{single_view/js/single_view.js => singleview/js/singleview.js} (94%) rename grade/report/{single_view/lang/en/gradereport_single_view.php => singleview/lang/en/gradereport_singleview.php} (96%) rename grade/report/{single_view => singleview}/lib.php (88%) rename grade/report/{single_view => singleview}/screens/grade/lib.php (95%) rename grade/report/{single_view => singleview}/screens/select/lib.php (86%) rename grade/report/{single_view => singleview}/screens/user/lib.php (95%) create mode 100644 grade/report/singleview/styles.css rename grade/report/{single_view => singleview}/version.php (100%) diff --git a/grade/report/single_view/styles.css b/grade/report/single_view/styles.css deleted file mode 100644 index c47043db76d..00000000000 --- a/grade/report/single_view/styles.css +++ /dev/null @@ -1,50 +0,0 @@ -#page-grade-report-single_view-index div.generalbox { - margin: 0 20px 15px 20px; -} - -#page-grade-report-single_view-index div.generalbox div.singleselect form div { - text-align: center; -} - -#page-grade-report-single_view-index div.generalbox table.generaltable { - margin: 0 auto 15px auto; -} - -#page-grade-report-single_view-index div.generalbox form div { - text-align: center; -} - -#page-grade-report-single_view-index .single_view_buttons { - padding: 10px 0; -} - -#page-grade-report-single_view-index table.generaltable .cell { - vertical-align: middle; -} - -#page-grade-report-single_view-index div.generalbox h2 { - text-align: center; -} - -input[name^="finalgrade"] { - width: 50px; -} - -#page-grade-report-single_view-index #region-main h2, .paging{ - text-align: center; -} -#page-grade-report-single_view-index itemnav.previtem { - float:left; -} -#page-grade-report-single_view-index itemnav.previtem { - float:left; -} -#page-grade-report-single_view-index.dir-rtl small.previtem { - float:right; -} -#page-grade-report-single_view-index small.nextitem { - float:right; -} -#page-grade-report-single_view-index.dir-rtl small.nextitem { - float:left; -} \ No newline at end of file diff --git a/grade/report/single_view/README.md b/grade/report/singleview/README.md similarity index 100% rename from grade/report/single_view/README.md rename to grade/report/singleview/README.md diff --git a/grade/report/single_view/classes/lib.php b/grade/report/singleview/classes/lib.php similarity index 91% rename from grade/report/single_view/classes/lib.php rename to grade/report/singleview/classes/lib.php index c679f9487a8..f0772258658 100644 --- a/grade/report/single_view/classes/lib.php +++ b/grade/report/singleview/classes/lib.php @@ -18,12 +18,12 @@ /** * The gradebook simple view - base class for the table * - * @package simple_view + * @package singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once $CFG->dirroot . '/grade/report/single_view/classes/uilib.php'; +require_once $CFG->dirroot . '/grade/report/singleview/classes/uilib.php'; interface selectable_items { public function description(); @@ -37,7 +37,7 @@ interface item_filtering { public static function filter($item); } -abstract class single_view_screen { +abstract class singleview_screen { var $courseid; var $itemid; @@ -72,7 +72,7 @@ abstract class single_view_screen { } public function format_link($screen, $itemid, $display = null) { - $url = new moodle_url('/grade/report/single_view/index.php', array( + $url = new moodle_url('/grade/report/singleview/index.php', array( 'id' => $this->courseid, 'item' => $screen, 'itemid' => $itemid, @@ -123,12 +123,12 @@ abstract class single_view_screen { } public function make_toggle_links($key) { - return get_string($key, 'gradereport_single_view') . ' ' . + return get_string($key, 'gradereport_singleview') . ' ' . $this->make_toggle($key); } public function heading() { - return get_string('pluginname', 'gradereport_single_view'); + return get_string('pluginname', 'gradereport_singleview'); } public abstract function init($self_item_is_empty = false); @@ -146,11 +146,11 @@ abstract class single_view_screen { global $OUTPUT; - list($___, $item) = explode('single_view_', get_class($this)); + list($___, $item) = explode('singleview_', get_class($this)); return $OUTPUT->paging_bar( count($this->items), $this->page, $this->perpage, - new moodle_url('/grade/report/single_view/index.php', array( + new moodle_url('/grade/report/singleview/index.php', array( 'perpage' => $this->perpage, 'id' => $this->courseid, 'groupid' => $this->groupid, @@ -164,17 +164,17 @@ abstract class single_view_screen { global $PAGE; $module = array( - 'name' => 'gradereport_single_view', - 'fullpath' => '/grade/report/single_view/js/single_view.js', + 'name' => 'gradereport_singleview', + 'fullpath' => '/grade/report/singleview/js/singleview.js', 'requires' => array('base', 'dom', 'event', 'event-simulate', 'io-base') ); - $PAGE->requires->js_init_call('M.gradereport_single_view.init', array(), false, $module); + $PAGE->requires->js_init_call('M.gradereport_singleview.init', array(), false, $module); } public function factory() { if (empty($this->__factory)) { - $this->__factory = new single_view_grade_ui_factory(); + $this->__factory = new singleview_grade_ui_factory(); } return $this->__factory; @@ -250,7 +250,7 @@ abstract class single_view_screen { } } -abstract class single_view_tablelike extends single_view_screen implements tabbable { +abstract class singleview_tablelike extends singleview_screen implements tabbable { var $items; protected $headers = array(); @@ -380,7 +380,7 @@ abstract class single_view_tablelike extends single_view_screen implements tabba qe_events_trigger($underlying . '_table_built', $data); - $button_attr = array('class' => 'single_view_buttons submit'); + $button_attr = array('class' => 'singleview_buttons submit'); $button_html = implode(' ', $this->buttons()); $buttons = html_writer::tag('div', $button_html, $button_attr); @@ -395,7 +395,7 @@ abstract class single_view_tablelike extends single_view_screen implements tabba return html_writer::tag( 'div', $this->factory()->create('bulk_insert')->format($this->item)->html(), - array('class' => 'single_view_bulk') + array('class' => 'singleview_bulk') ); } diff --git a/grade/report/single_view/classes/uilib.php b/grade/report/singleview/classes/uilib.php similarity index 87% rename from grade/report/single_view/classes/uilib.php rename to grade/report/singleview/classes/uilib.php index c753eb17e2c..cc676ca678e 100644 --- a/grade/report/single_view/classes/uilib.php +++ b/grade/report/singleview/classes/uilib.php @@ -18,26 +18,26 @@ /** * The gradebook simple view - UI factory * - * @package simple_view + * @package singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -abstract class single_view_ui_factory { +abstract class singleview_ui_factory { public abstract function create($type); protected function wrap($class) { - return new single_view_factory_class_wrap($class); + return new singleview_factory_class_wrap($class); } } -class single_view_grade_ui_factory extends single_view_ui_factory { +class singleview_grade_ui_factory extends singleview_ui_factory { public function create($type) { - return $this->wrap("single_view_{$type}_ui"); + return $this->wrap("singleview_{$type}_ui"); } } -class single_view_factory_class_wrap { +class singleview_factory_class_wrap { function __construct($class) { $this->class = $class; } @@ -50,7 +50,7 @@ class single_view_factory_class_wrap { } } -abstract class single_view_ui_element { +abstract class singleview_ui_element { var $name; var $value; @@ -74,10 +74,10 @@ abstract class single_view_ui_element { abstract function html(); } -class single_view_empty_element extends single_view_ui_element { +class singleview_empty_element extends singleview_ui_element { function __construct($msg = null) { if (is_null($msg)) { - $this->text = get_string('notavailable', 'gradereport_single_view'); + $this->text = get_string('notavailable', 'gradereport_singleview'); } else { $this->text = $msg; } @@ -88,7 +88,7 @@ class single_view_empty_element extends single_view_ui_element { } } -class single_view_text_attribute extends single_view_ui_element { +class singleview_text_attribute extends singleview_ui_element { var $is_disabled; var $tabindex; @@ -129,7 +129,7 @@ class single_view_text_attribute extends single_view_ui_element { } } -class single_view_checkbox_attribute extends single_view_ui_element { +class singleview_checkbox_attribute extends singleview_ui_element { var $is_checked; var $tabindex; @@ -185,7 +185,7 @@ class single_view_checkbox_attribute extends single_view_ui_element { } } -class single_view_dropdown_attribute extends single_view_ui_element { +class singleview_dropdown_attribute extends singleview_ui_element { var $selected; var $options; var $is_disabled; @@ -226,7 +226,7 @@ class single_view_dropdown_attribute extends single_view_ui_element { } } -abstract class single_view_grade_attribute_format extends single_view_attribute_format implements unique_name, tabbable { +abstract class singleview_grade_attribute_format extends singleview_attribute_format implements unique_name, tabbable { var $name; function __construct() { @@ -273,7 +273,7 @@ interface tabbable { function get_tabindex(); } -class single_view_bulk_insert_ui extends single_view_ui_element { +class singleview_bulk_insert_ui extends singleview_ui_element { function __construct($item) { $this->name = 'bulk_' . $item->id; $this->applyname = $this->name_for('apply'); @@ -295,7 +295,7 @@ class single_view_bulk_insert_ui extends single_view_ui_element { function html() { $_s = function($key) { - return get_string($key, 'gradereport_single_view'); + return get_string($key, 'gradereport_singleview'); }; $apply = html_writer::checkbox($this->applyname, 1, false, ' ' . $_s('bulk')); @@ -310,7 +310,7 @@ class single_view_bulk_insert_ui extends single_view_ui_element { ); $label = html_writer::tag('label', $_s('for')); - $text = new single_view_text_attribute($this->insertname, "0"); + $text = new singleview_text_attribute($this->insertname, "0"); return implode(' ', array($apply, $text->html(), $label, $select)); } @@ -319,7 +319,7 @@ class single_view_bulk_insert_ui extends single_view_ui_element { } } -abstract class single_view_attribute_format { +abstract class singleview_attribute_format { abstract function determine_format(); function __toString() { @@ -327,7 +327,7 @@ abstract class single_view_attribute_format { } } -class single_view_finalgrade_ui extends single_view_grade_attribute_format implements unique_value, be_disabled { +class singleview_finalgrade_ui extends singleview_grade_attribute_format implements unique_value, be_disabled { var $name = 'finalgrade'; @@ -368,7 +368,7 @@ class single_view_finalgrade_ui extends single_view_grade_attribute_format imple $options[$i + 1] = $name; } - return new single_view_dropdown_attribute( + return new singleview_dropdown_attribute( $this->get_name(), $options, $this->get_value(), @@ -376,7 +376,7 @@ class single_view_finalgrade_ui extends single_view_grade_attribute_format imple $this->get_tabindex() ); } else { - return new single_view_text_attribute( + return new singleview_text_attribute( $this->get_name(), $this->get_value(), $this->is_disabled(), @@ -427,12 +427,12 @@ class single_view_finalgrade_ui extends single_view_grade_attribute_format imple $errorstr = get_string($errorstr, 'grades', $gradestr); } - $grade_item->update_final_grade($userid, $finalgrade, 'single_view', $feedback, FORMAT_MOODLE); + $grade_item->update_final_grade($userid, $finalgrade, 'singleview', $feedback, FORMAT_MOODLE); return $errorstr; } } -class single_view_feedback_ui extends single_view_grade_attribute_format implements unique_value, be_disabled { +class singleview_feedback_ui extends singleview_grade_attribute_format implements unique_value, be_disabled { var $name = 'feedback'; @@ -456,7 +456,7 @@ class single_view_feedback_ui extends single_view_grade_attribute_format impleme } function determine_format() { - return new single_view_text_attribute( + return new singleview_text_attribute( $this->get_name(), $this->get_value(), $this->is_disabled(), @@ -474,14 +474,14 @@ class single_view_feedback_ui extends single_view_grade_attribute_format impleme } $this->grade->grade_item->update_final_grade( - $this->grade->userid, $finalgrade, 'single_view', + $this->grade->userid, $finalgrade, 'singleview', $feedback, FORMAT_MOODLE ); return false; } } -class single_view_override_ui extends single_view_grade_attribute_format implements be_checked, be_disabled { +class singleview_override_ui extends singleview_grade_attribute_format implements be_checked, be_disabled { var $name = 'override'; function is_checked() { @@ -497,9 +497,9 @@ class single_view_override_ui extends single_view_grade_attribute_format impleme function determine_format() { if (!$this->grade->grade_item->is_overridable_item()) { - return new single_view_empty_element(); + return new singleview_empty_element(); } - return new single_view_checkbox_attribute( + return new singleview_checkbox_attribute( $this->get_name(), $this->is_checked(), null, @@ -520,7 +520,7 @@ class single_view_override_ui extends single_view_grade_attribute_format impleme } } -class single_view_exclude_ui extends single_view_grade_attribute_format implements be_checked { +class singleview_exclude_ui extends singleview_grade_attribute_format implements be_checked { var $name = 'exclude'; function is_checked() { @@ -528,7 +528,7 @@ class single_view_exclude_ui extends single_view_grade_attribute_format implemen } function determine_format() { - return new single_view_checkbox_attribute( + return new singleview_checkbox_attribute( $this->get_name(), $this->is_checked() ); @@ -544,7 +544,7 @@ class single_view_exclude_ui extends single_view_grade_attribute_format implemen // Fill in arbitrary grade to be excluded. $grade_item->update_final_grade( - $this->grade->userid, null, 'single_view', null, FORMAT_MOODLE + $this->grade->userid, null, 'singleview', null, FORMAT_MOODLE ); $grade_params = array( @@ -565,7 +565,7 @@ class single_view_exclude_ui extends single_view_grade_attribute_format implemen } } -class single_view_range_ui extends single_view_attribute_format { +class singleview_range_ui extends singleview_attribute_format { function __construct($item) { $this->item = $item; } @@ -576,6 +576,6 @@ class single_view_range_ui extends single_view_attribute_format { $min = format_float($this->item->grademin, $decimals); $max = format_float($this->item->grademax, $decimals); - return new single_view_empty_element("$min - $max"); + return new singleview_empty_element("$min - $max"); } } diff --git a/grade/report/single_view/db/access.php b/grade/report/singleview/db/access.php similarity index 97% rename from grade/report/single_view/db/access.php rename to grade/report/singleview/db/access.php index ee7fcb677d1..d7ff86505e8 100755 --- a/grade/report/single_view/db/access.php +++ b/grade/report/singleview/db/access.php @@ -26,7 +26,7 @@ $capabilities = array( - 'gradereport/single_view:view' => array( + 'gradereport/singleview:view' => array( 'riskbitmask' => RISK_PERSONAL, 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, diff --git a/grade/report/single_view/index.php b/grade/report/singleview/index.php similarity index 85% rename from grade/report/single_view/index.php rename to grade/report/singleview/index.php index 30db476a078..32cd9d72324 100755 --- a/grade/report/single_view/index.php +++ b/grade/report/singleview/index.php @@ -25,7 +25,7 @@ require_once '../../../config.php'; require_once $CFG->dirroot.'/lib/gradelib.php'; require_once $CFG->dirroot.'/grade/lib.php'; -require_once $CFG->dirroot.'/grade/report/single_view/lib.php'; +require_once $CFG->dirroot.'/grade/report/singleview/lib.php'; $courseid = required_param('id', PARAM_INT); $groupid = optional_param('group', null, PARAM_INT); @@ -40,14 +40,14 @@ $itemtype = optional_param('item', $default_type, PARAM_TEXT); $course_params = array('id' => $courseid); -$PAGE->set_url(new moodle_url('/grade/report/single_view/index.php', $course_params)); +$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $course_params)); if (!$course = $DB->get_record('course', $course_params)) { print_error('nocourseid'); } -if (!in_array($itemtype, grade_report_single_view::valid_screens())) { - print_error('notvalid', 'gradereport_single_view', '', $itemtype); +if (!in_array($itemtype, grade_report_singleview::valid_screens())) { + print_error('notvalid', 'gradereport_singleview', '', $itemtype); } require_login($course); @@ -55,14 +55,14 @@ require_login($course); $context = context_course::instance($course->id); // This is the normal requirements -require_capability('gradereport/single_view:view', $context); +require_capability('gradereport/singleview:view', $context); require_capability('moodle/grade:viewall', $context); require_capability('moodle/grade:edit', $context); // End permission $gpr = new grade_plugin_return(array( 'type' => 'report', - 'plugin' => 'single_view', + 'plugin' => 'singleview', 'courseid' => $courseid )); @@ -70,21 +70,21 @@ $gpr = new grade_plugin_return(array( if (!isset($USER->grade_last_report)) { $USER->grade_last_report = array(); } -$USER->grade_last_report[$course->id] = 'single_view'; +$USER->grade_last_report[$course->id] = 'singleview'; grade_regrade_final_grades($courseid); -$report = new grade_report_single_view( +$report = new grade_report_singleview( $courseid, $gpr, $context, $itemtype, $itemid, $groupid ); $reportname = $report->screen->heading(); -$pluginname = get_string('pluginname', 'gradereport_single_view'); +$pluginname = get_string('pluginname', 'gradereport_singleview'); $report_url = new moodle_url('/grade/report/grader/index.php', $course_params); -$edit_url = new moodle_url('/grade/report/single_view/index.php', $course_params); +$edit_url = new moodle_url('/grade/report/singleview/index.php', $course_params); $PAGE->navbar->ignore_active(true); @@ -116,7 +116,7 @@ if ($report->screen instanceof selectable_items $optionkeys = array_keys($report->screen->options()); $optionitemid = array_shift($optionkeys); //just any one thanks - $relreport = new grade_report_single_view( + $relreport = new grade_report_singleview( $courseid, $gpr, $context, $report->screen->item_type(), $optionitemid, $groupid ); @@ -127,19 +127,20 @@ if ($report->screen instanceof selectable_items $navparams = array('item' => $itemtype, 'id' => $courseid, 'group' => $groupid); if ($i>0) { $navparams['itemid'] = $reloptionssorting[$i-1]; - $link = new moodle_url('/grade/report/single_view/index.php', $navparams); + $link = new moodle_url('/grade/report/singleview/index.php', $navparams); $navprev=html_writer::link($link, $reloptions[$reloptionssorting[$i-1]]); $graderleftnav = html_writer::tag('small', $navprev, array('class' => 'itemnav previtem')); } if ($i 'itemnav nextitem')); } } -print_grade_page_head($course->id, 'report', 'single_view', $reportname); +print_grade_page_head($course->id, 'report', 'singleview', $reportname); + if(!is_null($graderleftnav)) { echo $graderleftnav; } diff --git a/grade/report/single_view/js/single_view.js b/grade/report/singleview/js/singleview.js similarity index 94% rename from grade/report/single_view/js/single_view.js rename to grade/report/singleview/js/singleview.js index cfa6c0641c4..02d7be898c9 100644 --- a/grade/report/single_view/js/single_view.js +++ b/grade/report/singleview/js/singleview.js @@ -1,6 +1,6 @@ -M.gradereport_single_view = {}; +M.gradereport_singleview = {}; -M.gradereport_single_view.init = function(Y) { +M.gradereport_singleview.init = function(Y) { // Make toggle links Y.all('.include').each(function(link) { var type = link.getAttribute('class').split(" ")[2]; diff --git a/grade/report/single_view/lang/en/gradereport_single_view.php b/grade/report/singleview/lang/en/gradereport_singleview.php similarity index 96% rename from grade/report/single_view/lang/en/gradereport_single_view.php rename to grade/report/singleview/lang/en/gradereport_singleview.php index e3ce90beb42..6c7117add7e 100755 --- a/grade/report/single_view/lang/en/gradereport_single_view.php +++ b/grade/report/singleview/lang/en/gradereport_singleview.php @@ -24,7 +24,7 @@ // General Strings $string['pluginname'] = 'Single view'; -$string['single_view:view'] = 'View the '.$string['pluginname'].' report'; +$string['singleview:view'] = 'View the '.$string['pluginname'].' report'; $string['not_allowed'] = 'Not allowed to quick edit this item'; $string['filtergrades'] = 'Show grades for {$a}.'; diff --git a/grade/report/single_view/lib.php b/grade/report/singleview/lib.php similarity index 88% rename from grade/report/single_view/lib.php rename to grade/report/singleview/lib.php index 16b091e68d1..32adb850b82 100755 --- a/grade/report/single_view/lib.php +++ b/grade/report/singleview/lib.php @@ -23,9 +23,9 @@ /////////////////////////////////////////////////////////////////////////// require_once($CFG->dirroot . '/grade/report/lib.php'); -require_once($CFG->dirroot . '/grade/report/single_view/classes/lib.php'); +require_once($CFG->dirroot . '/grade/report/singleview/classes/lib.php'); -class grade_report_single_view extends grade_report { +class grade_report_singleview extends grade_report { public static function valid_screens() { $screendir = dirname(__FILE__) . '/screens'; @@ -53,11 +53,11 @@ class grade_report_single_view extends grade_report { require_once $screendir . '/lib.php'; - return 'single_view_' . $screen; + return 'singleview_' . $screen; } public static function filters() { - $classnames = array('grade_report_single_view', 'classname'); + $classnames = array('grade_report_singleview', 'classname'); $classes = array_map($classnames, self::valid_screens()); $screens = array_filter($classes, function($screen) { @@ -81,7 +81,7 @@ class grade_report_single_view extends grade_report { } function _s($key, $a = null) { - return get_string($key, 'gradereport_single_view', $a); + return get_string($key, 'gradereport_singleview', $a); } function __construct($courseid, $gpr, $context, $itemtype, $itemid, $groupid=null) { @@ -97,7 +97,7 @@ class grade_report_single_view extends grade_report { // Load custom or predifined js $this->screen->js(); - $base = '/grade/report/single_view/index.php'; + $base = '/grade/report/singleview/index.php'; $id_params = array('id' => $courseid); @@ -117,7 +117,7 @@ class grade_report_single_view extends grade_report { } } -function grade_report_single_view_profilereport($course, $user) { +function grade_report_singleview_profilereport($course, $user) { global $CFG, $OUTPUT; if (!function_exists('grade_report_user_profilereport')) { @@ -127,7 +127,7 @@ function grade_report_single_view_profilereport($course, $user) { $context = context_course::instance($course->id); $can_use = ( - has_capability('gradereport/single_view:view', $context) and + has_capability('gradereport/singleview:view', $context) and has_capability('moodle/grade:viewall', $context) and has_capability('moodle/grade:edit', $context) ); @@ -137,12 +137,12 @@ function grade_report_single_view_profilereport($course, $user) { } else { $gpr = new grade_plugin_return(array( 'type' => 'report', - 'plugin' => 'single_view', + 'plugin' => 'singleview', 'courseid' => $course->id, 'userid' => $user->id )); - $report = new grade_report_single_view($course->id, $gpr, $context, 'user', $user->id); + $report = new grade_report_singleview($course->id, $gpr, $context, 'user', $user->id); echo $OUTPUT->heading($report->screen->heading()); echo $report->output(); diff --git a/grade/report/single_view/screens/grade/lib.php b/grade/report/singleview/screens/grade/lib.php similarity index 95% rename from grade/report/single_view/screens/grade/lib.php rename to grade/report/singleview/screens/grade/lib.php index 2b802c9b722..362b9fd22fa 100644 --- a/grade/report/single_view/screens/grade/lib.php +++ b/grade/report/singleview/screens/grade/lib.php @@ -18,12 +18,12 @@ /** * The gradebook simple view - grades view (for an activity) * - * @package simple_view + * @package singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class single_view_grade extends single_view_tablelike +class singleview_grade extends singleview_tablelike implements selectable_items, item_filtering { private $requires_extra = false; @@ -114,12 +114,12 @@ class single_view_grade extends single_view_tablelike $this->item = grade_item::fetch($params); - $filter_fun = grade_report_single_view::filters(); + $filter_fun = grade_report_singleview::filters(); $allowed = $filter_fun($this->item); if (empty($allowed)) { - print_error('not_allowed', 'gradereport_single_view'); + print_error('not_allowed', 'gradereport_singleview'); } $this->requires_extra = !$this->item->is_manual_item(); @@ -169,7 +169,7 @@ class single_view_grade extends single_view_tablelike $url = new moodle_url("/user/view.php", array('id' => $item->id, 'course' => $this->courseid)); $line = array( - $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $fullname))), + $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_singleview', $fullname))), $OUTPUT->user_picture($item), html_writer::tag('a', $fullname, array('href' => $url)), $this->item_range() @@ -204,7 +204,7 @@ class single_view_grade extends single_view_tablelike return $OUTPUT->paging_bar( count($this->all_items), $this->page, $this->perpage, - new moodle_url('/grade/report/single_view/index.php', array( + new moodle_url('/grade/report/singleview/index.php', array( 'perpage' => $this->perpage, 'id' => $this->courseid, 'groupid' => $this->groupid, diff --git a/grade/report/single_view/screens/select/lib.php b/grade/report/singleview/screens/select/lib.php similarity index 86% rename from grade/report/single_view/screens/select/lib.php rename to grade/report/singleview/screens/select/lib.php index 282d94fcc5a..e58a5d5b9b4 100644 --- a/grade/report/single_view/screens/select/lib.php +++ b/grade/report/singleview/screens/select/lib.php @@ -18,12 +18,12 @@ /** * The gradebook simple view - initial view to select your search options * - * @package simple_view + * @package singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class single_view_select extends single_view_screen { +class singleview_select extends singleview_screen { public function init($self_item_is_empty = false) { global $DB; @@ -35,10 +35,10 @@ class single_view_select extends single_view_screen { $html = ''; - $types = grade_report_single_view::valid_screens(); + $types = grade_report_singleview::valid_screens(); foreach ($types as $type) { - $class = grade_report_single_view::classname($type); + $class = grade_report_singleview::classname($type); $screen = new $class($this->courseid, null, $this->groupid); @@ -58,14 +58,14 @@ class single_view_select extends single_view_screen { 'group' => $this->groupid ); - $url = new moodle_url('/grade/report/single_view/index.php', $params); + $url = new moodle_url('/grade/report/singleview/index.php', $params); $html .= $OUTPUT->heading($screen->description()); $html .= $OUTPUT->single_select($url, 'itemid', $options); } if (empty($html)) { - $OUTPUT->notification(get_string('no_screens', 'gradereport_single_view')); + $OUTPUT->notification(get_string('no_screens', 'gradereport_singleview')); } return $html; diff --git a/grade/report/single_view/screens/user/lib.php b/grade/report/singleview/screens/user/lib.php similarity index 95% rename from grade/report/single_view/screens/user/lib.php rename to grade/report/singleview/screens/user/lib.php index d011e223631..05cae08683f 100644 --- a/grade/report/single_view/screens/user/lib.php +++ b/grade/report/singleview/screens/user/lib.php @@ -18,12 +18,12 @@ /** * The gradebook simple view - grades view (for a user) * - * @package simple_view + * @package singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class single_view_user extends single_view_tablelike implements selectable_items { +class singleview_user extends singleview_tablelike implements selectable_items { private $categories = array(); @@ -62,7 +62,7 @@ class single_view_user extends single_view_tablelike implements selectable_items } } - $this->items = array_filter($seq->items, grade_report_single_view::filters()); + $this->items = array_filter($seq->items, grade_report_singleview::filters()); unset($seq); @@ -78,7 +78,7 @@ class single_view_user extends single_view_tablelike implements selectable_items return array( '', // for filter icon. '', // for activity icon. - get_string('assessmentname', 'gradereport_single_view'), + get_string('assessmentname', 'gradereport_singleview'), get_string('gradecategory', 'grades'), get_string('range', 'grades'), get_string('grade', 'grades'), @@ -104,7 +104,7 @@ class single_view_user extends single_view_tablelike implements selectable_items $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $item->cmid)); $line = array( - $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_single_view', $item->get_name()))), + $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_singleview', $item->get_name()))), $this->format_icon($item) . $lockicon, html_writer::link($url, $item->get_name()), $this->category($item), diff --git a/grade/report/singleview/styles.css b/grade/report/singleview/styles.css new file mode 100644 index 00000000000..d7e88178de0 --- /dev/null +++ b/grade/report/singleview/styles.css @@ -0,0 +1,51 @@ +#page-grade-report-singleview-index div.generalbox { + margin: 0 20px 15px 20px; +} + +#page-grade-report-singleview-index div.generalbox div.singleselect form div { + text-align: center; +} + +#page-grade-report-singleview-index div.generalbox table.generaltable { + margin: 0 auto 15px auto; +} + +#page-grade-report-singleview-index div.generalbox form div { + text-align: center; +} + +#page-grade-report-singleview-index .singleview_buttons { + padding: 10px 0; +} + +#page-grade-report-singleview-index table.generaltable .cell { + vertical-align: middle; +} + +#page-grade-report-singleview-index div.generalbox h2 { + text-align: center; +} + +input[name^="finalgrade"] { + width: 50px; +} + +#page-grade-report-singleview-index #region-main h2, .paging{ + text-align: center; +} + +#page-grade-report-singleview-index itemnav.previtem { + float:left; +} +#page-grade-report-singleview-index itemnav.previtem { + float:left; +} +#page-grade-report-singleview-index.dir-rtl small.previtem { + float:right; +} +#page-grade-report-singleview-index small.nextitem { + float:right; +} +#page-grade-report-singleview-index.dir-rtl small.nextitem { + float:left; +} diff --git a/grade/report/single_view/version.php b/grade/report/singleview/version.php similarity index 100% rename from grade/report/single_view/version.php rename to grade/report/singleview/version.php From 92c61fee641f55fa9ddf5c6e9362d11c9a906bc5 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Thu, 25 Sep 2014 15:51:45 +0800 Subject: [PATCH 08/16] MDL-18229 gradebook: Links to Single view via icons on Grade Report. --- grade/report/grader/lib.php | 15 +++++++++++++-- grade/report/singleview/screens/grade/lib.php | 4 ++-- lang/en/grades.php | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index f9feea807d8..677f10a5a76 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -665,8 +665,10 @@ class grade_report_grader extends grade_report { $a = new stdClass(); $a->user = $fullname; $strgradesforuser = get_string('gradesforuser', 'grades', $a); + $url = new moodle_url('/grade/report/singleview/index.php', array('id' => $this->course->id, 'itemid' => $user->id, 'item' => 'user')); + $singleview = $OUTPUT->action_icon($url, new pix_icon('t/editstring', get_string('singleview', 'grades', $fullname))); $url = new moodle_url('/grade/report/'.$CFG->grade_profilereport.'/index.php', array('userid' => $user->id, 'id' => $this->course->id)); - $userreportcell->text = $OUTPUT->action_icon($url, new pix_icon('t/grades', $strgradesforuser)); + $userreportcell->text = $OUTPUT->action_icon($url, new pix_icon('t/grades', $strgradesforuser)) . $singleview; $userrow->cells[] = $userreportcell; } @@ -805,8 +807,17 @@ class grade_report_grader extends grade_report { $itemcell->attributes['class'] .= ' dimmed_text'; } + $singleview = ''; + if (has_capability('gradereport/'.$CFG->grade_profilereport.':view', $this->context)) { + $url = new moodle_url('/grade/report/singleview/index.php', array( + 'id' => $this->course->id, + 'item' => 'grade', + 'itemid' => $element['object']->id)); + $singleview = $OUTPUT->action_icon($url, new pix_icon('t/editstring', get_string('singleview', 'grades', $element['object']->itemname))); + } + $itemcell->colspan = $colspan; - $itemcell->text = shorten_text($headerlink) . $arrow; + $itemcell->text = shorten_text($headerlink) . $arrow . $singleview; $itemcell->header = true; $itemcell->scope = 'col'; diff --git a/grade/report/singleview/screens/grade/lib.php b/grade/report/singleview/screens/grade/lib.php index 362b9fd22fa..3a894d9db43 100644 --- a/grade/report/singleview/screens/grade/lib.php +++ b/grade/report/singleview/screens/grade/lib.php @@ -169,9 +169,9 @@ class singleview_grade extends singleview_tablelike $url = new moodle_url("/user/view.php", array('id' => $item->id, 'course' => $this->courseid)); $line = array( - $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_singleview', $fullname))), + $OUTPUT->action_icon($this->format_link('user', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_singleview', $fullname))), $OUTPUT->user_picture($item), - html_writer::tag('a', $fullname, array('href' => $url)), + html_writer::link($url, $fullname), $this->item_range() ); return $this->format_definition($line, $grade); diff --git a/lang/en/grades.php b/lang/en/grades.php index 31816c06ca4..122d155453e 100644 --- a/lang/en/grades.php +++ b/lang/en/grades.php @@ -309,6 +309,7 @@ $string['gradereport'] = 'Grade report'; $string['graderreport'] = 'Grader report'; $string['grades'] = 'Grades'; $string['gradesforuser'] = 'Grades for {$a->user}'; +$string['singleview'] = 'Single view for {$a}'; $string['gradesonly'] = 'Grades only'; $string['gradessettings'] = 'Grade settings'; $string['gradetype'] = 'Grade type'; From 65c134f98aa4213fc4019f62af4996dc955d64a7 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Fri, 26 Sep 2014 15:18:59 +0800 Subject: [PATCH 09/16] MDL-18229 gradebook: Updating code to Moodle standard. --- grade/report/singleview/classes/lib.php | 10 +- grade/report/singleview/classes/uilib.php | 201 ++++++++++-------- grade/report/singleview/db/access.php | 47 ++-- grade/report/singleview/index.php | 102 +++++---- .../lang/en/gradereport_singleview.php | 69 +++--- grade/report/singleview/lib.php | 57 ++--- grade/report/singleview/screens/grade/lib.php | 76 +++---- .../report/singleview/screens/select/lib.php | 4 +- grade/report/singleview/screens/user/lib.php | 44 ++-- grade/report/singleview/version.php | 44 ++-- 10 files changed, 328 insertions(+), 326 deletions(-) diff --git a/grade/report/singleview/classes/lib.php b/grade/report/singleview/classes/lib.php index f0772258658..091a2a68a59 100644 --- a/grade/report/singleview/classes/lib.php +++ b/grade/report/singleview/classes/lib.php @@ -18,7 +18,7 @@ /** * The gradebook simple view - base class for the table * - * @package singleview + * @package gradereport_singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -213,7 +213,9 @@ abstract class singleview_screen { $oldname = "old$name"; $posted = $data->$name; - $oldvalue = $data->$oldname; + if (isset($data->$oldname)) { + $oldvalue = $data->$oldname; + } $format = $element->determine_format(); @@ -240,8 +242,6 @@ abstract class singleview_screen { $event_data->post_data = $data; $event_data->instance = $this; - qe_events_trigger(get_class($this) . '_edited', $event_data); - return $event_data->warnings; } @@ -378,8 +378,6 @@ abstract class singleview_tablelike extends singleview_screen implements tabbabl $data->table = $table; $data->instance = $this; - qe_events_trigger($underlying . '_table_built', $data); - $button_attr = array('class' => 'singleview_buttons submit'); $button_html = implode(' ', $this->buttons()); diff --git a/grade/report/singleview/classes/uilib.php b/grade/report/singleview/classes/uilib.php index cc676ca678e..9112a913204 100644 --- a/grade/report/singleview/classes/uilib.php +++ b/grade/report/singleview/classes/uilib.php @@ -18,7 +18,7 @@ /** * The gradebook simple view - UI factory * - * @package singleview + * @package gradereport_singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -38,11 +38,11 @@ class singleview_grade_ui_factory extends singleview_ui_factory { } class singleview_factory_class_wrap { - function __construct($class) { + public function __construct($class) { $this->class = $class; } - function format() { + public function format() { $args = func_get_args(); $reflect = new ReflectionClass($this->class); @@ -54,28 +54,28 @@ abstract class singleview_ui_element { var $name; var $value; - function __construct($name, $value) { + public function __construct($name, $value) { $this->name = $name; $this->value = $value; } - function is_checkbox() { + public function is_checkbox() { return false; } - function is_textbox() { + public function is_textbox() { return false; } - function is_dropdown() { + public function is_dropdown() { return false; } - abstract function html(); + abstract public function html(); } class singleview_empty_element extends singleview_ui_element { - function __construct($msg = null) { + public function __construct($msg = null) { if (is_null($msg)) { $this->text = get_string('notavailable', 'gradereport_singleview'); } else { @@ -83,26 +83,26 @@ class singleview_empty_element extends singleview_ui_element { } } - function html() { + public function html() { return $this->text; } } class singleview_text_attribute extends singleview_ui_element { - var $is_disabled; - var $tabindex; + private $isdisabled; + private $tabindex; - function __construct($name, $value, $is_disabled = false, $tabindex = null) { - $this->is_disabled = $is_disabled; + public function __construct($name, $value, $isdisabled = false, $tabindex = null) { + $this->isdisabled = $isdisabled; $this->tabindex = $tabindex; parent::__construct($name, $value); } - function is_textbox() { + public function is_textbox() { return true; } - function html() { + public function html() { $attributes = array( 'type' => 'text', 'name' => $this->name, @@ -112,7 +112,7 @@ class singleview_text_attribute extends singleview_ui_element { if (!empty($this->tabindex)) { $attributes['tabindex'] = $this->tabindex; } - if ($this->is_disabled) { + if ($this->isdisabled) { $attributes['disabled'] = 'DISABLED'; } @@ -122,29 +122,29 @@ class singleview_text_attribute extends singleview_ui_element { 'value' => $this->value ); - return ( - html_writer::empty_tag('input', $attributes) . + return ( + html_writer::empty_tag('input', $attributes) . html_writer::empty_tag('input', $hidden) ); } } class singleview_checkbox_attribute extends singleview_ui_element { - var $is_checked; - var $tabindex; + private $ischecked; + private $tabindex; - function __construct($name, $is_checked = false, $tabindex = null, $locked=0) { - $this->is_checked = $is_checked; + public function __construct($name, $ischecked = false, $tabindex = null, $locked=0) { + $this->ischecked = $ischecked; $this->tabindex = $tabindex; $this->locked = $locked; parent::__construct($name, 1); } - function is_checkbox() { + public function is_checkbox() { return true; } - function html() { + public function html() { $attributes = array( 'type' => 'checkbox', @@ -172,7 +172,7 @@ class singleview_checkbox_attribute extends singleview_ui_element { $attributes['tabindex'] = $this->tabindex; } - if ($this->is_checked) { + if ($this->ischecked) { $attributes['checked'] = 'CHECKED'; $hidden['value'] = 1; } @@ -186,23 +186,23 @@ class singleview_checkbox_attribute extends singleview_ui_element { } class singleview_dropdown_attribute extends singleview_ui_element { - var $selected; - var $options; - var $is_disabled; + private $selected; + private $options; + private $isdisabled; - function __construct($name, $options, $selected = '', $is_disabled = false, $tabindex = null) { + public function __construct($name, $options, $selected = '', $isdisabled = false, $tabindex = null) { $this->selected = $selected; $this->options = $options; $this->tabindex = $tabindex; - $this->is_disabled = $is_disabled; + $this->isdisabled = $isdisabled; parent::__construct($name, $selected); } - function is_dropdown() { + public function is_dropdown() { return true; } - function html() { + public function html() { $old = array( 'type' => 'hidden', 'name' => 'old' . $this->name, @@ -214,7 +214,7 @@ class singleview_dropdown_attribute extends singleview_ui_element { $attributes['tabindex'] = $this->tabindex; } - if (!empty($this->is_disabled)) { + if (!empty($this->isdisabled)) { $attributes['disabled'] = 'DISABLED'; } @@ -227,20 +227,20 @@ class singleview_dropdown_attribute extends singleview_ui_element { } abstract class singleview_grade_attribute_format extends singleview_attribute_format implements unique_name, tabbable { - var $name; + public $name; - function __construct() { + public function __construct() { $args = func_get_args(); $this->get_arg_or_nothing($args, 0, 'grade'); $this->get_arg_or_nothing($args, 1, 'tabindex'); } - function get_name() { + public function get_name() { return "{$this->name}_{$this->grade->itemid}_{$this->grade->userid}"; } - function get_tabindex() { + public function get_tabindex() { return isset($this->tabindex) ? $this->tabindex : null; } @@ -254,62 +254,62 @@ abstract class singleview_grade_attribute_format extends singleview_attribute_fo } interface unique_name { - function get_name(); + public function get_name(); } interface unique_value { - function get_value(); + public function get_value(); } interface be_disabled { - function is_disabled(); + public function is_disabled(); } interface be_checked { - function is_checked(); + public function ischecked(); } interface tabbable { - function get_tabindex(); + public function get_tabindex(); } class singleview_bulk_insert_ui extends singleview_ui_element { - function __construct($item) { + public function __construct($item) { $this->name = 'bulk_' . $item->id; $this->applyname = $this->name_for('apply'); $this->selectname = $this->name_for('type'); $this->insertname = $this->name_for('value'); } - function is_applied($data) { + public function is_applied($data) { return isset($data->{$this->applyname}); } - function get_type($data) { + public function get_type($data) { return $data->{$this->selectname}; } - function get_insert_value($data) { + public function get_insert_value($data) { return $data->{$this->insertname}; } - function html() { - $_s = function($key) { + public function html() { + $s = function($key) { return get_string($key, 'gradereport_singleview'); }; - $apply = html_writer::checkbox($this->applyname, 1, false, ' ' . $_s('bulk')); + $apply = html_writer::checkbox($this->applyname, 1, false, ' ' . $s('bulk')); - $insert_options = array( - 'all' => $_s('all_grades'), - 'blanks' => $_s('blanks') + $insertoptions = array( + 'all' => $s('all_grades'), + 'blanks' => $s('blanks') ); $select = html_writer::select( - $insert_options, $this->selectname, 'blanks', false + $insertoptions, $this->selectname, 'blanks', false ); - $label = html_writer::tag('label', $_s('for')); + $label = html_writer::tag('label', $s('for')); $text = new singleview_text_attribute($this->insertname, "0"); return implode(' ', array($apply, $text->html(), $label, $select)); } @@ -320,18 +320,18 @@ class singleview_bulk_insert_ui extends singleview_ui_element { } abstract class singleview_attribute_format { - abstract function determine_format(); + abstract public function determine_format(); - function __toString() { + public function __toString() { return $this->determine_format()->html(); } } class singleview_finalgrade_ui extends singleview_grade_attribute_format implements unique_value, be_disabled { - var $name = 'finalgrade'; + public $name = 'finalgrade'; - function get_value() { + public function get_value() { // Manual item raw grade support. $val = $this->grade->grade_item->is_manual_item() && (!is_null($this->grade->rawgrade)) ? $this->grade->rawgrade : $this->grade->finalgrade; @@ -343,7 +343,7 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme } } - function is_disabled() { + public function is_disabled() { $locked = 0; $gradeitemlocked = 0; $overridden = 0; @@ -352,13 +352,19 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme * at some point, we might want to show the reason for the lock * this code could be simplified, but its more readable for steve's little mind */ - if (!empty($this->grade->locked)) $locked = 1; - if (!empty($this->grade->grade_item->locked)) $gradeitemlocked = 1; - if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) $overridden = 1; + if (!empty($this->grade->locked)) { + $locked = 1; + } + if (!empty($this->grade->grade_item->locked)) { + $gradeitemlocked = 1; + } + if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) { + $overridden = 1; + } return ($locked || $gradeitemlocked || $overridden); } - function determine_format() { + public function determine_format() { if ($this->grade->grade_item->load_scale()) { $scale = $this->grade->grade_item->load_scale(); @@ -385,15 +391,15 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme } } - function set($value) { + public function set($value) { global $DB; $userid = $this->grade->userid; - $grade_item = $this->grade->grade_item; + $gradeitem = $this->grade->grade_item; $feedback = false; $feedbackformat = false; - if ($grade_item->gradetype == GRADE_TYPE_SCALE) { + if ($gradeitem->gradetype == GRADE_TYPE_SCALE) { if ($value == -1) { $finalgrade = null; } else { @@ -404,9 +410,8 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme } $errorstr = ''; - if (is_null($finalgrade)) { - } else { - $bounded = $grade_item->bounded_grade($finalgrade); + if ($finalgrade) { + $bounded = $gradeitem->bounded_grade($finalgrade); if ($bounded > $finalgrade) { $errorstr = 'lessthanmin'; } else if ($bounded < $finalgrade) { @@ -427,20 +432,20 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme $errorstr = get_string($errorstr, 'grades', $gradestr); } - $grade_item->update_final_grade($userid, $finalgrade, 'singleview', $feedback, FORMAT_MOODLE); + $gradeitem->update_final_grade($userid, $finalgrade, 'singleview', $feedback, FORMAT_MOODLE); return $errorstr; } } class singleview_feedback_ui extends singleview_grade_attribute_format implements unique_value, be_disabled { - var $name = 'feedback'; + public $name = 'feedback'; - function get_value() { + public function get_value() { return $this->grade->feedback ? $this->grade->feedback : ''; } - function is_disabled() { + public function is_disabled() { $locked = 0; $gradeitemlocked = 0; $overridden = 0; @@ -449,13 +454,19 @@ class singleview_feedback_ui extends singleview_grade_attribute_format implement * at some point, we might want to show the reason for the lock * this code could be simplified, but its more readable for steve's little mind */ - if (!empty($this->grade->locked)) $locked = 1; - if (!empty($this->grade->grade_item->locked)) $gradeitemlocked = 1; - if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) $overridden = 1; + if (!empty($this->grade->locked)) { + $locked = 1; + } + if (!empty($this->grade->grade_item->locked)) { + $gradeitemlocked = 1; + } + if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) { + $overridden = 1; + } return ($locked || $gradeitemlocked || $overridden); } - function determine_format() { + public function determine_format() { return new singleview_text_attribute( $this->get_name(), $this->get_value(), @@ -464,11 +475,11 @@ class singleview_feedback_ui extends singleview_grade_attribute_format implement ); } - function set($value) { + public function set($value) { $finalgrade = false; $trimmed = trim($value); if (empty($trimmed)) { - $feedback = NULL; + $feedback = null; } else { $feedback = $value; } @@ -482,17 +493,21 @@ class singleview_feedback_ui extends singleview_grade_attribute_format implement } class singleview_override_ui extends singleview_grade_attribute_format implements be_checked, be_disabled { - var $name = 'override'; + public $name = 'override'; - function is_checked() { + public function ischecked() { return $this->grade->is_overridden(); } - function is_disabled() { - $locked_grade = $locked_grade_item = 0; - if ( ! empty($this->grade->locked) ) $locked_grade = 1; - if ( ! empty($this->grade->grade_item->locked) ) $locked_grade_item = 1; - return ($locked_grade || $locked_grade_item); + public function is_disabled() { + $lockedgrade = $lockedgradeitem = 0; + if ( ! empty($this->grade->locked) ) { + $lockedgrade = 1; + } + if ( ! empty($this->grade->grade_item->locked) ) { + $lockedgradeitem = 1; + } + return ($lockedgrade || $lockedgradeitem); } function determine_format() { @@ -501,7 +516,7 @@ class singleview_override_ui extends singleview_grade_attribute_format implement } return new singleview_checkbox_attribute( $this->get_name(), - $this->is_checked(), + $this->ischecked(), null, $this->is_disabled() ); @@ -523,14 +538,14 @@ class singleview_override_ui extends singleview_grade_attribute_format implement class singleview_exclude_ui extends singleview_grade_attribute_format implements be_checked { var $name = 'exclude'; - function is_checked() { + function ischecked() { return $this->grade->is_excluded(); } function determine_format() { return new singleview_checkbox_attribute( $this->get_name(), - $this->is_checked() + $this->ischecked() ); } @@ -540,10 +555,10 @@ class singleview_exclude_ui extends singleview_grade_attribute_format implements return false; } - $grade_item = $this->grade->grade_item; + $gradeitem = $this->grade->grade_item; // Fill in arbitrary grade to be excluded. - $grade_item->update_final_grade( + $gradeitem->update_final_grade( $this->grade->userid, null, 'singleview', null, FORMAT_MOODLE ); @@ -553,7 +568,7 @@ class singleview_exclude_ui extends singleview_grade_attribute_format implements ); $this->grade = grade_grade::fetch($grade_params); - $this->grade->grade_item = $grade_item; + $this->grade->grade_item = $gradeitem; } $state = $value == 0 ? false : true; diff --git a/grade/report/singleview/db/access.php b/grade/report/singleview/db/access.php index d7ff86505e8..c5bbe851ca7 100755 --- a/grade/report/singleview/db/access.php +++ b/grade/report/singleview/db/access.php @@ -1,28 +1,27 @@ -. +/** + * The gradebook simple view - Database file + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ $capabilities = array( @@ -36,5 +35,3 @@ $capabilities = array( ) ) ); - -?> diff --git a/grade/report/singleview/index.php b/grade/report/singleview/index.php index 32cd9d72324..a6ce750daec 100755 --- a/grade/report/singleview/index.php +++ b/grade/report/singleview/index.php @@ -1,48 +1,48 @@ . -require_once '../../../config.php'; -require_once $CFG->dirroot.'/lib/gradelib.php'; -require_once $CFG->dirroot.'/grade/lib.php'; -require_once $CFG->dirroot.'/grade/report/singleview/lib.php'; +/** + * Displays the Single view + * + * @package gradereport_singleview + * @copyright 2014 Moodle + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once('../../../config.php'); +require_once($CFG->dirroot.'/lib/gradelib.php'); +require_once($CFG->dirroot.'/grade/lib.php'); +require_once($CFG->dirroot.'/grade/report/singleview/lib.php'); $courseid = required_param('id', PARAM_INT); $groupid = optional_param('group', null, PARAM_INT); - // Making this work with profile reports $userid = optional_param('userid', null, PARAM_INT); -$default_type = $userid ? 'user' : 'select'; +$defaulttype = $userid ? 'user' : 'select'; $itemid = optional_param('itemid', $userid, PARAM_INT); -$itemtype = optional_param('item', $default_type, PARAM_TEXT); +$itemtype = optional_param('item', $defaulttype, PARAM_TEXT); -$course_params = array('id' => $courseid); +$courseparams = array('id' => $courseid); -$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $course_params)); +$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $courseparams)); -if (!$course = $DB->get_record('course', $course_params)) { +if (!$course = $DB->get_record('course', $courseparams)) { print_error('nocourseid'); } @@ -54,11 +54,11 @@ require_login($course); $context = context_course::instance($course->id); -// This is the normal requirements +// This is the normal requirements. require_capability('gradereport/singleview:view', $context); require_capability('moodle/grade:viewall', $context); require_capability('moodle/grade:edit', $context); -// End permission +// End permission. $gpr = new grade_plugin_return(array( 'type' => 'report', @@ -66,7 +66,7 @@ $gpr = new grade_plugin_return(array( 'courseid' => $courseid )); -/// last selected report session tracking +// Last selected report session tracking. if (!isset($USER->grade_last_report)) { $USER->grade_last_report = array(); } @@ -83,19 +83,19 @@ $reportname = $report->screen->heading(); $pluginname = get_string('pluginname', 'gradereport_singleview'); -$report_url = new moodle_url('/grade/report/grader/index.php', $course_params); -$edit_url = new moodle_url('/grade/report/singleview/index.php', $course_params); +$reporturl = new moodle_url('/grade/report/grader/index.php', $courseparams); +$editurl = new moodle_url('/grade/report/singleview/index.php', $courseparams); $PAGE->navbar->ignore_active(true); $PAGE->navbar->add(get_string('courses')); -$PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', $course_params)); +$PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', $courseparams)); $PAGE->navbar->add(get_string('gradeadministration', 'grades')); -$PAGE->navbar->add(get_string('pluginname', 'gradereport_grader'), $report_url); +$PAGE->navbar->add(get_string('pluginname', 'gradereport_grader'), $reporturl); if ($reportname != $pluginname) { - $PAGE->navbar->add($pluginname, $edit_url); + $PAGE->navbar->add($pluginname, $editurl); $PAGE->navbar->add($reportname); } else { $PAGE->navbar->add($pluginname); @@ -105,16 +105,16 @@ if ($data = data_submitted()) { $warnings = $report->process_data($data); if (empty($warnings)) { - redirect($report_url); + redirect($reporturl); } } $graderrightnav = $graderleftnav = null; if ($report->screen instanceof selectable_items - && class_exists($report::classname($report->screen->item_type()))) { //should be ok for user and grade for now, allows other cross singleview nav too. + && class_exists($report::classname($report->screen->item_type()))) { $optionkeys = array_keys($report->screen->options()); - $optionitemid = array_shift($optionkeys); //just any one thanks + $optionitemid = array_shift($optionkeys); $relreport = new grade_report_singleview( $courseid, $gpr, $context, @@ -125,26 +125,26 @@ if ($report->screen instanceof selectable_items $i = array_search($itemid, $reloptionssorting); $navparams = array('item' => $itemtype, 'id' => $courseid, 'group' => $groupid); - if ($i>0) { - $navparams['itemid'] = $reloptionssorting[$i-1]; + if ($i > 0) { + $navparams['itemid'] = $reloptionssorting[$i - 1]; $link = new moodle_url('/grade/report/singleview/index.php', $navparams); - $navprev=html_writer::link($link, $reloptions[$reloptionssorting[$i-1]]); + $navprev = html_writer::link($link, $reloptions[$reloptionssorting[$i - 1]]); $graderleftnav = html_writer::tag('small', $navprev, array('class' => 'itemnav previtem')); } - if ($i 'itemnav nextitem')); } } print_grade_page_head($course->id, 'report', 'singleview', $reportname); -if(!is_null($graderleftnav)) { +if (!is_null($graderleftnav)) { echo $graderleftnav; } -if(!is_null($graderrightnav)) { +if (!is_null($graderrightnav)) { echo $graderrightnav; } @@ -176,5 +176,3 @@ if(!is_null($graderrightnav)) { } echo $OUTPUT->footer(); - -?> diff --git a/grade/report/singleview/lang/en/gradereport_singleview.php b/grade/report/singleview/lang/en/gradereport_singleview.php index 6c7117add7e..8628de4ea24 100755 --- a/grade/report/singleview/lang/en/gradereport_singleview.php +++ b/grade/report/singleview/lang/en/gradereport_singleview.php @@ -1,44 +1,39 @@ . + +/** + * Strings for Single view + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ // General Strings +$string['all_grades'] = 'All grades'; +$string['assessmentname'] = 'Assessment Name'; +$string['blanks'] = 'Empty grades'; +$string['bulk'] = 'Insert'; +$string['exclude'] = 'Exclude'; +$string['filtergrades'] = 'Show grades for {$a}.'; +$string['for'] = 'for'; +$string['override'] = 'Override'; $string['pluginname'] = 'Single view'; $string['singleview:view'] = 'View the '.$string['pluginname'].' report'; - -$string['not_allowed'] = 'Not allowed to quick edit this item'; -$string['filtergrades'] = 'Show grades for {$a}.'; -$string['no_screens'] = 'Could not find a suitable Single view screen.'; - -$string['exclude'] = 'Exclude'; -$string['override'] = 'Override'; -$string['assessmentname'] = 'Assessment Name'; -$string['notavailable'] = 'NA'; - -$string['bulk'] = 'Insert'; -$string['blanks'] = 'Empty grades'; -$string['for'] = 'for'; -$string['all_grades'] = 'All grades'; - -// Error Strings +$string['noscreens'] = 'Could not find a suitable Single view screen.'; +$string['notallowed'] = 'Not allowed to quick edit this item'; $string['notvalid'] = 'Not a valid Single view screen: {$a}'; diff --git a/grade/report/singleview/lib.php b/grade/report/singleview/lib.php index 32adb850b82..3fa3dff2e4d 100755 --- a/grade/report/singleview/lib.php +++ b/grade/report/singleview/lib.php @@ -1,26 +1,27 @@ . + +/** + * Base lib class for singleview functionality. + * + * @package gradereport_singleview + * @copyright 2014 Moodle + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ require_once($CFG->dirroot . '/grade/report/lib.php'); require_once($CFG->dirroot . '/grade/report/singleview/classes/lib.php'); @@ -91,9 +92,6 @@ class grade_report_singleview extends grade_report { $this->screen = new $class($courseid, $itemid, $groupid); - // TODO update events to new model - qe_events_trigger($class . '_instantiated', $this->screen); - // Load custom or predifined js $this->screen->js(); @@ -148,14 +146,3 @@ function grade_report_singleview_profilereport($course, $user) { echo $report->output(); } } - -/** - * qe_events_trigger hack for using legacy events without debug screaming at us - */ -function qe_events_trigger($eventname, $eventdata) { - if (function_exists('events_trigger_legacy')) { - events_trigger_legacy($eventname, $eventdata); - } else { - events_trigger($eventname, $eventdata); - } -} diff --git a/grade/report/singleview/screens/grade/lib.php b/grade/report/singleview/screens/grade/lib.php index 3a894d9db43..331944f2359 100644 --- a/grade/report/singleview/screens/grade/lib.php +++ b/grade/report/singleview/screens/grade/lib.php @@ -18,7 +18,7 @@ /** * The gradebook simple view - grades view (for an activity) * - * @package singleview + * @package gradereport_singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -26,25 +26,25 @@ class singleview_grade extends singleview_tablelike implements selectable_items, item_filtering { - private $requires_extra = false; + private $requiresextra = false; - private $requires_paging = false; + private $requirespaging = false; - var $structure; + public $structure; - private static $allow_categories; + private static $allowcategories; - public static function allow_categories() { - if (is_null(self::$allow_categories)) { - self::$allow_categories = get_config('moodle', 'grade_overridecat'); + public static function allowcategories() { + if (is_null(self::$allowcategories)) { + self::$allowcategories = get_config('moodle', 'grade_overridecat'); } - return self::$allow_categories; + return self::$allowcategories; } public static function filter($item) { return ( - self::allow_categories() or !( + self::allowcategories() or !( $item->is_course_item() or $item->is_category_item() ) ); @@ -55,13 +55,13 @@ class singleview_grade extends singleview_tablelike } public function options() { - return array_map(function($user) { + return array_map(function($user) { if (!empty($user->alternatename)) { return $user->alternatename . ' (' . $user->firstname . ') ' . $user->lastname; } else { return fullname($user); - } - }, $this->items); + } + }, $this->items); } public function item_type() { @@ -71,7 +71,7 @@ class singleview_grade extends singleview_tablelike public function original_definition() { $def = array('finalgrade', 'feedback'); - if ($this->requires_extra) { + if ($this->requiresextra) { $def[] = 'override'; } @@ -80,21 +80,22 @@ class singleview_grade extends singleview_tablelike return $def; } - public function init($self_item_is_empty = false) { + public function init($selfitemisempty = false) { $roleids = explode(',', get_config('moodle', 'gradebookroles')); $this->items = get_role_users( - $roleids, $this->context, false, '', - 'u.lastname, u.firstname', null, $this->groupid - ); + $roleids, $this->context, false, '', + 'u.lastname, u.firstname', null, $this->groupid, + $this->perpage * $this->page, $this->perpage + ); - if ($self_item_is_empty) { + if ($selfitemisempty) { return; } // Only page when necessary. if (count($this->items) > $this->perpage) { - $this->requires_paging = true; + $this->requirespaging = true; $this->all_items = $this->items; @@ -114,15 +115,15 @@ class singleview_grade extends singleview_tablelike $this->item = grade_item::fetch($params); - $filter_fun = grade_report_singleview::filters(); + $filterfun = grade_report_singleview::filters(); - $allowed = $filter_fun($this->item); + $allowed = $filterfun($this->item); if (empty($allowed)) { print_error('not_allowed', 'gradereport_singleview'); } - $this->requires_extra = !$this->item->is_manual_item(); + $this->requiresextra = !$this->item->is_manual_item(); $this->setup_structure(); @@ -132,8 +133,8 @@ class singleview_grade extends singleview_tablelike public function original_headers() { $headers = array( - '', // for filter icon. - '', // for user picture. + '', // For filter icon. + '', // For user picture. get_string('firstname') . ' (' . get_string('alternatename') . ') ' . get_string('lastname'), get_string('range', 'grades'), get_string('grade', 'grades'), @@ -148,15 +149,17 @@ class singleview_grade extends singleview_tablelike $grade = $this->fetch_grade_or_default($this->item, $item->id); - // UCSB add lock icon indicator. $lockicon = ''; - // CODE to make steve happy for his simple mind. - $locked_grade = $locked_grade_item = 0; - if ( ! empty($grade->locked) ) $locked_grade = 1; - if ( ! empty($grade->grade_item->locked) ) $locked_grade_item = 1; - // check both grade and grade item. - if ( $locked_grade || $locked_grade_item ) + $lockedgrade = $lockedgradeitem = 0; + if (!empty($grade->locked)) { + $lockedgrade = 1; + } + if (!empty($grade->grade_item->locked)) { + $lockedgradeitem = 1; + } + // Check both grade and grade item. + if ( $lockedgrade || $lockedgradeitem ) $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked') . ' '; if (!empty($item->alternatename)) { @@ -167,9 +170,10 @@ class singleview_grade extends singleview_tablelike $item->imagealt = $fullname; $url = new moodle_url("/user/view.php", array('id' => $item->id, 'course' => $this->courseid)); + $iconstring = get_string('filtergrades', 'gradereport_singleview', $fullname); - $line = array( - $OUTPUT->action_icon($this->format_link('user', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_singleview', $fullname))), + $line = array( + $OUTPUT->action_icon($this->format_link('user', $item->id), new pix_icon('t/editstring', $iconstring)), $OUTPUT->user_picture($item), html_writer::link($url, $fullname), $this->item_range() @@ -178,7 +182,7 @@ class singleview_grade extends singleview_tablelike } public function additional_headers($headers) { - if ($this->requires_extra) { + if ($this->requiresextra) { $headers[] = $this->make_toggle_links('override'); } @@ -196,7 +200,7 @@ class singleview_grade extends singleview_tablelike } public function supports_paging() { - return $this->requires_paging; + return $this->requirespaging; } public function pager() { diff --git a/grade/report/singleview/screens/select/lib.php b/grade/report/singleview/screens/select/lib.php index e58a5d5b9b4..2ce62f822b8 100644 --- a/grade/report/singleview/screens/select/lib.php +++ b/grade/report/singleview/screens/select/lib.php @@ -18,13 +18,13 @@ /** * The gradebook simple view - initial view to select your search options * - * @package singleview + * @package gradereport_singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class singleview_select extends singleview_screen { - public function init($self_item_is_empty = false) { + public function init($selfitemisempty = false) { global $DB; $this->item = $DB->get_record('course', array('id' => $this->courseid)); diff --git a/grade/report/singleview/screens/user/lib.php b/grade/report/singleview/screens/user/lib.php index 05cae08683f..2129a21c0ed 100644 --- a/grade/report/singleview/screens/user/lib.php +++ b/grade/report/singleview/screens/user/lib.php @@ -18,7 +18,7 @@ /** * The gradebook simple view - grades view (for a user) * - * @package singleview + * @package gradereport_singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -27,14 +27,16 @@ class singleview_user extends singleview_tablelike implements selectable_items { private $categories = array(); - var $structure; + public $structure; public function description() { return get_string('gradeitems', 'grades');; } public function options() { - return array_map(function($item) { return $item->get_name(); }, $this->items); + return array_map(function($item) { + return $item->get_name(); + }, $this->items); } public function item_type() { @@ -45,10 +47,10 @@ class singleview_user extends singleview_tablelike implements selectable_items { return false; } - public function init($self_item_is_empty = false) { + public function init($selfitemisempty = false) { global $DB; - if (!$self_item_is_empty) { + if (!$selfitemisempty) { $this->item = $DB->get_record('user', array('id' => $this->itemid)); } @@ -76,8 +78,8 @@ class singleview_user extends singleview_tablelike implements selectable_items { public function original_headers() { return array( - '', // for filter icon. - '', // for activity icon. + '', // For filter icon. + '', // For activity icon. get_string('assessmentname', 'gradereport_singleview'), get_string('gradecategory', 'grades'), get_string('range', 'grades'), @@ -95,16 +97,22 @@ class singleview_user extends singleview_tablelike implements selectable_items { $lockicon = ''; // UCSB add lock icon indicator. - $locked_grade = $locked_grade_item = 0; - if ( ! empty($grade->locked) ) $locked_grade = 1; - if ( ! empty($grade->grade_item->locked) ) $locked_grade_item = 1; - if ( $locked_grade || $locked_grade_item ) // check both grade and grade item. - $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); + $lockeditem = $lockeditemgrade = 0; + if (!empty($grade->locked)) { + $lockeditem = 1; + } + if (!empty($grade->grade_item->locked)) { + $lockeditemgrade = 1; + } + // Check both grade and grade item. + if ( $lockeditem || $lockeditemgrade ) + $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $item->cmid)); + $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name()); $line = array( - $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', get_string('filtergrades', 'gradereport_singleview', $item->get_name()))), + $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', $iconstring)), $this->format_icon($item) . $lockicon, html_writer::link($url, $item->get_name()), $this->category($item), @@ -143,10 +151,10 @@ class singleview_user extends singleview_tablelike implements selectable_items { } public function heading() { - if (!empty($this->item->alternatename)) { - return $this->item->alternatename . ' (' . $this->item->firstname . ') ' . $this->item->lastname; - } else { - return fullname($this->item); - } + if (!empty($this->item->alternatename)) { + return $this->item->alternatename . ' (' . $this->item->firstname . ') ' . $this->item->lastname; + } else { + return fullname($this->item); + } } } diff --git a/grade/report/singleview/version.php b/grade/report/singleview/version.php index 3f6e7768306..9e835d9b105 100755 --- a/grade/report/singleview/version.php +++ b/grade/report/singleview/version.php @@ -1,27 +1,27 @@ . + +/** + * Standard version file + * + * @package gradereport_singleview + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ $plugin->version = 2013081002; $plugin->requires = 2010090501; - From 7bd3932e76f4c696c0154d1cc78f0cdd3dffd408 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Thu, 2 Oct 2014 16:12:33 +0800 Subject: [PATCH 10/16] MDL-18229 gradereport: Labels for table items added. --- grade/report/singleview/classes/lib.php | 5 +- grade/report/singleview/classes/uilib.php | 81 +++++++++++++++---- .../lang/en/gradereport_singleview.php | 9 +++ grade/report/singleview/screens/grade/lib.php | 2 + grade/report/singleview/screens/user/lib.php | 1 + 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/grade/report/singleview/classes/lib.php b/grade/report/singleview/classes/lib.php index 091a2a68a59..76bab76cd53 100644 --- a/grade/report/singleview/classes/lib.php +++ b/grade/report/singleview/classes/lib.php @@ -345,7 +345,6 @@ abstract class singleview_tablelike extends singleview_screen implements tabbabl foreach ($this->definition() as $i => $field) { // Table tab index. $tab = ($i * $this->total) + $this->index; - $html = $this->factory()->create($field)->format($grade, $tab); if ($field == 'finalgrade' and !empty($this->structure)) { @@ -354,7 +353,7 @@ abstract class singleview_tablelike extends singleview_screen implements tabbabl $line[] = $html; } - + return $line; } @@ -401,7 +400,7 @@ abstract class singleview_tablelike extends singleview_screen implements tabbabl $save = html_writer::empty_tag('input', array( 'type' => 'submit', 'value' => get_string('update'), - 'tabindex' => $this->get_tabindex() + 'tabindex' => $this->get_tabindex(), )); return array($save); diff --git a/grade/report/singleview/classes/uilib.php b/grade/report/singleview/classes/uilib.php index 9112a913204..4c51a477756 100644 --- a/grade/report/singleview/classes/uilib.php +++ b/grade/report/singleview/classes/uilib.php @@ -51,12 +51,13 @@ class singleview_factory_class_wrap { } abstract class singleview_ui_element { - var $name; - var $value; + public $name; + public $value; - public function __construct($name, $value) { + public function __construct($name, $value, $label) { $this->name = $name; $this->value = $value; + $this->label = $label; } public function is_checkbox() { @@ -92,10 +93,10 @@ class singleview_text_attribute extends singleview_ui_element { private $isdisabled; private $tabindex; - public function __construct($name, $value, $isdisabled = false, $tabindex = null) { + public function __construct($name, $value, $label, $isdisabled = false, $tabindex = null) { $this->isdisabled = $isdisabled; $this->tabindex = $tabindex; - parent::__construct($name, $value); + parent::__construct($name, $value, $label); } public function is_textbox() { @@ -106,7 +107,8 @@ class singleview_text_attribute extends singleview_ui_element { $attributes = array( 'type' => 'text', 'name' => $this->name, - 'value' => $this->value + 'value' => $this->value, + 'id' => $this->name ); if (!empty($this->tabindex)) { @@ -122,7 +124,17 @@ class singleview_text_attribute extends singleview_ui_element { 'value' => $this->value ); + $label = ''; + if (preg_match("/^feedback/", $this->name)) { + $labeltitle = get_string('feedbackfor', 'gradereport_singleview', $this->label); + $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); + } else if (preg_match("/^finalgrade/", $this->name)) { + $labeltitle = get_string('gradefor', 'gradereport_singleview', $this->label); + $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); + } + return ( + $label . html_writer::empty_tag('input', $attributes) . html_writer::empty_tag('input', $hidden) ); @@ -133,11 +145,11 @@ class singleview_checkbox_attribute extends singleview_ui_element { private $ischecked; private $tabindex; - public function __construct($name, $ischecked = false, $tabindex = null, $locked=0) { + public function __construct($name, $label, $ischecked = false, $tabindex = null, $locked=0) { $this->ischecked = $ischecked; $this->tabindex = $tabindex; $this->locked = $locked; - parent::__construct($name, 1); + parent::__construct($name, 1, $label); } public function is_checkbox() { @@ -149,7 +161,8 @@ class singleview_checkbox_attribute extends singleview_ui_element { $attributes = array( 'type' => 'checkbox', 'name' => $this->name, - 'value' => 1 + 'value' => 1, + 'id' => $this->name ); // UCSB fixed user should not be able to override locked grade. @@ -177,8 +190,14 @@ class singleview_checkbox_attribute extends singleview_ui_element { $hidden['value'] = 1; } + $type = "override"; + if (preg_match("/^exclude/", $this->name)) { + $type = "exclude"; + } + return ( html_writer::empty_tag('input', $alt) . + html_writer::tag('label', get_string($type . 'for', 'gradereport_singleview', $this->label), array('for' => $this->name, 'class' => 'accesshide')) . html_writer::empty_tag('input', $attributes) . html_writer::empty_tag('input', $hidden) ); @@ -190,12 +209,12 @@ class singleview_dropdown_attribute extends singleview_ui_element { private $options; private $isdisabled; - public function __construct($name, $options, $selected = '', $isdisabled = false, $tabindex = null) { + public function __construct($name, $options, $label, $selected = '', $isdisabled = false, $tabindex = null) { $this->selected = $selected; $this->options = $options; $this->tabindex = $tabindex; $this->isdisabled = $isdisabled; - parent::__construct($name, $selected); + parent::__construct($name, $selected, $label); } public function is_dropdown() { @@ -228,6 +247,7 @@ class singleview_dropdown_attribute extends singleview_ui_element { abstract class singleview_grade_attribute_format extends singleview_attribute_format implements unique_name, tabbable { public $name; + public $label; public function __construct() { $args = func_get_args(); @@ -308,9 +328,9 @@ class singleview_bulk_insert_ui extends singleview_ui_element { $select = html_writer::select( $insertoptions, $this->selectname, 'blanks', false ); - + $label = html_writer::tag('label', $s('for')); - $text = new singleview_text_attribute($this->insertname, "0"); + $text = new singleview_text_attribute($this->insertname, "0", 'bulk'); return implode(' ', array($apply, $text->html(), $label, $select)); } @@ -332,6 +352,7 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme public $name = 'finalgrade'; public function get_value() { + $this->label = $this->grade->grade_item->itemname; // Manual item raw grade support. $val = $this->grade->grade_item->is_manual_item() && (!is_null($this->grade->rawgrade)) ? $this->grade->rawgrade : $this->grade->finalgrade; @@ -343,6 +364,13 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme } } + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + public function is_disabled() { $locked = 0; $gradeitemlocked = 0; @@ -378,6 +406,7 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme $this->get_name(), $options, $this->get_value(), + $this->get_label(), $this->is_disabled(), $this->get_tabindex() ); @@ -385,6 +414,7 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme return new singleview_text_attribute( $this->get_name(), $this->get_value(), + $this->get_label(), $this->is_disabled(), $this->get_tabindex() ); @@ -428,7 +458,6 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme $gradestr->username = $user->firstname . ' ' . $user->lastname; } $gradestr->itemname = $this->grade->grade_item->get_name(); - $errorstr = get_string($errorstr, 'grades', $gradestr); } @@ -445,6 +474,13 @@ class singleview_feedback_ui extends singleview_grade_attribute_format implement return $this->grade->feedback ? $this->grade->feedback : ''; } + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + public function is_disabled() { $locked = 0; $gradeitemlocked = 0; @@ -470,6 +506,7 @@ class singleview_feedback_ui extends singleview_grade_attribute_format implement return new singleview_text_attribute( $this->get_name(), $this->get_value(), + $this->get_label(), $this->is_disabled(), $this->get_tabindex() ); @@ -510,12 +547,20 @@ class singleview_override_ui extends singleview_grade_attribute_format implement return ($lockedgrade || $lockedgradeitem); } + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + function determine_format() { if (!$this->grade->grade_item->is_overridable_item()) { return new singleview_empty_element(); } return new singleview_checkbox_attribute( $this->get_name(), + $this->get_label(), $this->ischecked(), null, $this->is_disabled() @@ -545,10 +590,18 @@ class singleview_exclude_ui extends singleview_grade_attribute_format implements function determine_format() { return new singleview_checkbox_attribute( $this->get_name(), + $this->get_label(), $this->ischecked() ); } + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + function set($value) { if (empty($this->grade->id)) { if (empty($value)) { diff --git a/grade/report/singleview/lang/en/gradereport_singleview.php b/grade/report/singleview/lang/en/gradereport_singleview.php index 8628de4ea24..019688c1257 100755 --- a/grade/report/singleview/lang/en/gradereport_singleview.php +++ b/grade/report/singleview/lang/en/gradereport_singleview.php @@ -28,10 +28,19 @@ $string['all_grades'] = 'All grades'; $string['assessmentname'] = 'Assessment Name'; $string['blanks'] = 'Empty grades'; $string['bulk'] = 'Insert'; +$string['bulkfor'] = 'Grades for {$a}'; $string['exclude'] = 'Exclude'; +$string['excludeall'] = 'Exclude all grades'; +$string['excludefor'] = 'Exclude for {$a}'; +$string['excludenone'] = 'Exclude no grades'; +$string['feedbackfor'] = 'Feedback for {$a}'; $string['filtergrades'] = 'Show grades for {$a}.'; $string['for'] = 'for'; +$string['gradefor'] = 'Grade for {$a}'; $string['override'] = 'Override'; +$string['overrideall'] = 'Override all grades'; +$string['overridefor'] = 'Override for {$a}'; +$string['overridenone'] = 'Override no grades'; $string['pluginname'] = 'Single view'; $string['singleview:view'] = 'View the '.$string['pluginname'].' report'; $string['noscreens'] = 'Could not find a suitable Single view screen.'; diff --git a/grade/report/singleview/screens/grade/lib.php b/grade/report/singleview/screens/grade/lib.php index 331944f2359..7dfe9d0e27c 100644 --- a/grade/report/singleview/screens/grade/lib.php +++ b/grade/report/singleview/screens/grade/lib.php @@ -171,6 +171,7 @@ class singleview_grade extends singleview_tablelike $item->imagealt = $fullname; $url = new moodle_url("/user/view.php", array('id' => $item->id, 'course' => $this->courseid)); $iconstring = get_string('filtergrades', 'gradereport_singleview', $fullname); + $grade->label = $fullname; $line = array( $OUTPUT->action_icon($this->format_link('user', $item->id), new pix_icon('t/editstring', $iconstring)), @@ -178,6 +179,7 @@ class singleview_grade extends singleview_tablelike html_writer::link($url, $fullname), $this->item_range() ); + return $this->format_definition($line, $grade); } diff --git a/grade/report/singleview/screens/user/lib.php b/grade/report/singleview/screens/user/lib.php index 2129a21c0ed..1506852decd 100644 --- a/grade/report/singleview/screens/user/lib.php +++ b/grade/report/singleview/screens/user/lib.php @@ -110,6 +110,7 @@ class singleview_user extends singleview_tablelike implements selectable_items { $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $item->cmid)); $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name()); + $grade->label = $item->get_name(); $line = array( $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', $iconstring)), From 2fd9718d8b622ecdc1914650ff3caf56ee07f341 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Thu, 2 Oct 2014 16:13:19 +0800 Subject: [PATCH 11/16] MDL-18229 gradereport: Behat tests added. --- .../singleview/tests/behat/singleview.feature | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 grade/report/singleview/tests/behat/singleview.feature diff --git a/grade/report/singleview/tests/behat/singleview.feature b/grade/report/singleview/tests/behat/singleview.feature new file mode 100644 index 00000000000..4ede6f2ba73 --- /dev/null +++ b/grade/report/singleview/tests/behat/singleview.feature @@ -0,0 +1,90 @@ +@core @core_grades @singleview +Feature: We can use Single view + As a teacher + In order to view a user or an activities grades + +Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | idnumber | alternatename | + | teacher1 | Teacher | 1 | teacher1@asd.com | t1 | teacherbro | + | student1 | Student | 1 | student1@asd.com | s1 | studentbro | + | student2 | Student | 2 | student1@asd.com | s2 | studentjo | + | student3 | Student | 3 | student1@asd.com | s3 | studentlo | + | student4 | Student | 4 | student1@asd.com | s4 | studentawesemo | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | student3 | C1 | student | + | student4 | C1 | student | + And the following "grade categories" exist: + | fullname | course | + | Sub category 1 | C1| + | Sub category 2 | C1| + And the following "activities" exist: + | activity | course | idnumber | name | intro | grade | + | assign | C1 | a1 | Test assignment one | Submit something! | 300 | + | assign | C1 | a2 | Test assignment two | Submit something! | 100 | + | assign | C1 | a3 | Test assignment three | Submit something! | 150 | + | assign | C1 | a4 | Test assignment four | Submit nothing! | 150 | + And the following "activities" exist: + | activity | course | idnumber | name | intro | gradecategory | grade | + | assign | C1 | a5 | Test assignment five | Submit something! | Sub category 1 | 200 + | assign | C1 | a6 | Test assignment six | Submit something! | Sub category 1 | 100 + | assign | C1 | a7 | Test assignment seven | Submit nothing! | Sub category 1 | 150 + And the following "activities" exist: + | activity | course | idnumber | name | intro | gradecategory | grade | + | assign | C1 | a8 | Test assignment eight | Submit something! | Sub category 2 | 200 + | assign | C1 | a9 | Test assignment nine | Submit something! | Sub category 2 | 100 + | assign | C1 | 10 | Test assignment ten | Submit nothing! | Sub category 2 | 150 + And I log in as "teacher1" + And I follow "Course 1" + And I follow "Grades" + +@javascript +Scenario: I can update grades, add feedback and exclude grades. + And I click on "Single view" "option" + And I click on "studentawesemo (Student) 4" "option" + And I click on "Override for Test assignment eight" "checkbox" + And I set the following fields to these values: + | Grade for Test assignment eight | 10.00 | + | Feedback for Test assignment eight | test data | + And I click on "Exclude for Test assignment four" "checkbox" + And I press "Update" + Then the following should exist in the "user-grades" table: + | Test assignment four | + | excluded | + Then the following should exist in the "user-grades" table: + | Test assignment eight | + | 10.00 | + And I click on "Single view for Test assignment five" "link" + And I click on "Override for studentbro (Student) 1" "checkbox" + And I set the following fields to these values: + | Grade for studentbro (Student) 1 | 12.05 | + | Feedback for studentbro (Student) 1 | test data2 | + And I click on "Exclude for studentjo (Student) 2" "checkbox" + And I press "Update" + Then the following should exist in the "user-grades" table: + | Test assignment five | + | 12.05 | + | Excluded | + +@javascript +Scenario: Single view quick links work on grade report. + And I follow "Single view for Test assignment one" + And I follow "Grader report" + And I follow "Single view for Student 1" + +@javascript +Scenario: Navigation works in the Single view. + And I click on "Single view" "option" + And I click on "studentbro (Student) 1" "option" + And I follow "studentjo (Student) 2" + And I follow "studentbro (Student) 1" + And I click on "Show grades for Test assignment five" "link" + And I follow "Test assignment six" + And I follow "Test assignment five" From 8ec7b088ef105f171a5df29c9d192d95d9538afa Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Fri, 3 Oct 2014 09:57:55 +0800 Subject: [PATCH 12/16] MDL-18229 gradereport: Fixes and improvements from review. Added pagination back in with some general fixes. AMOS BEGIN CPY [override,mod_quiz],[override,gradereport_singleview] AMOS END --- grade/report/singleview/README.md | 21 ----- grade/report/singleview/classes/lib.php | 27 +++---- grade/report/singleview/classes/uilib.php | 81 +++++++++---------- grade/report/singleview/db/access.php | 2 +- grade/report/singleview/index.php | 12 +-- .../lang/en/gradereport_singleview.php | 10 +-- grade/report/singleview/lib.php | 16 ++-- grade/report/singleview/screens/grade/lib.php | 57 +++++-------- .../report/singleview/screens/select/lib.php | 15 ++-- grade/report/singleview/screens/user/lib.php | 19 ++--- grade/report/singleview/styles.css | 2 +- .../singleview/tests/behat/singleview.feature | 73 +++++++++-------- grade/report/singleview/version.php | 2 +- lib/classes/plugin_manager.php | 2 +- 14 files changed, 151 insertions(+), 188 deletions(-) delete mode 100644 grade/report/singleview/README.md diff --git a/grade/report/singleview/README.md b/grade/report/singleview/README.md deleted file mode 100644 index 036ab6e05bb..00000000000 --- a/grade/report/singleview/README.md +++ /dev/null @@ -1,21 +0,0 @@ -LSU Single view -============== - -Single view is a simple Moodle Gradebook plugin which allows teahers to do some awesome things. - -Single view allows for editing of multiple grades for a single grade item and all grade items for a single user. - -It allows the instructor to insert an arbitrary value ofr all students for a single item (incredibly useful) or all items for a single student (less useful). - -Single view also allows for inserting an arbitrary value for all empty items, allowing you to add zero grades for empties in one step. - -It also allows for bulk overrides. - -Single view works best with the LSU Gradebook. - -Installation Instructions -============== - -1. Drop into your grade/reports folder. -2. Click Notifications. - diff --git a/grade/report/singleview/classes/lib.php b/grade/report/singleview/classes/lib.php index 76bab76cd53..1753cc8b56d 100644 --- a/grade/report/singleview/classes/lib.php +++ b/grade/report/singleview/classes/lib.php @@ -25,7 +25,7 @@ require_once $CFG->dirroot . '/grade/report/singleview/classes/uilib.php'; -interface selectable_items { +interface gradereport_selectable_items { public function description(); public function options(); @@ -33,11 +33,11 @@ interface selectable_items { public function item_type(); } -interface item_filtering { +interface gradereport_item_filtering { public static function filter($item); } -abstract class singleview_screen { +abstract class gradereport_singleview_screen { var $courseid; var $itemid; @@ -61,7 +61,10 @@ abstract class singleview_screen { $this->course = $DB->get_record('course', array('id' => $courseid)); $this->page = optional_param('page', 0, PARAM_INT); - $this->perpage = optional_param('perpage', 300, PARAM_INT); + $this->perpage = optional_param('perpage', 100, PARAM_INT); + if ($this->perpage > 100) { + $this->perpage = 100; + } $this->init(empty($itemid)); } @@ -136,7 +139,7 @@ abstract class singleview_screen { public abstract function html(); public function supports_paging() { - return false; + return true; } public function pager() { @@ -147,7 +150,6 @@ abstract class singleview_screen { global $OUTPUT; list($___, $item) = explode('singleview_', get_class($this)); - return $OUTPUT->paging_bar( count($this->items), $this->page, $this->perpage, new moodle_url('/grade/report/singleview/index.php', array( @@ -174,7 +176,7 @@ abstract class singleview_screen { public function factory() { if (empty($this->__factory)) { - $this->__factory = new singleview_grade_ui_factory(); + $this->__factory = new gradereport_singleview_grade_ui_factory(); } return $this->__factory; @@ -250,8 +252,8 @@ abstract class singleview_screen { } } -abstract class singleview_tablelike extends singleview_screen implements tabbable { - var $items; +abstract class gradereport_singleview_tablelike extends gradereport_singleview_screen implements tabbable { + public $items; protected $headers = array(); @@ -284,13 +286,11 @@ abstract class singleview_tablelike extends singleview_screen implements tabbabl // Special injection for bulk operations. public function process($data) { $bulk = $this->factory()->create('bulk_insert')->format($this->item); - // Bulk insert messages the data to be passed in // ie: for all grades of empty grades apply the specified value. if ($bulk->is_applied($data)) { $filter = $bulk->get_type($data); $insert_value = $bulk->get_insert_value($data); - // Appropriately massage data that may not exist. if ($this->supports_paging()) { // TODO: this only works with the grade screen... @@ -301,7 +301,7 @@ abstract class singleview_tablelike extends singleview_screen implements tabbabl $null = $grade_item->gradetype == GRADE_TYPE_SCALE ? -1 : ''; - foreach ($this->all_items as $itemid => $item) { + foreach ($this->items as $itemid => $item) { $field = "finalgrade_{$grade_item->id}_{$itemid}"; if (isset($data->$field)) { continue; @@ -346,14 +346,13 @@ abstract class singleview_tablelike extends singleview_screen implements tabbabl // Table tab index. $tab = ($i * $this->total) + $this->index; $html = $this->factory()->create($field)->format($grade, $tab); - + if ($field == 'finalgrade' and !empty($this->structure)) { $html .= $this->structure->get_grade_analysis_icon($grade); } $line[] = $html; } - return $line; } diff --git a/grade/report/singleview/classes/uilib.php b/grade/report/singleview/classes/uilib.php index 4c51a477756..e5ed217b4f0 100644 --- a/grade/report/singleview/classes/uilib.php +++ b/grade/report/singleview/classes/uilib.php @@ -23,21 +23,21 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -abstract class singleview_ui_factory { +abstract class gradereport_singleview_ui_factory { public abstract function create($type); protected function wrap($class) { - return new singleview_factory_class_wrap($class); + return new gradereport_singleview_factory_class_wrap($class); } } -class singleview_grade_ui_factory extends singleview_ui_factory { +class gradereport_singleview_grade_ui_factory extends gradereport_singleview_ui_factory { public function create($type) { - return $this->wrap("singleview_{$type}_ui"); + return $this->wrap("gradereport_singleview_{$type}_ui"); } } -class singleview_factory_class_wrap { +class gradereport_singleview_factory_class_wrap { public function __construct($class) { $this->class = $class; } @@ -50,9 +50,10 @@ class singleview_factory_class_wrap { } } -abstract class singleview_ui_element { +abstract class gradereport_singleview_ui_element { public $name; public $value; + public $label; public function __construct($name, $value, $label) { $this->name = $name; @@ -75,7 +76,7 @@ abstract class singleview_ui_element { abstract public function html(); } -class singleview_empty_element extends singleview_ui_element { +class gradereport_singleview_empty_element extends gradereport_singleview_ui_element { public function __construct($msg = null) { if (is_null($msg)) { $this->text = get_string('notavailable', 'gradereport_singleview'); @@ -89,7 +90,7 @@ class singleview_empty_element extends singleview_ui_element { } } -class singleview_text_attribute extends singleview_ui_element { +class gradereport_singleview_text_attribute extends gradereport_singleview_ui_element { private $isdisabled; private $tabindex; @@ -141,7 +142,7 @@ class singleview_text_attribute extends singleview_ui_element { } } -class singleview_checkbox_attribute extends singleview_ui_element { +class gradereport_singleview_checkbox_attribute extends gradereport_singleview_ui_element { private $ischecked; private $tabindex; @@ -204,7 +205,7 @@ class singleview_checkbox_attribute extends singleview_ui_element { } } -class singleview_dropdown_attribute extends singleview_ui_element { +class gradereport_singleview_dropdown_attribute extends gradereport_singleview_ui_element { private $selected; private $options; private $isdisabled; @@ -245,7 +246,7 @@ class singleview_dropdown_attribute extends singleview_ui_element { } } -abstract class singleview_grade_attribute_format extends singleview_attribute_format implements unique_name, tabbable { +abstract class gradereport_singleview_grade_attribute_format extends gradereport_singleview_attribute_format implements unique_name, tabbable { public $name; public $label; @@ -286,14 +287,14 @@ interface be_disabled { } interface be_checked { - public function ischecked(); + public function is_checked(); } interface tabbable { public function get_tabindex(); } -class singleview_bulk_insert_ui extends singleview_ui_element { +class gradereport_singleview_bulk_insert_ui extends gradereport_singleview_ui_element { public function __construct($item) { $this->name = 'bulk_' . $item->id; $this->applyname = $this->name_for('apply'); @@ -314,23 +315,21 @@ class singleview_bulk_insert_ui extends singleview_ui_element { } public function html() { - $s = function($key) { - return get_string($key, 'gradereport_singleview'); - }; - - $apply = html_writer::checkbox($this->applyname, 1, false, ' ' . $s('bulk')); + $insertgrade = get_string('bulkinsertgrade', 'gradereport_singleview'); + $insertappliesto = get_string('bulkappliesto', 'gradereport_singleview'); + $apply = html_writer::checkbox($this->applyname, 1, false, $insertgrade); $insertoptions = array( - 'all' => $s('all_grades'), - 'blanks' => $s('blanks') + 'all' => get_string('all_grades', 'gradereport_singleview'), + 'blanks' => get_string('blanks', 'gradereport_singleview') ); $select = html_writer::select( $insertoptions, $this->selectname, 'blanks', false ); - $label = html_writer::tag('label', $s('for')); - $text = new singleview_text_attribute($this->insertname, "0", 'bulk'); + $label = html_writer::tag('label', $insertappliesto); + $text = new gradereport_singleview_text_attribute($this->insertname, "0", 'bulk'); return implode(' ', array($apply, $text->html(), $label, $select)); } @@ -339,7 +338,7 @@ class singleview_bulk_insert_ui extends singleview_ui_element { } } -abstract class singleview_attribute_format { +abstract class gradereport_singleview_attribute_format { abstract public function determine_format(); public function __toString() { @@ -347,7 +346,7 @@ abstract class singleview_attribute_format { } } -class singleview_finalgrade_ui extends singleview_grade_attribute_format implements unique_value, be_disabled { +class gradereport_singleview_finalgrade_ui extends gradereport_singleview_grade_attribute_format implements unique_value, be_disabled { public $name = 'finalgrade'; @@ -402,7 +401,7 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme $options[$i + 1] = $name; } - return new singleview_dropdown_attribute( + return new gradereport_singleview_dropdown_attribute( $this->get_name(), $options, $this->get_value(), @@ -411,7 +410,7 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme $this->get_tabindex() ); } else { - return new singleview_text_attribute( + return new gradereport_singleview_text_attribute( $this->get_name(), $this->get_value(), $this->get_label(), @@ -466,7 +465,7 @@ class singleview_finalgrade_ui extends singleview_grade_attribute_format impleme } } -class singleview_feedback_ui extends singleview_grade_attribute_format implements unique_value, be_disabled { +class gradereport_singleview_feedback_ui extends gradereport_singleview_grade_attribute_format implements unique_value, be_disabled { public $name = 'feedback'; @@ -503,7 +502,7 @@ class singleview_feedback_ui extends singleview_grade_attribute_format implement } public function determine_format() { - return new singleview_text_attribute( + return new gradereport_singleview_text_attribute( $this->get_name(), $this->get_value(), $this->get_label(), @@ -529,19 +528,19 @@ class singleview_feedback_ui extends singleview_grade_attribute_format implement } } -class singleview_override_ui extends singleview_grade_attribute_format implements be_checked, be_disabled { +class gradereport_singleview_override_ui extends gradereport_singleview_grade_attribute_format implements be_checked, be_disabled { public $name = 'override'; - public function ischecked() { + public function is_checked() { return $this->grade->is_overridden(); } public function is_disabled() { $lockedgrade = $lockedgradeitem = 0; - if ( ! empty($this->grade->locked) ) { + if (!empty($this->grade->locked)) { $lockedgrade = 1; } - if ( ! empty($this->grade->grade_item->locked) ) { + if (!empty($this->grade->grade_item->locked)) { $lockedgradeitem = 1; } return ($lockedgrade || $lockedgradeitem); @@ -556,12 +555,12 @@ class singleview_override_ui extends singleview_grade_attribute_format implement function determine_format() { if (!$this->grade->grade_item->is_overridable_item()) { - return new singleview_empty_element(); + return new gradereport_singleview_empty_element(); } - return new singleview_checkbox_attribute( + return new gradereport_singleview_checkbox_attribute( $this->get_name(), $this->get_label(), - $this->ischecked(), + $this->is_checked(), null, $this->is_disabled() ); @@ -580,18 +579,18 @@ class singleview_override_ui extends singleview_grade_attribute_format implement } } -class singleview_exclude_ui extends singleview_grade_attribute_format implements be_checked { +class gradereport_singleview_exclude_ui extends gradereport_singleview_grade_attribute_format implements be_checked { var $name = 'exclude'; - function ischecked() { + function is_checked() { return $this->grade->is_excluded(); } function determine_format() { - return new singleview_checkbox_attribute( + return new gradereport_singleview_checkbox_attribute( $this->get_name(), $this->get_label(), - $this->ischecked() + $this->is_checked() ); } @@ -633,7 +632,7 @@ class singleview_exclude_ui extends singleview_grade_attribute_format implements } } -class singleview_range_ui extends singleview_attribute_format { +class gradereport_singleview_range_ui extends gradereport_singleview_attribute_format { function __construct($item) { $this->item = $item; } @@ -644,6 +643,6 @@ class singleview_range_ui extends singleview_attribute_format { $min = format_float($this->item->grademin, $decimals); $max = format_float($this->item->grademax, $decimals); - return new singleview_empty_element("$min - $max"); + return new gradereport_singleview_empty_element("$min - $max"); } } diff --git a/grade/report/singleview/db/access.php b/grade/report/singleview/db/access.php index c5bbe851ca7..f0cbe0f29f0 100755 --- a/grade/report/singleview/db/access.php +++ b/grade/report/singleview/db/access.php @@ -1,4 +1,4 @@ -. /** - * Displays the Single view + * Displays the Single view * * @package gradereport_singleview - * @copyright 2014 Moodle + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -46,7 +46,7 @@ if (!$course = $DB->get_record('course', $courseparams)) { print_error('nocourseid'); } -if (!in_array($itemtype, grade_report_singleview::valid_screens())) { +if (!in_array($itemtype, gradereport_singleview::valid_screens())) { print_error('notvalid', 'gradereport_singleview', '', $itemtype); } @@ -74,7 +74,7 @@ $USER->grade_last_report[$course->id] = 'singleview'; grade_regrade_final_grades($courseid); -$report = new grade_report_singleview( +$report = new gradereport_singleview( $courseid, $gpr, $context, $itemtype, $itemid, $groupid ); @@ -111,12 +111,12 @@ if ($data = data_submitted()) { $graderrightnav = $graderleftnav = null; if ($report->screen instanceof selectable_items - && class_exists($report::classname($report->screen->item_type()))) { + && class_exists(gradereport_singleview::classname($report->screen->item_type()))) { $optionkeys = array_keys($report->screen->options()); $optionitemid = array_shift($optionkeys); - $relreport = new grade_report_singleview( + $relreport = new gradereport_singleview( $courseid, $gpr, $context, $report->screen->item_type(), $optionitemid, $groupid ); diff --git a/grade/report/singleview/lang/en/gradereport_singleview.php b/grade/report/singleview/lang/en/gradereport_singleview.php index 019688c1257..b00f666f249 100755 --- a/grade/report/singleview/lang/en/gradereport_singleview.php +++ b/grade/report/singleview/lang/en/gradereport_singleview.php @@ -27,7 +27,8 @@ $string['all_grades'] = 'All grades'; $string['assessmentname'] = 'Assessment Name'; $string['blanks'] = 'Empty grades'; -$string['bulk'] = 'Insert'; +$string['bulkappliesto'] = 'for'; +$string['bulkinsertgrade'] = 'Bulk insert'; $string['bulkfor'] = 'Grades for {$a}'; $string['exclude'] = 'Exclude'; $string['excludeall'] = 'Exclude all grades'; @@ -35,14 +36,13 @@ $string['excludefor'] = 'Exclude for {$a}'; $string['excludenone'] = 'Exclude no grades'; $string['feedbackfor'] = 'Feedback for {$a}'; $string['filtergrades'] = 'Show grades for {$a}.'; -$string['for'] = 'for'; $string['gradefor'] = 'Grade for {$a}'; +$string['noscreens'] = 'Could not find a suitable Single view screen.'; +$string['notallowed'] = 'Not allowed to quick edit this item'; +$string['notvalid'] = 'Not a valid Single view screen: {$a}'; $string['override'] = 'Override'; $string['overrideall'] = 'Override all grades'; $string['overridefor'] = 'Override for {$a}'; $string['overridenone'] = 'Override no grades'; $string['pluginname'] = 'Single view'; $string['singleview:view'] = 'View the '.$string['pluginname'].' report'; -$string['noscreens'] = 'Could not find a suitable Single view screen.'; -$string['notallowed'] = 'Not allowed to quick edit this item'; -$string['notvalid'] = 'Not a valid Single view screen: {$a}'; diff --git a/grade/report/singleview/lib.php b/grade/report/singleview/lib.php index 3fa3dff2e4d..fac070d905f 100755 --- a/grade/report/singleview/lib.php +++ b/grade/report/singleview/lib.php @@ -19,14 +19,14 @@ * Base lib class for singleview functionality. * * @package gradereport_singleview - * @copyright 2014 Moodle + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once($CFG->dirroot . '/grade/report/lib.php'); require_once($CFG->dirroot . '/grade/report/singleview/classes/lib.php'); -class grade_report_singleview extends grade_report { +class gradereport_singleview extends grade_report { public static function valid_screens() { $screendir = dirname(__FILE__) . '/screens'; @@ -54,11 +54,11 @@ class grade_report_singleview extends grade_report { require_once $screendir . '/lib.php'; - return 'singleview_' . $screen; + return 'gradereport_singleview_' . $screen; } public static function filters() { - $classnames = array('grade_report_singleview', 'classname'); + $classnames = array('gradereport_singleview', 'classname'); $classes = array_map($classnames, self::valid_screens()); $screens = array_filter($classes, function($screen) { @@ -115,10 +115,10 @@ class grade_report_singleview extends grade_report { } } -function grade_report_singleview_profilereport($course, $user) { +function gradereport_singleview_profilereport($course, $user) { global $CFG, $OUTPUT; - if (!function_exists('grade_report_user_profilereport')) { + if (!function_exists('gradereport_user_profilereport')) { require_once $CFG->dirroot . '/grade/report/user/lib.php'; } @@ -131,7 +131,7 @@ function grade_report_singleview_profilereport($course, $user) { ); if (!$can_use) { - grade_report_user_profilereport($course, $user); + gradereport_user_profilereport($course, $user); } else { $gpr = new grade_plugin_return(array( 'type' => 'report', @@ -140,7 +140,7 @@ function grade_report_singleview_profilereport($course, $user) { 'userid' => $user->id )); - $report = new grade_report_singleview($course->id, $gpr, $context, 'user', $user->id); + $report = new gradereport_singleview($course->id, $gpr, $context, 'user', $user->id); echo $OUTPUT->heading($report->screen->heading()); echo $report->output(); diff --git a/grade/report/singleview/screens/grade/lib.php b/grade/report/singleview/screens/grade/lib.php index 7dfe9d0e27c..e694138a0f7 100644 --- a/grade/report/singleview/screens/grade/lib.php +++ b/grade/report/singleview/screens/grade/lib.php @@ -23,12 +23,14 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class singleview_grade extends singleview_tablelike - implements selectable_items, item_filtering { +class gradereport_singleview_grade extends gradereport_singleview_tablelike + implements gradereport_selectable_items, gradereport_item_filtering { + + private $totalitemcount = 0; private $requiresextra = false; - private $requirespaging = false; + private $requirespaging = true; public $structure; @@ -84,28 +86,17 @@ class singleview_grade extends singleview_tablelike $roleids = explode(',', get_config('moodle', 'gradebookroles')); $this->items = get_role_users( - $roleids, $this->context, false, '', - 'u.lastname, u.firstname', null, $this->groupid, - $this->perpage * $this->page, $this->perpage - ); + $roleids, $this->context, false, '', + 'u.lastname, u.firstname', null, $this->groupid, + $this->perpage * $this->page, $this->perpage + ); + + $this->totalitemcount = count_role_users($roleids, $this->context); if ($selfitemisempty) { return; } - // Only page when necessary. - if (count($this->items) > $this->perpage) { - $this->requirespaging = true; - - $this->all_items = $this->items; - - $this->items = get_role_users( - $roleids, $this->context, false, '', - 'u.lastname, u.firstname', null, $this->groupid, - $this->perpage * $this->page, $this->perpage - ); - } - global $DB; $params = array( @@ -115,12 +106,12 @@ class singleview_grade extends singleview_tablelike $this->item = grade_item::fetch($params); - $filterfun = grade_report_singleview::filters(); + $filterfun = gradereport_singleview::filters(); $allowed = $filterfun($this->item); if (empty($allowed)) { - print_error('not_allowed', 'gradereport_singleview'); + print_error('notallowed', 'gradereport_singleview'); } $this->requiresextra = !$this->item->is_manual_item(); @@ -132,16 +123,16 @@ class singleview_grade extends singleview_tablelike } public function original_headers() { - $headers = array( + return array( '', // For filter icon. '', // For user picture. get_string('firstname') . ' (' . get_string('alternatename') . ') ' . get_string('lastname'), get_string('range', 'grades'), get_string('grade', 'grades'), - get_string('feedback', 'grades') + get_string('feedback', 'grades'), + $this->make_toggle_links('override'), + $this->make_toggle_links('exclude') ); - - return $this->additional_headers($headers); } public function format_line($item) { @@ -179,20 +170,10 @@ class singleview_grade extends singleview_tablelike html_writer::link($url, $fullname), $this->item_range() ); - + return $this->format_definition($line, $grade); } - public function additional_headers($headers) { - if ($this->requiresextra) { - $headers[] = $this->make_toggle_links('override'); - } - - $headers[] = $this->make_toggle_links('exclude'); - - return $headers; - } - public function item_range() { if (empty($this->range)) { $this->range = $this->factory()->create('range')->format($this->item); @@ -209,7 +190,7 @@ class singleview_grade extends singleview_tablelike global $OUTPUT; return $OUTPUT->paging_bar( - count($this->all_items), $this->page, $this->perpage, + $this->totalitemcount, $this->page, $this->perpage, new moodle_url('/grade/report/singleview/index.php', array( 'perpage' => $this->perpage, 'id' => $this->courseid, diff --git a/grade/report/singleview/screens/select/lib.php b/grade/report/singleview/screens/select/lib.php index 2ce62f822b8..e3aa2dd9ac1 100644 --- a/grade/report/singleview/screens/select/lib.php +++ b/grade/report/singleview/screens/select/lib.php @@ -23,10 +23,15 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class singleview_select extends singleview_screen { +class gradereport_singleview_select extends gradereport_singleview_screen { public function init($selfitemisempty = false) { global $DB; + $this->items = get_role_users( + '', $this->context, false, '', + 'u.lastname, u.firstname', null, $this->groupid, + $this->perpage * $this->page, $this->perpage + ); $this->item = $DB->get_record('course', array('id' => $this->courseid)); } @@ -35,14 +40,14 @@ class singleview_select extends singleview_screen { $html = ''; - $types = grade_report_singleview::valid_screens(); + $types = gradereport_singleview::valid_screens(); foreach ($types as $type) { - $class = grade_report_singleview::classname($type); + $class = gradereport_singleview::classname($type); $screen = new $class($this->courseid, null, $this->groupid); - if (!$screen instanceof selectable_items) { + if (!$screen instanceof gradereport_selectable_items) { continue; } @@ -65,7 +70,7 @@ class singleview_select extends singleview_screen { } if (empty($html)) { - $OUTPUT->notification(get_string('no_screens', 'gradereport_singleview')); + $OUTPUT->notification(get_string('noscreens', 'gradereport_singleview')); } return $html; diff --git a/grade/report/singleview/screens/user/lib.php b/grade/report/singleview/screens/user/lib.php index 1506852decd..63349eee3b8 100644 --- a/grade/report/singleview/screens/user/lib.php +++ b/grade/report/singleview/screens/user/lib.php @@ -23,7 +23,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class singleview_user extends singleview_tablelike implements selectable_items { +class gradereport_singleview_user extends gradereport_singleview_tablelike implements gradereport_selectable_items { private $categories = array(); @@ -64,7 +64,7 @@ class singleview_user extends singleview_tablelike implements selectable_items { } } - $this->items = array_filter($seq->items, grade_report_singleview::filters()); + $this->items = array_filter($seq->items, gradereport_singleview::filters()); unset($seq); @@ -105,10 +105,15 @@ class singleview_user extends singleview_tablelike implements selectable_items { $lockeditemgrade = 1; } // Check both grade and grade item. - if ( $lockeditem || $lockeditemgrade ) + if ($lockeditem || $lockeditemgrade) { $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); + } - $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $item->cmid)); + $realuserid = ''; + if (isset($item->cmid)) { + $realuserid = $item->cmid; + } + $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $realuserid)); $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name()); $grade->label = $item->get_name(); @@ -152,10 +157,6 @@ class singleview_user extends singleview_tablelike implements selectable_items { } public function heading() { - if (!empty($this->item->alternatename)) { - return $this->item->alternatename . ' (' . $this->item->firstname . ') ' . $this->item->lastname; - } else { - return fullname($this->item); - } + return fullname($this->item); } } diff --git a/grade/report/singleview/styles.css b/grade/report/singleview/styles.css index d7e88178de0..78a8607ac9e 100644 --- a/grade/report/singleview/styles.css +++ b/grade/report/singleview/styles.css @@ -26,7 +26,7 @@ text-align: center; } -input[name^="finalgrade"] { +#page-grade-report-singleview-index input[name^="finalgrade"] { width: 50px; } diff --git a/grade/report/singleview/tests/behat/singleview.feature b/grade/report/singleview/tests/behat/singleview.feature index 4ede6f2ba73..33dbc3ff1b7 100644 --- a/grade/report/singleview/tests/behat/singleview.feature +++ b/grade/report/singleview/tests/behat/singleview.feature @@ -1,12 +1,13 @@ -@core @core_grades @singleview +@core @core_grades @gradereport_singleview Feature: We can use Single view As a teacher - In order to view a user or an activities grades + In order to view and edit grades + For users and activities for a course. -Background: + Background: Given the following "courses" exist: - | fullname | shortname | category | groupmode | - | Course 1 | C1 | 0 | 1 | + | fullname | shortname | category | + | Course 1 | C1 | 0 | And the following "users" exist: | username | firstname | lastname | email | idnumber | alternatename | | teacher1 | Teacher | 1 | teacher1@asd.com | t1 | teacherbro | @@ -31,37 +32,27 @@ Background: | assign | C1 | a2 | Test assignment two | Submit something! | 100 | | assign | C1 | a3 | Test assignment three | Submit something! | 150 | | assign | C1 | a4 | Test assignment four | Submit nothing! | 150 | - And the following "activities" exist: - | activity | course | idnumber | name | intro | gradecategory | grade | - | assign | C1 | a5 | Test assignment five | Submit something! | Sub category 1 | 200 - | assign | C1 | a6 | Test assignment six | Submit something! | Sub category 1 | 100 - | assign | C1 | a7 | Test assignment seven | Submit nothing! | Sub category 1 | 150 - And the following "activities" exist: - | activity | course | idnumber | name | intro | gradecategory | grade | - | assign | C1 | a8 | Test assignment eight | Submit something! | Sub category 2 | 200 - | assign | C1 | a9 | Test assignment nine | Submit something! | Sub category 2 | 100 - | assign | C1 | 10 | Test assignment ten | Submit nothing! | Sub category 2 | 150 - And I log in as "teacher1" + Then I log in as "teacher1" And I follow "Course 1" And I follow "Grades" -@javascript -Scenario: I can update grades, add feedback and exclude grades. - And I click on "Single view" "option" - And I click on "studentawesemo (Student) 4" "option" - And I click on "Override for Test assignment eight" "checkbox" + @javascript + Scenario: I can update grades, add feedback and exclude grades. + Given I click on "Single view" "option" + Then I click on "studentawesemo (Student) 4" "option" + And I click on "Override for Test assignment one" "checkbox" And I set the following fields to these values: - | Grade for Test assignment eight | 10.00 | - | Feedback for Test assignment eight | test data | + | Grade for Test assignment one | 10.00 | + | Feedback for Test assignment one | test data | And I click on "Exclude for Test assignment four" "checkbox" And I press "Update" Then the following should exist in the "user-grades" table: | Test assignment four | | excluded | Then the following should exist in the "user-grades" table: - | Test assignment eight | + | Test assignment one | | 10.00 | - And I click on "Single view for Test assignment five" "link" + And I click on "Single view for Test assignment three" "link" And I click on "Override for studentbro (Student) 1" "checkbox" And I set the following fields to these values: | Grade for studentbro (Student) 1 | 12.05 | @@ -69,22 +60,30 @@ Scenario: I can update grades, add feedback and exclude grades. And I click on "Exclude for studentjo (Student) 2" "checkbox" And I press "Update" Then the following should exist in the "user-grades" table: - | Test assignment five | + | Test assignment three | | 12.05 | | Excluded | -@javascript -Scenario: Single view quick links work on grade report. - And I follow "Single view for Test assignment one" - And I follow "Grader report" + @javascript + Scenario: Single view quick links work on grade report. + Given I follow "Single view for Test assignment one" + Then I should see "Test assignment one" + Then I follow "Grader report" And I follow "Single view for Student 1" + Then I should see "Student 1" -@javascript -Scenario: Navigation works in the Single view. - And I click on "Single view" "option" - And I click on "studentbro (Student) 1" "option" + @javascript + Scenario: Navigation works in the Single view. + Given I click on "Single view" "option" + Then I click on "studentbro (Student) 1" "option" + Then I should see "Student 1" And I follow "studentjo (Student) 2" + Then I should see "Student 2" And I follow "studentbro (Student) 1" - And I click on "Show grades for Test assignment five" "link" - And I follow "Test assignment six" - And I follow "Test assignment five" + Then I should see "Student 1" + And I click on "Show grades for Test assignment four" "link" + Then I should see "Test assignment four" + And I follow "Test assignment three" + Then I should see "Test assignment three" + And I follow "Test assignment four" + Then I should see "Test assignment four" diff --git a/grade/report/singleview/version.php b/grade/report/singleview/version.php index 9e835d9b105..3225fbf15fb 100755 --- a/grade/report/singleview/version.php +++ b/grade/report/singleview/version.php @@ -19,7 +19,7 @@ * Standard version file * * @package gradereport_singleview - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index 334de7c6b9d..8344b6663bb 100644 --- a/lib/classes/plugin_manager.php +++ b/lib/classes/plugin_manager.php @@ -1038,7 +1038,7 @@ class core_plugin_manager { ), 'gradereport' => array( - 'grader', 'history', 'outcomes', 'overview', 'user' + 'grader', 'history', 'outcomes', 'overview', 'user', 'singleview' ), 'gradingform' => array( From 0a55da571a7e80353540b57024cbe6b6ab4a10d8 Mon Sep 17 00:00:00 2001 From: Aparup Banerjee Date: Mon, 6 Oct 2014 11:12:03 +0800 Subject: [PATCH 13/16] MDL-18229 gradereport: updated index.php test to calculate navigation based on new class name 'gradereport_selectable_items' --- grade/report/grader/lib.php | 20 +++++++++++++------ grade/report/singleview/classes/lib.php | 5 +---- grade/report/singleview/classes/uilib.php | 2 +- grade/report/singleview/index.php | 2 +- .../lang/en/gradereport_singleview.php | 2 +- grade/report/singleview/screens/grade/lib.php | 5 ++++- .../report/singleview/screens/select/lib.php | 6 ++++-- .../singleview/tests/behat/singleview.feature | 13 ++++++------ 8 files changed, 32 insertions(+), 23 deletions(-) diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index 677f10a5a76..eece138a0f5 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -658,17 +658,24 @@ class grade_report_grader extends grade_report { $userrow->cells[] = $usercell; + $userreportcell = new html_table_cell(); + $userreportcell->attributes['class'] = 'userreport'; + $userreportcell->header = true; if (has_capability('gradereport/'.$CFG->grade_profilereport.':view', $this->context)) { - $userreportcell = new html_table_cell(); - $userreportcell->attributes['class'] = 'userreport'; - $userreportcell->header = true; $a = new stdClass(); $a->user = $fullname; $strgradesforuser = get_string('gradesforuser', 'grades', $a); + $url = new moodle_url('/grade/report/'.$CFG->grade_profilereport.'/index.php', array('userid' => $user->id, 'id' => $this->course->id)); + $userreportcell->text .= $OUTPUT->action_icon($url, new pix_icon('t/grades', $strgradesforuser)); + } + + if (has_capability('gradereport/singleview:view', $this->context)) { $url = new moodle_url('/grade/report/singleview/index.php', array('id' => $this->course->id, 'itemid' => $user->id, 'item' => 'user')); $singleview = $OUTPUT->action_icon($url, new pix_icon('t/editstring', get_string('singleview', 'grades', $fullname))); - $url = new moodle_url('/grade/report/'.$CFG->grade_profilereport.'/index.php', array('userid' => $user->id, 'id' => $this->course->id)); - $userreportcell->text = $OUTPUT->action_icon($url, new pix_icon('t/grades', $strgradesforuser)) . $singleview; + $userreportcell->text .= $singleview; + } + + if ($userreportcell->text) { $userrow->cells[] = $userreportcell; } @@ -808,7 +815,8 @@ class grade_report_grader extends grade_report { } $singleview = ''; - if (has_capability('gradereport/'.$CFG->grade_profilereport.':view', $this->context)) { + if (has_capability('gradereport/singleview:view', $this->context) && + preg_match('/^item/', $type)) { $url = new moodle_url('/grade/report/singleview/index.php', array( 'id' => $this->course->id, 'item' => 'grade', diff --git a/grade/report/singleview/classes/lib.php b/grade/report/singleview/classes/lib.php index 1753cc8b56d..3153750673d 100644 --- a/grade/report/singleview/classes/lib.php +++ b/grade/report/singleview/classes/lib.php @@ -215,9 +215,6 @@ abstract class gradereport_singleview_screen { $oldname = "old$name"; $posted = $data->$name; - if (isset($data->$oldname)) { - $oldvalue = $data->$oldname; - } $format = $element->determine_format(); @@ -226,7 +223,7 @@ abstract class gradereport_singleview_screen { } // Same value; skip. - if ($oldvalue == $posted) { + if (isset($data->$oldname) && $data->$oldname == $posted) { continue; } diff --git a/grade/report/singleview/classes/uilib.php b/grade/report/singleview/classes/uilib.php index e5ed217b4f0..a91eefd2a1a 100644 --- a/grade/report/singleview/classes/uilib.php +++ b/grade/report/singleview/classes/uilib.php @@ -327,7 +327,7 @@ class gradereport_singleview_bulk_insert_ui extends gradereport_singleview_ui_el $select = html_writer::select( $insertoptions, $this->selectname, 'blanks', false ); - + $label = html_writer::tag('label', $insertappliesto); $text = new gradereport_singleview_text_attribute($this->insertname, "0", 'bulk'); return implode(' ', array($apply, $text->html(), $label, $select)); diff --git a/grade/report/singleview/index.php b/grade/report/singleview/index.php index 9ae3948ed6b..1e6706df6a1 100755 --- a/grade/report/singleview/index.php +++ b/grade/report/singleview/index.php @@ -110,7 +110,7 @@ if ($data = data_submitted()) { } $graderrightnav = $graderleftnav = null; -if ($report->screen instanceof selectable_items +if ($report->screen instanceof gradereport_selectable_items && class_exists(gradereport_singleview::classname($report->screen->item_type()))) { $optionkeys = array_keys($report->screen->options()); diff --git a/grade/report/singleview/lang/en/gradereport_singleview.php b/grade/report/singleview/lang/en/gradereport_singleview.php index b00f666f249..0058db8fa77 100755 --- a/grade/report/singleview/lang/en/gradereport_singleview.php +++ b/grade/report/singleview/lang/en/gradereport_singleview.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * Strings for Single view + * Strings for Single view * * @package gradereport_singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) diff --git a/grade/report/singleview/screens/grade/lib.php b/grade/report/singleview/screens/grade/lib.php index e694138a0f7..147817e8f47 100644 --- a/grade/report/singleview/screens/grade/lib.php +++ b/grade/report/singleview/screens/grade/lib.php @@ -57,13 +57,16 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike } public function options() { - return array_map(function($user) { + $options = array_map(function($user) { if (!empty($user->alternatename)) { return $user->alternatename . ' (' . $user->firstname . ') ' . $user->lastname; } else { return fullname($user); } }, $this->items); + + $options['name']= 'foo'; + return $options; } public function item_type() { diff --git a/grade/report/singleview/screens/select/lib.php b/grade/report/singleview/screens/select/lib.php index e3aa2dd9ac1..6dd59169239 100644 --- a/grade/report/singleview/screens/select/lib.php +++ b/grade/report/singleview/screens/select/lib.php @@ -27,9 +27,11 @@ class gradereport_singleview_select extends gradereport_singleview_screen { public function init($selfitemisempty = false) { global $DB; + $roleids = explode(',', get_config('moodle', 'gradebookroles')); + $this->items = get_role_users( - '', $this->context, false, '', - 'u.lastname, u.firstname', null, $this->groupid, + $roleids, $this->context, false, '', + 'u.id, u.lastname, u.firstname', null, $this->groupid, $this->perpage * $this->page, $this->perpage ); $this->item = $DB->get_record('course', array('id' => $this->courseid)); diff --git a/grade/report/singleview/tests/behat/singleview.feature b/grade/report/singleview/tests/behat/singleview.feature index 33dbc3ff1b7..e215ffdcd10 100644 --- a/grade/report/singleview/tests/behat/singleview.feature +++ b/grade/report/singleview/tests/behat/singleview.feature @@ -32,16 +32,16 @@ Feature: We can use Single view | assign | C1 | a2 | Test assignment two | Submit something! | 100 | | assign | C1 | a3 | Test assignment three | Submit something! | 150 | | assign | C1 | a4 | Test assignment four | Submit nothing! | 150 | - Then I log in as "teacher1" + And I log in as "teacher1" And I follow "Course 1" And I follow "Grades" - @javascript + @javascript Scenario: I can update grades, add feedback and exclude grades. Given I click on "Single view" "option" - Then I click on "studentawesemo (Student) 4" "option" + And I click on "studentawesemo (Student) 4" "option" And I click on "Override for Test assignment one" "checkbox" - And I set the following fields to these values: + When I set the following fields to these values: | Grade for Test assignment one | 10.00 | | Feedback for Test assignment one | test data | And I click on "Exclude for Test assignment four" "checkbox" @@ -49,7 +49,7 @@ Feature: We can use Single view Then the following should exist in the "user-grades" table: | Test assignment four | | excluded | - Then the following should exist in the "user-grades" table: + And the following should exist in the "user-grades" table: | Test assignment one | | 10.00 | And I click on "Single view for Test assignment three" "link" @@ -59,12 +59,11 @@ Feature: We can use Single view | Feedback for studentbro (Student) 1 | test data2 | And I click on "Exclude for studentjo (Student) 2" "checkbox" And I press "Update" - Then the following should exist in the "user-grades" table: + And the following should exist in the "user-grades" table: | Test assignment three | | 12.05 | | Excluded | - @javascript Scenario: Single view quick links work on grade report. Given I follow "Single view for Test assignment one" Then I should see "Test assignment one" From 5f3decb5cb76408c4e7e4ec3a80096175f3e4477 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Mon, 6 Oct 2014 14:38:43 +0800 Subject: [PATCH 14/16] MDL-18229 gradebook: Additional fixes. Random foo left in options. (test code) Allowed editing link for Course total. Fixes based on Apu's review. --- grade/report/grader/lib.php | 2 +- grade/report/singleview/lang/en/gradereport_singleview.php | 4 ++-- grade/report/singleview/lib.php | 4 +++- grade/report/singleview/screens/grade/lib.php | 1 - grade/report/singleview/screens/user/lib.php | 2 +- grade/report/singleview/tests/behat/singleview.feature | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index eece138a0f5..e7d75f87485 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -816,7 +816,7 @@ class grade_report_grader extends grade_report { $singleview = ''; if (has_capability('gradereport/singleview:view', $this->context) && - preg_match('/^item/', $type)) { + !preg_match('/^category/', $type)) { $url = new moodle_url('/grade/report/singleview/index.php', array( 'id' => $this->course->id, 'item' => 'grade', diff --git a/grade/report/singleview/lang/en/gradereport_singleview.php b/grade/report/singleview/lang/en/gradereport_singleview.php index 0058db8fa77..429e6f87863 100755 --- a/grade/report/singleview/lang/en/gradereport_singleview.php +++ b/grade/report/singleview/lang/en/gradereport_singleview.php @@ -38,11 +38,11 @@ $string['feedbackfor'] = 'Feedback for {$a}'; $string['filtergrades'] = 'Show grades for {$a}.'; $string['gradefor'] = 'Grade for {$a}'; $string['noscreens'] = 'Could not find a suitable Single view screen.'; -$string['notallowed'] = 'Not allowed to quick edit this item'; +$string['notallowed'] = 'Not allowed to use Singleview on this item.'; $string['notvalid'] = 'Not a valid Single view screen: {$a}'; $string['override'] = 'Override'; $string['overrideall'] = 'Override all grades'; $string['overridefor'] = 'Override for {$a}'; $string['overridenone'] = 'Override no grades'; $string['pluginname'] = 'Single view'; -$string['singleview:view'] = 'View the '.$string['pluginname'].' report'; +$string['singleview:view'] = 'View report'; diff --git a/grade/report/singleview/lib.php b/grade/report/singleview/lib.php index fac070d905f..798729e636d 100755 --- a/grade/report/singleview/lib.php +++ b/grade/report/singleview/lib.php @@ -75,7 +75,9 @@ class gradereport_singleview extends grade_report { } function process_data($data) { - return $this->screen->process($data); + if (has_capability('moodle/grade:manage', $this->context)) { + return $this->screen->process($data); + } } function process_action($target, $action) { diff --git a/grade/report/singleview/screens/grade/lib.php b/grade/report/singleview/screens/grade/lib.php index 147817e8f47..b403a06cdda 100644 --- a/grade/report/singleview/screens/grade/lib.php +++ b/grade/report/singleview/screens/grade/lib.php @@ -65,7 +65,6 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike } }, $this->items); - $options['name']= 'foo'; return $options; } diff --git a/grade/report/singleview/screens/user/lib.php b/grade/report/singleview/screens/user/lib.php index 63349eee3b8..513dfa24784 100644 --- a/grade/report/singleview/screens/user/lib.php +++ b/grade/report/singleview/screens/user/lib.php @@ -113,7 +113,7 @@ class gradereport_singleview_user extends gradereport_singleview_tablelike imple if (isset($item->cmid)) { $realuserid = $item->cmid; } - $url = new moodle_url("/mod/$item->itemmodule/view.php", array('id' => $realuserid)); + $url = new moodle_url('/mod/' . $item->itemmodule . '/view.php', array('id' => $realuserid)); $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name()); $grade->label = $item->get_name(); diff --git a/grade/report/singleview/tests/behat/singleview.feature b/grade/report/singleview/tests/behat/singleview.feature index e215ffdcd10..6ea012463fd 100644 --- a/grade/report/singleview/tests/behat/singleview.feature +++ b/grade/report/singleview/tests/behat/singleview.feature @@ -64,7 +64,7 @@ Feature: We can use Single view | 12.05 | | Excluded | - Scenario: Single view quick links work on grade report. + Scenario: Single view links work on grade report. Given I follow "Single view for Test assignment one" Then I should see "Test assignment one" Then I follow "Grader report" From 57fac09a40732ad11dbde555f4984511e9f4481a Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Fri, 10 Oct 2014 01:06:50 +0800 Subject: [PATCH 15/16] MDL-18229 Grades: singleview report mega cleanup. Fix all the things, including: * Fix $PAGE->url * Fix coding style. * Add event for reportviewed * Removed broken callback gradereport_singleview_profilereport * Removed vertical-align-middle * Changed prefixes in css * phpcs fixes * moodlecheck fixes including phpdocs * Move classes to use autoloading * Remove all smelly code tricks like func_get_args, scandir etc (lots). --- grade/report/grader/lib.php | 3 +- .../classes/event/grade_report_viewed.php | 60 ++ grade/report/singleview/classes/lib.php | 404 ----------- .../classes/local/screen/filterable_items.php | 44 ++ .../local/screen/grade.php} | 201 ++++-- .../classes/local/screen/screen.php | 339 +++++++++ .../local/screen/select.php} | 51 +- .../classes/local/screen/selectable_items.php | 54 ++ .../classes/local/screen/tablelike.php | 225 ++++++ .../singleview/classes/local/screen/user.php | 336 +++++++++ .../classes/local/ui/attribute_format.php | 52 ++ .../classes/local/ui/be_checked.php | 42 ++ .../classes/local/ui/be_disabled.php | 40 ++ .../classes/local/ui/bulk_insert.php | 116 ++++ .../classes/local/ui/checkbox_attribute.php | 122 ++++ .../classes/local/ui/dropdown_attribute.php | 101 +++ .../singleview/classes/local/ui/element.php | 89 +++ .../classes/local/ui/empty_element.php | 59 ++ .../singleview/classes/local/ui/exclude.php | 110 +++ .../singleview/classes/local/ui/feedback.php | 123 ++++ .../classes/local/ui/finalgrade.php | 181 +++++ .../local/ui/grade_attribute_format.php | 87 +++ .../singleview/classes/local/ui/override.php | 113 +++ .../singleview/classes/local/ui/range.php | 59 ++ .../singleview/classes/local/ui/tabbable.php | 43 ++ .../classes/local/ui/text_attribute.php | 108 +++ .../classes/local/ui/unique_name.php | 43 ++ .../classes/local/ui/unique_value.php | 42 ++ grade/report/singleview/classes/uilib.php | 648 ------------------ grade/report/singleview/db/access.php | 1 - grade/report/singleview/index.php | 75 +- .../lang/en/gradereport_singleview.php | 7 +- grade/report/singleview/lib.php | 144 ++-- grade/report/singleview/screens/user/lib.php | 162 ----- grade/report/singleview/styles.css | 30 +- grade/report/singleview/version.php | 2 +- 36 files changed, 2909 insertions(+), 1407 deletions(-) create mode 100644 grade/report/singleview/classes/event/grade_report_viewed.php delete mode 100644 grade/report/singleview/classes/lib.php create mode 100644 grade/report/singleview/classes/local/screen/filterable_items.php rename grade/report/singleview/{screens/grade/lib.php => classes/local/screen/grade.php} (50%) create mode 100644 grade/report/singleview/classes/local/screen/screen.php rename grade/report/singleview/{screens/select/lib.php => classes/local/screen/select.php} (66%) create mode 100644 grade/report/singleview/classes/local/screen/selectable_items.php create mode 100644 grade/report/singleview/classes/local/screen/tablelike.php create mode 100644 grade/report/singleview/classes/local/screen/user.php create mode 100644 grade/report/singleview/classes/local/ui/attribute_format.php create mode 100644 grade/report/singleview/classes/local/ui/be_checked.php create mode 100644 grade/report/singleview/classes/local/ui/be_disabled.php create mode 100644 grade/report/singleview/classes/local/ui/bulk_insert.php create mode 100644 grade/report/singleview/classes/local/ui/checkbox_attribute.php create mode 100644 grade/report/singleview/classes/local/ui/dropdown_attribute.php create mode 100644 grade/report/singleview/classes/local/ui/element.php create mode 100644 grade/report/singleview/classes/local/ui/empty_element.php create mode 100644 grade/report/singleview/classes/local/ui/exclude.php create mode 100644 grade/report/singleview/classes/local/ui/feedback.php create mode 100644 grade/report/singleview/classes/local/ui/finalgrade.php create mode 100644 grade/report/singleview/classes/local/ui/grade_attribute_format.php create mode 100644 grade/report/singleview/classes/local/ui/override.php create mode 100644 grade/report/singleview/classes/local/ui/range.php create mode 100644 grade/report/singleview/classes/local/ui/tabbable.php create mode 100644 grade/report/singleview/classes/local/ui/text_attribute.php create mode 100644 grade/report/singleview/classes/local/ui/unique_name.php create mode 100644 grade/report/singleview/classes/local/ui/unique_value.php delete mode 100644 grade/report/singleview/classes/uilib.php delete mode 100644 grade/report/singleview/screens/user/lib.php diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index e7d75f87485..13b092cb1d3 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -815,8 +815,7 @@ class grade_report_grader extends grade_report { } $singleview = ''; - if (has_capability('gradereport/singleview:view', $this->context) && - !preg_match('/^category/', $type)) { + if (has_capability('gradereport/singleview:view', $this->context)) { $url = new moodle_url('/grade/report/singleview/index.php', array( 'id' => $this->course->id, 'item' => 'grade', diff --git a/grade/report/singleview/classes/event/grade_report_viewed.php b/grade/report/singleview/classes/event/grade_report_viewed.php new file mode 100644 index 00000000000..b35c4cb1b13 --- /dev/null +++ b/grade/report/singleview/classes/event/grade_report_viewed.php @@ -0,0 +1,60 @@ +. + +/** + * Single view report viewed event. + * + * @package gradereport_singleview + * @copyright 2014 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\event; + +defined('MOODLE_INTERNAL') || die(); + +/** + * User report viewed event class. + * + * @package gradereport_singleview + * @since Moodle 2.8 + * @copyright 2014 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class grade_report_viewed extends \core\event\grade_report_viewed { + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventgradereportviewed', 'gradereport_singleview'); + } + + /** + * Custom validation. + * + * Throw \coding_exception notice in case of any problems. + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->relateduserid)) { + throw new \coding_exception('The \'relateduserid\' value must be set.'); + } + } +} diff --git a/grade/report/singleview/classes/lib.php b/grade/report/singleview/classes/lib.php deleted file mode 100644 index 3153750673d..00000000000 --- a/grade/report/singleview/classes/lib.php +++ /dev/null @@ -1,404 +0,0 @@ -. - -/** - * The gradebook simple view - base class for the table - * - * @package gradereport_singleview - * @copyright 2014 Moodle Pty Ltd (http://moodle.com) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require_once $CFG->dirroot . '/grade/report/singleview/classes/uilib.php'; - -interface gradereport_selectable_items { - public function description(); - - public function options(); - - public function item_type(); -} - -interface gradereport_item_filtering { - public static function filter($item); -} - -abstract class gradereport_singleview_screen { - var $courseid; - - var $itemid; - - var $groupid; - - var $context; - - var $page; - - var $perpage; - - function __construct($courseid, $itemid, $groupid = null) { - global $DB; - - $this->courseid = $courseid; - $this->itemid = $itemid; - $this->groupid = $groupid; - - $this->context = context_course::instance($this->courseid); - $this->course = $DB->get_record('course', array('id' => $courseid)); - - $this->page = optional_param('page', 0, PARAM_INT); - $this->perpage = optional_param('perpage', 100, PARAM_INT); - if ($this->perpage > 100) { - $this->perpage = 100; - } - - $this->init(empty($itemid)); - } - - public function setup_structure() { - $this->structure = new grade_structure(); - $this->structure->modinfo = get_fast_modinfo($this->course); - } - - public function format_link($screen, $itemid, $display = null) { - $url = new moodle_url('/grade/report/singleview/index.php', array( - 'id' => $this->courseid, - 'item' => $screen, - 'itemid' => $itemid, - 'group' => $this->groupid, - )); - - if ($display) { - return html_writer::link($url, $display); - } else { - return $url; - } - } - - public function fetch_grade_or_default($item, $userid) { - $grade = grade_grade::fetch(array( - 'itemid' => $item->id, 'userid' => $userid - )); - - if (!$grade) { - $default = new stdClass; - - $default->userid = $userid; - $default->itemid = $item->id; - $default->feedback = ''; - - $grade = new grade_grade($default, false); - } - - $grade->grade_item = $item; - - return $grade; - } - - public function make_toggle($key) { - $attrs = array('href' => '#'); - - $all = html_writer::tag('a', get_string('all'), $attrs + array( - 'class' => 'include all ' . $key - )); - - $none = html_writer::tag('a', get_string('none'), $attrs + array( - 'class' => 'include none ' . $key - )); - - return html_writer::tag('span', "$all / $none", array( - 'class' => 'inclusion_links' - )); - } - - public function make_toggle_links($key) { - return get_string($key, 'gradereport_singleview') . ' ' . - $this->make_toggle($key); - } - - public function heading() { - return get_string('pluginname', 'gradereport_singleview'); - } - - public abstract function init($self_item_is_empty = false); - - public abstract function html(); - - public function supports_paging() { - return true; - } - - public function pager() { - if (!$this->supports_paging()) { - return ''; - } - - global $OUTPUT; - - list($___, $item) = explode('singleview_', get_class($this)); - return $OUTPUT->paging_bar( - count($this->items), $this->page, $this->perpage, - new moodle_url('/grade/report/singleview/index.php', array( - 'perpage' => $this->perpage, - 'id' => $this->courseid, - 'groupid' => $this->groupid, - 'itemid' => $this->itemid, - 'item' => $item - )) - ); - } - - public function js() { - global $PAGE; - - $module = array( - 'name' => 'gradereport_singleview', - 'fullpath' => '/grade/report/singleview/js/singleview.js', - 'requires' => array('base', 'dom', 'event', 'event-simulate', 'io-base') - ); - - $PAGE->requires->js_init_call('M.gradereport_singleview.init', array(), false, $module); - } - - public function factory() { - if (empty($this->__factory)) { - $this->__factory = new gradereport_singleview_grade_ui_factory(); - } - - return $this->__factory; - } - - public function process($data) { - $warnings = array(); - - $fields = $this->definition(); - - foreach ($data as $varname => $throw) { - if (preg_match("/(\w+)_(\d+)_(\d+)/", $varname, $matches)) { - $itemid = $matches[2]; - $userid = $matches[3]; - } else { - continue; - } - - if (!in_array($matches[1], $fields)) { - continue; - } - - $grade_item = grade_item::fetch(array( - 'id' => $itemid, 'courseid' => $this->courseid - )); - - if (!$grade_item) { - continue; - } - - $grade = $this->fetch_grade_or_default($grade_item, $userid); - - $element = $this->factory()->create($matches[1])->format($grade); - - $name = $element->get_name(); - $oldname = "old$name"; - - $posted = $data->$name; - - $format = $element->determine_format(); - - if ($format->is_textbox() and trim($data->$name) === '') { - $data->$name = null; - } - - // Same value; skip. - if (isset($data->$oldname) && $data->$oldname == $posted) { - continue; - } - - $msg = $element->set($posted); - - // Optional type. - if (!empty($msg)) { - $warnings[] = $msg; - } - } - - // Some post-processing. - $event_data = new stdClass; - $event_data->warnings = $warnings; - $event_data->post_data = $data; - $event_data->instance = $this; - - return $event_data->warnings; - } - - public function display_group_selector() { - return true; - } -} - -abstract class gradereport_singleview_tablelike extends gradereport_singleview_screen implements tabbable { - public $items; - - protected $headers = array(); - - protected $definition = array(); - - public abstract function format_line($item); - - public function headers() { - return $this->headers; - } - - public function set_headers($overwrite) { - $this->headers = $overwrite; - return $this; - } - - public function definition() { - return $this->definition; - } - - public function set_definition($overwrite) { - $this->definition = $overwrite; - return $this; - } - - public function get_tabindex() { - return (count($this->definition()) * $this->total) + $this->index; - } - - // Special injection for bulk operations. - public function process($data) { - $bulk = $this->factory()->create('bulk_insert')->format($this->item); - // Bulk insert messages the data to be passed in - // ie: for all grades of empty grades apply the specified value. - if ($bulk->is_applied($data)) { - $filter = $bulk->get_type($data); - $insert_value = $bulk->get_insert_value($data); - // Appropriately massage data that may not exist. - if ($this->supports_paging()) { - // TODO: this only works with the grade screen... - $grade_item = grade_item::fetch(array( - 'courseid' => $this->courseid, - 'id' => $this->item->id - )); - - $null = $grade_item->gradetype == GRADE_TYPE_SCALE ? -1 : ''; - - foreach ($this->items as $itemid => $item) { - $field = "finalgrade_{$grade_item->id}_{$itemid}"; - if (isset($data->$field)) { - continue; - } - - $grade = grade_grade::fetch(array( - 'itemid' => $grade_item->id, - 'userid' => $itemid - )); - - $data->$field = empty($grade) ? $null : $grade->finalgrade; - $data->{"old$field"} = $data->$field; - } - } - - foreach ($data as $varname => $value) { - if (!preg_match('/^finalgrade_(\d+)_/', $varname, $matches)) { - continue; - } - - $grade_item = grade_item::fetch(array( - 'courseid' => $this->courseid, - 'id' => $matches[1] - )); - - $is_scale = ($grade_item->gradetype == GRADE_TYPE_SCALE); - - $empties = (trim($value) === '' or ($is_scale and $value == -1)); - - if ($filter == 'all' or $empties) { - $data->$varname = ($is_scale and empty($insert_value)) ? - -1 : $insert_value; - } - } - } - - return parent::process($data); - } - - public function format_definition($line, $grade) { - foreach ($this->definition() as $i => $field) { - // Table tab index. - $tab = ($i * $this->total) + $this->index; - $html = $this->factory()->create($field)->format($grade, $tab); - - if ($field == 'finalgrade' and !empty($this->structure)) { - $html .= $this->structure->get_grade_analysis_icon($grade); - } - - $line[] = $html; - } - return $line; - } - - public function html() { - $table = new html_table(); - - $table->head = $this->headers(); - - // To be used for extra formatting. - $this->index = 0; - $this->total = count($this->items); - - foreach ($this->items as $item) { - $this->index ++; - $table->data[] = $this->format_line($item); - } - - $underlying = get_class($this); - - $data = new stdClass; - $data->table = $table; - $data->instance = $this; - - $button_attr = array('class' => 'singleview_buttons submit'); - $button_html = implode(' ', $this->buttons()); - - $buttons = html_writer::tag('div', $button_html, $button_attr); - - return html_writer::tag('form', - $buttons . html_writer::table($table) . $this->bulk_insert() . $buttons, - array('method' => 'POST') - ); - } - - public function bulk_insert() { - return html_writer::tag( - 'div', - $this->factory()->create('bulk_insert')->format($this->item)->html(), - array('class' => 'singleview_bulk') - ); - } - - public function buttons() { - $save = html_writer::empty_tag('input', array( - 'type' => 'submit', - 'value' => get_string('update'), - 'tabindex' => $this->get_tabindex(), - )); - - return array($save); - } -} diff --git a/grade/report/singleview/classes/local/screen/filterable_items.php b/grade/report/singleview/classes/local/screen/filterable_items.php new file mode 100644 index 00000000000..b266cf9bbd8 --- /dev/null +++ b/grade/report/singleview/classes/local/screen/filterable_items.php @@ -0,0 +1,44 @@ +. + +/** + * The gradebook interface for a filterable class. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\screen; + +defined('MOODLE_INTERNAL') || die; + +/** + * The gradebook interface for a filterable class. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +interface filterable_items { + + /** + * Return true/false if this item should be filtered. + * @param mixed $item (user or grade_item) + * @return bool + */ + public static function filter($item); +} diff --git a/grade/report/singleview/screens/grade/lib.php b/grade/report/singleview/classes/local/screen/grade.php similarity index 50% rename from grade/report/singleview/screens/grade/lib.php rename to grade/report/singleview/classes/local/screen/grade.php index b403a06cdda..425fa3a73e6 100644 --- a/grade/report/singleview/screens/grade/lib.php +++ b/grade/report/singleview/classes/local/screen/grade.php @@ -1,5 +1,4 @@ . /** - * The gradebook simple view - grades view (for an activity) + * The screen with a list of users. * * @package gradereport_singleview * @copyright 2014 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class gradereport_singleview_grade extends gradereport_singleview_tablelike - implements gradereport_selectable_items, gradereport_item_filtering { +namespace gradereport_singleview\local\screen; +use gradereport_singleview\local\ui\range; +use grade_item; +use moodle_url; +use pix_icon; +use html_writer; +use gradereport_singleview; + +defined('MOODLE_INTERNAL') || die; + +/** + * The screen with a list of users. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class grade extends tablelike implements selectable_items, filterable_items { + + /** @var int $totalitemcount Used for paging */ private $totalitemcount = 0; + /** @var bool $requiresextra True if this is a manual grade item */ private $requiresextra = false; + /** @var bool $requirepaging True if there are more users than our limit. */ private $requirespaging = true; - public $structure; - - private static $allowcategories; - + /** + * True if $CFG->grade_overridecat is true + * + * @return bool + */ public static function allowcategories() { - if (is_null(self::$allowcategories)) { - self::$allowcategories = get_config('moodle', 'grade_overridecat'); - } - - return self::$allowcategories; + return get_config('moodle', 'grade_overridecat'); } + /** + * Filter the list excluding category items (if required)? + * @param grade_item $item The grade item. + */ public static function filter($item) { - return ( - self::allowcategories() or !( - $item->is_course_item() or $item->is_category_item() - ) - ); + return get_config('moodle', 'grade_overridecat') || + !($item->is_course_item() || $item->is_category_item()); } + /** + * Get the description of this page + * @return string + */ public function description() { return get_string('users'); } + /** + * Convert this list of items into an options list + * + * @return array + */ public function options() { - $options = array_map(function($user) { - if (!empty($user->alternatename)) { - return $user->alternatename . ' (' . $user->firstname . ') ' . $user->lastname; - } else { - return fullname($user); - } - }, $this->items); + $options = array(); + foreach ($this->items as $userid => $user) { + $options[$userid] = fullname($user); + } return $options; } + /** + * Return the type of the things in this list. + * @return string + */ public function item_type() { return 'user'; } + /** + * Get the original settings for this item + * @return array + */ public function original_definition() { $def = array('finalgrade', 'feedback'); @@ -84,14 +115,17 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike return $def; } + /** + * Init this page + * + * @param bool $selfitemisempty True if we have not selected a user. + */ public function init($selfitemisempty = false) { $roleids = explode(',', get_config('moodle', 'gradebookroles')); $this->items = get_role_users( $roleids, $this->context, false, '', - 'u.lastname, u.firstname', null, $this->groupid, - $this->perpage * $this->page, $this->perpage - ); + 'u.lastname, u.firstname', null, $this->groupid); $this->totalitemcount = count_role_users($roleids, $this->context); @@ -99,21 +133,15 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike return; } - global $DB; - $params = array( 'id' => $this->itemid, 'courseid' => $this->courseid ); $this->item = grade_item::fetch($params); - - $filterfun = gradereport_singleview::filters(); - - $allowed = $filterfun($this->item); - - if (empty($allowed)) { - print_error('notallowed', 'gradereport_singleview'); + if (!self::filter($this->item)) { + $this->items = array(); + $this->set_init_error(get_string('gradeitemcannotbeoverridden', 'gradereport_singleview')); } $this->requiresextra = !$this->item->is_manual_item(); @@ -124,6 +152,11 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike $this->set_headers($this->original_headers()); } + /** + * Get the table headers + * + * @return array + */ public function original_headers() { return array( '', // For filter icon. @@ -137,6 +170,12 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike ); } + /** + * Format a row in the table + * + * @param user $item + * @return string + */ public function format_line($item) { global $OUTPUT; @@ -152,8 +191,9 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike $lockedgradeitem = 1; } // Check both grade and grade item. - if ( $lockedgrade || $lockedgradeitem ) + if ( $lockedgrade || $lockedgradeitem ) { $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked') . ' '; + } if (!empty($item->alternatename)) { $fullname = $lockicon . $item->alternatename . ' (' . $item->firstname . ') ' . $item->lastname; @@ -176,18 +216,33 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike return $this->format_definition($line, $grade); } + /** + * Get the range ui element for this grade_item + * + * @return element; + */ public function item_range() { if (empty($this->range)) { - $this->range = $this->factory()->create('range')->format($this->item); + $this->range = new range($this->item); } return $this->range; } + /** + * Does this page require paging? + * + * @return bool + */ public function supports_paging() { return $this->requirespaging; } + /** + * Get the pager for this page. + * + * @return string + */ public function pager() { global $OUTPUT; @@ -203,7 +258,75 @@ class gradereport_singleview_grade extends gradereport_singleview_tablelike ); } + /** + * Get the heading for this page. + * + * @return string + */ public function heading() { return $this->item->get_name(); } + + /** + * Process the data from the form. + * + * @param array $data + * @return array of warnings + */ + public function process($data) { + $bulk = new bulk_insert($this->item); + // Bulk insert messages the data to be passed in + // ie: for all grades of empty grades apply the specified value. + if ($bulk->is_applied($data)) { + $filter = $bulk->get_type($data); + $insertvalue = $bulk->get_insert_value($data); + // Appropriately massage data that may not exist. + if ($this->supports_paging()) { + $gradeitem = grade_item::fetch(array( + 'courseid' => $this->courseid, + 'id' => $this->item->id + )); + + $null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : ''; + + foreach ($this->items as $itemid => $item) { + $field = "finalgrade_{$gradeitem->id}_{$itemid}"; + if (isset($data->$field)) { + continue; + } + + $grade = grade_grade::fetch(array( + 'itemid' => $gradeitem->id, + 'userid' => $itemid + )); + + $data->$field = empty($grade) ? $null : $grade->finalgrade; + $data->{"old$field"} = $data->$field; + } + } + + foreach ($data as $varname => $value) { + if (!preg_match('/^finalgrade_(\d+)_/', $varname, $matches)) { + continue; + } + + $gradeitem = grade_item::fetch(array( + 'courseid' => $this->courseid, + 'id' => $matches[1] + )); + + $isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE); + + $empties = (trim($value) === '' or ($isscale and $value == -1)); + + if ($filter == 'all' or $empties) { + $data->$varname = ($isscale and empty($insertvalue)) ? + -1 : $insertvalue; + } + } + } + + return parent::process($data); + } + } diff --git a/grade/report/singleview/classes/local/screen/screen.php b/grade/report/singleview/classes/local/screen/screen.php new file mode 100644 index 00000000000..22e3eeaa897 --- /dev/null +++ b/grade/report/singleview/classes/local/screen/screen.php @@ -0,0 +1,339 @@ +. + +/** + * Abstract class used as a base for the 3 screens. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\screen; + +use context_course; +use moodle_url; +use html_writer; +use grade_structure; +use grade_grade; +use grade_item; +use stdClass; + +defined('MOODLE_INTERNAL') || die; + +/** + * Abstract class used as a base for the 3 screens. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class screen { + + /** @var int $courseid The id of the course */ + protected $courseid; + + /** @var int $itemid Either a user id or a grade_item id */ + protected $itemid; + + /** @var int $groupid The currently set groupid (if set) */ + protected $groupid; + + /** @var course_context $context The course context */ + protected $context; + + /** @var int $page The page number */ + protected $page; + + /** @var int $perpage Results per page */ + protected $perpage; + + /** @var array $items List of items on the page, they could be users or grade_items */ + protected $items; + + /** + * Constructor + * + * @param int $courseid The course id + * @param int $itemid The item id + * @param int $groupid The group id + */ + public function __construct($courseid, $itemid, $groupid = null) { + global $DB; + + $this->courseid = $courseid; + $this->itemid = $itemid; + $this->groupid = $groupid; + + $this->context = context_course::instance($this->courseid); + $this->course = $DB->get_record('course', array('id' => $courseid)); + + $this->page = optional_param('page', 0, PARAM_INT); + $this->perpage = optional_param('perpage', 100, PARAM_INT); + if ($this->perpage > 100) { + $this->perpage = 100; + } + + $this->init(empty($itemid)); + } + + /** + * Cache the grade_structure class + */ + public function setup_structure() { + $this->structure = new grade_structure(); + $this->structure->modinfo = get_fast_modinfo($this->course); + } + + /** + * Create a nice link from a thing (user or grade_item). + * + * @param string $screen + * @param int $itemid + * @param bool $display Should we wrap this in an anchor ? + * @return string The link + */ + public function format_link($screen, $itemid, $display = null) { + $url = new moodle_url('/grade/report/singleview/index.php', array( + 'id' => $this->courseid, + 'item' => $screen, + 'itemid' => $itemid, + 'group' => $this->groupid, + )); + + if ($display) { + return html_writer::link($url, $display); + } else { + return $url; + } + } + + /** + * Get the grade_grade + * + * @param grade_item $item The grade_item + * @param int $userid The user id + * @return grade_grade + */ + public function fetch_grade_or_default($item, $userid) { + $grade = grade_grade::fetch(array( + 'itemid' => $item->id, 'userid' => $userid + )); + + if (!$grade) { + $default = new stdClass; + + $default->userid = $userid; + $default->itemid = $item->id; + $default->feedback = ''; + + $grade = new grade_grade($default, false); + } + + $grade->grade_item = $item; + + return $grade; + } + + /** + * Make the HTML element that toggles all the checkboxes on or off. + * + * @param string $key A unique key for this control - inserted in the classes. + * @return string + */ + public function make_toggle($key) { + $attrs = array('href' => '#'); + + $all = html_writer::tag('a', get_string('all'), $attrs + array( + 'class' => 'include all ' . $key + )); + + $none = html_writer::tag('a', get_string('none'), $attrs + array( + 'class' => 'include none ' . $key + )); + + return html_writer::tag('span', "$all / $none", array( + 'class' => 'inclusion_links' + )); + } + + /** + * Make a toggle link with some text before it. + * + * @param string $key A unique key for this control - inserted in the classes. + * @return string + */ + public function make_toggle_links($key) { + return get_string($key, 'gradereport_singleview') . ' ' . + $this->make_toggle($key); + } + + /** + * Get the default heading for the screen. + * + * @return string + */ + public function heading() { + return get_string('pluginname', 'gradereport_singleview'); + } + + /** + * Override this to init the screen. + * + * @param boolean $selfitemisempty True if no item has been selected yet. + */ + public abstract function init($selfitemisempty = false); + + /** + * Get the type of items in the list. + * + * @return string + */ + public abstract function item_type(); + + /** + * Get the entire screen as a string. + * + * @return string + */ + public abstract function html(); + + /** + * Does this screen support paging? + * + * @return bool + */ + public function supports_paging() { + return true; + } + + /** + * Default pager + * + * @return string + */ + public function pager() { + return ''; + } + + /** + * Initialise the js for this screen. + */ + public function js() { + global $PAGE; + + $module = array( + 'name' => 'gradereport_singleview', + 'fullpath' => '/grade/report/singleview/js/singleview.js', + 'requires' => array('base', 'dom', 'event', 'event-simulate', 'io-base') + ); + + $PAGE->requires->js_init_call('M.gradereport_singleview.init', array(), false, $module); + } + + /** + * Process the data from a form submission. + * + * @param array $data + * @return array of warnings + */ + public function process($data) { + $warnings = array(); + + $fields = $this->definition(); + + foreach ($data as $varname => $throw) { + if (preg_match("/(\w+)_(\d+)_(\d+)/", $varname, $matches)) { + $itemid = $matches[2]; + $userid = $matches[3]; + } else { + continue; + } + + if (!in_array($matches[1], $fields)) { + continue; + } + + $gradeitem = grade_item::fetch(array( + 'id' => $itemid, 'courseid' => $this->courseid + )); + + if (!$gradeitem) { + continue; + } + + $grade = $this->fetch_grade_or_default($gradeitem, $userid); + + $classname = '\\gradereport_singleview\\local\\ui\\' . $matches[1]; + $element = new $classname($grade); + + $name = $element->get_name(); + $oldname = "old$name"; + + $posted = $data->$name; + + $format = $element->determine_format(); + + if ($format->is_textbox() and trim($data->$name) === '') { + $data->$name = null; + } + + // Same value; skip. + if (isset($data->$oldname) && $data->$oldname == $posted) { + continue; + } + + $msg = $element->set($posted); + + // Optional type. + if (!empty($msg)) { + $warnings[] = $msg; + } + } + + // Some post-processing. + $eventdata = new stdClass; + $eventdata->warnings = $warnings; + $eventdata->post_data = $data; + $eventdata->instance = $this; + + return $eventdata->warnings; + } + + /** + * By default there are no options. + * @return array + */ + public function options() { + return array(); + } + + /** + * Should we show the group selector? + * @return bool + */ + public function display_group_selector() { + return true; + } + + /** + * Should we show the next prev selector? + * @return bool + */ + public function supports_next_prev() { + return true; + } +} diff --git a/grade/report/singleview/screens/select/lib.php b/grade/report/singleview/classes/local/screen/select.php similarity index 66% rename from grade/report/singleview/screens/select/lib.php rename to grade/report/singleview/classes/local/screen/select.php index 6dd59169239..4554043d70f 100644 --- a/grade/report/singleview/screens/select/lib.php +++ b/grade/report/singleview/classes/local/screen/select.php @@ -1,5 +1,4 @@ item = $DB->get_record('course', array('id' => $this->courseid)); } + /** + * Get the type of items on this screen, not valid so return false. + * + * @return bool + */ + public function item_type() { + return false; + } + + /** + * Return the HTML for the page. + * + * @return string + */ public function html() { global $OUTPUT; @@ -45,11 +78,11 @@ class gradereport_singleview_select extends gradereport_singleview_screen { $types = gradereport_singleview::valid_screens(); foreach ($types as $type) { - $class = gradereport_singleview::classname($type); + $classname = "gradereport_singleview\\local\\screen\\${type}"; - $screen = new $class($this->courseid, null, $this->groupid); + $screen = new $classname($this->courseid, null, $this->groupid); - if (!$screen instanceof gradereport_selectable_items) { + if (!$screen instanceof selectable_items) { continue; } @@ -77,4 +110,12 @@ class gradereport_singleview_select extends gradereport_singleview_screen { return $html; } + + /** + * Should we show the next prev selector? + * @return bool + */ + public function supports_next_prev() { + return false; + } } diff --git a/grade/report/singleview/classes/local/screen/selectable_items.php b/grade/report/singleview/classes/local/screen/selectable_items.php new file mode 100644 index 00000000000..84967fc0571 --- /dev/null +++ b/grade/report/singleview/classes/local/screen/selectable_items.php @@ -0,0 +1,54 @@ +. + +/** + * Interface for a list of selectable things. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\screen; + +defined('MOODLE_INTERNAL') || die; + +/** + * Interface for a list of selectable things. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +interface selectable_items { + /** + * Get the description of this list + * @return string + */ + public function description(); + + /** + * Get the list of options to show. + * @return array + */ + public function options(); + + /** + * Get type of things in the list (gradeitem or user) + * @return string + */ + public function item_type(); +} diff --git a/grade/report/singleview/classes/local/screen/tablelike.php b/grade/report/singleview/classes/local/screen/tablelike.php new file mode 100644 index 00000000000..775f1457100 --- /dev/null +++ b/grade/report/singleview/classes/local/screen/tablelike.php @@ -0,0 +1,225 @@ +. + +/** + * The gradebook simple view - base class for the table + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\screen; + +use html_table; +use html_writer; +use stdClass; +use grade_item; +use grade_grade; +use gradereport_singleview\local\ui\bulk_insert; + +defined('MOODLE_INTERNAL') || die; + +/** + * The gradebook simple view - base class for the table + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class tablelike extends screen { + + /** @var array $headers A list of table headers */ + protected $headers = array(); + + /** @var array $initerrors A list of errors that mean we should not show the table */ + protected $initerrors = array(); + + /** @var array $definition Describes the columns in the table */ + protected $definition = array(); + + /** + * Format a row of the table + * + * @param mixed $item + * @return string + */ + public abstract function format_line($item); + + /** + * Get the table headers + * + * @return array + */ + public function headers() { + return $this->headers; + } + + /** + * Set the table headers + * + * @param array $overwrite New headers + * @return tablelike This + */ + public function set_headers($overwrite) { + $this->headers = $overwrite; + return $this; + } + + /** + * Get the list of errors + * + * @return array + */ + public function init_errors() { + return $this->initerrors; + } + + /** + * Set an error detected while building the page. + * + * @param string $mesg + */ + public function set_init_error($mesg) { + $this->initerrors[] = $mesg; + } + + /** + * Get the table definition + * + * @return array The definition. + */ + public function definition() { + return $this->definition; + } + + /** + * Set the table definition + * + * @param array $overwrite New definition + * @return tablelike This + */ + public function set_definition($overwrite) { + $this->definition = $overwrite; + return $this; + } + + /** + * Get the tabindex for the table in the page. + * + * @return int + */ + public function get_tabindex() { + return (count($this->definition()) * $this->total) + $this->index; + } + + /** + * Get a element to generate the HTML for this table row + * @param array $line This is a list of lines in the table (modified) + * @param grade_grade $grade The grade. + * @return string + */ + public function format_definition($line, $grade) { + foreach ($this->definition() as $i => $field) { + // Table tab index. + $tab = ($i * $this->total) + $this->index; + $classname = '\\gradereport_singleview\\local\\ui\\' . $field; + $html = new $classname($grade, $tab); + + if ($field == 'finalgrade' and !empty($this->structure)) { + $html .= $this->structure->get_grade_analysis_icon($grade); + } + + $line[] = $html; + } + return $line; + } + + /** + * Get the HTML for the whole table + * @return string + */ + public function html() { + global $OUTPUT; + + if (!empty($this->initerrors)) { + $warnings = ''; + foreach ($this->initerrors as $mesg) { + $warnings .= $OUTPUT->notification($mesg); + } + return $warnings; + } + $table = new html_table(); + + $table->head = $this->headers(); + + // To be used for extra formatting. + $this->index = 0; + $this->total = count($this->items); + + foreach ($this->items as $item) { + if ($this->index >= ($this->perpage * $this->page) && + $this->index < ($this->perpage * ($this->page + 1))) { + $table->data[] = $this->format_line($item); + } + $this->index++; + } + + $underlying = get_class($this); + + $data = new stdClass; + $data->table = $table; + $data->instance = $this; + + $buttonattr = array('class' => 'singleview_buttons submit'); + $buttonhtml = implode(' ', $this->buttons()); + + $buttons = html_writer::tag('div', $buttonhtml, $buttonattr); + + return html_writer::tag('form', + $buttons . html_writer::table($table) . $this->bulk_insert() . $buttons, + array('method' => 'POST') + ); + } + + /** + * Get the HTML for the bulk insert form + * + * @return string + */ + public function bulk_insert() { + return html_writer::tag( + 'div', + (new bulk_insert($this->item))->html(), + array('class' => 'singleview_bulk') + ); + } + + /** + * Get the buttons for saving changes. + * + * @return array + */ + public function buttons() { + $save = html_writer::empty_tag('input', array( + 'type' => 'submit', + 'value' => get_string('update'), + 'tabindex' => $this->get_tabindex(), + )); + + return array($save); + } +} diff --git a/grade/report/singleview/classes/local/screen/user.php b/grade/report/singleview/classes/local/screen/user.php new file mode 100644 index 00000000000..2b87e45e0c5 --- /dev/null +++ b/grade/report/singleview/classes/local/screen/user.php @@ -0,0 +1,336 @@ +. + +/** + * The user screen. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\screen; + +use grade_seq; +use gradereport_singleview; +use moodle_url; +use pix_icon; +use html_writer; +use gradereport_singleview\local\ui\range; +use gradereport_singleview\local\ui\bulk_insert; +use grade_item; +use grade_grade; + +defined('MOODLE_INTERNAL') || die; + +/** + * The user screen. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class user extends tablelike implements selectable_items { + + /** @var array $categories A cache for grade_item categories */ + private $categories = array(); + + /** @var int $requirespaging Do we have more items than the paging limit? */ + private $requirespaging = true; + + /** + * Get the description for the screen. + * + * @return string + */ + public function description() { + return get_string('gradeitems', 'grades'); + } + + /** + * Convert the list of items to a list of options. + * + * @return array + */ + public function options() { + $result = array(); + foreach ($this->items as $itemid => $item) { + $result[$itemid] = $item->get_name(); + } + return $result; + } + + /** + * Get the type of items on this screen. + * + * @return string + */ + public function item_type() { + return 'grade'; + } + + /** + * Should we show the group selector on this screen? + * + * @return bool + */ + public function display_group_selector() { + return false; + } + + /** + * Init the screen + * + * @param bool $selfitemisempty Have we selected an item yet? + */ + public function init($selfitemisempty = false) { + global $DB; + + if (!$selfitemisempty) { + $this->item = $DB->get_record('user', array('id' => $this->itemid)); + } + + $params = array('courseid' => $this->courseid); + + $seq = new grade_seq($this->courseid, true); + foreach ($seq->items as $key => $item) { + if (isset($item->itemmodule)) { + list($courseid, $cmid) = get_course_and_cm_from_instance($item->iteminstance, $item->itemmodule); + $seq->items[$key]->cmid = $cmid->id; + } + } + + $this->items = array(); + foreach ($seq->items as $itemid => $item) { + if (grade::filter($item)) { + $this->items[$itemid] = $item; + } + } + + $this->requirespaging = count($this->items) > $this->perpage; + + unset($seq); + + $this->setup_structure(); + + $this->definition = array( + 'finalgrade', 'feedback', 'override', 'exclude' + ); + $this->set_headers($this->original_headers()); + } + + /** + * Get the list of headers for the table. + * + * @return array List of headers + */ + public function original_headers() { + return array( + '', // For filter icon. + '', // For activity icon. + get_string('assessmentname', 'gradereport_singleview'), + get_string('gradecategory', 'grades'), + get_string('range', 'grades'), + get_string('grade', 'grades'), + get_string('feedback', 'grades'), + $this->make_toggle_links('override'), + $this->make_toggle_links('exclude') + ); + } + + /** + * Format each row of the table. + * + * @param grade_item $item + * @return string + */ + public function format_line($item) { + global $OUTPUT; + + $grade = $this->fetch_grade_or_default($item, $this->item->id); + $lockicon = ''; + + $lockeditem = $lockeditemgrade = 0; + if (!empty($grade->locked)) { + $lockeditem = 1; + } + if (!empty($grade->grade_item->locked)) { + $lockeditemgrade = 1; + } + // Check both grade and grade item. + if ($lockeditem || $lockeditemgrade) { + $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); + } + + $realmodid = ''; + if (isset($item->cmid)) { + $realmodid = $item->cmid; + } + $url = new moodle_url('/mod/' . $item->itemmodule . '/view.php', array('id' => $realmodid)); + $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name()); + $grade->label = $item->get_name(); + + $line = array( + $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', $iconstring)), + $this->format_icon($item) . $lockicon, + html_writer::link($url, $item->get_name()), + $this->category($item), + (new range($item)) + ); + return $this->format_definition($line, $grade); + } + + /** + * Helper to get the icon for an item. + * + * @param grade_item $item + * @return string + */ + private function format_icon($item) { + $element = array('type' => 'item', 'object' => $item); + return $this->structure->get_element_icon($element); + } + + /** + * Helper to get the category for an item. + * + * @param grade_item $item + * @return grade_category + */ + private function category($item) { + if (empty($item->categoryid)) { + + if ($item->itemtype == 'course') { + return $this->course->fullname; + } + + global $DB; + + $params = array('id' => $item->iteminstance); + $elem = $DB->get_record('grade_categories', $params); + + return $elem->fullname; + } + + if (!isset($this->categories[$item->categoryid])) { + $category = $item->get_parent_category(); + + $this->categories[$category->id] = $category; + } + + return $this->categories[$item->categoryid]->get_name(); + } + + /** + * Get the heading for the page. + * + * @return string + */ + public function heading() { + return fullname($this->item); + } + + /** + * Default pager + * + * @return string + */ + public function pager() { + if (!$this->supports_paging()) { + return ''; + } + + global $OUTPUT; + + return $OUTPUT->paging_bar( + count($this->items), $this->page, $this->perpage, + new moodle_url('/grade/report/singleview/index.php', array( + 'perpage' => $this->perpage, + 'id' => $this->courseid, + 'groupid' => $this->groupid, + 'itemid' => $this->itemid, + 'item' => 'user' + )) + ); + } + + /** + * Does this page require paging? + * + * @return bool + */ + public function supports_paging() { + return $this->requirespaging; + } + + + /** + * Process the data from the form. + * + * @param array $data + * @return array of warnings + */ + public function process($data) { + $bulk = new bulk_insert($this->item); + // Bulk insert messages the data to be passed in + // ie: for all grades of empty grades apply the specified value. + if ($bulk->is_applied($data)) { + $filter = $bulk->get_type($data); + $insertvalue = $bulk->get_insert_value($data); + // Appropriately massage data that may not exist. + + $userid = $this->item->id; + + foreach ($this->items as $gradeitemid => $gradeitem) { + $null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : ''; + $field = "finalgrade_{$gradeitem->id}_{$gradeitemid}"; + if (isset($data->$field)) { + continue; + } + + $grade = grade_grade::fetch(array( + 'itemid' => $gradeitem->id, + 'userid' => $userid + )); + + $data->$field = empty($grade) ? $null : $grade->finalgrade; + $data->{"old$field"} = $data->$field; + } + + foreach ($data as $varname => $value) { + if (!preg_match('/^finalgrade_(\d+)_/', $varname, $matches)) { + continue; + } + + $gradeitem = grade_item::fetch(array( + 'courseid' => $this->courseid, + 'id' => $matches[1] + )); + + $isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE); + + $empties = (trim($value) === '' or ($isscale and $value == -1)); + + if ($filter == 'all' or $empties) { + $data->$varname = ($isscale and empty($insertvalue)) ? + -1 : $insertvalue; + } + } + } + + return parent::process($data); + } +} diff --git a/grade/report/singleview/classes/local/ui/attribute_format.php b/grade/report/singleview/classes/local/ui/attribute_format.php new file mode 100644 index 00000000000..bbf96e28cb2 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/attribute_format.php @@ -0,0 +1,52 @@ +. + +/** + * Class that builds an element tree that can be converted to a string + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Class that builds an element tree that can be converted to a string + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class attribute_format { + + /** + * Used to convert this class to an "element" which can be converted to a string. + * @return element + */ + abstract public function determine_format(); + + /** + * Convert this to an element and then to a string + * @return string + */ + public function __toString() { + return $this->determine_format()->html(); + } +} + diff --git a/grade/report/singleview/classes/local/ui/be_checked.php b/grade/report/singleview/classes/local/ui/be_checked.php new file mode 100644 index 00000000000..03b1bb72b84 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/be_checked.php @@ -0,0 +1,42 @@ +. + +/** + * Is this thing checked? + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Is this thing checked? + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +interface be_checked { + /** + * Return true if this is checked. + * @return bool + */ + public function is_checked(); +} diff --git a/grade/report/singleview/classes/local/ui/be_disabled.php b/grade/report/singleview/classes/local/ui/be_disabled.php new file mode 100644 index 00000000000..28790f37584 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/be_disabled.php @@ -0,0 +1,40 @@ +. + +/** + * be_disabled interface. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Simple interface implemented to add behaviour that an element can be checked to see + * if it should be disabled. + */ +interface be_disabled { + /** + * Am I disabled ? + * + * @return bool + */ + public function is_disabled(); +} diff --git a/grade/report/singleview/classes/local/ui/bulk_insert.php b/grade/report/singleview/classes/local/ui/bulk_insert.php new file mode 100644 index 00000000000..57d45c45a83 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/bulk_insert.php @@ -0,0 +1,116 @@ +. + +/** + * Checkbox element used for bulk inserting values in the gradebook. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +use html_writer; + +defined('MOODLE_INTERNAL') || die; + +/** + * Checkbox element used for bulk inserting values in the gradebook. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class bulk_insert extends element { + + /** + * Constructor + * + * @param mixed $item The grade item or user. + */ + public function __construct($item) { + $this->name = 'bulk_' . $item->id; + $this->applyname = $this->name_for('apply'); + $this->selectname = $this->name_for('type'); + $this->insertname = $this->name_for('value'); + } + + /** + * Is this checkbox checked? + * + * @param array $data The form data + * @return bool + */ + public function is_applied($data) { + return isset($data->{$this->applyname}); + } + + /** + * Get the type of this input (user or grade) + * + * @param array $data The form data + * @return string + */ + public function get_type($data) { + return $data->{$this->selectname}; + } + + /** + * Get the value from either the user or grade. + * + * @param array $data The form data + * @return string + */ + public function get_insert_value($data) { + return $data->{$this->insertname}; + } + + /** + * Generate the html for this form element. + * + * @return string HTML + */ + public function html() { + $insertgrade = get_string('bulkinsertgrade', 'gradereport_singleview'); + $insertappliesto = get_string('bulkappliesto', 'gradereport_singleview'); + + $apply = html_writer::checkbox($this->applyname, 1, false, $insertgrade); + $insertoptions = array( + 'all' => get_string('all_grades', 'gradereport_singleview'), + 'blanks' => get_string('blanks', 'gradereport_singleview') + ); + + $select = html_writer::select( + $insertoptions, $this->selectname, 'blanks', false + ); + + $label = html_writer::tag('label', $insertappliesto); + $text = new text_attribute($this->insertname, "0", 'bulk'); + return implode(' ', array($apply, $text->html(), $label, $select)); + } + + /** + * This form element has 3 elements with different suffixes. + * Generate the name with the suffix. + * + * @param string $extend The suffix. + * @return string + */ + private function name_for($extend) { + return "{$this->name}_$extend"; + } +} diff --git a/grade/report/singleview/classes/local/ui/checkbox_attribute.php b/grade/report/singleview/classes/local/ui/checkbox_attribute.php new file mode 100644 index 00000000000..1357974a9da --- /dev/null +++ b/grade/report/singleview/classes/local/ui/checkbox_attribute.php @@ -0,0 +1,122 @@ +. + +/** + * A checkbox ui element. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace gradereport_singleview\local\ui; + +use html_writer; + +defined('MOODLE_INTERNAL') || die; + +/** + * A checkbox ui element. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class checkbox_attribute extends element { + + /** @var bool $ischecked Is it checked? */ + private $ischecked; + + /** @var int $tabindex The tab index for this form element. */ + private $tabindex; + + /** + * Constructor + * + * @param string $name The element name + * @param string $label The label for the form element + * @param bool $ischecked Is this thing on? + * @param int $tabindex The tab index for the form element. + * @param int $locked Is this element locked either 0 or a time. + */ + public function __construct($name, $label, $ischecked = false, $tabindex = null, $locked=0) { + $this->ischecked = $ischecked; + $this->tabindex = $tabindex; + $this->locked = $locked; + parent::__construct($name, 1, $label); + } + + /** + * Nasty function allowing checkbox logic to escape the class. + * @return bool + */ + public function is_checkbox() { + return true; + } + + /** + * Generate the HTML + * + * @return string + */ + public function html() { + + $attributes = array( + 'type' => 'checkbox', + 'name' => $this->name, + 'value' => 1, + 'id' => $this->name + ); + + // UCSB fixed user should not be able to override locked grade. + if ( $this->locked) { + $attributes['disabled'] = 'DISABLED'; + } + + $alt = array( + 'type' => 'hidden', + 'name' => $this->name, + 'value' => 0 + ); + + $hidden = array( + 'type' => 'hidden', + 'name' => 'old' . $this->name + ); + + if (!empty($this->tabindex)) { + $attributes['tabindex'] = $this->tabindex; + } + + if ($this->ischecked) { + $attributes['checked'] = 'CHECKED'; + $hidden['value'] = 1; + } + + $type = "override"; + if (preg_match("/^exclude/", $this->name)) { + $type = "exclude"; + } + + return ( + html_writer::empty_tag('input', $alt) . + html_writer::tag('label', + get_string($type . 'for', 'gradereport_singleview', $this->label), + array('for' => $this->name, 'class' => 'accesshide')) . + html_writer::empty_tag('input', $attributes) . + html_writer::empty_tag('input', $hidden) + ); + } +} diff --git a/grade/report/singleview/classes/local/ui/dropdown_attribute.php b/grade/report/singleview/classes/local/ui/dropdown_attribute.php new file mode 100644 index 00000000000..af70f02b4c0 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/dropdown_attribute.php @@ -0,0 +1,101 @@ +. + +/** + * Drop down list (select list) element + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Drop down list (select list) element + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class dropdown_attribute extends element { + + /** @var string $selected Who is selected ? */ + private $selected; + + /** @var array $options List of options ? */ + private $options; + + /** @var bool $isdisabled Is this input disabled. */ + private $isdisabled; + + /** + * Constructor + * + * @param string $name The first bit of the name of this input. + * @param array $options The options list for this select. + * @param string $label The form label for this input. + * @param string $selected The name of the selected item in this input. + * @param bool $isdisabled Are we disabled? + * @param int $tabindex The tab index for this field + */ + public function __construct($name, $options, $label, $selected = '', $isdisabled = false, $tabindex = null) { + $this->selected = $selected; + $this->options = $options; + $this->tabindex = $tabindex; + $this->isdisabled = $isdisabled; + parent::__construct($name, $selected, $label); + } + + /** + * Nasty function spreading dropdown logic around. + * + * @return bool + */ + public function is_dropdown() { + return true; + } + + /** + * Render this element as html. + * + * @return string + */ + public function html() { + $old = array( + 'type' => 'hidden', + 'name' => 'old' . $this->name, + 'value' => $this->selected + ); + + $attributes = array(); + if (!empty($this->tabindex)) { + $attributes['tabindex'] = $this->tabindex; + } + + if (!empty($this->isdisabled)) { + $attributes['disabled'] = 'DISABLED'; + } + + $select = html_writer::select( + $this->options, $this->name, $this->selected, false, $attributes + ); + + return ($select . html_writer::empty_tag('input', $old)); + } +} diff --git a/grade/report/singleview/classes/local/ui/element.php b/grade/report/singleview/classes/local/ui/element.php new file mode 100644 index 00000000000..22b901b2588 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/element.php @@ -0,0 +1,89 @@ +. + +/** + * UI Element for an excluded grade_grade. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * UI Element for an excluded grade_grade. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class element { + + /** @var string $name The first bit of the name for this input. */ + public $name; + + /** @var string $value The value for this input. */ + public $value; + + /** @var string $label The form label for this input. */ + public $label; + + /** + * Constructor + * + * @param string $name The first bit of the name for this input + * @param string $value The value for this input + * @param string $label The label for this form field + */ + public function __construct($name, $value, $label) { + $this->name = $name; + $this->value = $value; + $this->label = $label; + } + + /** + * Nasty function used for spreading checkbox logic all around + * @return bool + */ + public function is_checkbox() { + return false; + } + + /** + * Nasty function used for spreading textbox logic all around + * @return bool + */ + public function is_textbox() { + return false; + } + + /** + * Nasty function used for spreading dropdown logic all around + * @return bool + */ + public function is_dropdown() { + return false; + } + + /** + * Return the HTML + * @return string + */ + abstract public function html(); +} diff --git a/grade/report/singleview/classes/local/ui/empty_element.php b/grade/report/singleview/classes/local/ui/empty_element.php new file mode 100644 index 00000000000..32ff3ce57fb --- /dev/null +++ b/grade/report/singleview/classes/local/ui/empty_element.php @@ -0,0 +1,59 @@ +. + +/** + * Element that just generates some text. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Element that just generates some text. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class empty_element extends element { + + /** + * Constructor + * + * @param string $msg The text + */ + public function __construct($msg = null) { + if (is_null($msg)) { + $this->text = ' '; + } else { + $this->text = $msg; + } + } + + /** + * Generate the html (simple case) + * + * @return string HTML + */ + public function html() { + return $this->text; + } +} diff --git a/grade/report/singleview/classes/local/ui/exclude.php b/grade/report/singleview/classes/local/ui/exclude.php new file mode 100644 index 00000000000..03e4f6ee14a --- /dev/null +++ b/grade/report/singleview/classes/local/ui/exclude.php @@ -0,0 +1,110 @@ +. + +/** + * Class that represents the exclude checkbox on a grade_grade. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Class that represents the exclude checkbox on a grade_grade. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class exclude extends grade_attribute_format implements be_checked { + + /** @var string $name The name of the input */ + public $name = 'exclude'; + + /** + * Is it checked? + * + * @return bool + */ + public function is_checked() { + return $this->grade->is_excluded(); + } + + /** + * Generate the element used to render the UI + * + * @return element + */ + public function determine_format() { + return new checkbox_attribute( + $this->get_name(), + $this->get_label(), + $this->is_checked() + ); + } + + /** + * Get the label for the form input + * + * @return string + */ + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + + /** + * Set the value that was changed in the form. + * + * @param string $value The value to set. + * @return mixed string|bool An error message or false. + */ + public function set($value) { + if (empty($this->grade->id)) { + if (empty($value)) { + return false; + } + + $gradeitem = $this->grade->grade_item; + + // Fill in arbitrary grade to be excluded. + $gradeitem->update_final_grade( + $this->grade->userid, null, 'singleview', null, FORMAT_MOODLE + ); + + $gradeparams = array( + 'userid' => $this->grade->userid, + 'itemid' => $this->grade->itemid + ); + + $this->grade = grade_grade::fetch($gradeparams); + $this->grade->grade_item = $gradeitem; + } + + $state = $value == 0 ? false : true; + + $this->grade->set_excluded($state); + + $this->grade->grade_item->get_parent_category()->force_regrading(); + return false; + } +} diff --git a/grade/report/singleview/classes/local/ui/feedback.php b/grade/report/singleview/classes/local/ui/feedback.php new file mode 100644 index 00000000000..a41e0f20d71 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/feedback.php @@ -0,0 +1,123 @@ +. + +/** + * Class used to render a feedback input box. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Class used to render a feedback input box. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class feedback extends grade_attribute_format implements unique_value, be_disabled { + + /** @var string $name Name of this input */ + public $name = 'feedback'; + + /** + * Get the value for this input. + * + * @return string The value + */ + public function get_value() { + return $this->grade->feedback ? $this->grade->feedback : ''; + } + + /** + * Get the string to use in the label for this input. + * + * @return string The label text + */ + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + + /** + * Determine if this input should be disabled based on the other settings. + * + * @return boolean Should this input be disabled when the page loads. + */ + public function is_disabled() { + $locked = 0; + $gradeitemlocked = 0; + $overridden = 0; + /* Disable editing if grade item or grade score is locked + * if any of these items are set, then we will disable editing + * at some point, we might want to show the reason for the lock + * this code could be simplified, but its more readable for steve's little mind + */ + if (!empty($this->grade->locked)) { + $locked = 1; + } + if (!empty($this->grade->grade_item->locked)) { + $gradeitemlocked = 1; + } + if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) { + $overridden = 1; + } + return ($locked || $gradeitemlocked || $overridden); + } + + /** + * Create a text_attribute for this ui element. + * + * @return text_attribute + */ + public function determine_format() { + return new text_attribute( + $this->get_name(), + $this->get_value(), + $this->get_label(), + $this->is_disabled(), + $this->get_tabindex() + ); + } + + /** + * Update the value for this input. + * + * @param string $value The new feedback value. + * @return string Any error message + */ + public function set($value) { + $finalgrade = false; + $trimmed = trim($value); + if (empty($trimmed)) { + $feedback = null; + } else { + $feedback = $value; + } + + $this->grade->grade_item->update_final_grade( + $this->grade->userid, $finalgrade, 'singleview', + $feedback, FORMAT_MOODLE + ); + } +} diff --git a/grade/report/singleview/classes/local/ui/finalgrade.php b/grade/report/singleview/classes/local/ui/finalgrade.php new file mode 100644 index 00000000000..03b7bf0c43f --- /dev/null +++ b/grade/report/singleview/classes/local/ui/finalgrade.php @@ -0,0 +1,181 @@ +. + +/** + * UI element representing the finalgrade column. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * UI element representing the finalgrade column. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class finalgrade extends grade_attribute_format implements unique_value, be_disabled { + + /** @var string $name Name of this input */ + public $name = 'finalgrade'; + + /** + * Get the value for this input. + * + * @return string The value based on the grade_grade. + */ + public function get_value() { + $this->label = $this->grade->grade_item->itemname; + // Manual item raw grade support. + $val = $this->grade->grade_item->is_manual_item() && (!is_null($this->grade->rawgrade)) ? + $this->grade->rawgrade : $this->grade->finalgrade; + + if ($this->grade->grade_item->scaleid) { + return $val ? (int)$val : -1; + } else { + return $val ? format_float($val, $this->grade->grade_item->get_decimals()) : ''; + } + } + + /** + * Get the label for this input. + * + * @return string The label for this form input. + */ + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + + /** + * Is this input field disabled. + * + * @return bool Set disabled on this input or not. + */ + public function is_disabled() { + $locked = 0; + $gradeitemlocked = 0; + $overridden = 0; + + // Disable editing if grade item or grade score is locked + // if any of these items are set, then we will disable editing + // at some point, we might want to show the reason for the lock + // this code could be simplified, but its more readable for steve's little mind. + + if (!empty($this->grade->locked)) { + $locked = 1; + } + if (!empty($this->grade->grade_item->locked)) { + $gradeitemlocked = 1; + } + if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) { + $overridden = 1; + } + return ($locked || $gradeitemlocked || $overridden); + } + + /** + * Create the element for this column. + * + * @return element + */ + public function determine_format() { + if ($this->grade->grade_item->load_scale()) { + $scale = $this->grade->grade_item->load_scale(); + + $options = array(-1 => get_string('nograde')); + + foreach ($scale->scale_items as $i => $name) { + $options[$i + 1] = $name; + } + + return new dropdown_attribute( + $this->get_name(), + $options, + $this->get_value(), + $this->get_label(), + $this->is_disabled(), + $this->get_tabindex() + ); + } else { + return new text_attribute( + $this->get_name(), + $this->get_value(), + $this->get_label(), + $this->is_disabled(), + $this->get_tabindex() + ); + } + } + + /** + * Save the altered value for this field. + * + * @param string $value The new value. + * @return string Any error string + */ + public function set($value) { + global $DB; + + $userid = $this->grade->userid; + $gradeitem = $this->grade->grade_item; + + $feedback = false; + $feedbackformat = false; + if ($gradeitem->gradetype == GRADE_TYPE_SCALE) { + if ($value == -1) { + $finalgrade = null; + } else { + $finalgrade = $value; + } + } else { + $finalgrade = unformat_float($value); + } + + $errorstr = ''; + if ($finalgrade) { + $bounded = $gradeitem->bounded_grade($finalgrade); + if ($bounded > $finalgrade) { + $errorstr = 'lessthanmin'; + } else if ($bounded < $finalgrade) { + $errorstr = 'morethanmax'; + } + } + + if ($errorstr) { + $user = $DB->get_record('user', array('id' => $userid), 'id, firstname, alternatename, lastname'); + $gradestr = new stdClass; + if (!empty($user->alternatename)) { + $gradestr->username = $user->alternatename . ' (' . $user->firstname . ') ' . $user->lastname; + } else { + $gradestr->username = $user->firstname . ' ' . $user->lastname; + } + $gradestr->itemname = $this->grade->grade_item->get_name(); + $errorstr = get_string($errorstr, 'grades', $gradestr); + } + + $gradeitem->update_final_grade($userid, $finalgrade, 'singleview', $feedback, FORMAT_MOODLE); + return $errorstr; + } +} diff --git a/grade/report/singleview/classes/local/ui/grade_attribute_format.php b/grade/report/singleview/classes/local/ui/grade_attribute_format.php new file mode 100644 index 00000000000..dcaebcd576f --- /dev/null +++ b/grade/report/singleview/classes/local/ui/grade_attribute_format.php @@ -0,0 +1,87 @@ +. + +/** + * Abstract class for a form element representing something about a grade_grade. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Abstract class for a form element representing something about a grade_grade. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class grade_attribute_format extends attribute_format implements unique_name, tabbable { + + /** @var string $name The first part of the name attribute of the form input */ + public $name; + + /** @var string $label The label of the input */ + public $label; + + /** @var grade_grade $grade The grade_grade of the input */ + public $grade; + + /** @var int $tabindex The tabindex of the input */ + public $tabindex; + + /** + * Constructor + * + * @param grade_grade $grade The grade_grade we are editing. + * @param int $tabindex The tabindex for the input. + */ + public function __construct($grade = 0, $tabindex = 1) { + + $this->grade = $grade; + $this->tabindex = $tabindex; + } + + /** + * Get a unique name for this form input + * + * @return string The form input name attribute. + */ + public function get_name() { + return "{$this->name}_{$this->grade->itemid}_{$this->grade->userid}"; + } + + /** + * Get the tabindex for this form input + * + * @return int The tab index + */ + public function get_tabindex() { + return isset($this->tabindex) ? $this->tabindex : null; + } + + /** + * Should be overridden by the child class to save the value returned in this input. + * + * @param string $value The value from the form. + * @return string Any error message + */ + public abstract function set($value); +} diff --git a/grade/report/singleview/classes/local/ui/override.php b/grade/report/singleview/classes/local/ui/override.php new file mode 100644 index 00000000000..64b829251fe --- /dev/null +++ b/grade/report/singleview/classes/local/ui/override.php @@ -0,0 +1,113 @@ +. + +/** + * An override grade checkbox element + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * An override grade checkbox element + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class override extends grade_attribute_format implements be_checked, be_disabled { + + /** @var string $name The name for this input */ + public $name = 'override'; + + /** + * Is this input checked + * + * @return bool + */ + public function is_checked() { + return $this->grade->is_overridden(); + } + + /** + * Is this input disabled + * + * @return bool + */ + public function is_disabled() { + $lockedgrade = $lockedgradeitem = 0; + if (!empty($this->grade->locked)) { + $lockedgrade = 1; + } + if (!empty($this->grade->grade_item->locked)) { + $lockedgradeitem = 1; + } + return ($lockedgrade || $lockedgradeitem); + } + + /** + * Get the label for this form element. + * + * @return string + */ + public function get_label() { + if (!isset($this->grade->label)) { + $this->grade->label = ''; + } + return $this->grade->label; + } + + /** + * Generate the element for this form input. + * + * @return element + */ + public function determine_format() { + if (!$this->grade->grade_item->is_overridable_item()) { + return new empty_element(); + } + return new checkbox_attribute( + $this->get_name(), + $this->get_label(), + $this->is_checked(), + null, + $this->is_disabled() + ); + } + + /** + * Save the modified value of this form element. + * + * @param string $value The new value to set + * @return mixed string|false Any error message + */ + public function set($value) { + if (empty($this->grade->id)) { + return false; + } + + $state = $value == 0 ? false : true; + + $this->grade->set_overridden($state); + $this->grade->grade_item->get_parent_category()->force_regrading(); + return false; + } +} diff --git a/grade/report/singleview/classes/local/ui/range.php b/grade/report/singleview/classes/local/ui/range.php new file mode 100644 index 00000000000..aa77f2e56da --- /dev/null +++ b/grade/report/singleview/classes/local/ui/range.php @@ -0,0 +1,59 @@ +. + +/** + * UI element that generates a min/max range (text only). + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * UI element that generates a grade_item min/max range (text only). + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class range extends attribute_format { + + /** + * Constructor + * @param grade_item $item The grade item + */ + public function __construct($item) { + $this->item = $item; + } + + /** + * Build this UI element. + * + * @return element + */ + public function determine_format() { + $decimals = $this->item->get_decimals(); + + $min = format_float($this->item->grademin, $decimals); + $max = format_float($this->item->grademax, $decimals); + + return new empty_element("$min - $max"); + } +} diff --git a/grade/report/singleview/classes/local/ui/tabbable.php b/grade/report/singleview/classes/local/ui/tabbable.php new file mode 100644 index 00000000000..d90493150a2 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/tabbable.php @@ -0,0 +1,43 @@ +. + +/** + * The gradebook simple view - UI factory + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * This element has a tabindex + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +interface tabbable { + /** + * Get the tabindex for this element + * @return int + */ + public function get_tabindex(); +} + diff --git a/grade/report/singleview/classes/local/ui/text_attribute.php b/grade/report/singleview/classes/local/ui/text_attribute.php new file mode 100644 index 00000000000..8c86349de4d --- /dev/null +++ b/grade/report/singleview/classes/local/ui/text_attribute.php @@ -0,0 +1,108 @@ +. + +/** + * UI element for a text input field. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +use html_writer; +defined('MOODLE_INTERNAL') || die; + +/** + * UI element for a text input field. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class text_attribute extends element { + + /** @var bool $isdisabled Is this input disabled? */ + private $isdisabled; + + /** @var int $tabindex Tabindex value for this input. */ + private $tabindex; + + /** + * Constructor + * + * @param string $name The input name (the first bit) + * @param string $value The input initial value. + * @param string $label The label for this input field. + * @param bool $isdisabled Is this input disabled. + * @param int $tabindex Tab index for this input. + */ + public function __construct($name, $value, $label, $isdisabled = false, $tabindex = null) { + $this->isdisabled = $isdisabled; + $this->tabindex = $tabindex; + parent::__construct($name, $value, $label); + } + + /** + * Nasty function allowing custom textbox behaviour outside the class. + * @return bool Is this a textbox. + */ + public function is_textbox() { + return true; + } + + /** + * Render the html for this field. + * @return string The HTML. + */ + public function html() { + $attributes = array( + 'type' => 'text', + 'name' => $this->name, + 'value' => $this->value, + 'id' => $this->name + ); + + if (!empty($this->tabindex)) { + $attributes['tabindex'] = $this->tabindex; + } + if ($this->isdisabled) { + $attributes['disabled'] = 'DISABLED'; + } + + $hidden = array( + 'type' => 'hidden', + 'name' => 'old' . $this->name, + 'value' => $this->value + ); + + $label = ''; + if (preg_match("/^feedback/", $this->name)) { + $labeltitle = get_string('feedbackfor', 'gradereport_singleview', $this->label); + $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); + } else if (preg_match("/^finalgrade/", $this->name)) { + $labeltitle = get_string('gradefor', 'gradereport_singleview', $this->label); + $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); + } + + return ( + $label . + html_writer::empty_tag('input', $attributes) . + html_writer::empty_tag('input', $hidden) + ); + } +} diff --git a/grade/report/singleview/classes/local/ui/unique_name.php b/grade/report/singleview/classes/local/ui/unique_name.php new file mode 100644 index 00000000000..00b7d7345c0 --- /dev/null +++ b/grade/report/singleview/classes/local/ui/unique_name.php @@ -0,0 +1,43 @@ +. + +/** + * A form element with a name field. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * A form element with a name field. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +interface unique_name { + + /** + * Get the name for this form element + * @return string + */ + public function get_name(); +} diff --git a/grade/report/singleview/classes/local/ui/unique_value.php b/grade/report/singleview/classes/local/ui/unique_value.php new file mode 100644 index 00000000000..a3e3ffd2dfa --- /dev/null +++ b/grade/report/singleview/classes/local/ui/unique_value.php @@ -0,0 +1,42 @@ +. + +/** + * The gradebook simple view - UI factory + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace gradereport_singleview\local\ui; + +defined('MOODLE_INTERNAL') || die; + +/** + * Simple interface for an item with a value. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +interface unique_value { + /** + * Get the value for this item. + * @return string + */ + public function get_value(); +} diff --git a/grade/report/singleview/classes/uilib.php b/grade/report/singleview/classes/uilib.php deleted file mode 100644 index a91eefd2a1a..00000000000 --- a/grade/report/singleview/classes/uilib.php +++ /dev/null @@ -1,648 +0,0 @@ -. - -/** - * The gradebook simple view - UI factory - * - * @package gradereport_singleview - * @copyright 2014 Moodle Pty Ltd (http://moodle.com) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -abstract class gradereport_singleview_ui_factory { - public abstract function create($type); - - protected function wrap($class) { - return new gradereport_singleview_factory_class_wrap($class); - } -} - -class gradereport_singleview_grade_ui_factory extends gradereport_singleview_ui_factory { - public function create($type) { - return $this->wrap("gradereport_singleview_{$type}_ui"); - } -} - -class gradereport_singleview_factory_class_wrap { - public function __construct($class) { - $this->class = $class; - } - - public function format() { - $args = func_get_args(); - - $reflect = new ReflectionClass($this->class); - return $reflect->newInstanceArgs($args); - } -} - -abstract class gradereport_singleview_ui_element { - public $name; - public $value; - public $label; - - public function __construct($name, $value, $label) { - $this->name = $name; - $this->value = $value; - $this->label = $label; - } - - public function is_checkbox() { - return false; - } - - public function is_textbox() { - return false; - } - - public function is_dropdown() { - return false; - } - - abstract public function html(); -} - -class gradereport_singleview_empty_element extends gradereport_singleview_ui_element { - public function __construct($msg = null) { - if (is_null($msg)) { - $this->text = get_string('notavailable', 'gradereport_singleview'); - } else { - $this->text = $msg; - } - } - - public function html() { - return $this->text; - } -} - -class gradereport_singleview_text_attribute extends gradereport_singleview_ui_element { - private $isdisabled; - private $tabindex; - - public function __construct($name, $value, $label, $isdisabled = false, $tabindex = null) { - $this->isdisabled = $isdisabled; - $this->tabindex = $tabindex; - parent::__construct($name, $value, $label); - } - - public function is_textbox() { - return true; - } - - public function html() { - $attributes = array( - 'type' => 'text', - 'name' => $this->name, - 'value' => $this->value, - 'id' => $this->name - ); - - if (!empty($this->tabindex)) { - $attributes['tabindex'] = $this->tabindex; - } - if ($this->isdisabled) { - $attributes['disabled'] = 'DISABLED'; - } - - $hidden = array( - 'type' => 'hidden', - 'name' => 'old' . $this->name, - 'value' => $this->value - ); - - $label = ''; - if (preg_match("/^feedback/", $this->name)) { - $labeltitle = get_string('feedbackfor', 'gradereport_singleview', $this->label); - $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); - } else if (preg_match("/^finalgrade/", $this->name)) { - $labeltitle = get_string('gradefor', 'gradereport_singleview', $this->label); - $label = html_writer::tag('label', $labeltitle, array('for' => $this->name, 'class' => 'accesshide')); - } - - return ( - $label . - html_writer::empty_tag('input', $attributes) . - html_writer::empty_tag('input', $hidden) - ); - } -} - -class gradereport_singleview_checkbox_attribute extends gradereport_singleview_ui_element { - private $ischecked; - private $tabindex; - - public function __construct($name, $label, $ischecked = false, $tabindex = null, $locked=0) { - $this->ischecked = $ischecked; - $this->tabindex = $tabindex; - $this->locked = $locked; - parent::__construct($name, 1, $label); - } - - public function is_checkbox() { - return true; - } - - public function html() { - - $attributes = array( - 'type' => 'checkbox', - 'name' => $this->name, - 'value' => 1, - 'id' => $this->name - ); - - // UCSB fixed user should not be able to override locked grade. - if ( $this->locked) { - $attributes['disabled'] = 'DISABLED'; - } - - $alt = array( - 'type' => 'hidden', - 'name' => $this->name, - 'value' => 0 - ); - - $hidden = array( - 'type' => 'hidden', - 'name' => 'old' . $this->name - ); - - if (!empty($this->tabindex)) { - $attributes['tabindex'] = $this->tabindex; - } - - if ($this->ischecked) { - $attributes['checked'] = 'CHECKED'; - $hidden['value'] = 1; - } - - $type = "override"; - if (preg_match("/^exclude/", $this->name)) { - $type = "exclude"; - } - - return ( - html_writer::empty_tag('input', $alt) . - html_writer::tag('label', get_string($type . 'for', 'gradereport_singleview', $this->label), array('for' => $this->name, 'class' => 'accesshide')) . - html_writer::empty_tag('input', $attributes) . - html_writer::empty_tag('input', $hidden) - ); - } -} - -class gradereport_singleview_dropdown_attribute extends gradereport_singleview_ui_element { - private $selected; - private $options; - private $isdisabled; - - public function __construct($name, $options, $label, $selected = '', $isdisabled = false, $tabindex = null) { - $this->selected = $selected; - $this->options = $options; - $this->tabindex = $tabindex; - $this->isdisabled = $isdisabled; - parent::__construct($name, $selected, $label); - } - - public function is_dropdown() { - return true; - } - - public function html() { - $old = array( - 'type' => 'hidden', - 'name' => 'old' . $this->name, - 'value' => $this->selected - ); - - $attributes = array(); - if (!empty($this->tabindex)) { - $attributes['tabindex'] = $this->tabindex; - } - - if (!empty($this->isdisabled)) { - $attributes['disabled'] = 'DISABLED'; - } - - $select = html_writer::select( - $this->options, $this->name, $this->selected, false, $attributes - ); - - return ($select . html_writer::empty_tag('input', $old)); - } -} - -abstract class gradereport_singleview_grade_attribute_format extends gradereport_singleview_attribute_format implements unique_name, tabbable { - public $name; - public $label; - - public function __construct() { - $args = func_get_args(); - - $this->get_arg_or_nothing($args, 0, 'grade'); - $this->get_arg_or_nothing($args, 1, 'tabindex'); - } - - public function get_name() { - return "{$this->name}_{$this->grade->itemid}_{$this->grade->userid}"; - } - - public function get_tabindex() { - return isset($this->tabindex) ? $this->tabindex : null; - } - - private function get_arg_or_nothing($args, $index, $field) { - if (isset($args[$index])) { - $this->$field = $args[$index]; - } - } - - public abstract function set($value); -} - -interface unique_name { - public function get_name(); -} - -interface unique_value { - public function get_value(); -} - -interface be_disabled { - public function is_disabled(); -} - -interface be_checked { - public function is_checked(); -} - -interface tabbable { - public function get_tabindex(); -} - -class gradereport_singleview_bulk_insert_ui extends gradereport_singleview_ui_element { - public function __construct($item) { - $this->name = 'bulk_' . $item->id; - $this->applyname = $this->name_for('apply'); - $this->selectname = $this->name_for('type'); - $this->insertname = $this->name_for('value'); - } - - public function is_applied($data) { - return isset($data->{$this->applyname}); - } - - public function get_type($data) { - return $data->{$this->selectname}; - } - - public function get_insert_value($data) { - return $data->{$this->insertname}; - } - - public function html() { - $insertgrade = get_string('bulkinsertgrade', 'gradereport_singleview'); - $insertappliesto = get_string('bulkappliesto', 'gradereport_singleview'); - - $apply = html_writer::checkbox($this->applyname, 1, false, $insertgrade); - $insertoptions = array( - 'all' => get_string('all_grades', 'gradereport_singleview'), - 'blanks' => get_string('blanks', 'gradereport_singleview') - ); - - $select = html_writer::select( - $insertoptions, $this->selectname, 'blanks', false - ); - - $label = html_writer::tag('label', $insertappliesto); - $text = new gradereport_singleview_text_attribute($this->insertname, "0", 'bulk'); - return implode(' ', array($apply, $text->html(), $label, $select)); - } - - private function name_for($extend) { - return "{$this->name}_$extend"; - } -} - -abstract class gradereport_singleview_attribute_format { - abstract public function determine_format(); - - public function __toString() { - return $this->determine_format()->html(); - } -} - -class gradereport_singleview_finalgrade_ui extends gradereport_singleview_grade_attribute_format implements unique_value, be_disabled { - - public $name = 'finalgrade'; - - public function get_value() { - $this->label = $this->grade->grade_item->itemname; - // Manual item raw grade support. - $val = $this->grade->grade_item->is_manual_item() && (!is_null($this->grade->rawgrade)) ? - $this->grade->rawgrade : $this->grade->finalgrade; - - if ($this->grade->grade_item->scaleid) { - return $val ? (int)$val : -1; - } else { - return $val ? format_float($val, $this->grade->grade_item->get_decimals()) : ''; - } - } - - public function get_label() { - if (!isset($this->grade->label)) { - $this->grade->label = ''; - } - return $this->grade->label; - } - - public function is_disabled() { - $locked = 0; - $gradeitemlocked = 0; - $overridden = 0; - /* Disable editing if grade item or grade score is locked - * if any of these items are set, then we will disable editing - * at some point, we might want to show the reason for the lock - * this code could be simplified, but its more readable for steve's little mind - */ - if (!empty($this->grade->locked)) { - $locked = 1; - } - if (!empty($this->grade->grade_item->locked)) { - $gradeitemlocked = 1; - } - if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) { - $overridden = 1; - } - return ($locked || $gradeitemlocked || $overridden); - } - - public function determine_format() { - if ($this->grade->grade_item->load_scale()) { - $scale = $this->grade->grade_item->load_scale(); - - $options = array(-1 => get_string('nograde')); - - foreach ($scale->scale_items as $i => $name) { - $options[$i + 1] = $name; - } - - return new gradereport_singleview_dropdown_attribute( - $this->get_name(), - $options, - $this->get_value(), - $this->get_label(), - $this->is_disabled(), - $this->get_tabindex() - ); - } else { - return new gradereport_singleview_text_attribute( - $this->get_name(), - $this->get_value(), - $this->get_label(), - $this->is_disabled(), - $this->get_tabindex() - ); - } - } - - public function set($value) { - global $DB; - - $userid = $this->grade->userid; - $gradeitem = $this->grade->grade_item; - - $feedback = false; - $feedbackformat = false; - if ($gradeitem->gradetype == GRADE_TYPE_SCALE) { - if ($value == -1) { - $finalgrade = null; - } else { - $finalgrade = $value; - } - } else { - $finalgrade = unformat_float($value); - } - - $errorstr = ''; - if ($finalgrade) { - $bounded = $gradeitem->bounded_grade($finalgrade); - if ($bounded > $finalgrade) { - $errorstr = 'lessthanmin'; - } else if ($bounded < $finalgrade) { - $errorstr = 'morethanmax'; - } - } - - if ($errorstr) { - $user = $DB->get_record('user', array('id' => $userid), 'id, firstname, alternatename, lastname'); - $gradestr = new stdClass; - if (!empty($user->alternatename)) { - $gradestr->username = $user->alternatename . ' (' . $user->firstname . ') ' . $user->lastname; - } else { - $gradestr->username = $user->firstname . ' ' . $user->lastname; - } - $gradestr->itemname = $this->grade->grade_item->get_name(); - $errorstr = get_string($errorstr, 'grades', $gradestr); - } - - $gradeitem->update_final_grade($userid, $finalgrade, 'singleview', $feedback, FORMAT_MOODLE); - return $errorstr; - } -} - -class gradereport_singleview_feedback_ui extends gradereport_singleview_grade_attribute_format implements unique_value, be_disabled { - - public $name = 'feedback'; - - public function get_value() { - return $this->grade->feedback ? $this->grade->feedback : ''; - } - - public function get_label() { - if (!isset($this->grade->label)) { - $this->grade->label = ''; - } - return $this->grade->label; - } - - public function is_disabled() { - $locked = 0; - $gradeitemlocked = 0; - $overridden = 0; - /* Disable editing if grade item or grade score is locked - * if any of these items are set, then we will disable editing - * at some point, we might want to show the reason for the lock - * this code could be simplified, but its more readable for steve's little mind - */ - if (!empty($this->grade->locked)) { - $locked = 1; - } - if (!empty($this->grade->grade_item->locked)) { - $gradeitemlocked = 1; - } - if ($this->grade->grade_item->is_overridable_item() and !$this->grade->is_overridden()) { - $overridden = 1; - } - return ($locked || $gradeitemlocked || $overridden); - } - - public function determine_format() { - return new gradereport_singleview_text_attribute( - $this->get_name(), - $this->get_value(), - $this->get_label(), - $this->is_disabled(), - $this->get_tabindex() - ); - } - - public function set($value) { - $finalgrade = false; - $trimmed = trim($value); - if (empty($trimmed)) { - $feedback = null; - } else { - $feedback = $value; - } - - $this->grade->grade_item->update_final_grade( - $this->grade->userid, $finalgrade, 'singleview', - $feedback, FORMAT_MOODLE - ); - return false; - } -} - -class gradereport_singleview_override_ui extends gradereport_singleview_grade_attribute_format implements be_checked, be_disabled { - public $name = 'override'; - - public function is_checked() { - return $this->grade->is_overridden(); - } - - public function is_disabled() { - $lockedgrade = $lockedgradeitem = 0; - if (!empty($this->grade->locked)) { - $lockedgrade = 1; - } - if (!empty($this->grade->grade_item->locked)) { - $lockedgradeitem = 1; - } - return ($lockedgrade || $lockedgradeitem); - } - - public function get_label() { - if (!isset($this->grade->label)) { - $this->grade->label = ''; - } - return $this->grade->label; - } - - function determine_format() { - if (!$this->grade->grade_item->is_overridable_item()) { - return new gradereport_singleview_empty_element(); - } - return new gradereport_singleview_checkbox_attribute( - $this->get_name(), - $this->get_label(), - $this->is_checked(), - null, - $this->is_disabled() - ); - } - - function set($value) { - if (empty($this->grade->id)) { - return false; - } - - $state = $value == 0 ? false : true; - - $this->grade->set_overridden($state); - $this->grade->grade_item->get_parent_category()->force_regrading(); - return false; - } -} - -class gradereport_singleview_exclude_ui extends gradereport_singleview_grade_attribute_format implements be_checked { - var $name = 'exclude'; - - function is_checked() { - return $this->grade->is_excluded(); - } - - function determine_format() { - return new gradereport_singleview_checkbox_attribute( - $this->get_name(), - $this->get_label(), - $this->is_checked() - ); - } - - public function get_label() { - if (!isset($this->grade->label)) { - $this->grade->label = ''; - } - return $this->grade->label; - } - - function set($value) { - if (empty($this->grade->id)) { - if (empty($value)) { - return false; - } - - $gradeitem = $this->grade->grade_item; - - // Fill in arbitrary grade to be excluded. - $gradeitem->update_final_grade( - $this->grade->userid, null, 'singleview', null, FORMAT_MOODLE - ); - - $grade_params = array( - 'userid' => $this->grade->userid, - 'itemid' => $this->grade->itemid - ); - - $this->grade = grade_grade::fetch($grade_params); - $this->grade->grade_item = $gradeitem; - } - - $state = $value == 0 ? false : true; - - $this->grade->set_excluded($state); - - $this->grade->grade_item->get_parent_category()->force_regrading(); - return false; - } -} - -class gradereport_singleview_range_ui extends gradereport_singleview_attribute_format { - function __construct($item) { - $this->item = $item; - } - - function determine_format() { - $decimals = $this->item->get_decimals(); - - $min = format_float($this->item->grademin, $decimals); - $max = format_float($this->item->grademax, $decimals); - - return new gradereport_singleview_empty_element("$min - $max"); - } -} diff --git a/grade/report/singleview/db/access.php b/grade/report/singleview/db/access.php index f0cbe0f29f0..2d7326145bf 100755 --- a/grade/report/singleview/db/access.php +++ b/grade/report/singleview/db/access.php @@ -1,5 +1,4 @@ dirroot.'/grade/report/singleview/lib.php'); $courseid = required_param('id', PARAM_INT); $groupid = optional_param('group', null, PARAM_INT); -// Making this work with profile reports + +// Making this work with profile reports. $userid = optional_param('userid', null, PARAM_INT); $defaulttype = $userid ? 'user' : 'select'; $itemid = optional_param('itemid', $userid, PARAM_INT); $itemtype = optional_param('item', $defaulttype, PARAM_TEXT); +$page = optional_param('page', 0, PARAM_INT); +$perpage = optional_param('perpage', 100, PARAM_INT); $courseparams = array('id' => $courseid); - $PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $courseparams)); if (!$course = $DB->get_record('course', $courseparams)) { print_error('nocourseid'); } +require_login($course); +$PAGE->set_pagelayout('report'); + if (!in_array($itemtype, gradereport_singleview::valid_screens())) { print_error('notvalid', 'gradereport_singleview', '', $itemtype); } -require_login($course); - $context = context_course::instance($course->id); // This is the normal requirements. require_capability('gradereport/singleview:view', $context); require_capability('moodle/grade:viewall', $context); require_capability('moodle/grade:edit', $context); -// End permission. $gpr = new grade_plugin_return(array( 'type' => 'report', @@ -72,6 +73,8 @@ if (!isset($USER->grade_last_report)) { } $USER->grade_last_report[$course->id] = 'singleview'; +// First make sure we have proper final grades - +// this must be done before constructing of the grade tree. grade_regrade_final_grades($courseid); $report = new gradereport_singleview( @@ -83,37 +86,36 @@ $reportname = $report->screen->heading(); $pluginname = get_string('pluginname', 'gradereport_singleview'); -$reporturl = new moodle_url('/grade/report/grader/index.php', $courseparams); -$editurl = new moodle_url('/grade/report/singleview/index.php', $courseparams); +$pageparams = array( + 'id' => $courseid, + 'itemid' => $itemid, + 'item' => $itemtype, + 'userid' => $userid, + 'group' => $groupid, + 'page' => $page, + 'perpage' => $perpage +); -$PAGE->navbar->ignore_active(true); - -$PAGE->navbar->add(get_string('courses')); -$PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', $courseparams)); - -$PAGE->navbar->add(get_string('gradeadministration', 'grades')); -$PAGE->navbar->add(get_string('pluginname', 'gradereport_grader'), $reporturl); - -if ($reportname != $pluginname) { - $PAGE->navbar->add($pluginname, $editurl); - $PAGE->navbar->add($reportname); -} else { - $PAGE->navbar->add($pluginname); -} +$currentpage = new moodle_url('/grade/report/singleview/index.php', $pageparams); if ($data = data_submitted()) { $warnings = $report->process_data($data); if (empty($warnings)) { - redirect($reporturl); + redirect($currentpage); + die(); } } -$graderrightnav = $graderleftnav = null; -if ($report->screen instanceof gradereport_selectable_items - && class_exists(gradereport_singleview::classname($report->screen->item_type()))) { +print_grade_page_head($course->id, 'report', 'singleview', $reportname); - $optionkeys = array_keys($report->screen->options()); +$graderrightnav = $graderleftnav = null; + +$options = $report->screen->options(); + +if (!empty($options)) { + + $optionkeys = array_keys($options); $optionitemid = array_shift($optionkeys); $relreport = new gradereport_singleview( @@ -128,19 +130,17 @@ if ($report->screen instanceof gradereport_selectable_items if ($i > 0) { $navparams['itemid'] = $reloptionssorting[$i - 1]; $link = new moodle_url('/grade/report/singleview/index.php', $navparams); - $navprev = html_writer::link($link, $reloptions[$reloptionssorting[$i - 1]]); + $navprev = html_writer::link($link, $OUTPUT->larrow() . ' ' . $reloptions[$reloptionssorting[$i - 1]]); $graderleftnav = html_writer::tag('small', $navprev, array('class' => 'itemnav previtem')); } if ($i < count($reloptionssorting) - 1) { $navparams['itemid'] = $reloptionssorting[$i + 1]; $link = new moodle_url('/grade/report/singleview/index.php', $navparams); - $navnext = html_writer::link($link, $reloptions[$reloptionssorting[$i + 1]]); + $navnext = html_writer::link($link, $reloptions[$reloptionssorting[$i + 1]] . ' ' . $OUTPUT->rarrow()); $graderrightnav = html_writer::tag('small', $navnext, array('class' => 'itemnav nextitem')); } } -print_grade_page_head($course->id, 'report', 'singleview', $reportname); - if (!is_null($graderleftnav)) { echo $graderleftnav; } @@ -168,11 +168,20 @@ if ($report->screen->supports_paging()) { echo $report->screen->pager(); } -if(!is_null($graderleftnav)) { +if (!is_null($graderleftnav)) { echo $graderleftnav; } -if(!is_null($graderrightnav)) { +if (!is_null($graderrightnav)) { echo $graderrightnav; } +$event = \gradereport_singleview\event\grade_report_viewed::create( + array( + 'context' => $context, + 'courseid' => $courseid, + 'relateduserid' => $USER->id, + ) +); +$event->trigger(); + echo $OUTPUT->footer(); diff --git a/grade/report/singleview/lang/en/gradereport_singleview.php b/grade/report/singleview/lang/en/gradereport_singleview.php index 429e6f87863..a4d354524da 100755 --- a/grade/report/singleview/lang/en/gradereport_singleview.php +++ b/grade/report/singleview/lang/en/gradereport_singleview.php @@ -1,5 +1,4 @@ dirroot . '/grade/report/lib.php'); -require_once($CFG->dirroot . '/grade/report/singleview/classes/lib.php'); +defined('MOODLE_INTERNAL') || die; +require_once($CFG->dirroot . '/grade/report/lib.php'); + +/** + * This class is the main class that must be implemented by a grade report plugin. + * + * @package gradereport_singleview + * @copyright 2014 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class gradereport_singleview extends grade_report { + /** + * Return the list of valid screens, used to validate the input. + * + * @return array List of screens. + */ public static function valid_screens() { - $screendir = dirname(__FILE__) . '/screens'; - - $is_valid = function($filename) use ($screendir) { - if (preg_match('/^\./', $filename)){ - return false; - } - - $file = $screendir . '/' . $filename; - - if (is_file($file)) { - return false; - } - - $plugin = $file . '/lib.php'; - return file_exists($plugin); - }; - - return array_filter(scandir($screendir), $is_valid); + // This is a list of all the known classes representing a screen in this plugin. + return array('user', 'select', 'grade'); } - public static function classname($screen) { - $screendir = dirname(__FILE__) . '/screens/' . $screen; - - require_once $screendir . '/lib.php'; - - return 'gradereport_singleview_' . $screen; - } - - public static function filters() { - $classnames = array('gradereport_singleview', 'classname'); - $classes = array_map($classnames, self::valid_screens()); - - $screens = array_filter($classes, function($screen) { - return method_exists($screen, 'filter'); - }); - - return function($item) use ($screens) { - $reduced = function($in, $screen) use ($item) { - return $in && $screen::filter($item); - }; - - return array_reduce($screens, $reduced, true); - }; - } - - function process_data($data) { + /** + * Process data from a form submission. Delegated to the current screen. + * + * @param array $data The data from the form + * @return array List of warnings + */ + public function process_data($data) { if (has_capability('moodle/grade:manage', $this->context)) { return $this->screen->process($data); } } - function process_action($target, $action) { + /** + * Unused - abstract function declared in the parent class. + * + * @param string $target + * @param string $action + */ + public function process_action($target, $action) { } - function _s($key, $a = null) { - return get_string($key, 'gradereport_singleview', $a); - } - - function __construct($courseid, $gpr, $context, $itemtype, $itemid, $groupid=null) { + /** + * Constructor for this report. Creates the appropriate screen class based on itemtype. + * + * @param int $courseid The course id. + * @param object $gpr grade plugin return tracking object + * @param context_course $context + * @param string $itemtype Should be user, select or grade + * @param int $itemid The id of the user or grade item + * @param int $groupid (optional) The current groupid. + */ + public function __construct($courseid, $gpr, $context, $itemtype, $itemid, $groupid=null) { parent::__construct($courseid, $gpr, $context); - $class = self::classname($itemtype); + $screenclass = "\\gradereport_singleview\\local\\screen\\${itemtype}"; - $this->screen = new $class($courseid, $itemid, $groupid); + $this->screen = new $screenclass($courseid, $itemid, $groupid); - // Load custom or predifined js + // Load custom or predifined js. $this->screen->js(); $base = '/grade/report/singleview/index.php'; - $id_params = array('id' => $courseid); + $idparams = array('id' => $courseid); - $this->baseurl = new moodle_url($base, $id_params); + $this->baseurl = new moodle_url($base, $idparams); - $this->pbarurl = new moodle_url($base, $id_params + array( + $this->pbarurl = new moodle_url($base, $idparams + array( 'item' => $itemtype, 'itemid' => $itemid )); @@ -111,40 +100,13 @@ class gradereport_singleview extends grade_report { $this->setup_groups(); } - function output() { + /** + * Build the html for the screen. + * @return string HTML to display + */ + public function output() { global $OUTPUT; return $OUTPUT->box($this->screen->html()); } } -function gradereport_singleview_profilereport($course, $user) { - global $CFG, $OUTPUT; - - if (!function_exists('gradereport_user_profilereport')) { - require_once $CFG->dirroot . '/grade/report/user/lib.php'; - } - - $context = context_course::instance($course->id); - - $can_use = ( - has_capability('gradereport/singleview:view', $context) and - has_capability('moodle/grade:viewall', $context) and - has_capability('moodle/grade:edit', $context) - ); - - if (!$can_use) { - gradereport_user_profilereport($course, $user); - } else { - $gpr = new grade_plugin_return(array( - 'type' => 'report', - 'plugin' => 'singleview', - 'courseid' => $course->id, - 'userid' => $user->id - )); - - $report = new gradereport_singleview($course->id, $gpr, $context, 'user', $user->id); - - echo $OUTPUT->heading($report->screen->heading()); - echo $report->output(); - } -} diff --git a/grade/report/singleview/screens/user/lib.php b/grade/report/singleview/screens/user/lib.php deleted file mode 100644 index 513dfa24784..00000000000 --- a/grade/report/singleview/screens/user/lib.php +++ /dev/null @@ -1,162 +0,0 @@ -. - -/** - * The gradebook simple view - grades view (for a user) - * - * @package gradereport_singleview - * @copyright 2014 Moodle Pty Ltd (http://moodle.com) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -class gradereport_singleview_user extends gradereport_singleview_tablelike implements gradereport_selectable_items { - - private $categories = array(); - - public $structure; - - public function description() { - return get_string('gradeitems', 'grades');; - } - - public function options() { - return array_map(function($item) { - return $item->get_name(); - }, $this->items); - } - - public function item_type() { - return 'grade'; - } - - public function display_group_selector() { - return false; - } - - public function init($selfitemisempty = false) { - global $DB; - - if (!$selfitemisempty) { - $this->item = $DB->get_record('user', array('id' => $this->itemid)); - } - - $params = array('courseid' => $this->courseid); - - $seq = new grade_seq($this->courseid, true); - foreach ($seq->items as $key => $item) { - if (isset($item->itemmodule)) { - list($courseid, $cmid) = get_course_and_cm_from_instance($item->iteminstance, $item->itemmodule); - $seq->items[$key]->cmid = $cmid->id; - } - } - - $this->items = array_filter($seq->items, gradereport_singleview::filters()); - - unset($seq); - - $this->setup_structure(); - - $this->definition = array( - 'finalgrade', 'feedback', 'override', 'exclude' - ); - $this->set_headers($this->original_headers()); - } - - public function original_headers() { - return array( - '', // For filter icon. - '', // For activity icon. - get_string('assessmentname', 'gradereport_singleview'), - get_string('gradecategory', 'grades'), - get_string('range', 'grades'), - get_string('grade', 'grades'), - get_string('feedback', 'grades'), - $this->make_toggle_links('override'), - $this->make_toggle_links('exclude') - ); - } - - public function format_line($item) { - global $OUTPUT; - - $grade = $this->fetch_grade_or_default($item, $this->item->id); - $lockicon = ''; - - // UCSB add lock icon indicator. - $lockeditem = $lockeditemgrade = 0; - if (!empty($grade->locked)) { - $lockeditem = 1; - } - if (!empty($grade->grade_item->locked)) { - $lockeditemgrade = 1; - } - // Check both grade and grade item. - if ($lockeditem || $lockeditemgrade) { - $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked'); - } - - $realuserid = ''; - if (isset($item->cmid)) { - $realuserid = $item->cmid; - } - $url = new moodle_url('/mod/' . $item->itemmodule . '/view.php', array('id' => $realuserid)); - $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name()); - $grade->label = $item->get_name(); - - $line = array( - $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', $iconstring)), - $this->format_icon($item) . $lockicon, - html_writer::link($url, $item->get_name()), - $this->category($item), - $this->factory()->create('range')->format($item) - ); - return $this->format_definition($line, $grade); - } - - private function format_icon($item) { - $element = array('type' => 'item', 'object' => $item); - return $this->structure->get_element_icon($element); - } - - private function category($item) { - if (empty($item->categoryid)) { - - if ($item->itemtype == 'course') { - return $this->course->fullname; - } - - global $DB; - - $params = array('id' => $item->iteminstance); - $elem = $DB->get_record('grade_categories', $params); - - return $elem->fullname; - } - - if (!isset($this->categories[$item->categoryid])) { - $category = $item->get_parent_category(); - - $this->categories[$category->id] = $category; - } - - return $this->categories[$item->categoryid]->get_name(); - } - - public function heading() { - return fullname($this->item); - } -} diff --git a/grade/report/singleview/styles.css b/grade/report/singleview/styles.css index 78a8607ac9e..3c2cca7bc43 100644 --- a/grade/report/singleview/styles.css +++ b/grade/report/singleview/styles.css @@ -1,51 +1,47 @@ -#page-grade-report-singleview-index div.generalbox { +.path-grade-report-singleview div.generalbox { margin: 0 20px 15px 20px; } -#page-grade-report-singleview-index div.generalbox div.singleselect form div { +.path-grade-report-singleview div.generalbox div.singleselect form div { text-align: center; } -#page-grade-report-singleview-index div.generalbox table.generaltable { +.path-grade-report-singleview div.generalbox table.generaltable { margin: 0 auto 15px auto; } -#page-grade-report-singleview-index div.generalbox form div { +.path-grade-report-singleview div.generalbox form div { text-align: center; } -#page-grade-report-singleview-index .singleview_buttons { +.path-grade-report-singleview .singleview_buttons { padding: 10px 0; } -#page-grade-report-singleview-index table.generaltable .cell { - vertical-align: middle; -} - -#page-grade-report-singleview-index div.generalbox h2 { +.path-grade-report-singleview div.generalbox h2 { text-align: center; } -#page-grade-report-singleview-index input[name^="finalgrade"] { +.path-grade-report-singleview input[name^="finalgrade"] { width: 50px; } -#page-grade-report-singleview-index #region-main h2, .paging{ +.path-grade-report-singleview #region-main h2, .paging{ text-align: center; } -#page-grade-report-singleview-index itemnav.previtem { +.path-grade-report-singleview itemnav.previtem { float:left; } -#page-grade-report-singleview-index itemnav.previtem { +.path-grade-report-singleview itemnav.previtem { float:left; } -#page-grade-report-singleview-index.dir-rtl small.previtem { +.path-grade-report-singleview.dir-rtl small.previtem { float:right; } -#page-grade-report-singleview-index small.nextitem { +.path-grade-report-singleview small.nextitem { float:right; } -#page-grade-report-singleview-index.dir-rtl small.nextitem { +.path-grade-report-singleview.dir-rtl small.nextitem { float:left; } diff --git a/grade/report/singleview/version.php b/grade/report/singleview/version.php index 3225fbf15fb..cf792d4e6b4 100755 --- a/grade/report/singleview/version.php +++ b/grade/report/singleview/version.php @@ -1,5 +1,4 @@ component = 'gradereport_singleview'; // Full name of the plugin (used for diagnostics). $plugin->version = 2013081002; $plugin->requires = 2010090501; From 1b2c1ccb4c9fc1ed88832b8ef7740434b2ec5114 Mon Sep 17 00:00:00 2001 From: Zachary Durber Date: Tue, 14 Oct 2014 13:18:45 +0800 Subject: [PATCH 16/16] MDL-18229 gradebook: Fixes for bulk insert and checkboxes. --- .../singleview/classes/local/screen/grade.php | 2 ++ .../singleview/classes/local/screen/screen.php | 15 +++++++++++---- .../singleview/classes/local/screen/user.php | 1 - .../classes/local/ui/checkbox_attribute.php | 7 ------- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/grade/report/singleview/classes/local/screen/grade.php b/grade/report/singleview/classes/local/screen/grade.php index 425fa3a73e6..0cb0321b935 100644 --- a/grade/report/singleview/classes/local/screen/grade.php +++ b/grade/report/singleview/classes/local/screen/grade.php @@ -25,6 +25,8 @@ namespace gradereport_singleview\local\screen; use gradereport_singleview\local\ui\range; +use gradereport_singleview\local\ui\bulk_insert; +use grade_grade; use grade_item; use moodle_url; use pix_icon; diff --git a/grade/report/singleview/classes/local/screen/screen.php b/grade/report/singleview/classes/local/screen/screen.php index 22e3eeaa897..fd4fa6d0f91 100644 --- a/grade/report/singleview/classes/local/screen/screen.php +++ b/grade/report/singleview/classes/local/screen/screen.php @@ -263,14 +263,21 @@ abstract class screen { continue; } - if (!in_array($matches[1], $fields)) { - continue; - } - $gradeitem = grade_item::fetch(array( 'id' => $itemid, 'courseid' => $this->courseid )); + if (preg_match('/^old[oe]{1}/', $varname)) { + $elementname = preg_replace('/^old/', '', $varname); + if (!isset($data->$elementname)) { + $data->$elementname = false; + } + } + + if (!in_array($matches[1], $fields)) { + continue; + } + if (!$gradeitem) { continue; } diff --git a/grade/report/singleview/classes/local/screen/user.php b/grade/report/singleview/classes/local/screen/user.php index 2b87e45e0c5..ba2f59bd141 100644 --- a/grade/report/singleview/classes/local/screen/user.php +++ b/grade/report/singleview/classes/local/screen/user.php @@ -293,7 +293,6 @@ class user extends tablelike implements selectable_items { // Appropriately massage data that may not exist. $userid = $this->item->id; - foreach ($this->items as $gradeitemid => $gradeitem) { $null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : ''; $field = "finalgrade_{$gradeitem->id}_{$gradeitemid}"; diff --git a/grade/report/singleview/classes/local/ui/checkbox_attribute.php b/grade/report/singleview/classes/local/ui/checkbox_attribute.php index 1357974a9da..a16b08180b4 100644 --- a/grade/report/singleview/classes/local/ui/checkbox_attribute.php +++ b/grade/report/singleview/classes/local/ui/checkbox_attribute.php @@ -85,12 +85,6 @@ class checkbox_attribute extends element { $attributes['disabled'] = 'DISABLED'; } - $alt = array( - 'type' => 'hidden', - 'name' => $this->name, - 'value' => 0 - ); - $hidden = array( 'type' => 'hidden', 'name' => 'old' . $this->name @@ -111,7 +105,6 @@ class checkbox_attribute extends element { } return ( - html_writer::empty_tag('input', $alt) . html_writer::tag('label', get_string($type . 'for', 'gradereport_singleview', $this->label), array('for' => $this->name, 'class' => 'accesshide')) .