case 'add':
if ($data = data_submitted() and confirm_sesskey()) {
- $shortname = moodle_strtolower(clean_param(clean_filename($shortname), PARAM_SAFEDIR)); // only lowercase safe ASCII characters
+ $shortname = moodle_strtolower(clean_filename($shortname)); // only lowercase safe ASCII characters
$legacytype = required_param('legacytype', PARAM_RAW);
$legacyroles = get_legacy_roles();
// Create a unique temporary directory, to process the zip file
// contents.
- $zipdir = my_mktempdir($CFG->dataroot.'/temp/', 'usrpic');
+ $zipodir = my_mktempdir($CFG->dataroot.'/temp/', 'usrpic');
+ $dstfile = $zipodir.'/images.zip';
- if (!$mform->save_files($zipdir)) {
+ if (!$mform->save_file('userfile', $dstfile, true)) {
notify(get_string('uploadpicture_cannotmovezip','admin'));
@remove_dir($zipdir);
} else {
- $dstfile = $zipdir.'/'.$mform->get_new_filename();
- if(!unzip_file($dstfile, $zipdir, false)) {
+ if (!unzip_file($dstfile, $zipdir, false)) {
notify(get_string('uploadpicture_cannotunzip','admin'));
@remove_dir($zipdir);
} else {
function do_delete($post) {
global $returnurl, $DB;
+ blog_delete_attachments($post);
+
$status = $DB->delete_records('post', array('id'=>$post->id));
tag_set('post', $post->id, array());
- blog_delete_old_attachments($post);
-
add_to_log(SITEID, 'blog', 'delete', 'index.php?userid='. $post->userid, 'deleted blog entry with entry id# '. $post->id);
if (!$status) {
if ($id = $DB->insert_record('post', $post)) {
$post->id = $id;
// add blog attachment
- $dir = blog_file_area_name($post);
- if ($blogeditform->save_files($dir) and $newfilename = $blogeditform->get_new_filename()) {
- $DB->set_field("post", "attachment", $newfilename, array("id"=>$post->id));
+ if ($blogeditform->get_new_filename('attachment')) {
+ if ($blogeditform->save_stored_file('attachment', SYSCONTEXTID, 'blog', $post->id, '/', false, $USER->id)) {
+ $DB->set_field("post", "attachment", 1, array("id"=>$post->id));
+ }
}
+
add_tags_info($post->id);
add_to_log(SITEID, 'blog', 'add', 'index.php?userid='.$post->userid.'&postid='.$post->id, $post->subject);
$post->lastmodified = time();
- $dir = blog_file_area_name($post);
- if ($blogeditform->save_files($dir) and $newfilename = $blogeditform->get_new_filename()) {
- $post->attachment = $newfilename;
+ if ($blogeditform->get_new_filename('attachment')) {
+ blog_delete_attachments($post);
+ if ($blogeditform->save_stored_file('attachment', SYSCONTEXTID, 'blog', $post->id, '/', false, $USER->id)) {
+ $post->attachment = 1;
+ } else {
+ $post->attachment = 1;
+ }
}
// update record
$post = $this->_customdata['existing'];
$sitecontext = $this->_customdata['sitecontext'];
- // the upload manager is used directly in entry processing, moodleform::save_files() is not used yet
- $this->set_upload_manager(new upload_manager('attachment', true, false, $COURSE, false, 0, true, true, false));
-
$mform->addElement('header', 'general', get_string('general', 'form'));
$mform->addElement('text', 'subject', get_string('entrytitle', 'blog'), 'size="60"');
$mform->setType('subject', PARAM_TEXT);
if($blogEntry->created != $blogEntry->lastmodified){
$template['lastmod'] = userdate($blogEntry->lastmodified);
}
-
+
$template['publishstate'] = $blogEntry->publishstate;
/// preventing user to browse blogs that they aren't supposed to see
print(get_string('tags', 'tag') .': '. $blogtags);
}
echo '</div>';
- }
+ }
/// Commands
}
- /**
- * Creates a directory file name, suitable for make_upload_directory()
- * $CFG->dataroot/blog/attachments/xxxx/file.jpg
- */
- function blog_file_area_name($blogentry) {
- return "blog/attachments/$blogentry->id";
- }
-
- function blog_file_area($blogentry) {
- return make_upload_directory( blog_file_area_name($blogentry) );
- }
-
/**
* Deletes all the user files in the attachments area for a post
- * EXCEPT for any file named $exception
*/
- function blog_delete_old_attachments($post, $exception="") {
- if ($basedir = blog_file_area($post)) {
- if ($files = get_directory_list($basedir)) {
- foreach ($files as $file) {
- if ($file != $exception) {
- unlink("$basedir/$file");
- notify("Existing file '$file' has been deleted!");
- }
- }
- }
- if (!$exception) { // Delete directory as well, if empty
- rmdir("$basedir");
- }
- }
+ function blog_delete_attachments($post) {
+ $fs = get_file_storage();
+ $fs->delete_area_files(SYSCONTEXTID, 'blog', $post->id);
}
/**
function blog_print_attachments($blogentry, $return=NULL) {
global $CFG;
- $filearea = blog_file_area_name($blogentry);
+ require_once($CFG->libdir.'/filelib.php');
+
+ $fs = get_file_storage();
+ $browser = get_file_browser();
+
+ $files = $fs->get_area_files(SYSCONTEXTID, 'blog', $blogentry->id);
$imagereturn = "";
$output = "";
- if ($basedir = blog_file_area($blogentry)) {
- if ($files = get_directory_list($basedir)) {
- $strattachment = get_string("attachment", "forum");
- foreach ($files as $file) {
- include_once($CFG->libdir.'/filelib.php');
- $icon = mimeinfo("icon", $file);
- $type = mimeinfo("type", $file);
- $ffurl = get_file_url("$filearea/$file");
- $image = "<img src=\"$CFG->pixpath/f/$icon\" class=\"icon\" alt=\"\" />";
+ $strattachment = get_string("attachment", "forum");
- if ($return == "html") {
- $output .= "<a href=\"$ffurl\">$image</a> ";
- $output .= "<a href=\"$ffurl\">$file</a><br />";
+ foreach ($files as $file) {
+ if ($file->is_directory()) {
+ continue;
+ }
- } else if ($return == "text") {
- $output .= "$strattachment $file:\n$ffurl\n";
+ $filename = $file->get_filename();
+ $ffurl = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.SYSCONTEXTID.'/blog/'.$blogentry->id.'/'.$filename);
+ $type = $file->get_mimetype();
+ $icon = mimeinfo_from_type("icon", $type);
+ $type = mimeinfo_from_type("type", $type);
- } else {
- if (in_array($type, array('image/gif', 'image/jpeg', 'image/png'))) { // Image attachments don't get printed as links
- $imagereturn .= "<br /><img src=\"$ffurl\" alt=\"\" />";
- } else {
- echo "<a href=\"$ffurl\">$image</a> ";
- echo filter_text("<a href=\"$ffurl\">$file</a><br />");
- }
- }
+ $image = "<img src=\"$CFG->pixpath/f/$icon\" class=\"icon\" alt=\"\" />";
+
+ if ($return == "html") {
+ $output .= "<a href=\"$ffurl\">$image</a> ";
+ $output .= "<a href=\"$ffurl\">$filename</a><br />";
+
+ } else if ($return == "text") {
+ $output .= "$strattachment $filename:\n$ffurl\n";
+
+ } else {
+ if (in_array($type, array('image/gif', 'image/jpeg', 'image/png'))) { // Image attachments don't get printed as links
+ $imagereturn .= "<br /><img src=\"$ffurl\" alt=\"\" />";
+ } else {
+ echo "<a href=\"$ffurl\">$image</a> ";
+ echo filter_text("<a href=\"$ffurl\">$filename</a><br />");
}
}
}
function blog_get_participants() {
global $CFG, $DB;
- return $DB->get_records_sql("SELECT userid AS id
+ return $DB->get_records_sql("SELECT userid AS id
FROM {post}
WHERE module = 'blog' AND courseid = 0");
}
// $CFG->defaultblocks = 'participants,activity_modules,search_forums,admin,course_list:news_items,calendar_upcoming,recent_activity';
//
//
-// Allow unicode characters in uploaded files, generated reports, etc.
-// This setting is new and not much tested, there are known problems
-// with backup/restore that will not be solved, because native infozip
-// binaries are doing some weird conversions - use internal PHP zipping instead.
-// NOT RECOMMENDED FOR PRODUCTION SITES
-// $CFG->unicodecleanfilename = true;
-//
// Seconds for files to remain in caches. Decrease this if you are worried
// about students being served outdated versions of uploaded files.
// $CFG->filelifetime = 86400;
--- /dev/null
+<?php //$Id$
//TODO: Blog attachments do not have access control implemented - anybody can read them!
// It might be better to move the code to separate file because the access
- // control is quite complex - see bolg/index.php
+ // control is quite complex - see bolg/index.php
require_once('config.php');
require_once('lib/filelib.php');
$relativepath = get_file_argument('file.php');
$forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);
-
+
// relative path must start with '/', because of backup/restore!!!
if (!$relativepath) {
print_error('invalidargorconf');
print_error('pathdoesnotstartslash');
}
- $pathname = $CFG->dataroot.$relativepath;
-
// extract relative path components
- $args = explode('/', trim($relativepath, '/'));
+ $args = explode('/', ltrim($relativepath, '/'));
+
if (count($args) == 0) { // always at least courseid, may search for index.html in course root
print_error('invalidarguments');
}
-
- // security: limit access to existing course subdirectories
- if (($args[0]!='blog') and (!$course = $DB->get_record_sql("SELECT * FROM {course} WHERE id=?", array((int)$args[0])))) {
- print_error('invalidcourseid');
- }
- // security: prevent access to "000" or "1 something" directories
- // hack for blogs, needs proper security check too
- if (($args[0] != 'blog') and ($args[0] != $course->id)) {
+ $courseid = (int)array_shift($args);
+ $relativepath = '/'.implode('/', $args);
+
+ // security: limit access to existing course subdirectories
+ if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
print_error('invalidcourseid');
}
- // security: login to course if necessary
- // Note: file.php always calls require_login() with $setwantsurltome=false
- // in order to avoid messing redirects. MDL-14495
- if ($args[0] == 'blog') {
- if (empty($CFG->bloglevel)) {
- print_error('blogdisable', 'blog');
- } else if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) {
- require_login(0, true, null, false);
- } else if ($CFG->forcelogin) {
- require_login(0, true, null, false);
- }
- } else if ($course->id != SITEID) {
+ if ($course->id != SITEID) {
require_login($course->id, true, null, false);
+
} else if ($CFG->forcelogin) {
if (!empty($CFG->sitepolicy)
and ($CFG->sitepolicy == $CFG->wwwroot.'/file.php'.$relativepath
}
}
- // security: only editing teachers can access backups
- if ((count($args) >= 2) and (strtolower($args[1]) == 'backupdata')) {
- if (!has_capability('moodle/site:backup', get_context_instance(CONTEXT_COURSE, $course->id))) {
- print_error('nopermissions');
- } else {
- $lifetime = 0; //disable browser caching for backups
- }
- }
+ $context = get_context_instance(CONTEXT_COURSE, $course->id);
- if (is_dir($pathname)) {
- if (file_exists($pathname.'/index.html')) {
- $pathname = rtrim($pathname, '/').'/index.html';
- $args[] = 'index.html';
- } else if (file_exists($pathname.'/index.htm')) {
- $pathname = rtrim($pathname, '/').'/index.htm';
- $args[] = 'index.htm';
- } else if (file_exists($pathname.'/Default.htm')) {
- $pathname = rtrim($pathname, '/').'/Default.htm';
- $args[] = 'Default.htm';
- } else {
- // security: do not return directory node!
- not_found($course->id);
- }
- }
-
- // security: teachers can view all assignments, students only their own
- if ((count($args) >= 3)
- and (strtolower($args[1]) == 'moddata')
- and (strtolower($args[2]) == 'assignment')) {
+ $fs = get_file_storage();
- $lifetime = 0; // do not cache assignments, students may reupload them
- if ($args[4] == $USER->id) {
- //can view own assignemnt submissions
- } else {
- $instance = (int)$args[3];
- if (!$cm = get_coursemodule_from_instance('assignment', $instance, $course->id)) {
- not_found($course->id);
- }
- if (!has_capability('mod/assignment:grade', get_context_instance(CONTEXT_MODULE, $cm->id))) {
- print_error('nopermissions');
- }
- }
- }
+ $fullpath = $context->id.'course_content0'.$relativepath;
- // security: force download of all attachments submitted by students
- if ((count($args) >= 3)
- and (strtolower($args[1]) == 'moddata')
- and ((strtolower($args[2]) == 'forum')
- or (strtolower($args[2]) == 'assignment')
- or (strtolower($args[2]) == 'data')
- or (strtolower($args[2]) == 'glossary')
- or (strtolower($args[2]) == 'wiki')
- or (strtolower($args[2]) == 'exercise')
- or (strtolower($args[2]) == 'workshop')
- )) {
- $forcedownload = 1; // force download of all attachments
- }
- if ($args[0] == 'blog') {
- $forcedownload = 1; // force download of all attachments
- }
-
- // security: some protection of hidden resource files
- // warning: it may break backwards compatibility
- if ((!empty($CFG->preventaccesstohiddenfiles))
- and (count($args) >= 2)
- and (!(strtolower($args[1]) == 'moddata' and strtolower($args[2]) != 'resource')) // do not block files from other modules!
- and (!has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_COURSE, $course->id)))) {
-
- $rargs = $args;
- array_shift($rargs);
- $reference = implode('/', $rargs);
-
- $sql = "SELECT COUNT(r.id)
- FROM {resource} r, {course_modules} cm, {modules} m
- WHERE r.course = ?
- AND m.name = 'resource'
- AND cm.module = m.id
- AND cm.instance = r.id
- AND cm.visible = 0
- AND r.type = 'file'
- AND r.reference = ?";
- $params = array($course->id, $reference);
-
- if ($DB->count_records_sql($sql, $params)) {
- print_error('nopermissions');
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath))) {
+ if (strrpos($fullpath, '/') !== strlen($fullpath) -1 ) {
+ $fullpath .= '/';
+ }
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath.'/.'))) {
+ not_found();
}
}
-
- // check that file exists
- if (!file_exists($pathname)) {
- not_found($course->id);
+ // do not serve dirs
+ if ($file->get_filename() == '.') {
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath.'index.html'))) {
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath.'index.htm'))) {
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath.'Default.htm'))) {
+ not_found();
+ }
+ }
+ }
}
// ========================================
// finally send the file
// ========================================
session_write_close(); // unlock session during fileserving
- $filename = $args[count($args)-1];
- send_file($pathname, $filename, $lifetime, $CFG->filteruploadedfiles, false, $forcedownload);
+ send_stored_file($file, $lifetime, $CFG->filteruploadedfiles, $forcedownload);
- function not_found($courseid) {
- global $CFG;
+ function not_found() {
+ global $CFG, $COURSE;
header('HTTP/1.0 404 not found');
- print_error('filenotfound', 'error', $CFG->wwwroot.'/course/view.php?id='.$courseid); //this is not displayed on IIS??
+ print_error('filenotfound', 'error', $CFG->wwwroot.'/course/view.php?id='.$COURSE->id); //this is not displayed on IIS??
}
-?>
+
<?php // $Id$
-// Manage all uploaded files in a course file area
-
-// All the Moodle-specific stuff is in this top section
-// Configuration and access control occurs here.
-// Must define: USER, basedir, baseweb, html_header and html_footer
-// USER is a persistent variable using sessions
-
require('../config.php');
- require($CFG->libdir.'/filelib.php');
- require($CFG->libdir.'/adminlib.php');
-
- $id = required_param('id', PARAM_INT);
- $file = optional_param('file', '', PARAM_PATH);
- $wdir = optional_param('wdir', '', PARAM_PATH);
- $action = optional_param('action', '', PARAM_ACTION);
- $name = optional_param('name', '', PARAM_FILE);
- $oldname = optional_param('oldname', '', PARAM_FILE);
- $choose = optional_param('choose', '', PARAM_FILE); //in fact it is always 'formname.inputname'
- $userfile= optional_param('userfile','',PARAM_FILE);
- $save = optional_param('save', 0, PARAM_BOOL);
- $text = optional_param('text', '', PARAM_RAW);
- $confirm = optional_param('confirm', 0, PARAM_BOOL);
-
- if ($choose) {
- if (count(explode('.', $choose)) > 2) {
- print_error('invalidformatpara');
- }
- }
-
+ require_once($CFG->libdir.'/filelib.php');
+ require_once($CFG->libdir.'/adminlib.php');
- if (! $course = $DB->get_record("course", array("id"=>$id))) {
- print_error('invalidcourseid');
- }
+ $courseid = optional_param('id', 0, PARAM_INT);
- require_login($course);
-
- require_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $course->id));
-
- function html_footer() {
- global $COURSE, $choose;
-
- echo '</td></tr></table>';
-
- print_footer($COURSE);
- }
+ $contextid = optional_param('contextid', SYSCONTEXTID, PARAM_INT);
+ $filearea = optional_param('filearea', '', PARAM_SAFEDIR);
+ $itemid = optional_param('itemid', -1, PARAM_INT);
+ $filepath = optional_param('filepath', '', PARAM_PATH);
+ $filename = optional_param('filename', '', PARAM_FILE);
- function html_header($course, $wdir, $formfield=""){
- global $CFG, $ME, $choose;
+ $newdirname = optional_param('newdirname', '', PARAM_FILE);
+ $delete = optional_param('delete', 0, PARAM_BOOL);
- $navlinks = array();
- // $navlinks[] = array('name' => $course->shortname, 'link' => "../course/view.php?id=$course->id", 'type' => 'misc');
-
- if ($course->id == SITEID) {
- $strfiles = get_string("sitefiles");
- } else {
- $strfiles = get_string("files");
+ if ($courseid) {
+ if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
+ print_error('invalidcourseid');
}
-
- if ($wdir == "/") {
- $navlinks[] = array('name' => $strfiles, 'link' => null, 'type' => 'misc');
- } else {
- $dirs = explode("/", $wdir);
- $numdirs = count($dirs);
- $link = "";
- $navlinks[] = array('name' => $strfiles,
- 'link' => $ME."?id=$course->id&wdir=/&choose=$choose",
- 'type' => 'misc');
-
- for ($i=1; $i<$numdirs-1; $i++) {
- $link .= "/".urlencode($dirs[$i]);
- $navlinks[] = array('name' => $dirs[$i],
- 'link' => $ME."?id=$course->id&wdir=$link&choose=$choose",
- 'type' => 'misc');
- }
- $navlinks[] = array('name' => $dirs[$numdirs-1], 'link' => null, 'type' => 'misc');
+ if (!$context = get_context_instance(CONTEXT_COURSE, $course->id)) {
+ print_error('invalidcontext');
}
-
- $navigation = build_navigation($navlinks);
-
- if ($choose) {
- print_header();
-
- $chooseparts = explode('.', $choose);
- if (count($chooseparts)==2){
- ?>
- <script type="text/javascript">
- //<![CDATA[
- function set_value(txt) {
- opener.document.forms['<?php echo $chooseparts[0]."'].".$chooseparts[1] ?>.value = txt;
- window.close();
- }
- //]]>
- </script>
-
- <?php
- } elseif (count($chooseparts)==1){
- ?>
- <script type="text/javascript">
- //<![CDATA[
- function set_value(txt) {
- opener.document.getElementById('<?php echo $chooseparts[0] ?>').value = txt;
- window.close();
- }
- //]]>
- </script>
-
- <?php
-
- }
- $fullnav = '';
- $i = 0;
- foreach ($navlinks as $navlink) {
- // If this is the last link do not link
- if ($i == count($navlinks) - 1) {
- $fullnav .= $navlink['name'];
- } else {
- $fullnav .= '<a href="'.$navlink['link'].'">'.$navlink['name'].'</a>';
- }
- $fullnav .= ' -> ';
- $i++;
- }
- $fullnav = substr($fullnav, 0, -4);
- $fullnav = str_replace('->', '»', format_string($course->shortname) . " -> " . $fullnav);
- echo '<div id="nav-bar">'.$fullnav.'</div>';
-
- if ($course->id == SITEID and $wdir != "/backupdata") {
- print_heading(get_string("publicsitefileswarning"), "center", 2);
- }
-
- } else {
-
- if ($course->id == SITEID) {
-
- if ($wdir == "/backupdata") {
- admin_externalpage_setup('frontpagerestore');
- admin_externalpage_print_header();
- } else {
- admin_externalpage_setup('sitefiles');
- admin_externalpage_print_header();
-
- print_heading(get_string("publicsitefileswarning"), "center", 2);
-
- }
-
- } else {
- print_header("$course->shortname: $strfiles", $course->fullname, $navigation, $formfield);
- }
- }
-
-
- echo "<table border=\"0\" style=\"margin-left:auto;margin-right:auto\" cellspacing=\"3\" cellpadding=\"3\" width=\"640\">";
- echo "<tr>";
- echo "<td colspan=\"2\">";
-
+ redirect('index.php?contextid='.$context->id.'&filearea=coursefiles');
}
-
- if (! $basedir = make_upload_directory("$course->id")) {
- print_error("nopermissiontomkdir");
+ if (!$context = get_context_instance_by_id($contextid)) {
+ print_error('invalidcontext');
}
- $baseweb = $CFG->wwwroot;
+ require_login();
+ require_capability('moodle/course:managefiles', $context);
-// End of configuration and access control
-
-
- if ($wdir == '') {
- $wdir = "/";
+ if ($filearea === '') {
+ $filearea = null;
}
- if ($wdir{0} != '/') { //make sure $wdir starts with slash
- $wdir = "/".$wdir;
+ if ($itemid < 0) {
+ $itemid = null;
}
- if ($wdir == "/backupdata") {
- if (! make_upload_directory("$course->id/backupdata")) { // Backup folder
- print_error('cannotcreatebackupdir');
- }
+ if ($filepath === '') {
+ $filepath = null;
}
- if (!is_dir($basedir.$wdir)) {
- html_header($course, $wdir);
- print_error('nofolder', '', "$CFG->wwwroot/files/index.php?id=$id");
+ if ($filename === '') {
+ $filename = null;
}
- switch ($action) {
-
- case "upload":
- html_header($course, $wdir);
- require_once($CFG->dirroot.'/lib/uploadlib.php');
-
- if ($save and confirm_sesskey()) {
- $course->maxbytes = 0; // We are ignoring course limits
- $um = new upload_manager('userfile',false,false,$course,false,0);
- $dir = "$basedir$wdir";
- if ($um->process_file_uploads($dir)) {
- notify(get_string('uploadedfile'));
- }
- // um will take care of error reporting.
- displaydir($wdir);
- } else {
- $upload_max_filesize = get_max_upload_file_size($CFG->maxbytes);
- $filesize = display_size($upload_max_filesize);
-
- $struploadafile = get_string("uploadafile");
- $struploadthisfile = get_string("uploadthisfile");
- $strmaxsize = get_string("maxsize", "", $filesize);
- $strcancel = get_string("cancel");
-
- echo "<p>$struploadafile ($strmaxsize) --> <b>$wdir</b></p>";
- echo "<form enctype=\"multipart/form-data\" method=\"post\" action=\"index.php\">";
- echo "<div>";
- echo "<table><tr><td colspan=\"2\">";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"upload\" />";
- echo " <input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
- upload_print_form_fragment(1,array('userfile'),null,false,null,$upload_max_filesize,0,false);
- echo " </td></tr></table>";
- echo " <input type=\"submit\" name=\"save\" value=\"$struploadthisfile\" />";
- echo "</div>";
- echo "</form>";
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"cancel\" />";
- echo " <input type=\"submit\" value=\"$strcancel\" />";
- echo "</div>";
- echo "</form>";
- }
- html_footer();
- break;
-
- case "delete":
- if ($confirm and confirm_sesskey()) {
- html_header($course, $wdir);
- if (!empty($USER->filelist)) {
- foreach ($USER->filelist as $file) {
- $fullfile = $basedir.'/'.$file;
- if (! fulldelete($fullfile)) {
- echo "<br />Error: Could not delete: $fullfile";
- }
- }
- }
- clearfilelist();
- displaydir($wdir);
- html_footer();
-
- } else {
- html_header($course, $wdir);
-
- if (setfilelist($_POST)) {
- notify(get_string('deletecheckwarning').':');
- print_simple_box_start("center");
- printfilelist($USER->filelist);
- print_simple_box_end();
- echo "<br />";
-
- require_once($CFG->dirroot.'/mod/resource/lib.php');
- $block = resource_delete_warning($course, $USER->filelist);
-
- if (empty($CFG->resource_blockdeletingfile) or $block == '') {
- $optionsyes = array('id'=>$id, 'wdir'=>$wdir, 'action'=>'delete', 'confirm'=>1, 'sesskey'=>sesskey(), 'choose'=>$choose);
- $optionsno = array('id'=>$id, 'wdir'=>$wdir, 'action'=>'cancel', 'choose'=>$choose);
- notice_yesno (get_string('deletecheckfiles'), 'index.php', 'index.php', $optionsyes, $optionsno, 'post', 'get');
- } else {
-
- notify(get_string('warningblockingdelete', 'resource'));
- $options = array('id'=>$id, 'wdir'=>$wdir, 'action'=>'cancel', 'choose'=>$choose);
- print_continue("index.php?id=$id&wdir=$wdir&action=cancel&choose=$choose");
- }
- } else {
- displaydir($wdir);
- }
- html_footer();
- }
- break;
-
- case "move":
- html_header($course, $wdir);
- if (($count = setfilelist($_POST)) and confirm_sesskey()) {
- $USER->fileop = $action;
- $USER->filesource = $wdir;
- echo "<p class=\"centerpara\">";
- print_string("selectednowmove", "moodle", $count);
- echo "</p>";
- }
- displaydir($wdir);
- html_footer();
- break;
-
- case "paste":
- html_header($course, $wdir);
- if (isset($USER->fileop) and ($USER->fileop == "move") and confirm_sesskey()) {
- foreach ($USER->filelist as $file) {
- $shortfile = basename($file);
- $oldfile = $basedir.'/'.$file;
- $newfile = $basedir.$wdir."/".$shortfile;
- if (!rename($oldfile, $newfile)) {
- echo "<p>Error: $shortfile not moved</p>";
- }
- }
- }
- clearfilelist();
- displaydir($wdir);
- html_footer();
- break;
-
- case "rename":
- if (($name != '') and confirm_sesskey()) {
- html_header($course, $wdir);
- $name = clean_filename($name);
- if (file_exists($basedir.$wdir."/".$name)) {
- echo "<center>Error: $name already exists!</center>";
- } else if (!rename($basedir.$wdir."/".$oldname, $basedir.$wdir."/".$name)) {
- echo "<p align=\"center\">Error: could not rename $oldname to $name</p>";
- } else {
- //file was renamed now update resources if needed
- require_once($CFG->dirroot.'/mod/resource/lib.php');
- resource_renamefiles($course, $wdir, $oldname, $name);
- }
- displaydir($wdir);
-
- } else {
- $strrename = get_string("rename");
- $strcancel = get_string("cancel");
- $strrenamefileto = get_string("renamefileto", "moodle", $file);
- html_header($course, $wdir, "form.name");
- echo "<p>$strrenamefileto:</p>";
- echo "<table><tr><td>";
- echo "<form action=\"index.php\" method=\"post\">";
- echo "<fieldset class=\"invisiblefieldset\">";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"rename\" />";
- echo " <input type=\"hidden\" name=\"oldname\" value=\"$file\" />";
- echo " <input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
- echo " <input type=\"text\" name=\"name\" size=\"35\" value=\"$file\" />";
- echo " <input type=\"submit\" value=\"$strrename\" />";
- echo "</fieldset>";
- echo "</form>";
- echo "</td><td>";
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"cancel\" />";
- echo " <input type=\"submit\" value=\"$strcancel\" />";
- echo "</div>";
- echo "</form>";
- echo "</td></tr></table>";
- }
- html_footer();
- break;
-
- case "makedir":
- if (($name != '') and confirm_sesskey()) {
- html_header($course, $wdir);
- $name = clean_filename($name);
- if (file_exists("$basedir$wdir/$name")) {
- echo "Error: $name already exists!";
- } else if (! make_upload_directory("$course->id$wdir/$name")) {
- echo "Error: could not create $name";
- }
- displaydir($wdir);
-
- } else {
- $strcreate = get_string("create");
- $strcancel = get_string("cancel");
- $strcreatefolder = get_string("createfolder", "moodle", $wdir);
- html_header($course, $wdir, "form.name");
- echo "<p>$strcreatefolder:</p>";
- echo "<table><tr><td>";
- echo "<form action=\"index.php\" method=\"post\">";
- echo "<fieldset class=\"invisiblefieldset\">";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"makedir\" />";
- echo " <input type=\"text\" name=\"name\" size=\"35\" />";
- echo " <input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
- echo " <input type=\"submit\" value=\"$strcreate\" />";
- echo "</fieldset>";
- echo "</form>";
- echo "</td><td>";
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"cancel\" />";
- echo " <input type=\"submit\" value=\"$strcancel\" />";
- echo "</div>";
- echo "</form>";
- echo "</td></tr></table>";
- }
- html_footer();
- break;
-
- case "edit":
- html_header($course, $wdir);
- if (($text != '') and confirm_sesskey()) {
- $fileptr = fopen($basedir.'/'.$file,"w");
- $text = preg_replace('/\x0D/', '', $text); // http://moodle.org/mod/forum/discuss.php?d=38860
- fputs($fileptr, $text);
- fclose($fileptr);
- displaydir($wdir);
-
- } else {
- $streditfile = get_string("edit", "", "<b>$file</b>");
- $fileptr = fopen($basedir.'/'.$file, "r");
- $contents = fread($fileptr, filesize($basedir.'/'.$file));
- fclose($fileptr);
-
- if (mimeinfo("type", $file) == "text/html") {
- $usehtmleditor = can_use_html_editor();
- } else {
- $usehtmleditor = false;
- }
- $usehtmleditor = false; // Always keep it off for now
-
- print_heading("$streditfile");
-
- echo "<table><tr><td colspan=\"2\">";
- echo "<form action=\"index.php\" method=\"post\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"file\" value=\"$file\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"edit\" />";
- echo " <input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
- print_textarea($usehtmleditor, 25, 80, 680, 400, "text", $contents);
- echo "</td></tr><tr><td>";
- echo " <input type=\"submit\" value=\"".get_string("savechanges")."\" />";
- echo "</div>";
- echo "</form>";
- echo "</td><td>";
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"cancel\" />";
- echo " <input type=\"submit\" value=\"".get_string("cancel")."\" />";
- echo "</div>";
- echo "</form>";
- echo "</td></tr></table>";
-
- if ($usehtmleditor) {
- use_html_editor();
- }
-
-
- }
- html_footer();
- break;
+ $error = '';
- case "zip":
- if (($name != '') and confirm_sesskey()) {
- html_header($course, $wdir);
- $name = clean_filename($name);
+ $browser = get_file_browser();
- $files = array();
- foreach ($USER->filelist as $file) {
- $files[] = "$basedir/$file";
- }
+ $file_info = $browser->get_file_info($context, $filearea, $itemid, $filepath, $filename);
- if (!zip_files($files,"$basedir$wdir/$name")) {
- print_error("zipfileserror", "error");
- }
+/// process actions
+ if ($file_info and $file_info->is_directory() and $file_info->is_writable() and $newdirname !== '' and data_submitted() and confirm_sesskey()) {
+ if ($newdir_info = $file_info->create_directory($newdirname, $USER->id)) {
+ $params = $newdir_info->get_params_rawencoded();
+ $params = implode('&', $params);
+ redirect("index.php?$params");
+ } else {
+ $error = "Could not create new dir"; // TODO: localise
+ }
+ }
- clearfilelist();
- displaydir($wdir);
+ if ($file_info and $file_info->is_directory() and $file_info->is_writable() and isset($_FILES['newfile']) and data_submitted() and confirm_sesskey()) {
+ $file = $_FILES['newfile'];
+ $newfilename = clean_param($file['name'], PARAM_FILE);
+ if (is_uploaded_file($_FILES['newfile']['tmp_name'])) {
+ try {
+ if ($newfile = $file_info->create_file_from_pathname($newfilename, $_FILES['newfile']['tmp_name'], $USER->id)) {
+ $params = $file_info->get_params_rawencoded();
+ $params = implode('&', $params);
+ redirect("index.php?$params");
- } else {
- html_header($course, $wdir, "form.name");
-
- if (setfilelist($_POST)) {
- echo "<p align=\"center\">".get_string("youareabouttocreatezip").":</p>";
- print_simple_box_start("center");
- printfilelist($USER->filelist);
- print_simple_box_end();
- echo "<br />";
- echo "<p align=\"center\">".get_string("whattocallzip")."</p>";
- echo "<table><tr><td>";
- echo "<form action=\"index.php\" method=\"post\">";
- echo "<fieldset class=\"invisiblefieldset\">";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"zip\" />";
- echo " <input type=\"text\" name=\"name\" size=\"35\" value=\"new.zip\" />";
- echo " <input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
- echo " <input type=\"submit\" value=\"".get_string("createziparchive")."\" />";
- echo "<fieldset>";
- echo "</form>";
- echo "</td><td>";
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"cancel\" />";
- echo " <input type=\"submit\" value=\"".get_string("cancel")."\" />";
- echo "</div>";
- echo "</form>";
- echo "</td></tr></table>";
} else {
- displaydir($wdir);
- clearfilelist();
+ $error = "Could not create upload file"; // TODO: localise
}
+ } catch (file_exception $e) {
+ $error = "Exception: Could not create upload file"; // TODO: localise
}
- html_footer();
- break;
-
- case "unzip":
- html_header($course, $wdir);
- if (($file != '') and confirm_sesskey()) {
- $strok = get_string("ok");
- $strunpacking = get_string("unpacking", "", $file);
+ }
+ }
- echo "<p align=\"center\">$strunpacking:</p>";
+ if ($file_info and $delete) {
+ if (!data_submitted() or !confirm_sesskey()) {
+ print_header();
+ notify(get_string('deletecheckwarning').': '.$file_info->get_visible_name());
+ $parent_info = $file_info->get_parent();
- $file = basename($file);
+ $optionsno = $parent_info->get_params();
+ $optionsyes = $file_info->get_params();
+ $optionsyes['delete'] = 1;
+ $optionsyes['sesskey'] = sesskey();
- if (!unzip_file("$basedir$wdir/$file")) {
- print_error("unzipfileserror", "error");
- }
-
- echo "<div style=\"text-align:center\"><form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"cancel\" />";
- echo " <input type=\"submit\" value=\"$strok\" />";
- echo "</div>";
- echo "</form>";
- echo "</div>";
- } else {
- displaydir($wdir);
- }
- html_footer();
- break;
-
- case "listzip":
- html_header($course, $wdir);
- if (($file != '') and confirm_sesskey()) {
- $strname = get_string("name");
- $strsize = get_string("size");
- $strmodified = get_string("modified");
- $strok = get_string("ok");
- $strlistfiles = get_string("listfiles", "", $file);
-
- echo "<p align=\"center\">$strlistfiles:</p>";
- $file = basename($file);
-
- include_once("$CFG->libdir/pclzip/pclzip.lib.php");
- $archive = new PclZip(cleardoubleslashes("$basedir$wdir/$file"));
- if (!$list = $archive->listContent(cleardoubleslashes("$basedir$wdir"))) {
- notify($archive->errorInfo(true));
+ notice_yesno (get_string('deletecheckfiles'), 'index.php', 'index.php', $optionsyes, $optionsno, 'post', 'get');
+ print_footer();
+ die;
+ }
- } else {
- echo "<table cellpadding=\"4\" cellspacing=\"2\" border=\"0\" width=\"640\" class=\"files\">";
- echo "<tr class=\"file\"><th align=\"left\" class=\"header name\" scope=\"col\">$strname</th><th align=\"right\" class=\"header size\" scope=\"col\">$strsize</th><th align=\"right\" class=\"header date\" scope=\"col\">$strmodified</th></tr>";
- foreach ($list as $item) {
- echo "<tr>";
- print_cell("left", s($item['filename']), 'name');
- if (! $item['folder']) {
- print_cell("right", display_size($item['size']), 'size');
- } else {
- echo "<td> </td>";
- }
- $filedate = userdate($item['mtime'], get_string("strftimedatetime"));
- print_cell("right", $filedate, 'date');
- echo "</tr>";
- }
- echo "</table>";
- }
- echo "<br /><center><form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"cancel\" />";
- echo " <input type=\"submit\" value=\"$strok\" />";
- echo "</div>";
- echo "</form>";
- echo "</center>";
- } else {
- displaydir($wdir);
+ if ($parent_info = $file_info->get_parent() and $parent_info->is_writable()) {
+ if (!$file_info->delete()) {
+ $error = "Could not delete file!"; // TODO: localise
}
- html_footer();
- break;
-
- case "restore":
- html_header($course, $wdir);
- if (($file != '') and confirm_sesskey()) {
- echo "<p align=\"center\">".get_string("youaregoingtorestorefrom").":</p>";
- print_simple_box_start("center");
- echo $file;
- print_simple_box_end();
- echo "<br />";
- echo "<p align=\"center\">".get_string("areyousuretorestorethisinfo")."</p>";
- $restore_path = "$CFG->wwwroot/backup/restore.php";
- notice_yesno (get_string("areyousuretorestorethis"),
- $restore_path."?id=".$id."&file=".cleardoubleslashes($id.$wdir."/".$file)."&method=manual",
- "index.php?id=$id&wdir=$wdir&action=cancel");
- } else {
- displaydir($wdir);
- }
- html_footer();
- break;
-
- case "cancel":
- clearfilelist();
-
- default:
- html_header($course, $wdir);
- displaydir($wdir);
- html_footer();
- break;
-}
-
-
-/// FILE FUNCTIONS ///////////////////////////////////////////////////////////
+ $params = $parent_info->get_params_rawencoded();
+ $params = implode('&', $params);
+ redirect("index.php?$params", $error);
+ }
+ }
-function setfilelist($VARS) {
- global $USER;
+/// print dir listing
+ html_header($context, $file_info);
- $USER->filelist = array ();
- $USER->fileop = "";
+ if ($error !== '') {
+ notify($error);
+ }
- $count = 0;
- foreach ($VARS as $key => $val) {
- if (substr($key,0,4) == "file") {
- $count++;
- $val = rawurldecode($val);
- $USER->filelist[] = clean_param($val, PARAM_PATH);
- }
+ displaydir($file_info);
+
+ if ($file_info and $file_info->is_directory() and $file_info->is_writable()) {
+ echo '<br />';
+
+ echo '<form action="index.php" method="post"><div>';
+ echo '<input type="hidden" name="contextid" value="'.$contextid.'" />';
+ echo '<input type="hidden" name="filearea" value="'.$filearea.'" />';
+ echo '<input type="hidden" name="itemid" value="'.$itemid.'" />';
+ echo '<input type="hidden" name="filepath" value="'.s($filepath).'" />';
+ echo '<input type="hidden" name="filename" value="'.s($filename).'" />';
+ echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
+ echo '<input type="text" name="newdirname" value="" />';
+ echo '<input type="submit" value="'.get_string('makeafolder').'" />';
+ echo '</div></form>';
+
+ echo '<br />';
+
+ echo '<form enctype="multipart/form-data" method="post" action="index.php">';
+ echo '<input type="hidden" name="contextid" value="'.$contextid.'" />';
+ echo '<input type="hidden" name="filearea" value="'.$filearea.'" />';
+ echo '<input type="hidden" name="itemid" value="'.$itemid.'" />';
+ echo '<input type="hidden" name="filepath" value="'.s($filepath).'" />';
+ echo '<input type="hidden" name="filename" value="'.s($filename).'" />';
+ echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
+ echo '<input name="newfile" type="file" />';
+ echo '<input type="submit" value="'.get_string('uploadafile').'" />';
+ echo '</div></form>';
}
- return $count;
-}
-function clearfilelist() {
- global $USER;
+ html_footer();
- $USER->filelist = array ();
- $USER->fileop = "";
+/// UI functions /////////////////////////
+
+function html_footer() {
+ echo '</td></tr></table>';
+ print_footer();
}
+function html_header($context, $file_info){
+ global $CFG, $SITE;
-function printfilelist($filelist) {
- global $CFG, $basedir;
+ $navlinks = array();
+ $strfiles = get_string("files");
- $strfolder = get_string("folder");
- $strfile = get_string("file");
+ $navlinks[] = array('name' => $strfiles, 'link' => null, 'type' => 'misc');
- foreach ($filelist as $file) {
- if (is_dir($basedir.'/'.$file)) {
- echo '<img src="'. $CFG->pixpath .'/f/folder.gif" class="icon" alt="'. $strfolder .'" /> '. htmlspecialchars($file) .'<br />';
- $subfilelist = array();
- $currdir = opendir($basedir.'/'.$file);
- while (false !== ($subfile = readdir($currdir))) {
- if ($subfile <> ".." && $subfile <> ".") {
- $subfilelist[] = $file."/".$subfile;
- }
- }
- printfilelist($subfilelist);
+ $navigation = build_navigation($navlinks);
+ print_header("$SITE->shortname: $strfiles", '', $navigation);
- } else {
- $icon = mimeinfo("icon", $file);
- echo '<img src="'. $CFG->pixpath .'/f/'. $icon .'" class="icon" alt="'. $strfile .'" /> '. htmlspecialchars($file) .'<br />';
- }
- }
+ echo "<table border=\"0\" style=\"margin-left:auto;margin-right:auto\" cellspacing=\"3\" cellpadding=\"3\" width=\"740\">";
+ echo "<tr>";
+ echo "<td colspan=\"2\">";
}
+/// FILE FUNCTIONS ///////////////////////////////////////////////////////////
function print_cell($alignment='center', $text=' ', $class='') {
if ($class) {
echo '<td align="'.$alignment.'" style="white-space:nowrap "'.$class.'>'.$text.'</td>';
}
-function displaydir ($wdir) {
-// $wdir == / or /a or /a/b/c/d etc
+function displaydir($file_info) {
+ global $CFG;
+
+ $children = $file_info->get_children();
+ $parent_info = $file_info->get_parent();
+
+ $strname = get_string('name');
+ $strsize = get_string('size');
+ $strmodified = get_string('modified');
+ $strfolder = get_string('folder');
+ $strfile = get_string('file');
+ $strdownload = get_string('download');
+ $strdelete = get_string('delete');
+ $straction = get_string('action');
+
+ $path = array();
+ $params = $file_info->get_params_rawencoded();
+ $params = implode('&', $params);
+ $path[] = $file_info->get_visible_name();
+
+ $level = $parent_info;
+ while ($level) {
+ $params = $level->get_params_rawencoded();
+ $params = implode('&', $params);
+ $path[] = '<a href="index.php?'.$params.'">'.$level->get_visible_name().'</a>';
+ $level = $level->get_parent();
+ }
- global $basedir;
- global $id;
- global $USER, $CFG;
- global $choose;
+ $path = array_reverse($path);
- $fullpath = $basedir.$wdir;
- $dirlist = array();
+ $path = implode (' / ', $path);
+ echo $path. ' /';
- $directory = opendir($fullpath); // Find all files
- while (false !== ($file = readdir($directory))) {
- if ($file == "." || $file == "..") {
- continue;
- }
-
- if (is_dir($fullpath."/".$file)) {
- $dirlist[] = $file;
- } else {
- $filelist[] = $file;
- }
- }
- closedir($directory);
-
- $strname = get_string("name");
- $strsize = get_string("size");
- $strmodified = get_string("modified");
- $straction = get_string("action");
- $strmakeafolder = get_string("makeafolder");
- $struploadafile = get_string("uploadafile");
- $strselectall = get_string("selectall");
- $strselectnone = get_string("deselectall");
- $strwithchosenfiles = get_string("withchosenfiles");
- $strmovetoanotherfolder = get_string("movetoanotherfolder");
- $strmovefilestohere = get_string("movefilestohere");
- $strdeletecompletely = get_string("deletecompletely");
- $strcreateziparchive = get_string("createziparchive");
- $strrename = get_string("rename");
- $stredit = get_string("edit");
- $strunzip = get_string("unzip");
- $strlist = get_string("list");
- $strrestore= get_string("restore");
- $strchoose = get_string("choose");
- $strfolder = get_string("folder");
- $strfile = get_string("file");
-
-
- echo "<form action=\"index.php\" method=\"post\" id=\"dirform\">";
echo "<div>";
- echo '<input type="hidden" name="choose" value="'.$choose.'" />';
- // echo "<hr align=\"center\" noshade=\"noshade\" size=\"1\" />";
echo "<hr/>";
- echo "<table border=\"0\" cellspacing=\"2\" cellpadding=\"2\" width=\"640\" class=\"files\">";
+ echo "<table border=\"0\" cellspacing=\"2\" cellpadding=\"2\" width=\"740\" class=\"files\">";
echo "<tr>";
echo "<th class=\"header\" scope=\"col\"></th>";
echo "<th class=\"header name\" scope=\"col\">$strname</th>";
echo "<th class=\"header commands\" scope=\"col\">$straction</th>";
echo "</tr>\n";
- if ($wdir != "/") {
- $dirlist[] = '..';
- }
-
- $count = 0;
-
- if (!empty($dirlist)) {
- asort($dirlist);
- foreach ($dirlist as $dir) {
- echo "<tr class=\"folder\">";
+ $parentwritable = $file_info->is_writable();
- if ($dir == '..') {
- $fileurl = rawurlencode(dirname($wdir));
- print_cell();
- // alt attribute intentionally empty to prevent repetition in screen reader
- print_cell('left', '<a href="index.php?id='.$id.'&wdir='.$fileurl.'&choose='.$choose.'"><img src="'.$CFG->pixpath.'/f/parent.gif" class="icon" alt="" /> '.get_string('parentfolder').'</a>', 'name');
- print_cell();
- print_cell();
- print_cell();
+ if ($parent_info) {
+ $params = $parent_info->get_params_rawencoded();
+ $params = implode('&', $params);
- } else {
- $count++;
- $filename = $fullpath."/".$dir;
- $fileurl = rawurlencode($wdir."/".$dir);
- $filesafe = rawurlencode($dir);
- $filesize = display_size(get_directory_size("$fullpath/$dir"));
- $filedate = userdate(filemtime($filename), "%d %b %Y, %I:%M %p");
- print_cell("center", "<input type=\"checkbox\" name=\"file$count\" value=\"$fileurl\" />", 'checkbox');
- print_cell("left", "<a href=\"index.php?id=$id&wdir=$fileurl&choose=$choose\"><img src=\"$CFG->pixpath/f/folder.gif\" class=\"icon\" alt=\"$strfolder\" /> ".htmlspecialchars($dir)."</a>", 'name');
- print_cell("right", $filesize, 'size');
- print_cell("right", $filedate, 'date');
- print_cell("right", "<a href=\"index.php?id=$id&wdir=$wdir&file=$filesafe&action=rename&choose=$choose\">$strrename</a>", 'commands');
- }
+ echo "<tr class=\"folder\">";
+ print_cell();
+ print_cell('left', '<a href="index.php?'.$params.'"><img src="'.$CFG->pixpath.'/f/parent.gif" class="icon" alt="" /> '.get_string('parentfolder').'</a>', 'name');
+ print_cell();
+ print_cell();
+ print_cell();
- echo "</tr>";
- }
+ echo "</tr>";
}
+ if ($children) {
+ foreach ($children as $child_info) {
+ $filename = $child_info->get_visible_name();
+ $filesize = $child_info->get_filesize();
+ $filesize = $filesize ? display_size($filesize) : '';
+ $filedate = $child_info->get_timemodified();
+ $filedate = $filedate ? userdate($filedate) : '';
- if (!empty($filelist)) {
- asort($filelist);
- foreach ($filelist as $file) {
-
- $icon = mimeinfo("icon", $file);
+ $mimetype = $child_info->get_mimetype();
- $count++;
- $filename = $fullpath."/".$file;
- $fileurl = trim($wdir, "/")."/$file";
- $filesafe = rawurlencode($file);
- $fileurlsafe = rawurlencode($fileurl);
- $filedate = userdate(filemtime($filename), "%d %b %Y, %I:%M %p");
+ $params = $child_info->get_params_rawencoded();
+ $params = implode('&', $params);
- $selectfile = trim($fileurl, "/");
+ if ($child_info->is_directory()) {
- echo "<tr class=\"file\">";
+ echo "<tr class=\"folder\">";
+ print_cell();
+ print_cell("left", "<a href=\"index.php?$params\"><img src=\"$CFG->pixpath/f/folder.gif\" class=\"icon\" alt=\"$strfolder\" /> ".s($filename)."</a>", 'name');
+ print_cell("right", $filesize, 'size');
+ print_cell("right", $filedate, 'date');
+ if ($parentwritable) {
+ print_cell("right", "<a href=\"index.php?$params&sesskey=".sesskey()."&delete=1\"><img src=\"$CFG->pixpath/t/delete.gif\" class=\"iconsmall\" alt=\"$strdelete\" /></a>", 'command');
+ } else {
+ print_cell();
+ }
+ echo "</tr>";
- print_cell("center", "<input type=\"checkbox\" name=\"file$count\" value=\"$fileurl\" />", 'checkbox');
- echo "<td align=\"left\" style=\"white-space:nowrap\" class=\"name\">";
+ } else {
- $ffurl = get_file_url($id.'/'.$fileurl);
- link_to_popup_window ($ffurl, "display",
- "<img src=\"$CFG->pixpath/f/$icon\" class=\"icon\" alt=\"$strfile\" /> ".htmlspecialchars($file),
- 480, 640);
- echo "</td>";
+ $icon = mimeinfo_from_type("icon", $mimetype);
+ if ($downloadurl = $child_info->get_url(true)) {
+ $downloadurl = " <a href=\"$downloadurl\"><img src=\"$CFG->pixpath/t/down.gif\" class=\"iconsmall\" alt=\"$strdownload\" />";
+ } else {
+ $downloadurl = '';
+ }
- $file_size = filesize($filename);
- print_cell("right", display_size($file_size), 'size');
- print_cell("right", $filedate, 'date');
+ if ($viewurl = $child_info->get_url()) {
+ $viewurl = " ".link_to_popup_window ($viewurl, "display",
+ "<img src=\"$CFG->pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strfile\" /> ",
+ 480, 640, null, null, true);
+ } else {
+ $viewurl = '';
+ }
- if ($choose) {
- $edittext = "<strong><a onclick=\"return set_value('$selectfile')\" href=\"#\">$strchoose</a></strong> ";
- } else {
- $edittext = '';
- }
- if ($icon == "text.gif" || $icon == "html.gif") {
- $edittext .= "<a href=\"index.php?id=$id&wdir=$wdir&file=$fileurl&action=edit&choose=$choose\">$stredit</a>";
- } else if ($icon == "zip.gif") {
- $edittext .= "<a href=\"index.php?id=$id&wdir=$wdir&file=$fileurl&action=unzip&sesskey=$USER->sesskey&choose=$choose\">$strunzip</a> ";
- $edittext .= "<a href=\"index.php?id=$id&wdir=$wdir&file=$fileurl&action=listzip&sesskey=$USER->sesskey&choose=$choose\">$strlist</a> ";
- if (!empty($CFG->backup_version) and has_capability('moodle/site:restore', get_context_instance(CONTEXT_COURSE, $id))) {
- $edittext .= "<a href=\"index.php?id=$id&wdir=$wdir&file=$filesafe&action=restore&sesskey=$USER->sesskey&choose=$choose\">$strrestore</a> ";
+ echo "<tr class=\"file\">";
+ print_cell();
+ print_cell("left", "<img src=\"$CFG->pixpath/f/$icon\" class=\"icon\" alt=\"$strfile\" /> ".s($filename).$downloadurl.$viewurl, 'name');
+ print_cell("right", $filesize, 'size');
+ print_cell("right", $filedate, 'date');
+ if ($parentwritable) {
+ print_cell("right", "<a href=\"index.php?$params&sesskey=".sesskey()."&delete=1\"><img src=\"$CFG->pixpath/t/delete.gif\" class=\"iconsmall\" alt=\"$strdelete\" /></a>", 'command');
+ } else {
+ print_cell();
}
+ echo "</tr>";
}
-
- print_cell("right", "$edittext <a href=\"index.php?id=$id&wdir=$wdir&file=$filesafe&action=rename&choose=$choose\">$strrename</a>", 'commands');
-
- echo "</tr>";
}
}
- echo "</table>";
- echo "<hr />";
- //echo "<hr width=\"640\" align=\"center\" noshade=\"noshade\" size=\"1\" />";
-
- echo "<table border=\"0\" cellspacing=\"2\" cellpadding=\"2\" width=\"640\">";
- echo "<tr><td>";
- echo "<input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo '<input type="hidden" name="choose" value="'.$choose.'" />';
- echo "<input type=\"hidden\" name=\"wdir\" value=\"$wdir\" /> ";
- echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
- $options = array (
- "move" => "$strmovetoanotherfolder",
- "delete" => "$strdeletecompletely",
- "zip" => "$strcreateziparchive"
- );
- if (!empty($count)) {
-
- choose_from_menu ($options, "action", "", "$strwithchosenfiles...", "javascript:getElementById('dirform').submit()");
- echo '<div id="noscriptgo" style="display: inline;">';
- echo '<input type="submit" value="'.get_string('go').'" />';
- echo '<script type="text/javascript">'.
- "\n//<![CDATA[\n".
- 'document.getElementById("noscriptgo").style.display = "none";'.
- "\n//]]>\n".'</script>';
- echo '</div>';
- }
- echo "</td></tr></table>";
- echo "</div>";
- echo "</form>";
- echo "<table border=\"0\" cellspacing=\"2\" cellpadding=\"2\" width=\"640\"><tr>";
- echo "<td align=\"center\">";
- if (!empty($USER->fileop) and ($USER->fileop == "move") and ($USER->filesource <> $wdir)) {
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"paste\" />";
- echo " <input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
- echo " <input type=\"submit\" value=\"$strmovefilestohere\" />";
- echo "</div>";
- echo "</form>";
- }
- echo "</td>";
- echo "<td align=\"right\">";
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"makedir\" />";
- echo " <input type=\"submit\" value=\"$strmakeafolder\" />";
- echo "</div>";
- echo "</form>";
- echo "</td>";
- echo "<td align=\"right\">";
- echo "<form action=\"index.php\" method=\"get\">"; //dummy form - alignment only
- echo "<fieldset class=\"invisiblefieldset\">";
- echo " <input type=\"button\" value=\"$strselectall\" onclick=\"checkall();\" />";
- echo " <input type=\"button\" value=\"$strselectnone\" onclick=\"uncheckall();\" />";
- echo "</fieldset>";
- echo "</form>";
- echo "</td>";
- echo "<td align=\"right\">";
- echo "<form action=\"index.php\" method=\"get\">";
- echo "<div>";
- echo ' <input type="hidden" name="choose" value="'.$choose.'" />';
- echo " <input type=\"hidden\" name=\"id\" value=\"$id\" />";
- echo " <input type=\"hidden\" name=\"wdir\" value=\"$wdir\" />";
- echo " <input type=\"hidden\" name=\"action\" value=\"upload\" />";
- echo " <input type=\"submit\" value=\"$struploadafile\" />";
- echo "</div>";
- echo "</form>";
- echo "</td></tr>";
echo "</table>";
+ echo "</div>";
echo "<hr/>";
- //echo "<hr width=\"640\" align=\"center\" noshade=\"noshade\" size=\"1\" />";
}
} elseif ($data = $editform->get_data()) {
if ($data->id) {
- if (!groups_update_group($data, $editform->_upload_manager)) {
+ if (!groups_update_group($data, $editform)) {
print_error('cannotupdategroup');
}
} else {
- if (!$id = groups_create_group($data, $editform->_upload_manager)) {
+ if (!$id = groups_create_group($data, $editform)) {
print_error('cannotcreategroup');
}
$returnurl = $CFG->wwwroot.'/group/index.php?id='.$course->id.'&group='.$id;
$options = array(get_string('no'), get_string('yes'));
$mform->addElement('select', 'hidepicture', get_string('hidepicture'), $options);
- $this->set_upload_manager(new upload_manager('imagefile', false, false, null, false, 0, true, true, false));
$mform->addElement('file', 'imagefile', get_string('newpicture', 'group'));
$mform->setHelpButton('imagefile', array ('picture', get_string('helppicture')), true);
}
* @param object $um upload manager with group picture
* @return id of group or false if error
*/
-function groups_create_group($data, $um=false) {
+function groups_create_group($data, $editform=false) {
global $CFG, $DB;
require_once("$CFG->libdir/gdlib.php");
if ($id) {
$data->id = $id;
- if ($um) {
+ if ($editform) {
//update image
- if (save_profile_image($id, $um, 'groups')) {
+ if (save_profile_image($id, $editform, 'groups')) {
$DB->set_field('groups', 'picture', 1, array('id'=>$id));
}
$data->picture = 1;
* @param object $um upload manager with group picture
* @return boolean success
*/
-function groups_update_group($data, $um=false) {
+function groups_update_group($data, $editform=false) {
global $CFG, $DB;
require_once("$CFG->libdir/gdlib.php");
$result = $DB->update_record('groups', $data);
if ($result) {
- if ($um) {
+ if ($editform) {
//update image
- if (save_profile_image($data->id, $um, 'groups')) {
+ if (save_profile_image($data->id, $editform, 'groups')) {
$DB->set_field('groups', 'picture', 1, array('id'=>$data->id));
$data->picture = 1;
}
$string['guestnoeditprofile'] = 'The guest user cannot edit their profile';
$string['guestnorate'] = 'Guests are not allowed to rate entries';
$string['guestnoeditprofileother'] = 'The guest user profile cannot be edited';
+$string['hashpoolproblem'] = 'Incorrect pool file content $a.';
$string['invalidaction'] = 'Invalid action parameter';
$string['invalidarguments'] = 'No valid arguments supplied';
$string['invalidargorconf'] = 'No valid arguments supplied or incorrect server configuration';
$string['listcantmovedown'] = 'Failed to move item down, as it is the last of it\'s peers';
$string['listcantmoveleft'] = 'Failed to move item left, as it has no parent';
$string['listcantmoveright'] = 'Failed to move item right, as there is no peer to make it a child of. Move it below another peer and then you can move it right.';
+$string['localfilecannotcreatefiledirs'] = 'Can not create local file pool directories, please verify permissions in dataroot.';
+$string['localfilecannotread'] = 'Can not read file, either file does not exist or there are permission problems';
+$string['localfilenotcreated'] = 'Can not create file \"$a->contextid/$a->filearea/$a->itemid/$a->filepath/$a->filename\"';
+$string['localfileproblem'] = 'Unknown exception related to local files ($a)';
$string['loginasonecourse'] = 'You cannot enter this course.<br /> You have to terminate the \"Login as\" session before entering any other course.';
$string['loginasnoenrol'] = 'You cannot use enrol or unenrol when in course \"Login as\" session';
$string['logfilenotavailable'] = 'Logs not available';
)
),
+ 'moodle/site:backupdownload' => array(
+
+ 'riskbitmask' => RISK_SPAM | RISK_PERSONAL | RISK_XSS,
+
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_COURSE,
+ 'legacy' => array(
+ 'editingteacher' => CAP_ALLOW,
+ 'admin' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/site:backup'
+ ),
+
+ 'moodle/site:backupupload' => array(
+
+ 'riskbitmask' => RISK_SPAM | RISK_PERSONAL | RISK_XSS,
+
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_COURSE,
+ 'legacy' => array(
+ 'editingteacher' => CAP_ALLOW,
+ 'admin' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/site:restore'
+ ),
+
'moodle/site:restore' => array(
'riskbitmask' => RISK_SPAM | RISK_PERSONAL | RISK_XSS,
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me"/>
</KEYS>
</TABLE>
- <TABLE NAME="portfolio_log" COMMENT="log of portfolio transfers (used to later check for duplicates)" PREVIOUS="message_working">
+ <TABLE NAME="portfolio_log" COMMENT="log of portfolio transfers (used to later check for duplicates)" PREVIOUS="message_working" NEXT="files">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="userid"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="user who exported content" PREVIOUS="id" NEXT="time"/>
<KEY NAME="portfoliofk" TYPE="foreign" FIELDS="portfolio" REFTABLE="portfolio_instance" REFFIELDS="id" COMMENT="fk to portfolio_instance" PREVIOUS="userfk"/>
</KEYS>
</TABLE>
+ <TABLE NAME="files" COMMENT="description of files, content stored in sha1 file pool" PREVIOUS="portfolio_log" NEXT="files_cleanup">
+ <FIELDS>
+ <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="contenthash"/>
+ <FIELD NAME="contenthash" TYPE="char" LENGTH="40" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="sha1 hash of file content" PREVIOUS="id" NEXT="pathnamehash"/>
+ <FIELD NAME="pathnamehash" TYPE="char" LENGTH="40" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="complete file path sha1 hash - unique for each file" PREVIOUS="contenthash" NEXT="contextid"/>
+ <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The context id defined in context table - identifies the instance of plugin owning the file" PREVIOUS="pathnamehash" NEXT="filearea"/>
+ <FIELD NAME="filearea" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Like "coursefiles". "submission", "intro" and "content" (images and swf linked from summaries), etc." PREVIOUS="contextid" NEXT="itemid"/>
+ <FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Optional - some plugin specific item id (eg. forum post, blog entry or assignment submission, user id for user files)" PREVIOUS="filearea" NEXT="filepath"/>
+ <FIELD NAME="filepath" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Optional - relative path to file from module content root, useful in Scorm and Resource mod - most of the mods do not need this" PREVIOUS="itemid" NEXT="filename"/>
+ <FIELD NAME="filename" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="The full Unicode name of this file (case sensitive) - some chars are not allowed though" PREVIOUS="filepath" NEXT="userid"/>
+ <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Optional - general userid field - meaning depending on plugin" PREVIOUS="filename" NEXT="filesize"/>
+ <FIELD NAME="filesize" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="userid" NEXT="mimetype"/>
+ <FIELD NAME="mimetype" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="type of file - jpeg image, open document spreadsheet" PREVIOUS="filesize" NEXT="status"/>
+ <FIELD NAME="status" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="number greater than 0 means something is wrong with this file (virus, missing, etc.)" PREVIOUS="mimetype" NEXT="timecreated"/>
+ <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="status" NEXT="timemodified"/>
+ <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/>
+ </FIELDS>
+ <KEYS>
+ <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="contextid"/>
+ <KEY NAME="contextid" TYPE="foreign" FIELDS="contextid" REFTABLE="context" REFFIELDS="id" PREVIOUS="primary" NEXT="userid"/>
+ <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="contextid"/>
+ </KEYS>
+ <INDEXES>
+ <INDEX NAME="filearea-contextid-itemid" UNIQUE="false" FIELDS="filearea, contextid, itemid" NEXT="contenthash"/>
+ <INDEX NAME="contenthash" UNIQUE="false" FIELDS="contenthash" PREVIOUS="filearea-contextid-itemid" NEXT="pathnamehash"/>
+ <INDEX NAME="pathnamehash" UNIQUE="true" FIELDS="pathnamehash" PREVIOUS="contenthash"/>
+ </INDEXES>
+ </TABLE>
+ <TABLE NAME="files_cleanup" COMMENT="File pool cleanup candidates" PREVIOUS="files">
+ <FIELDS>
+ <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="contenthash"/>
+ <FIELD NAME="contenthash" TYPE="char" LENGTH="40" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="id"/>
+ </FIELDS>
+ <KEYS>
+ <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+ </KEYS>
+ <INDEXES>
+ <INDEX NAME="contenthash" UNIQUE="true" FIELDS="contenthash"/>
+ </INDEXES>
+ </TABLE>
</TABLES>
<STATEMENTS>
<STATEMENT NAME="insert mnet_application" TYPE="insert" TABLE="mnet_application" COMMENT="Initial insert of records on table mnet_application" NEXT="insert log_display">
}
if ($result && $oldversion < 2008072400) {
- /// Create the database tables for message_processors
+ /// Create the database tables for message_processors and message_providers
+ $table = new xmldb_table('message_providers');
+ $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+ $table->add_field('modulename', XMLDB_TYPE_CHAR, '166', null, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('modulefile', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+ $dbman->create_table($table);
+
$table = new xmldb_table('message_processors');
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '166', null, XMLDB_NOTNULL, null, null, null, null);
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbman->create_table($table);
+
+ $provider = new object();
+ $provider->modulename = 'moodle';
+ $provider->modulefile = 'index.php';
+ $DB->insert_record('message_providers', $provider);
+
/// delete old and create new fields
$table = new xmldb_table('message');
$field = new xmldb_field('messagetype');
upgrade_main_savepoint($result, 2008073104);
}
-
-/*
- * TODO:
- * drop adodb_logsql table and create a new general sql log table
- *
- */
+
+ if ($result && $oldversion < 2008073111) {
+ /// Define table files to be created
+ $table = new xmldb_table('files');
+
+ /// Adding fields to table files
+ $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+ $table->add_field('contenthash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('pathnamehash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('filearea', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('filepath', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('filename', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
+ $table->add_field('filesize', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('mimetype', XMLDB_TYPE_CHAR, '100', null, null, null, null, null, null);
+ $table->add_field('status', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+ $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+ $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+
+ /// Adding keys to table files
+ $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+ $table->add_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
+ $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
+
+ /// Adding indexes to table files
+ $table->add_index('filearea-contextid-itemid', XMLDB_INDEX_NOTUNIQUE, array('filearea', 'contextid', 'itemid'));
+ $table->add_index('contenthash', XMLDB_INDEX_NOTUNIQUE, array('contenthash'));
+ $table->add_index('pathnamehash', XMLDB_INDEX_UNIQUE, array('pathnamehash'));
+
+ /// Conditionally launch create table for files
+ $dbman->create_table($table);
+
+ /// Main savepoint reached
+ upgrade_main_savepoint($result, 2008073111);
+ }
+
+ if ($result && $oldversion < 2008073112) {
+ /// Define table files_cleanup to be created
+ $table = new xmldb_table('files_cleanup');
+
+ /// Adding fields to table files_cleanup
+ $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+ $table->add_field('contenthash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null, null, null);
+
+ /// Adding keys to table files_cleanup
+ $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+
+ /// Adding indexes to table files_cleanup
+ $table->add_index('contenthash', XMLDB_INDEX_UNIQUE, array('contenthash'));
+
+ /// Conditionally launch create table for files_cleanup
+ $dbman->create_table($table);
+
+ /// Main savepoint reached
+ upgrade_main_savepoint($result, 2008073112);
+ }
+
+ if ($result && $oldversion < 2008073113) {
+ /// move all course, backup and other files to new filepool based storage
+ upgrade_migrate_files_courses();
+ /// Main savepoint reached
+ upgrade_main_savepoint($result, 2008073113);
+ }
+
+ if ($result && $oldversion < 2008073114) {
+ /// move all course, backup and other files to new filepool based storage
+ upgrade_migrate_files_blog();
+ /// Main savepoint reached
+ upgrade_main_savepoint($result, 2008073114);
+ }
return $result;
}
}
}
-?>
+/**
+ * Moves all course files except the moddata to new file storage
+ *
+ * Unfortunately this function uses core file related functions - it might be necessary to tweak it if something changes there :-(
+ */
+function upgrade_migrate_files_courses() {
+ global $DB, $CFG;
+ require_once($CFG->libdir.'/filelib.php');
+
+ $count = $DB->count_records('course');
+ $pbar = new progress_bar('migratecoursefiles', 500, true);
+
+ $rs = $DB->get_recordset('course');
+ $olddebug = $DB->get_debug();
+ $DB->set_debug(false); // lower debug level, there might be many files
+ $i = 0;
+ foreach ($rs as $course) {
+ $i++;
+ $context = get_context_instance(CONTEXT_COURSE, $course->id);
+ upgrade_migrate_files_course($context, '/', true);
+ $pbar->update($i, $count, "Migrated course files - course $i/$count.");
+ }
+ $DB->set_debug($olddebug); // reset debug level
+ $rs->close();
+
+ return true;
+}
+
+/**
+ * Internal function - do not use directly
+ */
+function upgrade_migrate_files_course($context, $path, $delete) {
+ global $CFG;
+
+ $fullpathname = $CFG->dataroot.'/'.$context->instanceid.$path;
+ if (!file_exists($fullpathname)) {
+ return;
+ }
+ $items = new DirectoryIterator($fullpathname);
+ $fs = get_file_storage();
+
+ foreach ($items as $item) {
+ if ($item->isDot()) {
+ continue;
+ }
+
+ if ($item->isLink()) {
+ // do not delete symbolic links or its children
+ $delete_this = false;
+ } else {
+ $delete_this = $delete;
+ }
+
+ if (strpos($path, '/backupdata/') === 0) {
+ $filearea = 'course_backup';
+ $filepath = substr($path, strlen('/backupdata'));
+ } else {
+ $filearea = 'course_content';
+ $filepath = $path;
+ }
+
+ if ($item->isFile()) {
+ if (!$item->isReadable()) {
+ notify(" File not readable, skipping: ".$fullpathname.$item->getFilename());
+ continue;
+ }
+
+ $filepath = clean_param($filepath, PARAM_PATH);
+ $filename = clean_param($item->getFilename(), PARAM_FILE);
+
+ if ($filename === '') {
+ continue;
+ }
+
+ if (!$fs->file_exists($context->id, $filearea, '0', $filepath, $filename)) {
+ $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename,
+ 'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime());
+ if ($fs->create_file_from_pathname($file_record, $fullpathname.$item->getFilename())) {
+ if ($delete_this) {
+ @unlink($fullpathname.$item->getFilename());
+ }
+ }
+ }
+
+ } else {
+ if ($path == '/' and $item->getFilename() == 'moddata') {
+ continue; // modules are responsible
+ }
+
+ $filepath = clean_param($filepath.$item->getFilename().'/', PARAM_PATH);
+ if ($filepath !== '/backupdata/') {
+ $fs->create_directory($context->id, $filearea, 0, $filepath);
+ }
+
+ //migrate recursively all subdirectories
+ upgrade_migrate_files_course($context, $path.$item->getFilename().'/', $delete_this);
+ if ($delete_this) {
+ // delete dir if empty
+ @rmdir($fullpathname.$item->getFilename());
+ }
+ }
+ }
+ unset($items); //release file handles
+}
+
+/**
+ * Moves all block attachments
+ *
+ * Unfortunately this function uses core file related functions - it might be necessary to tweak it if something changes there :-(
+ */
+function upgrade_migrate_files_blog() {
+ global $DB, $CFG;
+
+ $fs = get_file_storage();
+
+ $count = $DB->count_records_select('post', "module='blog' AND attachment IS NOT NULL AND attachment <> 1");
+
+ if ($rs = $DB->get_recordset_select('post', "module='blog' AND attachment IS NOT NULL AND attachment <> 1")) {
+
+ $pbar = new progress_bar('migrateblogfiles', 500, true);
+
+ $olddebug = $DB->get_debug();
+ $DB->set_debug(false); // lower debug level, there might be many files
+ $i = 0;
+ foreach ($rs as $entry) {
+ $i++;
+ $pathname = "$CFG->dataroot/blog/attachments/$entry->id/$entry->attachment";
+ if (!file_exists($pathname)) {
+ // hmm, we could set atatchment NULL here, but it would break badly in concurrent ugprades, disabling for now
+ //$entry->attachment = NULL;
+ //$DB->update_record('post', $entry);
+ continue;
+ }
+
+ $filename = clean_param($entry->attachment, PARAM_FILE);
+ if ($filename === '') {
+ // weird file name, ignore it
+ $entry->attachment = NULL;
+ $DB->update_record('post', $entry);
+ continue;
+ }
+
+ if (!is_readable($pathname)) {
+ notify(" File not readable, skipping: ".$pathname);
+ continue;
+ }
+
+ if (!$fs->file_exists(SYSCONTEXTID, 'blog', $entry->id, '/', $filename)) {
+ $file_record = array('contextid'=>SYSCONTEXTID, 'filearea'=>'blog', 'itemid'=>$entry->id, 'filepath'=>'/', 'filename'=>$filename,
+ 'timecreated'=>filectime($pathname), 'timemodified'=>filemtime($pathname), 'userid'=>$post->userid);
+ $fs->create_file_from_pathname($file_record, $pathname);
+ }
+ @unlink($pathname);
+ @rmdir("$CFG->dataroot/blog/attachments/$entry->id/");
+
+ $entry->attachment = 1; // file name not needed there anymore
+ $DB->update_record('post', $entry);
+ $pbar->update($i, $count, "Migrated blog attachments - $i/$count.");
+ }
+ $DB->set_debug($olddebug); // reset debug level
+ $rs->close();
+ }
+
+ @rmdir("$CFG->dataroot/blog/attachments/");
+ @rmdir("$CFG->dataroot/blog/");
+}
require("../../../config.php");
require_once($CFG->libdir.'/filelib.php');
+error('Not reimplemented yet, sorry');
+
$id = required_param('id', PARAM_INT);
$file = optional_param('file', '', PARAM_PATH);
$wdir = optional_param('wdir', '', PARAM_PATH);
require("../../../config.php");\r
require_once($CFG->libdir.'/filelib.php');\r
\r
+error('Not reimplemented yet, sorry');\r
+\r
$id = required_param('id', PARAM_INT);\r
$file = optional_param('file', '', PARAM_PATH);\r
$wdir = optional_param('wdir', '', PARAM_PATH);\r
--- /dev/null
+<?php //$Id$
+
+require_once("$CFG->libdir/file/file_info.php");
+require_once("$CFG->libdir/file/file_info_stored.php");
+require_once("$CFG->libdir/file/file_info_system.php");
+require_once("$CFG->libdir/file/file_info_user.php");
+require_once("$CFG->libdir/file/file_info_coursecat.php");
+require_once("$CFG->libdir/file/file_info_course.php");
+require_once("$CFG->libdir/file/file_info_coursefile.php");
+
+/**
+ * Main interface for browsing of file tree (local files, areas, virtual files, etc.).
+ */
+class file_browser {
+
+ /**
+ * Looks up file_info object
+ * @param object $context
+ * @param string $filearea
+ * @param int $itemid
+ * @param string $filepath
+ * @param string $filename
+ * @return object file_info object or null if not found or access not allowed
+ */
+ public function get_file_info($context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
+ global $USER, $CFG, $DB;
+
+ $fs = get_file_storage();
+
+ if ($context->contextlevel == CONTEXT_SYSTEM) {
+ if (is_null($filearea)) {
+ return new file_info_system($this);
+ }
+ //TODO: question files browsing
+
+ } else if ($context->contextlevel == CONTEXT_USER) {
+ // access control: only own files
+ if ($context->instanceid != $USER->id) {
+ return null;
+ }
+
+ if (!is_null($filearea) and !in_array($filearea, array('user_private', 'user_draft'))) {
+ // file area does not exist, sorry
+ return null;
+ }
+
+ if (is_null($filearea)) {
+ return new file_info_user($this, $context);
+ } else {
+ if ($filearea == 'user_private') {
+ if (is_null($itemid)) {
+ return new file_info_user($this, $context);
+ }
+ $filepath = is_null($filepath) ? '/' : $filepath;
+ $filename = is_null($filename) ? '.' : $filename;
+
+ if (!$localfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+ if ($filepath === '/' and $filename === '.') {
+ $localfile = $fs->create_directory($context->id, $filearea, 0, $filepath, $USER->id);
+ } else {
+ // not found
+ return null;
+ }
+ }
+ $urlbase = $CFG->wwwroot.'/userfile.php';
+ // TODO: localise
+ return new file_info_stored($this, $context, $localfile, $urlbase, 'Personal files', false, true, true);
+
+ } else if ($filearea == 'user_draft') {
+ if (empty($itemid)) {
+ return new file_info_user($this, $context);
+ }
+ $urlbase = $CFG->wwwroot.'/draftfile.php';
+ if (!$localfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
+ return null;
+ }
+ //something must create the top most directory
+ // TODO: localise
+ return new file_info_stored($this, $context, $localfile, $urlbase, 'Draft file area', true, true, true);
+ }
+ }
+
+ } else if ($context->contextlevel == CONTEXT_COURSECAT) {
+ if (!$category = $DB->get_record('course_categories', array('id'=>$context->instanceid))) {
+ return null;
+ }
+
+ if (!$category->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ return null;
+ }
+
+ if (!is_null($filearea) and !in_array($filearea, array('coursecat_intro'))) {
+ // file area does not exist, sorry
+ $filearea = null;
+ }
+
+ if (is_null($filearea) or is_null($itemid)) {
+ return new file_info_coursecat($this, $context, $category);
+
+ } else {
+ if ($filearea == 'coursecat_intro') {
+ if (!has_capability('moodle/course:update', $context)) {
+ return null;
+ }
+
+ $filepath = is_null($filepath) ? '/' : $filepath;
+ $filename = is_null($filename) ? '.' : $filename;
+
+ $urlbase = $CFG->wwwroot.'/pluginfile.php';
+ if (!$localfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+ if ($filepath === '/' and $filename === '.') {
+ $localfile = $fs->create_directory($context->id, $filearea, 0, $filepath);
+ } else {
+ // not found
+ return null;
+ }
+ }
+ // TODO: localise
+ return new file_info_stored($this, $context, $localfile, $urlbase, 'Category introduction files', false, true, true);
+
+ }
+ }
+
+ } else if ($context->contextlevel == CONTEXT_COURSE) {
+ if (!$course = $DB->get_record('course', array('id'=>$context->instanceid))) {
+ return null;
+ }
+
+ if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ return null;
+ }
+
+ if (!is_null($filearea) and !in_array($filearea, array('course_intro', 'course_content', 'course_backup'))) {
+ // file area does not exist, sorry
+ $filearea = null;
+ }
+
+ $filepath = is_null($filepath) ? '/' : $filepath;
+ $filename = is_null($filename) ? '.' : $filename;
+
+ if (is_null($filearea) or is_null($itemid)) {
+ return new file_info_course($this, $context, $course);
+
+ } else {
+ if ($filearea === 'course_intro') {
+ if (!has_capability('moodle/course:update', $context)) {
+ return null;
+ }
+
+ $urlbase = $CFG->wwwroot.'/pluginfile.php';
+ if (!$localfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+ if ($filepath === '/' and $filename === '.') {
+ $localfile = $fs->create_directory($context->id, $filearea, 0, $filepath);
+ } else {
+ // not found
+ return null;
+ }
+ }
+ // TODO: localise
+ return new file_info_stored($this, $context, $localfile, $urlbase, 'Course introduction files', false, true, true);
+
+ } else if ($filearea == 'course_backup') {
+ if (!has_capability('moodle/site:backup', $context) and !has_capability('moodle/site:restore', $context)) {
+ return null;
+ }
+
+ $urlbase = $CFG->wwwroot.'/pluginfile.php';
+ if (!$localfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+ if ($filepath === '/' and $filename === '.') {
+ $localfile = $fs->create_directory($context->id, $filearea, 0, $filepath);
+ } else {
+ // not found
+ return null;
+ }
+ }
+
+ $downloadable = has_capability('moodle/site:backupdownload', $context);
+ $uploadable = has_capability('moodle/site:backupupload', $context);
+ // TODO: localise
+ return new file_info_stored($this, $context, $localfile, $urlbase, 'Backup files', false, $downloadable, $uploadable);
+
+ } else if ($filearea == 'course_content') {
+ if (!has_capability('moodle/course:managefiles', $context)) {
+ return null;
+ }
+
+ if (!$localfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+ if ($filepath === '/' and $filename === '.') {
+ $localfile = $fs->create_directory($context->id, $filearea, 0, $filepath);
+ } else {
+ // not found
+ return null;
+ }
+ }
+
+ return new file_info_coursefile($this, $context, $localfile);
+ }
+ }
+
+ } else if ($context->contextlevel == CONTEXT_MODULE) {
+ //TODO
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns content of local directory
+ */
+ public function build_stored_file_children($context, $filearea, $itemid, $filepath, $urlbase, $areavisiblename, $itemidused, $readaccess, $writeaccess) {
+ global $DB;
+
+ $dirs = array();
+ $files = array();
+ $fs = get_file_storage();
+ $level = substr_count($filepath, '/');
+
+ // TODO: this should be improved ;-)
+ $localfiles = $fs->get_area_files($context->id, $filearea, $itemid, "filepath, filename");
+ foreach ($localfiles as $file) {
+ $name = $file->get_filename();
+ $path = $file->get_filepath();
+ $l = substr_count($path, '/');
+
+ if ($filepath === $path) {
+ if ($name !== '.') {
+ $files[] = new file_info_stored($this, $context, $file, $urlbase, $areavisiblename, $itemidused, $readaccess, $writeaccess);
+ }
+ } else if ($level == $l-1 and $name === '.' and strpos($path, $filepath) === 0) {
+ $dirs[] = new file_info_stored($this, $context, $file, $urlbase, $areavisiblename, $itemidused, $readaccess, $writeaccess);
+ }
+ }
+
+ return array_merge($dirs, $files);
+ }
+
+ /**
+ * Returns content of coursefiles directory
+ */
+ public function build_coursefile_children($context, $filepath) {
+ global $DB;
+
+ $dirs = array();
+ $files = array();
+ $fs = get_file_storage();
+ $level = substr_count($filepath, '/');
+
+ // TODO: this should be improved ;-)
+ $localfiles = $fs->get_area_files($context->id, 'course_content', 0, "filepath, filename");
+ foreach ($localfiles as $file) {
+ $name = $file->get_filename();
+ $path = $file->get_filepath();
+ $l = substr_count($path, '/');
+
+ if ($filepath === $path) {
+ if ($name !== '.') {
+ $files[] = new file_info_coursefile($this, $context, $file);
+ }
+ } else if ($level == $l-1 and $name === '.' and strpos($path, $filepath) === 0) {
+ $dirs[] = new file_info_coursefile($this, $context, $file);
+ }
+ }
+
+ return array_merge($dirs, $files);
+ }
+
+ public function encodepath($urlbase, $path, $forcedownload=false, $https=false) {
+ global $CFG;
+
+ if ($CFG->slasharguments) {
+ $parts = explode('/', $path);
+ $parts = array_map('rawurlencode', $parts);
+ $path = implode('/', $parts);
+ $return = $urlbase.$path;
+ if ($forcedownload) {
+ $return .= '?forcedownload=1';
+ }
+ } else {
+ $path = rawurlencode($path);
+ $return = $urlbase.'?file='.$path;
+ if ($forcedownload) {
+ $return .= '&forcedownload=1';
+ }
+ }
+
+ if ($https) {
+ $return = str_replace('http://', 'https://', $return);
+ }
+
+ return $return;
+ }
+
+}
--- /dev/null
+<?php //$Id$
+
+/**
+ * Basic file related exception class
+ */
+class file_exception extends moodle_exception {
+ function __construct($errorcode, $a=NULL, $debuginfo=null) {
+ parent::__construct($errorcode, '', '', $a, $debuginfo);
+ }
+}
+
+/**
+ * Table does not exist problem exception
+ */
+class stored_file_creation_exception extends file_exception {
+ function __construct($contextid, $filearea, $itemid, $filepath, $filename, $debuginfo=null) {
+ $a = new object();
+ $a->contextid = $contextid;
+ $a->filearea = $filearea;
+ $a->itemid = $itemid;
+ $a->filepath = $filepath;
+ $a->filename = $filename;
+ parent::__construct('localfilenotcreated', $a, $debuginfo);
+ }
+}
+
+/**
+ * Table does not exist problem exception
+ */
+class file_access_exception extends file_exception {
+ function __construct($debuginfo=null) {
+ parent::__construct('nopermissions', NULL, $debuginfo);
+ }
+}
+
+/**
+ * Hash file content problem
+ */
+class file_pool_content_exception extends file_exception {
+ function __construct($contenthash, $debuginfo=null) {
+ parent::__construct('hashpoolproblem', $contenthash, $debuginfo);
+ }
+}
--- /dev/null
+<?php //$Id$
+
+abstract class file_info {
+ protected $context;
+ protected $browser;
+
+ public function __construct($browser, $context) {
+ $this->browser = $browser;
+ $this->context = $context;
+ }
+
+ public abstract function get_params();
+ public abstract function get_visible_name();
+ public abstract function is_directory();
+ public abstract function get_children();
+ public abstract function get_parent();
+
+
+ public function get_params_rawencoded() {
+ $params = $this->get_params();
+ $encoded = array();
+ $encoded[] = 'contextid='.$params['contextid'];
+ $encoded[] = 'filearea='.$params['filearea'];
+ $encoded[] = 'itemid='.(is_null($params['itemid']) ? -1 : $params['itemid']);
+ $encoded[] = 'filepath='.(is_null($params['filepath']) ? '' : rawurlencode($params['filepath']));
+ $encoded[] = 'filename='.((is_null($params['filename']) or $params['filename'] === '.') ? '' : rawurlencode($params['filename']));
+
+ return $encoded;
+ }
+
+
+
+ public function get_url($forcedownload=false, $https=false) {
+ return null;
+ }
+
+ public function is_readable() {
+ return true;
+ }
+
+ public function is_writable() {
+ return true;
+ }
+
+ public function get_filesize() {
+ return null;
+ }
+
+ public function get_mimetype() {
+ // TODO: add some custom mime icons for courses, categories??
+ return null;
+ }
+
+ public function get_timecreated() {
+ return null;
+ }
+
+ public function get_timemodified() {
+ return null;
+ }
+
+ public function create_directory($newdirname, $userid=null) {
+ return null;
+ }
+
+ public function create_file_from_string($newfilename, $content, $userid=null) {
+ return null;
+ }
+
+ public function create_file_from_pathname($newfilename, $pathname, $userid=null) {
+ return null;
+ }
+
+ public function create_file_from_localfile($newfilename, $fid, $userid=null) {
+ return null;
+ }
+
+ public function delete() {
+ return false;
+ }
+
+//TODO: following methods are not implemented yet ;-)
+
+ //public abstract function copy(location params);
+ //public abstract function move(location params);
+ //public abstract function rename(new name);
+ //public abstract function unzip(location params);
+ //public abstract function zip(zip file, file info);
+}
--- /dev/null
+<?php //$Id$
+
+class file_info_course extends file_info {
+ protected $course;
+
+ public function __construct($browser, $context, $course) {
+ global $DB;
+ parent::__construct($browser, $context);
+ $this->course = $course;
+ }
+
+ public function get_params() {
+ return array('contextid'=>$this->context->id,
+ 'filearea' =>null,
+ 'itemid' =>null,
+ 'filepath' =>null,
+ 'filename' =>null);
+ }
+
+ public function get_visible_name() {
+ return ($this->course->id == SITEID) ? get_string('frontpage', 'admin') : format_string($this->course->fullname);
+ }
+
+ public function is_writable() {
+ return false;
+ }
+
+ public function is_directory() {
+ return true;
+ }
+
+ public function get_children() {
+ $children = array();
+
+ if (has_capability('moodle/course:update', $this->context)) {
+ if ($child = $this->browser->get_file_info($this->context, 'course_intro', 0)) {
+ $children[] = $child;
+ }
+ }
+
+ if (has_capability('moodle/site:backup', $this->context) or has_capability('moodle/site:restorep', $this->context)) {
+ if ($child = $this->browser->get_file_info($this->context, 'course_backup', 0)) {
+ $children[] = $child;
+ }
+ }
+
+ if (has_capability('moodle/course:managefiles', $this->context)) {
+ if ($child = $this->browser->get_file_info($this->context, 'course_content', 0)) {
+ $children[] = $child;
+ }
+ }
+
+ return $children;
+ }
+
+ public function get_parent() {
+ $pcid = get_parent_contextid($this->context);
+ $parent = get_context_instance_by_id($pcid);
+ return $this->browser->get_file_info($parent);
+ }
+}
--- /dev/null
+<?php //$Id$
+
+class file_info_coursecat extends file_info {
+ protected $category;
+
+ public function __construct($browser, $context, $category) {
+ parent::__construct($browser, $context);
+ $this->category = $category;
+ }
+
+ public function get_params() {
+ return array('contextid'=>$this->context->id,
+ 'filearea' =>null,
+ 'itemid' =>null,
+ 'filepath' =>null,
+ 'filename' =>null);
+ }
+
+ public function get_visible_name() {
+ return format_string($this->category->name);
+ }
+
+ public function is_directory() {
+ return true;
+ }
+
+ public function get_children() {
+ global $DB;
+
+ $children = array();
+
+ if ($child = $this->browser->get_file_info($this->context, 'coursecat_intro', 0)) {
+ $children[] = $child;
+ }
+
+ $course_cats = $DB->get_records('course_categories', array('parent'=>$this->category->id), 'sortorder');
+ foreach ($course_cats as $category) {
+ $context = get_context_instance(CONTEXT_COURSECAT, $category->id);
+ if (!$category->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ continue;
+ }
+ if ($child = $this->browser->get_file_info($context)) {
+ $children[] = $child;
+ }
+ }
+
+ $courses = $DB->get_records('course', array('category'=>$this->category->id), 'sortorder');
+ foreach ($courses as $course) {
+ $context = get_context_instance(CONTEXT_COURSE, $course->id);
+ if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ continue;
+ }
+ if ($child = $this->browser->get_file_info($context)) {
+ $children[] = $child;
+ }
+ }
+
+ return $children;
+ }
+
+ public function get_parent() {
+ $cid = get_parent_contextid($this->context);
+ $parent = get_context_instance_by_id($cid);
+ return $this->browser->get_file_info($parent);
+ }
+}
--- /dev/null
+<?php //$Id$
+
+class file_info_coursefile extends file_info_stored {
+ public function __construct($browser, $context, $localfile) {
+ global $CFG;
+ $urlbase = $CFG->wwwroot.'/file.php';
+ parent::__construct($browser, $context, $localfile, $urlbase, 'Course files', false, true, true); // TODO: localise
+ }
+
+ public function get_url($forcedownload=false, $https=false) {
+ global $CFG;
+
+ if (!$this->is_readable()) {
+ return null;
+ }
+
+ if ($this->lf->get_filename() === '.') {
+ return null;
+ }
+
+ $filepath = $this->lf->get_filepath();
+ $filename = $this->lf->get_filename();
+ $courseid = $this->context->instanceid;
+
+ $path = '/'.$courseid.$filepath.$filename;
+
+ return $this->browser->encodepath($this->urlbase, $path, $forcedownload, $https);
+ }
+
+ public function get_children() {
+ if ($this->lf->get_filename() !== '.') {
+ return array(); //not a dir
+ }
+ return $this->browser->build_coursefile_children($this->context, $this->lf->get_filepath());
+ }
+
+
+}
--- /dev/null
+<?php //$Id$
+
+class file_info_stored extends file_info {
+ protected $lf;
+ protected $urlbase;
+ protected $areavisiblename;
+ protected $itemidused;
+ protected $readaccess;
+ protected $writeaccess;
+
+ public function __construct($browser, $context, $localfile, $urlbase, $areavisiblename, $itemidused, $readaccess, $writeaccess) {
+ parent::__construct($browser, $context);
+
+ $this->lf = $localfile;
+ $this->urlbase = $urlbase;
+ $this->areavisiblename = $areavisiblename;
+ $this->itemidused = $itemidused;
+ $this->readaccess = $readaccess;
+ $this->writeaccess = $writeaccess;
+ }
+
+ public function get_params() {
+ return array('contextid'=>$this->context->id,
+ 'filearea' =>$this->lf->get_filearea(),
+ 'itemid' =>$this->lf->get_itemid(),
+ 'filepath' =>$this->lf->get_filepath(),
+ 'filename' =>$this->lf->get_filename());
+ }
+
+ public function get_visible_name() {
+ $filename = $this->lf->get_filename();
+ $filepath = $this->lf->get_filepath();
+
+ if ($filename !== '.') {
+ return $filename;
+
+ } else {
+ $dir = trim($filepath, '/');
+ $dir = explode('/', $dir);
+ $dir = array_pop($dir);
+ if ($dir === '') {
+ if ($this->itemidused) {
+ return $this->itemid;
+ } else {
+ return $this->areavisiblename;
+ }
+ } else {
+ return $dir;
+ }
+ }
+ }
+
+ public function get_url($forcedownload=false, $https=false) {
+ global $CFG;
+
+ if (!$this->is_readable()) {
+ return null;
+ }
+
+ if ($this->is_directory()) {
+ return null;
+ }
+
+ $this->urlbase;
+ $contextid = $this->lf->get_contextid();
+ $filearea = $this->lf->get_filearea();
+ $filepath = $this->lf->get_filepath();
+ $filename = $this->lf->get_filename();
+ $itemid = $this->lf->get_itemid();
+
+ if ($this->itemidused) {
+ $path = '/'.$contextid.'/'.$filearea.'/'.$itemid.$filepath.$filename;
+ } else {
+ $path = '/'.$contextid.'/'.$filearea.$filepath.$filename;
+ }
+ return $this->browser->encodepath($this->urlbase, $path, $forcedownload, $https);
+ }
+
+ public function is_readable() {
+ return $this->readaccess;
+ }
+
+ public function is_writable() {
+ return $this->writeaccess;
+ }
+
+ public function get_filesize() {
+ return $this->lf->get_filesize();
+ }
+
+ public function get_mimetype() {
+ // TODO: add some custom mime icons for courses, categories??
+ return $this->lf->get_mimetype();
+ }
+
+ public function get_timecreated() {
+ return $this->lf->get_timecreated();
+ }
+
+ public function get_timemodified() {
+ return $this->lf->get_timemodified();
+ }
+
+ public function is_directory() {
+ if (!$this->lf) {
+ return true;
+ }
+
+ return ($this->lf->get_filename() === '.');
+ }
+
+ public function get_children() {
+ if ($this->lf->get_filename() !== '.') {
+ return array(); //not a dir
+ }
+ return $this->browser->build_stored_file_children($this->context, $this->lf->get_filearea(), $this->lf->get_itemid(), $this->lf->get_filepath(),
+ $this->urlbase, $this->areavisiblename, $this->itemidused, $this->readaccess, $this->writeaccess);
+ }
+
+ public function get_parent() {
+ if ($this->lf->get_filename() !== '.') {
+ return $this->browser->get_file_info($this->context, $this->lf->get_filearea(), $this->lf->get_itemid(), $this->lf->get_filepath(), '.');
+ }
+
+ if ($this->lf->get_filepath() === '/') {
+ if ($this->itemidused) {
+ return $this->browser->get_file_info($this->context, $this->lf->get_filearea(), $this->lf->get_itemid());
+ } else {
+ return $this->browser->get_file_info($this->context, $this->lf->get_filearea());
+ }
+ }
+
+ $filepath = $this->lf->get_filepath();
+ $filepath = trim($filepath, '/');
+ $dirs = explode('/', $filepath);
+ array_pop($dirs);
+ $filepath = implode('/', $dirs);
+ $filepath = ($filepath === '') ? '/' : "/$filepath/";
+
+ return $this->browser->get_file_info($this->context, $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, '.');
+ }
+
+ public function create_directory($newdirname, $userid=null) {
+ if (!$this->is_writable() or $this->lf->get_filename() !== '.') {
+ return null;
+ }
+
+ $newdirname = clean_param($newdirname, PARAM_FILE);
+ if ($newdirname === '') {
+ return null;
+ }
+
+ $filepath = $this->lf->get_filepath().'/'.$newdirname.'/';
+
+ $fs = get_file_storage();
+
+ if ($file = $fs->create_directory($this->lf->get_contextid(), $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, $userid)) {
+ return $this->browser->get_file_info($this->context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
+ }
+ return null;
+ }
+
+
+ public function create_file_from_string($newfilename, $content, $userid=null) {
+ if (!$this->is_writable() or $this->lf->get_filename() !== '.') {
+ return null;
+ }
+
+ $newfilename = clean_param($newfilename, PARAM_FILE);
+ if ($newfilename === '') {
+ return null;
+ }
+
+ $now = time();
+
+ $newrecord = new object();
+ $newrecord->contextid = $this->lf->get_contextid();
+ $newrecord->filearea = $this->lf->get_filearea();
+ $newrecord->itemid = $this->lf->get_itemid();
+ $newrecord->filepath = $this->lf->get_filepath();
+ $newrecord->filename = $newfilename;
+
+ $newrecord->timecreated = $now;
+ $newrecord->timemodified = $now;
+ $newrecord->mimetype = mimeinfo('type', $newfilename);
+ $newrecord->userid = $userid;
+
+ $fs = get_file_storage();
+
+ if ($file = $fs->create_file_from_string($newrecord, $content)) {
+ return $this->browser->get_file_info($this->context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
+ }
+ return null;
+ }
+
+ public function create_file_from_pathname($newfilename, $pathname, $userid=null) {
+ if (!$this->is_writable() or $this->lf->get_filename() !== '.') {
+ return null;
+ }
+
+ $newfilename = clean_param($newfilename, PARAM_FILE);
+ if ($newfilename === '') {
+ return null;
+ }
+
+ $now = time();
+
+ $newrecord = new object();
+ $newrecord->contextid = $this->lf->get_contextid();
+ $newrecord->filearea = $this->lf->get_filearea();
+ $newrecord->itemid = $this->lf->get_itemid();
+ $newrecord->filepath = $this->lf->get_filepath();
+ $newrecord->filename = $newfilename;
+
+ $newrecord->timecreated = $now;
+ $newrecord->timemodified = $now;
+ $newrecord->mimetype = mimeinfo('type', $newfilename);
+ $newrecord->userid = $userid;
+
+ $fs = get_file_storage();
+
+ if ($file = $fs->create_file_from_pathname($newrecord, $pathname)) {
+ return $this->browser->get_file_info($this->context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
+ }
+ return null;
+ }
+
+ public function create_file_from_localfile($newfilename, $fid, $userid=null) {
+ if (!$this->is_writable() or $this->lf->get_filename() !== '.') {
+ return null;
+ }
+
+ $newfilename = clean_param($newfilename, PARAM_FILE);
+ if ($newfilename === '') {
+ return null;
+ }
+
+ $now = time();
+
+ $newrecord = new object();
+ $newrecord->contextid = $this->lf->get_contextid();
+ $newrecord->filearea = $this->lf->get_filearea();
+ $newrecord->itemid = $this->lf->get_itemid();
+ $newrecord->filepath = $this->lf->get_filepath();
+ $newrecord->filename = $newfilename;
+
+ $newrecord->timecreated = $now;
+ $newrecord->timemodified = $now;
+ $newrecord->mimetype = mimeinfo('type', $newfilename);
+ $newrecord->userid = $userid;
+
+ $fs = get_file_storage();
+
+ if ($file = $fs->create_file_from_localfile($newrecord, $fid)) {
+ return $this->browser->get_file_info($this->context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
+ }
+ return null;
+ }
+
+ public function delete() {
+ if (!$this->lf or !$this->is_writable()) {
+ return false;
+ }
+
+ if ($this->is_directory()) {
+ $filepath = $this->lf->get_filepath();
+ $fs = get_file_storage();
+ $localfiles = $fs->get_area_files($this->context->id, $this->lf->get_filearea(), $this->lf->get_itemid(), "");
+ foreach ($localfiles as $file) {
+ if (strpos($file->get_filepath(), $filepath) === 0) {
+ $file->delete();
+ }
+ }
+ }
+
+ return $this->lf->delete();
+ }
+}
--- /dev/null
+<?php //$Id$
+
+class file_info_system extends file_info {
+ public function __construct($browser) {
+ parent::__construct($browser, get_context_instance(CONTEXT_SYSTEM));
+ }
+
+ public function get_params() {
+ return array('contextid'=>$this->context->id,
+ 'filearea' =>null,
+ 'itemid' =>null,
+ 'filepath' =>null,
+ 'filename' =>null);
+ }
+
+ public function get_visible_name() {
+ return 'Root'; // TODO: fix & localise
+ }
+
+ public function is_writable() {
+ return false;
+ }
+
+ public function is_directory() {
+ return true;
+ }
+
+ public function get_children() {
+ global $DB, $USER;
+
+ $children = array();
+
+ if ($child = $this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id))) {
+ $children[] = $child;
+ }
+
+ $course_cats = $DB->get_records('course_categories', array('parent'=>0), 'sortorder');
+ foreach ($course_cats as $category) {
+ $context = get_context_instance(CONTEXT_COURSECAT, $category->id);
+ if (!$category->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ continue;
+ }
+ if ($child = $this->browser->get_file_info($context)) {
+ $children[] = $child;
+ }
+ }
+
+ $courses = $DB->get_records('course', array('category'=>0), 'sortorder');
+ foreach ($courses as $course) {
+ if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ continue;
+ }
+ $context = get_context_instance(CONTEXT_COURSE, $course->id);
+ if ($child = $this->browser->get_file_info($context)) {
+ $children[] = $child;
+ }
+ }
+
+ return $children;
+ }
+
+ public function get_parent() {
+ return null;
+ }
+}
--- /dev/null
+<?php //$Id$
+
+class file_info_user extends file_info {
+ protected $user;
+
+ public function __construct($browser, $context) {
+ global $DB, $USER;
+
+ parent::__construct($browser, $context);
+
+ $userid = $context->instanceid;
+
+ if ($userid == $USER->id) {
+ $this->user = $USER;
+ } else {
+ // if context exists user record should exist too ;-)
+ $this->user = $DB->get_record('user', array('id'=>$userid));
+ }
+ }
+
+ public function get_params() {
+ return array('contextid'=>$this->context->id,
+ 'filearea' =>null,
+ 'itemid' =>null,
+ 'filepath' =>null,
+ 'filename' =>null);
+ }
+
+ public function get_visible_name() {
+ return fullname($this->user, true);
+ }
+
+ public function is_directory() {
+ return true;
+ }
+
+ public function get_children() {
+ global $USER, $CFG;
+
+ // only current user for now
+ return array($this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id), 'user_private', 0));
+ }
+
+ public function get_parent() {
+ return $this->browser->get_file_info(get_context_instance(CONTEXT_SYSTEM));
+ }
+}
--- /dev/null
+<?php //$Id$
+
+class file_packer {
+
+}
\ No newline at end of file
--- /dev/null
+<?php //$Id$
+
+require_once("$CFG->libdir/file/stored_file.php");
+
+class file_storage {
+ private $filedir;
+
+ /**
+ * Contructor
+ * @param string $filedir full path to pool directory
+ */
+ public function __construct() {
+ global $CFG;
+ if (isset($CFG->filedir)) {
+ $this->filedir = $CFG->filedir;
+ } else {
+ $this->filedir = $CFG->dataroot.'/filedir';
+ }
+
+ // make sure the file pool directory exists
+ if (!is_dir($this->filedir)) {
+ if (!check_dir_exists($this->filedir, true, true)) {
+ throw new file_exception('localfilecannotcreatefiledirs'); // permission trouble
+ }
+ // place warning file in file pool root
+ $fp = fopen($this->filedir.'/warning.txt', 'w');
+ fwrite($fp, 'This directory contains the content of uploaded files and is controlled by Moodle code. Do not manually move, change or rename any of the files and subdirectories here.');
+ fclose($fp);
+ unset($fp);
+ }
+ }
+
+ /**
+ * Calculates sha1 hash of unique full path name information
+ * @param int $contextid
+ * @param string $filearea
+ * @param int $itemid
+ * @param string $filepath
+ * @param string $filename
+ * @return string
+ */
+ public static function get_pathname_hash($contextid, $filearea, $itemid, $filepath, $filename) {
+ return sha1($contextid.$filearea.$itemid.$filepath.$filename);
+ }
+
+ /**
+ * Does this file exist?
+ * @param int $contextid
+ * @param string $filearea
+ * @param int $itemid
+ * @param string $filepath
+ * @param string $filename
+ * @return bool
+ */
+ public function file_exists($contextid, $filearea, $itemid, $filepath, $filename) {
+ $filepath = clean_param($filepath, PARAM_PATH);
+ $filename = clean_param($filename, PARAM_FILE);
+
+ if ($filename === '') {
+ $filename = '.';
+ }
+
+ $pathnamehash = $this->get_pathname_hash($contextid, $filearea, $itemid, $filepath, $filename);
+ return $this->file_exists_by_hash($pathnamehash);
+ }
+
+ /**
+ * Does this file exist?
+ * @param string $pathnamehash
+ * @return bool
+ */
+ public function file_exists_by_hash($pathnamehash) {
+ global $DB;
+
+ return $DB->record_exists('files', array('pathnamehash'=>$pathnamehash));
+ }
+
+ /**
+ * Fetch file using local file id
+ * @param int $fileid
+ * @return mixed stored_file instance if exists, false if not
+ */
+ public function get_file_by_id($fileid) {
+ global $DB;
+
+ if ($file_record = $DB->get_record('files', array('id'=>$fileid))) {
+ return new stored_file($this, $file_record);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Fetch file using local file full pathname hash
+ * @param string $pathnamehash
+ * @return mixed stored_file instance if exists, false if not
+ */
+ public function get_file_by_hash($pathnamehash) {
+ global $DB;
+
+ if ($file_record = $DB->get_record('files', array('pathnamehash'=>$pathnamehash))) {
+ return new stored_file($this, $file_record);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Fetch file
+ * @param int $contextid
+ * @param string $filearea
+ * @param int $itemid
+ * @param string $filepath
+ * @param string $filename
+ * @return mixed stored_file instance if exists, false if not
+ */
+ public function get_file($contextid, $filearea, $itemid, $filepath, $filename) {
+ global $DB;
+
+ $filepath = clean_param($filepath, PARAM_PATH);
+ $filename = clean_param($filename, PARAM_FILE);
+
+ if ($filename === '') {
+ $filename = '.';
+ }
+
+ $pathnamehash = $this->get_pathname_hash($contextid, $filearea, $itemid, $filepath, $filename);
+ return $this->get_file_by_hash($pathnamehash);
+ }
+
+ /**
+ * Returns all area files (optionally limited by itemid)
+ * @param int $contextid
+ * @param string $filearea
+ * @param int $itemid (all files if not specified)
+ * @param string $sort
+ * @param bool $includedirs
+ * @return array of stored_files
+ */
+ public function get_area_files($contextid, $filearea, $itemid=false, $sort="itemid, filepath, filename", $inludedirs=true) {
+ global $DB;
+
+ $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea);
+ if ($itemid !== false) {
+ $conditions['itemid'] = $itemid;
+ }
+
+ $result = array();
+ $file_records = $DB->get_records('files', $conditions, $sort);
+ foreach ($file_records as $file_record) {
+ if (!$inludedirs and $file_record->filename === '.') {
+ continue;
+ }
+ $result[] = new stored_file($this, $file_record);
+ }
+ return $result;
+ }
+
+ /**
+ * Delete all area files (optionally limited by itemid)
+ * @param int $contextid
+ * @param string $filearea
+ * @param int $itemid (all files if not specified)
+ * @return success
+ */
+ public function delete_area_files($contextid, $filearea, $itemid=false) {
+ global $DB;
+
+ $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea);
+ if ($itemid !== false) {
+ $conditions['itemid'] = $itemid;
+ }
+
+ $success = true;
+
+ $file_records = $DB->get_records('files', $conditions);
+ foreach ($file_records as $file_record) {
+ $stored_file = new stored_file($this, $file_record);
+ $success = $stored_file->delete() && $success;
+ }
+
+ return $success;
+ }
+
+ /**
+ * Recursively creates director
+ * @param int $contextid
+ * @param string $filearea
+ * @param int $itemid
+ * @param string $filepath
+ * @param string $filename
+ * @return bool success
+ */
+ public function create_directory($contextid, $filearea, $itemid, $filepath, $userid=null) {
+ global $DB;
+
+ // validate all parameters, we do not want any rubbish stored in database, right?
+ if (!is_number($contextid) or $contextid < 1) {
+ throw new file_exception('localfileproblem', 'Invalid contextid');
+ }
+
+ $filearea = clean_param($filearea, PARAM_SAFEDIR);
+ if ($filearea === '') {
+ throw new file_exception('localfileproblem', 'Invalid filearea');
+ }
+
+ if (!is_number($itemid) or $itemid < 0) {
+ throw new file_exception('localfileproblem', 'Invalid itemid');
+ }
+
+ $filepath = clean_param($filepath, PARAM_PATH);
+ if (strpos($filepath, '/') !== 0 or strrpos($filepath, '/') !== strlen($filepath)-1) {
+ // path must start and end with '/'
+ throw new file_exception('localfileproblem', 'Invalid file path');
+ }
+
+ $pathnamehash = $this->get_pathname_hash($contextid, $filearea, $itemid, $filepath, '.');
+
+ if ($dir_info = $this->get_file_by_hash($pathnamehash)) {
+ return $dir_info;
+ }
+
+ static $contenthash = null;
+ if (!$contenthash) {
+ $this->add_to_pool_string('');
+ $contenthash = sha1('');
+ }
+
+ $now = time();
+
+ $dir_record = new object();
+ $dir_record->contextid = $contextid;
+ $dir_record->filearea = $filearea;
+ $dir_record->itemid = $itemid;
+ $dir_record->filepath = $filepath;
+ $dir_record->filename = '.';
+ $dir_record->contenthash = $contenthash;
+ $dir_record->filesize = 0;
+
+ $dir_record->timecreated = $now;
+ $dir_record->timemodified = $now;
+ $dir_record->mimetype = null;
+ $dir_record->userid = $userid;
+
+ $dir_record->pathnamehash = $pathnamehash;
+
+ $DB->insert_record('files', $dir_record);
+ $dir_info = $this->get_file_by_hash($pathnamehash);
+
+ if ($filepath !== '/') {
+ //recurse to parent dirs
+ $filepath = trim($filepath, '/');
+ $filepath = explode('/', $filepath);
+ array_pop($filepath);
+ $filepath = implode('/', $filepath);
+ $filepath = ($filepath === '') ? '/' : "/$filepath/";
+ $this->create_directory($contextid, $filearea, $itemid, $filepath, $userid);
+ }
+
+ return $dir_info;
+ }
+
+ /**
+ * Add new local file based on existing local file
+ * @param mixed $file_record object or array describing changes
+ * @param int $fid id of existing local file
+ * @return object stored_file instance
+ */
+ public function create_file_from_localfile($file_record, $fid) {
+ global $DB;
+
+ $file_record = (array)$file_record; // we support arrays too
+ unset($file_record['id']);
+ unset($file_record['filesize']);
+ unset($file_record['contenthash']);
+
+ $now = time();
+
+ if ($newrecord = $DB->get_record('files', array('id'=>$fid))) {
+ throw new file_exception('localfileproblem', 'File does not exist');
+ }
+
+ unset($newrecord->id);
+
+ foreach ($file_record as $key=>$value) {
+ // validate all parameters, we do not want any rubbish stored in database, right?
+ if ($key == 'contextid' and (!is_number($value) or $value < 1)) {
+ throw new file_exception('localfileproblem', 'Invalid contextid');
+ }
+
+ if ($key == 'filearea') {
+ $value = clean_param($value, PARAM_SAFEDIR);
+ if ($value === '') {
+ throw new file_exception('localfileproblem', 'Invalid filearea');
+ }
+ }
+
+ if ($key == 'itemid' and (!is_number($value) or $value < 0)) {
+ throw new file_exception('localfileproblem', 'Invalid itemid');
+ }
+
+
+ if ($key == 'filepath') {
+ $value = clean_param($value, PARAM_PATH);
+ if (strpos($value, '/') !== 0 or strpos($value, '/') !== strlen($value)-1) {
+ // path must start and end with '/'
+ throw new file_exception('localfileproblem', 'Invalid file path');
+ }
+ }
+
+ if ($key == 'filename') {
+ $value = clean_param($value, PARAM_FILE);
+ if ($value === '') {
+ // path must start and end with '/'
+ throw new file_exception('localfileproblem', 'Invalid file name');
+ }
+ }
+
+ $newrecord->$key = $value;
+ }
+
+ $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename);
+
+ try {
+ $newrecord->id = $DB->insert_record('files', $newrecord);
+ } catch (database_exception $e) {
+ $newrecord->id = false;
+ }
+
+ if (!$newrecord->id) {
+ throw new stored_file_creation_exception($newrecord->contextid, $newrecord->filearea, $newrecord->itemid,
+ $newrecord->filepath, $newrecord->filename);
+ }
+
+ $this->create_directory($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid);
+
+ return new stored_file($this, $newrecord);
+ }
+
+ /**
+ * Add new local file
+ * @param mixed $file_record object or array describing file
+ * @param string $path path to file or content of file
+ * @return object stored_file instance
+ */
+ public function create_file_from_pathname($file_record, $pathname) {
+ global $DB;
+
+ $file_record = (object)$file_record; // we support arrays too
+
+ // validate all parameters, we do not want any rubbish stored in database, right?
+ if (!is_number($file_record->contextid) or $file_record->contextid < 1) {
+ throw new file_exception('localfileproblem', 'Invalid contextid');
+ }
+
+ $file_record->filearea = clean_param($file_record->filearea, PARAM_SAFEDIR);
+ if ($file_record->filearea === '') {
+ throw new file_exception('localfileproblem', 'Invalid filearea');
+ }
+
+ if (!is_number($file_record->itemid) or $file_record->itemid < 0) {
+ throw new file_exception('localfileproblem', 'Invalid itemid');
+ }
+
+ $file_record->filepath = clean_param($file_record->filepath, PARAM_PATH);
+ if (strpos($file_record->filepath, '/') !== 0 or strrpos($file_record->filepath, '/') !== strlen($file_record->filepath)-1) {
+ // path must start and end with '/'
+ throw new file_exception('localfileproblem', 'Invalid file path');
+ }
+
+ $file_record->filename = clean_param($file_record->filename, PARAM_FILE);
+ if ($file_record->filename === '') {
+ // path must start and end with '/'
+ throw new file_exception('localfileproblem', 'Invalid file name');
+ }
+
+ $now = time();
+
+ $newrecord = new object();
+
+ $newrecord->contextid = $file_record->contextid;
+ $newrecord->filearea = $file_record->filearea;
+ $newrecord->itemid = $file_record->itemid;
+ $newrecord->filepath = $file_record->filepath;
+ $newrecord->filename = $file_record->filename;
+
+ $newrecord->timecreated = empty($file_record->timecreated) ? $now : $file_record->timecreated;
+ $newrecord->timemodified = empty($file_record->timemodified) ? $now : $file_record->timemodified;
+ $newrecord->mimetype = empty($file_record->mimetype) ? mimeinfo('type', $file_record->filename) : $file_record->mimetype;
+ $newrecord->userid = empty($file_record->userid) ? null : $file_record->userid;
+
+ list($newrecord->contenthash, $newrecord->filesize, $newfile) = $this->add_to_pool_pathname($pathname);
+
+ $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename);
+
+ try {
+ $newrecord->id = $DB->insert_record('files', $newrecord);
+ } catch (database_exception $e) {
+ $newrecord->id = false;
+ }
+
+ if (!$newrecord->id) {
+ if ($newfile) {
+ $this->mark_delete_candidate($newrecord->contenthash);
+ }
+ throw new stored_file_creation_exception($newrecord->contextid, $newrecord->filearea, $newrecord->itemid,
+ $newrecord->filepath, $newrecord->filename);
+ }
+
+ $this->create_directory($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid);
+
+ return new stored_file($this, $newrecord);
+ }
+
+ /**
+ * Add new local file
+ * @param mixed $file_record object or array describing file
+ * @param string $content content of file
+ * @return object stored_file instance
+ */
+ public function create_file_from_string($file_record, $content) {
+ global $DB;
+
+ $file_record = (object)$file_record; // we support arrays too
+
+ // validate all parameters, we do not want any rubbish stored in database, right?
+ if (!is_number($file_record->contextid) or $file_record->contextid < 1) {
+ throw new file_exception('localfileproblem', 'Invalid contextid');
+ }
+
+ $file_record->filearea = clean_param($file_record->filearea, PARAM_SAFEDIR);
+ if ($file_record->filearea === '') {
+ throw new file_exception('localfileproblem', 'Invalid filearea');
+ }
+
+ if (!is_number($file_record->itemid) or $file_record->itemid < 0) {
+ throw new file_exception('localfileproblem', 'Invalid itemid');
+ }
+
+ $file_record->filepath = clean_param($file_record->filepath, PARAM_PATH);
+ if (strpos($file_record->filepath, '/') !== 0 or strrpos($file_record->filepath, '/') !== strlen($file_record->filepath)-1) {
+ // path must start and end with '/'
+ throw new file_exception('localfileproblem', 'Invalid file path');
+ }
+
+ $file_record->filename = clean_param($file_record->filename, PARAM_FILE);
+ if ($file_record->filename === '') {
+ // path must start and end with '/'
+ throw new file_exception('localfileproblem', 'Invalid file name');
+ }
+
+ $now = time();
+
+ $newrecord = new object();
+
+ $newrecord->contextid = $file_record->contextid;
+ $newrecord->filearea = $file_record->filearea;
+ $newrecord->itemid = $file_record->itemid;
+ $newrecord->filepath = $file_record->filepath;
+ $newrecord->filename = $file_record->filename;
+
+ $newrecord->timecreated = empty($file_record->timecreated) ? $now : $file_record->timecreated;
+ $newrecord->timemodified = empty($file_record->timemodified) ? $now : $file_record->timemodified;
+ $newrecord->mimetype = empty($file_record->mimetype) ? mimeinfo('type', $file_record->filename) : $file_record->mimetype;
+ $newrecord->userid = empty($file_record->userid) ? null : $file_record->userid;
+
+ list($newrecord->contenthash, $newrecord->filesize, $newfile) = $this->add_to_pool_string($content);
+
+ $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename);
+
+ try {
+ $newrecord->id = $DB->insert_record('files', $newrecord);
+ } catch (database_exception $e) {
+ $newrecord->id = false;
+ }
+
+ if (!$newrecord->id) {
+ if ($newfile) {
+ $this->mark_delete_candidate($newrecord->contenthash);
+ }
+ throw new stored_file_creation_exception($newrecord->contextid, $newrecord->filearea, $newrecord->itemid,
+ $newrecord->filepath, $newrecord->filename);
+ }
+
+ $this->create_directory($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid);
+
+ return new stored_file($this, $newrecord);
+ }
+
+ /**
+ * Add file content to sha1 pool
+ * @param string $pathname path to file
+ * @param string sha1 hash of content if known (performance only)
+ * @return array(contenthash, filesize, newfile)
+ */
+ public function add_to_pool_pathname($pathname, $contenthash=null) {
+ if (!is_readable($pathname)) {
+ throw new file_exception('localfilecannotread');
+ }
+
+ if (is_null($contenthash)) {
+ $contenthash = sha1_file($pathname);
+ }
+
+ $filesize = filesize($pathname);
+
+ $hashpath = $this->path_from_hash($contenthash);
+ $hashfile = "$hashpath/$contenthash";
+
+ if (file_exists($hashfile)) {
+ if (filesize($hashfile) !== $filesize) {
+ throw new file_pool_content_exception($contenthash);
+ }
+ $newfile = false;
+
+ } else {
+ if (!check_dir_exists($hashpath, true, true)) {
+ throw new file_exception('localfilecannotcreatefiledirs'); // permission trouble
+ }
+ $newfile = true;
+
+ $fs = fopen($pathname, 'rb');
+ $fp = fopen($hashfile, 'wb');
+ while(!feof($fs)) {
+ $buf = fread($fs, 65536);
+ if ($buf === false) {
+ throw new file_exception('localfilecannotread');
+ }
+ fwrite($fp, $buf);
+ }
+ fclose($fp);
+ fclose($fs);
+
+ if (filesize($hashfile) !== $filesize) {
+ @unlink($hashfile);
+ throw new file_pool_content_exception($contenthash);
+ }
+ }
+
+
+ return array($contenthash, $filesize, $newfile);
+ }
+
+ /**
+ * Add string content to sha1 pool
+ * @param string $content file content - binary string
+ * @return array(contenthash, filesize, newfile)
+ */
+ public function add_to_pool_string($content) {
+ $contenthash = sha1($content);
+ $filesize = strlen($content); // binary length
+
+ $hashpath = $this->path_from_hash($contenthash);
+ $hashfile = "$hashpath/$contenthash";
+
+
+ if (file_exists($hashfile)) {
+ if (filesize($hashfile) !== $filesize) {
+ throw new file_pool_content_exception($contenthash);
+ }
+ $newfile = false;
+
+ } else {
+ if (!check_dir_exists($hashpath, true, true)) {
+ throw new file_exception('localfilecannotcreatefiledirs'); // permission trouble
+ }
+ $newfile = true;
+
+ $fp = fopen($hashfile, 'wb');
+
+ fwrite($fp, $content);
+ fclose($fp);
+
+ if (filesize($hashfile) !== $filesize) {
+ @unlink($hashfile);
+ throw new file_pool_content_exception($contenthash);
+ }
+ }
+
+ return array($contenthash, $filesize, $newfile);
+ }
+
+ /**
+ * Return path to file with given hash
+ *
+ * DO NOT USE - should be protected, but protected is dumb in PHP
+ *
+ * @param string $contenthash
+ * @return string expected file location
+ */
+ public function path_from_hash($contenthash) {
+ $l1 = $contenthash[0].$contenthash[1];
+ $l2 = $contenthash[2].$contenthash[3];
+ $l3 = $contenthash[4].$contenthash[5];
+ return "$this->filedir/$l1/$l2/$l3";
+ }
+
+ /**
+ * Marks pool file as candidate for deleting
+ * @param string $contenthash
+ */
+ public function mark_delete_candidate($contenthash) {
+ global $DB;
+
+ if ($DB->record_exists('files_cleanup', array('contenthash'=>$contenthash))) {
+ return;
+ }
+ $rec = new object();
+ $rec->contenthash = $contenthash;
+ $DB->insert_record('files_cleanup', $rec);
+ }
+
+ /**
+ * Cron cleanup job.
+ */
+ public function cron() {
+ global $DB;
+
+ //TODO: there is a small chance that reused files might be deleted
+ // if this function takes too long we should add some table locking here
+
+ $sql = "SELECT 1 AS id, fc.contenthash
+ FROM {files_cleanup} fc
+ LEFT JOIN {files} f ON f.contenthash = fc.contenthash
+ WHERE f.id IS NULL";
+ while ($hash = $DB->get_record_sql($sql, null, true)) {
+ $file = $this->path_from_hash($hash->contenthash).'/'.$hash->contenthash;
+ @unlink($file);
+ $DB->delete_records('files_cleanup', array('contenthash'=>$hash->contenthash));
+ }
+ }
+}
--- /dev/null
+<?php //$Id$
+
+/**
+ * Class representing local files stored in sha1 file pool
+ */
+class stored_file {
+ private $fs;
+ private $file_record;
+
+ /**
+ * Constructor
+ * @param object $fs file storage instance
+ * @param object $file_record description of file
+ */
+ public function __construct($fs, $file_record) {
+ $this->fs = $fs;
+ $this->file_record = clone($file_record);
+ }
+
+ /**
+ * Is this a directory?
+ * @return bool
+ */
+ public function is_directory() {
+ return $this->file_record->filename === '.';
+ }
+
+ /**
+ * Delete file
+ * @return success
+ */
+ public function delete() {
+ global $DB;
+ $this->fs->mark_delete_candidate($this->file_record->contenthash);
+ return $DB->delete_records('files', array('id'=>$this->file_record->id));
+ }
+
+ /**
+ * Protected - devs must not gain direct access to this function
+ **/
+ protected function get_content_file_location() {
+ // NOTE: do not make this public, we must not modify or delete the pool files directly! ;-)
+ $hashpath = $this->fs->path_from_hash($this->file_record->contenthash);
+ return $hashpath.'/'.$this->file_record->contenthash;
+ }
+
+ /**
+ * Returns file handle - read only mode, no writing allowed into pool files!
+ * @return file handle
+ */
+ public function get_content_file_handle() {
+ $path = $this->get_content_file_location();
+ if (!is_readable($path)) {
+ throw new file_exception('localfilecannotread');
+ }
+ return fopen($path, 'rb'); //binary reading only!!
+ }
+
+ /**
+ * Dumps file content to page
+ * @return file handle
+ */
+ public function readfile() {
+ $path = $this->get_content_file_location();
+ if (!is_readable($path)) {
+ throw new file_exception('localfilecannotread');
+ }
+ readfile($path);
+ }
+
+ /**
+ * Returns file content as string
+ * @return string content
+ */
+ public function get_content() {
+ $path = $this->get_content_file_location();
+ if (!is_readable($path)) {
+ throw new file_exception('localfilecannotread');
+ }
+ return file_get_contents($this->get_content_file_location());
+ }
+
+ public function get_contextid() {
+ return $this->file_record->contextid;
+ }
+
+ public function get_filearea() {
+ return $this->file_record->filearea;
+ }
+
+ public function get_itemid() {
+ return $this->file_record->itemid;
+ }
+
+ public function get_filepath() {
+ return $this->file_record->filepath;
+ }
+
+ public function get_filename() {
+ return $this->file_record->filename;
+ }
+
+ public function get_userid() {
+ return $this->file_record->userid;
+ }
+
+ public function get_filesize() {
+ return $this->file_record->filesize;
+ }
+
+ public function get_mimetype() {
+ return $this->file_record->mimetype;
+ }
+
+ public function get_timecreated() {
+ return $this->file_record->timecreated;
+ }
+
+ public function get_timemodified() {
+ return $this->file_record->timemodified;
+ }
+}
define('BYTESERVING_BOUNDARY', 's1k2o3d4a5k6s7'); //unique string constant
+require_once("$CFG->libdir/file/file_exceptions.php");
+require_once("$CFG->libdir/file/file_storage.php");
+require_once("$CFG->libdir/file/file_browser.php");
+
function get_file_url($path, $options=null, $type='coursefile') {
global $CFG;
- $path = str_replace('//', '/', $path);
+ $path = str_replace('//', '/', $path);
$path = trim($path, '/'); // no leading and trailing slashes
// type of file
* Unknown types should use the 'xxx' entry which includes defaults.
*/
function get_mimetypes_array() {
- return array (
+ static $mimearray = array (
'xxx' => array ('type'=>'document/unknown', 'icon'=>'unknown.gif'),
'3gp' => array ('type'=>'video/quicktime', 'icon'=>'video.gif'),
'ai' => array ('type'=>'application/postscript', 'icon'=>'image.gif'),
'xsl' => array ('type'=>'text/xml', 'icon'=>'xml.gif'),
'zip' => array ('type'=>'application/zip', 'icon'=>'zip.gif')
);
+ return $mimearray;
}
/**
* @return string Requested piece of information from array
*/
function mimeinfo($element, $filename) {
- static $mimeinfo = null;
- if (is_null($mimeinfo)) {
- $mimeinfo = get_mimetypes_array();
- }
+ $mimeinfo = get_mimetypes_array();
if (eregi('\.([a-z0-9]+)$', $filename, $match)) {
if (isset($mimeinfo[strtolower($match[1])][$element])) {
* @return string Requested piece of information from array
*/
function mimeinfo_from_type($element, $mimetype) {
- static $mimeinfo;
- $mimeinfo=get_mimetypes_array();
+ $mimeinfo = get_mimetypes_array();
foreach($mimeinfo as $values) {
if($values['type']==$mimetype) {
* @return string Requested piece of information from array
*/
function mimeinfo_from_icon($element, $icon) {
- static $mimeinfo;
- $mimeinfo=get_mimetypes_array();
+ $mimeinfo = get_mimetypes_array();
if (preg_match("/\/(.*)/", $icon, $matches)) {
$icon = $matches[1];
function send_file($path, $filename, $lifetime=86400 , $filter=0, $pathisstring=false, $forcedownload=false, $mimetype='') {
global $CFG, $COURSE, $SESSION;
+ session_write_close(); // unlock session during fileserving
+
// Use given MIME type if specified, otherwise guess it using mimeinfo.
// IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
// only Firefox saves all files locally before opening when content-disposition: attachment stated
$ranges = false;
}
if ($ranges) {
- byteserving_send_file($path, $mimetype, $ranges);
+ $handle = fopen($filename, 'rb');
+ byteserving_send_file($handle, $mimetype, $ranges, $filesize);
}
}
} else {
die; //no more chars to output!!!
}
+/**
+ * Handles the sending of file data to the user's browser, including support for
+ * byteranges etc.
+ * @param object $stored_file local file object
+ * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours)
+ * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only
+ * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin
+ * @param string $filename Override filename
+ * @param string $mimetype Include to specify the MIME type; leave blank to have it guess the type from $filename
+ */
+function send_stored_file($stored_file, $lifetime=86400 , $filter=0, $forcedownload=false, $filename=null) {
+ global $CFG, $COURSE, $SESSION;
+
+ session_write_close(); // unlock session during fileserving
+
+ // Use given MIME type if specified, otherwise guess it using mimeinfo.
+ // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
+ // only Firefox saves all files locally before opening when content-disposition: attachment stated
+ $filename = is_null($filename) ? $stored_file->get_filename() : $filename;
+ $isFF = check_browser_version('Firefox', '1.5'); // only FF > 1.5 properly tested
+ $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
+ ($stored_file->get_mimetype() ? $stored_file->get_mimetype() : mimeinfo('type', $filename));
+ $lastmodified = $stored_file->get_timemodified();
+ $filesize = $stored_file->get_filesize();
+
+ //IE compatibiltiy HACK!
+ if (ini_get('zlib.output_compression')) {
+ ini_set('zlib.output_compression', 'Off');
+ }
+
+ //try to disable automatic sid rewrite in cookieless mode
+ @ini_set("session.use_trans_sid", "false");
+
+ //do not put '@' before the next header to detect incorrect moodle configurations,
+ //error should be better than "weird" empty lines for admins/users
+ //TODO: should we remove all those @ before the header()? Are all of the values supported on all servers?
+ header('Last-Modified: '. gmdate('D, d M Y H:i:s', $lastmodified) .' GMT');
+
+ // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
+ if (check_browser_version('MSIE')) {
+ $filename = rawurlencode($filename);
+ }
+
+ if ($forcedownload) {
+ @header('Content-Disposition: attachment; filename="'.$filename.'"');
+ } else {
+ @header('Content-Disposition: inline; filename="'.$filename.'"');
+ }
+
+ if ($lifetime > 0) {
+ @header('Cache-Control: max-age='.$lifetime);
+ @header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT');
+ @header('Pragma: ');
+
+ if (empty($CFG->disablebyteserving) && $mimetype != 'text/plain' && $mimetype != 'text/html') {
+
+ @header('Accept-Ranges: bytes');
+
+ if (!empty($_SERVER['HTTP_RANGE']) && strpos($_SERVER['HTTP_RANGE'],'bytes=') !== FALSE) {
+ // byteserving stuff - for acrobat reader and download accelerators
+ // see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
+ // inspired by: http://www.coneural.org/florian/papers/04_byteserving.php
+ $ranges = false;
+ if (preg_match_all('/(\d*)-(\d*)/', $_SERVER['HTTP_RANGE'], $ranges, PREG_SET_ORDER)) {
+ foreach ($ranges as $key=>$value) {
+ if ($ranges[$key][1] == '') {
+ //suffix case
+ $ranges[$key][1] = $filesize - $ranges[$key][2];
+ $ranges[$key][2] = $filesize - 1;
+ } else if ($ranges[$key][2] == '' || $ranges[$key][2] > $filesize - 1) {
+ //fix range length
+ $ranges[$key][2] = $filesize - 1;
+ }
+ if ($ranges[$key][2] != '' && $ranges[$key][2] < $ranges[$key][1]) {
+ //invalid byte-range ==> ignore header
+ $ranges = false;
+ break;
+ }
+ //prepare multipart header
+ $ranges[$key][0] = "\r\n--".BYTESERVING_BOUNDARY."\r\nContent-Type: $mimetype\r\n";
+ $ranges[$key][0] .= "Content-Range: bytes {$ranges[$key][1]}-{$ranges[$key][2]}/$filesize\r\n\r\n";
+ }
+ } else {
+ $ranges = false;
+ }
+ if ($ranges) {
+ byteserving_send_file($stored_file->get_content_file_handle(), $mimetype, $ranges, $filesize);
+ }
+ }
+ } else {
+ /// Do not byteserve (disabled, strings, text and html files).
+ @header('Accept-Ranges: none');
+ }
+ } else { // Do not cache files in proxies and browsers
+ if (strpos($CFG->wwwroot, 'https://') === 0) { //https sites - watch out for IE! KB812935 and KB316431
+ @header('Cache-Control: max-age=10');
+ @header('Expires: '. gmdate('D, d M Y H:i:s', 0) .' GMT');
+ @header('Pragma: ');
+ } else { //normal http - prevent caching at all cost
+ @header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0');
+ @header('Expires: '. gmdate('D, d M Y H:i:s', 0) .' GMT');
+ @header('Pragma: no-cache');
+ }
+ @header('Accept-Ranges: none'); // Do not allow byteserving when caching disabled
+ }
+
+ if (empty($filter)) {
+ $filtered = false;
+ if ($mimetype == 'text/html' && !empty($CFG->usesid) && empty($_COOKIE['MoodleSession'.$CFG->sessioncookie])) {
+ //cookieless mode - rewrite links
+ @header('Content-Type: text/html');
+ $text = $stored_file->get_content();
+ $text = $SESSION->sid_ob_rewrite($text);
+ $filesize = strlen($text);
+ $filtered = true;
+ } else if ($mimetype == 'text/plain') {
+ @header('Content-Type: Text/plain; charset=utf-8'); //add encoding
+ } else {
+ @header('Content-Type: '.$mimetype);
+ }
+ @header('Content-Length: '.$filesize);
+ while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
+ if ($filtered) {
+ echo $text;
+ } else {
+ $stored_file->readfile();
+ }
+
+ } else { // Try to put the file through filters
+ if ($mimetype == 'text/html') {
+ $options = new object();
+ $options->noclean = true;
+ $options->nocache = true; // temporary workaround for MDL-5136
+ $text = $stored_file->get_content();
+ $text = file_modify_html_header($text);
+ $output = format_text($text, FORMAT_HTML, $options, $COURSE->id);
+ if (!empty($CFG->usesid) && empty($_COOKIE['MoodleSession'.$CFG->sessioncookie])) {
+ //cookieless mode - rewrite links
+ $output = $SESSION->sid_ob_rewrite($output);
+ }
+
+ @header('Content-Length: '.strlen($output));
+ @header('Content-Type: text/html');
+ while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
+ echo $output;
+ // only filter text if filter all files is selected
+ } else if (($mimetype == 'text/plain') and ($filter == 1)) {
+ $options = new object();
+ $options->newlines = false;
+ $options->noclean = true;
+ $text = $stored_file->get_content();
+ $output = '<pre>'. format_text($text, FORMAT_MOODLE, $options, $COURSE->id) .'</pre>';
+ if (!empty($CFG->usesid) && empty($_COOKIE['MoodleSession'.$CFG->sessioncookie])) {
+ //cookieless mode - rewrite links
+ $output = $SESSION->sid_ob_rewrite($output);
+ }
+
+ @header('Content-Length: '.strlen($output));
+ @header('Content-Type: text/html; charset=utf-8'); //add encoding
+ while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
+ echo $output;
+ } else { // Just send it out raw
+ @header('Content-Length: '.$filesize);
+ @header('Content-Type: '.$mimetype);
+ while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
+ $stored_file->readfile();
+ }
+ }
+ die; //no more chars to output!!!
+}
+
function get_records_csv($file, $table) {
global $CFG, $DB;
/**
* Send requested byterange of file.
*/
-function byteserving_send_file($filename, $mimetype, $ranges) {
+function byteserving_send_file($handle, $mimetype, $ranges, $filesize) {
$chunksize = 1*(1024*1024); // 1MB chunks - must be less than 2MB!
- $handle = fopen($filename, 'rb');
if ($handle === false) {
die;
}
$length = $ranges[0][2] - $ranges[0][1] + 1;
@header('HTTP/1.1 206 Partial content');
@header('Content-Length: '.$length);
- @header('Content-Range: bytes '.$ranges[0][1].'-'.$ranges[0][2].'/'.filesize($filename));
+ @header('Content-Range: bytes '.$ranges[0][1].'-'.$ranges[0][2].'/'.$filesize);
@header('Content-Type: '.$mimetype);
while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
$buffer = '';
* Download multiple files in parallel
* $c = new curl;
* $c->download(array(
- * array('url'=>'http://localhost/', 'file'=>fopen('a', 'wb')),
+ * array('url'=>'http://localhost/', 'file'=>fopen('a', 'wb')),
* array('url'=>'http://localhost/20/', 'file'=>fopen('b', 'wb'))
* ));
*/
require_once 'HTML/QuickForm/DHTMLRulesTableless.php';
require_once 'HTML/QuickForm/Renderer/Tableless.php';
-require_once $CFG->libdir.'/uploadlib.php';
+require_once $CFG->libdir.'/uploadlib.php'; // TODO: remove
/**
* Callback called when PEAR throws an error
* You will write your own definition() method which performs the form set up.
*/
class moodleform {
- var $_formname; // form name
+ protected $_formname; // form name
/**
* quickform object definition
*
* @var MoodleQuickForm
*/
- var $_form;
+ protected $_form;
/**
* globals workaround
*
* @var array
*/
- var $_customdata;
- /**
- * file upload manager
- *
- * @var upload_manager
- */
- var $_upload_manager; //
+ protected $_customdata;
/**
* definition_after_data executed flag
* @var definition_finalized
*/
- var $_definition_finalized = false;
+ protected $_definition_finalized = false;
/**
* The constructor function calls the abstract function definition() and it will then
if (!$editable){
$this->_form->hardFreeze();
}
- $this->set_upload_manager(new upload_manager());
$this->definition();
* Internal method. Validates all uploaded files.
*/
function _validate_files(&$files) {
+ global $CFG, $COURSE;
+
$files = array();
if (empty($_FILES)) {
// note: server side rules do not work for files - use custom verification in validate() instead
return true;
}
- $errors = array();
- $mform =& $this->_form;
- // check the files
- $status = $this->_upload_manager->preprocess_files();
+ $errors = array();
+ $filenames = array();
// now check that we really want each file
foreach ($_FILES as $elname=>$file) {
- if ($mform->elementExists($elname) and $mform->getElementType($elname)=='file') {
- $required = $mform->isElementRequired($elname);
- if (!empty($this->_upload_manager->files[$elname]['uploadlog']) and empty($this->_upload_manager->files[$elname]['clear'])) {
- if (!$required and $file['error'] == UPLOAD_ERR_NO_FILE) {
- // file not uploaded and not required - ignore it
- continue;
- }
- $errors[$elname] = $this->_upload_manager->files[$elname]['uploadlog'];
+ $required = $this->_form->isElementRequired($elname);
- } else if (!empty($this->_upload_manager->files[$elname]['clear'])) {
- $files[$elname] = $this->_upload_manager->files[$elname]['tmp_name'];
+ if ($file['error'] == 4 and $file['size'] == 0) {
+ if ($required) {
+ $errors[$elname] = get_string('required');
}
- } else {
- print_error('cannotuploadfile');
+ unset($_FILES[$elname]);
+ continue;
+ }
+
+ if ($file['error'] > 0) {
+ switch ($file['error']) {
+ case 1: // UPLOAD_ERR_INI_SIZE
+ $errmessage = get_string('uploadserverlimit');
+ break;
+
+ case 2: // UPLOAD_ERR_FORM_SIZE
+ $errmessage = get_string('uploadformlimit');
+ break;
+
+ case 3: // UPLOAD_ERR_PARTIAL
+ $errmessage = get_string('uploadpartialfile');
+ break;
+
+ case 4: // UPLOAD_ERR_NO_FILE
+ $errmessage = get_string('uploadnofilefound');
+ break;
+
+ // Note: there is no error with a value of 5
+
+ case 6: // UPLOAD_ERR_NO_TMP_DIR
+ $errmessage = get_string('uploadnotempdir');
+ break;
+
+ case 7: // UPLOAD_ERR_CANT_WRITE
+ $errmessage = get_string('uploadcantwrite');
+ break;
+
+ case 8: // UPLOAD_ERR_EXTENSION
+ $errmessage = get_string('uploadextension');
+ break;
+
+ default:
+ $errmessage = get_string('uploadproblem', $file['name']);
+ }
+ $errors[$elname] = $errmessage;
+ unset($_FILES[$elname]);
+ continue;
+ }
+
+ if (!is_uploaded_file($file['tmp_name'])) {
+ // TODO: improve error message
+ $errors[$elname] = get_string('error');
+ unset($_FILES[$elname]);
+ continue;
+ }
+
+ if (!$this->_form->elementExists($elname) or !$this->_form->getElementType($elname)=='file') {
+ // hmm, this file was not requested
+ unset($_FILES[$elname]);
+ continue;
+ }
+
+/*
+ // TODO: rethink the file scanning
+ if ($CFG->runclamonupload) {
+ if (!clam_scan_moodle_file($_FILES[$elname], $COURSE)) {
+ $errors[$elname] = $_FILES[$elname]['uploadlog'];
+ unset($_FILES[$elname]);
+ continue;
+ }
+ }
+*/
+ $filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
+ if ($filename === '') {
+ // TODO: improve error message - wrong chars
+ $errors[$elname] = get_string('error');
+ unset($_FILES[$elname]);
+ continue;
}
+ if (in_array($filename, $filenames)) {
+ // TODO: improve error message - duplicate name
+ $errors[$elname] = get_string('error');
+ unset($_FILES[$elname]);
+ continue;
+ }
+ $filenames[] = $filename;
+ $_FILES[$elname]['name'] = $filename;
+
+ $files[$elname] = $_FILES[$elname]['tmp_name'];
}
// return errors if found
- if ($status and 0 == count($errors)){
+ if (count($errors) == 0){
return true;
} else {
$this->_form->setDefaults($default_values);
}
- /**
- * Set custom upload manager.
- * Must be used BEFORE creating of file element!
- *
- * @param object $um - custom upload manager
- */
function set_upload_manager($um=false) {
- if ($um === false) {
- $um = new upload_manager();
- }
- $this->_upload_manager = $um;
-
- $this->_form->setMaxFileSize($um->config->maxbytes);
+ debugging('Not used anymore, please fix code!');
}
/**
/**
* Return submitted data if properly submitted or returns NULL if validation fails or
* if there is no submitted data.
- *
+ *
* note: $slashed param removed
*
* @return object submitted data; NULL if not valid or not submitted
/**
* Save verified uploaded files into directory. Upload process can be customised from definition()
- * method by creating instance of upload manager and storing it in $this->_upload_form
- *
- * @param string $destination where to store uploaded files
- * @return bool success
+ * NOTE: please use save_stored_file() or save_file()
*/
function save_files($destination) {
- if ($this->is_submitted() and $this->is_validated()) {
- return $this->_upload_manager->save_files($destination);
- }
+ debugging('Not used anymore, please fix code! Use save_stored_file() or save_file() instead');
return false;
}
/**
- * If we're only handling one file (if inputname was given in the constructor)
- * this will return the (possibly changed) filename of the file.
+ * Returns name of uploaded file.
+ * @param string $elname, first element if null
* @return mixed false in case of failure, string if ok
*/
- function get_new_filename() {
- return $this->_upload_manager->get_new_filename();
+ function get_new_filename($elname=null) {
+ if (!$this->is_submitted() or !$this->is_validated()) {
+ return false;
+ }
+
+ if (is_null($elname)) {
+ if (empty($_FILES)) {
+ return false;
+ }
+ reset($_FILES);
+ $elname = key($_FILES);
+ }
+ if (!isset($_FILES[$elname])) {
+ return false;
+ }
+
+ return $_FILES[$elname]['name'];
}
/**
- * Get content of uploaded file.
- * @param $element name of file upload element
- * @return mixed false in case of failure, string if ok
+ * Save file to standard filesystem
+ * @param string $elname name of element
+ * @param string $pathname full path name of file
+ * @param bool $override override file if exists
+ * @return bool success
*/
- function get_file_content($elname) {
+ function save_file($elname, $pathname, $override=false) {
if (!$this->is_submitted() or !$this->is_validated()) {
return false;
}
- if (!$this->_form->elementExists($elname)) {
+ if (!isset($_FILES[$elname])) {
return false;
}
- if (empty($this->_upload_manager->files[$elname]['clear'])) {
+ if (file_exists($pathname)) {
+ if ($override) {
+ if (!@unlink($pathname)) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ if (!$temp = @fopen($_FILES[$elname]['tmp_name'], "rb")) {
+ return false;
+ }
+ if (!$file = @fopen($pathname, "wb")) {
+ return false;
+ }
+
+ while (!feof($temp)) {
+ $data = fread($temp, 65536);
+ fwrite($file, $data);
+ }
+ fclose($file);
+ fclose($temp);
+
+ return true;
+ }
+
+ /**
+ * Save file to local filesystem pool
+ * @param string $elname name of element
+ * @param int $contextid
+ * @param string $filearea
+ * @param string $filepath
+ * @param string $filename - use specified filename, if not specified name of uploaded file used
+ * @param bool $override override file if exists
+ * @param int $userid
+ * @return mixed stored_file object or false if error; may throw exception if duplicate found
+ */
+ function save_stored_file($elname, $contextid, $filearea, $itemid, $filepath, $filename=null, $override=false, $userid=null) {
+ if (!$this->is_submitted() or !$this->is_validated()) {
return false;
- }
+ }
- if (empty($this->_upload_manager->files[$elname]['tmp_name'])) {
+ if (!isset($_FILES[$elname])) {
return false;
}
- $data = "";
- $file = @fopen($this->_upload_manager->files[$elname]['tmp_name'], "rb");
- if ($file) {
- while (!feof($file)) {
- $data .= fread($file, 1024); // TODO: do we really have to do this?
+ $filename = is_null($filename) ? $_FILES[$elname]['name'] : $filename;
+
+ $fs = get_file_storage();
+
+ if ($file = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename)) {
+ if ($override) {
+ $file->delete();
+ } else {
+ return false;
}
- fclose($file);
- return $data;
- } else {
+ }
+
+ $file_record = new object();
+ $file_record->contextid = $contextid;
+ $file_record->filearea = $filearea;
+ $file_record->itemid = $itemid;
+ $file_record->filepath = $filepath;
+ $file_record->filename = $filename;
+ $file_record->userid = $userid;
+
+ return $fs->create_file_from_pathname($file_record, $_FILES[$elname]['tmp_name']);
+ }
+
+ /**
+ * Get content of uploaded file.
+ * @param $element name of file upload element
+ * @return mixed false in case of failure, string if ok
+ */
+ function get_file_content($elname) {
+ if (!$this->is_submitted() or !$this->is_validated()) {
+ return false;
+ }
+
+ if (!isset($_FILES[$elname])) {
return false;
}
+
+ if (!$file = @fopen($_FILES[$elname]['tmp_name'], "rb")) {
+ return false;
+ }
+
+ $data = '';
+ while (!feof($file)) {
+ $data .= fread($file, 4048);
+ }
+ fclose($file);
+
+ return $data;
}
/**
* @param array $attributes associative array of HTML attributes
* @param int $originalValue The original general state of the checkboxes before the user first clicks this element
*/
- function add_checkbox_controller($groupid, $buttontext, $attributes, $originalValue = 0) {
+ function add_checkbox_controller($groupid, $buttontext, $attributes, $originalValue = 0) {
global $CFG;
if (empty($text)) {
$text = get_string('selectallornone', 'form');
$mform->addElement('hidden', "checkbox_controller$groupid");
$mform->setConstants(array("checkbox_controller$groupid" => $new_select_value));
-
+
// Locate all checkboxes for this group and set their value, IF the optional param was given
if (!is_null($select_value)) {
foreach ($this->_form->_elements as $element) {
$checkbox_controller_name = 'nosubmit_checkbox_controller' . $groupid;
$mform->registerNoSubmitButton($checkbox_controller_name);
-
+
// Prepare Javascript for submit element
$js = "\n//<![CDATA[\n";
if (!defined('HTML_QUICKFORM_CHECKBOXCONTROLLER_EXISTS')) {
var newvalue = false;
var global = eval('html_quickform_checkboxgroup' + group + ';');
if (global == 1) {
- eval('html_quickform_checkboxgroup' + group + ' = 0;');
+ eval('html_quickform_checkboxgroup' + group + ' = 0;');
newvalue = '';
} else {
- eval('html_quickform_checkboxgroup' + group + ' = 1;');
+ eval('html_quickform_checkboxgroup' + group + ' = 1;');
newvalue = 'checked';
}
for (i = 0; i < checkboxes.length; i++) {
- checkboxes[i].checked = newvalue;
+ checkboxes[i].checked = newvalue;
}
}
EOS;
define('HTML_QUICKFORM_CHECKBOXCONTROLLER_EXISTS', true);
}
$js .= "\nvar html_quickform_checkboxgroup$groupid=$originalValue;\n";
-
+
$js .= "//]]>\n";
-
+
require_once("$CFG->libdir/form/submitlink.php");
$submitlink = new MoodleQuickForm_submitlink($checkbox_controller_name, $attributes);
$submitlink->_js = $js;
$submitlink->_onclick = "html_quickform_toggle_checkboxes($groupid); return false;";
- $mform->addElement($submitlink);
+ $mform->addElement($submitlink);
$mform->setDefault($checkbox_controller_name, $text);
}
}
function renderElement(&$element, $required, $error){
- //manipulate id of all elements before rendering
+ //manipulate id of all elements before rendering
if (!is_null($element->getAttribute('id'))) {
$id = $element->getAttribute('id');
} else {
}
//adding stuff to place holders in template
- //check if this is a group element first
+ //check if this is a group element first
if (($this->_inGroup) and !empty($this->_groupElementTemplate)) {
// so it gets substitutions for *each* element
$html = $this->_groupTemplates[$element->getName()];
}
elseif (!isset($this->_templates[$element->getName()])) {
$this->_templates[$element->getName()] = $html;
- }
-
+ }
+
parent::renderElement($element, $required, $error);
}
document.write("'.addslashes_js($button_js).'")
//]]>
</script><noscript><div style="display:inline">'.$button_nojs.'</div></noscript>'; // the extra div should fix xhtml validation
-
+
$header_html = str_replace('{button}', $button, $header_html);
} else {
$header_html = str_replace('{button}', '', $header_html);
* it and saves it in the right place to be a "user" or "group" image.
*
* @param int $id user or group id
- * @param object $uploadmanager object referencing the image
+ * @param object $userform with imagefile upload field
* @param string $dir type of entity - groups, user, ...
* @return boolean success
*/
-function save_profile_image($id, $uploadmanager, $dir='user') {
-
- if (!$uploadmanager) {
- return false;
- }
+function save_profile_image($id, $userform, $dir='user') {
$destination = create_profile_image_destination($id, $dir);
if ($destination === false) {
return false;
}
- if (!$uploadmanager->save_files($destination)) {
+ $filename = $userform->get_new_filename('imagefile');
+ $pathname = $destination.'/'.$filename;
+
+ if (!$userform->save_file('imagefile', $pathname, true)) {
return false;
}
- return process_profile_image($uploadmanager->get_new_filepath(), $destination);
+ return process_profile_image($pathname, $destination);
}
/**
/// FILE HANDLING /////////////////////////////////////////////
+/**
+ * Returns local file storage instance
+ * @return object file_storage
+ */
+function get_file_storage() {
+ global $CFG;
+
+ static $fs = null;
+
+ if ($fs) {
+ return $fs;
+ }
+
+ require_once("$CFG->libdir/filelib.php");
+
+ $fs = new file_storage();
+
+ return $fs;
+}
+
+/**
+ * Returns local file storage instance
+ * @return object file_storage
+ */
+function get_file_browser() {
+ global $CFG;
+
+ static $fb = null;
+
+ if ($fb) {
+ return $fb;
+ }
+
+ require_once("$CFG->libdir/filelib.php");
+
+ $fb = new file_browser();
+
+ return $fb;
+}
/**
* Makes an upload directory for a particular module.
$status = true;
- if(!is_dir($dir)) {
+ if (!is_dir($dir)) {
if (!$create) {
$status = false;
} else {
- umask(0000);
- if ($recursive) {
- /// PHP 5.0 has recursive mkdir parameter, but 4.x does not :-(
- $dir = str_replace('\\', '/', $dir); //windows compatibility
- /// We are going to make it recursive under $CFG->dataroot only
- /// (will help sites running open_basedir security and others)
- $dir = str_replace($CFG->dataroot . '/', '', $dir);
- $dirs = explode('/', $dir); /// Extract path parts
- /// Iterate over each part with start point $CFG->dataroot
- $dir = $CFG->dataroot . '/';
- foreach ($dirs as $part) {
- if ($part == '') {
- continue;
- }
- $dir .= $part.'/';
- if (!is_dir($dir)) {
- if (!mkdir($dir, $CFG->directorypermissions)) {
- $status = false;
- break;
- }
- }
- }
- } else {
- $status = mkdir($dir, $CFG->directorypermissions);
- }
+ $status = mkdir($dir, $CFG->directorypermissions, $recursive);
}
}
return $status;
private $lastcall;
private $time_start;
private $minimum_time = 2; //min time between updates.
- function __construct($html_id = 'pid', $width = 100, $autostart = false){
+ function __construct($html_id = 'pid', $width = 500, $autostart = false){
$this->html_id = $html_id;
$this->clr = new stdClass;
$this->clr->done = 'green';
$DB->set_debug(true);
upgrade_mod_savepoint($result, 2007101511, 'assignment');
}
-
+
+ if ($result && $oldversion < 2008073000) {
+
+ /////////////////////////////////////
+ /// new file storage upgrade code ///
+ /////////////////////////////////////
+
+ $fs = get_file_storage();
+
+ $sql = "SELECT s.id, s.userid, s.teacher, s.assignment, a.course
+ FROM {assignment_submissions} s
+ JOIN {assignment} a ON a.id = s.assignment
+ ORDER BY a.course, s.assignment";
+
+ $count = $DB->count_records_sql($sql);
+
+ $lastcourse = 0;
+ $lastassignment = 0;
+
+ if ($rs = $DB->get_recordset_sql($sql)) {
+
+ $pbar = new progress_bar('migrateassignmentfiles', 500, true);
+
+ $olddebug = $DB->get_debug();
+// $DB->set_debug(false); // lower debug level, there might be many files
+ $i = 0;
+ foreach ($rs as $submission) {
+ $i++;
+ $basepath = "$CFG->dataroot/$submission->course/$CFG->moddata/assignment/$submission->assignment/$submission->userid/";
+ if (!file_exists($basepath)) {
+ //no files
+ continue;
+ }
+ $context = get_context_instance(CONTEXT_MODULE, $submission->assignment);
+
+ // migrate submitted files fisrt
+ $path = $basepath;
+ $filearea = 'assignment_submission';
+ $items = new DirectoryIterator($path);
+ foreach ($items as $item) {
+ if (!$item->isFile()) {
+ continue;
+ }
+ if (!$item->isReadable()) {
+ notify(" File not readable, skipping: ".$path.$item->getFilename());
+ continue;
+ }
+ $filename = clean_param($item->getFilename(), PARAM_FILE);
+ if ($filename === '') {
+ continue;
+ }
+ if (!$fs->file_exists($context->id, $filearea, '0', '/', $filename)) {
+ $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$submission->userid, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$submission->userid);
+ if ($fs->create_file_from_pathname($file_record, $path.$item->getFilename())) {
+ unlink($path.$item->getFilename());
+ }
+ }
+ }
+ unset($items); //release file handles
+
+ // migrate teacher response files
+ $path = $basepath.'responses/';
+ if (file_exists($path)) {
+ $filearea = 'assignment_response';
+ $items = new DirectoryIterator($path);
+ foreach ($items as $item) {
+ if (!$item->isFile()) {
+ continue;
+ }
+ $filename = clean_param($item->getFilename(), PARAM_FILE);
+ if ($filename === '') {
+ continue;
+ }
+ if (!$fs->file_exists($context->id, $filearea, '0', '/', $filename)) {
+ $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$submission->userid, 'filepath'=>'/', 'filename'=>$filename,
+ 'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime());
+ if ($submission->teacher) {
+ $file_record['userid'] = $submission->teacher;
+ }
+ if ($fs->create_file_from_pathname($file_record, $path.$item->getFilename())) {
+ unlink($path.$item->getFilename());
+ }
+ }
+ }
+ unset($items); //release file handles
+ @rmdir("$CFG->dataroot/$submission->course/$CFG->moddata/assignment/$submission->assignment/$submission->userid/responses/");
+ }
+
+ @rmdir("$CFG->dataroot/$submission->course/$CFG->moddata/assignment/$submission->assignment/$submission->userid/");
+
+ if ($lastassignment and $lastassignment != $submission->assignment) {
+ @rmdir("$CFG->dataroot/$lastcourse/$CFG->moddata/assignment/$lastassignment");
+ }
+
+ if ($lastcourse and $lastcourse != $submission->course) {
+ @rmdir("$CFG->dataroot/$lastcourse/$CFG->moddata/assignment");
+ @rmdir("$CFG->dataroot/$lastcourse/$CFG->moddata");
+ @rmdir("$CFG->dataroot/$lastcourse");
+ }
+ $lastsubmission = $submission->assignment;
+ $lastcourse = $submission->course;
+
+ $pbar->update($i, $count, "Migrated assignment submissions - $i/$count.");
+ }
+ $DB->set_debug($olddebug); // reset debug level
+ $rs->close();
+
+ // cleanup after the last submission
+ if ($lastcourse) {
+ @rmdir("$CFG->dataroot/$lastcourse/$CFG->moddata/assignment/$lastassignment");
+ @rmdir("$CFG->dataroot/$lastcourse/$CFG->moddata/assignment");
+ @rmdir("$CFG->dataroot/$lastcourse/$CFG->moddata");
+ @rmdir("$CFG->dataroot/$lastcourse");
+ }
+ }
+
+ upgrade_mod_savepoint($result, 2008073000, 'assignment');
+ }
+
return $result;
}
*/
require_once($CFG->libdir.'/eventslib.php');
+require_once($CFG->libdir.'/formslib.php');
DEFINE ('ASSIGNMENT_COUNT_WORDS', 1);
DEFINE ('ASSIGNMENT_COUNT_LETTERS', 2);
}
}
+ function send_file($filearea, $args) {
+ debugging('plugin does not implement file sending', DEBUG_DEVELOPER);
+ return false;
+ }
+
/**
* Returns a list of teachers that should be grading given submission
*/
$userid = $USER->id;
}
- $filearea = $this->file_area_name($userid);
-
$output = '';
- if ($basedir = $this->file_area($userid)) {
- if ($files = get_directory_list($basedir)) {
- require_once($CFG->libdir.'/filelib.php');
- $p = array(
- 'userid' => $userid,
- 'assignmentid' => $this->cm->id,
- );
- foreach ($files as $key => $file) {
-
- $icon = mimeinfo('icon', $file);
- $ffurl = get_file_url("$filearea/$file", array('forcedownload'=>1));
-
- $output .= '<img src="'.$CFG->pixpath.'/f/'.$icon.'" class="icon" alt="'.$icon.'" />'.
- '<a href="'.$ffurl.'" >'.$file.'</a>';
- if ($this->portfolio_exportable() && true) { // @todo replace with capability check
- $p['file'] = $file;
- $output .= portfolio_add_button('assignment_portfolio_caller', $p, null, false, true);
- }
- $output .= '<br />';
- }
- if ($this->portfolio_exportable() && true) { //@todo replace with check capability
- unset($p['file']);// for all files
- $output .= '<br />' . portfolio_add_button('assignment_portfolio_caller', $p, null, true, true);
+ $fs = get_file_storage();
+ $browser = get_file_browser();
+
+ $found = false;
+
+ if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "timemodified", false)) {
+ $p = array(
+ 'userid' => $userid,
+ 'assignmentid' => $this->cm->id,
+ );
+ foreach ($files as $file) {
+ $filename = $file->get_filename();
+ $found = true;
+ $mimetype = $file->get_mimetype();
+ $icon = mimeinfo_from_type('icon', $mimetype);
+ $path = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename);
+ $output .= '<a href="'.$path.'" ><img src="'.$CFG->pixpath.'/f/'.$icon.'" class="icon" alt="'.$icon.'" />'.s($filename).'</a>';
+ if ($this->portfolio_exportable() && true) { // @todo replace with capability check
+ $p['file'] = $file;
+ $output .= portfolio_add_button('assignment_portfolio_caller', $p, null, false, true);
}
+ $output .= '<br />';
+ }
+ if ($this->portfolio_exportable() && true) { //@todo replace with check capability
+ unset($p['file']);// for all files
+ $output .= '<br />' . portfolio_add_button('assignment_portfolio_caller', $p, null, true, true);
}
}
* @return int
*/
function count_user_files($userid) {
- global $CFG;
-
- $filearea = $this->file_area_name($userid);
-
- if ( is_dir($CFG->dataroot.'/'.$filearea) && $basedir = $this->file_area($userid)) {
- if ($files = get_directory_list($basedir)) {
- return count($files);
- }
- }
- return 0;
- }
-
- /**
- * Creates a directory file name, suitable for make_upload_directory()
- *
- * @param $userid int The user id
- * @return string path to file area
- */
- function file_area_name($userid) {
- global $CFG;
-
- return $this->course->id.'/'.$CFG->moddata.'/assignment/'.$this->assignment->id.'/'.$userid;
- }
-
- /**
- * Makes an upload directory
- *
- * @param $userid int The user id
- * @return string path to file area.
- */
- function file_area($userid) {
- return make_upload_directory( $this->file_area_name($userid) );
+ $fs = get_file_storage();
+ $files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "id", false);
+ return count($files);
}
/**
*/
function user_complete($user) {
if ($submission = $this->get_submission($user->id)) {
- if ($basedir = $this->file_area($user->id)) {
- if ($files = get_directory_list($basedir)) {
- $countfiles = count($files)." ".get_string("uploadedfiles", "assignment");
- foreach ($files as $file) {
- $countfiles .= "; $file";
- }
+
+ $fs = get_file_storage();
+ $browser = get_file_browser();
+
+ if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $user->id, "timemodified", false)) {
+ $countfiles = count($files)." ".get_string("uploadedfiles", "assignment");
+ foreach ($files as $file) {
+ $countfiles .= "; ".$file->get_filename();
}
}
}
} ////// End of the assignment_base class
+class mod_assignment_upload_file_form extends moodleform {
+ function definition() {
+ $mform = $this->_form;
+ $instance = $this->_customdata;
+
+ //TODO: improve upload size checking
+ $mform->setMaxFileSize($instance->assignment->maxbytes);
+
+ // visible elements
+ $mform->addElement('file', 'newfile', get_string('uploadafile'));
+
+ // hidden params
+ $mform->addElement('hidden', 'id', $instance->cm->id);
+ $mform->setType('id', PARAM_INT);
+ $mform->addElement('hidden', 'action', 'uploadfile');
+ $mform->setType('action', PARAM_ALPHA);
+
+ // buttons
+ $this->add_action_buttons(false, get_string('uploadthisfile'));
+ }
+}
/// OTHER STANDARD FUNCTIONS ////////////////////////////////////////////////////////
return ($students);
}
+function assignment_pluginfile($course, $cminfo, $context, $filearea, $args) {
+ global $CFG, $DB;
+
+ if (!$assignment = $DB->get_record('assignment', array('id'=>$cminfo->instance))) {
+ return false;
+ }
+ if (!$cm = get_coursemodule_from_instance('assignment', $assignment->id, $course->id)) {
+ return false;
+ }
+
+ require_once($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php');
+ $assignmentclass = 'assignment_'.$assignment->assignmenttype;
+ $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course);
+
+ return $assignmentinstance->send_file($filearea, $args);
+}
/**
* Checks if a scale is being used by an assignment
*
if (is_callable(array($this->assignment, 'portfolio_prepare_package'))) {
return $this->assignment->portfolio_prepare_package($tempdir);
}
+error('TODO: covert');
// default...
$filearea = $CFG->dataroot . '/' . $this->assignment->file_area_name($this->userid);
//@todo penny this is a dreadful thing to have to call (replace with files api anyway)
if (is_callable(array($this->assignment, 'portfolio_get_sha1'))) {
return $this->assignment->portfolio_get_sha1();
}
+
+error('TODO: covert');
// default ...
$filearea = $CFG->dataroot . '/' . $this->assignment->file_area_name($this->userid);
if ($this->file) {
<?php // $Id$
-require_once($CFG->libdir.'/formslib.php');
require_once($CFG->libdir . '/portfoliolib.php');
require_once($CFG->dirroot . '/mod/assignment/lib.php');
$submission = $this->get_submission($USER->id);
- $struploadafile = get_string('uploadafile');
- $maxbytes = $this->assignment->maxbytes == 0 ? $this->course->maxbytes : $this->assignment->maxbytes;
- $strmaxsize = get_string('maxsize', '', display_size($maxbytes));
-
if ($this->is_finalized($submission)) {
// no uploading
return;
}
if ($this->can_upload_file($submission)) {
- echo '<div style="text-align:center">';
- echo '<form enctype="multipart/form-data" method="post" action="upload.php">';
- echo '<fieldset class="invisiblefieldset">';
- echo "<p>$struploadafile ($strmaxsize)</p>";
- echo '<input type="hidden" name="id" value="'.$this->cm->id.'" />';
- echo '<input type="hidden" name="action" value="uploadfile" />';
- require_once($CFG->libdir.'/uploadlib.php');
- upload_print_form_fragment(1,array('newfile'),null,false,null,0,$this->assignment->maxbytes,false);
- echo '<input type="submit" name="save" value="'.get_string('uploadthisfile').'" />';
- echo '</fieldset>';
- echo '</form>';
- echo '</div>';
- echo '<br />';
+ $mform = new mod_assignment_upload_file_form('upload.php', $this);
+ $mform->display();
}
}
$offset = optional_param('offset', 0, PARAM_INT);
$forcerefresh = optional_param('forcerefresh', 0, PARAM_BOOL);
+ $mform = new mod_assignment_upload_response_form("$CFG->wwwroot/mod/assignment/upload.php", $this);
+
+ $mform->set_data(array('id'=>$this->cm->id, 'offset'=>$offset, 'forcerefresh'=>$forcerefresh, 'userid'=>$submission->userid, 'mode'=>$mode));
+
$output = get_string('responsefiles', 'assignment').': ';
- $output .= '<form enctype="multipart/form-data" method="post" '.
- "action=\"$CFG->wwwroot/mod/assignment/upload.php\">";
- $output .= '<div>';
- $output .= '<input type="hidden" name="id" value="'.$this->cm->id.'" />';
- $output .= '<input type="hidden" name="action" value="uploadresponse" />';
- $output .= '<input type="hidden" name="mode" value="'.$mode.'" />';
- $output .= '<input type="hidden" name="offset" value="'.$offset.'" />';
- $output .= '<input type="hidden" name="userid" value="'.$submission->userid.'" />';
- require_once($CFG->libdir.'/uploadlib.php');
- $output .= upload_print_form_fragment(1,array('newfile'),null,false,null,0,0,true);
- $output .= '<input type="submit" name="save" value="'.get_string('uploadthisfile').'" />';
- $output .= '</div>';
- $output .= '</form>';
+ ob_start();
+ $mform->display();
+ $output = ob_get_clean();
if ($forcerefresh) {
$output .= $this->update_main_listing($submission);
function print_student_answer($userid, $return=false){
global $CFG;
- $filearea = $this->file_area_name($userid);
$submission = $this->get_submission($userid);
$output = '';
- if ($basedir = $this->file_area($userid)) {
- if ($this->drafts_tracked() and $this->isopen() and !$this->is_finalized($submission)) {
- $output .= '<strong>'.get_string('draft', 'assignment').':</strong> ';
- }
+ if ($this->drafts_tracked() and $this->isopen() and !$this->is_finalized($submission)) {
+ $output .= '<strong>'.get_string('draft', 'assignment').':</strong> ';
+ }
- if ($this->notes_allowed() and !empty($submission->data1)) {
- $output .= link_to_popup_window ('/mod/assignment/type/upload/notes.php?id='.$this->cm->id.'&userid='.$userid,
- 'notes'.$userid, get_string('notes', 'assignment'), 500, 780, get_string('notes', 'assignment'), 'none', true, 'notesbutton'.$userid);
- $output .= ' ';
- }
+ if ($this->notes_allowed() and !empty($submission->data1)) {
+ $output .= link_to_popup_window ('/mod/assignment/type/upload/notes.php?id='.$this->cm->id.'&userid='.$userid,
+ 'notes'.$userid, get_string('notes', 'assignment'), 500, 780, get_string('notes', 'assignment'), 'none', true, 'notesbutton'.$userid);
+ $output .= ' ';
+ }
- if ($files = get_directory_list($basedir, 'responses')) {
- require_once($CFG->libdir.'/filelib.php');
- foreach ($files as $key => $file) {
- $icon = mimeinfo('icon', $file);
- $ffurl = get_file_url("$filearea/$file");
- $output .= '<a href="'.$ffurl.'" ><img class="icon" src="'.$CFG->pixpath.'/f/'.$icon.'" alt="'.$icon.'" />'.$file.'</a> ';
- }
+ $fs = get_file_storage();
+ $browser = get_file_browser();
+
+ if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "timemodified", false)) {
+
+ foreach ($files as $file) {
+ $filename = $file->get_filename();
+ $found = true;
+ $mimetype = $file->get_mimetype();
+ $icon = mimeinfo_from_type('icon', $mimetype);
+ $path = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename);
+ $output .= '<a href="'.$path.'" ><img class="icon" src="'.$CFG->pixpath.'/f/'.$icon.'" alt="'.$icon.'" />'.s($filename).'</a> ';
+
}
+
}
$output = '<div class="files">'.$output.'</div>';
$output .= '<br />';
$userid = $USER->id;
}
- $filearea = $this->file_area_name($userid);
-
$output = '';
$submission = $this->get_submission($userid);
}
- if ($basedir = $this->file_area($userid)) {
- if ($files = get_directory_list($basedir, 'responses')) {
- require_once($CFG->libdir.'/filelib.php');
- $p = array(
- 'userid' => $userid,
- 'assignmentid' => $this->cm->id,
- );
- foreach ($files as $key => $file) {
-
- $icon = mimeinfo('icon', $file);
- $ffurl = get_file_url("$filearea/$file");
-
- $output .= '<a href="'.$ffurl.'" ><img src="'.$CFG->pixpath.'/f/'.$icon.'" class="icon" alt="'.$icon.'" />'.$file.'</a>';
-
- if ($candelete) {
- $delurl = "$CFG->wwwroot/mod/assignment/delete.php?id={$this->cm->id}&file=$file&userid={$submission->userid}&mode=$mode&offset=$offset";
-
- $output .= '<a href="'.$delurl.'"> '
- .'<img title="'.$strdelete.'" src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="" /></a> ';
- }
- if (true) { // @todo penny replace with capability check
- $p['file'] = $file;
- $output .= portfolio_add_button('assignment_portfolio_caller', $p, '/mod/assignment/lib.php', false, true);
- }
- $output .= '<br />';
+ $fs = get_file_storage();
+ $browser = get_file_browser();
+
+ if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "timemodified", false)) {
+ $p = array(
+ 'userid' => $userid,
+ 'assignmentid' => $this->cm->id,
+ );
+ foreach ($files as $file) {
+ $filename = $file->get_filename();
+ $mimetype = $file->get_mimetype();
+ $icon = mimeinfo_from_type('icon', $mimetype);
+ $path = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename);
+ $output .= '<a href="'.$path.'" ><img src="'.$CFG->pixpath.'/f/'.$icon.'" class="icon" alt="'.$icon.'" />'.s($filename).'</a>';
+
+ if ($candelete) {
+ $delurl = "$CFG->wwwroot/mod/assignment/delete.php?id={$this->cm->id}&file=".rawurlencode($filename)."&userid={$submission->userid}&mode=$mode&offset=$offset";
+
+ $output .= '<a href="'.$delurl.'"> '
+ .'<img title="'.$strdelete.'" src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="" /></a> ';
}
- if (true) { //@todo penny replace with check capability
- unset($p['file']);// for all files
- $output .= '<br />' . portfolio_add_button('assignment_portfolio_caller', $p, '/mod/assignment/lib.php', true, true);
+
+ if (true) { // @todo penny replace with capability check
+ $p['file'] = $filename;
+ $output .= portfolio_add_button('assignment_portfolio_caller', $p, '/mod/assignment/lib.php', false, true);
}
+ $output .= '<br />';
+ }
+ if (true) { //@todo penny replace with check capability
+ unset($p['file']);// for all files
+ $output .= '<br />' . portfolio_add_button('assignment_portfolio_caller', $p, '/mod/assignment/lib.php', true, true);
}
}
$mode = optional_param('mode', '', PARAM_ALPHA);
$offset = optional_param('offset', 0, PARAM_INT);
- $filearea = $this->file_area_name($userid).'/responses';
-
$output = '';
$candelete = $this->can_manage_responsefiles();
$strdelete = get_string('delete');
- if ($basedir = $this->file_area($userid)) {
- $basedir .= '/responses';
+ $fs = get_file_storage();
+ $browser = get_file_browser();
- if ($files = get_directory_list($basedir)) {
- require_once($CFG->libdir.'/filelib.php');
- foreach ($files as $key => $file) {
+ if ($files = $fs->get_area_files($this->context->id, 'assignment_response', $userid, "timemodified", false)) {
+ foreach ($files as $file) {
+ $filename = $file->get_filename();
+ $found = true;
+ $mimetype = $file->get_mimetype();
+ $icon = mimeinfo_from_type('icon', $mimetype);
+ $path = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_response/'.$userid.'/'.$filename);
- $icon = mimeinfo('icon', $file);
+ $output .= '<a href="'.$path.'" ><img src="'.$CFG->pixpath.'/f/'.$icon.'" alt="'.$icon.'" />'.$filename.'</a>';
- $ffurl = get_file_url("$filearea/$file");
+ if ($candelete) {
+ $delurl = "$CFG->wwwroot/mod/assignment/delete.php?id={$this->cm->id}&file=".rawurlencode($filename)."&userid=$userid&mode=$mode&offset=$offset&action=response";
- $output .= '<a href="'.$ffurl.'" ><img src="'.$CFG->pixpath.'/f/'.$icon.'" alt="'.$icon.'" />'.$file.'</a>';
-
- if ($candelete) {
- $delurl = "$CFG->wwwroot/mod/assignment/delete.php?id={$this->cm->id}&file=$file&userid=$userid&mode=$mode&offset=$offset&action=response";
-
- $output .= '<a href="'.$delurl.'"> '
- .'<img title="'.$strdelete.'" src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt=""/></a> ';
- }
-
- $output .= ' ';
+ $output .= '<a href="'.$delurl.'"> '
+ .'<img title="'.$strdelete.'" src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt=""/></a> ';
}
- }
+ $output .= ' ';
+ }
$output = '<div class="responsefiles">'.$output.'</div>';
-
}
if ($return) {
}
function upload_responsefile() {
- global $CFG;
+ global $CFG, $USER;
$userid = required_param('userid', PARAM_INT);
$mode = required_param('mode', PARAM_ALPHA);
$returnurl = "submissions.php?id={$this->cm->id}&userid=$userid&mode=$mode&offset=$offset";
- if (data_submitted() and $this->can_manage_responsefiles()) {
- $dir = $this->file_area_name($userid).'/responses';
- check_dir_exists($CFG->dataroot.'/'.$dir, true, true);
-
- require_once($CFG->dirroot.'/lib/uploadlib.php');
- $um = new upload_manager('newfile',false,true,$this->course,false,0,true);
-
- if (!$um->process_file_uploads($dir)) {
- print_header(get_string('upload'));
- notify(get_string('uploaderror', 'assignment'));
- echo $um->get_errors();
- print_continue($returnurl);
- print_footer('none');
- die;
+ $mform = new mod_assignment_upload_response_form(null, $this);
+ if ($mform->get_data() and $this->can_manage_responsefiles()) {
+ $fs = get_file_storage();
+ $filename = $mform->get_new_filename('newfile');
+ if ($filename !== false) {
+ if (!$fs->file_exists($this->context->id, 'assignment_response', $userid, '/', $filename)) {
+ if ($file = $mform->save_stored_file('newfile', $this->context->id, 'assignment_response', $userid, '/', $filename, false, $USER->id)) {
+ redirect($returnurl);
+ }
+ }
}
}
- redirect($returnurl);
+ print_header(get_string('upload'));
+ notify(get_string('uploaderror', 'assignment'));
+ print_continue($returnurl);
+ print_footer('none');
+ die;
}
function upload_file() {
global $CFG, $USER, $DB;
- $mode = optional_param('mode', '', PARAM_ALPHA);
- $offset = optional_param('offset', 0, PARAM_INT);
-
$returnurl = 'view.php?id='.$this->cm->id;
$filecount = $this->count_user_files($USER->id);
die;
}
- $dir = $this->file_area_name($USER->id);
- check_dir_exists($CFG->dataroot.'/'.$dir, true, true); // better to create now so that student submissions do not block it later
-
- require_once($CFG->dirroot.'/lib/uploadlib.php');
- $um = new upload_manager('newfile',false,true,$this->course,false,$this->assignment->maxbytes,true);
-
- if ($um->process_file_uploads($dir)) {
- $submission = $this->get_submission($USER->id, true); //create new submission if needed
- $updated = new object();
- $updated->id = $submission->id;
- $updated->timemodified = time();
-
- if ($DB->update_record('assignment_submissions', $updated)) {
- add_to_log($this->course->id, 'assignment', 'upload',
- 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
- $submission = $this->get_submission($USER->id);
- $this->update_grade($submission);
- if (!$this->drafts_tracked()) {
- $this->email_teachers($submission);
+ $mform = new mod_assignment_upload_file_form('upload.php', $this);
+ if ($mform->get_data()) {
+ $fs = get_file_storage();
+ $filename = $mform->get_new_filename('newfile');
+ if ($filename !== false) {
+ if (!$fs->file_exists($this->context->id, 'assignment_submission', $USER->id, '/', $filename)) {
+ if ($file = $mform->save_stored_file('newfile', $this->context->id, 'assignment_submission', $USER->id, '/', $filename, false, $USER->id)) {
+ $submission = $this->get_submission($USER->id, true); //create new submission if needed
+ $submission->timemodified = time();
+ if ($DB->update_record('assignment_submissions', $submission)) {
+ add_to_log($this->course->id, 'assignment', 'upload',
+ 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
+ $this->update_grade($submission);
+ if (!$this->drafts_tracked()) {
+ $this->email_teachers($submission);
+ }
+ redirect('view.php?id='.$this->cm->id);
+ } else {
+ $file->delete();
+ }
+ }
}
- } else {
- $new_filename = $um->get_new_filename();
- $this->view_header(get_string('upload'));
- notify(get_string('uploadnotregistered', 'assignment', $new_filename));
- print_continue($returnurl);
- $this->view_footer();
- die;
}
- redirect('view.php?id='.$this->cm->id);
}
+
$this->view_header(get_string('upload'));
notify(get_string('uploaderror', 'assignment'));
- echo $um->get_errors();
print_continue($returnurl);
$this->view_footer();
die;
}
+ function send_file($filearea, $args) {
+ global $CFG, $DB, $USER;
+ require_once($CFG->libdir.'/filelib.php');
+
+ require_login($this->course, false, $this->cm);
+
+ $userid = (int)array_shift($args);
+ $relativepath = '/'.implode('/', $args);
+ $fullpath = $this->context->id.$filearea.$userid.$relativepath;
+
+ $fs = get_file_storage();
+
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+ return false;
+ }
+
+ if ($filearea === 'assignment_submission') {
+ if ($USER->id != $userid and !has_capability('mod/assignment:grade', $this->context)) {
+ return false;
+ }
+
+ } else if ($filearea === 'assignment_response') {
+ if ($USER->id != $userid and !has_capability('mod/assignment:grade', $this->context)) {
+ return false;
+ }
+
+ } else {
+ return false;
+ }
+
+ send_stored_file($file, 0, 0, true); // downlaod MUST be forced - security!
+ }
+
function finalize() {
global $USER, $DB;
die;
}
- $dir = $this->file_area_name($userid).'/responses';
- $filepath = $CFG->dataroot.'/'.$dir.'/'.$file;
- if (file_exists($filepath)) {
- if (@unlink($filepath)) {
+ $fs = get_file_storage();
+ if ($file = $fs->get_file($this->context->id, 'assignment_submission', $userid, '/', $file)) {
+ if ($file->delete()) {
redirect($returnurl);
}
}
$this->view_footer();
die;
}
- $dir = $this->file_area_name($userid);
if (!data_submitted() or !$confirm) {
$optionsyes = array ('id'=>$this->cm->id, 'file'=>$file, 'userid'=>$userid, 'confirm'=>1, 'sesskey'=>sesskey(), 'mode'=>$mode, 'offset'=>$offset);
die;
}
- $filepath = $CFG->dataroot.'/'.$dir.'/'.$file;
- if (file_exists($filepath)) {
- if (@unlink($filepath)) {
- $updated = new object();
- $updated->id = $submission->id;
- $updated->timemodified = time();
- if ($DB->update_record('assignment_submissions', $updated)) {
+ $fs = get_file_storage();
+ if ($file = $fs->get_file($this->context->id, 'assignment_submission', $userid, '/', $file)) {
+ if ($file->delete()) {
+ $submission->timemodified = time();
+ if ($DB->update_record('assignment_submissions', $submission)) {
add_to_log($this->course->id, 'assignment', 'upload', //TODO: add delete action to log
'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
- $submission = $this->get_submission($userid);
$this->update_grade($submission);
}
redirect($returnurl);
return (boolean)$this->assignment->var2;
}
- /**
- * Count the files uploaded by a given user
- *
- * @param $userid int The user id
- * @return int
- */
- function count_user_files($userid) {
- global $CFG;
-
- $filearea = $this->file_area_name($userid);
-
- if ( is_dir($CFG->dataroot.'/'.$filearea) && $basedir = $this->file_area($userid)) {
- if ($files = get_directory_list($basedir, 'responses')) {
- return count($files);
- }
- }
- return 0;
- }
-
function count_responsefiles($userid) {
- global $CFG;
-
- $filearea = $this->file_area_name($userid).'/responses';
-
- if ( is_dir($CFG->dataroot.'/'.$filearea) && $basedir = $this->file_area($userid)) {
- $basedir .= '/responses';
- if ($files = get_directory_list($basedir)) {
- return count($files);
- }
- }
- return 0;
+ $fs = get_file_storage();
+ $files = $fs->get_area_files($this->context->id, 'assignment_response', $userid, "id", false);
+ return count($files);
}
function setup_elements(&$mform) {
class mod_assignment_upload_notes_form extends moodleform {
function definition() {
- $mform =& $this->_form;
+ $mform = $this->_form;
// visible elements
$mform->addElement('htmleditor', 'text', get_string('notes', 'assignment'), array('cols'=>85, 'rows'=>30));
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'action', 'savenotes');
- $mform->setType('id', PARAM_ALPHA);
+ $mform->setType('action', PARAM_ALPHA);
// buttons
$this->add_action_buttons();
}
}
+class mod_assignment_upload_response_form extends moodleform {
+ function definition() {
+ $mform = $this->_form;
+ $instance = $this->_customdata;
+
+ // visible elements
+ $mform->addElement('file', 'newfile', get_string('uploadafile'));
+
+ // hidden params
+ $mform->addElement('hidden', 'id', $instance->cm->id);
+ $mform->setType('id', PARAM_INT);
+ $mform->addElement('hidden', 'action', 'uploadresponse');
+ $mform->setType('action', PARAM_ALPHA);
+ $mform->addElement('hidden', 'mode');
+ $mform->setType('mode', PARAM_ALPHA);
+ $mform->addElement('hidden', 'offset');
+ $mform->setType('offset', PARAM_INT);
+ $mform->addElement('hidden', 'forcerefresh');
+ $mform->setType('forcerefresh', PARAM_INT);
+ $mform->addElement('hidden', 'userid');
+ $mform->setType('userid', PARAM_INT);
+
+ // buttons
+ $this->add_action_buttons(false, get_string('uploadthisfile'));
+ }
+}
+
?>
function print_student_answer($userid, $return=false){
- global $CFG, $USER;
+ global $CFG, $USER;
- $filearea = $this->file_area_name($userid);
+ $fs = get_file_storage();
+ $browser = get_file_browser();
- $output = '';
+ if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "timemodified", false)) {
- if ($basedir = $this->file_area($userid)) {
- if ($files = get_directory_list($basedir)) {
- require_once($CFG->libdir.'/filelib.php');
- foreach ($files as $key => $file) {
-
- $icon = mimeinfo('icon', $file);
- $ffurl = get_file_url("$filearea/$file");
-
- //died right here
- //require_once($ffurl);
- $output = '<img src="'.$CFG->pixpath.'/f/'.$icon.'" class="icon" alt="'.$icon.'" />'.
- '<a href="'.$ffurl.'" >'.$file.'</a><br />';
- }
+ foreach ($files as $file) {
+ $filename = $file->get_filename();
+ $found = true;
+ $mimetype = $file->get_mimetype();
+ $icon = mimeinfo_from_type('icon', $mimetype);
+ $path = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename);
+ $output .= '<a href="'.$path.'" ><img class="icon" src="'.$CFG->pixpath.'/f/'.$icon.'" alt="'.$icon.'" />'.s($filename).'</a><br />';
}
}
function view_upload_form() {
- global $CFG;
- $struploadafile = get_string("uploadafile");
-
- $maxbytes = $this->assignment->maxbytes == 0 ? $this->course->maxbytes : $this->assignment->maxbytes;
- $strmaxsize = get_string('maxsize', '', display_size($maxbytes));
-
- echo '<div style="text-align:center">';
- echo '<form enctype="multipart/form-data" method="post" '.
- "action=\"$CFG->wwwroot/mod/assignment/upload.php\">";
- echo '<fieldset class="invisiblefieldset">';
- echo "<p>$struploadafile ($strmaxsize)</p>";
- echo '<input type="hidden" name="id" value="'.$this->cm->id.'" />';
- require_once($CFG->libdir.'/uploadlib.php');
- upload_print_form_fragment(1,array('newfile'),false,null,0,$this->assignment->maxbytes,false);
- echo '<input type="submit" name="save" value="'.get_string('uploadthisfile').'" />';
- echo '</fieldset>';
- echo '</form>';
- echo '</div>';
+ $mform = new mod_assignment_upload_file_form('upload.php', $this);
+ $mform->display();
}
}
}
- $dir = $this->file_area_name($USER->id);
-
- require_once($CFG->dirroot.'/lib/uploadlib.php');
- $um = new upload_manager('newfile',true,false,$this->course,false,$this->assignment->maxbytes);
- if ($um->process_file_uploads($dir)) {
- $newfile_name = $um->get_new_filename();
- if ($submission) {
- $submission->timemodified = time();
- $submission->numfiles = 1;
- $submission->submissioncomment = $submission->submissioncomment;
- unset($submission->data1); // Don't need to update this.
- unset($submission->data2); // Don't need to update this.
- if ($DB->update_record("assignment_submissions", $submission)) {
- add_to_log($this->course->id, 'assignment', 'upload',
- 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
- $submission = $this->get_submission($USER->id);
- $this->update_grade($submission);
- $this->email_teachers($submission);
- print_heading(get_string('uploadedfile'));
- } else {
- notify(get_string("uploadfailnoupdate", "assignment"));
- }
- } else {
- $newsubmission = $this->prepare_new_submission($USER->id);
- $newsubmission->timemodified = time();
- $newsubmission->numfiles = 1;
- if ($DB->insert_record('assignment_submissions', $newsubmission)) {
- add_to_log($this->course->id, 'assignment', 'upload',
- 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
- $submission = $this->get_submission($USER->id);
- $this->update_grade($submission);
- $this->email_teachers($newsubmission);
- print_heading(get_string('uploadedfile'));
- } else {
- notify(get_string("uploadnotregistered", "assignment", $newfile_name) );
+ $mform = new mod_assignment_upload_file_form('upload.php', $this);
+ if ($mform->get_data()) {
+ $fs = get_file_storage();
+ $filename = $mform->get_new_filename('newfile');
+ if ($filename !== false) {
+ $fs->delete_area_files($this->context->id, 'assignment_submission', $USER->id);
+ if ($file = $mform->save_stored_file('newfile', $this->context->id, 'assignment_submission', $USER->id, '/', $filename, false, $USER->id)) {
+ $submission = $this->get_submission($USER->id, true); //create new submission if needed
+ $submission->timemodified = time();
+ $submission->numfiles = 1;
+ if ($DB->update_record('assignment_submissions', $submission)) {
+ add_to_log($this->course->id, 'assignment', 'upload',
+ 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id);
+ $this->update_grade($submission);
+ $this->email_teachers($submission);
+ print_heading(get_string('uploadedfile'));
+ redirect('view.php?id='.$this->cm->id);
+ } else {
+ notify(get_string("uploadnotregistered", "assignment", $newfile_name) );
+ $file->delete();
+ }
}
}
+ } else {
+ notify(get_string("uploaderror", "assignment")); //submitting not allowed!
}
- } else {
- notify(get_string("uploaderror", "assignment")); //submitting not allowed!
}
print_continue('view.php?id='.$this->cm->id);
return true;
}
+ function send_file($filearea, $args) {
+ global $CFG, $DB, $USER;
+ require_once($CFG->libdir.'/filelib.php');
+
+ require_login($this->course, false, $this->cm);
+
+ $userid = (int)array_shift($args);
+ $relativepath = '/'.implode('/', $args);
+ $fullpath = $this->context->id.$filearea.$userid.$relativepath;
+
+ $fs = get_file_storage();
+
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+ return false;
+ }
+
+ if ($filearea === 'assignment_submission') {
+ if ($USER->id != $userid and !has_capability('mod/assignment:grade', $this->context)) {
+ return false;
+ }
+
+ } else {
+ return false;
+ }
+
+ send_stored_file($file, 0, 0, true); // downlaod MUST be forced - security!
+ }
+
}
?>
require_login($course->id, false, $cm);
/// Load up the required assignment code
- require($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php');
+ require_once($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php');
$assignmentclass = 'assignment_'.$assignment->assignmenttype;
$assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course);
// This fragment is called by /admin/index.php
////////////////////////////////////////////////////////////////////////////////
-$module->version = 2008072401;
+$module->version = 2008073000;
$module->requires = 2008072401; // Requires this Moodle version
$module->cron = 60;
--- /dev/null
+<?php // $Id$
+
+ require_once('config.php');
+ require_once('lib/filelib.php');
+
+ // disable moodle specific debug messages
+ disable_debugging();
+
+ $relativepath = get_file_argument('file.php');
+ $forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);
+
+ // relative path must start with '/'
+ if (!$relativepath) {
+ print_error('invalidargorconf');
+ } else if ($relativepath{0} != '/') {
+ print_error('pathdoesnotstartslash');
+ }
+
+ // extract relative path components
+ $args = explode('/', ltrim($relativepath, '/'));
+
+ if (count($args) == 0) { // always at least user id
+ print_error('invalidarguments');
+ }
+
+ $contextid = (int)array_shift($args);
+ $filearea = array_shift($args);
+
+ $context = get_context_instance_by_id($contextid);
+ $fs = get_file_storage();
+
+
+ if ($context->contextlevel == CONTEXT_SYSTEM) {
+ if ($filearea === 'blog') {
+
+ if (empty($CFG->bloglevel)) {
+ print_error('siteblogdisable', 'blog');
+ }
+ if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) {
+ require_login();
+ if (isguestuser()) {
+ print_error('noguest');
+ }
+ if ($CFG->bloglevel == BLOG_USER_LEVEL) {
+ if ($USER->id != $entry->userid) {
+ not_found();
+ }
+ }
+ }
+ $entryid = (int)array_shift($args);
+ if (!$entry = $DB->get_record('post', array('module'=>'blog', 'id'=>$entryid))) {
+ not_found();
+ }
+ if ('publishstate' === 'public') {
+ if ($CFG->forcelogin) {
+ require_login();
+ }
+
+ } else if ('publishstate' === 'site') {
+ require_login();
+ //ok
+ } else if ('publishstate' === 'draft') {
+ require_login();
+ if ($USER->id != $entry->userid) {
+ not_found();
+ }
+ }
+
+ //TODO: implement shared course and shared group access
+
+ $relativepath = '/'.implode('/', $args);
+ $fullpath = $context->id.'blog'.$entryid.$relativepath;
+
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+ not_found();
+ }
+
+ send_stored_file($file, 10*60, 0, true); // downlaod MUST be forced - security!
+
+ } else {
+ not_found();
+ }
+
+
+ } else if ($context->contextlevel == CONTEXT_USER) {
+ not_found();
+
+
+ } else if ($context->contextlevel == CONTEXT_COURSECAT) {
+ if ($filearea !== 'intro') {
+ not_found();
+ }
+
+ if ($CFG->forcelogin) {
+ // no login necessary - unless login forced everywhere
+ require_login();
+ }
+
+ $relativepath = '/'.implode('/', $args);
+ $fullpath = $context->id.'intro0'.$relativepath;
+
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->get_filename() == '.') {
+ not_found();
+ }
+
+ session_write_close(); // unlock session during fileserving
+ send_stored_file($file, 60*60, 0, $forcedownload);
+
+
+ } else if ($context->contextlevel == CONTEXT_COURSE) {
+ if ($filearea !== 'intro' and $filearea !== 'backup') {
+ not_found();
+ }
+
+ if (!$course = $DB->get_record('course', array('id'=>$context->instanceid))) {
+ print_error('invalidcourseid');
+ }
+
+ if ($filearea === 'backup') {
+ require_login($course);
+ require_capability('moodle/site:backupdownload', $context);
+ } else {
+ if ($CFG->forcelogin) {
+ require_login();
+ }
+ }
+
+ $relativepath = '/'.implode('/', $args);
+ $fullpath = $context->id.'intro0'.$relativepath;
+
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+ not_found();
+ }
+
+ session_write_close(); // unlock session during fileserving
+ send_stored_file($file, 60*60, 0, $forcedownload);
+
+
+ } else if ($context->contextlevel == CONTEXT_MODULE) {
+
+ if (!$coursecontext = get_context_instance_by_id(get_parent_contextid($context))) {
+ not_found();
+ }
+
+ if (!$course = $DB->get_record('course', array('id'=>$coursecontext->instanceid))) {
+ not_found();
+ }
+ $modinfo = get_fast_modinfo($course);
+ if (empty($modinfo->cms[$context->instanceid])) {
+ not_found();
+ }
+
+ $cminfo = $modinfo->cms[$context->instanceid];
+ $modname = $cminfo->modname;
+ $libfile = "$CFG->dirroot/mod/$modname/lib.php";
+ if (file_exists($libfile)) {
+ require_once($libfile);
+ $filefunction = $modname.'_pluginfile';
+ if (function_exists($filefunction)) {
+ if ($filefunction($course, $cminfo, $context, $filearea, $args) !== false) {
+ die;
+ }
+ }
+ }
+ not_found();
+
+ } else if ($context->contextlevel == CONTEXT_BLOCK) {
+ //not supported yet
+ not_found();
+
+
+ } else {
+ not_found();
+ }
+
+
+ function not_found() {
+ global $CFG;
+ header('HTTP/1.0 404 not found');
+ print_error('filenotfound', 'error', $CFG->wwwroot.'/'); //this is not displayed on IIS??
+ }
global $CFG, $COURSE;
$mform =& $this->_form;
- $this->set_upload_manager(new upload_manager('imagefile', false, false, null, false, 0, true, true, false));
//Accessibility: "Required" is bad legend text.
$strgeneral = get_string('general');
$strrequired = get_string('required');
global $USER, $CFG, $COURSE;
$mform =& $this->_form;
- $this->set_upload_manager(new upload_manager('imagefile', false, false, null, false, 0, true, true, false));
//Accessibility: "Required" is bad legend text.
$strgeneral = get_string('general');
$strrequired = get_string('required');
}
}
-function useredit_update_picture(&$usernew, &$userform) {
+function useredit_update_picture(&$usernew, $userform) {
global $CFG, $DB;
if (isset($usernew->deletepicture) and $usernew->deletepicture) {
$location = make_user_directory($usernew->id, true);
@remove_dir($location);
$DB->set_field('user', 'picture', 0, array('id'=>$usernew->id));
- } else if ($usernew->picture = save_profile_image($usernew->id, $userform->get_um(), 'user')) {
- $DB->set_field('user', 'picture', 1, array('id'=>$usernew->id));
+
+ } else if ($userform->get_new_filename('imagefile')) {
+ $usernew->picture = (int)save_profile_image($usernew->id, $userform, 'user', 'imagefile');
+ $DB->set_field('user', 'picture', $usernew->picture, array('id'=>$usernew->id));
}
}
--- /dev/null
+<?php // $Id$
+
+ require_once('config.php');
+ require_once('lib/filelib.php');
+
+ require_login();
+ if (isguestuser()) {
+ print_error('noguest');
+ }
+
+ // disable moodle specific debug messages
+ disable_debugging();
+
+ $relativepath = get_file_argument('file.php');
+ $forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);
+
+ // relative path must start with '/'
+ if (!$relativepath) {
+ print_error('invalidargorconf');
+ } else if ($relativepath{0} != '/') {
+ print_error('pathdoesnotstartslash');
+ }
+
+ // extract relative path components
+ $args = explode('/', ltrim($relativepath, '/'));
+
+ if (count($args) == 0) { // always at least user id
+ print_error('invalidarguments');
+ }
+
+ $contextid = (int)array_shift($args);
+ $filearea = array_shift($args);
+
+ $context = get_context_instance_by_id($contextid);
+ if ($context->contextlevel != CONTEXT_USER) {
+ print_error('invalidarguments');
+ }
+
+ $userid = $context->instanceid;
+ if ($USER->id != $userid) {
+ print_error('invaliduserid');
+ }
+
+ switch ($filearea) {
+ case 'private': $itemid = 0; $forcedownload = true; break;
+ case 'draft' : $itemid = (int)array_shift($args); break;
+ default: not_found();
+ }
+
+ $relativepath = '/'.implode('/', $args);
+
+
+ $fs = get_file_storage();
+
+ $fullpath = $context->id.$filearea.$itemid.$relativepath;
+
+ if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->get_filename() == '.') {
+ not_found();
+ }
+
+ // ========================================
+ // finally send the file
+ // ========================================
+ session_write_close(); // unlock session during fileserving
+ send_stored_file($file, 0, false, $forcedownload);
+
+ function not_found() {
+ global $CFG;
+ header('HTTP/1.0 404 not found');
+ print_error('filenotfound', 'error', $CFG->wwwroot.'/'); //this is not displayed on IIS??
+ }
// This is compared against the values stored in the database to determine
// whether upgrades should be performed (see lib/db/*.php)
- $version = 2008073104; // YYYYMMDD = date of the last version bump
+ $version = 2008073114; // YYYYMMDD = date of the last version bump
// XX = daily increments
$release = '2.0 dev (Build: 20080731)'; // Human-friendly version name