Skip to content

Commit

Permalink
Merge branch 'MDL-31675-file-browsing' of git://github.com/mudrd8mz/m…
Browse files Browse the repository at this point in the history
…oodle
  • Loading branch information
danpoltawski committed May 18, 2012
2 parents 79f3d0e + 386b67d commit 7e89cbe
Show file tree
Hide file tree
Showing 9 changed files with 504 additions and 92 deletions.
1 change: 1 addition & 0 deletions mod/data/lang/en/data.php
Expand Up @@ -32,6 +32,7 @@
$string['alttext'] = 'Alternative text';
$string['approve'] = 'Approve';
$string['approved'] = 'Approved';
$string['areacontent'] = 'Fields';
$string['ascending'] = 'Ascending';
$string['asearchtemplate'] = 'Advanced search template';
$string['atmaxentry'] = 'You have entered the maximum number of entries allowed!';
Expand Down
91 changes: 52 additions & 39 deletions mod/data/lib.php
Expand Up @@ -2800,6 +2800,10 @@ function data_get_exportdata($dataid, $fields, $selectedfields, $currentgroup=0)
return $exportdata;
}

////////////////////////////////////////////////////////////////////////////////
// File API //
////////////////////////////////////////////////////////////////////////////////

/**
* Lists all browsable file areas
*
Expand All @@ -2811,8 +2815,7 @@ function data_get_exportdata($dataid, $fields, $selectedfields, $currentgroup=0)
* @return array
*/
function data_get_file_areas($course, $cm, $context) {
$areas = array();
return $areas;
return array('content' => get_string('areacontent', 'mod_data'));
}

/**
Expand All @@ -2836,55 +2839,65 @@ function mod_data_get_file_info($browser, $areas, $course, $cm, $context, $filea
return null;
}

if ($filearea === 'content') {
if (!$content = $DB->get_record('data_content', array('id'=>$itemid))) {
return null;
}
if (!isset($areas[$filearea])) {
return null;
}

if (!$field = $DB->get_record('data_fields', array('id'=>$content->fieldid))) {
return null;
}
if (!has_capability('moodle/course:managefiles', $context)) {
return null;
}

if (!$record = $DB->get_record('data_records', array('id'=>$content->recordid))) {
return null;
}
if (is_null($itemid)) {
require_once($CFG->dirroot.'/mod/data/locallib.php');
return new data_file_info_container($browser, $course, $cm, $context, $areas, $filearea);
}

if (!$data = $DB->get_record('data', array('id'=>$field->dataid))) {
return null;
}
if (!$content = $DB->get_record('data_content', array('id'=>$itemid))) {
return null;
}

//check if approved
if ($data->approval and !$record->approved and !data_isowner($record) and !has_capability('mod/data:approve', $context)) {
return null;
}
if (!$field = $DB->get_record('data_fields', array('id'=>$content->fieldid))) {
return null;
}

// group access
if ($record->groupid) {
$groupmode = groups_get_activity_groupmode($cm, $course);
if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($record->groupid)) {
return null;
}
if (!$record = $DB->get_record('data_records', array('id'=>$content->recordid))) {
return null;
}

if (!$data = $DB->get_record('data', array('id'=>$field->dataid))) {
return null;
}

//check if approved
if ($data->approval and !$record->approved and !data_isowner($record) and !has_capability('mod/data:approve', $context)) {
return null;
}

// group access
if ($record->groupid) {
$groupmode = groups_get_activity_groupmode($cm, $course);
if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($record->groupid)) {
return null;
}
}
}

$fieldobj = data_get_field($field, $data, $cm);
$fieldobj = data_get_field($field, $data, $cm);

$filepath = is_null($filepath) ? '/' : $filepath;
$filename = is_null($filename) ? '.' : $filename;
if (!$fieldobj->file_ok($filepath.$filename)) {
return null;
}
$filepath = is_null($filepath) ? '/' : $filepath;
$filename = is_null($filename) ? '.' : $filename;
if (!$fieldobj->file_ok($filepath.$filename)) {
return null;
}

$fs = get_file_storage();
if (!($storedfile = $fs->get_file($context->id, 'mod_data', $filearea, $itemid, $filepath, $filename))) {
return null;
}
$urlbase = $CFG->wwwroot.'/pluginfile.php';
return new file_info_stored($browser, $context, $storedfile, $urlbase, $filearea, $itemid, true, true, false);
$fs = get_file_storage();
if (!($storedfile = $fs->get_file($context->id, 'mod_data', $filearea, $itemid, $filepath, $filename))) {
return null;
}
$urlbase = $CFG->wwwroot.'/pluginfile.php';

return null;
return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false);
}

/**
Expand Down
116 changes: 116 additions & 0 deletions mod/data/locallib.php
Expand Up @@ -398,3 +398,119 @@ public function get_allowed_export_config() {
return array('mineonly');
}
}


/**
* Class representing the virtual node with all itemids in the file browser
*
* @category files
* @copyright 2012 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class data_file_info_container extends file_info {
/** @var file_browser */
protected $browser;
/** @var stdClass */
protected $course;
/** @var stdClass */
protected $cm;
/** @var string */
protected $component;
/** @var stdClass */
protected $context;
/** @var array */
protected $areas;
/** @var string */
protected $filearea;

/**
* Constructor (in case you did not realize it ;-)
*
* @param file_browser $browser
* @param stdClass $course
* @param stdClass $cm
* @param stdClass $context
* @param array $areas
* @param string $filearea
*/
public function __construct($browser, $course, $cm, $context, $areas, $filearea) {
parent::__construct($browser, $context);
$this->browser = $browser;
$this->course = $course;
$this->cm = $cm;
$this->component = 'mod_data';
$this->context = $context;
$this->areas = $areas;
$this->filearea = $filearea;
}

