mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 08:56:36 +02:00
Merge branch 'wip-MDL-33550-master' of git://github.com/marinaglancy/moodle
This commit is contained in:
commit
4585e6ac98
18 changed files with 366 additions and 323 deletions
|
@ -1090,16 +1090,39 @@ abstract class repository {
|
|||
}
|
||||
|
||||
/**
|
||||
* Repository method to serve file
|
||||
* Repository method to serve the referenced file
|
||||
*
|
||||
* @param stored_file $storedfile
|
||||
* @see send_stored_file
|
||||
*
|
||||
* @param stored_file $storedfile the file that contains the reference
|
||||
* @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 array $options additional options affecting the file serving
|
||||
*/
|
||||
public function send_file($storedfile, $lifetime=86400 , $filter=0, $forcedownload=false, array $options = null) {
|
||||
throw new coding_exception("Repository plugin must implement send_file() method.");
|
||||
if ($this->has_moodle_files()) {
|
||||
$fs = get_file_storage();
|
||||
$params = file_storage::unpack_reference($storedfile->get_reference(), true);
|
||||
$srcfile = null;
|
||||
if (is_array($params)) {
|
||||
$srcfile = $fs->get_file($params['contextid'], $params['component'], $params['filearea'],
|
||||
$params['itemid'], $params['filepath'], $params['filename']);
|
||||
}
|
||||
if (empty($options)) {
|
||||
$options = array();
|
||||
}
|
||||
if (!isset($options['filename'])) {
|
||||
$options['filename'] = $storedfile->get_filename();
|
||||
}
|
||||
if (!$srcfile) {
|
||||
send_file_not_found();
|
||||
} else {
|
||||
send_stored_file($srcfile, $lifetime, $filter, $forcedownload, $options);
|
||||
}
|
||||
} else {
|
||||
throw new coding_exception("Repository plugin must implement send_file() method.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1128,10 +1151,35 @@ abstract class repository {
|
|||
* {@link stored_file::get_reference()}
|
||||
*
|
||||
* @param string $reference
|
||||
* @return string|null
|
||||
* @param int $filestatus status of the file, 0 - ok, 666 - source missing
|
||||
* @return string
|
||||
*/
|
||||
public function get_reference_details($reference) {
|
||||
return null;
|
||||
public function get_reference_details($reference, $filestatus = 0) {
|
||||
if ($this->has_moodle_files()) {
|
||||
$fileinfo = null;
|
||||
$params = file_storage::unpack_reference($reference, true);
|
||||
if (is_array($params)) {
|
||||
$context = get_context_instance_by_id($params['contextid']);
|
||||
if ($context) {
|
||||
$browser = get_file_browser();
|
||||
$fileinfo = $browser->get_file_info($context, $params['component'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename']);
|
||||
}
|
||||
}
|
||||
if (empty($fileinfo)) {
|
||||
if ($filestatus == 666) {
|
||||
if (is_siteadmin() || ($context && has_capability('moodle/course:managefiles', $context))) {
|
||||
return get_string('lostsource', 'repository',
|
||||
$params['contextid']. '/'. $params['component']. '/'. $params['filearea']. '/'. $params['itemid']. $params['filepath']. $params['filename']);
|
||||
} else {
|
||||
return get_string('lostsource', 'repository', '');
|
||||
}
|
||||
}
|
||||
return get_string('undisclosedsource', 'repository');
|
||||
} else {
|
||||
return $fileinfo->get_readable_fullname();
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1148,14 +1196,33 @@ abstract class repository {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get file from external repository by reference
|
||||
* Returns information about file in this repository by reference
|
||||
* {@link repository::get_file_reference()}
|
||||
* {@link repository::get_file()}
|
||||
*
|
||||
* Returns null if file not found or is not readable
|
||||
*
|
||||
* @param stdClass $reference file reference db record
|
||||
* @return stdClass|null|false
|
||||
* @return stdClass|null contains one of the following:
|
||||
* - 'contenthash' and 'filesize'
|
||||
* - 'filepath'
|
||||
* - 'handle'
|
||||
* - 'content'
|
||||
*/
|
||||
public function get_file_by_reference($reference) {
|
||||
if ($this->has_moodle_files() && isset($reference->reference)) {
|
||||
$fs = get_file_storage();
|
||||
$params = file_storage::unpack_reference($reference->reference, true);
|
||||
if (!is_array($params) || !($storedfile = $fs->get_file($params['contextid'],
|
||||
$params['component'], $params['filearea'], $params['itemid'], $params['filepath'],
|
||||
$params['filename']))) {
|
||||
return null;
|
||||
}
|
||||
return (object)array(
|
||||
'contenthash' => $storedfile->get_contenthash(),
|
||||
'filesize' => $storedfile->get_filesize()
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1433,6 +1500,13 @@ abstract class repository {
|
|||
* @return string file referece
|
||||
*/
|
||||
public function get_file_reference($source) {
|
||||
if ($this->has_moodle_files() && ($this->supported_returntypes() & FILE_REFERENCE)) {
|
||||
$params = file_storage::unpack_reference($source);
|
||||
if (!is_array($params)) {
|
||||
throw new repository_exception('invalidparams', 'repository');
|
||||
}
|
||||
return file_storage::pack_reference($params);
|
||||
}
|
||||
return $source;
|
||||
}
|
||||
/**
|
||||
|
@ -1484,16 +1558,22 @@ abstract class repository {
|
|||
*
|
||||
* @param string $url the url of file
|
||||
* @param string $filename save location
|
||||
* @return string the location of the file
|
||||
* @return array with elements:
|
||||
* path: internal location of the file
|
||||
* url: URL to the source (from parameters)
|
||||
*/
|
||||
public function get_file($url, $filename = '') {
|
||||
global $CFG;
|
||||
$path = $this->prepare_file($filename);
|
||||
$fp = fopen($path, 'w');
|
||||
$c = new curl;
|
||||
$c->download(array(array('url'=>$url, 'file'=>$fp)));
|
||||
$result = $c->download(array(array('url'=>$url, 'file'=>$fp)));
|
||||
// Close file handler.
|
||||
fclose($fp);
|
||||
if (empty($result)) {
|
||||
unlink($path);
|
||||
return null;
|
||||
}
|
||||
return array('path'=>$path, 'url'=>$url);
|
||||
}
|
||||
|
||||
|
@ -2137,25 +2217,47 @@ abstract class repository {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called from phpunit between tests, resets whatever was cached
|
||||
*/
|
||||
public static function reset_caches() {
|
||||
self::sync_external_file(null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to request proxy file sync with repository source.
|
||||
*
|
||||
* @param stored_file $file
|
||||
* @param bool $resetsynchistory whether to reset all history of sync (used by phpunit)
|
||||
* @return bool success
|
||||
*/
|
||||
public static function sync_external_file(stored_file $file) {
|
||||
public static function sync_external_file($file, $resetsynchistory = false) {
|
||||
global $DB;
|
||||
// TODO MDL-25290 static should be replaced with MUC code.
|
||||
static $synchronized = array();
|
||||
if ($resetsynchistory) {
|
||||
$synchronized = array();
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
|
||||
if (!$file || !$file->get_referencefileid()) {
|
||||
return false;
|
||||
}
|
||||
if (array_key_exists($file->get_id(), $synchronized)) {
|
||||
return $synchronized[$file->get_id()];
|
||||
}
|
||||
|
||||
// remember that we already cached in current request to prevent from querying again
|
||||
$synchronized[$file->get_id()] = false;
|
||||
|
||||
if (!$reference = $DB->get_record('files_reference', array('id'=>$file->get_referencefileid()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($reference->lastsync) and ($reference->lastsync + $reference->lifetime > time())) {
|
||||
return false;
|
||||
$synchronized[$file->get_id()] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$repository = self::get_repository_by_id($reference->repositoryid, SYSCONTEXTID)) {
|
||||
|
@ -2169,14 +2271,10 @@ abstract class repository {
|
|||
$fileinfo = $repository->get_file_by_reference($reference);
|
||||
if ($fileinfo === null) {
|
||||
// does not exist any more - set status to missing
|
||||
$sql = "UPDATE {files} SET status = :missing WHERE referencefileid = :referencefileid";
|
||||
$params = array('referencefileid'=>$reference->id, 'missing'=>666);
|
||||
$DB->execute($sql, $params);
|
||||
$file->set_missingsource();
|
||||
//TODO: purge content from pool if we set some other content hash and it is no used any more
|
||||
$synchronized[$file->get_id()] = true;
|
||||
return true;
|
||||
} else if ($fileinfo === false) {
|
||||
// error
|
||||
return false;
|
||||
}
|
||||
|
||||
$contenthash = null;
|
||||
|
@ -2205,15 +2303,9 @@ abstract class repository {
|
|||
return false;
|
||||
}
|
||||
|
||||
$now = time();
|
||||
// update files table
|
||||
$sql = "UPDATE {files} SET contenthash = :contenthash, filesize = :filesize, referencelastsync = :now, referencelifetime = :lifetime, timemodified = :now2 WHERE referencefileid = :referencefileid AND contenthash <> :contenthash2";
|
||||
$params = array('contenthash'=>$contenthash, 'filesize'=>$filesize, 'now'=>$now, 'lifetime'=>$reference->lifetime,
|
||||
'now2'=>$now, 'referencefileid'=>$reference->id, 'contenthash2'=>$contenthash);
|
||||
$DB->execute($sql, $params);
|
||||
|
||||
$DB->set_field('files_reference', 'lastsync', $now, array('id'=>$reference->id));
|
||||
|
||||
$file->set_synchronized($contenthash, $filesize);
|
||||
$synchronized[$file->get_id()] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue