diff --git a/repository/dropbox/classes/legacy.php b/repository/dropbox/classes/legacy.php
new file mode 100644
index 00000000000..8dc34248ba9
--- /dev/null
+++ b/repository/dropbox/classes/legacy.php
@@ -0,0 +1,654 @@
+.
+
+/**
+ * This plugin is used to access user's dropbox files
+ *
+ * @since Moodle 2.0
+ * @package repository_dropbox
+ * @copyright 2012 Marina Glancy
+ * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->dirroot . '/repository/lib.php');
+
+/**
+ * Repository to access Dropbox files
+ *
+ * @package repository_dropbox
+ * @copyright 2010 Dongsheng Cai
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class repository_dropbox_legacy extends repository {
+ /** @var dropbox the instance of dropbox client */
+ private $dropbox;
+ /** @var array files */
+ public $files;
+ /** @var bool flag of login status */
+ public $logged = false;
+ /** @var int maximum size of file to cache in moodle filepool */
+ public $cachelimit = null;
+
+ /** @var int cached file ttl */
+ private $cachedfilettl = null;
+
+ /**
+ * Constructor of dropbox plugin
+ *
+ * @param int $repositoryid
+ * @param stdClass $context
+ * @param array $options
+ */
+ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
+ global $CFG;
+ $options['page'] = optional_param('p', 1, PARAM_INT);
+ parent::__construct($repositoryid, $context, $options);
+
+ $this->setting = 'dropbox_';
+
+ $this->dropbox_key = $this->get_option('dropbox_key');
+ $this->dropbox_secret = $this->get_option('dropbox_secret');
+
+ // One day.
+ $this->cachedfilettl = 60 * 60 * 24;
+
+ if (isset($options['access_key'])) {
+ $this->access_key = $options['access_key'];
+ } else {
+ $this->access_key = get_user_preferences($this->setting.'_access_key', '');
+ }
+ if (isset($options['access_secret'])) {
+ $this->access_secret = $options['access_secret'];
+ } else {
+ $this->access_secret = get_user_preferences($this->setting.'_access_secret', '');
+ }
+
+ if (!empty($this->access_key) && !empty($this->access_secret)) {
+ $this->logged = true;
+ }
+
+ $callbackurl = new moodle_url($CFG->wwwroot.'/repository/repository_callback.php', array(
+ 'callback' => 'yes',
+ 'repo_id' => $repositoryid
+ ));
+
+ $args = array(
+ 'oauth_consumer_key' => $this->dropbox_key,
+ 'oauth_consumer_secret' => $this->dropbox_secret,
+ 'oauth_callback' => $callbackurl->out(false),
+ 'api_root' => 'https://api.dropbox.com/1/oauth',
+ );
+
+ $this->dropbox = new repository_dropbox_legacy_dropbox($args);
+ }
+
+ /**
+ * Get the type name (no whitespace)
+ * For a human readable name, use get_readablename()
+ *
+ * @return string the type name
+ */
+ public function get_typename() {
+ return 'dropbox';
+ }
+
+ /**
+ * Set access key
+ *
+ * @param string $access_key
+ */
+ public function set_access_key($access_key) {
+ $this->access_key = $access_key;
+ }
+
+ /**
+ * Set access secret
+ *
+ * @param string $access_secret
+ */
+ public function set_access_secret($access_secret) {
+ $this->access_secret = $access_secret;
+ }
+
+
+ /**
+ * Check if moodle has got access token and secret
+ *
+ * @return bool
+ */
+ public function check_login() {
+ return !empty($this->logged);
+ }
+
+ /**
+ * Generate dropbox login url
+ *
+ * @return array
+ */
+ public function print_login() {
+ $result = $this->dropbox->request_token();
+ set_user_preference($this->setting.'_request_secret', $result['oauth_token_secret']);
+ $url = $result['authorize_url'];
+ if ($this->options['ajax']) {
+ $ret = array();
+ $popup_btn = new stdClass();
+ $popup_btn->type = 'popup';
+ $popup_btn->url = $url;
+ $ret['login'] = array($popup_btn);
+ return $ret;
+ } else {
+ echo ''.get_string('login', 'repository').'';
+ }
+ }
+
+ /**
+ * Request access token
+ *
+ * @return array
+ */
+ public function callback() {
+ $token = optional_param('oauth_token', '', PARAM_TEXT);
+ $secret = get_user_preferences($this->setting.'_request_secret', '');
+ $access_token = $this->dropbox->get_access_token($token, $secret);
+ set_user_preference($this->setting.'_access_key', $access_token['oauth_token']);
+ set_user_preference($this->setting.'_access_secret', $access_token['oauth_token_secret']);
+ }
+
+ /**
+ * Get dropbox files
+ *
+ * @param string $path
+ * @param int $page
+ * @return array
+ */
+ public function get_listing($path = '', $page = '1') {
+ global $OUTPUT;
+ if (empty($path) || $path == '/') {
+ $path = '/';
+ } else {
+ $path = file_correct_filepath($path);
+ }
+ $encoded_path = str_replace("%2F", "/", rawurlencode($path));
+
+ $list = array();
+ $list['list'] = array();
+ $list['manage'] = 'https://www.dropbox.com/home';
+ $list['dynload'] = true;
+ $list['nosearch'] = true;
+ $list['logouturl'] = 'https://www.dropbox.com/logout';
+ $list['message'] = get_string('logoutdesc', 'repository_dropbox');
+ // Process breadcrumb trail.
+ $list['path'] = array(
+ array('name' => get_string('dropbox', 'repository_dropbox'), 'path' => '/')
+ );
+
+ $result = $this->dropbox->get_listing($encoded_path, $this->access_key, $this->access_secret);
+
+ if (!is_object($result) || empty($result)) {
+ return $list;
+ }
+ if (empty($result->path)) {
+ $current_path = '/';
+ } else {
+ $current_path = file_correct_filepath($result->path);
+ }
+
+ $trail = '';
+ if (!empty($path)) {
+ $parts = explode('/', $path);
+ if (count($parts) > 1) {
+ foreach ($parts as $part) {
+ if (!empty($part)) {
+ $trail .= ('/'.$part);
+ $list['path'][] = array('name' => $part, 'path' => $trail);
+ }
+ }
+ } else {
+ $list['path'][] = array('name' => $path, 'path' => $path);
+ }
+ }
+
+ if (!empty($result->error)) {
+ // Reset access key.
+ set_user_preference($this->setting.'_access_key', '');
+ set_user_preference($this->setting.'_access_secret', '');
+ throw new repository_exception('repositoryerror', 'repository', '', $result->error);
+ }
+ if (empty($result->contents) or !is_array($result->contents)) {
+ return $list;
+ }
+ $files = $result->contents;
+ $dirslist = array();
+ $fileslist = array();
+ foreach ($files as $file) {
+ if ($file->is_dir) {
+ $dirslist[] = array(
+ 'title' => substr($file->path, strpos($file->path, $current_path) + strlen($current_path)),
+ 'path' => file_correct_filepath($file->path),
+ 'date' => strtotime($file->modified),
+ 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(64))->out(false),
+ 'thumbnail_height' => 64,
+ 'thumbnail_width' => 64,
+ 'children' => array(),
+ );
+ } else {
+ $thumbnail = null;
+ if ($file->thumb_exists) {
+ $thumburl = new moodle_url('/repository/dropbox/thumbnail.php',
+ array('repo_id' => $this->id,
+ 'ctx_id' => $this->context->id,
+ 'source' => $file->path,
+ 'rev' => $file->rev // include revision to avoid cache problems
+ ));
+ $thumbnail = $thumburl->out(false);
+ }
+ $fileslist[] = array(
+ 'title' => substr($file->path, strpos($file->path, $current_path) + strlen($current_path)),
+ 'source' => $file->path,
+ 'size' => $file->bytes,
+ 'date' => strtotime($file->modified),
+ 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->path, 64))->out(false),
+ 'realthumbnail' => $thumbnail,
+ 'thumbnail_height' => 64,
+ 'thumbnail_width' => 64,
+ );
+ }
+ }
+ $fileslist = array_filter($fileslist, array($this, 'filter'));
+ $list['list'] = array_merge($dirslist, array_values($fileslist));
+ return $list;
+ }
+
+ /**
+ * Displays a thumbnail for current user's dropbox file
+ *
+ * @param string $string
+ */
+ public function send_thumbnail($source) {
+ global $CFG;
+ $saveas = $this->prepare_file('');
+ try {
+ $access_key = get_user_preferences($this->setting.'_access_key', '');
+ $access_secret = get_user_preferences($this->setting.'_access_secret', '');
+ $this->dropbox->set_access_token($access_key, $access_secret);
+ $this->dropbox->get_thumbnail($source, $saveas, $CFG->repositorysyncimagetimeout);
+ $content = file_get_contents($saveas);
+ unlink($saveas);
+ // Set 30 days lifetime for the image. If the image is changed in dropbox it will have
+ // different revision number and URL will be different. It is completely safe
+ // to cache thumbnail in the browser for a long time.
+ send_file($content, basename($source), 30*24*60*60, 0, true);
+ } catch (Exception $e) {}
+ }
+
+ /**
+ * Logout from dropbox
+ * @return array
+ */
+ public function logout() {
+ set_user_preference($this->setting.'_access_key', '');
+ set_user_preference($this->setting.'_access_secret', '');
+ $this->access_key = '';
+ $this->access_secret = '';
+ return $this->print_login();
+ }
+
+ /**
+ * Fixes references in DB that contains user credentials
+ *
+ * @param string $reference contents of DB field files_reference.reference
+ */
+ public function fix_old_style_reference($reference) {
+ global $CFG;
+ $ref = unserialize($reference);
+ if (!isset($ref->url)) {
+ $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
+ $ref->url = $this->dropbox->get_file_share_link($ref->path, $CFG->repositorygetfiletimeout);
+ if (!$ref->url) {
+ // Some error occurred, do not fix reference for now.
+ return $reference;
+ }
+ }
+ unset($ref->access_key);
+ unset($ref->access_secret);
+ $newreference = serialize($ref);
+ if ($newreference !== $reference) {
+ // We need to update references in the database.
+ global $DB;
+ $params = array(
+ 'newreference' => $newreference,
+ 'newhash' => sha1($newreference),
+ 'reference' => $reference,
+ 'hash' => sha1($reference),
+ 'repoid' => $this->id
+ );
+ $refid = $DB->get_field_sql('SELECT id FROM {files_reference}
+ WHERE reference = :reference AND referencehash = :hash
+ AND repositoryid = :repoid', $params);
+ if (!$refid) {
+ return $newreference;
+ }
+ $existingrefid = $DB->get_field_sql('SELECT id FROM {files_reference}
+ WHERE reference = :newreference AND referencehash = :newhash
+ AND repositoryid = :repoid', $params);
+ if ($existingrefid) {
+ // The same reference already exists, we unlink all files from it,
+ // link them to the current reference and remove the old one.
+ $DB->execute('UPDATE {files} SET referencefileid = :refid
+ WHERE referencefileid = :existingrefid',
+ array('refid' => $refid, 'existingrefid' => $existingrefid));
+ $DB->delete_records('files_reference', array('id' => $existingrefid));
+ }
+ // Update the reference.
+ $params['refid'] = $refid;
+ $DB->execute('UPDATE {files_reference}
+ SET reference = :newreference, referencehash = :newhash
+ WHERE id = :refid', $params);
+ }
+ return $newreference;
+ }
+
+ /**
+ * Converts a URL received from dropbox API function 'shares' into URL that
+ * can be used to download/access file directly
+ *
+ * @param string $sharedurl
+ * @return string
+ */
+ private function get_file_download_link($sharedurl) {
+ $url = new \moodle_url($sharedurl);
+ $url->param('dl', 1);
+
+ return $url->out(false);
+ }
+
+ /**
+ * Downloads a file from external repository and saves it in temp dir
+ *
+ * @throws moodle_exception when file could not be downloaded
+ *
+ * @param string $reference the content of files.reference field or result of
+ * function {@link repository_dropbox::get_file_reference()}
+ * @param string $saveas filename (without path) to save the downloaded file in the
+ * temporary directory, if omitted or file already exists the new filename will be generated
+ * @return array with elements:
+ * path: internal location of the file
+ * url: URL to the source (from parameters)
+ */
+ public function get_file($reference, $saveas = '') {
+ global $CFG;
+ $ref = unserialize($reference);
+ $saveas = $this->prepare_file($saveas);
+ if (isset($ref->access_key) && isset($ref->access_secret) && isset($ref->path)) {
+ $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
+ return $this->dropbox->get_file($ref->path, $saveas, $CFG->repositorygetfiletimeout);
+ } else if (isset($ref->url)) {
+ $c = new curl;
+ $url = $this->get_file_download_link($ref->url);
+ $result = $c->download_one($url, null, array('filepath' => $saveas, 'timeout' => $CFG->repositorygetfiletimeout, 'followlocation' => true));
+ $info = $c->get_info();
+ if ($result !== true || !isset($info['http_code']) || $info['http_code'] != 200) {
+ throw new moodle_exception('errorwhiledownload', 'repository', '', $result);
+ }
+ return array('path' => $saveas, 'url' => $url);
+ }
+ throw new moodle_exception('cannotdownload', 'repository');
+ }
+
+ /**
+ * Dropbox plugin supports all kinds of files
+ *
+ * @return array
+ */
+ public function supported_filetypes() {
+ return '*';
+ }
+
+ /**
+ * User cannot use the external link to dropbox
+ *
+ * @return int
+ */
+ public function supported_returntypes() {
+ return FILE_INTERNAL | FILE_REFERENCE | FILE_EXTERNAL;
+ }
+
+ /**
+ * Return file URL for external link
+ *
+ * @param string $reference the result of get_file_reference()
+ * @return string
+ */
+ public function get_link($reference) {
+ global $CFG;
+ $ref = unserialize($reference);
+ if (!isset($ref->url)) {
+ $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
+ $ref->url = $this->dropbox->get_file_share_link($ref->path, $CFG->repositorygetfiletimeout);
+ }
+ return $this->get_file_download_link($ref->url);
+ }
+
+ /**
+ * Prepare file reference information
+ *
+ * @param string $source
+ * @return string file referece
+ */
+ public function get_file_reference($source) {
+ global $USER, $CFG;
+ $reference = new stdClass;
+ $reference->path = $source;
+ $reference->userid = $USER->id;
+ $reference->username = fullname($USER);
+ $reference->access_key = get_user_preferences($this->setting.'_access_key', '');
+ $reference->access_secret = get_user_preferences($this->setting.'_access_secret', '');
+
+ // By API we don't know if we need this reference to just download a file from dropbox
+ // into moodle filepool or create a reference. Since we need to create a shared link
+ // only in case of reference we analyze the script parameter.
+ $usefilereference = optional_param('usefilereference', false, PARAM_BOOL);
+ if ($usefilereference) {
+ $this->dropbox->set_access_token($reference->access_key, $reference->access_secret);
+ $url = $this->dropbox->get_file_share_link($source, $CFG->repositorygetfiletimeout);
+ if ($url) {
+ unset($reference->access_key);
+ unset($reference->access_secret);
+ $reference->url = $url;
+ }
+ }
+ return serialize($reference);
+ }
+
+ public function sync_reference(stored_file $file) {
+ global $CFG;
+
+ if ($file->get_referencelastsync() + DAYSECS > time()) {
+ // Synchronise not more often than once a day.
+ return false;
+ }
+ $ref = unserialize($file->get_reference());
+ if (!isset($ref->url)) {
+ // This is an old-style reference in DB. We need to fix it.
+ $ref = unserialize($this->fix_old_style_reference($file->get_reference()));
+ }
+ if (!isset($ref->url)) {
+ return false;
+ }
+ $c = new curl;
+ $url = $this->get_file_download_link($ref->url);
+ if (file_extension_in_typegroup($ref->path, 'web_image')) {
+ $saveas = $this->prepare_file('');
+ try {
+ $result = $c->download_one($url, array(), array('filepath' => $saveas, 'timeout' => $CFG->repositorysyncimagetimeout, 'followlocation' => true));
+ $info = $c->get_info();
+ if ($result === true && isset($info['http_code']) && $info['http_code'] == 200) {
+ $fs = get_file_storage();
+ list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($saveas);
+ $file->set_synchronized($contenthash, $filesize);
+ return true;
+ }
+ } catch (Exception $e) {
+ }
+ }
+ $c->get($url, null, array('timeout' => $CFG->repositorysyncimagetimeout, 'followlocation' => true, 'nobody' => true));
+ $info = $c->get_info();
+ if (isset($info['http_code']) && $info['http_code'] == 200 &&
+ array_key_exists('download_content_length', $info) &&
+ $info['download_content_length'] >= 0) {
+ $filesize = (int)$info['download_content_length'];
+ $file->set_synchronized(null, $filesize);
+ return true;
+ }
+ $file->set_missingsource();
+ return true;
+ }
+
+ /**
+ * Cache file from external repository by reference.
+ *
+ * Dropbox repository regularly caches all external files that are smaller than
+ * {@link repository_dropbox::max_cache_bytes()}
+ *
+ * @param string $reference this reference is generated by
+ * repository::get_file_reference()
+ * @param stored_file $storedfile created file reference
+ */
+ public function cache_file_by_reference($reference, $storedfile) {
+ try {
+ $this->import_external_file_contents($storedfile, $this->max_cache_bytes());
+ } catch (Exception $e) {
+ }
+ }
+
+ /**
+ * Return human readable reference information.
+ * {@link stored_file::get_reference()}
+ *
+ * @param string $reference
+ * @param int $filestatus status of the file, 0 - ok, 666 - source missing
+ * @return string
+ */
+ public function get_reference_details($reference, $filestatus = 0) {
+ global $USER;
+ $ref = unserialize($reference);
+ $detailsprefix = $this->get_name();
+ if (isset($ref->userid) && $ref->userid != $USER->id && isset($ref->username)) {
+ $detailsprefix .= ' ('.$ref->username.')';
+ }
+ $details = $detailsprefix;
+ if (isset($ref->path)) {
+ $details .= ': '. $ref->path;
+ }
+ if (isset($ref->path) && !$filestatus) {
+ // Indicate this is from dropbox with path.
+ return $details;
+ } else {
+ if (isset($ref->url)) {
+ $details = $detailsprefix. ': '. $ref->url;
+ }
+ return get_string('lostsource', 'repository', $details);
+ }
+ }
+
+ /**
+ * Return the source information
+ *
+ * @param string $source
+ * @return string
+ */
+ public function get_file_source_info($source) {
+ global $USER;
+ return 'Dropbox ('.fullname($USER).'): ' . $source;
+ }
+
+ /**
+ * Repository method to serve the referenced file
+ *
+ * This method is ivoked from {@link send_stored_file()}.
+ * Dropbox repository first caches the file by reading it into temporary folder and then
+ * serves from there.
+ *
+ * @param stored_file $storedfile the file that contains the reference
+ * @param int $lifetime Number of seconds before the file should expire from caches (null means $CFG->filelifetime)
+ * @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=null , $filter=0, $forcedownload=false, array $options = null) {
+ $ref = unserialize($storedfile->get_reference());
+ if ($storedfile->get_filesize() > $this->max_cache_bytes()) {
+ header('Location: '.$this->get_file_download_link($ref->url));
+ die;
+ }
+ try {
+ $this->import_external_file_contents($storedfile, $this->max_cache_bytes());
+ if (!is_array($options)) {
+ $options = array();
+ }
+ $options['sendcachedexternalfile'] = true;
+ send_stored_file($storedfile, $lifetime, $filter, $forcedownload, $options);
+ } catch (moodle_exception $e) {
+ // Redirect to Dropbox, it will show the error.
+ // We redirect to Dropbox shared link, not to download link here!
+ header('Location: '.$ref->url);
+ die;
+ }
+ }
+
+ /**
+ * Returns the maximum size of the Dropbox files to cache in moodle.
+ *
+ * Note that {@link repository_dropbox::sync_reference()} will try to cache images even
+ * when they are bigger in order to generate thumbnails. However there is
+ * a small timeout for downloading images for synchronisation and it will
+ * probably fail if the image is too big.
+ *
+ * @return int
+ */
+ public function max_cache_bytes() {
+ if ($this->cachelimit === null) {
+ $this->cachelimit = (int) get_config('dropbox', 'dropbox_cachelimit');
+ }
+ return $this->cachelimit;
+ }
+
+ /**
+ * Caches all references to Dropbox files in moodle filepool
+ *
+ * Invoked by {@link repository_dropbox_cron()}. Only files smaller than
+ * {@link repository_dropbox::max_cache_bytes()} and only files which
+ * synchronisation timeout have not expired are cached.
+ */
+ public function cron() {
+ $fs = get_file_storage();
+ $files = $fs->get_external_files($this->id);
+ $fetchedreferences = [];
+ foreach ($files as $file) {
+ if (isset($fetchedreferences[$file->get_referencefileid()])) {
+ continue;
+ }
+ try {
+ // This call will cache all files that are smaller than max_cache_bytes()
+ // and synchronise file size of all others
+ $this->import_external_file_contents($file, $this->max_cache_bytes());
+ $fetchedreferences[$file->get_referencefileid()] = true;
+ } catch (moodle_exception $e) {}
+ }
+ }
+}
diff --git a/repository/dropbox/locallib.php b/repository/dropbox/classes/legacy_dropbox.php
similarity index 98%
rename from repository/dropbox/locallib.php
rename to repository/dropbox/classes/legacy_dropbox.php
index d376685558b..5cfb5183081 100644
--- a/repository/dropbox/locallib.php
+++ b/repository/dropbox/classes/legacy_dropbox.php
@@ -35,7 +35,7 @@ require_once($CFG->libdir.'/oauthlib.php');
* @copyright 2010 Dongsheng Cai
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-class dropbox extends oauth_helper {
+class repository_dropbox_legacy_dropbox extends oauth_helper {
/** @var string dropbox access type, can be dropbox or sandbox */
private $mode = 'dropbox';
/** @var string dropbox api url*/
diff --git a/repository/dropbox/lib.php b/repository/dropbox/lib.php
index 46611afa177..f96be02e811 100644
--- a/repository/dropbox/lib.php
+++ b/repository/dropbox/lib.php
@@ -24,7 +24,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->dirroot . '/repository/lib.php');
-require_once(dirname(__FILE__).'/locallib.php');
/**
* Repository to access Dropbox files
@@ -34,419 +33,214 @@ require_once(dirname(__FILE__).'/locallib.php');
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class repository_dropbox extends repository {
- /** @var dropbox the instance of dropbox client */
- private $dropbox;
- /** @var array files */
- public $files;
- /** @var bool flag of login status */
- public $logged=false;
- /** @var int maximum size of file to cache in moodle filepool */
- public $cachelimit=null;
-
- /** @var int cached file ttl */
- private $cachedfilettl = null;
+ /**
+ * @var int The maximum file size to cache in the moodle filepool.
+ */
+ public $cachelimit = null;
/**
- * Constructor of dropbox plugin
- *
- * @param int $repositoryid
- * @param stdClass $context
- * @param array $options
+ * @var repository The actual repository.
*/
- public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
- global $CFG;
- $options['page'] = optional_param('p', 1, PARAM_INT);
+ protected $legacy;
+
+ /**
+ * Constructor of dropbox plugin.
+ *
+ * @inheritDocs
+ */
+ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = []) {
+ $this->legacy = new repository_dropbox_legacy($repositoryid, $context, $options);
+
parent::__construct($repositoryid, $context, $options);
-
- $this->setting = 'dropbox_';
-
- $this->dropbox_key = $this->get_option('dropbox_key');
- $this->dropbox_secret = $this->get_option('dropbox_secret');
-
- // one day
- $this->cachedfilettl = 60 * 60 * 24;
-
- if (isset($options['access_key'])) {
- $this->access_key = $options['access_key'];
- } else {
- $this->access_key = get_user_preferences($this->setting.'_access_key', '');
- }
- if (isset($options['access_secret'])) {
- $this->access_secret = $options['access_secret'];
- } else {
- $this->access_secret = get_user_preferences($this->setting.'_access_secret', '');
- }
-
- if (!empty($this->access_key) && !empty($this->access_secret)) {
- $this->logged = true;
- }
-
- $callbackurl = new moodle_url($CFG->wwwroot.'/repository/repository_callback.php', array(
- 'callback'=>'yes',
- 'repo_id'=>$repositoryid
- ));
-
- $args = array(
- 'oauth_consumer_key'=>$this->dropbox_key,
- 'oauth_consumer_secret'=>$this->dropbox_secret,
- 'oauth_callback' => $callbackurl->out(false),
- 'api_root' => 'https://api.dropbox.com/1/oauth',
- );
-
- $this->dropbox = new dropbox($args);
}
/**
- * Set access key
+ * Repository method to serve the referenced file.
*
- * @param string $access_key
+ * @inheritDocs
*/
- public function set_access_key($access_key) {
- $this->access_key = $access_key;
+ public function send_file($storedfile, $lifetime=null , $filter=0, $forcedownload=false, array $options = null) {
+ return $this->legacy->send_file($storedfile, $lifetime, $filter, $forcedownload, $options);
}
/**
- * Set access secret
+ * Return human readable reference information.
+ * {@link stored_file::get_reference()}
*
- * @param string $access_secret
+ * @inheritDocs
*/
- public function set_access_secret($access_secret) {
- $this->access_secret = $access_secret;
+ public function get_reference_details($reference, $filestatus = 0) {
+ return $this->legacy->get_reference_details($reference, $filestatus);
}
-
/**
- * Check if moodle has got access token and secret
+ * Cache file from external repository by reference.
+ * {@link repository::get_file_reference()}
+ * {@link repository::get_file()}
+ * Invoked at MOODLE/repository/repository_ajax.php.
*
- * @return bool
+ * @inheritDocs
*/
- public function check_login() {
- return !empty($this->logged);
+ public function cache_file_by_reference($reference, $storedfile) {
+ return $this->legacy->cache_file_by_reference($reference, $storedfile);
}
/**
- * Generate dropbox login url
+ * Return the source information.
*
- * @return array
- */
- public function print_login() {
- $result = $this->dropbox->request_token();
- set_user_preference($this->setting.'_request_secret', $result['oauth_token_secret']);
- $url = $result['authorize_url'];
- if ($this->options['ajax']) {
- $ret = array();
- $popup_btn = new stdClass();
- $popup_btn->type = 'popup';
- $popup_btn->url = $url;
- $ret['login'] = array($popup_btn);
- return $ret;
- } else {
- echo ''.get_string('login', 'repository').'';
- }
- }
-
- /**
- * Request access token
+ * The result of the function is stored in files.source field. It may be analysed
+ * when the source file is lost or repository may use it to display human-readable
+ * location of reference original.
*
- * @return array
- */
- public function callback() {
- $token = optional_param('oauth_token', '', PARAM_TEXT);
- $secret = get_user_preferences($this->setting.'_request_secret', '');
- $access_token = $this->dropbox->get_access_token($token, $secret);
- set_user_preference($this->setting.'_access_key', $access_token['oauth_token']);
- set_user_preference($this->setting.'_access_secret', $access_token['oauth_token_secret']);
- }
-
- /**
- * Get dropbox files
+ * This method is called when file is picked for the first time only. When file
+ * (either copy or a reference) is already in moodle and it is being picked
+ * again to another file area (also as a copy or as a reference), the value of
+ * files.source is copied.
*
- * @param string $path
- * @param int $page
- * @return array
+ * @inheritDocs
*/
- public function get_listing($path = '', $page = '1') {
- global $OUTPUT;
- if (empty($path) || $path=='/') {
- $path = '/';
- } else {
- $path = file_correct_filepath($path);
- }
- $encoded_path = str_replace("%2F", "/", rawurlencode($path));
-
- $list = array();
- $list['list'] = array();
- $list['manage'] = 'https://www.dropbox.com/home';
- $list['dynload'] = true;
- $list['nosearch'] = true;
- $list['logouturl'] = 'https://www.dropbox.com/logout';
- $list['message'] = get_string('logoutdesc', 'repository_dropbox');
- // process breadcrumb trail
- $list['path'] = array(
- array('name'=>get_string('dropbox', 'repository_dropbox'), 'path'=>'/')
- );
-
- $result = $this->dropbox->get_listing($encoded_path, $this->access_key, $this->access_secret);
-
- if (!is_object($result) || empty($result)) {
- return $list;
- }
- if (empty($result->path)) {
- $current_path = '/';
- } else {
- $current_path = file_correct_filepath($result->path);
- }
-
- $trail = '';
- if (!empty($path)) {
- $parts = explode('/', $path);
- if (count($parts) > 1) {
- foreach ($parts as $part) {
- if (!empty($part)) {
- $trail .= ('/'.$part);
- $list['path'][] = array('name'=>$part, 'path'=>$trail);
- }
- }
- } else {
- $list['path'][] = array('name'=>$path, 'path'=>$path);
- }
- }
-
- if (!empty($result->error)) {
- // reset access key
- set_user_preference($this->setting.'_access_key', '');
- set_user_preference($this->setting.'_access_secret', '');
- throw new repository_exception('repositoryerror', 'repository', '', $result->error);
- }
- if (empty($result->contents) or !is_array($result->contents)) {
- return $list;
- }
- $files = $result->contents;
- $dirslist = array();
- $fileslist = array();
- foreach ($files as $file) {
- if ($file->is_dir) {
- $dirslist[] = array(
- 'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
- 'path' => file_correct_filepath($file->path),
- 'date' => strtotime($file->modified),
- 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(64))->out(false),
- 'thumbnail_height' => 64,
- 'thumbnail_width' => 64,
- 'children' => array(),
- );
- } else {
- $thumbnail = null;
- if ($file->thumb_exists) {
- $thumburl = new moodle_url('/repository/dropbox/thumbnail.php',
- array('repo_id' => $this->id,
- 'ctx_id' => $this->context->id,
- 'source' => $file->path,
- 'rev' => $file->rev // include revision to avoid cache problems
- ));
- $thumbnail = $thumburl->out(false);
- }
- $fileslist[] = array(
- 'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
- 'source' => $file->path,
- 'size' => $file->bytes,
- 'date' => strtotime($file->modified),
- 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->path, 64))->out(false),
- 'realthumbnail' => $thumbnail,
- 'thumbnail_height' => 64,
- 'thumbnail_width' => 64,
- );
- }
- }
- $fileslist = array_filter($fileslist, array($this, 'filter'));
- $list['list'] = array_merge($dirslist, array_values($fileslist));
- return $list;
+ public function get_file_source_info($source) {
+ return $this->legacy->get_file_source_info($source);
}
/**
- * Displays a thumbnail for current user's dropbox file
+ * Prepare file reference information.
*
- * @param string $string
+ * @inheritDocs
*/
- public function send_thumbnail($source) {
- global $CFG;
- $saveas = $this->prepare_file('');
- try {
- $access_key = get_user_preferences($this->setting.'_access_key', '');
- $access_secret = get_user_preferences($this->setting.'_access_secret', '');
- $this->dropbox->set_access_token($access_key, $access_secret);
- $this->dropbox->get_thumbnail($source, $saveas, $CFG->repositorysyncimagetimeout);
- $content = file_get_contents($saveas);
- unlink($saveas);
- // set 30 days lifetime for the image. If the image is changed in dropbox it will have
- // different revision number and URL will be different. It is completely safe
- // to cache thumbnail in the browser for a long time
- send_file($content, basename($source), 30*24*60*60, 0, true);
- } catch (Exception $e) {}
+ public function get_file_reference($source) {
+ return $this->legacy->get_file_reference($source);
}
/**
- * Logout from dropbox
- * @return array
- */
- public function logout() {
- set_user_preference($this->setting.'_access_key', '');
- set_user_preference($this->setting.'_access_secret', '');
- $this->access_key = '';
- $this->access_secret = '';
- return $this->print_login();
- }
-
- /**
- * Set dropbox option
- * @param array $options
- * @return mixed
- */
- public function set_option($options = array()) {
- if (!empty($options['dropbox_key'])) {
- set_config('dropbox_key', trim($options['dropbox_key']), 'dropbox');
- }
- if (!empty($options['dropbox_secret'])) {
- set_config('dropbox_secret', trim($options['dropbox_secret']), 'dropbox');
- }
- if (!empty($options['dropbox_cachelimit'])) {
- $this->cachelimit = (int)trim($options['dropbox_cachelimit']);
- set_config('dropbox_cachelimit', $this->cachelimit, 'dropbox');
- }
- unset($options['dropbox_key']);
- unset($options['dropbox_secret']);
- unset($options['dropbox_cachelimit']);
- $ret = parent::set_option($options);
- return $ret;
- }
-
- /**
- * Get dropbox options
- * @param string $config
- * @return mixed
- */
- public function get_option($config = '') {
- if ($config==='dropbox_key') {
- return trim(get_config('dropbox', 'dropbox_key'));
- } elseif ($config==='dropbox_secret') {
- return trim(get_config('dropbox', 'dropbox_secret'));
- } elseif ($config==='dropbox_cachelimit') {
- return $this->max_cache_bytes();
- } else {
- $options = parent::get_option();
- $options['dropbox_key'] = trim(get_config('dropbox', 'dropbox_key'));
- $options['dropbox_secret'] = trim(get_config('dropbox', 'dropbox_secret'));
- $options['dropbox_cachelimit'] = $this->max_cache_bytes();
- }
- return $options;
- }
-
- /**
- * Fixes references in DB that contains user credentials
+ * Return file URL for external link.
*
- * @param string $reference contents of DB field files_reference.reference
+ * @inheritDocs
*/
- public function fix_old_style_reference($reference) {
- global $CFG;
- $ref = unserialize($reference);
- if (!isset($ref->url)) {
- $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
- $ref->url = $this->dropbox->get_file_share_link($ref->path, $CFG->repositorygetfiletimeout);
- if (!$ref->url) {
- // some error occurred, do not fix reference for now
- return $reference;
- }
- }
- unset($ref->access_key);
- unset($ref->access_secret);
- $newreference = serialize($ref);
- if ($newreference !== $reference) {
- // we need to update references in the database
- global $DB;
- $params = array(
- 'newreference' => $newreference,
- 'newhash' => sha1($newreference),
- 'reference' => $reference,
- 'hash' => sha1($reference),
- 'repoid' => $this->id
- );
- $refid = $DB->get_field_sql('SELECT id FROM {files_reference}
- WHERE reference = :reference AND referencehash = :hash
- AND repositoryid = :repoid', $params);
- if (!$refid) {
- return $newreference;
- }
- $existingrefid = $DB->get_field_sql('SELECT id FROM {files_reference}
- WHERE reference = :newreference AND referencehash = :newhash
- AND repositoryid = :repoid', $params);
- if ($existingrefid) {
- // the same reference already exists, we unlink all files from it,
- // link them to the current reference and remove the old one
- $DB->execute('UPDATE {files} SET referencefileid = :refid
- WHERE referencefileid = :existingrefid',
- array('refid' => $refid, 'existingrefid' => $existingrefid));
- $DB->delete_records('files_reference', array('id' => $existingrefid));
- }
- // update the reference
- $params['refid'] = $refid;
- $DB->execute('UPDATE {files_reference}
- SET reference = :newreference, referencehash = :newhash
- WHERE id = :refid', $params);
- }
- return $newreference;
+ public function get_link($reference) {
+ return $this->legacy->get_link($reference);
}
/**
- * Converts a URL received from dropbox API function 'shares' into URL that
- * can be used to download/access file directly
+ * Downloads a file from external repository and saves it in temp dir.
*
- * @param string $sharedurl
- * @return string
- */
- private function get_file_download_link($sharedurl) {
- return preg_replace('|^(\w*://)www(.dropbox.com)|','\1dl\2',$sharedurl);
- }
-
- /**
- * Downloads a file from external repository and saves it in temp dir
- *
- * @throws moodle_exception when file could not be downloaded
- *
- * @param string $reference the content of files.reference field or result of
- * function {@link repository_dropbox::get_file_reference()}
- * @param string $saveas filename (without path) to save the downloaded file in the
- * temporary directory, if omitted or file already exists the new filename will be generated
- * @return array with elements:
- * path: internal location of the file
- * url: URL to the source (from parameters)
+ * @inheritDocs
*/
public function get_file($reference, $saveas = '') {
- global $CFG;
- $ref = unserialize($reference);
- $saveas = $this->prepare_file($saveas);
- if (isset($ref->access_key) && isset($ref->access_secret) && isset($ref->path)) {
- $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
- return $this->dropbox->get_file($ref->path, $saveas, $CFG->repositorygetfiletimeout);
- } else if (isset($ref->url)) {
- $c = new curl;
- $url = $this->get_file_download_link($ref->url);
- $result = $c->download_one($url, null, array('filepath' => $saveas, 'timeout' => $CFG->repositorygetfiletimeout, 'followlocation' => true));
- $info = $c->get_info();
- if ($result !== true || !isset($info['http_code']) || $info['http_code'] != 200) {
- throw new moodle_exception('errorwhiledownload', 'repository', '', $result);
- }
- return array('path'=>$saveas, 'url'=>$url);
- }
- throw new moodle_exception('cannotdownload', 'repository');
+ return $this->legacy->get_file($reference, $saveas);
+ }
+
+ /**
+ * Dropbox plugin supports all kinds of files.
+ *
+ * @inheritDocs
+ */
+ public function supported_filetypes() {
+ return $this->legacy->supported_filetypes();
+ }
+
+ /**
+ * User cannot use the external link to dropbox.
+ *
+ * @inheritDocs
+ */
+ public function supported_returntypes() {
+ return $this->legacy->supported_returntypes();
+ }
+
+ /**
+ * Get dropbox files.
+ *
+ * @inheritDocs
+ */
+ public function get_listing($path = '', $page = '1') {
+ return $this->legacy->get_listing($path, $page);
+ }
+
+ /**
+ * Get dropbox files in the specified path.
+ *
+ * @param string $query The search query
+ * @param int $page The page number
+ * @return array
+ */
+ public function search($query, $page = 0) {
+ return parent::search($query, $page);
+ }
+
+ /**
+ * Displays a thumbnail for current user's dropbox file.
+ *
+ * @inheritDocs
+ */
+ public function send_thumbnail($source) {
+ return $this->legacy->send_thumbnail($source);
+ }
+
+ /**
+ * Fixes references in DB that contains user credentials.
+ *
+ * @param string $packed Content of DB field files_reference.reference
+ * @return string New serialized reference
+ */
+ protected function fix_old_style_reference($packed) {
+ return $this->legacy->fix_old_style_reference($packed);
}
/**
- * Add Plugin settings input to Moodle form
+ * Logout from dropbox.
*
- * @param moodleform $mform Moodle form (passed by reference)
- * @param string $classname repository class name
+ * @inheritDocs
+ */
+ public function logout() {
+ return $this->legacy->logout();
+ }
+
+ /**
+ * Check if moodle has got access token and secret.
+ *
+ * @inheritDocs
+ */
+ public function check_login() {
+ return $this->legacy->check_login();
+ }
+
+ /**
+ * Generate dropbox login url.
+ *
+ * @inheritDocs
+ */
+ public function print_login() {
+ return $this->legacy->print_login();
+ }
+
+ /**
+ * Request access token.
+ *
+ * @inheritDocs
+ */
+ public function callback() {
+ return $this->legacy->callback();
+ }
+
+ /**
+ * Caches all references to Dropbox files in moodle filepool.
+ *
+ * Invoked by {@link repository_dropbox_cron()}. Only files smaller than
+ * {@link repository_dropbox::max_cache_bytes()} and only files which
+ * synchronisation timeout have not expired are cached.
+ *
+ * @inheritDocs
+ */
+ public function cron() {
+ return $this->legacy->cron();
+ }
+
+ /**
+ * Add Plugin settings input to Moodle form.
+ *
+ * @inheritDocs
*/
public static function type_config_form($mform, $classname = 'repository') {
- global $CFG;
parent::type_config_form($mform);
$key = get_config('dropbox', 'dropbox_key');
$secret = get_config('dropbox', 'dropbox_secret');
@@ -458,200 +252,116 @@ class repository_dropbox extends repository {
$secret = '';
}
- $strrequired = get_string('required');
-
$mform->addElement('text', 'dropbox_key', get_string('apikey', 'repository_dropbox'), array('value'=>$key,'size' => '40'));
$mform->setType('dropbox_key', PARAM_RAW_TRIMMED);
$mform->addElement('text', 'dropbox_secret', get_string('secret', 'repository_dropbox'), array('value'=>$secret,'size' => '40'));
- $mform->addRule('dropbox_key', $strrequired, 'required', null, 'client');
- $mform->addRule('dropbox_secret', $strrequired, 'required', null, 'client');
+ $mform->addRule('dropbox_key', get_string('required'), 'required', null, 'client');
+ $mform->addRule('dropbox_secret', get_string('required'), 'required', null, 'client');
$mform->setType('dropbox_secret', PARAM_RAW_TRIMMED);
- $str_getkey = get_string('instruction', 'repository_dropbox');
- $mform->addElement('static', null, '', $str_getkey);
+ $mform->addElement('static', null, '', get_string('instruction', 'repository_dropbox'));
$mform->addElement('text', 'dropbox_cachelimit', get_string('cachelimit', 'repository_dropbox'), array('size' => '40'));
$mform->addRule('dropbox_cachelimit', null, 'numeric', null, 'client');
$mform->setType('dropbox_cachelimit', PARAM_INT);
$mform->addElement('static', 'dropbox_cachelimit_info', '', get_string('cachelimit_info', 'repository_dropbox'));
+
}
/**
- * Option names of dropbox plugin
+ * Set options.
*
- * @return array
+ * @param array $options
+ * @return mixed
+ */
+ public function set_option($options = []) {
+ if (!empty($options['dropbox_key'])) {
+ set_config('dropbox_key', trim($options['dropbox_key']), 'dropbox');
+ unset($options['dropbox_key']);
+ }
+ if (!empty($options['dropbox_secret'])) {
+ set_config('dropbox_secret', trim($options['dropbox_secret']), 'dropbox');
+ unset($options['dropbox_secret']);
+ }
+ if (!empty($options['dropbox_cachelimit'])) {
+ $this->cachelimit = (int) trim($options['dropbox_cachelimit']);
+ set_config('dropbox_cachelimit', $this->cachelimit, 'dropbox');
+ unset($options['dropbox_cachelimit']);
+ }
+
+ return parent::set_option($options);
+ }
+
+ /**
+ * Get dropbox options
+ * @param string $config
+ * @return mixed
+ */
+ public function get_option($config = '') {
+ if ($config === 'dropbox_key') {
+ return trim(get_config('dropbox', 'dropbox_key'));
+ } else if ($config === 'dropbox_secret') {
+ return trim(get_config('dropbox', 'dropbox_secret'));
+ } else if ($config === 'dropbox_cachelimit') {
+ return $this->max_cache_bytes();
+ } else {
+ $options = parent::get_option();
+ $options['dropbox_key'] = trim(get_config('dropbox', 'dropbox_key'));
+ $options['dropbox_secret'] = trim(get_config('dropbox', 'dropbox_secret'));
+ $options['dropbox_cachelimit'] = $this->max_cache_bytes();
+ }
+
+ return $options;
+ }
+
+ /**
+ * Option names of dropbox plugin.
+ *
+ * @inheritDocs
*/
public static function get_type_option_names() {
- return array('dropbox_key', 'dropbox_secret', 'pluginname', 'dropbox_cachelimit');
+ return [
+ 'dropbox_key',
+ 'dropbox_secret',
+ 'pluginname',
+ 'dropbox_cachelimit',
+ ];
}
/**
- * Dropbox plugin supports all kinds of files
+ * Performs synchronisation of an external file if the previous one has expired.
*
- * @return array
- */
- public function supported_filetypes() {
- return '*';
- }
-
- /**
- * User cannot use the external link to dropbox
+ * This function must be implemented for external repositories supporting
+ * FILE_REFERENCE, it is called for existing aliases when their filesize,
+ * contenthash or timemodified are requested. It is not called for internal
+ * repositories (see {@link repository::has_moodle_files()}), references to
+ * internal files are updated immediately when source is modified.
*
- * @return int
- */
- public function supported_returntypes() {
- return FILE_INTERNAL | FILE_REFERENCE | FILE_EXTERNAL;
- }
-
- /**
- * Return file URL for external link
+ * Referenced files may optionally keep their content in Moodle filepool (for
+ * thumbnail generation or to be able to serve cached copy). In this
+ * case both contenthash and filesize need to be synchronized. Otherwise repositories
+ * should use contenthash of empty file and correct filesize in bytes.
*
- * @param string $reference the result of get_file_reference()
- * @return string
- */
- public function get_link($reference) {
- global $CFG;
- $ref = unserialize($reference);
- if (!isset($ref->url)) {
- $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
- $ref->url = $this->dropbox->get_file_share_link($ref->path, $CFG->repositorygetfiletimeout);
- }
- return $this->get_file_download_link($ref->url);
- }
-
- /**
- * Prepare file reference information
+ * Note that this function may be run for EACH file that needs to be synchronised at the
+ * moment. If anything is being downloaded or requested from external sources there
+ * should be a small timeout. The synchronisation is performed to update the size of
+ * the file and/or to update image and re-generated image preview. There is nothing
+ * fatal if syncronisation fails but it is fatal if syncronisation takes too long
+ * and hangs the script generating a page.
*
- * @param string $source
- * @return string file referece
+ * Note: If you wish to call $file->get_filesize(), $file->get_contenthash() or
+ * $file->get_timemodified() make sure that recursion does not happen.
+ *
+ * Called from {@link stored_file::sync_external_file()}
+ *
+ * @inheritDocs
*/
- public function get_file_reference($source) {
- global $USER, $CFG;
- $reference = new stdClass;
- $reference->path = $source;
- $reference->userid = $USER->id;
- $reference->username = fullname($USER);
- $reference->access_key = get_user_preferences($this->setting.'_access_key', '');
- $reference->access_secret = get_user_preferences($this->setting.'_access_secret', '');
-
- // by API we don't know if we need this reference to just download a file from dropbox
- // into moodle filepool or create a reference. Since we need to create a shared link
- // only in case of reference we analyze the script parameter
- $usefilereference = optional_param('usefilereference', false, PARAM_BOOL);
- if ($usefilereference) {
- $this->dropbox->set_access_token($reference->access_key, $reference->access_secret);
- $url = $this->dropbox->get_file_share_link($source, $CFG->repositorygetfiletimeout);
- if ($url) {
- unset($reference->access_key);
- unset($reference->access_secret);
- $reference->url = $url;
- }
- }
- return serialize($reference);
- }
-
public function sync_reference(stored_file $file) {
- global $CFG;
-
- if ($file->get_referencelastsync() + DAYSECS > time()) {
- // Synchronise not more often than once a day.
- return false;
- }
- $ref = unserialize($file->get_reference());
- if (!isset($ref->url)) {
- // this is an old-style reference in DB. We need to fix it
- $ref = unserialize($this->fix_old_style_reference($file->get_reference()));
- }
- if (!isset($ref->url)) {
- return false;
- }
- $c = new curl;
- $url = $this->get_file_download_link($ref->url);
- if (file_extension_in_typegroup($ref->path, 'web_image')) {
- $saveas = $this->prepare_file('');
- try {
- $result = $c->download_one($url, array(), array('filepath' => $saveas, 'timeout' => $CFG->repositorysyncimagetimeout, 'followlocation' => true));
- $info = $c->get_info();
- if ($result === true && isset($info['http_code']) && $info['http_code'] == 200) {
- $fs = get_file_storage();
- list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($saveas);
- $file->set_synchronized($contenthash, $filesize);
- return true;
- }
- } catch (Exception $e) {}
- }
- $c->get($url, null, array('timeout' => $CFG->repositorysyncimagetimeout, 'followlocation' => true, 'nobody' => true));
- $info = $c->get_info();
- if (isset($info['http_code']) && $info['http_code'] == 200 &&
- array_key_exists('download_content_length', $info) &&
- $info['download_content_length'] >= 0) {
- $filesize = (int)$info['download_content_length'];
- $file->set_synchronized(null, $filesize);
- return true;
- }
- $file->set_missingsource();
- return true;
+ return $this->legacy->sync_reference($file);
}
/**
- * Cache file from external repository by reference
- *
- * Dropbox repository regularly caches all external files that are smaller than
- * {@link repository_dropbox::max_cache_bytes()}
- *
- * @param string $reference this reference is generated by
- * repository::get_file_reference()
- * @param stored_file $storedfile created file reference
- */
- public function cache_file_by_reference($reference, $storedfile) {
- try {
- $this->import_external_file_contents($storedfile, $this->max_cache_bytes());
- } catch (Exception $e) {}
- }
-
- /**
- * Return human readable reference information
- * {@link stored_file::get_reference()}
- *
- * @param string $reference
- * @param int $filestatus status of the file, 0 - ok, 666 - source missing
- * @return string
- */
- public function get_reference_details($reference, $filestatus = 0) {
- global $USER;
- $ref = unserialize($reference);
- $detailsprefix = $this->get_name();
- if (isset($ref->userid) && $ref->userid != $USER->id && isset($ref->username)) {
- $detailsprefix .= ' ('.$ref->username.')';
- }
- $details = $detailsprefix;
- if (isset($ref->path)) {
- $details .= ': '. $ref->path;
- }
- if (isset($ref->path) && !$filestatus) {
- // Indicate this is from dropbox with path
- return $details;
- } else {
- if (isset($ref->url)) {
- $details = $detailsprefix. ': '. $ref->url;
- }
- return get_string('lostsource', 'repository', $details);
- }
- }
-
- /**
- * Return the source information
- *
- * @param string $source
- * @return string
- */
- public function get_file_source_info($source) {
- global $USER;
- return 'Dropbox ('.fullname($USER).'): ' . $source;
- }
-
- /**
- * Returns the maximum size of the Dropbox files to cache in moodle
+ * Returns the maximum size of the Dropbox files to cache in moodle.
*
* Note that {@link repository_dropbox::sync_reference()} will try to cache images even
* when they are bigger in order to generate thumbnails. However there is
@@ -662,67 +372,14 @@ class repository_dropbox extends repository {
*/
public function max_cache_bytes() {
if ($this->cachelimit === null) {
- $this->cachelimit = (int)get_config('dropbox', 'dropbox_cachelimit');
+ $this->cachelimit = (int) get_config('dropbox', 'dropbox_cachelimit');
}
return $this->cachelimit;
}
-
- /**
- * Repository method to serve the referenced file
- *
- * This method is ivoked from {@link send_stored_file()}.
- * Dropbox repository first caches the file by reading it into temporary folder and then
- * serves from there.
- *
- * @param stored_file $storedfile the file that contains the reference
- * @param int $lifetime Number of seconds before the file should expire from caches (null means $CFG->filelifetime)
- * @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=null , $filter=0, $forcedownload=false, array $options = null) {
- $ref = unserialize($storedfile->get_reference());
- if ($storedfile->get_filesize() > $this->max_cache_bytes()) {
- header('Location: '.$this->get_file_download_link($ref->url));
- die;
- }
- try {
- $this->import_external_file_contents($storedfile, $this->max_cache_bytes());
- if (!is_array($options)) {
- $options = array();
- }
- $options['sendcachedexternalfile'] = true;
- send_stored_file($storedfile, $lifetime, $filter, $forcedownload, $options);
- } catch (moodle_exception $e) {
- // redirect to Dropbox, it will show the error.
- // We redirect to Dropbox shared link, not to download link here!
- header('Location: '.$ref->url);
- die;
- }
- }
-
- /**
- * Caches all references to Dropbox files in moodle filepool
- *
- * Invoked by {@link repository_dropbox_cron()}. Only files smaller than
- * {@link repository_dropbox::max_cache_bytes()} and only files which
- * synchronisation timeout have not expired are cached.
- */
- public function cron() {
- $fs = get_file_storage();
- $files = $fs->get_external_files($this->id);
- foreach ($files as $file) {
- try {
- // This call will cache all files that are smaller than max_cache_bytes()
- // and synchronise file size of all others
- $this->import_external_file_contents($file, $this->max_cache_bytes());
- } catch (moodle_exception $e) {}
- }
- }
}
/**
- * Dropbox plugin cron task
+ * Dropbox plugin cron task.
*/
function repository_dropbox_cron() {
$instances = repository::get_instances(array('type'=>'dropbox'));