From b8ead2e6a4d5e970d8757f856b79f2125b1f0895 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Mon, 4 Jan 2010 17:48:33 +0000 Subject: [PATCH] Uses workshop renderer to display assessment page Some small refactoring like using single function to group users done. --- mod/workshop/allocation/manual/renderer.php | 24 ++- mod/workshop/allocation/random/allocator.php | 6 +- mod/workshop/assessment.php | 100 +++++------ mod/workshop/editform.php | 24 +-- mod/workshop/grading/strategy.php | 4 +- mod/workshop/lang/en_utf8/workshop.php | 6 +- mod/workshop/lib.php | 14 +- mod/workshop/locallib.php | 168 +++++++++++-------- mod/workshop/renderer.php | 132 ++++++++++++++- mod/workshop/styles.php | 56 +++++++ mod/workshop/submission.php | 4 +- mod/workshop/view.php | 15 +- 12 files changed, 385 insertions(+), 168 deletions(-) diff --git a/mod/workshop/allocation/manual/renderer.php b/mod/workshop/allocation/manual/renderer.php index 5effbc7606..3ceddae5b5 100644 --- a/mod/workshop/allocation/manual/renderer.php +++ b/mod/workshop/allocation/manual/renderer.php @@ -131,10 +131,7 @@ class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_bas if (is_null($user->submissionid)) { $o .= $this->output->output_tag('span', array('class' => 'info'), get_string('nothingtoreview', 'workshop')); } else { - $options = array(); - foreach ($workshop->get_peer_reviewers(!$workshop->assesswosubmission) as $reviewer) { - $options[$reviewer->id] = fullname($reviewer); - } + $options = $this->users_to_menu_options($workshop->get_peer_reviewers(!$workshop->assesswosubmission)); if (!$workshop->useselfassessment) { // students can not review their own submissions in this workshop if (isset($options[$user->id])) { @@ -173,10 +170,7 @@ class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_bas if (is_null($user->submissionid)) { $o .= $this->output->container(get_string('withoutsubmission', 'workshop'), 'info'); } - $options = array(); - foreach ($workshop->get_peer_authors() as $author) { - $options[$author->id] = fullname($author); - } + $options = $this->users_to_menu_options($workshop->get_peer_authors()); if (!$workshop->useselfassessment) { // students can not be reviewed by themselves in this workshop if (isset($options[$user->id])) { @@ -202,4 +196,18 @@ class moodle_mod_workshop_allocation_manual_renderer extends moodle_renderer_bas return $o; } + /** + * Given a list of users, returns an array suitable to render the HTML select field + * + * @param array $users array of users or array of groups of users + * @return array of options to be passed to {@see popup_form()} + */ + protected function users_to_menu_options(&$users) { + $options = array(); + foreach ($users as $user) { + $options[$user->id] = fullname($user); + } + return $options; + } + } diff --git a/mod/workshop/allocation/random/allocator.php b/mod/workshop/allocation/random/allocator.php index fb0fcfbc25..d1268b06c4 100644 --- a/mod/workshop/allocation/random/allocator.php +++ b/mod/workshop/allocation/random/allocator.php @@ -84,8 +84,10 @@ class workshop_random_allocator implements workshop_allocator { $musthavesubmission = empty($assesswosubmission); $addselfassessment = required_param('addselfassessment', PARAM_INT); - $authors = $this->workshop->get_peer_authors_by_group(); - $reviewers = $this->workshop->get_peer_reviewers_by_group($musthavesubmission); + $authors = $this->workshop->get_peer_authors(); + $authors = $this->workshop->get_grouped($authors); + $reviewers = $this->workshop->get_peer_reviewers($musthavesubmission); + $reviewers = $this->workshop->get_grouped($reviewers); $assessments = $this->workshop->get_assessments(); $newallocations = array(); // array of (reviewer,reviewee) tuples diff --git a/mod/workshop/assessment.php b/mod/workshop/assessment.php index 639fc8f217..b995d7700c 100644 --- a/mod/workshop/assessment.php +++ b/mod/workshop/assessment.php @@ -30,58 +30,42 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); require_once(dirname(__FILE__).'/locallib.php'); if ($preview = optional_param('preview', 0, PARAM_INT)) { - $mode = 'preview'; - if (!$cm = get_coursemodule_from_id('workshop', $preview)) { - print_error('invalidcoursemodule'); - } - if (!$course = $DB->get_record('course', array('id' => $cm->course))) { - print_error('coursemisconf'); - } - if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { - print_error('err_invalidworkshopid', 'workshop'); - } + $mode = 'preview'; + $cm = get_coursemodule_from_id('workshop', $preview, 0, false, MUST_EXIST); + $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); + $workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); $submission = new stdClass(); $assessment = new stdClass(); + } else { - $mode = 'assessment'; - $assessmentid = required_param('asid', PARAM_INT); // assessment id - if (!$assessment = $DB->get_record('workshop_assessments', array('id' => $assessmentid))) { - print_error('err_unknownassessment', 'workshop'); - } - if (!$submission = $DB->get_record('workshop_submissions', array('id' => $assessment->submissionid))) { - print_error('err_unknownsubmission', 'workshop'); - } - if (!$workshop = $DB->get_record('workshop', array('id' => $submission->workshopid))) { - print_error('err_invalidworkshopid', 'workshop'); - } - if (!$cm = get_coursemodule_from_instance('workshop', $workshop->id, $workshop->course)) { - print_error('invalidcoursemodule'); - } - if (!$course = $DB->get_record('course', array('id' => $cm->course))) { - print_error('coursemisconf'); - } + $mode = 'assessment'; + $asid = required_param('asid', PARAM_INT); // assessment id + $assessment = $DB->get_record('workshop_assessments', array('id' => $asid), '*', MUST_EXIST); + $submission = $DB->get_record('workshop_submissions', array('id' => $assessment->submissionid), '*', MUST_EXIST); + $workshop = $DB->get_record('workshop', array('id' => $submission->workshopid), '*', MUST_EXIST); + $course = $DB->get_record('course', array('id' => $workshop->course), '*', MUST_EXIST); + $cm = get_coursemodule_from_instance('workshop', $workshop->id, $course->id, false, MUST_EXIST); } require_login($course, false, $cm); - $workshop = new workshop_api($workshop, $cm, $course); -$context = $PAGE->context; +if ('preview' == $mode) { + require_capability('mod/workshop:editdimensions', $PAGE->context); + // TODO logging add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id"); + $PAGE->set_url($workshop->previewform_url()); + $PAGE->set_title($workshop->name); + $PAGE->set_heading($course->fullname); -if (isguestuser()) { - print_error('err_noguests', 'workshop', "$CFG->wwwroot/mod/workshop/view.php?id=$cmid"); -} - -// where should the user be sent after closing the assessment form -$returnurl = "{$CFG->wwwroot}/mod/workshop/view.php?id={$cm->id}"; -// the URL of this handler -if ($mode == 'preview') { - $selfurl = "{$CFG->wwwroot}/mod/workshop/assessment.php?preview={$cm->id}"; -} elseif ($mode == 'assessment') { - $selfurl = "{$CFG->wwwroot}/mod/workshop/assessment.php?asid={$assessment->id}"; +} elseif ('assessment' == $mode) { + if (!(has_capability('mod/workshop:peerassess', $PAGE->context) || has_capability('mod/workshop:peerassess', $PAGE->context))) { + print_error('nopermissions', '', $workshop->view_url()); + } + // TODO logging add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id"); + $PAGE->set_url($workshop->assess_url($assessment->id)); + $PAGE->set_title($workshop->name); + $PAGE->set_heading($course->fullname); } -// the URL to edit this assessment form -$editurl = "{$CFG->wwwroot}/mod/workshop/editform.php?cmid={$cm->id}"; // load the grading strategy logic $strategy = $workshop->grading_strategy_instance(); @@ -93,23 +77,24 @@ $strategy = $workshop->grading_strategy_instance(); //todo $formdata = $strategy->load_assessment($assessment); // load the form to edit the grading strategy dimensions -$mform = $strategy->get_assessment_form($selfurl, $mode); +$mform = $strategy->get_assessment_form($PAGE->url, $mode); // initialize form data //todo $mform->set_data($formdata); if ($mform->is_cancelled()) { redirect($returnurl); + } elseif ($data = $mform->get_data()) { if (isset($data->backtoeditform)) { - redirect($editurl); + redirect($workshop->editform_url()); } $strategy->save_assessment($data); if (isset($data->saveandclose)) { - redirect($returnurl); + redirect($workshop->view_url()); } else { // save and continue - redirect to self to prevent data being re-posted by pressing "Reload" - redirect($selfurl); + redirect($PAGE->url->out()); } } @@ -123,7 +108,7 @@ $navlinks[] = array('name' => format_string($workshop->name), 'type' => 'activityinstance'); if ($mode == 'preview') { $navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'), - 'link' => $editurl, + 'link' => $workshop->editform_url(), 'type' => 'title'); $navlinks[] = array('name' => get_string('previewassessmentform', 'workshop'), 'link' => '', @@ -135,13 +120,18 @@ if ($mode == 'preview') { } $navigation = build_navigation($navlinks); -// OUTPUT STARTS HERE - -print_header_simple(format_string($workshop->name), '', $navigation, '', '', true, '', navmenu($course, $cm)); - -print_heading(get_string('assessmentform', 'workshop')); +// Output starts here +$wsoutput = $THEME->get_renderer('mod_workshop', $PAGE); // workshop renderer +echo $OUTPUT->header($navigation); +echo $OUTPUT->heading(get_string('assessmentform', 'workshop'), 2); +if (has_capability('mod/workshop:viewauthornames', $PAGE->context)) { + $showname = true; + $author = $workshop->user_info($submission->userid); +} else { + $showname = false; + $author = null; +} +echo $wsoutput->submission_full($submission, $showname, $author); $mform->display(); - -/// Finish the page -print_footer($course); +echo $OUTPUT->footer(); diff --git a/mod/workshop/editform.php b/mod/workshop/editform.php index 12ab1b889c..3499056ceb 100644 --- a/mod/workshop/editform.php +++ b/mod/workshop/editform.php @@ -26,26 +26,20 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); require_once(dirname(__FILE__).'/locallib.php'); -$cmid = required_param('cmid', PARAM_INT); // course module id +$cmid = required_param('cmid', PARAM_INT); $cm = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); require_login($course, false, $cm); -if (isguestuser()) { - print_error('guestnoedit', 'workshop', "$CFG->wwwroot/mod/workshop/view.php?id=$cmid"); -} require_capability('mod/workshop:editdimensions', $PAGE->context); $workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); $workshop = new workshop_api($workshop, $cm, $course); -// where should the user be sent after closing the editing form -$returnurl = "{$CFG->wwwroot}/mod/workshop/view.php?id={$cm->id}"; -// the URL of this editing form -$selfurl = "{$CFG->wwwroot}/mod/workshop/editform.php?cmid={$cm->id}"; -// the URL to preview the assessment form -$previewurl = "{$CFG->wwwroot}/mod/workshop/assessment.php?preview={$cm->id}"; +$PAGE->set_url($workshop->editform_url()); +$PAGE->set_title($workshop->name); +$PAGE->set_heading($course->fullname); // load the grading strategy logic $strategy = $workshop->grading_strategy_instance(); @@ -56,22 +50,22 @@ $strategy = $workshop->grading_strategy_instance(); $formdata = $strategy->load_form(); // load the form to edit the grading strategy dimensions -$mform = $strategy->get_edit_strategy_form($selfurl); +$mform = $strategy->get_edit_strategy_form($PAGE->url); // initialize form data $mform->set_data($formdata); if ($mform->is_cancelled()) { - redirect($returnurl); + redirect($workshop->view_url()); } elseif ($data = $mform->get_data()) { $strategy->save_form($data); if (isset($data->saveandclose)) { - redirect($returnurl); + redirect($workshop->view_url()); } elseif (isset($data->saveandpreview)) { - redirect($previewurl); + redirect($workshop->previewform_url()); } else { // save and continue - redirect to self to prevent data being re-posted by pressing "Reload" - redirect($selfurl); + redirect($PAGE->url); } } diff --git a/mod/workshop/grading/strategy.php b/mod/workshop/grading/strategy.php index e5f5185912..290363d2c3 100644 --- a/mod/workshop/grading/strategy.php +++ b/mod/workshop/grading/strategy.php @@ -154,10 +154,10 @@ abstract class workshop_base_strategy implements workshop_strategy { * By default, the class is defined in grading/{strategy}/assessment_form.php and is named * workshop_{strategy}_assessment_form * - * @param string $actionurl URL of form handler, defaults to auto detect the current url + * @param moodle_url $actionurl URL of form handler, defaults to auto detect the current url * @param string $mode Mode to open the form in: preview/assessment */ - public function get_assessment_form($actionurl=null, $mode='preview') { + public function get_assessment_form(moodle_url $actionurl=null, $mode='preview') { global $CFG; // needed because the included files use it $assessmentform = dirname(__FILE__) . '/' . $this->name . '/assessment_form.php'; diff --git a/mod/workshop/lang/en_utf8/workshop.php b/mod/workshop/lang/en_utf8/workshop.php index d9e1c4837c..194ba51691 100644 --- a/mod/workshop/lang/en_utf8/workshop.php +++ b/mod/workshop/lang/en_utf8/workshop.php @@ -25,9 +25,9 @@ defined('MOODLE_INTERNAL') || die(); -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; +$string['userdatecreated'] = 'submitted on $a'; +$string['userdatemodified'] = 'modified on $a'; +$string['byfullname'] = 'by url}\">{$a->name}'; $string[''] = ''; $string[''] = ''; $string[''] = ''; diff --git a/mod/workshop/lib.php b/mod/workshop/lib.php index 4f1fe1c564..0dc0c277d3 100644 --- a/mod/workshop/lib.php +++ b/mod/workshop/lib.php @@ -316,14 +316,18 @@ function workshop_get_extra_capabilities() { return array('moodle/site:accessallgroups'); } -//////////////////////////////// -/// File API /////////////////// -//////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// File API // +//////////////////////////////////////////////////////////////////////////////// /** - * Serves the submission attachments + * Serves the files from the workshop file areas * - * The access rights to the file are checked here. + * Apart from module intro (handled by pluginfile.php automatically), workshop files may be + * media inserted into submission content (like images) and submission attachments. For these two, + * the fileareas workshop_submission_content and workshop_submission_attachment are used. + * The access rights to the files are checked here. The user must be either a peer-reviewer + * of the submission or have capability ... (todo) to access the submission files. * * @param object $course * @param object $cminfo diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index 2d17ada78c..ca44945987 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -78,7 +78,10 @@ class workshop_api extends workshop { } if ($musthavesubmission && is_null($userswithsubmission)) { - $userswithsubmission = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'userid'); + $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); } @@ -89,49 +92,6 @@ class workshop_api extends workshop { } } - /** - * Returns all users with the capability mod/workshop:submit sorted by groups - * - * This takes the module grouping settings into account. If "Available for group members only" - * is set, returns only groups withing the course module grouping. - * - * @param bool $musthavesubmission If true, return only users who have already submitted. All possible authors otherwise. - * @return array array[groupid][userid] => stdClass{->id ->lastname ->firstname} - */ - public function get_peer_authors_by_group($musthavesubmission=true) { - global $DB; - - $authors = $this->get_peer_authors($musthavesubmission); - $gauthors = array(); // grouped authors to be returned - if (empty($authors)) { - return $gauthors; - } - if ($this->cm->groupmembersonly) { - // Available for group members only - the workshop is available only - // to users assigned to groups within the selected grouping, or to - // any group if no grouping is selected. - $groupingid = $this->cm->groupingid; - // All authors that are members of at least one group will be - // added into a virtual group id 0 - $gauthors[0] = array(); - } else { - $groupingid = 0; - // there is no need to be member of a group so $gauthors[0] will contain - // all authors with a submission - $gauthors[0] = $authors; - } - $gmemberships = groups_get_all_groups($this->cm->course, array_keys($authors), $groupingid, - 'gm.id,gm.groupid,gm.userid'); - foreach ($gmemberships as $gmembership) { - if (!isset($gauthors[$gmembership->groupid])) { - $gauthors[$gmembership->groupid] = array(); - } - $gauthors[$gmembership->groupid][$gmembership->userid] = $authors[$gmembership->userid]; - $gauthors[0][$gmembership->userid] = $authors[$gmembership->userid]; - } - return $gauthors; - } - /** * Fetches all users with the capability mod/workshop:peerassess in the current context * @@ -139,6 +99,7 @@ class workshop_api extends workshop { * and firstname properties and are ordered by lastname,firstname * * @param bool $musthavesubmission If true, return only users who have already submitted. All possible users otherwise. + * @see get_super_reviewers() * @return array array[userid] => stdClass{->id ->lastname ->firstname} */ public function get_peer_reviewers($musthavesubmission=false) { @@ -152,7 +113,10 @@ class workshop_api extends workshop { 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true); if ($musthavesubmission && is_null($userswithsubmission)) { // users without their own submission can not be reviewers - $userswithsubmission = $DB->get_records_list('workshop_submissions', 'userid', array_keys($users),'', 'userid'); + $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); } } @@ -164,46 +128,68 @@ class workshop_api extends workshop { } /** - * Returns all users with the capability mod/workshop:peerassess sorted by groups + * Fetches all users with the capability mod/workshop:assessallsubmissions in the current context * - * This takes the module grouping settings into account. If "Available for group members only" - * is set, returns only groups withing the course module grouping. + * Static variable used to cache the results. The returned objects contain id, lastname + * and firstname properties and are ordered by lastname,firstname * * @param bool $musthavesubmission If true, return only users who have already submitted. All possible users otherwise. + * @see get_peer_reviewers() + * @return array array[userid] => stdClass{->id ->lastname ->firstname} + */ + public function get_super_reviewers() { + global $DB; + static $users = null; + + if (is_null($users)) { + $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); + $users = get_users_by_capability($context, 'mod/workshop:assessallsubmissions', + 'u.id, u.lastname, u.firstname', 'u.lastname,u.firstname', '', '', '', '', false, false, true); + } + return $users; + } + + /** + * Groups the given users by the group membership + * + * This takes the module grouping settings into account. If "Available for group members only" + * is set, returns only groups withing the course module grouping. Always returns group [0] with + * all the given users. + * + * @param array $users array[userid] => stdClass{->id ->lastname ->firstname} * @return array array[groupid][userid] => stdClass{->id ->lastname ->firstname} */ - public function get_peer_reviewers_by_group($musthavesubmission=false) { + public function get_grouped(&$users) { global $DB; - $reviewers = $this->get_peer_reviewers($musthavesubmission); - $greviewers = array(); // grouped reviewers to be returned - if (empty($reviewers)) { - return $greviewers; + $grouped = array(); // grouped users to be returned + if (empty($users)) { + return $grouped; } if ($this->cm->groupmembersonly) { // Available for group members only - the workshop is available only // to users assigned to groups within the selected grouping, or to // any group if no grouping is selected. $groupingid = $this->cm->groupingid; - // All reviewers that are members of at least one group will be + // All users that are members of at least one group will be // added into a virtual group id 0 - $greviewers[0] = array(); + $grouped[0] = array(); } else { $groupingid = 0; - // there is no need to be member of a group so $greviewers[0] will contain - // all reviewers - $greviewers[0] = $reviewers; + // there is no need to be member of a group so $grouped[0] will contain + // all users + $grouped[0] = $users; } - $gmemberships = groups_get_all_groups($this->cm->course, array_keys($reviewers), $groupingid, + $gmemberships = groups_get_all_groups($this->cm->course, array_keys($users), $groupingid, 'gm.id,gm.groupid,gm.userid'); foreach ($gmemberships as $gmembership) { - if (!isset($greviewers[$gmembership->groupid])) { - $greviewers[$gmembership->groupid] = array(); + if (!isset($grouped[$gmembership->groupid])) { + $grouped[$gmembership->groupid] = array(); } - $greviewers[$gmembership->groupid][$gmembership->userid] = $reviewers[$gmembership->userid]; - $greviewers[0][$gmembership->userid] = $reviewers[$gmembership->userid]; + $grouped[$gmembership->groupid][$gmembership->userid] = $users[$gmembership->userid]; + $grouped[0][$gmembership->userid] = $users[$gmembership->userid]; } - return $greviewers; + return $grouped; } /** @@ -334,11 +320,12 @@ class workshop_api extends workshop { * mainly they do not contain text fields. * * @param mixed $reviewerid 'all'|int|array User ID of the reviewer + * @param mixed $id 'all'|int Assessment ID * @return array [assessmentid] => assessment object * @see workshop_api::get_assessments_recordset() for the structure of returned objects */ - public function get_assessments($reviewerid='all') { - $rs = $this->get_assessments_recordset($reviewerid, 'all'); + public function get_assessments($reviewerid='all', $id='all') { + $rs = $this->get_assessments_recordset($reviewerid, $id); $assessments = array(); foreach ($rs as $assessment) { // copy selected properties into the array to be returned. This is here mainly in order not @@ -545,6 +532,55 @@ class workshop_api extends workshop { return new $classname($this); } + /** + * @return object {@link moodle_url} the URL of this workshop's view page + */ + public function view_url() { + global $CFG; + return new moodle_url($CFG->wwwroot . '/mod/workshop/view.php', array('id' => $this->cm->id)); + } + + /** + * @return object {@link moodle_url} the URL of the page for editing this workshop's grading form + */ + public function editform_url() { + global $CFG; + return new moodle_url($CFG->wwwroot . '/mod/workshop/editform.php', array('cmid' => $this->cm->id)); + } + + /** + * @return object {@link moodle_url} the URL of the page for previewing this workshop's grading form + */ + public function previewform_url() { + global $CFG; + return new moodle_url($CFG->wwwroot . '/mod/workshop/assessment.php', array('preview' => $this->cm->id)); + } + + /** + * @param int $assessmentid The ID of assessment record + * @return object {@link moodle_url} the URL of the assessment page + */ + public function assess_url() { + global $CFG; + return new moodle_url($CFG->wwwroot . '/mod/workshop/assessment.php', array('asid' => $this->cm->id)); + } + + /** + * Returns an object containing all data to display the user's full name and picture + * + * @param int $id optional user id, defaults to the current user + * @return object containing properties lastname, firstname, picture and imagealt + */ + public function user_info($id=null) { + global $USER, $DB; + + if (is_null($id) || ($id == $USER->id)) { + return $USER; + } else { + return $DB->get_record('user', array('id' => $id), 'id,lastname,firstname,picture,imagealt', MUST_EXIST); + } + } + } /** diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index 8795147cbd..fed5272927 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -84,7 +84,7 @@ class moodle_mod_workshop_renderer extends moodle_renderer_base { * the type of the message and may influence its visualisation. * * @param mixed $result int|array returned by init() - * @return string $html to be echoed + * @return string html to be echoed */ public function allocation_init_result($result='') { $msg = new stdClass(); @@ -112,4 +112,134 @@ class moodle_mod_workshop_renderer extends moodle_renderer_base { return $o; } + /** + * Displays the submission fulltext + * + * By default, this looks similar to a forum post. + * + * @param stdClass $submission The submission record + * @param bool $showauthorname Should the author name be displayed + * @param stdClass $author If author's name should be displayed, this object contains the author data + * @return string html to be echoed + */ + public function submission_full(stdClass $submission, $showauthorname=false, stdClass $author=null) { + global $CFG; + + $o = ''; // output code + $at = array('class' => 'submission-full'); + if (!$showauthorname || !$author) { + $at['class'] .= ' anonymous'; + } + $o .= $this->output->output_start_tag('div', $at); //+ + $o .= $this->output->output_start_tag('div', array('class' => 'header')); //++ + $o .= $this->output->heading(format_string($submission->title), 3, 'title'); + if ($showauthorname && $author) { + $o .= $this->output->output_start_tag('div', array('class' => 'author')); //+++ + $userpic = new user_picture(); + $userpic->user = $author; + $userpic->courseid = $this->page->course->id; + $userpic->url = true; + $userpic->size = 64; + $userpic = $this->output->user_picture($userpic); + $userurl = new moodle_url($CFG->wwwroot . '/user/view.php', + array('id' => $author->id, 'course' => $this->page->course->id)); + $a = new stdClass(); + $a->name = fullname($author); + $a->url = $userurl->out(); + $byfullname = get_string('byfullname', 'workshop', $a); + $o .= $this->output->output_tag('div', array('class' => 'picture'), $userpic); + $o .= $this->output->output_tag('div', array('class' => 'fullname'), $byfullname); + $o .= $this->output->output_end_tag('div'); // end of author //++ + } + $created = get_string('userdatecreated', 'workshop', userdate($submission->timecreated)); + $o .= $this->output->output_tag('div', array('class' => 'userdate created'), $created); + if ($submission->timemodified > $submission->timecreated) { + $modified = get_string('userdatemodified', 'workshop', userdate($submission->timemodified)); + $o .= $this->output->output_tag('div', array('class' => 'userdate modified'), $modified); + } + $o .= $this->output->output_end_tag('div'); // end of header //+ + + $content = format_text($submission->content, $submission->contentformat); + $content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $this->page->context->id, + 'workshop_submission_content', $submission->id); + $o .= $this->output->output_tag('div', array('class' => 'content'), $content); + + $o .= $this->submission_attachments($submission); + + $o .= $this->output->output_end_tag('div'); // end of submission-full // + + return $o; + } + + /** + * Renders a list of files attached to the submission + * + * If format==html, then format a html string. If format==text, then format a text-only string. + * Otherwise, returns html for non-images and html to display the image inline. + * + * @param stdClass $submission Submission record + * @param string format The format of the returned string + * @return string HTML code to be echoed + */ + public function submission_attachments(stdClass $submission, $format=null) { + global $CFG; + require_once($CFG->libdir.'/filelib.php'); + + $fs = get_file_storage(); + $ctx = $this->page->context; + $files = $fs->get_area_files($ctx->id, 'workshop_submission_attachment', $submission->id); + + $outputimgs = ""; // images to be displayed inline + $outputfiles = ""; // list of attachment files + + foreach ($files as $file) { + if ($file->is_directory()) { + continue; + } + + $filename = $file->get_filename(); + $fileurl = file_encode_url($CFG->wwwroot . '/pluginfile.php', + '/' . $ctx->id . '/workshop_submission_attachment/' . $submission->id . '/' . $filename, true); + $type = $file->get_mimetype(); + $type = mimeinfo_from_type("type", $type); + $icon = new html_image(); + $icon->src = $this->output->old_icon_url(file_mimetype_icon($type)); + $icon->set_classes('icon'); + $icon->alt = $type; + $image = $this->output->image($icon); + + $linkhtml = $this->output->link($fileurl, $image) . $this->output->link($fileurl, $filename); + $linktxt = "$filename [$fileurl]"; + + if ($format == "html") { + // this is the same as the code in the last else-branch + $outputfiles .= $this->output->output_tag('li', array('class' => $type), $linkhtml); + + } else if ($format == "text") { + $outputfiles .= $linktxt . "\n"; + + } else { + if (in_array($type, array('image/gif', 'image/jpeg', 'image/png'))) { + $preview = new html_image(); + $preview->src = $fileurl; + $preview->set_classes('preview'); + $preview = $this->output->image($preview); + $preview = $this->output->link($fileurl, $preview); + $outputimgs .= $this->output->output_tag('div', array(), $preview); + } else { + // this is the same as the code in html if-branch + $outputfiles .= $this->output->output_tag('li', array('class' => $type), $linkhtml); + } + } + } + + if ($outputimgs) { + $outputimgs = $this->output->output_tag('div', array('class' => 'images'), $outputimgs); + } + if ($format !== "text") { + $outputfiles = $this->output->output_tag('ul', array('class' => 'files'), $outputfiles); + } + return $this->output->output_tag('div', array('class' => 'attachments'), $outputimgs . $outputfiles); + } + } diff --git a/mod/workshop/styles.php b/mod/workshop/styles.php index 7ae5de33a7..c80a38f288 100644 --- a/mod/workshop/styles.php +++ b/mod/workshop/styles.php @@ -1,3 +1,59 @@ +/** + * Submission - full display + */ +.submission-full { + border: 1px solid #ddd; +} + +.submission-full .header { + position: relative; + background-color: #ddd; + padding: 3px; +} + +.submission-full .header .title, +.submission-full .header .author, +.submission-full .header .userdate { + margin: 0px 0px 0px 80px; +} + +.submission-full.anonymous .header .title, +.submission-full.anonymous .header .author, +.submission-full.anonymous .header .userdate { + margin: 0px 0px 0px 5px; +} + +.submission-full .header .userdate.modified { + margin-left: 10px; + padding-left: 10px; + border-left: 1px solid #000; +} + +.submission-full .header .userdate { + font-size: x-small; + color: #333; + display: inline; +} + +.submission-full .header .userdate span { + font-style: italic; +} + +.submission-full .header .author .picture { + position: absolute; + top: 3px; + left: 3px; +} + +.submission-full .content, +.submission-full .attachments { + padding: 5px 10px; +} + +.submission-full .attachments .files img.icon { + margin-right: 5px; +} + /** * Elements generated by the workshop renderer */ diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index bb808cee94..f2857108e5 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -35,10 +35,10 @@ $cm = get_coursemodule_from_id('workshop', $cmid, 0, false, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); require_login($course, false, $cm); +require_capability('mod/workshop:submit', $PAGE->context); if (isguestuser()) { - print_error('guestnoedit', 'workshop', "$CFG->wwwroot/mod/workshop/view.php?id=$cmid"); + print_error('guestsarenotallowed'); } -require_capability('mod/workshop:submit', $PAGE->context); $workshop = $DB->get_record('workshop', array('id' => $cm->instance), '*', MUST_EXIST); $workshop = new workshop_api($workshop, $cm, $course); diff --git a/mod/workshop/view.php b/mod/workshop/view.php index 2a3f85e23b..c9b9bf79c5 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -42,18 +42,17 @@ if ($id) { $cm = get_coursemodule_from_instance('workshop', $workshop->id, $course->id, false, MUST_EXIST); } -$workshop = new workshop_api($workshop, $cm, $course); require_login($course, true, $cm); -$context = $PAGE->context; +$workshop = new workshop_api($workshop, $cm, $course); // todo has_capability() check using something like // if (!(($workshop->is_open() && has_capability('mod/workshop:view')) || has_capability(...) || has_capability(...))) { // unable to view this page // -add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id"); +// todo logging add_to_log($course->id, "workshop", "view", "view.php?id=$cm->id", "$workshop->id"); -$PAGE->set_url('mod/workshop/view.php', array('id' => $cm->id)); +$PAGE->set_url($workshop->view_url()); $PAGE->set_title($workshop->name); $PAGE->set_heading($course->fullname); $PAGE->set_button(update_module_button($cm->id, $course->id, get_string('modulename', 'workshop'))); @@ -69,18 +68,16 @@ $navlinks[] = array('name' => format_string($workshop->name), $navigation = build_navigation($navlinks); $menu = navmenu($course, $cm); -$output = $THEME->get_renderer('mod_workshop', $PAGE); +/// Output starts here echo $OUTPUT->header($navigation, $menu); -echo $OUTPUT->heading('Workshop administration tools', 3); - /// Print the main part of the page - todo these are just links to help during development - +echo $OUTPUT->heading('Workshop administration tools', 3); echo $OUTPUT->box_start(); echo $OUTPUT->heading('Workshop administration tools', 3); echo ''; -- 2.39.5