More work done on the Workshop Plan UI
authorDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:01:05 +0000 (18:01 +0000)
committerDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:01:05 +0000 (18:01 +0000)
mod/workshop/lang/en_utf8/workshop.php
mod/workshop/locallib.php
mod/workshop/renderer.php
mod/workshop/styles.php
mod/workshop/tabs.php
mod/workshop/view.php

index c439afec08ccb0c1a4cfe7c1a3d26095dc4b81c6..ae56e68fadc9ee0b5125f36e49aa29a4cfda4b4a 100644 (file)
 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<br />pending: $a->todo';
+$string['allocatedetails'] = 'submissions: $a->total<br />allocated: $a->done';
+$string['taskassesspeersdetails'] = 'total: $a->total<br />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';
index d95295dea99261d4889ca9a0bbbfaa43757a640c..84b4cb929a558ed7bafc62454eadccf54c3d5bb0 100644 (file)
@@ -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;
             }
         }
index 16cbdb31e197cedf2603206105b064b701d9b62f..305967d0ca30380caf46eea4a6ba88fe2d8b5abe 100644 (file)
@@ -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);
index d5e63606dbe6cfab853f0fd8e2a1defbc68d2a72..4545a084d058ba7803bc168acab42199ccb01707 100644 (file)
 .userplan {
     width: 70%;
     margin: 1em auto 1em auto;
+    font-size: 80%;
 }
 
 .userplan th {
 .userplan th.active {
     vertical-align: top;
     color: black;
-    font-size: 110%;
+    font-size: 140%;
     border: 1px solid #ddd;
     border-bottom: none;
     background-color: #e7f1c3;
     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;
     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;
     padding: 0px 10px 0px 20px;
 }
 
-.userplan tr.phasetasks .info {
+.userplan tr.phasetasks .details {
     padding: 0px 10px 0px 25px;
     font-size: 80%;
 }
index 4d633b063a62d31b22af101050c8ae55b6e1cc97..4678158f45ff969806377e0f42f306150450590b 100644 (file)
@@ -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);
index 4f0954f81b0a26dc95034065480931517bb717c2..5b545051e277987eac14695c529ed092f00f6067 100644 (file)
@@ -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');
     }