Index: files/files_ajax.php ========================================================= --- files/files_ajax.php (revision 1.7) +++ files/files_ajax.php Thu May 27 14:16:46 WST 2010 @@ -90,6 +90,15 @@ } break; +case 'setmainfile': + $filepath = file_correct_filepath($filepath); + // reset sort order + file_reset_sortorder($user_context->id, $filearea, $itemid); + // set main file + $return = file_set_sortorder($user_context->id, $filearea, $itemid, $filepath, $filename, 1); + echo json_encode($return); + break; + case 'renamedir': $fs = get_file_storage(); $fb = get_file_browser(); Index: lib/db/install.xml ========================================================= --- lib/db/install.xml (revision 1.254) +++ lib/db/install.xml Fri May 28 14:22:50 WST 2010 @@ -2249,7 +2249,8 @@ - + + Index: lib/db/upgrade.php ========================================================= --- lib/db/upgrade.php (revision 1.421) +++ lib/db/upgrade.php Fri May 28 14:25:50 WST 2010 @@ -4156,7 +4156,7 @@ /// Main savepoint reached upgrade_main_savepoint($result, 2010052700); } - + if ($result && $oldversion < 2010052800) { /// Changes to modinfo mean we need to rebuild course cache require_once($CFG->dirroot . '/course/lib.php'); @@ -4164,6 +4164,20 @@ upgrade_main_savepoint($result, 2010052800); } + if ($result && $oldversion < 2010052801) { + + /// Define field sortorder to be added to files + $table = new xmldb_table('files'); + $field = new xmldb_field('sortorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'timemodified'); + + /// Conditionally launch add field sortorder + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + /// Main savepoint reached + upgrade_main_savepoint($result, 2010052801); + } return $result; } Index: lib/file/file_info.php ========================================================= --- lib/file/file_info.php (revision 1.8) +++ lib/file/file_info.php Thu May 27 10:18:42 WST 2010 @@ -170,6 +170,14 @@ } /** + * Returns the sort order of the file + * @return int + */ + public function get_sortorder() { + return 0; + } + + /** * Create new directory, may throw exception - make sure * params are valid. * @param string $newdirname name of new directory Index: lib/file/file_info_stored.php ========================================================= --- lib/file/file_info_stored.php (revision 1.15) +++ lib/file/file_info_stored.php Thu May 27 10:25:26 WST 2010 @@ -200,6 +200,14 @@ } /** + * Returns the sort order of the file + * @return int + */ + public function get_sortorder() { + return $this->lf->get_sortorder(); + } + + /** * Returns list of children. * @return array of file_info instances */ Index: lib/file/file_storage.php ========================================================= --- lib/file/file_storage.php (revision 1.41) +++ lib/file/file_storage.php Thu May 27 10:17:10 WST 2010 @@ -218,7 +218,7 @@ * @param bool $includedirs * @return array of stored_files indexed by pathanmehash */ - public function get_area_files($contextid, $filearea, $itemid=false, $sort="itemid, filepath, filename", $includedirs = true) { + public function get_area_files($contextid, $filearea, $itemid=false, $sort="sortorder, itemid, filepath, filename", $includedirs = true) { global $DB; $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea); @@ -247,7 +247,7 @@ */ public function get_area_tree($contextid, $filearea, $itemid) { $result = array('dirname'=>'', 'dirfile'=>null, 'subdirs'=>array(), 'files'=>array()); - $files = $this->get_area_files($contextid, $filearea, $itemid, $sort="itemid, filepath, filename", true); + $files = $this->get_area_files($contextid, $filearea, $itemid, $sort="sortorder, itemid, filepath, filename", true); // first create directory structure foreach ($files as $hash=>$dir) { if (!$dir->is_directory()) { @@ -654,6 +654,14 @@ throw new file_exception('storedfileproblem', 'Invalid itemid'); } + if (!empty($file_record->sortorder)) { + if (!is_number($file_record->sortorder) or $file_record->sortorder < 0) { + $file_record->sortorder = 0; + } + } else { + $file_record->sortorder = 0; + } + $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 '/' @@ -683,6 +691,7 @@ $newrecord->source = empty($file_record->source) ? null : $file_record->source; $newrecord->author = empty($file_record->author) ? null : $file_record->author; $newrecord->license = empty($file_record->license) ? null : $file_record->license; + $newrecord->sortorder = $file_record->sortorder; list($newrecord->contenthash, $newrecord->filesize, $newfile) = $this->add_file_to_pool($pathname); @@ -734,6 +743,14 @@ throw new file_exception('storedfileproblem', 'Invalid itemid'); } + if (!empty($file_record->sortorder)) { + if (!is_number($file_record->sortorder) or $file_record->sortorder < 0) { + $file_record->sortorder = 0; + } + } else { + $file_record->sortorder = 0; + } + $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 '/' @@ -763,6 +780,7 @@ $newrecord->source = empty($file_record->source) ? null : $file_record->source; $newrecord->author = empty($file_record->author) ? null : $file_record->author; $newrecord->license = empty($file_record->license) ? null : $file_record->license; + $newrecord->sortorder = $file_record->sortorder; list($newrecord->contenthash, $newrecord->filesize, $newfile) = $this->add_string_to_pool($content); Index: lib/file/stored_file.php ========================================================= --- lib/file/stored_file.php (revision 1.19) +++ lib/file/stored_file.php Thu May 27 10:10:12 WST 2010 @@ -448,5 +448,13 @@ public function get_source() { return $this->file_record->source; } + + /** + * Returns the sort order of file + * + * @return int + */ + public function get_sortorder() { + return $this->file_record->sortorder; + } } - Index: lib/filelib.php ========================================================= --- lib/filelib.php (revision 1.192) +++ lib/filelib.php Thu May 27 16:43:19 WST 2010 @@ -557,6 +557,7 @@ foreach ($files as $file) { if ($file->is_directory()) { $item = new stdclass; + $item->sortorder = $file->get_sortorder(); $item->filepath = $file->get_filepath(); $foldername = explode('/', trim($item->filepath, '/')); @@ -615,6 +616,7 @@ $icon = mimeinfo_from_type('icon', $file->get_mimetype()); $icon = str_replace('.gif', '', $icon); $item->icon = $OUTPUT->pix_url('f/' . $icon)->out(); + $item->sortorder = $file->get_sortorder(); if ($icon == 'zip') { $item->type = 'zip'; @@ -632,6 +634,7 @@ $fb = get_file_browser(); $fileinfo = $fb->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename()); $item->url = $fileinfo->get_url(); + $item->sortorder = $fileinfo->get_sortorder(); } $list[] = $item; } @@ -740,7 +743,8 @@ $filecount = 0; foreach ($oldfiles as $file) { $oldhash = $file->get_pathnamehash(); - if (isset($newhashes[$oldhash])) { + // check if sortorder, filename, filepath, filearea, itemid and contextid changed + if (isset($newhashes[$oldhash]) && $file->get_sortorder() == $newhashes[$oldhash]->get_sortorder()) { if (!$file->is_directory()) { $filecount++; } @@ -798,6 +802,53 @@ } /** + * Set file sort order + * @global object $DB + * @param integer $contextid the context id + * @param string $filearea file area. + * @param integer $itemid itemid. + * @param string $filepath file path. + * @param string $filename file name. + * @param integer $sortorer the sort order of file. + * @return boolean + */ +function file_set_sortorder($contextid, $filearea, $itemid, $filepath, $filename, $sortorder) { + global $DB; + $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'filename'=>$filename); + if ($file_record = $DB->get_record('files', $conditions)) { + $sortorder = (int)$sortorder; + $file_record->sortorder = $sortorder; + $DB->update_record('files', $file_record); + return true; + } + return false; +} + +/** + * reset file sort order number to 0 + * @global object $DB + * @param integer $contextid the context id + * @param string $filearea file area. + * @param integer $itemid itemid. + * @return boolean + */ +function file_reset_sortorder($contextid, $filearea, $itemid=false) { + global $DB; + + $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea); + if ($itemid !== false) { + $conditions['itemid'] = $itemid; + } + + $file_records = $DB->get_records('files', $conditions); + foreach ($file_records as $file_record) { + $file_record->sortorder = 0; + $DB->update_record('files', $file_record); + } + return true; +} + +/** * Returns description of upload error * * @param int $errorcode found in $_FILES['filename.ext']['error'] Index: lib/form/filemanager.js ========================================================= --- lib/form/filemanager.js (revision 1.34) +++ lib/form/filemanager.js Thu May 27 12:16:54 WST 2010 @@ -56,13 +56,6 @@ this.options = options; if (options.mainfile) { this.enablemainfile = options.mainfile; - var mainid = '#id_'+this.enablemainfile; - var filename = Y.one(mainid).get('value'); - this.mainfilename = ''; - if (filename) { - var parts = filename.split('/'); - this.mainfilename = parts[parts.length-1]; - } } this.client_id = options.client_id; this.currentpath = '/'; @@ -397,7 +390,7 @@ } var fullname = list[i].fullname; - if (this.mainfilename == fullname) { + if (list[i].sortorder == 1) { html = html.replace('___fullname___', ' ' + fullname + ''); } else { html = html.replace('___fullname___', ' ' + fullname + ''); @@ -452,11 +445,20 @@ ]; function setmainfile(type, ev, obj) { var file = obj[node.get('id')]; - this.mainfilename = file.filename; - Y.one(mainid).set('value', file.filepath+file.filename); - scope.refresh(scope.currentpath); + //Y.one(mainid).set('value', file.filepath+file.filename); + var params = {}; + params['filepath'] = file.filepath; + params['filename'] = file.filename; + this.request({ + action: 'setmainfile', + scope: scope, + params: params, + callback: function(id, obj, args) { + scope.refresh(scope.currentpath); + } + }); } - if (this.enablemainfile && (file.filename != this.mainfilename)) { + if (this.enablemainfile && (file.sortorder != 1)) { var mainid = '#id_'+this.enablemainfile; var menu = {text: M.str.repository.setmainfile, onclick:{fn: setmainfile, obj:data, scope:this}}; menuitems.push(menu); Index: mod/resource/db/install.xml ========================================================= --- mod/resource/db/install.xml (revision 1.8) +++ mod/resource/db/install.xml Thu May 27 15:36:06 WST 2010 @@ -1,5 +1,5 @@ - @@ -11,9 +11,8 @@ - - - + + Index: mod/resource/db/upgrade.php ========================================================= --- mod/resource/db/upgrade.php (revision 1.13) +++ mod/resource/db/upgrade.php Fri May 28 14:17:02 WST 2010 @@ -211,5 +211,40 @@ upgrade_mod_savepoint($result, 2009063000, 'resource'); } + if ($result && $oldversion < 2009080501) { + require_once("$CFG->libdir/filelib.php"); + + $sql = "SELECT r.id, + r.mainfile, + cm.id AS cmid + FROM {resource} r + JOIN {modules} m ON m.name='resource' + JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = r.id)"; + + if ($instances = $DB->get_recordset_sql($sql)) { + foreach ($instances as $instance) { + $context = get_context_instance(CONTEXT_MODULE, $instance->cmid); + $filearea = 'resource_content'; + $itemid = 0; + $filepath = file_correct_filepath(dirname($instance->mainfile)); + $filename = basename($instance->mainfile); + file_set_sortorder($context->id, $filearea, $itemid, $filepath, $filename, 1); + } + } + + /// Define field mainfile to be dropped from resource + $table = new xmldb_table('resource'); + $field = new xmldb_field('mainfile'); + + /// Conditionally launch drop field mainfile + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + /// resource savepoint reached + upgrade_mod_savepoint($result, 2009080501, 'resource'); + } + + return $result; } Index: mod/resource/lib.php ========================================================= --- mod/resource/lib.php (revision 1.126) +++ mod/resource/lib.php Thu May 27 17:46:56 WST 2010 @@ -84,10 +84,7 @@ function resource_add_instance($data, $mform) { global $CFG, $DB; require_once("$CFG->libdir/resourcelib.php"); - - $cmid = $data->coursemodule; - $draftitemid = $data->files; - + $cmid = $data->coursemodule; $data->timemodified = time(); $displayoptions = array(); if ($data->display == RESOURCELIB_DISPLAY_POPUP) { @@ -104,23 +101,7 @@ // we need to use context now, so we need to make sure all needed info is already in db $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid)); - $context = get_context_instance(CONTEXT_MODULE, $cmid); - - if ($draftitemid) { - file_save_draft_area_files($draftitemid, $context->id, 'resource_content', 0, array('subdirs'=>true)); - } - - $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'resource_content', 0, '', false); - if (count($files) == 1) { - $file = reset($files); - $path = $file->get_filepath().$file->get_filename(); - if ($path !== $data->mainfile) { - $data->mainfile = $path; - $DB->set_field('resource', 'mainfile', $path, array('id'=>$data->id)); - } - } - + resource_set_mainfile($data); return $data->id; } @@ -133,10 +114,6 @@ function resource_update_instance($data, $mform) { global $CFG, $DB; require_once("$CFG->libdir/resourcelib.php"); - - $cmid = $data->coursemodule; - $draftitemid = $data->files; - $data->timemodified = time(); $data->id = $data->instance; $data->revision++; @@ -153,23 +130,7 @@ $data->displayoptions = serialize($displayoptions); $DB->update_record('resource', $data); - - $context = get_context_instance(CONTEXT_MODULE, $cmid); - if ($draftitemid) { - file_save_draft_area_files($draftitemid, $context->id, 'resource_content', 0, array('subdirs'=>true)); - } - - $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'resource_content', 0, '', false); - if (count($files) == 1) { - $file = reset($files); - $path = $file->get_filepath().$file->get_filename(); - if ($path !== $data->mainfile) { - $data->mainfile = $path; - $DB->set_field('resource', 'mainfile', $path, array('id'=>$data->id)); - } - } - + resource_set_mainfile($data); return true; } @@ -267,8 +228,9 @@ global $CFG, $DB; require_once("$CFG->libdir/filelib.php"); require_once("$CFG->dirroot/mod/resource/locallib.php"); + $context = get_context_instance(CONTEXT_MODULE, $coursemodule->id); - if (!$resource = $DB->get_record('resource', array('id'=>$coursemodule->instance), 'id, name, display, displayoptions, tobemigrated, mainfile, revision')) { + if (!$resource = $DB->get_record('resource', array('id'=>$coursemodule->instance), 'id, name, display, displayoptions, tobemigrated, revision')) { return NULL; } @@ -279,8 +241,13 @@ $info->icon ='i/cross_red_big'; return $info; } - - $info->icon = str_replace(array('.gif', '.png'), '', file_extension_icon($resource->mainfile)); + $fs = get_file_storage(); + $files = $fs->get_area_files($context->id, 'resource_content', 0, 'sortorder'); + if (count($files) >= 1) { + $mainfile = array_pop($files); + $info->icon = str_replace(array('.gif', '.png'), '', file_extension_icon($mainfile->get_filename())); + $resource->mainfile = $mainfile->get_filename(); + } $display = resource_get_final_display_type($resource); @@ -301,9 +268,11 @@ $info->extra = "onclick=\"window.location.href ='$fullurl';return false;\""; } else if ($display == RESOURCELIB_DISPLAY_DOWNLOAD) { + if (empty($mainfile)) { + return NULL; + } // do not open any window because it would be left there after download - $context = get_context_instance(CONTEXT_MODULE, $coursemodule->id); - $path = '/'.$context->id.'/resource_content/'.$resource->revision.$resource->mainfile; + $path = '/'.$context->id.'/resource_content/'.$resource->revision.$mainfile->get_filename(); $fullurl = addslashes_js(file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, true)); // When completion information is enabled for download files, make Index: mod/resource/locallib.php ========================================================= --- mod/resource/locallib.php (revision 1.10) +++ mod/resource/locallib.php Thu May 27 17:45:30 WST 2010 @@ -214,6 +214,7 @@ resource_print_heading($resource, $cm, $course, true); resource_print_intro($resource, $cm, $course, true); + $resource->mainfile = $file->get_filename(); echo '
'; switch (resource_get_final_display_type($resource)) { case RESOURCELIB_DISPLAY_POPUP: @@ -360,7 +361,11 @@ 'application/pdf', 'text/html', ); - $mimetype = mimeinfo('type', $resource->mainfile); + if (empty($resource->mainfile)) { + return RESOURCELIB_DISPLAY_DOWNLOAD; + } else { + $mimetype = mimeinfo('type', $resource->mainfile); + } if (in_array($mimetype, $download)) { return RESOURCELIB_DISPLAY_DOWNLOAD; @@ -390,3 +395,21 @@ return parent::get_visible_name(); } } + +function resource_set_mainfile($data) { + global $DB; + $fs = get_file_storage(); + $cmid = $data->coursemodule; + $draftitemid = $data->files; + + $context = get_context_instance(CONTEXT_MODULE, $cmid); + if ($draftitemid) { + file_save_draft_area_files($draftitemid, $context->id, 'resource_content', 0, array('subdirs'=>true)); + } + $files = $fs->get_area_files($context->id, 'resource_content', 0, 'sortorder', false); + if (count($files) == 1) { + // only one file attached, set it as main file automatically + $file = reset($files); + file_set_sortorder($context->id, 'resource_content', 0, $file->get_filepath(), $file->get_filename(), 1); + } +} Index: mod/resource/mod_form.php ========================================================= --- mod/resource/mod_form.php (revision 1.32) +++ mod/resource/mod_form.php Thu May 27 13:51:31 WST 2010 @@ -68,13 +68,10 @@ $filemanager_options['accepted_types'] = '*'; $filemanager_options['maxbytes'] = 0; $filemanager_options['maxfiles'] = -1; - $filemanager_options['mainfile'] = 'mainfile'; + $filemanager_options['mainfile'] = true; $mform->addElement('filemanager', 'files', get_string('selectfiles'), null, $filemanager_options); - $mform->addElement('hidden', 'mainfile', get_string('areamainfile', 'repository'), array('id'=>'id_mainfile')); - $mform->setType('mainfile', PARAM_PATH); - //------------------------------------------------------- $mform->addElement('header', 'optionssection', get_string('optionsheader', 'resource')); @@ -197,20 +194,25 @@ $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); - if (!$files = $fs->get_area_files($usercontext->id, 'user_draft', $data['files'], 'id', false)) { + if (!$files = $fs->get_area_files($usercontext->id, 'user_draft', $data['files'], 'sortorder', false)) { $errors['files'] = get_string('required'); return $errors; } if (count($files) == 1) { // no need to select main file if only one picked return $errors; - } - $filepaths = array(); - foreach ($files as $file) { - $filepaths[] = $file->get_filepath().$file->get_filename(); - } - if (!in_array($data['mainfile'], $filepaths)) { - $errors['files'] = get_string('selectmainfile', 'resource'); + } else if(count($files) > 1) { + // looking for main file + $mainfile = false; + foreach($files as $file) { + if ($file->get_sortorder() == 1) { + $mainfile = true; + break; + } + } + if (!$mainfile) { + $errors['files'] = get_string('selectmainfile', 'resource'); + } } return $errors; } Index: mod/resource/version.php ========================================================= --- mod/resource/version.php (revision 1.40) +++ mod/resource/version.php Thu May 27 15:54:21 WST 2010 @@ -23,7 +23,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -$module->version = 2009080500; +$module->version = 2009080501; $module->requires = 2009073101; // Requires this Moodle version $module->cron = 0; Index: mod/resource/view.php ========================================================= --- mod/resource/view.php (revision 1.69) +++ mod/resource/view.php Thu May 27 17:40:49 WST 2010 @@ -64,10 +64,12 @@ } $fs = get_file_storage(); -$pathnamehash = sha1($context->id.'resource_content0'.$resource->mainfile); -if (!$file = $fs->get_file_by_hash($pathnamehash)) { +$files = $fs->get_area_files($context->id, 'resource_content', 0, 'sortorder'); +if (count($files) < 1) { resource_print_filenotfound($resource, $cm, $course); die; +} else { + $file = array_pop($files); } if ($redirect) { @@ -78,6 +80,7 @@ redirect($fullurl); } +$resource->mainfile = $file->get_filename(); switch (resource_get_final_display_type($resource)) { case RESOURCELIB_DISPLAY_EMBED: resource_display_embed($resource, $cm, $course, $file); Index: version.php ========================================================= --- version.php (revision 1.1594) +++ version.php Fri May 28 14:25:02 WST 2010 @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2010052800; // YYYYMMDD = date of the last version bump + $version = 2010052801; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 Preview 2 (Build: 20100528)'; // Human-friendly version name