Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

MDL-34290 repository API: add repository function to import reference…

…d file

it must be independed from sync_external_file because sync often does not actually download contents, it is used just to retrieve
the size of the file. Besides the timeouts for get_file and sync requests are very different.

Also add option to send_stored_file() to ignore reference and send cached contents
  • Loading branch information...
commit 9001c7242e1ffdc658366a6a14e16123be1d9a06 1 parent 22fa5d9
Marina Glancy marinaglancy authored
2  lib/filelib.php
@@ -2326,7 +2326,7 @@ function send_stored_file($stored_file, $lifetime=86400 , $filter=0, $forcedownl
2326 2326 }
2327 2327
2328 2328 // handle external resource
2329   - if ($stored_file && $stored_file->is_external_file()) {
  2329 + if ($stored_file && $stored_file->is_external_file() && !isset($options['sendcachedexternalfile'])) {
2330 2330 $stored_file->send_file($lifetime, $filter, $forcedownload, $options);
2331 2331 die;
2332 2332 }
10 lib/filestorage/file_storage.php
@@ -1841,15 +1841,15 @@ public function update_references_to_storedfile(stored_file $storedfile) {
1841 1841 /**
1842 1842 * Convert file alias to local file
1843 1843 *
  1844 + * @throws moodle_exception if file could not be downloaded
  1845 + *
1844 1846 * @param stored_file $storedfile a stored_file instances
  1847 + * @param int $maxbytes throw an exception if file size is bigger than $maxbytes (0 means no limit)
1845 1848 * @return stored_file stored_file
1846 1849 */
1847   - public function import_external_file(stored_file $storedfile) {
  1850 + public function import_external_file(stored_file $storedfile, $maxbytes = 0) {
1848 1851 global $CFG;
1849   - require_once($CFG->dirroot.'/repository/lib.php');
1850   - // sync external file
1851   - repository::sync_external_file($storedfile);
1852   - // Remove file references
  1852 + $storedfile->import_external_file_contents($maxbytes);
1853 1853 $storedfile->delete_reference();
1854 1854 return $storedfile;
1855 1855 }
12 lib/filestorage/stored_file.php
@@ -928,4 +928,16 @@ public function set_missingsource($lifetime = null) {
928 928 public function send_file($lifetime, $filter, $forcedownload, $options) {
929 929 $this->repository->send_file($this, $lifetime, $filter, $forcedownload, $options);
930 930 }
  931 +
  932 + /**
  933 + * Imports the contents of an external file into moodle filepool.
  934 + *
  935 + * @throws moodle_exception if file could not be downloaded or is too big
  936 + * @param int $maxbytes throw an exception if file size is bigger than $maxbytes (0 means no limit)
  937 + */
  938 + public function import_external_file_contents($maxbytes = 0) {
  939 + if ($this->repository) {
  940 + $this->repository->import_external_file_contents($this, $maxbytes);
  941 + }
  942 + }
931 943 }
71 repository/lib.php
@@ -1633,6 +1633,77 @@ public function get_file($url, $filename = '') {
1633 1633 }
1634 1634
1635 1635 /**
  1636 + * Downloads the file from external repository and saves it in moodle filepool.
  1637 + * This function is different from {@link repository::sync_external_file()} because it has
  1638 + * bigger request timeout and always downloads the content.
  1639 + *
  1640 + * This function is invoked when we try to unlink the file from the source and convert
  1641 + * a reference into a true copy.
  1642 + *
  1643 + * @throws exception when file could not be imported
  1644 + *
  1645 + * @param stored_file $file
  1646 + * @param int $maxbytes throw an exception if file size is bigger than $maxbytes (0 means no limit)
  1647 + */
  1648 + public function import_external_file_contents(stored_file $file, $maxbytes = 0) {
  1649 + if (!$file->is_external_file()) {
  1650 + // nothing to import if the file is not a reference
  1651 + return;
  1652 + } else if ($file->get_repository_id() != $this->id) {
  1653 + // error
  1654 + debugging('Repository instance id does not match');
  1655 + return;
  1656 + } else if ($this->has_moodle_files()) {
  1657 + // files that are references to local files are already in moodle filepool
  1658 + // just validate the size
  1659 + if ($maxbytes > 0 && $file->get_filesize() > $maxbytes) {
  1660 + throw new file_exception('maxbytes');
  1661 + }
  1662 + return;
  1663 + } else {
  1664 + if ($maxbytes > 0 && $file->get_filesize() > $maxbytes) {
  1665 + // note that stored_file::get_filesize() also calls synchronisation
  1666 + throw new file_exception('maxbytes');
  1667 + }
  1668 + $fs = get_file_storage();
  1669 + $contentexists = $fs->content_exists($file->get_contenthash());
  1670 + if ($contentexists && $file->get_filesize() && $file->get_contenthash() === sha1('')) {
  1671 + // even when 'file_storage::content_exists()' returns true this may be an empty
  1672 + // content for the file that was not actually downloaded
  1673 + $contentexists = false;
  1674 + }
  1675 + $now = time();
  1676 + if ($file->get_referencelastsync() + $file->get_referencelifetime() >= $now &&
  1677 + !$file->get_status() &&
  1678 + $contentexists) {
  1679 + // we already have the content in moodle filepool and it was synchronised recently.
  1680 + // Repositories may overwrite it if they want to force synchronisation anyway!
  1681 + return;
  1682 + } else {
  1683 + // attempt to get a file
  1684 + try {
  1685 + $fileinfo = $this->get_file($file->get_reference());
  1686 + if (isset($fileinfo['path'])) {
  1687 + list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($fileinfo['path']);
  1688 + // set this file and other similar aliases synchronised
  1689 + $lifetime = $this->get_reference_file_lifetime($file->get_reference());
  1690 + $file->set_synchronized($contenthash, $filesize, 0, $lifetime);
  1691 + } else {
  1692 + throw new moodle_exception('errorwhiledownload', 'repository', '', '');
  1693 + }
  1694 + } catch (Exception $e) {
  1695 + if ($contentexists) {
  1696 + // better something than nothing. We have a copy of file. It's sync time
  1697 + // has expired but it is still very likely that it is the last version
  1698 + } else {
  1699 + throw($e);
  1700 + }
  1701 + }
  1702 + }
  1703 + }
  1704 + }
  1705 +
  1706 + /**
1636 1707 * Return size of a file in bytes.
1637 1708 *
1638 1709 * @param string $source encoded and serialized data of file

0 comments on commit 9001c72

Please sign in to comment.
Something went wrong with that request. Please try again.