From da0b1f70c122d6b6e529e89e0e8c53d0d24f1bb3 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Mon, 4 Jan 2010 18:01:05 +0000 Subject: [PATCH] More work done on the Workshop Plan UI --- mod/workshop/lang/en_utf8/workshop.php | 13 +- mod/workshop/locallib.php | 162 ++++++++++++++++++++----- mod/workshop/renderer.php | 23 ++-- mod/workshop/styles.php | 33 ++++- mod/workshop/tabs.php | 7 +- mod/workshop/view.php | 3 +- 6 files changed, 193 insertions(+), 48 deletions(-) diff --git a/mod/workshop/lang/en_utf8/workshop.php b/mod/workshop/lang/en_utf8/workshop.php index c439afec08..ae56e68fad 100644 --- a/mod/workshop/lang/en_utf8/workshop.php +++ b/mod/workshop/lang/en_utf8/workshop.php @@ -26,16 +26,23 @@ defined('MOODLE_INTERNAL') || die(); $string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string['info'] = 'Info'; +$string['undersetup'] = 'The workshop is currently under setup. Please wait until it is switched to the next phase.'; +$string['taskinstructreviewers'] = 'Provide instructions for grading'; +$string['taskinstructauthors'] = 'Provide instructions for submitting'; +$string['taskintro'] = 'Set the workshop introduction'; $string['phaseclosed'] = 'Closed'; $string['phaseevaluation'] = 'Grading evaluation phase'; $string['phaseassessment'] = 'Assessment phase'; $string['phasesubmission'] = 'Submission phase'; -$string['phasesetup'] = 'Setup'; +$string['phasesetup'] = 'Setup phase'; $string['taskassessself'] = 'Assess yourself'; $string['taskassesspeers'] = 'Assess peers'; -$string['taskassesspeersinfo'] = 'total: $a->total
pending: $a->todo'; +$string['allocatedetails'] = 'submissions: $a->total
allocated: $a->done'; +$string['taskassesspeersdetails'] = 'total: $a->total
pending: $a->todo'; $string['tasksubmit'] = 'Submit your work'; -$string['taskeditform'] = 'Define the assessment form'; $string['accesscontrol'] = 'Access control'; $string['agreeassessments'] = 'Assessments must be agreed'; $string['agreeassessmentsdesc'] = 'Authors may comment assessments of their work and agree/disagree with it'; diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index d95295dea9..84b4cb929a 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -96,11 +96,38 @@ class workshop { */ public function __get($key) { if (!isset($this->dbrecord->{$key})) { - throw new coding_exception('You are trying to get a non-existing property'); + // todo remove the comment here // throw new coding_exception('You are trying to get a non-existing property'); + return null; } return $this->dbrecord->{$key}; } + /** + * Given a list of user ids, returns the filtered one containing just ids of users with own submission + * + * Example submissions are ignored. + * + * @param array $userids + * @return TODO + */ + protected function users_with_submission(array $userids) { + global $DB; + + $userswithsubmission = array(); + list($usql, $uparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); + $sql = "SELECT id,userid + FROM {workshop_submissions} + WHERE example = 0 AND workshopid = :workshopid AND userid $usql"; + $params = array('workshopid' => $this->id); + $params = array_merge($params, $uparams); + $submissions = $DB->get_records_sql($sql, $params); + foreach ($submissions as $submission) { + $userswithsubmission[$submission->userid] = null; + } + + return $userswithsubmission; + } + /** * Fetches all users with the capability mod/workshop:submit in the current context * @@ -110,25 +137,15 @@ class workshop { * @return array array[userid] => stdClass{->id ->lastname ->firstname} */ public function get_peer_authors($musthavesubmission=true) { - global $DB; $users = get_users_by_capability($this->context, 'mod/workshop:submit', 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true); if ($musthavesubmission) { - $userswithsubmission = array(); - $submissions = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'id,userid'); - foreach ($submissions as $submission) { - $userswithsubmission[$submission->userid] = null; - } - $userswithsubmission = array_intersect_key($users, $userswithsubmission); + $users = array_intersect_key($users, $this->users_with_submission(array_keys($users))); } - if ($musthavesubmission) { - return $userswithsubmission; - } else { - return $users; - } + return $users; } /** @@ -147,18 +164,10 @@ class workshop { if ($musthavesubmission) { // users without their own submission can not be reviewers - $submissions = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'id,userid'); - foreach ($submissions as $submission) { - $userswithsubmission[$submission->userid] = null; - } - $userswithsubmission = array_intersect_key($users, $userswithsubmission); + $users = array_intersect_key($users, $this->users_with_submission(array_keys($users))); } - if ($musthavesubmission) { - return $userswithsubmission; - } else { - return $users; - } + return $users; } /** @@ -594,6 +603,19 @@ class workshop { return new moodle_url($CFG->wwwroot . '/mod/workshop/submission.php', array('cmid' => $this->cm->id)); } + /** + * @return stdClass {@link moodle_url} the URL of the mod_edit form + */ + public function updatemod_url() { + global $CFG; + return new moodle_url($CFG->wwwroot . '/course/modedit.php', array('update' => $this->cm->id, 'return' => 1)); + } + + public function allocation_url() { + global $CFG; + return new moodle_url($CFG->wwwroot . '/mod/workshop/allocation.php', array('cmid' => $this->cm->id)); + } + /** * Returns an object containing all data to display the user's full name and picture * @@ -645,12 +667,43 @@ class workshop { $phase = new stdClass(); $phase->title = get_string('phasesetup', 'workshop'); $phase->tasks = array(); + if (has_capability('moodle/course:manageactivities', $this->context, $userid)) { + $task = new stdClass(); + $task->title = get_string('taskintro', 'workshop'); + $task->link = $this->updatemod_url(); + $task->completed = !(trim(strip_tags($this->intro)) == ''); + $phase->tasks['intro'] = $task; + } if (has_capability('mod/workshop:editdimensions', $this->context, $userid)) { $task = new stdClass(); - $task->title = get_string('taskeditform', 'workshop'); - $task->completed = $this->assessment_form_ready(); + $task->title = get_string('editassessmentform', 'workshop'); + $task->link = $this->editform_url(); + if ($this->assessment_form_ready()) { + $task->completed = true; + } elseif ($this->phase > self::PHASE_SETUP) { + $task->completed = false; + } $phase->tasks['editform'] = $task; } + if (has_capability('moodle/course:manageactivities', $this->context, $userid)) { + $task = new stdClass(); + $task->title = get_string('taskinstructauthors', 'workshop'); + $task->link = $this->updatemod_url(); + if (trim(strip_tags($this->instructauthors))) { + $task->completed = true; + } elseif ($this->phase >= self::PHASE_SUBMISSION) { + $task->completed = false; + } + $phase->tasks['instructauthors'] = $task; + } + if (empty($phase->tasks) and $this->phase == self::PHASE_SETUP) { + // if we are in the setup phase and there is no task (typical for students), let us + // display some explanation what is going on + $task = new stdClass(); + $task->title = get_string('undersetup', 'workshop'); + $task->completed = 'info'; + $phase->tasks['setupinfo'] = $task; + } $phases[self::PHASE_SETUP] = $phase; // Prepare tasks for the submission phase @@ -660,11 +713,61 @@ class workshop { if (has_capability('mod/workshop:submit', $this->context, $userid)) { $task = new stdClass(); $task->title = get_string('tasksubmit', 'workshop'); - $task->completed = $DB->record_exists('workshop_submissions', - array('workshopid' => $this->id, 'example' => 0, 'userid' => $userid)); + $task->link = $this->submission_url(); + if ($DB->record_exists('workshop_submissions', array('workshopid'=>$this->id, 'example'=>0, 'userid'=>$userid))) { + $task->completed = true; + } elseif ($this->phase >= self::PHASE_ASSESSMENT) { + $task->completed = false; + } else { + $task->completed = null; // still has a chance to submit + } $phase->tasks['submit'] = $task; } + if (has_capability('moodle/course:manageactivities', $this->context, $userid)) { + $task = new stdClass(); + $task->title = get_string('taskinstructreviewers', 'workshop'); + $task->link = $this->updatemod_url(); + if (trim(strip_tags($this->instructreviewers))) { + $task->completed = true; + } elseif ($this->phase >= self::PHASE_ASSESSMENT) { + $task->completed = false; + } + $phase->tasks['instructreviewers'] = $task; + } $phases[self::PHASE_SUBMISSION] = $phase; + if (has_capability('mod/workshop:allocate', $this->context, $userid)) { + $task = new stdClass(); + $task->title = get_string('allocate', 'workshop'); + $task->link = $this->allocation_url(); + $rs = $this->get_allocations_recordset(); + $allocations = array(); // 'submissionid' => isallocated + foreach ($rs as $allocation) { + if (!isset($allocations[$allocation->submissionid])) { + $allocations[$allocation->submissionid] = false; + } + if (!empty($allocation->reviewerid)) { + $allocations[$allocation->submissionid] = true; + } + } + $numofsubmissions = count($allocations); + $numofallocated = count(array_filter($allocations)); + $rs->close(); + if ($numofsubmissions == 0) { + $task->completed = null; + } elseif ($numofsubmissions == $numofallocated) { + $task->completed = true; + } elseif ($this->phase > self::PHASE_SUBMISSION) { + $task->completed = false; + } else { + $task->completed = null; // still has a chance to allocate + } + $a = new stdClass(); + $a->total = $numofsubmissions; + $a->done = $numofallocated; + $task->details = get_string('allocatedetails', 'workshop', $a); + unset($a); + $phase->tasks['submit'] = $task; + } // Prepare tasks for the peer-assessment phase (includes eventual self-assessments) $phase = new stdClass(); @@ -697,7 +800,7 @@ class workshop { $a->total = $numofpeers; $a->todo = $numofpeerstodo; $task->title = get_string('taskassesspeers', 'workshop'); - $task->info = get_string('taskassesspeersinfo', 'workshop', $a); + $task->details = get_string('taskassesspeersdetails', 'workshop', $a); unset($a); $phase->tasks['assesspeers'] = $task; } @@ -733,7 +836,8 @@ class workshop { foreach ($phase->tasks as $taskcode => $task) { $task->title = isset($task->title) ? $task->title : ''; - $task->info = isset($task->info) ? $task->info : ''; + $task->link = isset($task->link) ? $task->link : null; + $task->details = isset($task->details) ? $task->details : ''; $task->completed = isset($task->completed) ? $task->completed : null; } } diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index 16cbdb31e1..305967d0ca 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -63,7 +63,7 @@ class moodle_mod_workshop_renderer extends moodle_renderer_base { if (empty($message->text)) { return ''; } - $sty = $message->sty ? $message->sty : 'info'; + $sty = empty($message->sty) ? 'info' : $message->sty; $o = $this->output->output_tag('span', array(), $message->text); $closer = $this->output->output_tag('a', array('href' => $this->page->url->out()), @@ -287,18 +287,23 @@ class moodle_mod_workshop_renderer extends moodle_renderer_base { $classes = ''; $icon = null; if ($task->completed === true) { - $icon = new html_image(); - $icon->src = $this->old_icon_url('i/tick_green_big.gif'); - $icon->alt = '+'; $classes .= ' completed'; } elseif ($task->completed === false) { - $classes .= ' pending'; + $classes .= ' fail'; + } elseif ($task->completed === 'info') { + $classes .= ' info'; + } + if (is_null($task->link)) { + $title = $task->title; } else { - $classes .= ' statusunknown'; + $link = new html_link(); + $link->url = $task->link; + $link->text = $task->title; + $title = $this->output->link($link); } - $title = $this->output->container($task->title, 'title'); - $info = $this->output->container($task->info, 'info'); - $out .= $this->output->output_tag('li', array('class' => $classes), $title . $info); + $title = $this->output->container($title, 'title'); + $details = $this->output->container($task->details, 'details'); + $out .= $this->output->output_tag('li', array('class' => $classes), $title . $details); } if ($out) { $out = $this->output->output_tag('ul', array('class' => 'tasks'), $out); diff --git a/mod/workshop/styles.php b/mod/workshop/styles.php index d5e63606db..4545a084d0 100644 --- a/mod/workshop/styles.php +++ b/mod/workshop/styles.php @@ -186,6 +186,7 @@ .userplan { width: 70%; margin: 1em auto 1em auto; + font-size: 80%; } .userplan th { @@ -199,7 +200,7 @@ .userplan th.active { vertical-align: top; color: black; - font-size: 110%; + font-size: 140%; border: 1px solid #ddd; border-bottom: none; background-color: #e7f1c3; @@ -210,15 +211,31 @@ vertical-align: top; border-right: 1px solid #ddd; background-color: #f5f5f5; +} + +.userplan td, +.userplan td a, +.userplan td a:link, +.userplan td a:hover, +.userplan td a:visited, +.userplan td a:active { color: #999; } +.userplan td.active, +.userplan td.active a, +.userplan td.active a:link, +.userplan td.active a:hover, +.userplan td.active a:visited, +.userplan td.active a:active { + color: black; +} + .userplan td.lastcol { border-right: none; } .userplan td.active { - color: black; border-left: 1px solid #ddd; border-right: 1px solid #ddd; background-color: #e7f1c3; @@ -230,10 +247,18 @@ background-repeat: no-repeat; } -.userplan tr.phasetasks .completed { +.userplan tr.phasetasks li.completed { background-image: url(../../pix/i/completion-auto-y.gif); } +.userplan tr.phasetasks li.fail { + background-image: url(../../pix/i/completion-auto-fail.gif); +} + +.userplan tr.phasetasks li.info { + background-image: url(../../pix/i/info.gif); +} + .userplan tr.phasetasks .tasks { list-style:none; margin: 3px; @@ -244,7 +269,7 @@ padding: 0px 10px 0px 20px; } -.userplan tr.phasetasks .info { +.userplan tr.phasetasks .details { padding: 0px 10px 0px 25px; font-size: 80%; } diff --git a/mod/workshop/tabs.php b/mod/workshop/tabs.php index 4d633b063a..4678158f45 100644 --- a/mod/workshop/tabs.php +++ b/mod/workshop/tabs.php @@ -40,12 +40,15 @@ $inactive = array(); $activated = array(); // top level tabs -if (has_capability('mod/workshop:view', $PAGE->context)) { +if (has_capability('mod/workshop:view', $workshop->context)) { $row[] = new tabobject('info', $workshop->view_url()->out(), get_string('info', 'workshop')); } -if (has_capability('mod/workshop:editdimensions', $PAGE->context)) { +if (has_capability('mod/workshop:editdimensions', $workshop->context)) { $row[] = new tabobject('editform', $workshop->editform_url()->out(), get_string('editassessmentform', 'workshop')); } +if (has_capability('mod/workshop:submit', $workshop->context)) { + $row[] = new tabobject('submission', $workshop->submission_url()->out(), get_string('editsubmission', 'workshop')); +} $tabs[] = $row; print_tabs($tabs, $currenttab, $inactive, $activated); diff --git a/mod/workshop/view.php b/mod/workshop/view.php index 4f0954f81b..5b545051e2 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -76,6 +76,8 @@ $wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE); echo $OUTPUT->header(); include(dirname(__FILE__) . '/tabs.php'); +echo $OUTPUT->heading(format_string($workshop->name)); + $workshop->phase = 10; // todo xxx devel hack echo $wsoutput->user_plan($workshop->prepare_user_plan($USER->id)); @@ -83,7 +85,6 @@ echo $wsoutput->user_plan($workshop->prepare_user_plan($USER->id)); switch ($workshop->phase) { case workshop::PHASE_SETUP: // print workshop name and description - echo $OUTPUT->heading(format_string($workshop->name)); if (trim(strip_tags($workshop->intro))) { echo $OUTPUT->box(format_module_intro('workshop', $workshop, $workshop->cm->id), 'generalbox', 'intro'); } -- 2.39.5