/**
* @return array with keys contextid, filearea, itemid, filepath and filename
*/
public function get_params() {
return array(
'contextid' => $this->context->id,
'component' => $this->component,
'filearea' => $this->filearea,
'itemid' => null,
'filepath' => null,
'filename' => null,
);
}

/**
* Can new files or directories be added via the file browser
*
* @return bool
*/
public function is_writable() {
return false;
}

/**
* Should this node be considered as a folder in the file browser
*
* @return bool
*/
public function is_directory() {
return true;
}

/**
* Returns localised visible name of this node
*
* @return string
*/
public function get_visible_name() {
return $this->areas[$this->filearea];
}

/**
* Returns list of children nodes
*
* @return array of file_info instances
*/
public function get_children() {
global $DB;

$children = array();
$itemids = $DB->get_records('files', array('contextid' => $this->context->id, 'component' => $this->component,
'filearea' => $this->filearea), 'itemid DESC', "DISTINCT itemid");
foreach ($itemids as $itemid => $unused) {
if ($child = $this->browser->get_file_info($this->context, 'mod_data', $this->filearea, $itemid)) {
$children[] = $child;
}
}

return $children;
}

/**
* Returns parent file_info instance
*
* @return file_info or null for root
*/
public function get_parent() {
return $this->browser->get_file_info($this->context);
}
}
2 changes: 2 additions & 0 deletions mod/forum/lang/en/forum.php
Expand Up @@ -35,6 +35,8 @@
$string['allunsubscribe'] = 'Unsubscribe from all forums';
$string['alreadyfirstpost'] = 'This is already the first post in the discussion';
$string['anyfile'] = 'Any file';
$string['areaattachment'] = 'Attachments';
$string['areapost'] = 'Messages';
$string['attachment'] = 'Attachment';
$string['attachment_help'] = 'You can optionally attach one or more files to a forum post. If you attach an image, it will be displayed after the message.';
$string['attachmentnopost'] = 'You cannot export attachments without a post id';
Expand Down
67 changes: 44 additions & 23 deletions mod/forum/lib.php
Expand Up @@ -3958,6 +3958,10 @@ function forum_print_attachments($post, $cm, $type) {
}
}

////////////////////////////////////////////////////////////////////////////////
// File API //
////////////////////////////////////////////////////////////////////////////////

/**
* Lists all browsable file areas
*
Expand All @@ -3969,8 +3973,10 @@ function forum_print_attachments($post, $cm, $type) {
* @return array
*/
function forum_get_file_areas($course, $cm, $context) {
$areas = array();
return $areas;
return array(
'attachment' => get_string('areaattachment', 'mod_forum'),
'post' => get_string('areapost', 'mod_forum'),
);
}

/**
Expand All @@ -3996,11 +4002,28 @@ function forum_get_file_info($browser, $areas, $course, $cm, $context, $filearea
return null;
}

$fileareas = array('attachment', 'post');
if (!in_array($filearea, $fileareas)) {
// filearea must contain a real area
if (!isset($areas[$filearea])) {
return null;
}

// this is enforced by {@link file_info_context_course} currently
if (!has_capability('moodle/course:managefiles', $context)) {
return null;
}

// Note that forum_user_can_see_post() additionally allows access for parent roles
// and it explicitly checks qanda forum type, too. One day, when we stop requiring
// course:managefiles, we will need to extend this.
if (!has_capability('mod/forum:viewdiscussion', $context)) {
return null;
}

if (is_null($itemid)) {
require_once($CFG->dirroot.'/mod/forum/locallib.php');
return new forum_file_info_container($browser, $course, $cm, $context, $areas, $filearea);
}

if (!$post = $DB->get_record('forum_posts', array('id' => $itemid))) {
return null;
}
Expand All @@ -4021,14 +4044,12 @@ function forum_get_file_info($browser, $areas, $course, $cm, $context, $filearea
}

// Make sure groups allow this user to see this file
if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
if (!groups_group_exists($discussion->groupid)) { // Can't find group
return null; // Be safe and don't send it to anyone
}

if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
// do not send posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
return null;
if ($discussion->groupid > 0) {
$groupmode = groups_get_activity_groupmode($cm, $course);
if ($groupmode == SEPARATEGROUPS) {
if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
return null;
}
}
}

Expand All @@ -4038,7 +4059,7 @@ function forum_get_file_info($browser, $areas, $course, $cm, $context, $filearea
}

$urlbase = $CFG->wwwroot.'/pluginfile.php';
return new file_info_stored($browser, $context, $storedfile, $urlbase, $filearea, $itemid, true, true, false);
return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false);
}

/**
Expand All @@ -4064,8 +4085,10 @@ function forum_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo

require_course_login($course, true, $cm);

$fileareas = array('attachment', 'post');
if (!in_array($filearea, $fileareas)) {
$areas = forum_get_file_areas($course, $cm, $context);

// filearea must contain a real area
if (!isset($areas[$filearea])) {
return false;
}

Expand All @@ -4091,14 +4114,12 @@ function forum_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo
}

// Make sure groups allow this user to see this file
if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
if (!groups_group_exists($discussion->groupid)) { // Can't find group
return false; // Be safe and don't send it to anyone
}

if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
// do not send posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
return false;
if ($discussion->groupid > 0) {
$groupmode = groups_get_activity_groupmode($cm, $course);
if ($groupmode == SEPARATEGROUPS) {
if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
return false;
}
}
}

Expand Down

0 comments on commit 7e89cbe

Please sign in to comment.