Merge branch 'MDL-32638-workshop-files' of git://github.com/mudrd8mz/moodle

This commit is contained in:
Sam Hemelryk 2012-04-30 13:26:38 +12:00
commit 21f7b01d19
2 changed files with 100 additions and 37 deletions

View file

@ -16,12 +16,12 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Defines workshop_file_info class
* Provides code used during file browsing
*
* @package mod
* @subpackage workshop
* @copyright 2009 David Mudrak <david.mudrak@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @category files
* @package mod_workshop
* @copyright 2009 David Mudrak <david.mudrak@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
@ -29,9 +29,10 @@ defined('MOODLE_INTERNAL') || die();
/**
* Represents virtual root node for all submissions
*
* Workshop submission uses two fileareas: workshop_submission_content
* for editor's embeded media and workshop_submission_attachment for attachments.
* In both, the itemid represents the submission id.
* Workshop submission uses two fileareas: submission_content for editor's embeded media
* and submission_attachment for attachments. In both, the itemid represents the submission id.
* This container is used to display the list of all submissions in these areas (ie when
* these areas are browsed with itemid == null).
*/
class workshop_file_info_submissions_container extends file_info {
protected $course;

View file

@ -1212,10 +1212,8 @@ function workshop_get_file_areas($course, $cm, $context) {
*
* 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.
* Besides that, areas workshop_instructauthors and mod_workshop instructreviewers contain the media
* the fileareas submission_content and submission_attachment are used.
* Besides that, areas instructauthors and instructreviewers contain the media
* embedded using the mod_form.php.
*
* @package mod_workshop
@ -1231,7 +1229,7 @@ function workshop_get_file_areas($course, $cm, $context) {
* @return bool false if the file not found, just send the file otherwise and do not return anything
*/
function workshop_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload, array $options=array()) {
global $DB, $CFG;
global $DB, $CFG, $USER;
if ($context->contextlevel != CONTEXT_MODULE) {
return false;
@ -1240,12 +1238,7 @@ function workshop_pluginfile($course, $cm, $context, $filearea, array $args, $fo
require_login($course, true, $cm);
if ($filearea === 'instructauthors') {
// submission instructions may contain sensitive data
if (!has_any_capability(array('moodle/course:manageactivities', 'mod/workshop:submit'), $context)) {
send_file_not_found();
}
array_shift($args); // we do not use itemids here
array_shift($args); // itemid is ignored here
$relativepath = implode('/', $args);
$fullpath = "/$context->id/mod_workshop/$filearea/0/$relativepath";
@ -1261,12 +1254,7 @@ function workshop_pluginfile($course, $cm, $context, $filearea, array $args, $fo
}
if ($filearea === 'instructreviewers') {
// submission instructions may contain sensitive data
if (!has_any_capability(array('moodle/course:manageactivities', 'mod/workshop:peerassess'), $context)) {
send_file_not_found();
}
array_shift($args); // we do not use itemids here
array_shift($args); // itemid is ignored here
$relativepath = implode('/', $args);
$fullpath = "/$context->id/mod_workshop/$filearea/0/$relativepath";
@ -1288,7 +1276,35 @@ function workshop_pluginfile($course, $cm, $context, $filearea, array $args, $fo
if (!$submission = $DB->get_record('workshop_submissions', array('id' => $itemid, 'workshopid' => $workshop->id))) {
return false;
}
// TODO now make sure the user is allowed to see the file
// make sure the user is allowed to see the file
if (empty($submission->example)) {
if ($USER->id != $submission->authorid) {
if (!$DB->record_exists('workshop_assessments', array('submissionid' => $submission->id, 'reviewerid' => $USER->id))) {
if (!has_capability('mod/workshop:viewallsubmissions', $context)) {
send_file_not_found();
} else {
$gmode = groups_get_activity_groupmode($cm, $course);
if ($gmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
// check there is at least one common group with both the $USER
// and the submission author
$sql = "SELECT 'x'
FROM {workshop_submissions} s
JOIN {user} a ON (a.id = s.authorid)
JOIN {groups_members} agm ON (a.id = agm.userid)
JOIN {user} u ON (u.id = ?)
JOIN {groups_members} ugm ON (u.id = ugm.userid)
WHERE s.example = 0 AND s.workshopid = ? AND s.id = ? AND agm.groupid = ugm.groupid";
$params = array($USER->id, $workshop->id, $submission->id);
if (!$DB->record_exists_sql($sql, $params)) {
send_file_not_found();
}
}
}
}
}
}
$fs = get_file_storage();
$relativepath = implode('/', $args);
$fullpath = "/$context->id/mod_workshop/$filearea/$itemid/$relativepath";
@ -1321,8 +1337,11 @@ function workshop_pluginfile($course, $cm, $context, $filearea, array $args, $fo
* @return file_info instance or null if not found
*/
function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
global $CFG, $DB;
global $CFG, $DB, $USER;
/** @var array internal cache for author names */
static $submissionauthors = array();
// this is enforced by {@link file_info_context_course} currently
if (!has_capability('moodle/course:managefiles', $context)) {
return null;
}
@ -1331,12 +1350,37 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea
if ($filearea === 'content' or $filearea === 'attachment') {
if (!has_capability('mod/workshop:viewallsubmissions', $context)) {
return null;
}
if (is_null($itemid)) {
// no itemid (submissionid) passed, display the list of all submissions
require_once($CFG->dirroot . '/mod/workshop/fileinfolib.php');
return new workshop_file_info_submissions_container($browser, $course, $cm, $context, $areas, $filearea);
}
// we are inside the submission container
// make sure the user can see the particular submission in separate groups mode
$gmode = groups_get_activity_groupmode($cm, $course);
if ($gmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
// check there is at least one common group with both the $USER
// and the submission author (this is not expected to be a frequent
// usecase so we can live with pretty ineffective one query per submission here...)
$sql = "SELECT 'x'
FROM {workshop_submissions} s
JOIN {user} a ON (a.id = s.authorid)
JOIN {groups_members} agm ON (a.id = agm.userid)
JOIN {user} u ON (u.id = ?)
JOIN {groups_members} ugm ON (u.id = ugm.userid)
WHERE s.example = 0 AND s.workshopid = ? AND s.id = ? AND agm.groupid = ugm.groupid";
$params = array($USER->id, $cm->instance, $itemid);
if (!$DB->record_exists_sql($sql, $params)) {
return null;
}
}
// we are inside some particular submission container
$filepath = is_null($filepath) ? '/' : $filepath;
$filename = is_null($filename) ? '.' : $filename;
@ -1351,16 +1395,34 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea
}
// let us display the author's name instead of itemid (submission id)
// todo some sort of caching should happen here
$sql = "SELECT s.id, u.lastname, u.firstname
FROM {workshop_submissions} s
INNER JOIN {user} u ON (s.authorid = u.id)
WHERE s.workshopid = ?";
$params = array($cm->instance);
$authors = $DB->get_records_sql($sql, $params);
$urlbase = $CFG->wwwroot . '/pluginfile.php';
$topvisiblename = fullname($authors[$itemid]);
if (isset($submissionauthors[$itemid])) {
$topvisiblename = $submissionauthors[$itemid];
} else {
$sql = "SELECT s.id, u.lastname, u.firstname
FROM {workshop_submissions} s
JOIN {user} u ON (s.authorid = u.id)
WHERE s.example = 0 AND s.workshopid = ?";
$params = array($cm->instance);
$rs = $DB->get_recordset_sql($sql, $params);
foreach ($rs as $submissionauthor) {
$title = s(fullname($submissionauthor)); // this is generally not unique...
$submissionauthors[$submissionauthor->id] = $title;
}
$rs->close();
if (!isset($submissionauthors[$itemid])) {
// should not happen
return null;
} else {
$topvisiblename = $submissionauthors[$itemid];
}
}
$urlbase = $CFG->wwwroot . '/pluginfile.php';
// do not allow manual modification of any files!
return new file_info_stored($browser, $context, $storedfile, $urlbase, $topvisiblename, true, true, false, false);
}