diff --git a/attforblock.js b/attforblock.js deleted file mode 100644 index 008dc3d..0000000 --- a/attforblock.js +++ /dev/null @@ -1,12 +0,0 @@ -M.mod_attforblock = {} - -M.mod_attforblock.init_manage = function(Y) { - - Y.on('click', function(e) { - if (e.target.get('checked')) - checkall(); - else - checknone(); - }, '#cb_selector' ); - -}; \ No newline at end of file diff --git a/locallib.php b/locallib.php index a02d726..61f520a 100644 --- a/locallib.php +++ b/locallib.php @@ -85,6 +85,11 @@ class attforblock_permissions { return $this->canchangepreferences; } + public function require_change_preferences_capability() { + require_capability('mod/attforblock:changepreferences', $this->context); + } + + public function can_export() { if (is_null($this->canexport)) $this->canexport = has_capability('mod/attforblock:export', $this->context); @@ -320,6 +325,29 @@ class att_report_page_params extends att_page_with_filter_controls { } } +class att_preferences_page_params { + const ACTION_ADD = 1; + const ACTION_DELETE = 2; + const ACTION_HIDE = 3; + const ACTION_SHOW = 4; + const ACTION_SAVE = 5; + + /** @var int view mode of taking attendance page*/ + public $action; + + public $statusid; + + public function get_significant_params() { + $params = array(); + + if (isset($this->action)) $params['action'] = $this->action; + if (isset($this->statusid)) $params['statusid'] = $this->statusid; + + return $params; + } +} + + class attforblock { const SESSION_COMMON = 0; @@ -562,9 +590,9 @@ class attforblock { /** * @return moodle_url of attsettings.php for attendance instance */ - public function url_settings() { - $params = array('id' => $this->cm->id); - return new moodle_url('/mod/attforblock/attsettings.php', $params); + public function url_preferences($params=array()) { + $params = array_merge(array('id' => $this->cm->id), $params); + return new moodle_url('/mod/attforblock/preferences.php', $params); } /** @@ -1042,6 +1070,59 @@ class attforblock { } // TODO: log } + + public function remove_status($statusid) { + global $DB; + + $DB->set_field('attendance_statuses', 'deleted', 1, array('id' => $statusid)); + } + + public function add_status($acronym, $description, $grade) { + global $DB; + + if ($acronym && $description) { + $rec = new stdClass(); + $rec->courseid = $this->course->id; + $rec->attendanceid = $this->id; + $rec->acronym = $acronym; + $rec->description = $description; + $rec->grade = $grade; + $DB->insert_record('attendance_statuses', $rec); + + // TODO: log + //add_to_log($course->id, 'attendance', 'setting added', 'mod/attforblock/attsettings.php?course='.$course->id, $user->lastname.' '.$user->firstname); + } else { + print_error('cantaddstatus', 'attforblock', $this->url_preferences()); + } + } + + public function update_status($statusid, $acronym, $description, $grade, $visible) { + global $DB; + + $updated = array(); + + $status = new stdClass(); + $status->id = $statusid; + if ($acronym) { + $status->acronym = $acronym; + $updated[] = $acronym; + } + if ($description) { + $status->description = $description; + $updated[] = $description; + } + if (isset($grade)) { + $status->grade = $grade; + $updated[] = $grade; + } + if (isset($visible)) { + $status->visible = $visible; + $updated[] = $visible ? get_string('show') : get_string('hide'); + } + $DB->update_record('attendance_statuses', $status); + + // TODO: log + } } @@ -1154,4 +1235,10 @@ function update_all_users_grades($attid, $course, $context) { $attid, 0, $grades); } +function has_logs_for_status($statusid) { + global $DB; + + return $DB->count_records('attendance_log', array('statusid'=> $statusid)) > 0; +} + ?> diff --git a/module.js b/module.js new file mode 100644 index 0000000..d98a86b --- /dev/null +++ b/module.js @@ -0,0 +1,27 @@ +M.mod_attforblock = {} + +M.mod_attforblock.init_manage = function(Y) { + + Y.on('click', function(e) { + if (e.target.get('checked')) + checkall(); + else + checknone(); + }, '#cb_selector' ); + +}; + +M.mod_attforblock.set_preferences_action = function(action) { + var item = document.getElementById('preferencesaction'); + if (item) { + item.setAttribute('value', action); + } + else { + item = document.getElementById('preferencesform'); + var input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", "action"); + input.setAttribute("value", action); + item.appendChild(input); + } +}; \ No newline at end of file diff --git a/preferences.php b/preferences.php new file mode 100644 index 0000000..e1009c8 --- /dev/null +++ b/preferences.php @@ -0,0 +1,98 @@ +action = optional_param('action', NULL, PARAM_INT); +$pageparams->statusid = optional_param('statusid', NULL, PARAM_INT); + +$cm = get_coursemodule_from_id('attforblock', $id, 0, false, MUST_EXIST); +$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); +$att = $DB->get_record('attforblock', array('id' => $cm->instance), '*', MUST_EXIST); + +require_login($course, true, $cm); + +$att = new attforblock($att, $cm, $course, $PAGE->context, $pageparams); + +$att->perm->require_change_preferences_capability(); + +$PAGE->set_url($att->url_preferences()); +$PAGE->set_title($course->shortname. ": ".$att->name.' - '.get_string('settings', 'attforblock')); +$PAGE->set_heading($course->fullname); +$PAGE->set_cacheable(true); +$PAGE->set_button($OUTPUT->update_module_button($cm->id, 'attforblock')); +$PAGE->navbar->add(get_string('settings', 'attforblock')); + +switch ($att->pageparams->action) { + case att_preferences_page_params::ACTION_ADD: + $newacronym = optional_param('newacronym', null, PARAM_MULTILANG); + $newdescription = optional_param('newdescription', null, PARAM_MULTILANG); + $newgrade = optional_param('newgrade', 0, PARAM_INT); + + $att->add_status($newacronym, $newdescription, $newgrade); + break; + case att_preferences_page_params::ACTION_DELETE: + if (has_logs_for_status($att->pageparams->statusid)) + print_error('cantdeletestatus', 'attforblock', "attsettings.php?id=$id"); + + $confirm = optional_param('confirm', NULL, PARAM_INT); + if (isset($confirm)) { + $att->remove_status($att->pageparams->statusid); + redirect($att->url_preferences(), get_string('statusdeleted','attforblock')); + } + + $statuses = $att->get_statuses(); + $status = $statuses[$att->pageparams->statusid]; + $message = get_string('deletecheckfull', '', get_string('variable', 'attforblock')); + $message .= str_repeat(html_writer::empty_tag('br'), 2); + $message .= $status->acronym.': '.($status->description ? $status->description : get_string('nodescription', 'attforblock')); + $params = array_merge($att->pageparams->get_significant_params(), array('confirm' => 1)); + echo $OUTPUT->header(); + echo $OUTPUT->heading(get_string('attendanceforthecourse','attforblock').' :: ' .$course->fullname); + echo $OUTPUT->confirm($message, $att->url_preferences($params), $att->url_preferences()); + echo $OUTPUT->footer(); + exit; + case att_preferences_page_params::ACTION_HIDE: + $att->update_status($att->pageparams->statusid, null, null, null, 0); + break; + case att_preferences_page_params::ACTION_SHOW: + $att->update_status($att->pageparams->statusid, null, null, null, 1); + break; + case att_preferences_page_params::ACTION_SAVE: + $acronym = required_param('acronym', PARAM_MULTILANG); + $description = required_param('description', PARAM_MULTILANG); + $grade = required_param('grade', PARAM_INT); + + foreach ($acronym as $id => $v) { + $att->update_status($id, $acronym[$id], $description[$id], $grade[$id], null); + } + update_all_users_grades($att->id, $att->course, $att->context); + break; +} + +$output = $PAGE->get_renderer('mod_attforblock'); +$tabs = new attforblock_tabs($att, attforblock_tabs::TAB_PREFERENCES); +$prefdata = new attforblock_preferences_data($att); + +/// Output starts here + +echo $output->header(); +echo $output->heading(get_string('attendanceforthecourse','attforblock').' :: ' .$course->fullname); +echo $output->render($tabs); +echo $output->render($prefdata); + +echo $output->footer(); + +?> diff --git a/renderables.php b/renderables.php index 9d2c538..7e34cf0 100644 --- a/renderables.php +++ b/renderables.php @@ -20,11 +20,11 @@ require_once(dirname(__FILE__).'/locallib.php'); * */ class attforblock_tabs implements renderable { - const TAB_SESSIONS = 1; - const TAB_ADD = 2; - const TAB_REPORT = 3; - const TAB_EXPORT = 4; - const TAB_SETTINGS = 5; + const TAB_SESSIONS = 1; + const TAB_ADD = 2; + const TAB_REPORT = 3; + const TAB_EXPORT = 4; + const TAB_PREFERENCES = 5; public $currenttab; @@ -71,7 +71,7 @@ class attforblock_tabs implements renderable { } if ($this->att->perm->can_change_preferences()) { - $toprow[] = new tabobject(self::TAB_SETTINGS, $this->att->url_settings()->out(), + $toprow[] = new tabobject(self::TAB_PREFERENCES, $this->att->url_preferences()->out(), get_string('settings','attforblock')); } @@ -482,6 +482,27 @@ class attforblock_report_data implements renderable { } +class attforblock_preferences_data implements renderable { + public $statuses; + + private $att; + + public function __construct(attforblock $att) { + $this->statuses = $att->get_statuses(false); + + foreach ($this->statuses as $st) $st->haslogs = has_logs_for_status ($st->id); + + $this->att = $att; + } + + public function url($params=array(), $significant_params=TRUE) { + if ($significant_params) + $params = array_merge($this->att->pageparams->get_significant_params(), $params); + + return $this->att->url_preferences($params); + } +} + class url_helpers { public static function url_take($att, $sessionid, $grouptype) { $params = array('sessionid' => $sessionid); diff --git a/renderer.php b/renderer.php index 28c5056..3828ed6 100644 --- a/renderer.php +++ b/renderer.php @@ -161,7 +161,6 @@ class mod_attforblock_renderer extends plugin_renderer_base { } protected function render_sess_manage_table(attforblock_manage_data $sessdata) { - $this->page->requires->js('/mod/attforblock/attforblock.js'); $this->page->requires->js_init_call('M.mod_attforblock.init_manage'); $table = new html_table(); @@ -770,5 +769,95 @@ class mod_attforblock_renderer extends plugin_renderer_base { } } + + protected function render_attforblock_preferences_data(attforblock_preferences_data $prefdata) { + $this->page->requires->js('/mod/attforblock/module.js'); + + $table = new html_table(); + $table->width = '100%'; + $table->head = array('#', + get_string('acronym', 'attforblock'), + get_string('description'), + get_string('grade'), + get_string('action')); + $table->align = array('center', 'center', 'center', 'center', 'center', 'center'); + + $i = 1; + foreach ($prefdata->statuses as $st) { + $table->data[$i][] = $i; + $table->data[$i][] = $this->construct_text_input('acronym['.$st->id.']', 2, 2, $st->acronym); + $table->data[$i][] = $this->construct_text_input('description['.$st->id.']', 30, 30, $st->description); + $table->data[$i][] = $this->construct_text_input('grade['.$st->id.']', 4, 4, $st->grade); + $table->data[$i][] = $this->construct_preferences_actions_icons($st, $prefdata); + + $i++; + } + + $table->data[$i][] = '*'; + $table->data[$i][] = $this->construct_text_input('newacronym', 2, 2); + $table->data[$i][] = $this->construct_text_input('newdescription', 30, 30); + $table->data[$i][] = $this->construct_text_input('newgrade', 4, 4); + $table->data[$i][] = $this->construct_preferences_button(get_string('add', 'attforblock'), att_preferences_page_params::ACTION_ADD); + + $o = html_writer::tag('h1', get_string('myvariables','attforblock')); + $o .= html_writer::table($table); + $o .= html_writer::input_hidden_params($prefdata->url(array(), false)); + $o .= $this->construct_preferences_button(get_string('update', 'attforblock'), att_preferences_page_params::ACTION_SAVE); + $o = html_writer::tag('form', $o, array('id' => 'preferencesform', 'method' => 'post', 'action' => $prefdata->url(array(), false)->out_omit_querystring())); + $o = $this->output->container($o, 'generalbox attwidth'); + + return $o; + } + + private function construct_text_input($name, $size, $maxlength, $value='') { + $attributes = array( + 'type' => 'text', + 'name' => $name, + 'size' => $size, + 'maxlength' => $maxlength, + 'value' => $value); + return html_writer::empty_tag('input', $attributes); + } + + private function construct_preferences_actions_icons($st, $prefdata) { + global $OUTPUT; + + if ($st->visible) { + $params = array( + 'action' => att_preferences_page_params::ACTION_HIDE, + 'statusid' => $st->id); + $showhideicon = $OUTPUT->action_icon( + $prefdata->url($params), + new pix_icon("t/hide", get_string('hide'))); + } + else { + $params = array( + 'action' => att_preferences_page_params::ACTION_SHOW, + 'statusid' => $st->id); + $showhideicon = $OUTPUT->action_icon( + $prefdata->url($params), + new pix_icon("t/show", get_string('show'))); + } + if (!$st->haslogs) { + $params = array( + 'action' => att_preferences_page_params::ACTION_DELETE, + 'statusid' => $st->id); + $deleteicon = $OUTPUT->action_icon( + $prefdata->url($params), + new pix_icon("t/delete", get_string('delete'))); + } + else $deleteicon = ''; + + return $showhideicon . $deleteicon; + } + + private function construct_preferences_button($text, $action) { + $attributes = array( + 'type' => 'submit', + 'value' => $text, + 'onclick' => 'M.mod_attforblock.set_preferences_action('.$action.')'); + return html_writer::empty_tag('input', $attributes); + } + } ?> diff --git a/report.php b/report.php index 78186be..f7e56a7 100644 --- a/report.php +++ b/report.php @@ -1,7 +1,7 @@