From: skodak Date: Sun, 21 Sep 2008 15:37:07 +0000 (+0000) Subject: MDL-16596 reworked areafiles element X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=b933a13955973165bcb8a76e95f6c0953b06d45f;p=moodle.git MDL-16596 reworked areafiles element --- diff --git a/files/areafiles.php b/files/draftfiles.php similarity index 84% rename from files/areafiles.php rename to files/draftfiles.php index 90fced9666..b79dcc7fb3 100644 --- a/files/areafiles.php +++ b/files/draftfiles.php @@ -3,8 +3,6 @@ require('../config.php'); require_once($CFG->libdir.'/filelib.php'); - $contextid = required_param('contextid', PARAM_INT); - $filearea = required_param('filearea', PARAM_ALPHAEXT); $itemid = required_param('itemid', PARAM_INT); $filepath = optional_param('filepath', '/', PARAM_PATH); @@ -13,15 +11,18 @@ $newdirname = optional_param('newdirname', '', PARAM_FILE); $delete = optional_param('delete', 0, PARAM_BOOL); - if (!$context = get_context_instance_by_id($contextid)) { - print_error('invalidcontext'); - } - require_login(); if (isguestuser()) { print_error('noguest'); } + if (!$context = get_context_instance(CONTEXT_USER, $USER->id)) { + print_error('invalidcontext'); + } + + $contextid = $context->id; + $filearea = 'user_draft'; + $browser = get_file_browser(); if (!$area_info = $browser->get_file_info($context, $filearea, $itemid, '/', null)) { @@ -47,7 +48,7 @@ if ($newdir_info = $file_info->create_directory($newdirname, $USER->id)) { $params = $newdir_info->get_params_rawencoded(); $params = implode('&', $params); - redirect("areafiles.php?$params"); + redirect("draftfiles.php?$params"); } else { $error = "Could not create new dir"; // TODO: localise } @@ -61,7 +62,7 @@ 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("areafiles.php?$params"); + redirect("draftfiles.php?$params"); } else { $error = "Could not create upload file"; // TODO: localise @@ -83,7 +84,7 @@ $optionsyes['delete'] = 1; $optionsyes['sesskey'] = sesskey(); - notice_yesno (get_string('deletecheckfiles'), 'areafiles.php', 'areafiles.php', $optionsyes, $optionsno, 'post', 'get'); + notice_yesno (get_string('deletecheckfiles'), 'draftfiles.php', 'draftfiles.php', $optionsyes, $optionsno, 'post', 'get'); print_footer('empty'); die; } @@ -94,7 +95,7 @@ } $params = $parent_info->get_params_rawencoded(); $params = implode('&', $params); - redirect("areafiles.php?$params", $error); + redirect("draftfiles.php?$params", $error); } } @@ -110,7 +111,7 @@ if ($file_info and $file_info->is_directory() and $file_info->is_writable()) { - echo '
'; + echo '
'; echo ''; echo ''; echo ''; @@ -121,7 +122,7 @@ echo ''; echo '
'; - echo '
'; + echo '
'; echo ''; echo ''; echo ''; @@ -163,7 +164,7 @@ function displaydir($file_info) { $params = implode('&', $params); echo ''; } @@ -181,9 +182,9 @@ function displaydir($file_info) { if ($child_info->is_directory()) { echo ''; @@ -198,7 +199,7 @@ function displaydir($file_info) { 480, 640, get_string('viewfileinpopup'), null, true); } if ($parentwritable) { - echo "pixpath/t/delete.gif\" class=\"iconsmall\" alt=\"$strdelete\" />";; + echo "pixpath/t/delete.gif\" class=\"iconsmall\" alt=\"$strdelete\" />";; } echo '
'; } diff --git a/lib/filelib.php b/lib/filelib.php index 52522f52b5..ffa8bac267 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -60,12 +60,13 @@ function get_file_url($path, $options=null, $type='coursefile') { /** * Returns empty user upload draft area information - * @return array with area info + * @return int draftareaid */ -function get_new_draftarea() { +function file_get_new_draftitemid() { global $DB, $USER; if (isguestuser() or !isloggedin()) { + // guests and not-logged-in users can not be allowed to upload anything! print_error('noguest'); } @@ -78,39 +79,125 @@ function get_new_draftarea() { $draftitemid = rand(1, 999999999); } - return array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$draftitemid); + return $draftitemid; } /** - * Converts absolute links in text and moves draft files. - * @param int $draftitemid + * Creates new draft area if not exists yet and copies files there + * @param int &$draftitemid * @param int $contextid * @param string $filearea * @param int $itemid * @param string $text usually html text with embedded links to draft area - * @param boolean $https force https + * @param boolean $forcehttps force https * @return string text with relative links starting with @@PLUGINFILE@@ */ -function file_convert_draftarea($draftitemid, $contextid, $filearea, $itemid, $text=null, $https=false) { +function file_prepare_draftarea(&$draftitemid, $contextid, $filearea, $itemid, $text=null, $forcehttps=false) { global $CFG, $USER; - /// move draft files first $usercontext = get_context_instance(CONTEXT_USER, $USER->id); + $fs = get_file_storage(); + + if (empty($draftitemid)) { + // create a new area and copy existing files into + $draftitemid = file_get_new_draftitemid(); + $file_record = array('contextid'=>$usercontext->id, 'filearea'=>'user_draft', 'itemid'=>$draftitemid); + if ($files = $fs->get_area_files($contextid, $filearea, $itemid)) { + foreach ($files as $file) { + $fs->create_file_from_storedfile($file_record, $file); + } + } + } else { + // nothing to do + } + + if (is_null($text)) { + return null; + } + + /// relink embedded files - editor can not handle @@PLUGINFILE@@ ! + + if ($CFG->slasharguments) { + $draftbase = "$CFG->wwwroot/draftfile.php/user_draft/$draftitemid/"; + } else { + $draftbase = "$CFG->wwwroot/draftfile.php?file=/user_draft/$draftitemid/"; + } + if ($forcehttps) { + $draftbase = str_replace('http://', 'https://', $draftbase); + } + + $text = str_replace('@@PLUGINFILE@@/', $draftbase); + + return $text; +} + +/** + * Converts absolute links in text and merges draft files to target area. + * @param int $draftitemid + * @param int $contextid + * @param string $filearea + * @param int $itemid + * @param string $text usually html text with embedded links to draft area + * @param boolean $forcehttps force https + * @return string text with relative links starting with @@PLUGINFILE@@ + */ +function file_convert_draftarea($draftitemid, $contextid, $filearea, $itemid, $text=null, $forcehttps=false) { + global $CFG, $USER; + + $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); - if ($files = $fs->get_area_files($usercontext->id, 'user_draft', $draftitemid, 'id', 'false')) { + + $draftfiles = $fs->get_area_files($usercontext->id, 'user_draft', $draftitemid, 'id'); + $oldfiles = $fs->get_area_files($contextid, $filearea, $itemid, 'id'); + + if (count($draftfiles) < 2) { + // means there are no files - one file means root dir only ;-) + $fs->delete_area_files($contextid, $filearea, $itemid); + + } else if (count($oldfiles) < 2) { + // there were no files before - one file means root dir only ;-) + $fs->delete_area_files($contextid, $filearea, $itemid); $file_record = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid); - foreach ($files as $file) { - $fs->create_file_from_stored($file_record, $file); + foreach ($draftfiles as $file) { + $fs->create_file_from_storedfile($file_record, $file); + } + + } else { + // we have to merge old and new files - we want to keep file ids for files that were not changed + $file_record = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid); + foreach ($draftfiles as $file) { + $newhash = sha1($contextid.$filearea.$itemid.$file->get_filepath().$file->get_filename()); + if (isset($oldfiles[$newhash])) { + $oldfile = $oldfiles[$newhash]; + unset($oldfiles[$newhash]); // do not delete afterwards + + if (!$file->is_directory()) { + if ($file->get_contenthash() === $oldfile->get_contenthash()) { + // file was not changed at all + continue; + } else { + // file changed, delete the original + $oldfile->delete(); + } + } + } + $fs->create_file_from_storedfile($file_record, $file); + } + // cleanup deleted files and dirs + foreach ($oldfiles as $file) { $file->delete(); } } + // purge the draft area + $fs->delete_area_files($usercontext->id, 'user_draft', $draftitemid); + if (is_null($text)) { return null; } - /// relink embedded files if text submitted - no absolute links allowed! + /// relink embedded files if text submitted - no absolute links allowed in database! if ($CFG->slasharguments) { $draftbase = "$CFG->wwwroot/draftfile.php/user_draft/$draftitemid/"; @@ -118,7 +205,7 @@ function file_convert_draftarea($draftitemid, $contextid, $filearea, $itemid, $t $draftbase = "$CFG->wwwroot/draftfile.php?file=/user_draft/$draftitemid/"; } - if ($https) { + if ($forcehttps) { $draftbase = str_replace('http://', 'https://', $draftbase); } @@ -128,10 +215,10 @@ function file_convert_draftarea($draftitemid, $contextid, $filearea, $itemid, $t } /** - * Finds occurences of a link to "draftfile.php" in text and replaces the - * address based on passed information. Matching is performed using the given - * current itemid, contextid and filearea and $CFG->wwwroot. This function - * replaces all the urls for one file. If more than one files were sent, it + * Finds occurences of a link to "draftfile.php" in text and replaces the + * address based on passed information. Matching is performed using the given + * current itemid, contextid and filearea and $CFG->wwwroot. This function + * replaces all the urls for one file. If more than one files were sent, it * must be called once for each file. * * @uses $CFG @@ -198,7 +285,7 @@ function file_rewrite_urls($text, $contextid, $filepath, $filearea, $itemid, $cu $text = str_replace('"'. $currenturl .'"', '"'. $newurl .'"', $text); } } // else file not found, wrong file, or string is just not a file so we leave it alone. - + } return $text; } @@ -1887,7 +1974,7 @@ class curl_cache { } if (empty($CFG->repository_cache_expire)) { $CFG->repository_cache_expire = 120; - } + } } public function get($param){ global $CFG, $USER; diff --git a/lib/form/areafiles.php b/lib/form/areafiles.php index 28454ee98f..539ed2876f 100644 --- a/lib/form/areafiles.php +++ b/lib/form/areafiles.php @@ -3,11 +3,12 @@ require_once('HTML/QuickForm/element.php'); class MoodleQuickForm_areafiles extends HTML_QuickForm_element { - var $_helpbutton = ''; - var $_areainfo = array(); + protected $_helpbutton = ''; + protected $_options = null; - function MoodleQuickForm_files($elementName=null, $elementLabel=null, $attributes=null) { - parent::HTML_QuickForm_element($elementName, $elementLabel, $attributes); + function MoodleQuickForm_files($elementName=null, $elementLabel=null, $options=null) { + $this->_options = $options; + parent::HTML_QuickForm_element($elementName, $elementLabel); } function setName($name) { @@ -19,30 +20,26 @@ class MoodleQuickForm_areafiles extends HTML_QuickForm_element { } function setValue($value) { - if (!is_array($value)) { - $this->_areainfo = array(); - } else { - $this->_areainfo = $value; - } + $this->updateAttributes(array('value'=>$value)); } function getValue() { - return $this->_areainfo; + return $this->getAttribute('value'); } - function setHelpButton($helpbuttonargs, $function='helpbutton') { - if (!is_array($helpbuttonargs)) { - $helpbuttonargs = array($helpbuttonargs); + function setHelpButton($_helpbuttonargs, $function='_helpbutton') { + if (!is_array($_helpbuttonargs)) { + $_helpbuttonargs = array($_helpbuttonargs); } else { - $helpbuttonargs = $helpbuttonargs; + $_helpbuttonargs = $_helpbuttonargs; } //we do this to to return html instead of printing it //without having to specify it in every call to make a button. - if ('helpbutton' == $function){ + if ('_helpbutton' == $function){ $defaultargs = array('', '', 'moodle', true, false, '', true); - $helpbuttonargs = $helpbuttonargs + $defaultargs ; + $_helpbuttonargs = $_helpbuttonargs + $defaultargs ; } - $this->_helpbutton=call_user_func_array($function, $helpbuttonargs); + $this->_helpbutton=call_user_func_array($function, $_helpbuttonargs); } function getHelpButton() { @@ -58,7 +55,12 @@ class MoodleQuickForm_areafiles extends HTML_QuickForm_element { } function toHtml() { - global $CFG; + global $CFG, $USER; + + // security - never ever allow guest/not logged in user to upload anything or use this element! + if (isguestuser() or !isloggedin()) { + print_error('noguest'); + } if ($this->_flagFrozen) { return $this->getFrozenHtml(); @@ -67,35 +69,22 @@ class MoodleQuickForm_areafiles extends HTML_QuickForm_element { $id = $this->_attributes['id']; $elname = $this->_attributes['name']; - $value = $this->getValue(); + $draftitemid = $this->getValue(); - if (empty($value['contextid'])) { + if (empty($draftitemid)) { // no existing area info provided - let's use fresh new draft area require_once("$CFG->libdir/filelib.php"); - $this->setValue(get_new_draftarea()); - $value = $this->getValue(); + $this->setValue(file_get_new_draftitemid()); + $draftitemid = $this->getValue(); } - $contextid = $value['contextid']; - $filearea = $value['filearea']; - $itemid = $value['itemid']; + $editorurl = "$CFG->wwwroot/files/draftfiles.php?itemid=$draftitemid"; - $str = ''; - $str .= ''; - $str .= ''; - - $url = "$CFG->wwwroot/files/areafiles.php?contextid=$contextid&filearea=$filearea&itemid=$itemid"; - - $str .= 'Error'; // TODO: localise, fix styles, etc. + $str = $this->_getTabs(); + $str .= ''; + $str .= 'Error'; // TODO: localise, fix styles, etc. return $str; } - function exportValue(&$submitValues, $assoc = false) { - return array( - $this->_attributes['name']['contexid'] => $submitValues[$this->_attributes['name']]['contextid'], - $this->_attributes['name']['filearea'] => $submitValues[$this->_attributes['name']]['filearea'], - $this->_attributes['name']['itemid'] => $submitValues[$this->_attributes['name']]['itemid'], - ); - } }