[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/repository/dropbox/ -> lib.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * This plugin is used to access user's dropbox files
  19   *
  20   * @since Moodle 2.0
  21   * @package    repository_dropbox
  22   * @copyright  2012 Marina Glancy
  23   * @copyright  2010 Dongsheng Cai {@link http://dongsheng.org}
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  require_once($CFG->dirroot . '/repository/lib.php');
  27  require_once (__DIR__.'/locallib.php');
  28  
  29  /**
  30   * Repository to access Dropbox files
  31   *
  32   * @package    repository_dropbox
  33   * @copyright  2010 Dongsheng Cai
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class repository_dropbox extends repository {
  37      /** @var dropbox the instance of dropbox client */
  38      private $dropbox;
  39      /** @var array files */
  40      public $files;
  41      /** @var bool flag of login status */
  42      public $logged=false;
  43      /** @var int maximum size of file to cache in moodle filepool */
  44      public $cachelimit=null;
  45  
  46      /** @var int cached file ttl */
  47      private $cachedfilettl = null;
  48  
  49      /**
  50       * Constructor of dropbox plugin
  51       *
  52       * @param int $repositoryid
  53       * @param stdClass $context
  54       * @param array $options
  55       */
  56      public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
  57          global $CFG;
  58          $options['page']    = optional_param('p', 1, PARAM_INT);
  59          parent::__construct($repositoryid, $context, $options);
  60  
  61          $this->setting = 'dropbox_';
  62  
  63          $this->dropbox_key = $this->get_option('dropbox_key');
  64          $this->dropbox_secret  = $this->get_option('dropbox_secret');
  65  
  66          // one day
  67          $this->cachedfilettl = 60 * 60 * 24;
  68  
  69          if (isset($options['access_key'])) {
  70              $this->access_key = $options['access_key'];
  71          } else {
  72              $this->access_key = get_user_preferences($this->setting.'_access_key', '');
  73          }
  74          if (isset($options['access_secret'])) {
  75              $this->access_secret = $options['access_secret'];
  76          } else {
  77              $this->access_secret = get_user_preferences($this->setting.'_access_secret', '');
  78          }
  79  
  80          if (!empty($this->access_key) && !empty($this->access_secret)) {
  81              $this->logged = true;
  82          }
  83  
  84          $callbackurl = new moodle_url($CFG->wwwroot.'/repository/repository_callback.php', array(
  85              'callback'=>'yes',
  86              'repo_id'=>$repositoryid
  87              ));
  88  
  89          $args = array(
  90              'oauth_consumer_key'=>$this->dropbox_key,
  91              'oauth_consumer_secret'=>$this->dropbox_secret,
  92              'oauth_callback' => $callbackurl->out(false),
  93              'api_root' => 'https://api.dropbox.com/1/oauth',
  94          );
  95  
  96          $this->dropbox = new dropbox($args);
  97      }
  98  
  99      /**
 100       * Set access key
 101       *
 102       * @param string $access_key
 103       */
 104      public function set_access_key($access_key) {
 105          $this->access_key = $access_key;
 106      }
 107  
 108      /**
 109       * Set access secret
 110       *
 111       * @param string $access_secret
 112       */
 113      public function set_access_secret($access_secret) {
 114          $this->access_secret = $access_secret;
 115      }
 116  
 117  
 118      /**
 119       * Check if moodle has got access token and secret
 120       *
 121       * @return bool
 122       */
 123      public function check_login() {
 124          return !empty($this->logged);
 125      }
 126  
 127      /**
 128       * Generate dropbox login url
 129       *
 130       * @return array
 131       */
 132      public function print_login() {
 133          $result = $this->dropbox->request_token();
 134          set_user_preference($this->setting.'_request_secret', $result['oauth_token_secret']);
 135          $url = $result['authorize_url'];
 136          if ($this->options['ajax']) {
 137              $ret = array();
 138              $popup_btn = new stdClass();
 139              $popup_btn->type = 'popup';
 140              $popup_btn->url = $url;
 141              $ret['login'] = array($popup_btn);
 142              return $ret;
 143          } else {
 144              echo '<a target="_blank" href="'.$url.'">'.get_string('login', 'repository').'</a>';
 145          }
 146      }
 147  
 148      /**
 149       * Request access token
 150       *
 151       * @return array
 152       */
 153      public function callback() {
 154          $token  = optional_param('oauth_token', '', PARAM_TEXT);
 155          $secret = get_user_preferences($this->setting.'_request_secret', '');
 156          $access_token = $this->dropbox->get_access_token($token, $secret);
 157          set_user_preference($this->setting.'_access_key', $access_token['oauth_token']);
 158          set_user_preference($this->setting.'_access_secret', $access_token['oauth_token_secret']);
 159      }
 160  
 161      /**
 162       * Get dropbox files
 163       *
 164       * @param string $path
 165       * @param int $page
 166       * @return array
 167       */
 168      public function get_listing($path = '', $page = '1') {
 169          global $OUTPUT;
 170          if (empty($path) || $path=='/') {
 171              $path = '/';
 172          } else {
 173              $path = file_correct_filepath($path);
 174          }
 175          $encoded_path = str_replace("%2F", "/", rawurlencode($path));
 176  
 177          $list = array();
 178          $list['list'] = array();
 179          $list['manage'] = 'https://www.dropbox.com/home';
 180          $list['dynload'] = true;
 181          $list['nosearch'] = true;
 182          $list['logouturl'] = 'https://www.dropbox.com/logout';
 183          $list['message'] = get_string('logoutdesc', 'repository_dropbox');
 184          // process breadcrumb trail
 185          $list['path'] = array(
 186              array('name'=>get_string('dropbox', 'repository_dropbox'), 'path'=>'/')
 187          );
 188  
 189          $result = $this->dropbox->get_listing($encoded_path, $this->access_key, $this->access_secret);
 190  
 191          if (!is_object($result) || empty($result)) {
 192              return $list;
 193          }
 194          if (empty($result->path)) {
 195              $current_path = '/';
 196          } else {
 197              $current_path = file_correct_filepath($result->path);
 198          }
 199  
 200          $trail = '';
 201          if (!empty($path)) {
 202              $parts = explode('/', $path);
 203              if (count($parts) > 1) {
 204                  foreach ($parts as $part) {
 205                      if (!empty($part)) {
 206                          $trail .= ('/'.$part);
 207                          $list['path'][] = array('name'=>$part, 'path'=>$trail);
 208                      }
 209                  }
 210              } else {
 211                  $list['path'][] = array('name'=>$path, 'path'=>$path);
 212              }
 213          }
 214  
 215          if (!empty($result->error)) {
 216              // reset access key
 217              set_user_preference($this->setting.'_access_key', '');
 218              set_user_preference($this->setting.'_access_secret', '');
 219              throw new repository_exception('repositoryerror', 'repository', '', $result->error);
 220          }
 221          if (empty($result->contents) or !is_array($result->contents)) {
 222              return $list;
 223          }
 224          $files = $result->contents;
 225          $dirslist = array();
 226          $fileslist = array();
 227          foreach ($files as $file) {
 228              if ($file->is_dir) {
 229                  $dirslist[] = array(
 230                      'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
 231                      'path' => file_correct_filepath($file->path),
 232                      'date' => strtotime($file->modified),
 233                      'thumbnail' => $OUTPUT->pix_url(file_folder_icon(64))->out(false),
 234                      'thumbnail_height' => 64,
 235                      'thumbnail_width' => 64,
 236                      'children' => array(),
 237                  );
 238              } else {
 239                  $thumbnail = null;
 240                  if ($file->thumb_exists) {
 241                      $thumburl = new moodle_url('/repository/dropbox/thumbnail.php',
 242                              array('repo_id' => $this->id,
 243                                  'ctx_id' => $this->context->id,
 244                                  'source' => $file->path,
 245                                  'rev' => $file->rev // include revision to avoid cache problems
 246                              ));
 247                      $thumbnail = $thumburl->out(false);
 248                  }
 249                  $fileslist[] = array(
 250                      'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
 251                      'source' => $file->path,
 252                      'size' => $file->bytes,
 253                      'date' => strtotime($file->modified),
 254                      'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->path, 64))->out(false),
 255                      'realthumbnail' => $thumbnail,
 256                      'thumbnail_height' => 64,
 257                      'thumbnail_width' => 64,
 258                  );
 259              }
 260          }
 261          $fileslist = array_filter($fileslist, array($this, 'filter'));
 262          $list['list'] = array_merge($dirslist, array_values($fileslist));
 263          return $list;
 264      }
 265  
 266      /**
 267       * Displays a thumbnail for current user's dropbox file
 268       *
 269       * @param string $string
 270       */
 271      public function send_thumbnail($source) {
 272          global $CFG;
 273          $saveas = $this->prepare_file('');
 274          try {
 275              $access_key = get_user_preferences($this->setting.'_access_key', '');
 276              $access_secret = get_user_preferences($this->setting.'_access_secret', '');
 277              $this->dropbox->set_access_token($access_key, $access_secret);
 278              $this->dropbox->get_thumbnail($source, $saveas, $CFG->repositorysyncimagetimeout);
 279              $content = file_get_contents($saveas);
 280              unlink($saveas);
 281              // set 30 days lifetime for the image. If the image is changed in dropbox it will have
 282              // different revision number and URL will be different. It is completely safe
 283              // to cache thumbnail in the browser for a long time
 284              send_file($content, basename($source), 30*24*60*60, 0, true);
 285          } catch (Exception $e) {}
 286      }
 287  
 288      /**
 289       * Logout from dropbox
 290       * @return array
 291       */
 292      public function logout() {
 293          set_user_preference($this->setting.'_access_key', '');
 294          set_user_preference($this->setting.'_access_secret', '');
 295          $this->access_key    = '';
 296          $this->access_secret = '';
 297          return $this->print_login();
 298      }
 299  
 300      /**
 301       * Set dropbox option
 302       * @param array $options
 303       * @return mixed
 304       */
 305      public function set_option($options = array()) {
 306          if (!empty($options['dropbox_key'])) {
 307              set_config('dropbox_key', trim($options['dropbox_key']), 'dropbox');
 308          }
 309          if (!empty($options['dropbox_secret'])) {
 310              set_config('dropbox_secret', trim($options['dropbox_secret']), 'dropbox');
 311          }
 312          if (!empty($options['dropbox_cachelimit'])) {
 313              $this->cachelimit = (int)trim($options['dropbox_cachelimit']);
 314              set_config('dropbox_cachelimit', $this->cachelimit, 'dropbox');
 315          }
 316          unset($options['dropbox_key']);
 317          unset($options['dropbox_secret']);
 318          unset($options['dropbox_cachelimit']);
 319          $ret = parent::set_option($options);
 320          return $ret;
 321      }
 322  
 323      /**
 324       * Get dropbox options
 325       * @param string $config
 326       * @return mixed
 327       */
 328      public function get_option($config = '') {
 329          if ($config==='dropbox_key') {
 330              return trim(get_config('dropbox', 'dropbox_key'));
 331          } elseif ($config==='dropbox_secret') {
 332              return trim(get_config('dropbox', 'dropbox_secret'));
 333          } elseif ($config==='dropbox_cachelimit') {
 334              return $this->max_cache_bytes();
 335          } else {
 336              $options = parent::get_option();
 337              $options['dropbox_key'] = trim(get_config('dropbox', 'dropbox_key'));
 338              $options['dropbox_secret'] = trim(get_config('dropbox', 'dropbox_secret'));
 339              $options['dropbox_cachelimit'] = $this->max_cache_bytes();
 340          }
 341          return $options;
 342      }
 343  
 344      /**
 345       * Fixes references in DB that contains user credentials
 346       *
 347       * @param string $reference contents of DB field files_reference.reference
 348       */
 349      public function fix_old_style_reference($reference) {
 350          global $CFG;
 351          $ref = unserialize($reference);
 352          if (!isset($ref->url)) {
 353              $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
 354              $ref->url = $this->dropbox->get_file_share_link($ref->path, $CFG->repositorygetfiletimeout);
 355              if (!$ref->url) {
 356                  // some error occurred, do not fix reference for now
 357                  return $reference;
 358              }
 359          }
 360          unset($ref->access_key);
 361          unset($ref->access_secret);
 362          $newreference = serialize($ref);
 363          if ($newreference !== $reference) {
 364              // we need to update references in the database
 365              global $DB;
 366              $params = array(
 367                  'newreference' => $newreference,
 368                  'newhash' => sha1($newreference),
 369                  'reference' => $reference,
 370                  'hash' => sha1($reference),
 371                  'repoid' => $this->id
 372              );
 373              $refid = $DB->get_field_sql('SELECT id FROM {files_reference}
 374                  WHERE reference = :reference AND referencehash = :hash
 375                  AND repositoryid = :repoid', $params);
 376              if (!$refid) {
 377                  return $newreference;
 378              }
 379              $existingrefid = $DB->get_field_sql('SELECT id FROM {files_reference}
 380                      WHERE reference = :newreference AND referencehash = :newhash
 381                      AND repositoryid = :repoid', $params);
 382              if ($existingrefid) {
 383                  // the same reference already exists, we unlink all files from it,
 384                  // link them to the current reference and remove the old one
 385                  $DB->execute('UPDATE {files} SET referencefileid = :refid
 386                      WHERE referencefileid = :existingrefid',
 387                      array('refid' => $refid, 'existingrefid' => $existingrefid));
 388                  $DB->delete_records('files_reference', array('id' => $existingrefid));
 389              }
 390              // update the reference
 391              $params['refid'] = $refid;
 392              $DB->execute('UPDATE {files_reference}
 393                  SET reference = :newreference, referencehash = :newhash
 394                  WHERE id = :refid', $params);
 395          }
 396          return $newreference;
 397      }
 398  
 399      /**
 400       * Converts a URL received from dropbox API function 'shares' into URL that
 401       * can be used to download/access file directly
 402       *
 403       * @param string $sharedurl
 404       * @return string
 405       */
 406      private function get_file_download_link($sharedurl) {
 407          return preg_replace('|^(\w*://)www(.dropbox.com)|','\1dl\2',$sharedurl);
 408      }
 409  
 410      /**
 411       * Downloads a file from external repository and saves it in temp dir
 412       *
 413       * @throws moodle_exception when file could not be downloaded
 414       *
 415       * @param string $reference the content of files.reference field or result of
 416       * function {@link repository_dropbox::get_file_reference()}
 417       * @param string $saveas filename (without path) to save the downloaded file in the
 418       * temporary directory, if omitted or file already exists the new filename will be generated
 419       * @return array with elements:
 420       *   path: internal location of the file
 421       *   url: URL to the source (from parameters)
 422       */
 423      public function get_file($reference, $saveas = '') {
 424          global $CFG;
 425          $ref = unserialize($reference);
 426          $saveas = $this->prepare_file($saveas);
 427          if (isset($ref->access_key) && isset($ref->access_secret) && isset($ref->path)) {
 428              $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
 429              return $this->dropbox->get_file($ref->path, $saveas, $CFG->repositorygetfiletimeout);
 430          } else if (isset($ref->url)) {
 431              $c = new curl;
 432              $url = $this->get_file_download_link($ref->url);
 433              $result = $c->download_one($url, null, array('filepath' => $saveas, 'timeout' => $CFG->repositorygetfiletimeout, 'followlocation' => true));
 434              $info = $c->get_info();
 435              if ($result !== true || !isset($info['http_code']) || $info['http_code'] != 200) {
 436                  throw new moodle_exception('errorwhiledownload', 'repository', '', $result);
 437              }
 438              return array('path'=>$saveas, 'url'=>$url);
 439          }
 440          throw new moodle_exception('cannotdownload', 'repository');
 441      }
 442      /**
 443       * Add Plugin settings input to Moodle form
 444       *
 445       * @param moodleform $mform Moodle form (passed by reference)
 446       * @param string $classname repository class name
 447       */
 448      public static function type_config_form($mform, $classname = 'repository') {
 449          global $CFG;
 450          parent::type_config_form($mform);
 451          $key    = get_config('dropbox', 'dropbox_key');
 452          $secret = get_config('dropbox', 'dropbox_secret');
 453  
 454          if (empty($key)) {
 455              $key = '';
 456          }
 457          if (empty($secret)) {
 458              $secret = '';
 459          }
 460  
 461          $strrequired = get_string('required');
 462  
 463          $mform->addElement('text', 'dropbox_key', get_string('apikey', 'repository_dropbox'), array('value'=>$key,'size' => '40'));
 464          $mform->setType('dropbox_key', PARAM_RAW_TRIMMED);
 465          $mform->addElement('text', 'dropbox_secret', get_string('secret', 'repository_dropbox'), array('value'=>$secret,'size' => '40'));
 466  
 467          $mform->addRule('dropbox_key', $strrequired, 'required', null, 'client');
 468          $mform->addRule('dropbox_secret', $strrequired, 'required', null, 'client');
 469          $mform->setType('dropbox_secret', PARAM_RAW_TRIMMED);
 470          $str_getkey = get_string('instruction', 'repository_dropbox');
 471          $mform->addElement('static', null, '',  $str_getkey);
 472  
 473          $mform->addElement('text', 'dropbox_cachelimit', get_string('cachelimit', 'repository_dropbox'), array('size' => '40'));
 474          $mform->addRule('dropbox_cachelimit', null, 'numeric', null, 'client');
 475          $mform->setType('dropbox_cachelimit', PARAM_INT);
 476          $mform->addElement('static', 'dropbox_cachelimit_info', '',  get_string('cachelimit_info', 'repository_dropbox'));
 477      }
 478  
 479      /**
 480       * Option names of dropbox plugin
 481       *
 482       * @return array
 483       */
 484      public static function get_type_option_names() {
 485          return array('dropbox_key', 'dropbox_secret', 'pluginname', 'dropbox_cachelimit');
 486      }
 487  
 488      /**
 489       * Dropbox plugin supports all kinds of files
 490       *
 491       * @return array
 492       */
 493      public function supported_filetypes() {
 494          return '*';
 495      }
 496  
 497      /**
 498       * User cannot use the external link to dropbox
 499       *
 500       * @return int
 501       */
 502      public function supported_returntypes() {
 503          return FILE_INTERNAL | FILE_REFERENCE | FILE_EXTERNAL;
 504      }
 505  
 506      /**
 507       * Return file URL for external link
 508       *
 509       * @param string $reference the result of get_file_reference()
 510       * @return string
 511       */
 512      public function get_link($reference) {
 513          global $CFG;
 514          $ref = unserialize($reference);
 515          if (!isset($ref->url)) {
 516              $this->dropbox->set_access_token($ref->access_key, $ref->access_secret);
 517              $ref->url = $this->dropbox->get_file_share_link($ref->path, $CFG->repositorygetfiletimeout);
 518          }
 519          return $this->get_file_download_link($ref->url);
 520      }
 521  
 522      /**
 523       * Prepare file reference information
 524       *
 525       * @param string $source
 526       * @return string file referece
 527       */
 528      public function get_file_reference($source) {
 529          global $USER, $CFG;
 530          $reference = new stdClass;
 531          $reference->path = $source;
 532          $reference->userid = $USER->id;
 533          $reference->username = fullname($USER);
 534          $reference->access_key = get_user_preferences($this->setting.'_access_key', '');
 535          $reference->access_secret = get_user_preferences($this->setting.'_access_secret', '');
 536  
 537          // by API we don't know if we need this reference to just download a file from dropbox
 538          // into moodle filepool or create a reference. Since we need to create a shared link
 539          // only in case of reference we analyze the script parameter
 540          $usefilereference = optional_param('usefilereference', false, PARAM_BOOL);
 541          if ($usefilereference) {
 542              $this->dropbox->set_access_token($reference->access_key, $reference->access_secret);
 543              $url = $this->dropbox->get_file_share_link($source, $CFG->repositorygetfiletimeout);
 544              if ($url) {
 545                  unset($reference->access_key);
 546                  unset($reference->access_secret);
 547                  $reference->url = $url;
 548              }
 549          }
 550          return serialize($reference);
 551      }
 552  
 553      public function sync_reference(stored_file $file) {
 554          global $CFG;
 555  
 556          if ($file->get_referencelastsync() + DAYSECS > time()) {
 557              // Synchronise not more often than once a day.
 558              return false;
 559          }
 560          $ref = unserialize($file->get_reference());
 561          if (!isset($ref->url)) {
 562              // this is an old-style reference in DB. We need to fix it
 563              $ref = unserialize($this->fix_old_style_reference($file->get_reference()));
 564          }
 565          if (!isset($ref->url)) {
 566              return false;
 567          }
 568          $c = new curl;
 569          $url = $this->get_file_download_link($ref->url);
 570          if (file_extension_in_typegroup($ref->path, 'web_image')) {
 571              $saveas = $this->prepare_file('');
 572              try {
 573                  $result = $c->download_one($url, array(), array('filepath' => $saveas, 'timeout' => $CFG->repositorysyncimagetimeout, 'followlocation' => true));
 574                  $info = $c->get_info();
 575                  if ($result === true && isset($info['http_code']) && $info['http_code'] == 200) {
 576                      $fs = get_file_storage();
 577                      list($contenthash, $filesize, $newfile) = $fs->add_file_to_pool($saveas);
 578                      $file->set_synchronized($contenthash, $filesize);
 579                      return true;
 580                  }
 581              } catch (Exception $e) {}
 582          }
 583          $c->get($url, null, array('timeout' => $CFG->repositorysyncimagetimeout, 'followlocation' => true, 'nobody' => true));
 584          $info = $c->get_info();
 585          if (isset($info['http_code']) && $info['http_code'] == 200 &&
 586                  array_key_exists('download_content_length', $info) &&
 587                  $info['download_content_length'] >= 0) {
 588              $filesize = (int)$info['download_content_length'];
 589              $file->set_synchronized(null, $filesize);
 590              return true;
 591          }
 592          $file->set_missingsource();
 593          return true;
 594      }
 595  
 596      /**
 597       * Cache file from external repository by reference
 598       *
 599       * Dropbox repository regularly caches all external files that are smaller than
 600       * {@link repository_dropbox::max_cache_bytes()}
 601       *
 602       * @param string $reference this reference is generated by
 603       *                          repository::get_file_reference()
 604       * @param stored_file $storedfile created file reference
 605       */
 606      public function cache_file_by_reference($reference, $storedfile) {
 607          try {
 608              $this->import_external_file_contents($storedfile, $this->max_cache_bytes());
 609          } catch (Exception $e) {}
 610      }
 611  
 612      /**
 613       * Return human readable reference information
 614       * {@link stored_file::get_reference()}
 615       *
 616       * @param string $reference
 617       * @param int $filestatus status of the file, 0 - ok, 666 - source missing
 618       * @return string
 619       */
 620      public function get_reference_details($reference, $filestatus = 0) {
 621          global $USER;
 622          $ref  = unserialize($reference);
 623          $detailsprefix = $this->get_name();
 624          if (isset($ref->userid) && $ref->userid != $USER->id && isset($ref->username)) {
 625              $detailsprefix .= ' ('.$ref->username.')';
 626          }
 627          $details = $detailsprefix;
 628          if (isset($ref->path)) {
 629              $details .= ': '. $ref->path;
 630          }
 631          if (isset($ref->path) && !$filestatus) {
 632              // Indicate this is from dropbox with path
 633              return $details;
 634          } else {
 635              if (isset($ref->url)) {
 636                  $details = $detailsprefix. ': '. $ref->url;
 637              }
 638              return get_string('lostsource', 'repository', $details);
 639          }
 640      }
 641  
 642      /**
 643       * Return the source information
 644       *
 645       * @param string $source
 646       * @return string
 647       */
 648      public function get_file_source_info($source) {
 649          global $USER;
 650          return 'Dropbox ('.fullname($USER).'): ' . $source;
 651      }
 652  
 653      /**
 654       * Returns the maximum size of the Dropbox files to cache in moodle
 655       *
 656       * Note that {@link repository_dropbox::sync_reference()} will try to cache images even
 657       * when they are bigger in order to generate thumbnails. However there is
 658       * a small timeout for downloading images for synchronisation and it will
 659       * probably fail if the image is too big.
 660       *
 661       * @return int
 662       */
 663      public function max_cache_bytes() {
 664          if ($this->cachelimit === null) {
 665              $this->cachelimit = (int)get_config('dropbox', 'dropbox_cachelimit');
 666          }
 667          return $this->cachelimit;
 668      }
 669  
 670      /**
 671       * Repository method to serve the referenced file
 672       *
 673       * This method is ivoked from {@link send_stored_file()}.
 674       * Dropbox repository first caches the file by reading it into temporary folder and then
 675       * serves from there.
 676       *
 677       * @param stored_file $storedfile the file that contains the reference
 678       * @param int $lifetime Number of seconds before the file should expire from caches (null means $CFG->filelifetime)
 679       * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only
 680       * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin
 681       * @param array $options additional options affecting the file serving
 682       */
 683      public function send_file($storedfile, $lifetime=null , $filter=0, $forcedownload=false, array $options = null) {
 684          $ref = unserialize($storedfile->get_reference());
 685          if ($storedfile->get_filesize() > $this->max_cache_bytes()) {
 686              header('Location: '.$this->get_file_download_link($ref->url));
 687              die;
 688          }
 689          try {
 690              $this->import_external_file_contents($storedfile, $this->max_cache_bytes());
 691              if (!is_array($options)) {
 692                  $options = array();
 693              }
 694              $options['sendcachedexternalfile'] = true;
 695              send_stored_file($storedfile, $lifetime, $filter, $forcedownload, $options);
 696          } catch (moodle_exception $e) {
 697              // redirect to Dropbox, it will show the error.
 698              // We redirect to Dropbox shared link, not to download link here!
 699              header('Location: '.$ref->url);
 700              die;
 701          }
 702      }
 703  
 704      /**
 705       * Caches all references to Dropbox files in moodle filepool
 706       *
 707       * Invoked by {@link repository_dropbox_cron()}. Only files smaller than
 708       * {@link repository_dropbox::max_cache_bytes()} and only files which
 709       * synchronisation timeout have not expired are cached.
 710       */
 711      public function cron() {
 712          $fs = get_file_storage();
 713          $files = $fs->get_external_files($this->id);
 714          foreach ($files as $file) {
 715              try {
 716                  // This call will cache all files that are smaller than max_cache_bytes()
 717                  // and synchronise file size of all others
 718                  $this->import_external_file_contents($file, $this->max_cache_bytes());
 719              } catch (moodle_exception $e) {}
 720          }
 721      }
 722  }
 723  
 724  /**
 725   * Dropbox plugin cron task
 726   */
 727  function repository_dropbox_cron() {
 728      $instances = repository::get_instances(array('type'=>'dropbox'));
 729      foreach ($instances as $instance) {
 730          $instance->cron();
 731      }
 732  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1