MDL-22982
authorDongsheng Cai <unoter@gmail.com>
Mon, 5 Jul 2010 07:27:49 +0000 (07:27 +0000)
committerDongsheng Cai <unoter@gmail.com>
Mon, 5 Jul 2010 07:27:49 +0000 (07:27 +0000)
1. rename repository.class to lib.php
2. fixed repository_callback.php
3. repository_ajax use moodle default exception handler
4. improve file_get_user_used_space performance

32 files changed:
lang/en/repository.php
lib/filelib.php
lib/simpletest/testrepositorylib.php
repository/alfresco/lib.php [moved from repository/alfresco/repository.class.php with 99% similarity]
repository/boxnet/lib.php [moved from repository/boxnet/repository.class.php with 100% similarity]
repository/dropbox/lib.php
repository/dropbox/locallib.php [new file with mode: 0644]
repository/dropbox/repository.class.php [deleted file]
repository/filepicker.js
repository/filepicker.php
repository/filesystem/lib.php [moved from repository/filesystem/repository.class.php with 100% similarity]
repository/flickr/lib.php [moved from repository/flickr/repository.class.php with 100% similarity]
repository/flickr_public/lib.php [moved from repository/flickr_public/repository.class.php with 99% similarity]
repository/googledocs/lib.php [moved from repository/googledocs/repository.class.php with 97% similarity]
repository/lib.php
repository/local/db/install.php
repository/local/lib.php [moved from repository/local/repository.class.php with 91% similarity]
repository/merlot/lib.php [moved from repository/merlot/repository.class.php with 100% similarity]
repository/picasa/lib.php [moved from repository/picasa/repository.class.php with 97% similarity]
repository/recent/lib.php [moved from repository/recent/repository.class.php with 85% similarity]
repository/repository_ajax.php
repository/repository_callback.php
repository/s3/lib.php [moved from repository/s3/repository.class.php with 100% similarity]
repository/upload/db/install.php
repository/upload/lib.php [moved from repository/upload/repository.class.php with 56% similarity]
repository/url/lib.php
repository/url/locallib.php [new file with mode: 0644]
repository/url/repository.class.php [deleted file]
repository/user/lib.php [moved from repository/user/repository.class.php with 88% similarity]
repository/webdav/lib.php [moved from repository/webdav/repository.class.php with 100% similarity]
repository/wikimedia/lib.php [moved from repository/wikimedia/repository.class.php with 100% similarity]
repository/youtube/lib.php [moved from repository/youtube/repository.class.php with 100% similarity]

index bf3b11d..80abb94 100644 (file)
@@ -101,6 +101,7 @@ $string['instancesforadmin'] = 'common instance(s)';
 $string['instancesforothers'] = 'private instance(s)';
 $string['invalidjson'] = 'Invalid JSON string';
 $string['invalidplugin'] = 'Invalid repository {$a} plug-in';
+$string['invalidfiletype'] = '{$a} filetype cannot be accepted.';
 $string['invalidrepositoryid'] = 'Invalid repository ID';
 $string['isactive'] = 'Active?';
 $string['keyword'] = 'Keyword';
index 8d7c7a7..2ea4351 100644 (file)
@@ -514,26 +514,17 @@ function file_get_draft_area_info($draftitemid) {
  * @return int total bytes
  */
 function file_get_user_used_space() {
-    global $DB, $CFG, $USER;
+    global $DB, $USER;
 
     $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
-
-    $totalbytes = 0;
-    $files = array();
-    //TODO: rewrite to true sql SUM(), this is goign to run out of memory if limits are hight!
-    $file_records = $DB->get_records('files', "contextid = ? AND component = 'user' AND filearea != 'draft'", array($usercontext->id));
-    foreach ($file_records as $file_record) {
-        if ($file_record->filename === '.') {
-            continue;
-        }
-        // doesn't count same files
-        if (!isset($files[$file_record->contenthash])) {
-            $totalbytes += $file_record->filesize;
-        } else {
-            $files[$file_record->contenthash] = true;
-        }
-    }
-    return (int)$totalbytes;
+    $sql = "SELECT SUM(files1.filesize) AS totalbytes FROM {files} files1
+            JOIN (SELECT contenthash, filename, MAX(id) AS id
+            FROM {files}
+            WHERE contextid = ? AND component = ? AND filearea != ?
+            GROUP BY contenthash, filename) files2 ON files1.id = files2.id";
+    $params = array('contextid'=>$usercontext->id, 'component'=>'user', 'filearea'=>'draft');
+    $record = $DB->get_record_sql($sql, $params);
+    return (int)$record->totalbytes;
 }
 
 /**
@@ -2874,7 +2865,7 @@ class curl_cache {
     }
 
     /**
-     * @todo Document this function
+     * Get cached value
      *
      * @global object
      * @global object
@@ -2901,10 +2892,10 @@ class curl_cache {
     }
 
     /**
-     * @todo Document this function
+     * Set cache value
      *
-     * @global object
-     * @global object
+     * @global object $CFG
+     * @global object $USER
      * @param mixed $param
      * @param mixed $val
      */
@@ -2917,7 +2908,7 @@ class curl_cache {
     }
 
     /**
-     * @todo Document this function
+     * Remove cache files
      *
      * @param int $expire The number os seconds before expiry
      */
@@ -2936,8 +2927,8 @@ class curl_cache {
     /**
      * delete current user's cache file
      *
-     * @global object
-     * @global object
+     * @global object $CFG
+     * @global object $USER
      */
     public function refresh(){
         global $CFG, $USER;
index 3e8b691..04f185f 100644 (file)
@@ -42,7 +42,7 @@ require_once("$CFG->dirroot/$CFG->admin/generator.php");
 $repository_plugins = get_list_of_plugins('repository');
 
 foreach ($repository_plugins as $plugin) {
-    require_once($CFG->dirroot . "/repository/$plugin/repository.class.php");
+    require_once($CFG->dirroot . "/repository/$plugin/lib.php");
     Mock::generatePartial("repository_$plugin", "partialmock_$plugin", array('send_package'));
 }
 
similarity index 99%
rename from repository/alfresco/repository.class.php
rename to repository/alfresco/lib.php
index c3fc791..df3d77c 100755 (executable)
@@ -202,8 +202,8 @@ class repository_alfresco extends repository {
         return array('path'=>$path, 'url'=>$url);
     }
 
-    public function print_search($client_id) {
-        $str = parent::print_search($client_id);
+    public function print_search() {
+        $str = parent::print_search();
         $str .= '<label>Space: </label><br /><select name="space">';
         foreach ($this->user_session->stores as $v) {
             $str .= '<option ';
index 963124c..0073df5 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * dropbox class
- * A helper class to access dropbox resources
+ * repository_dropbox class
+ * This plugin is used to access user's dropbox files
+ *
+ * TODO:
+ * Dropbox has problems to process filepath with spaces, tried to use
+ * urlencode filepath, still doesn't work
+ * http://code.google.com/p/dropbox-php/ has the same problem
  *
  * @since 2.0
  * @package moodlecore
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+require_once(dirname(__FILE__).'/locallib.php');
+
+class repository_dropbox extends repository {
+    private $dropbox;
+    public $files;
+    public $logged=false;
+
+    /**
+     * Constructor of dropbox plugin
+     * @param int $repositoryid
+     * @param object $context
+     * @param array $options
+     */
+    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
+        global $SESSION, $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');
+
+        $this->access_key    = get_user_preferences($this->setting.'_access_key', '');
+        $this->access_secret = get_user_preferences($this->setting.'_access_secret', '');
+
+        if (!empty($this->access_key) && !empty($this->access_secret)) {
+            $this->logged = true;
+        }
+
+        $this->callback = new moodle_url($CFG->wwwroot.'/repository/repository_ajax.php', array(
+            'callback'=>'yes',
+            'repo_id'=>$repositoryid
+            ));
+
+        $args = array(
+            'oauth_consumer_key'=>$this->dropbox_key,
+            'oauth_consumer_secret'=>$this->dropbox_secret,
+            'oauth_callback' => $this->callback->out(false),
+            'api_root' => 'http://api.dropbox.com/0/oauth',
+        );
+
+        $this->dropbox = new dropbox($args);
+    }
+
+    /**
+     * 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 '<a target="_blank" href="'.$this->flickr->auth().'">'.get_string('login', 'repository').'</a>';
+        }
+    }
+
+    /**
+     * 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);
+        }
+        $result = $this->dropbox->get_listing($path, $this->access_key, $this->access_secret);
+        $current_path = file_correct_filepath($result->path);
+        if (empty($result->path)) {
+            $current_path = '/';
+        }
+
+        $list = array();
+        $list['list'] = array();
+        // process breacrumb trail
+        $list['path'] = array(
+            array('name'=>'Dropbox Sandbox', '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);
+            }
+        }
+        $list['manage'] = false;
+        $list['dynload'] = true;
+        $list['nosearch'] = true;
+
+        $files = $result->contents;
+        foreach ($files as $file) {
+            if ($file->is_dir) {
+                $list['list'][] = array(
+                    'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
+                    'path' => file_correct_filepath($file->path),
+                    'size' => $file->size,
+                    'date' => $file->modified,
+                    'thumbnail' => $OUTPUT->pix_url('f/folder-32').'',
+                    'children' => array(),
+                );
+            } else {
+                $list['list'][] = array(
+                    'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
+                    'source' => $file->path,
+                    'size' => $file->size,
+                    'date' => $file->modified,
+                    'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->path, 32)).''
+                );
+            }
+        }
+        return $list;
+    }
+    /**
+     * 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');
+        }
+        unset($options['dropbox_key']);
+        unset($options['dropbox_secret']);
+        $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'));
+        } else {
+            $options['dropbox_key'] = trim(get_config('dropbox', 'dropbox_key'));
+            $options['dropbox_secret'] = trim(get_config('dropbox', 'dropbox_secret'));
+        }
+        $options = parent::get_option($config);
+        return $options;
+    }
+
+    /**
+     *
+     * @param string $photo_id
+     * @param string $file
+     * @return string
+     */
+    public function get_file($filepath, $saveas = '') {
+        $this->dropbox->set_access_token($this->access_key, $this->access_secret);
+        return $this->dropbox->get_file($filepath, $saveas);
+    }
+    /**
+     * Add Plugin settings input to Moodle form
+     * @param object $mform
+     */
+    public function type_config_form($mform) {
+        global $CFG;
+        $key    = get_config('dropbox', 'dropbox_key');
+        $secret = get_config('dropbox', 'dropbox_secret');
+
+        if (empty($key)) {
+            $key = '';
+        }
+        if (empty($secret)) {
+            $secret = '';
+        }
+
+        $strrequired = get_string('required');
+
+        $mform->addElement('text', 'dropbox_key', get_string('apikey', 'repository_dropbox'), array('value'=>$key,'size' => '40'));
+        $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');
+        $str_getkey = get_string('instruction', 'repository_dropbox');
+        $mform->addElement('static', null, '',  $str_getkey);
+    }
+
+    /**
+     * Option names of dropbox plugin
+     * @return array
+     */
+    public static function get_type_option_names() {
+        return array('dropbox_key', 'dropbox_secret');
+    }
+
+    /**
+     * Dropbox plugin supports all kinds of files
+     * @return array
+     */
+    public function supported_filetypes() {
+        return '*';
+    }
 
-require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
-require_once($CFG->libdir.'/oauthlib.php');
-
-class dropbox extends oauth_helper {
-    private $mode = 'sandbox';
-    private $dropbox_api = 'http://api.dropbox.com/0';
-    private $dropbox_content_api = 'http://api-content.dropbox.com/0';
-    function __construct($args) {
-        parent::__construct($args);
-    }
-    public function get_listing($path='/', $token='', $secret='') {
-        $url = $this->dropbox_api.'/metadata/'.$this->mode.$path;
-        $content = $this->get($url, array(), $token, $secret);
-        $data = json_decode($content);
-        return $data;
-    }
-    public function get_account_info($token, $secret) {
-        $url = $this->dropbox_api.'/account/info';
-        $content = $this->get($url, array(), $token, $secret);
-        return $content;
-    }
-    public function get_file($filepath, $saveas) {
-        $url = 'http://api-content.dropbox.com/0/files/sandbox'.$filepath;
-        $content = $this->get($url, array());
-        file_put_contents($saveas, $content);
-        return array('path'=>$saveas, 'url'=>$url);
+    /**
+     * User cannot use the external link to dropbox
+     * @return int
+     */
+    public function supported_returntypes() {
+        return FILE_INTERNAL;
     }
 }
diff --git a/repository/dropbox/locallib.php b/repository/dropbox/locallib.php
new file mode 100644 (file)
index 0000000..963124c
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * dropbox class
+ * A helper class to access dropbox resources
+ *
+ * @since 2.0
+ * @package moodlecore
+ * @subpackage repository
+ * @copyright 2010 Dongsheng Cai
+ * @author Dongsheng Cai <dongsheng@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
+require_once($CFG->libdir.'/oauthlib.php');
+
+class dropbox extends oauth_helper {
+    private $mode = 'sandbox';
+    private $dropbox_api = 'http://api.dropbox.com/0';
+    private $dropbox_content_api = 'http://api-content.dropbox.com/0';
+    function __construct($args) {
+        parent::__construct($args);
+    }
+    public function get_listing($path='/', $token='', $secret='') {
+        $url = $this->dropbox_api.'/metadata/'.$this->mode.$path;
+        $content = $this->get($url, array(), $token, $secret);
+        $data = json_decode($content);
+        return $data;
+    }
+    public function get_account_info($token, $secret) {
+        $url = $this->dropbox_api.'/account/info';
+        $content = $this->get($url, array(), $token, $secret);
+        return $content;
+    }
+    public function get_file($filepath, $saveas) {
+        $url = 'http://api-content.dropbox.com/0/files/sandbox'.$filepath;
+        $content = $this->get($url, array());
+        file_put_contents($saveas, $content);
+        return array('path'=>$saveas, 'url'=>$url);
+    }
+}
diff --git a/repository/dropbox/repository.class.php b/repository/dropbox/repository.class.php
deleted file mode 100755 (executable)
index b80fb2b..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-<?php
-
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * repository_dropbox class
- * This plugin is used to access user's dropbox files
- *
- * TODO:
- * Dropbox has problems to process filepath with spaces, tried to use
- * urlencode filepath, still doesn't work
- * http://code.google.com/p/dropbox-php/ has the same problem
- *
- * @since 2.0
- * @package moodlecore
- * @subpackage repository
- * @copyright 2010 Dongsheng Cai
- * @author Dongsheng Cai <dongsheng@moodle.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require_once($CFG->dirroot.'/repository/dropbox/lib.php');
-
-class repository_dropbox extends repository {
-    private $dropbox;
-    public $files;
-    public $logged=false;
-
-    /**
-     * Constructor of dropbox plugin
-     * @param int $repositoryid
-     * @param object $context
-     * @param array $options
-     */
-    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
-        global $SESSION, $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');
-
-        $this->access_key    = get_user_preferences($this->setting.'_access_key', '');
-        $this->access_secret = get_user_preferences($this->setting.'_access_secret', '');
-
-        if (!empty($this->access_key) && !empty($this->access_secret)) {
-            $this->logged = true;
-        }
-
-        $this->callback = new moodle_url($CFG->wwwroot.'/repository/repository_callback.php', array(
-            'repo_id'=>$repositoryid
-            ));
-
-        $args = array(
-            'oauth_consumer_key'=>$this->dropbox_key,
-            'oauth_consumer_secret'=>$this->dropbox_secret,
-            'oauth_callback' => $this->callback->out(false),
-            'api_root' => 'http://api.dropbox.com/0/oauth',
-        );
-
-        $this->dropbox = new dropbox($args);
-    }
-
-    /**
-     * 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 '<a target="_blank" href="'.$this->flickr->auth().'">'.get_string('login', 'repository').'</a>';
-        }
-    }
-
-    /**
-     * 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);
-        }
-        $result = $this->dropbox->get_listing($path, $this->access_key, $this->access_secret);
-        $current_path = file_correct_filepath($result->path);
-        if (empty($result->path)) {
-            $current_path = '/';
-        }
-
-        $list = array();
-        $list['list'] = array();
-        // process breacrumb trail
-        $list['path'] = array(
-            array('name'=>'Dropbox Sandbox', '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);
-            }
-        }
-        $list['manage'] = false;
-        $list['dynload'] = true;
-        $list['nosearch'] = true;
-
-        $files = $result->contents;
-        foreach ($files as $file) {
-            if ($file->is_dir) {
-                $list['list'][] = array(
-                    'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
-                    'path' => file_correct_filepath($file->path),
-                    'size' => $file->size,
-                    'date' => $file->modified,
-                    'thumbnail' => $OUTPUT->pix_url('f/folder-32').'',
-                    'children' => array(),
-                );
-            } else {
-                $list['list'][] = array(
-                    'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
-                    'source' => $file->path,
-                    'size' => $file->size,
-                    'date' => $file->modified,
-                    'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->path, 32)).''
-                );
-            }
-        }
-        return $list;
-    }
-    /**
-     * 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');
-        }
-        unset($options['dropbox_key']);
-        unset($options['dropbox_secret']);
-        $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'));
-        } else {
-            $options['dropbox_key'] = trim(get_config('dropbox', 'dropbox_key'));
-            $options['dropbox_secret'] = trim(get_config('dropbox', 'dropbox_secret'));
-        }
-        $options = parent::get_option($config);
-        return $options;
-    }
-
-    /**
-     *
-     * @param string $photo_id
-     * @param string $file
-     * @return string
-     */
-    public function get_file($filepath, $saveas = '') {
-        $this->dropbox->set_access_token($this->access_key, $this->access_secret);
-        return $this->dropbox->get_file($filepath, $saveas);
-    }
-    /**
-     * Add Plugin settings input to Moodle form
-     * @param object $mform
-     */
-    public function type_config_form($mform) {
-        global $CFG;
-        $key    = get_config('dropbox', 'dropbox_key');
-        $secret = get_config('dropbox', 'dropbox_secret');
-
-        if (empty($key)) {
-            $key = '';
-        }
-        if (empty($secret)) {
-            $secret = '';
-        }
-
-        $strrequired = get_string('required');
-
-        $mform->addElement('text', 'dropbox_key', get_string('apikey', 'repository_dropbox'), array('value'=>$key,'size' => '40'));
-        $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');
-        $str_getkey = get_string('instruction', 'repository_dropbox');
-        $mform->addElement('static', null, '',  $str_getkey);
-    }
-
-    /**
-     * Option names of dropbox plugin
-     * @return array
-     */
-    public static function get_type_option_names() {
-        return array('dropbox_key', 'dropbox_secret');
-    }
-
-    /**
-     * 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;
-    }
-}
index 27224ee..17e34f2 100644 (file)
@@ -97,7 +97,7 @@ M.core_filepicker.init = function(Y, options) {
             params['env']=this.options.env;
             // the form element only accept certain file types
             params['accepted_types']=this.options.accepted_types;
-            params['sesskey']=M.cfg.sesskey;
+            params['sesskey'] = M.cfg.sesskey;
             params['client_id'] = args.client_id;
             params['itemid'] = this.options.itemid?this.options.itemid:0;
             params['maxbytes'] = this.options.maxbytes?this.options.maxbytes:-1;
@@ -124,9 +124,8 @@ M.core_filepicker.init = function(Y, options) {
                             return;
                         }
                         // error checking
-                        if (data && data.e) {
-                            //Y.one(panel_id).set('innerHTML', 'ERROR: '+data.e);
-                            scope.print_msg(data.e, 'error');
+                        if (data && data.error) {
+                            scope.print_msg(data.error, 'error');
                             scope.list();
                             return;
                         } else {
@@ -189,7 +188,6 @@ M.core_filepicker.init = function(Y, options) {
             }
             this.msg_dlg.setHeader(type);
             this.msg_dlg.show();
-
         },
         build_tree: function(node, level) {
             var client_id = this.options.client_id;
@@ -653,7 +651,7 @@ M.core_filepicker.init = function(Y, options) {
                 }
                 if (count==0) {
                     if (this.options.externallink) {
-                        list.set('innerHTML', M.str.repository.norepositoriesavexternalailable);
+                        list.set('innerHTML', M.str.repository.norepositoriesexternalavailable);
                     } else {
                         list.set('innerHTML', M.str.repository.norepositoriesavailable);
                     }
@@ -962,6 +960,7 @@ M.core_filepicker.init = function(Y, options) {
         create_upload_form: function(data) {
             var client_id = this.options.client_id;
             Y.one('#panel-'+client_id).set('innerHTML', '');
+            var types = this.options.accepted_types;
 
             this.print_header();
             var id = data.upload.id+'_'+client_id;
@@ -971,8 +970,11 @@ M.core_filepicker.init = function(Y, options) {
             str += '<tr><td class="mdl-right">';
             str += '<label for="'+id+'_file">'+data.upload.label+': </label></td>';
             str += '<td class="mdl-left"><input type="file" id="'+id+'_file" name="repo_upload_file" />';
-            str += '<input type="hidden" name="itemid" value="'+this.options.itemid+'" /></tr>';
-            str += '<tr>';
+            str += '<input type="hidden" name="itemid" value="'+this.options.itemid+'" />';
+            for (var i in types) {
+                str += '<input type="hidden" name="accepted_types[]" value="'+types[i]+'" />';
+            }
+            str += '</td></tr><tr>';
             str += '<td class="mdl-right"><label>'+M.str.repository.author+': </label></td>';
             str += '<td class="mdl-left"><input type="text" name="author" value="'+this.options.author+'" /></td>';
             str += '</tr>';
index 2b7cf2e..d257e62 100755 (executable)
@@ -80,8 +80,8 @@ $sql = 'SELECT i.name, i.typeid, r.type FROM {repository} r, {repository_instanc
        'WHERE i.id=? AND i.typeid=r.id';
 if ($repository = $DB->get_record_sql($sql, array($repo_id))) {
     $type = $repository->type;
-    if (file_exists($CFG->dirroot.'/repository/'.$type.'/repository.class.php')) {
-        require_once($CFG->dirroot.'/repository/'.$type.'/repository.class.php');
+    if (file_exists($CFG->dirroot.'/repository/'.$type.'/lib.php')) {
+        require_once($CFG->dirroot.'/repository/'.$type.'/lib.php');
         $classname = 'repository_' . $type;
         try {
             $repo = new $classname($repo_id, $contextid, array('ajax'=>false, 'name'=>$repository->name));
similarity index 99%
rename from repository/flickr_public/repository.class.php
rename to repository/flickr_public/lib.php
index bbc0e4c..ab508e1 100644 (file)
@@ -389,6 +389,7 @@ class repository_flickr_public extends repository {
     public function get_link($photo_id) {
         global $CFG;
         $result = $this->flickr->photos_getSizes($photo_id);
+        throw new file_exception('abc');
         $url = '';
         if(!empty($result[4])) {
             $url = $result[4]['source'];
similarity index 97%
rename from repository/googledocs/repository.class.php
rename to repository/googledocs/lib.php
index 9c8a020..1a58b56 100644 (file)
@@ -68,7 +68,7 @@ class repository_googledocs extends repository {
             $ret = array();
             $popup_btn = new stdclass;
             $popup_btn->type = 'popup';
-            $returnurl = $CFG->wwwroot.'/repository/repository_callback.php?repo_id='.$this->id;
+            $returnurl = $CFG->wwwroot.'/repository/repository_ajax.php?callback=yes&repo_id='.$this->id;
             $popup_btn->url = google_authsub::login_url($returnurl, google_docs::REALM);
             $ret['login'] = array($popup_btn);
             return $ret;
index 4ac21bf..a423437 100644 (file)
@@ -426,7 +426,7 @@ class repository_type {
  * To use repository plugin, see:
  * http://docs.moodle.org/en/Development:Repository_How_to_Create_Plugin
  * class repository is an abstract class, some functions must be implemented in subclass.
- * See an example: repository/boxnet/repository.class.php
+ * See an example: repository/boxnet/lib.php
  *
  * A few notes:
  *   // for ajax file picker, this will print a json string to tell file picker
@@ -457,15 +457,20 @@ abstract class repository {
      * 1. Initialize context and options
      * 2. Accept necessary parameters
      *
-     * @param integer $repositoryid
-     * @param integer $contextid
-     * @param array $options
+     * @param integer $repositoryid repository instance id
+     * @param integer|object a context id or context object
+     * @param array $options repository options
      */
-    public function __construct($repositoryid, $contextid = SYSCONTEXTID, $options = array(), $readonly = 0) {
+    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array(), $readonly = 0) {
         $this->id = $repositoryid;
-        $this->context = get_context_instance_by_id($contextid);
+        if (!empty($context->id)) {
+            $this->context = $context;
+        } else {
+            $this->context = get_context_instance_by_id($context);
+        }
         $this->readonly = $readonly;
         $this->options = array();
+
         if (is_array($options)) {
             $options = array_merge($this->get_option(), $options);
         } else {
@@ -480,10 +485,10 @@ abstract class repository {
     }
 
     /**
-     * Return a type for a given type name.
+     * Get a repository type object by a given type name.
      * @global object $DB
-     * @param string $typename the type name
-     * @return repository_type
+     * @param string $typename the repository type name
+     * @return repository_type|bool
      */
     public static function get_type_by_typename($typename) {
         global $DB;
@@ -496,7 +501,7 @@ abstract class repository {
     }
 
     /**
-     * Return a type for a given type id.
+     * Get the repository type by a given repository type id.
      * @global object $DB
      * @param int $id the type id
      * @return object
@@ -512,9 +517,10 @@ abstract class repository {
     }
 
     /**
-     * Return all repository types ordered by sortorder
-     * first type in returnedarray[0], second type in returnedarray[1], ...
+     * Return all repository types ordered by sortorder field
+     * first repository type in returnedarray[0], second repository type in returnedarray[1], ...
      * @global object $DB
+     * @global object $CFG
      * @param boolean $visible can return types by visiblity, return all types if null
      * @return array Repository types
      */
@@ -528,7 +534,7 @@ abstract class repository {
         }
         if ($records = $DB->get_records('repository',$params,'sortorder')) {
             foreach($records as $type) {
-                if (file_exists($CFG->dirroot . '/repository/'. $type->type .'/repository.class.php')) {
+                if (file_exists($CFG->dirroot . '/repository/'. $type->type .'/lib.php')) {
                     $types[] = new repository_type($type->type, (array)get_config($type->type), $type->visible, $type->sortorder);
                 }
             }
@@ -538,14 +544,15 @@ abstract class repository {
     }
 
     /**
-     * Check context
-     * @param int $ctx_id
+     * To check if the context id is valid
+     * @global object $USER
+     * @param int $contextid
      * @return boolean
      */
-    public static function check_context($ctx_id) {
+    public static function check_context($contextid) {
         global $USER;
 
-        $context = get_context_instance_by_id($ctx_id);
+        $context = get_context_instance_by_id($contextid);
         $level = $context->contextlevel;
 
         if ($level == CONTEXT_COURSE) {
@@ -556,7 +563,7 @@ abstract class repository {
             }
         } else if ($level == CONTEXT_USER) {
             $c = get_context_instance(CONTEXT_USER, $USER->id);
-            if ($c->id == $ctx_id) {
+            if ($c->id == $contextid) {
                 return true;
             } else {
                 return false;
@@ -626,8 +633,8 @@ abstract class repository {
         }
 
         $onlyvisible = isset($args['onlyvisible']) ? $args['onlyvisible'] : true;
+        $returntypes = isset($args['return_types']) ? $args['return_types'] : 3;
         $type        = isset($args['type']) ? $args['type'] : null;
-        $returntypes   = isset($args['return_types']) ? $args['return_types'] : 3;
 
         $params = array();
         $sql = "SELECT i.*, r.type AS repositorytype, r.sortorder, r.visible
@@ -681,10 +688,10 @@ abstract class repository {
             $accepted_types = '*';
         }
         foreach ($records as $record) {
-            if (!file_exists($CFG->dirroot . '/repository/'. $record->repositorytype.'/repository.class.php')) {
+            if (!file_exists($CFG->dirroot . '/repository/'. $record->repositorytype.'/lib.php')) {
                 continue;
             }
-            require_once($CFG->dirroot . '/repository/'. $record->repositorytype.'/repository.class.php');
+            require_once($CFG->dirroot . '/repository/'. $record->repositorytype.'/lib.php');
             $options['visible'] = $record->visible;
             $options['name']    = $record->name;
             $options['type']    = $record->repositorytype;
@@ -723,12 +730,10 @@ abstract class repository {
                     }
                 }
                 if (!$onlyvisible || ($repository->is_visible() && !$repository->disabled)) {
-
                     // check capability in current context
                     if (!empty($current_context)) {
                         $capability = has_capability('repository/'.$record->repositorytype.':view', $current_context);
                     } else {
-                        // TODO: what should we do if current context isn't set?
                         $capability = has_capability('repository/'.$record->repositorytype.':view', get_system_context());
                     }
                     if ($is_supported && $capability) {
@@ -757,8 +762,7 @@ abstract class repository {
         if (!$instance = $DB->get_record_sql($sql, array($id))) {
             return false;
         }
-        require_once($CFG->dirroot . '/repository/'. $instance->repositorytype
-                . '/repository.class.php');
+        require_once($CFG->dirroot . '/repository/'. $instance->repositorytype.'/lib.php');
         $classname = 'repository_' . $instance->repositorytype;
         $options['typeid'] = $instance->typeid;
         $options['type']   = $instance->repositorytype;
@@ -771,7 +775,7 @@ abstract class repository {
     }
 
     /**
-     * call a static function.  Any additional arguments than plugin and function will be passed through.
+     * Call a static function. Any additional arguments than plugin and function will be passed through.
      * @global object $CFG
      * @param string $plugin
      * @param string $function
@@ -781,7 +785,7 @@ abstract class repository {
         global $CFG;
 
         //check that the plugin exists
-        $typedirectory = $CFG->dirroot . '/repository/'. $plugin . '/repository.class.php';
+        $typedirectory = $CFG->dirroot . '/repository/'. $plugin . '/lib.php';
         if (!file_exists($typedirectory)) {
             //throw new repository_exception('invalidplugin', 'repository');
             return false;
@@ -798,8 +802,7 @@ abstract class repository {
         $args = func_get_args();
         if (count($args) <= 2) {
             $args = array();
-        }
-        else {
+        } else {
             array_shift($args);
             array_shift($args);
         }
@@ -963,13 +966,12 @@ abstract class repository {
         //if the context is SYSTEM, so we call it from administration page
         $admin = ($context->id == SYSCONTEXTID) ? true : false;
         if ($admin) {
-            $baseurl = "$CFG->httpswwwroot/$CFG->admin/repositoryinstance.php?sesskey=" . sesskey();
-            $output .= "<div ><h2 style='text-align: center'>" . get_string('siteinstances', 'repository') . " ";
-            $output .= "</h2></div>";
+            $baseurl = new moodle_url('/'.$CFG->admin.'/repositoryinstance.php', array('sesskey'=>sesskey()));
+            $output .= $OUTPUT->heading(get_string('siteinstances', 'repository'));
         } else {
-            $baseurl = $CFG->httpswwwroot . '/repository/manage_instances.php?contextid=' . $context->id . '&amp;sesskey=' . sesskey();
+            $baseurl = new moodle_url('/repository/manage_instances.php', array('contextid'=>$context->id, 'sesskey'=>sesskey()));
         }
-        $url = new moodle_url($baseurl);
+        $url = $baseurl;
 
         $namestr = get_string('name');
         $pluginstr = get_string('plugin', 'repository');
@@ -1044,8 +1046,9 @@ abstract class repository {
                 if (!empty($type) && $type->get_visible()) {
                     $instanceoptionnames = repository::static_function($type->get_typename(), 'get_instance_option_names');
                     if (!empty($instanceoptionnames)) {
-                        $instancehtml .= '<li><a href="'.$baseurl.'&amp;new='.$type->get_typename().'">'.get_string('createxxinstance', 'repository', get_string('pluginname', 'repository_'.$type->get_typename()))
-                            .'</a></li>';
+                        $baseurl->param('new', $type->get_typename());
+                        $instancehtml .= '<li><a href="'.$baseurl->out().'">'.get_string('createxxinstance', 'repository', get_string('pluginname', 'repository_'.$type->get_typename())).  '</a></li>';
+                        $baseurl->remove_params('new');
                         $addable++;
                     }
                 }
@@ -1056,9 +1059,11 @@ abstract class repository {
             $instanceoptionnames = repository::static_function($typename, 'get_instance_option_names');
             if (!empty($instanceoptionnames)) {   //create a unique type of instance
                 $addable = 1;
-                $instancehtml .= "<form action='".$baseurl."&amp;new=".$typename."' method='post'>
-                    <p style='text-align:center'><input type='submit' value='".get_string('createinstance', 'repository')."'/></p>
+                $baseurl->param('new', $typename);
+                $instancehtml .= "<form action='".$baseurl->out()."' method='post'>
+                    <p><input type='submit' value='".get_string('createinstance', 'repository')."'/></p>
                     </form>";
+                $baseurl->remove_params('new');
             }
         }
 
@@ -1074,8 +1079,7 @@ abstract class repository {
     }
 
     /**
-     * Decide where to save the file, can be
-     * reused by sub class
+     * Decide where to save the file, can be overwriten by subclass
      * @param string filename
      */
     public function prepare_file($filename) {
@@ -1217,7 +1221,7 @@ abstract class repository {
     public static function create($type, $userid, $context, $params, $readonly=0) {
         global $CFG, $DB;
         $params = (array)$params;
-        require_once($CFG->dirroot . '/repository/'. $type . '/repository.class.php');
+        require_once($CFG->dirroot . '/repository/'. $type . '/lib.php');
         $classname = 'repository_' . $type;
         if ($repo = $DB->get_record('repository', array('type'=>$type))) {
             $record = new stdclass;
@@ -1289,37 +1293,6 @@ abstract class repository {
         return false;
     }
 
-    /**
-     * Cache login details for repositories
-     * @global object $DB
-     * @param string $username
-     * @param string $password
-     * @param integer $userid The id of specific user
-     * @return integer Id of the record
-     */
-    public function store_login($username = '', $password = '', $userid = 1) {
-        global $DB;
-
-        $repository = new stdclass;
-        if (!empty($this->id)) {
-            $repository->id = $this->id;
-        } else {
-            $repository->userid         = $userid;
-            $repository->repositorytype = $this->type;
-            $repository->contextid      = $this->context->id;
-        }
-        if ($entry = $DB->get_record('repository', $repository)) {
-            $repository->id = $entry->id;
-            $repository->username = $username;
-            $repository->password = $password;
-            return $DB->update_record('repository', $repository);
-        } else {
-            $repository->username = $username;
-            $repository->password = $password;
-            return $DB->insert_record('repository', $repository);
-        }
-    }
-
     /**
      * Save settings for repository instance
      * $repo->set_option(array('api_key'=>'f2188bde132', 'name'=>'dongsheng'));
@@ -1548,6 +1521,7 @@ abstract class repository {
     public static function get_instance_option_names() {
         return array();
     }
+
     public function get_short_filename($str, $maxlength) {
         if (strlen($str) >= $maxlength) {
             return trim(substr($str, 0, $maxlength)).'...';
@@ -1569,8 +1543,6 @@ abstract class repository {
 class repository_exception extends moodle_exception {
 }
 
-
-
 /**
  * This is a class used to define a repository instance form
  *
index 971b551..d71d0b0 100644 (file)
@@ -1,5 +1,20 @@
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 function xmldb_repository_local_install() {
     global $CFG;
     $result = true;
similarity index 91%
rename from repository/local/repository.class.php
rename to repository/local/lib.php
index f5df313..ca06fdf 100755 (executable)
@@ -75,7 +75,6 @@ class repository_local extends repository {
                 $itemid   = $params['itemid'];
                 $filename = $params['filename'];
                 $filearea = $params['filearea'];
-                $component = $params['component'];
                 $filepath = $params['filepath'];
                 $context  = get_context_instance_by_id($params['contextid']);
             }
@@ -83,7 +82,6 @@ class repository_local extends repository {
             $itemid   = null;
             $filename = null;
             $filearea = null;
-            $component = null;
             $filepath = null;
             $context  = get_system_context();
         }
@@ -91,7 +89,7 @@ class repository_local extends repository {
         try {
             $browser = get_file_browser();
 
-            if ($fileinfo = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename)) {
+            if ($fileinfo = $browser->get_file_info($context, $filearea, $itemid, $filepath, $filename)) {
                 // build path navigation
                 $pathnodes = array();
                 $encodedpath = base64_encode(serialize($fileinfo->get_params()));
@@ -119,7 +117,7 @@ class repository_local extends repository {
                         $encodedpath = base64_encode(serialize($params));
                         // hide user_private area from local plugin, user should
                         // use private file plugin to access private files
-                        if ($params['component'] = 'user' and $params['filearea'] == 'private') {
+                        if ($params['filearea'] == 'user_private') {
                             continue;
                         }
                         $node = array(
@@ -184,7 +182,7 @@ class repository_local extends repository {
      * @param string $new_filepath the new path in draft area
      * @return array The information of file
      */
-    public function copy_to_area($encoded, $new_filearea='ignored', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
+    public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
         global $USER, $DB;
         $info = array();
 
@@ -193,15 +191,14 @@ class repository_local extends repository {
         $user_context = get_context_instance(CONTEXT_USER, $USER->id);
         // the final file
         $contextid  = $params['contextid'];
-        $component  = $params['component'];
         $filearea   = $params['filearea'];
         $filepath   = $params['filepath'];
         $filename   = $params['filename'];
         $fileitemid = $params['itemid'];
         $context    = get_context_instance_by_id($contextid);
         try {
-            $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename);
-            $file_info->copy_to_storage($user_context->id, 'user', 'draft', $new_itemid, $new_filepath, $new_filename);
+            $file_info = $browser->get_file_info($context, $filearea, $fileitemid, $filepath, $filename);
+            $file_info->copy_to_storage($user_context->id, $new_filearea, $new_itemid, $new_filepath, $new_filename);
         } catch (Exception $e) {
             throw $e;
         }
similarity index 97%
rename from repository/picasa/repository.class.php
rename to repository/picasa/lib.php
index 7de106d..bc9128a 100644 (file)
@@ -65,7 +65,7 @@ class repository_picasa extends repository {
 
     public function print_login(){
         global $CFG;
-        $returnurl = $CFG->wwwroot.'/repository/repository_callback.php?repo_id='.$this->id;
+        $returnurl = $CFG->wwwroot.'/repository/repository_ajax.php?callback=yes&repo_id='.$this->id;
         $authurl = google_authsub::login_url($returnurl, google_picasa::REALM);
         if($this->options['ajax']){
             $ret = array();
similarity index 85%
rename from repository/recent/repository.class.php
rename to repository/recent/lib.php
index 78d7431..c431950 100755 (executable)
@@ -30,7 +30,7 @@ define('DEFAULT_RECENT_FILES_NUM', 50);
 class repository_recent extends repository {
 
     /**
-     * initialize recent plugin
+     * Initialize recent plugin
      * @param int $repositoryid
      * @param int $context
      * @param array $options
@@ -65,23 +65,20 @@ class repository_recent extends repository {
 
     private function get_recent_files($limitfrom = 0, $limit = DEFAULT_RECENT_FILES_NUM) {
         global $USER, $DB;
-
-        // TODO: this is not really secure, we should validate the result with file_browser (skodak)
-
+        // TODO: should exclude user_draft area files?
         $sql = 'SELECT * FROM {files} files1
                 JOIN (SELECT contenthash, filename, MAX(id) AS id
                 FROM {files}
-                WHERE userid = :userid AND filename != :filename AND filearea != :filearea
+                WHERE userid = ? AND filename != ? AND filearea != ?
                 GROUP BY contenthash, filename) files2 ON files1.id = files2.id
                 ORDER BY files1.timemodified DESC';
-        $params = array('userid'=>$USER->id, 'filename'=>'.', 'filearea'=>'draft');
+        $params = array('userid'=>$USER->id, 'filename'=>'.', 'filearea'=>'user_draft');
         $rs = $DB->get_recordset_sql($sql, $params, $limitfrom, $limit);
         $result = array();
         foreach ($rs as $file_record) {
             $info = array();
             $info['contextid'] = $file_record->contextid;
             $info['itemid'] = $file_record->itemid;
-            $info['component'] = $file_record->component;
             $info['filearea'] = $file_record->filearea;
             $info['filepath'] = $file_record->filepath;
             $info['filename'] = $file_record->filename;
@@ -124,7 +121,6 @@ class repository_recent extends repository {
         } catch (Exception $e) {
             throw new repository_exception('emptyfilelist', 'repository_recent');
         }
-        $ret['list'] = $list;
         $ret['list'] = array_filter($list, array($this, 'filter'));
         return $ret;
     }
@@ -165,13 +161,13 @@ class repository_recent extends repository {
      *
      * @global object $USER
      * @global object $DB
-     * @param string $encoded The information of file, it is base64 encoded php serialized data
+     * @param string $encoded The information of file, it is base64 encoded php seriablized data
      * @param string $new_filename The intended name of file
      * @param string $new_itemid itemid
      * @param string $new_filepath the new path in draft area
      * @return array The information of file
      */
-    public function copy_to_area($encoded, $new_filearea='ignored', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
+    public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
         global $USER, $DB;
         $info = array();
         $fs = get_file_storage();
@@ -179,10 +175,7 @@ class repository_recent extends repository {
         $params = unserialize(base64_decode($encoded));
         $user_context = get_context_instance(CONTEXT_USER, $USER->id);
 
-        //TODO: this is really HORRIBLE!!! Where is any security check??????? (skodak)
-
         $contextid  = $params['contextid'];
-        $component  = $params['component'];
         $filearea   = $params['filearea'];
         $filepath   = $params['filepath'];
         $filename   = $params['filename'];
@@ -191,17 +184,14 @@ class repository_recent extends repository {
         // XXX:
         // When user try to pick a file from other filearea, normally file api will use file browse to
         // operate the files with capability check, but in some areas, users don't have permission to
-        // browse the files (for example, forum attachment area).
+        // browse the files (for example, forum_attachment area).
         //
         // To get 'recent' plugin working, we need to use lower level file_stoarge class to bypass the
         // capability check, we will use a better workaround to improve it.
-        //
-        // TODO: no this is a BIG security hole, we should really use file_browser here and instead filter the available files (skodak)
-        //
-        if ($stored_file = $fs->get_file($contextid, $component, $filearea, $fileitemid, $filepath, $filename)) {
-            $file_record = array('contextid'=>$user_context->id, 'component'=>'user', 'filearea'=>'draft',
+        if ($stored_file = $fs->get_file($contextid, $filearea, $fileitemid, $filepath, $filename)) {
+            $file_record = array('contextid'=>$user_context->id, 'filearea'=>$new_filearea,
                 'itemid'=>$new_itemid, 'filepath'=>$new_filepath, 'filename'=>$new_filename);
-            if ($file = $fs->get_file($user_context->id, 'user' ,'draft', $new_itemid, $new_filepath, $new_filename)) {
+            if ($file = $fs->get_file($user_context->id, $new_filearea, $new_itemid, $new_filepath, $new_filename)) {
                 $file->delete();
             }
             $fs->create_file_from_storedfile($file_record, $stored_file);
index 7c5de1d..53c07de 100755 (executable)
@@ -26,6 +26,8 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+define('AJAX_SCRIPT', true);
+
 require_once(dirname(dirname(__FILE__)).'/config.php');
 require_once(dirname(dirname(__FILE__)).'/lib/filelib.php');
 require_once(dirname(__FILE__).'/lib.php');
@@ -35,7 +37,6 @@ require_login();
 /// Parameters
 $action    = optional_param('action', '', PARAM_ALPHA);
 $repo_id   = optional_param('repo_id', 0, PARAM_INT);           // Pepository ID
-$client_id = optional_param('client_id', '', PARAM_RAW);        // Client ID
 $contextid = optional_param('ctx_id', SYSCONTEXTID, PARAM_INT); // Context ID
 $env       = optional_param('env', 'filepicker', PARAM_ALPHA);  // Opened in editor or moodleform
 $license   = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT);
@@ -45,6 +46,7 @@ $itemid    = optional_param('itemid', 0, PARAM_INT);            // Itemid
 $page      = optional_param('page', '', PARAM_RAW);             // Page
 $maxbytes  = optional_param('maxbytes', 0, PARAM_INT);          // Maxbytes
 $req_path  = optional_param('p', '', PARAM_RAW);                // Path
+$accepted_types  = optional_param('accepted_types', '*', PARAM_RAW);
 $saveas_filename = optional_param('title', '', PARAM_FILE);     // save as file name
 $saveas_path   = optional_param('savepath', '/', PARAM_PATH);   // save as file path
 $search_text   = optional_param('s', '', PARAM_CLEANHTML);
@@ -55,7 +57,6 @@ header('Cache-Control: no-cache, must-revalidate');
 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
 
 $err = new stdclass;
-$err->client_id = $client_id;
 
 if (!confirm_sesskey()) {
     $err->error = get_string('invalidsesskey');
@@ -64,7 +65,7 @@ if (!confirm_sesskey()) {
 
 /// Check permissions
 if (! (isloggedin() && repository::check_context($contextid)) ) {
-    $err->e = get_string('nopermissiontoaccess', 'repository');
+    $err->error = get_string('nopermissiontoaccess', 'repository');
     die(json_encode($err));
 }
 
@@ -88,20 +89,14 @@ switch ($action) {
         $list = array();
         foreach($repos as $repo){
             if ($repo->global_search()) {
-                try {
-                    $ret = $repo->search($search_text);
-                    array_walk($ret['list'], 'repository_attach_id', $repo->id);  // See function below
-                    $tmp = array_merge($list, $ret['list']);
-                    $list = $tmp;
-                } catch (repository_exception $e) {
-                    $err->e = $e->getMessage();
-                    die(json_encode($err));
-                }
+                $ret = $repo->search($search_text);
+                array_walk($ret['list'], 'repository_attach_id', $repo->id);  // See function below
+                $tmp = array_merge($list, $ret['list']);
+                $list = $tmp;
             }
         }
         $listing = array('list'=>$list);
         $listing['gsearch'] = true;
-        $listing['client_id'] = $client_id;
         die(json_encode($listing));
         break;
 
@@ -118,23 +113,18 @@ $sql = 'SELECT i.name, i.typeid, r.type FROM {repository} r, {repository_instanc
        'WHERE i.id=? AND i.typeid=r.id';
 
 if (!$repository = $DB->get_record_sql($sql, array($repo_id))) {
-    $err->e = get_string('invalidrepositoryid', 'repository');
+    $err->error = get_string('invalidrepositoryid', 'repository');
     die(json_encode($err));
 } else {
     $type = $repository->type;
 }
 
-if (file_exists($CFG->dirroot.'/repository/'.$type.'/repository.class.php')) {
-    require_once($CFG->dirroot.'/repository/'.$type.'/repository.class.php');
+if (file_exists($CFG->dirroot.'/repository/'.$type.'/lib.php')) {
+    require_once($CFG->dirroot.'/repository/'.$type.'/lib.php');
     $classname = 'repository_' . $type;
-    try {
-        $repo = new $classname($repo_id, $contextid, array('ajax'=>true, 'name'=>$repository->name, 'type'=>$type, 'client_id'=>$client_id));
-    } catch (repository_exception $e){
-        $err->e = $e->getMessage();
-        die(json_encode($err));
-    }
+    $repo = new $classname($repo_id, $contextid, array('ajax'=>true, 'name'=>$repository->name, 'type'=>$type));
 } else {
-    $err->e = get_string('invalidplugin', 'repository', $type);
+    $err->error = get_string('invalidplugin', 'repository', $type);
     die(json_encode($err));
 }
 
@@ -144,160 +134,132 @@ switch ($action) {
     case 'signin':
     case 'list':
         if ($repo->check_login()) {
-            try {
-                $listing = $repo->get_listing($req_path, $page);
-                $listing['client_id'] = $client_id;
-                $listing['repo_id'] = $repo_id;
-                echo json_encode($listing);
-            } catch (repository_exception $e) {
-                $err->e = $e->getMessage();
-                die(json_encode($err));
-            }
+            $listing = $repo->get_listing($req_path, $page);
+            $listing['repo_id'] = $repo_id;
+            echo json_encode($listing);
             break;
         } else {
             $action = 'login';
         }
     case 'login':
-        try {
-            $listing = $repo->print_login();
-            $listing['client_id'] = $client_id;
-            $listing['repo_id'] = $repo_id;
-            echo json_encode($listing);
-        } catch (repository_exception $e){
-            $err->e = $e->getMessage();
-            die(json_encode($err));
-        }
+        $listing = $repo->print_login();
+        $listing['repo_id'] = $repo_id;
+        echo json_encode($listing);
         break;
     case 'logout':
         $logout = $repo->logout();
-        $logout['client_id'] = $client_id;
         $logout['repo_id'] = $repo_id;
         echo json_encode($logout);
         break;
     case 'searchform':
-        $search_form['form'] = $repo->print_search($client_id);
-        $search_form['client_id'] = $client_id;
+        $search_form['form'] = $repo->print_search();
         echo json_encode($search_form);
         break;
     case 'search':
-        try {
-            $search_result = $repo->search($search_text, (int)$page);
-            $search_result['client_id'] = $client_id;
-            $search_result['repo_id'] = $repo_id;
-            $search_result['search_result'] = true;
-            echo json_encode($search_result);
-        } catch (repository_exception $e) {
-            $err->e = $e->getMessage();
-            die(json_encode($err));
-        }
+        $search_result = $repo->search($search_text, (int)$page);
+        $search_result['repo_id'] = $repo_id;
+        $search_result['search_result'] = true;
+        echo json_encode($search_result);
         break;
     case 'download':
-        try {
-            // We have two special repoisitory type need to deal with
-            // local and recent plugins don't added new files to moodle, just add new records to database
-            // so we don't check user quota and maxbytes here
-            if (in_array($repo->options['type'], array('local', 'recent', 'user'))) {
-                try {
-                    $fileinfo = $repo->copy_to_area($source, 'draft', $itemid, $saveas_path, $saveas_filename);
-                } catch (Exception $e) {
-                    throw $e;
-                }
+        // validate mimetype
+        $mimetypes = array();
+        if (in_array('*', $accepted_types) or $accepted_types == '*') {
+            $mimetypes = '*';
+        } else {
+            foreach ($accepted_types as $type) {
+                $mimetypes = mimeinfo('type', $type);
+            }
+            if (!in_array(mimeinfo('type', $saveas_filename), $mimetypes)) {
+                throw new moodle_exception('invalidfiletype', 'repository', '', mimeinfo('type', $_FILES[$elname]['name']));
+            }
+        }
+
+        // We have two special repoisitory type need to deal with
+        // local and recent plugins don't added new files to moodle, just add new records to database
+        // so we don't check user quota and maxbytes here
+        if (in_array($repo->options['type'], array('local', 'recent', 'user'))) {
+            $fileinfo = $repo->copy_to_area($source, 'draft', $itemid, $saveas_path, $saveas_filename);
+            $info = array();
+            $info['file'] = $fileinfo['title'];
+            $info['id'] = $itemid;
+            $info['url'] = $CFG->httpswwwroot.'/draftfile.php/'.$fileinfo['contextid'].'/user_draft/'.$itemid.'/'.$fileinfo['title'];
+            $filesize = $fileinfo['filesize'];
+            if (($maxbytes!==-1) && ($filesize>$maxbytes)) {
+                throw new file_exception('maxbytes');
+            }
+            echo json_encode($info);
+            die; // ends here!!
+        } else {
+            $allowexternallink = (int)get_config(null, 'repositoryallowexternallinks');
+            if (!empty($allowexternallink)) {
+                $allowexternallink = true;
+            } else {
+                $allowexternallink = false;
+            }
+            // allow external links in url element all the time
+            $allowexternallink = ($allowexternallink || ($env == 'url'));
+
+            // Use link of the files
+            if ($allowexternallink and $linkexternal === 'yes' and ($repo->supported_returntypes() & FILE_EXTERNAL)) {
+                // use external link
+                $link = $repo->get_link($source);
                 $info = array();
-                $info['client_id'] = $client_id;
-                $info['file'] = $fileinfo['title'];
-                $info['id'] = $itemid;
-                $info['url'] = $CFG->httpswwwroot.'/draftfile.php/'.$fileinfo['contextid'].'/user_draft/'.$itemid.'/'.$fileinfo['title'];
-                $filesize = $fileinfo['filesize'];
-                if (($maxbytes!==-1) && ($filesize>$maxbytes)) {
-                    throw new file_exception('maxbytes');
-                }
+                $info['filename'] = $saveas_filename;
+                $info['type'] = 'link';
+                $info['url'] = $link;
                 echo json_encode($info);
-                die; // ends here!!
+                die;
             } else {
-                $allowexternallink = (int)get_config(null, 'repositoryallowexternallinks');
-                if (!empty($allowexternallink)) {
-                    $allowexternallink = true;
-                } else {
-                    $allowexternallink = false;
+                // Download file to moodle
+                $file = $repo->get_file($source, $saveas_filename);
+                if ($file['path'] === false) {
+                    $err->error = get_string('cannotdownload', 'repository');
+                    die(json_encode($err));
                 }
-                // allow external links in url element all the time
-                $allowexternallink = ($allowexternallink || ($env == 'url'));
-
-                // Use link of the files
-                if ($allowexternallink and $linkexternal === 'yes' and ($repo->supported_returntypes() || FILE_EXTERNAL)) {
-                    // use external link
-                    try {
-                        $link = $repo->get_link($source);
-                    } catch (repository_exception $e){
-                        throw $e;
-                    }
-                    $info = array();
-                    $info['filename'] = $saveas_filename;
-                    $info['type'] = 'link';
-                    $info['url'] = $link;
-                    echo json_encode($info);
-                    die;
-                } else {
-                    // Download file to moodle
-                    $file = $repo->get_file($source, $saveas_filename);
-                    if ($file['path'] === false) {
-                        $err->e = get_string('cannotdownload', 'repository');
-                        die(json_encode($err));
-                    }
 
-                    // check if exceed maxbytes
-                    if (($maxbytes!==-1) && (filesize($file['path']) > $maxbytes)) {
-                        throw new file_exception('maxbytes');
-                    }
+                // check if exceed maxbytes
+                if (($maxbytes!==-1) && (filesize($file['path']) > $maxbytes)) {
+                    throw new file_exception('maxbytes');
+                }
 
-                    // check if exceed user quota
-                    $userquota = file_get_user_used_space();
-                    if (filesize($file['path'])+$userquota>=(int)$CFG->userquota) {
-                        throw new file_exception('userquotalimit');
-                    }
+                // check if exceed user quota
+                $userquota = file_get_user_used_space();
+                if (filesize($file['path'])+$userquota>=(int)$CFG->userquota) {
+                    throw new file_exception('userquotalimit');
+                }
 
-                    $record = new stdclass;
-                    $record->filepath = $saveas_path;
-                    $record->filename = $saveas_filename;
-                    $record->component = 'user';
-                    $record->filearea = 'draft';
-                    $record->itemid   = $itemid;
+                $record = new stdclass;
+                $record->filepath = $saveas_path;
+                $record->filename = $saveas_filename;
+                $record->component = 'user';
+                $record->filearea = 'draft';
+                $record->itemid   = $itemid;
 
-                    if (!empty($file['license'])) {
-                        $record->license  = $file['license'];
-                    } else {
-                        $record->license  = $license;
-                    }
-                    if (!empty($file['author'])) {
-                        $record->author   = $file['author'];
-                    } else {
-                        $record->author   = $author;
-                    }
-                    $record->source = !empty($file['url']) ? $file['url'] : '';
+                if (!empty($file['license'])) {
+                    $record->license  = $file['license'];
+                } else {
+                    $record->license  = $license;
+                }
+                if (!empty($file['author'])) {
+                    $record->author   = $file['author'];
+                } else {
+                    $record->author   = $author;
+                }
+                $record->source = !empty($file['url']) ? $file['url'] : '';
 
-                    $info = repository::move_to_filepool($file['path'], $record);
-                    if (empty($info)) {
-                        $info['e'] = get_string('error', 'moodle');
-                    }
-                    echo json_encode($info);
-                    die;
+                $info = repository::move_to_filepool($file['path'], $record);
+                if (empty($info)) {
+                    $info['e'] = get_string('error', 'moodle');
                 }
+                echo json_encode($info);
+                die;
             }
-        } catch (Exception $e) {
-            $err->e = $e->getMessage();
-            die(json_encode($err));
         }
         break;
     case 'upload':
-        try {
-            $result = $repo->upload();
-            $result['client_id'] = $client_id;
-            echo json_encode($result);
-        } catch (Exception $e){
-            $err->e = $e->getMessage();
-            $err->client_id = $client_id;
-            die(json_encode($err));
-        }
+        $result = $repo->upload();
+        echo json_encode($result);
         break;
 }
 
index f24116e..ab73445 100755 (executable)
@@ -17,7 +17,7 @@
 
 
 /**
- * The Web service script that is called from the filepicker front end
+ * Repository instance callback script
  *
  * @since 2.0
  * @package moodlecore
@@ -33,36 +33,27 @@ require_once(dirname(__FILE__).'/lib.php');
 require_login();
 
 /// Parameters
-
-$repo_id   = required_param('repo_id', PARAM_INT);           // Repository ID
-
-$client_id = optional_param('client_id', '', PARAM_RAW);        // Client ID
-$contextid = optional_param('ctx_id', SYSCONTEXTID, PARAM_INT); // Context ID
+$repo_id   = required_param('repo_id', PARAM_INT); // Repository ID
 
 /// Headers to make it not cacheable
 header('Cache-Control: no-cache, must-revalidate');
 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
 
-/// Check permissions
-if (repository::check_context($contextid)) { //TODO: this is weird (skodak)
-    print_error('nopermissiontoaccess', 'repository');
-}
-
 /// Wait as long as it takes for this script to finish
 set_time_limit(0);
 
 /// Get repository instance information
-$sql = 'SELECT i.name, i.typeid, r.type FROM {repository} r, {repository_instances} i '.
+$sql = 'SELECT i.name, i.typeid, r.type, i.contextid FROM {repository} r, {repository_instances} i '.
        'WHERE i.id=? AND i.typeid=r.id';
 
 $repository = $DB->get_record_sql($sql, array($repo_id), '*', MUST_EXIST);
 
 $type = $repository->type;
 
-if (file_exists($CFG->dirroot.'/repository/'.$type.'/repository.class.php')) {
-    require_once($CFG->dirroot.'/repository/'.$type.'/repository.class.php');
+if (file_exists($CFG->dirroot.'/repository/'.$type.'/lib.php')) {
+    require_once($CFG->dirroot.'/repository/'.$type.'/lib.php');
     $classname = 'repository_' . $type;
-    $repo = new $classname($repo_id, $contextid, array('ajax'=>true, 'name'=>$repository->name, 'type'=>$type, 'client_id'=>$client_id)); //TODO: this is very weird constructor! (skodak)
+    $repo = new $classname($repo_id, $repository->contextid);
 } else {
     print_error('invalidplugin', 'repository', $type);
 }
index a3443dd..e9ad182 100644 (file)
@@ -1,5 +1,20 @@
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 function xmldb_repository_upload_install() {
     global $CFG;
     $result = true;
similarity index 56%
rename from repository/upload/repository.class.php
rename to repository/upload/lib.php
index 3e3ce48..ae717b8 100755 (executable)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * repository_upload class
- * A subclass of repository, which is used to upload file
+ * A repository plugin to allow user uploading files
  *
  * @since 2.0
  * @package moodlecore
  * @subpackage repository
  * @copyright 2009 Dongsheng Cai
  * @author Dongsheng Cai <dongsheng@moodle.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 class repository_upload extends repository {
-
-    /**
-     *
-     * @param int $repositoryid
-     * @param object $context
-     * @param array $options
-     */
-    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()){
-        global $CFG;
-        parent::__construct($repositoryid, $context, $options);
-        $this->itemid = optional_param('itemid', '', PARAM_INT);
-        $this->license = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT);
-        $this->author = optional_param('author', '', PARAM_TEXT);
-        $this->filepath = urldecode(optional_param('savepath', '/', PARAM_PATH));
-    }
+    private $mimetypes = array();
 
     /**
      * Print a upload form
-     *
      * @return array
      */
     public function print_login() {
@@ -55,74 +39,36 @@ class repository_upload extends repository {
 
     /**
      * Process uploaded file
-     *
-     * @return array
+     * @return array|bool
      */
     public function upload() {
-        try {
-            $record = new stdclass;
-            $record->filearea = 'draft';;
-            $record->component = 'user';;
-            $record->filepath = $this->filepath;
-            $record->itemid   = $this->itemid;
-            $record->license  = $this->license;
-            $record->author   = $this->author;
-            $this->info = $this->upload_to_filepool('repo_upload_file', $record);
-        } catch(Exception $e) {
-            throw $e;
-        }
-        return $this->info;
-    }
-
-    public function get_listing() {
-        global $CFG;
-        $ret = array();
-        $ret['nologin']  = true;
-        $ret['nosearch'] = true;
-        $ret['norefresh'] = true;
-        // define upload form in file picker
-        $ret['upload'] = array('label'=>get_string('attachment', 'repository'), 'id'=>'repo-form');
+        global $USER, $CFG;
 
-        if (has_capability('moodle/course:managefiles', $this->context)) {
-            $ret['manage'] = $CFG->wwwroot .'/files/index.php';
+        $types = optional_param('accepted_types', '*', PARAM_RAW);
+        if ((is_array($types) and in_array('*', $types)) or $types == '*') {
+            $this->mimetypes = '*';
+        } else {
+            foreach ($types as $type) {
+                $this->mimetypes[] = mimeinfo('type', $type);
+            }
         }
-        $ret['list'] = array();
-        $ret['dynload'] = false;
-        return $ret;
-    }
-
-    /**
-     * Define the name of this repository
-     * @return string
-     */
-    public function get_name(){
-        return get_string('pluginname', 'repository_upload');
-    }
 
-    /**
-     * supported return types
-     * @return int
-     */
-    public function supported_returntypes() {
-        return FILE_INTERNAL;
-    }
+        $record = new stdclass;
+        $record->filearea = 'draft';
+        $record->component = 'user';
+        $record->filepath = urldecode(optional_param('savepath', '/', PARAM_PATH));
+        $record->itemid   = optional_param('itemid', 0, PARAM_INT);
+        $record->license  = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT);
+        $record->author   = optional_param('author', '', PARAM_TEXT);
 
-    /**
-     * Upload file to local filesystem pool
-     * @param string $elname name of element
-     * @param object $record
-     * @param bool $override override file if exists
-     * @return mixed stored_file object or false if error; may throw exception if duplicate found
-     */
-    public function upload_to_filepool($elname, $record, $override = true) {
-        global $USER, $CFG;
         $context = get_context_instance(CONTEXT_USER, $USER->id);
+        $elname = 'repo_upload_file';
 
         $fs = get_file_storage();
+        $browser = get_file_browser();
 
         if ($record->filepath !== '/') {
-            $record->filepath = trim($record->filepath, '/');
-            $record->filepath = '/'.$record->filepath.'/';
+            $record->filepath = file_correct_filepath($record->filepath);
         }
 
         if (!isset($_FILES[$elname])) {
@@ -137,36 +83,80 @@ class repository_upload extends repository {
             $record->filename = $_FILES[$elname]['name'];
         }
 
+        if ($this->mimetypes != '*') {
+            // check filetype
+            if (!in_array(mimeinfo('type', $_FILES[$elname]['name']), $this->mimetypes)) {
+                throw new moodle_exception('invalidfiletype', 'repository', '', mimeinfo('type', $_FILES[$elname]['name']));
+            }
+        }
+
+        $userquota = file_get_user_used_space();
+        if (filesize($_FILES[$elname]['tmp_name'])+$userquota>=(int)$CFG->userquota) {
+            throw new file_exception('userquotalimit');
+        }
+
         if (empty($record->itemid)) {
             $record->itemid = 0;
         }
 
-        if ($file = $fs->get_file($context->id, 'user', 'draft', $record->itemid, $record->filepath, $record->filename)) {
-            if ($override) {
-                $file->delete();
-            } else {
-                throw new moodle_exception('fileexist');
-            }
+        if ($file = $browser->get_file_info($context, $record->filearea, $record->itemid, $record->filepath, $record->filename)) {
+            $file->delete();
+            //throw new moodle_exception('fileexist');
         }
 
         $record->contextid = $context->id;
-        $record->component = 'user';
-        $record->filearea  = 'draft';
         $record->userid    = $USER->id;
         $record->source    = '';
 
-        try {
-            $file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
-        } catch (Exception $e) {
-            //TODO: ??? (skodak)
-            $e->obj = $_FILES[$elname];
-            throw $e;
-        }
+        $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
 
         return array(
-            'url'=>file_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename()),
+            'url'=>file_draftfile_url($record->itemid, $record->filepath, $record->filename),
             'id'=>$record->itemid,
-            'file'=>$file->get_filename()
-        );
+            'file'=>$record->filename);
+    }
+
+    /**
+     * Return a upload form
+     * @return array
+     */
+    public function get_listing() {
+        global $CFG;
+        $ret = array();
+        $ret['nologin']  = true;
+        $ret['nosearch'] = true;
+        $ret['norefresh'] = true;
+        $ret['list'] = array();
+        $ret['dynload'] = false;
+        $ret['upload'] = array('label'=>get_string('attachment', 'repository'), 'id'=>'repo-form');
+        return $ret;
+    }
+
+    /**
+     * Define the readable name of this repository
+     * @return string
+     */
+    public function get_name(){
+        return get_string('pluginname', 'repository_upload');
+    }
+
+    /**
+     * supported return types
+     * @return int
+     */
+    public function supported_returntypes() {
+        return FILE_INTERNAL;
+    }
+
+    /**
+     * Upload file to local filesystem pool
+     * @param string $elname name of element
+     * @param string $filearea
+     * @param string $filepath
+     * @param string $filename - use specified filename, if not specified name of uploaded file used
+     * @param bool $override override file if exists
+     * @return mixed stored_file object or false if error; may throw exception if duplicate found
+     */
+    public function upload_to_filepool($elname, $record, $override = true) {
     }
 }
index f9c65f8..171b6cd 100644 (file)
 <?php
 
-/**
- * Copyright (c) 2008, David R. Nadeau, NadeauSoftware.com.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the names of David R. Nadeau or NadeauSoftware.com, nor
- *       the names of its contributors may be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- */
-
-/*
- * This is a BSD License approved by the Open Source Initiative (OSI).
- * See:  http://www.opensource.org/licenses/bsd-license.php
- */
-
-/**
- * Combine a base URL and a relative URL to produce a new
- * absolute URL.  The base URL is often the URL of a page,
- * and the relative URL is a URL embedded on that page.
- *
- * This function implements the "absolutize" algorithm from
- * the RFC3986 specification for URLs.
- *
- * This function supports multi-byte characters with the UTF-8 encoding,
- * per the URL specification.
- *
- * Parameters:
- *     baseUrl         the absolute base URL.
- *
- *     url             the relative URL to convert.
- *
- * Return values:
- *     An absolute URL that combines parts of the base and relative
- *     URLs, or FALSE if the base URL is not absolute or if either
- *     URL cannot be parsed.
- */
-function url_to_absolute( $baseUrl, $relativeUrl )
-{
-       // If relative URL has a scheme, clean path and return.
-       $r = split_url( $relativeUrl );
-       if ( $r === FALSE )
-               return FALSE;
-       if ( !empty( $r['scheme'] ) )
-       {
-               if ( !empty( $r['path'] ) && $r['path'][0] == '/' )
-                       $r['path'] = url_remove_dot_segments( $r['path'] );
-               return join_url( $r );
-       }
-
-       // Make sure the base URL is absolute.
-       $b = split_url( $baseUrl );
-       if ( $b === FALSE || empty( $b['scheme'] ) || empty( $b['host'] ) )
-               return FALSE;
-       $r['scheme'] = $b['scheme'];
-
-       // If relative URL has an authority, clean path and return.
-       if ( isset( $r['host'] ) )
-       {
-               if ( !empty( $r['path'] ) )
-                       $r['path'] = url_remove_dot_segments( $r['path'] );
-               return join_url( $r );
-       }
-       unset( $r['port'] );
-       unset( $r['user'] );
-       unset( $r['pass'] );
-
-       // Copy base authority.
-       $r['host'] = $b['host'];
-       if ( isset( $b['port'] ) ) $r['port'] = $b['port'];
-       if ( isset( $b['user'] ) ) $r['user'] = $b['user'];
-       if ( isset( $b['pass'] ) ) $r['pass'] = $b['pass'];
-
-       // If relative URL has no path, use base path
-       if ( empty( $r['path'] ) )
-       {
-               if ( !empty( $b['path'] ) )
-                       $r['path'] = $b['path'];
-               if ( !isset( $r['query'] ) && isset( $b['query'] ) )
-                       $r['query'] = $b['query'];
-               return join_url( $r );
-       }
-
-       // If relative URL path doesn't start with /, merge with base path
-       if ( $r['path'][0] != '/' )
-       {
-               $base = mb_strrchr( $b['path'], '/', TRUE, 'UTF-8' );
-               if ( $base === FALSE ) $base = '';
-               $r['path'] = $base . '/' . $r['path'];
-       }
-       $r['path'] = url_remove_dot_segments( $r['path'] );
-       return join_url( $r );
-}
-
-/**
- * Filter out "." and ".." segments from a URL's path and return
- * the result.
- *
- * This function implements the "remove_dot_segments" algorithm from
- * the RFC3986 specification for URLs.
- *
- * This function supports multi-byte characters with the UTF-8 encoding,
- * per the URL specification.
- *
- * Parameters:
- *     path    the path to filter
- *
- * Return values:
- *     The filtered path with "." and ".." removed.
- */
-function url_remove_dot_segments( $path )
-{
-       // multi-byte character explode
-       $inSegs  = preg_split( '!/!u', $path );
-       $outSegs = array( );
-       foreach ( $inSegs as $seg )
-       {
-               if ( $seg == '' || $seg == '.')
-                       continue;
-               if ( $seg == '..' )
-                       array_pop( $outSegs );
-               else
-                       array_push( $outSegs, $seg );
-       }
-       $outPath = implode( '/', $outSegs );
-       if ( $path[0] == '/' )
-               $outPath = '/' . $outPath;
-       // compare last multi-byte character against '/'
-       if ( $outPath != '/' &&
-               (mb_strlen($path)-1) == mb_strrpos( $path, '/', 'UTF-8' ) )
-               $outPath .= '/';
-       return $outPath;
-}
-
-/**
- * This function parses an absolute or relative URL and splits it
- * into individual components.
- *
- * RFC3986 specifies the components of a Uniform Resource Identifier (URI).
- * A portion of the ABNFs are repeated here:
- *
- *     URI-reference   = URI
- *                     / relative-ref
- *
- *     URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
- *
- *     relative-ref    = relative-part [ "?" query ] [ "#" fragment ]
- *
- *     hier-part       = "//" authority path-abempty
- *                     / path-absolute
- *                     / path-rootless
- *                     / path-empty
- *
- *     relative-part   = "//" authority path-abempty
- *                     / path-absolute
- *                     / path-noscheme
- *                     / path-empty
- *
- *     authority       = [ userinfo "@" ] host [ ":" port ]
- *
- * So, a URL has the following major components:
- *
- *     scheme
- *             The name of a method used to interpret the rest of
- *             the URL.  Examples:  "http", "https", "mailto", "file'.
- *
- *     authority
- *             The name of the authority governing the URL's name
- *             space.  Examples:  "example.com", "user@example.com",
- *             "example.com:80", "user:password@example.com:80".
- *
- *             The authority may include a host name, port number,
- *             user name, and password.
- *
- *             The host may be a name, an IPv4 numeric address, or
- *             an IPv6 numeric address.
- *
- *     path
- *             The hierarchical path to the URL's resource.
- *             Examples:  "/index.htm", "/scripts/page.php".
- *
- *     query
- *             The data for a query.  Examples:  "?search=google.com".
- *
- *     fragment
- *             The name of a secondary resource relative to that named
- *             by the path.  Examples:  "#section1", "#header".
- *
- * An "absolute" URL must include a scheme and path.  The authority, query,
- * and fragment components are optional.
- *
- * A "relative" URL does not include a scheme and must include a path.  The
- * authority, query, and fragment components are optional.
- *
- * This function splits the $url argument into the following components
- * and returns them in an associative array.  Keys to that array include:
- *
- *     "scheme"        The scheme, such as "http".
- *     "host"          The host name, IPv4, or IPv6 address.
- *     "port"          The port number.
- *     "user"          The user name.
- *     "pass"          The user password.
- *     "path"          The path, such as a file path for "http".
- *     "query"         The query.
- *     "fragment"      The fragment.
- *
- * One or more of these may not be present, depending upon the URL.
- *
- * Optionally, the "user", "pass", "host" (if a name, not an IP address),
- * "path", "query", and "fragment" may have percent-encoded characters
- * decoded.  The "scheme" and "port" cannot include percent-encoded
- * characters and are never decoded.  Decoding occurs after the URL has
- * been parsed.
- *
- * Parameters:
- *     url             the URL to parse.
- *
- *     decode          an optional boolean flag selecting whether
- *                     to decode percent encoding or not.  Default = TRUE.
- *
- * Return values:
- *     the associative array of URL parts, or FALSE if the URL is
- *     too malformed to recognize any parts.
- */
-function split_url( $url, $decode=TRUE )
-{
-       // Character sets from RFC3986.
-       $xunressub     = 'a-zA-Z\d\-._~\!$&\'()*+,;=';
-       $xpchar        = $xunressub . ':@%';
-
-       // Scheme from RFC3986.
-       $xscheme        = '([a-zA-Z][a-zA-Z\d+-.]*)';
-
-       // User info (user + password) from RFC3986.
-       $xuserinfo     = '((['  . $xunressub . '%]*)' .
-                        '(:([' . $xunressub . ':%]*))?)';
-
-       // IPv4 from RFC3986 (without digit constraints).
-       $xipv4         = '(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})';
-
-       // IPv6 from RFC2732 (without digit and grouping constraints).
-       $xipv6         = '(\[([a-fA-F\d.:]+)\])';
-
-       // Host name from RFC1035.  Technically, must start with a letter.
-       // Relax that restriction to better parse URL structure, then
-       // leave host name validation to application.
-       $xhost_name    = '([a-zA-Z\d-.%]+)';
-
-       // Authority from RFC3986.  Skip IP future.
-       $xhost         = '(' . $xhost_name . '|' . $xipv4 . '|' . $xipv6 . ')';
-       $xport         = '(\d*)';
-       $xauthority    = '((' . $xuserinfo . '@)?' . $xhost .
-                        '?(:' . $xport . ')?)';
-
-       // Path from RFC3986.  Blend absolute & relative for efficiency.
-       $xslash_seg    = '(/[' . $xpchar . ']*)';
-       $xpath_authabs = '((//' . $xauthority . ')((/[' . $xpchar . ']*)*))';
-       $xpath_rel     = '([' . $xpchar . ']+' . $xslash_seg . '*)';
-       $xpath_abs     = '(/(' . $xpath_rel . ')?)';
-       $xapath        = '(' . $xpath_authabs . '|' . $xpath_abs .
-                        '|' . $xpath_rel . ')';
-
-       // Query and fragment from RFC3986.
-       $xqueryfrag    = '([' . $xpchar . '/?' . ']*)';
-
-       // URL.
-       $xurl          = '^(' . $xscheme . ':)?' .  $xapath . '?' .
-                        '(\?' . $xqueryfrag . ')?(#' . $xqueryfrag . ')?$';
-
-
-       // Split the URL into components.
-       if ( !preg_match( '!' . $xurl . '!', $url, $m ) )
-               return FALSE;
-
-       if ( !empty($m[2]) )            $parts['scheme']  = strtolower($m[2]);
-
-       if ( !empty($m[7]) ) {
-               if ( isset( $m[9] ) )   $parts['user']    = $m[9];
-               else                    $parts['user']    = '';
-       }
-       if ( !empty($m[10]) )           $parts['pass']    = $m[11];
-
-       if ( !empty($m[13]) )           $h=$parts['host'] = $m[13];
-       else if ( !empty($m[14]) )      $parts['host']    = $m[14];
-       else if ( !empty($m[16]) )      $parts['host']    = $m[16];
-       else if ( !empty( $m[5] ) )     $parts['host']    = '';
-       if ( !empty($m[17]) )           $parts['port']    = $m[18];
-
-       if ( !empty($m[19]) )           $parts['path']    = $m[19];
-       else if ( !empty($m[21]) )      $parts['path']    = $m[21];
-       else if ( !empty($m[25]) )      $parts['path']    = $m[25];
-
-       if ( !empty($m[27]) )           $parts['query']   = $m[28];
-       if ( !empty($m[29]) )           $parts['fragment']= $m[30];
-
-       if ( !$decode )
-               return $parts;
-       if ( !empty($parts['user']) )
-               $parts['user']     = rawurldecode( $parts['user'] );
-       if ( !empty($parts['pass']) )
-               $parts['pass']     = rawurldecode( $parts['pass'] );
-       if ( !empty($parts['path']) )
-               $parts['path']     = rawurldecode( $parts['path'] );
-       if ( isset($h) )
-               $parts['host']     = rawurldecode( $parts['host'] );
-       if ( !empty($parts['query']) )
-               $parts['query']    = rawurldecode( $parts['query'] );
-       if ( !empty($parts['fragment']) )
-               $parts['fragment'] = rawurldecode( $parts['fragment'] );
-       return $parts;
-}
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * This function joins together URL components to form a complete URL.
- *
- * RFC3986 specifies the components of a Uniform Resource Identifier (URI).
- * This function implements the specification's "component recomposition"
- * algorithm for combining URI components into a full URI string.
- *
- * The $parts argument is an associative array containing zero or
- * more of the following:
- *
- *     "scheme"        The scheme, such as "http".
- *     "host"          The host name, IPv4, or IPv6 address.
- *     "port"          The port number.
- *     "user"          The user name.
- *     "pass"          The user password.
- *     "path"          The path, such as a file path for "http".
- *     "query"         The query.
- *     "fragment"      The fragment.
- *
- * The "port", "user", and "pass" values are only used when a "host"
- * is present.
- *
- * The optional $encode argument indicates if appropriate URL components
- * should be percent-encoded as they are assembled into the URL.  Encoding
- * is only applied to the "user", "pass", "host" (if a host name, not an
- * IP address), "path", "query", and "fragment" components.  The "scheme"
- * and "port" are never encoded.  When a "scheme" and "host" are both
- * present, the "path" is presumed to be hierarchical and encoding
- * processes each segment of the hierarchy separately (i.e., the slashes
- * are left alone).
- *
- * The assembled URL string is returned.
- *
- * Parameters:
- *     parts           an associative array of strings containing the
- *                     individual parts of a URL.
- *
- *     encode          an optional boolean flag selecting whether
- *                     to do percent encoding or not.  Default = true.
- *
- * Return values:
- *     Returns the assembled URL string.  The string is an absolute
- *     URL if a scheme is supplied, and a relative URL if not.  An
- *     empty string is returned if the $parts array does not contain
- *     any of the needed values.
- */
-function join_url( $parts, $encode=TRUE )
-{
-       if ( $encode )
-       {
-               if ( isset( $parts['user'] ) )
-                       $parts['user']     = rawurlencode( $parts['user'] );
-               if ( isset( $parts['pass'] ) )
-                       $parts['pass']     = rawurlencode( $parts['pass'] );
-               if ( isset( $parts['host'] ) &&
-                       !preg_match( '!^(\[[\da-f.:]+\]])|([\da-f.:]+)$!ui', $parts['host'] ) )
-                       $parts['host']     = rawurlencode( $parts['host'] );
-               if ( !empty( $parts['path'] ) )
-                       $parts['path']     = preg_replace( '!%2F!ui', '/',
-                               rawurlencode( $parts['path'] ) );
-               if ( isset( $parts['query'] ) )
-                       $parts['query']    = rawurlencode( $parts['query'] );
-               if ( isset( $parts['fragment'] ) )
-                       $parts['fragment'] = rawurlencode( $parts['fragment'] );
-       }
-
-       $url = '';
-       if ( !empty( $parts['scheme'] ) )
-               $url .= $parts['scheme'] . ':';
-       if ( isset( $parts['host'] ) )
-       {
-               $url .= '//';
-               if ( isset( $parts['user'] ) )
-               {
-                       $url .= $parts['user'];
-                       if ( isset( $parts['pass'] ) )
-                               $url .= ':' . $parts['pass'];
-                       $url .= '@';
-               }
-               if ( preg_match( '!^[\da-f]*:[\da-f.:]+$!ui', $parts['host'] ) )
-                       $url .= '[' . $parts['host'] . ']';     // IPv6
-               else
-                       $url .= $parts['host'];                 // IPv4 or name
-               if ( isset( $parts['port'] ) )
-                       $url .= ':' . $parts['port'];
-               if ( !empty( $parts['path'] ) && $parts['path'][0] != '/' )
-                       $url .= '/';
-       }
-       if ( !empty( $parts['path'] ) )
-               $url .= $parts['path'];
-       if ( isset( $parts['query'] ) )
-               $url .= '?' . $parts['query'];
-       if ( isset( $parts['fragment'] ) )
-               $url .= '#' . $parts['fragment'];
-       return $url;
-}
-/**
- * Extract URLs from a web page.
- *
- * URLs are extracted from a long list of tags and attributes as defined
- * by the HTML 2.0, HTML 3.2, HTML 4.01, and draft HTML 5.0 specifications.
- * URLs are also extracted from tags and attributes that are common
- * extensions of HTML, from the draft Forms 2.0 specification, from XHTML,
- * and from WML 1.3 and 2.0.
- *
- * The function returns an associative array of associative arrays of
- * arrays of URLs.  The outermost array's keys are the tag (element) name,
- * such as "a" for <a> or "img" for <img>.  The values for these entries
- * are associative arrays where the keys are attribute names for those
- * tags, such as "href" for <a href="...">.  Finally, the values for
- * those arrays are URLs found in those tags and attributes throughout
- * the text.
- *
- * Parameters:
- *     text            the UTF-8 text to scan
- *
- * Return values:
- *     an associative array where keys are tags and values are an
- *     associative array where keys are attributes and values are
- *     an array of URLs.
- *
- * See:
- *     http://nadeausoftware.com/articles/2008/01/php_tip_how_extract_urls_web_page
+ * repository_url class
+ * A subclass of repository, which is used to download a file from a specific url
+ *
+ * @since 2.0
+ * @package moodlecore
+ * @subpackage repository
+ * @copyright 2009 Dongsheng Cai
+ * @author Dongsheng Cai <dongsheng@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-function extract_html_urls( $text )
-{
-       $match_elements = array(
-               // HTML
-               array('element'=>'a',           'attribute'=>'href'),           // 2.0
-               array('element'=>'a',           'attribute'=>'urn'),            // 2.0
-               array('element'=>'base',        'attribute'=>'href'),           // 2.0
-               array('element'=>'form',        'attribute'=>'action'),         // 2.0
-               array('element'=>'img',         'attribute'=>'src'),            // 2.0
-               array('element'=>'link',        'attribute'=>'href'),           // 2.0
-
-               array('element'=>'applet',      'attribute'=>'code'),           // 3.2
-               array('element'=>'applet',      'attribute'=>'codebase'),       // 3.2
-               array('element'=>'area',        'attribute'=>'href'),           // 3.2
-               array('element'=>'body',        'attribute'=>'background'),     // 3.2
-               array('element'=>'img',         'attribute'=>'usemap'),         // 3.2
-               array('element'=>'input',       'attribute'=>'src'),            // 3.2
-
-               array('element'=>'applet',      'attribute'=>'archive'),        // 4.01
-               array('element'=>'applet',      'attribute'=>'object'),         // 4.01
-               array('element'=>'blockquote',  'attribute'=>'cite'),           // 4.01
-               array('element'=>'del',         'attribute'=>'cite'),           // 4.01
-               array('element'=>'frame',       'attribute'=>'longdesc'),       // 4.01
-               array('element'=>'frame',       'attribute'=>'src'),            // 4.01
-               array('element'=>'head',        'attribute'=>'profile'),        // 4.01
-               array('element'=>'iframe',      'attribute'=>'longdesc'),       // 4.01
-               array('element'=>'iframe',      'attribute'=>'src'),            // 4.01
-               array('element'=>'img',         'attribute'=>'longdesc'),       // 4.01
-               array('element'=>'input',       'attribute'=>'usemap'),         // 4.01
-               array('element'=>'ins',         'attribute'=>'cite'),           // 4.01
-               array('element'=>'object',      'attribute'=>'archive'),        // 4.01
-               array('element'=>'object',      'attribute'=>'classid'),        // 4.01
-               array('element'=>'object',      'attribute'=>'codebase'),       // 4.01
-               array('element'=>'object',      'attribute'=>'data'),           // 4.01
-               array('element'=>'object',      'attribute'=>'usemap'),         // 4.01
-               array('element'=>'q',           'attribute'=>'cite'),           // 4.01
-               array('element'=>'script',      'attribute'=>'src'),            // 4.01
-
-               array('element'=>'audio',       'attribute'=>'src'),            // 5.0
-               array('element'=>'command',     'attribute'=>'icon'),           // 5.0
-               array('element'=>'embed',       'attribute'=>'src'),            // 5.0
-               array('element'=>'event-source','attribute'=>'src'),            // 5.0
-               array('element'=>'html',        'attribute'=>'manifest'),       // 5.0
-               array('element'=>'source',      'attribute'=>'src'),            // 5.0
-               array('element'=>'video',       'attribute'=>'src'),            // 5.0
-               array('element'=>'video',       'attribute'=>'poster'),         // 5.0
-
-               array('element'=>'bgsound',     'attribute'=>'src'),            // Extension
-               array('element'=>'body',        'attribute'=>'credits'),        // Extension
-               array('element'=>'body',        'attribute'=>'instructions'),   // Extension
-               array('element'=>'body',        'attribute'=>'logo'),           // Extension
-               array('element'=>'div',         'attribute'=>'href'),           // Extension
-               array('element'=>'div',         'attribute'=>'src'),            // Extension
-               array('element'=>'embed',       'attribute'=>'code'),           // Extension
-               array('element'=>'embed',       'attribute'=>'pluginspage'),    // Extension
-               array('element'=>'html',        'attribute'=>'background'),     // Extension
-               array('element'=>'ilayer',      'attribute'=>'src'),            // Extension
-               array('element'=>'img',         'attribute'=>'dynsrc'),         // Extension
-               array('element'=>'img',         'attribute'=>'lowsrc'),         // Extension
-               array('element'=>'input',       'attribute'=>'dynsrc'),         // Extension
-               array('element'=>'input',       'attribute'=>'lowsrc'),         // Extension
-               array('element'=>'table',       'attribute'=>'background'),     // Extension
-               array('element'=>'td',          'attribute'=>'background'),     // Extension
-               array('element'=>'th',          'attribute'=>'background'),     // Extension
-               array('element'=>'layer',       'attribute'=>'src'),            // Extension
-               array('element'=>'xml',         'attribute'=>'src'),            // Extension
-
-               array('element'=>'button',      'attribute'=>'action'),         // Forms 2.0
-               array('element'=>'datalist',    'attribute'=>'data'),           // Forms 2.0
-               array('element'=>'form',        'attribute'=>'data'),           // Forms 2.0
-               array('element'=>'input',       'attribute'=>'action'),         // Forms 2.0
-               array('element'=>'select',      'attribute'=>'data'),           // Forms 2.0
-
-               // XHTML
-               array('element'=>'html',        'attribute'=>'xmlns'),
-
-               // WML
-               array('element'=>'access',      'attribute'=>'path'),           // 1.3
-               array('element'=>'card',        'attribute'=>'onenterforward'), // 1.3
-               array('element'=>'card',        'attribute'=>'onenterbackward'),// 1.3
-               array('element'=>'card',        'attribute'=>'ontimer'),        // 1.3
-               array('element'=>'go',          'attribute'=>'href'),           // 1.3
-               array('element'=>'option',      'attribute'=>'onpick'),         // 1.3
-               array('element'=>'template',    'attribute'=>'onenterforward'), // 1.3
-               array('element'=>'template',    'attribute'=>'onenterbackward'),// 1.3
-               array('element'=>'template',    'attribute'=>'ontimer'),        // 1.3
-               array('element'=>'wml',         'attribute'=>'xmlns'),          // 2.0
-       );
-
-       $match_metas = array(
-               'content-base',
-               'content-location',
-               'referer',
-               'location',
-               'refresh',
-       );
-
-       // Extract all elements
-       if ( !preg_match_all( '/<([a-z][^>]*)>/iu', $text, $matches ) )
-               return array( );
-       $elements = $matches[1];
-       $value_pattern = '=(("([^"]*)")|([^\s]*))';
-
-       // Match elements and attributes
-       foreach ( $match_elements as $match_element )
-       {
-               $name = $match_element['element'];
-               $attr = $match_element['attribute'];
-               $pattern = '/^' . $name . '\s.*' . $attr . $value_pattern . '/iu';
-               if ( $name == 'object' )
-                       $split_pattern = '/\s*/u';      // Space-separated URL list
-               else if ( $name == 'archive' )
-                       $split_pattern = '/,\s*/u';     // Comma-separated URL list
-               else
-                       unset( $split_pattern );        // Single URL
-               foreach ( $elements as $element )
-               {
-                       if ( !preg_match( $pattern, $element, $match ) )
-                               continue;
-                       $m = empty($match[3]) ? (!empty($match[4])?$match[4]:'') : $match[3];
-                       if ( !isset( $split_pattern ) )
-                               $urls[$name][$attr][] = $m;
-                       else
-                       {
-                               $msplit = preg_split( $split_pattern, $m );
-                               foreach ( $msplit as $ms )
-                                       $urls[$name][$attr][] = $ms;
-                       }
-               }
-       }
-
-       // Match meta http-equiv elements
-       foreach ( $match_metas as $match_meta )
-       {
-               $attr_pattern    = '/http-equiv="?' . $match_meta . '"?/iu';
-               $content_pattern = '/content'  . $value_pattern . '/iu';
-               $refresh_pattern = '/\d*;\s*(url=)?(.*)$/iu';
-               foreach ( $elements as $element )
-               {
-                       if ( !preg_match( '/^meta/iu', $element ) ||
-                               !preg_match( $attr_pattern, $element ) ||
-                               !preg_match( $content_pattern, $element, $match ) )
-                               continue;
-                       $m = empty($match[3]) ? $match[4] : $match[3];
-                       if ( $match_meta != 'refresh' )
-                               $urls['meta']['http-equiv'][] = $m;
-                       else if ( preg_match( $refresh_pattern, $m, $match ) )
-                               $urls['meta']['http-equiv'][] = $match[2];
-               }
-       }
 
-       // Match style attributes
-       $urls['style'] = array( );
-       $style_pattern = '/style' . $value_pattern . '/iu';
-       foreach ( $elements as $element )
-       {
-               if ( !preg_match( $style_pattern, $element, $match ) )
-                       continue;
-               $m = empty($match[3]) ? $match[4] : $match[3];
-               $style_urls = extract_css_urls( $m );
-               if ( !empty( $style_urls ) )
-                       $urls['style'] = array_merge_recursive(
-                               $urls['style'], $style_urls );
-       }
-
-       // Match style bodies
-       if ( preg_match_all( '/<style[^>]*>(.*?)<\/style>/siu', $text, $style_bodies ) )
-       {
-               foreach ( $style_bodies[1] as $style_body )
-               {
-                       $style_urls = extract_css_urls( $style_body );
-                       if ( !empty( $style_urls ) )
-                               $urls['style'] = array_merge_recursive(
-                                       $urls['style'], $style_urls );
-               }
-       }
-       if ( empty($urls['style']) )
-               unset( $urls['style'] );
-
-       return $urls;
+require_once(dirname(__FILE__).'/locallib.php');
+
+class repository_url extends repository {
+
+    /**
+     * @param int $repositoryid
+     * @param object $context
+     * @param array $options
+     */
+    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()){
+        global $CFG;
+        parent::__construct($repositoryid, $context, $options);
+        if (!empty($options['client_id'])) {
+            // will be used to construct download form
+            $this->client_id = $options['client_id'];
+        }
+        $this->file_url = optional_param('file', '', PARAM_RAW);
+    }
+
+    public function get_file($url, $file = '') {
+        global $CFG;
+        //$CFG->repository_no_delete = true;
+        $path = $this->prepare_file($file);
+        $fp = fopen($path, 'w');
+        $c = new curl;
+        $c->download(array(array('url'=>$url, 'file'=>$fp)));
+        return array('path'=>$path, 'url'=>$url);
+    }
+
+    public function check_login() {
+        if (!empty($this->file_url)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    /**
+     * @return mixed
+     */
+    public function print_login() {
+        $strdownload = get_string('download', 'repository');
+        $strname     = get_string('rename', 'repository_url');
+        $strurl      = get_string('url', 'repository_url');
+        if ($this->options['ajax']) {
+            $url = new stdclass;
+            $url->label = $strurl.': ';
+            $url->id   = 'fileurl-'.$this->client_id;
+            $url->type = 'text';
+            $url->name = 'file';
+
+            $ret['login'] = array($url);
+            $ret['login_btn_label'] = get_string('download', 'repository_url');
+            return $ret;
+        } else {
+            echo <<<EOD
+<table>
+<tr>
+<td>{$strurl}: </td><td><input name="file" type="text" /></td>
+</tr>
+</table>
+<input type="submit" value="{$strdownload}" />
+EOD;
+
+        }
+    }
+
+    /**
+     * @param mixed $path
+     * @param string $search
+     * @return array
+     */
+    public function get_listing($path='', $page='') {
+        global $CFG, $OUTPUT;
+        $ret = array();
+        $curl = new curl;
+        $msg = $curl->head($this->file_url);
+        $info = $curl->get_info();
+        if ($info['http_code'] != 200) {
+            $ret['e'] = $msg;
+        } else {
+            $ret['list'] = array();
+            $ret['nosearch'] = true;
+            $ret['nologin'] = true;
+            $filename = $this->guess_filename($info['url'], $info['content_type']);
+            if (strstr($info['content_type'], 'text/html') || empty($info['content_type'])) {
+                // analysis this web page, general file list
+                $ret['list'] = array();
+                $content = $curl->get($info['url']);
+                $this->analyse_page($info['url'], $content, $ret);
+            } else {
+                // download this file
+                $ret['list'][] = array(
+                    'title'=>$filename,
+                    'source'=>$this->file_url,
+                    'thumbnail' => $OUTPUT->pix_url(file_extension_icon($filename, 32))
+                    );
+            }
+        }
+        return $ret;
+    }
+    public function analyse_page($baseurl, $content, &$list) {
+        global $CFG, $OUTPUT;
+        $urls = extract_html_urls($content);
+        $images = $urls['img']['src'];
+        $pattern = '#img(.+)src="?\'?([[:alnum:]:?=&@/._+-]+)"?\'?#i';
+        if (!empty($images)) {
+            foreach($images as $url) {
+                $list['list'][] = array(
+                    'title'=>$this->guess_filename($url, ''),
+                    'source'=>url_to_absolute($baseurl, $url),
+                    'thumbnail'=>url_to_absolute($baseurl, $url),
+                    'thumbnail_height'=>84,
+                    'thumbnail_width'=>84
+                );
+            }
+        }
+    }
+    public function guess_filename($url, $type) {
+        $pattern = '#\/([\w_\?\-.]+)$#';
+        $matches = null;
+        preg_match($pattern, $url, $matches);
+        if (empty($matches[1])) {
+            return $url;
+        } else {
+            return $matches[1];
+        }
+    }
+
+    public function get_name(){
+        return get_string('pluginname', 'repository_url');;
+    }
+    public function supported_returntypes() {
+        return (FILE_INTERNAL | FILE_EXTERNAL);
+    }
 }
-/**
- * Extract URLs from UTF-8 CSS text.
- *
- * URLs within @import statements and url() property functions are extracted
- * and returned in an associative array of arrays.  Array keys indicate
- * the use context for the URL, including:
- *
- *     "import"
- *     "property"
- *
- * Each value in the associative array is an array of URLs.
- *
- * Parameters:
- *     text            the UTF-8 text to scan
- *
- * Return values:
- *     an associative array of arrays of URLs.
- *
- * See:
- *     http://nadeausoftware.com/articles/2008/01/php_tip_how_extract_urls_css_file
- */
-function extract_css_urls( $text )
-{
-       $urls = array( );
-
-       $url_pattern     = '(([^\\\\\'", \(\)]*(\\\\.)?)+)';
-       $urlfunc_pattern = 'url\(\s*[\'"]?' . $url_pattern . '[\'"]?\s*\)';
-       $pattern         = '/(' .
-                '(@import\s*[\'"]' . $url_pattern     . '[\'"])' .
-               '|(@import\s*'      . $urlfunc_pattern . ')'      .
-               '|('                . $urlfunc_pattern . ')'      .  ')/iu';
-       if ( !preg_match_all( $pattern, $text, $matches ) )
-               return $urls;
-
-       // @import '...'
-       // @import "..."
-       foreach ( $matches[3] as $match )
-               if ( !empty($match) )
-                       $urls['import'][] =
-                               preg_replace( '/\\\\(.)/u', '\\1', $match );
 
-       // @import url(...)
-       // @import url('...')
-       // @import url("...")
-       foreach ( $matches[7] as $match )
-               if ( !empty($match) )
-                       $urls['import'][] =
-                               preg_replace( '/\\\\(.)/u', '\\1', $match );
-
-       // url(...)
-       // url('...')
-       // url("...")
-       foreach ( $matches[11] as $match )
-               if ( !empty($match) )
-                       $urls['property'][] =
-                               preg_replace( '/\\\\(.)/u', '\\1', $match );
-
-       return $urls;
-}
diff --git a/repository/url/locallib.php b/repository/url/locallib.php
new file mode 100644 (file)
index 0000000..f9c65f8
--- /dev/null
@@ -0,0 +1,702 @@
+<?php
+
+/**
+ * Copyright (c) 2008, David R. Nadeau, NadeauSoftware.com.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *
+ *     * Neither the names of David R. Nadeau or NadeauSoftware.com, nor
+ *       the names of its contributors may be used to endorse or promote
+ *       products derived from this software without specific prior
+ *       written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * This is a BSD License approved by the Open Source Initiative (OSI).
+ * See:  http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Combine a base URL and a relative URL to produce a new
+ * absolute URL.  The base URL is often the URL of a page,
+ * and the relative URL is a URL embedded on that page.
+ *
+ * This function implements the "absolutize" algorithm from
+ * the RFC3986 specification for URLs.
+ *
+ * This function supports multi-byte characters with the UTF-8 encoding,
+ * per the URL specification.
+ *
+ * Parameters:
+ *     baseUrl         the absolute base URL.
+ *
+ *     url             the relative URL to convert.
+ *
+ * Return values:
+ *     An absolute URL that combines parts of the base and relative
+ *     URLs, or FALSE if the base URL is not absolute or if either
+ *     URL cannot be parsed.
+ */
+function url_to_absolute( $baseUrl, $relativeUrl )
+{
+       // If relative URL has a scheme, clean path and return.
+       $r = split_url( $relativeUrl );
+       if ( $r === FALSE )
+               return FALSE;
+       if ( !empty( $r['scheme'] ) )
+       {
+               if ( !empty( $r['path'] ) && $r['path'][0] == '/' )
+                       $r['path'] = url_remove_dot_segments( $r['path'] );
+               return join_url( $r );
+       }
+
+       // Make sure the base URL is absolute.
+       $b = split_url( $baseUrl );
+       if ( $b === FALSE || empty( $b['scheme'] ) || empty( $b['host'] ) )
+               return FALSE;
+       $r['scheme'] = $b['scheme'];
+
+       // If relative URL has an authority, clean path and return.
+       if ( isset( $r['host'] ) )
+       {
+               if ( !empty( $r['path'] ) )
+                       $r['path'] = url_remove_dot_segments( $r['path'] );
+               return join_url( $r );
+       }
+       unset( $r['port'] );
+       unset( $r['user'] );
+       unset( $r['pass'] );
+
+       // Copy base authority.
+       $r['host'] = $b['host'];
+       if ( isset( $b['port'] ) ) $r['port'] = $b['port'];
+       if ( isset( $b['user'] ) ) $r['user'] = $b['user'];
+       if ( isset( $b['pass'] ) ) $r['pass'] = $b['pass'];
+
+       // If relative URL has no path, use base path
+       if ( empty( $r['path'] ) )
+       {
+               if ( !empty( $b['path'] ) )
+                       $r['path'] = $b['path'];
+               if ( !isset( $r['query'] ) && isset( $b['query'] ) )
+                       $r['query'] = $b['query'];
+               return join_url( $r );
+       }
+
+       // If relative URL path doesn't start with /, merge with base path
+       if ( $r['path'][0] != '/' )
+       {
+               $base = mb_strrchr( $b['path'], '/', TRUE, 'UTF-8' );
+               if ( $base === FALSE ) $base = '';
+               $r['path'] = $base . '/' . $r['path'];
+       }
+       $r['path'] = url_remove_dot_segments( $r['path'] );
+       return join_url( $r );
+}
+
+/**
+ * Filter out "." and ".." segments from a URL's path and return
+ * the result.
+ *
+ * This function implements the "remove_dot_segments" algorithm from
+ * the RFC3986 specification for URLs.
+ *
+ * This function supports multi-byte characters with the UTF-8 encoding,
+ * per the URL specification.
+ *
+ * Parameters:
+ *     path    the path to filter
+ *
+ * Return values:
+ *     The filtered path with "." and ".." removed.
+ */
+function url_remove_dot_segments( $path )
+{
+       // multi-byte character explode
+       $inSegs  = preg_split( '!/!u', $path );
+       $outSegs = array( );
+       foreach ( $inSegs as $seg )
+       {
+               if ( $seg == '' || $seg == '.')
+                       continue;
+               if ( $seg == '..' )
+                       array_pop( $outSegs );
+               else
+                       array_push( $outSegs, $seg );
+       }
+       $outPath = implode( '/', $outSegs );
+       if ( $path[0] == '/' )
+               $outPath = '/' . $outPath;
+       // compare last multi-byte character against '/'
+       if ( $outPath != '/' &&
+               (mb_strlen($path)-1) == mb_strrpos( $path, '/', 'UTF-8' ) )
+               $outPath .= '/';
+       return $outPath;
+}
+
+/**
+ * This function parses an absolute or relative URL and splits it
+ * into individual components.
+ *
+ * RFC3986 specifies the components of a Uniform Resource Identifier (URI).
+ * A portion of the ABNFs are repeated here:
+ *
+ *     URI-reference   = URI
+ *                     / relative-ref
+ *
+ *     URI             = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+ *
+ *     relative-ref    = relative-part [ "?" query ] [ "#" fragment ]
+ *
+ *     hier-part       = "//" authority path-abempty
+ *                     / path-absolute
+ *                     / path-rootless
+ *                     / path-empty
+ *
+ *     relative-part   = "//" authority path-abempty
+ *                     / path-absolute
+ *                     / path-noscheme
+ *                     / path-empty
+ *
+ *     authority       = [ userinfo "@" ] host [ ":" port ]
+ *
+ * So, a URL has the following major components:
+ *
+ *     scheme
+ *             The name of a method used to interpret the rest of
+ *             the URL.  Examples:  "http", "https", "mailto", "file'.
+ *
+ *     authority
+ *             The name of the authority governing the URL's name
+ *             space.  Examples:  "example.com", "user@example.com",
+ *             "example.com:80", "user:password@example.com:80".
+ *
+ *             The authority may include a host name, port number,
+ *             user name, and password.
+ *
+ *             The host may be a name, an IPv4 numeric address, or
+ *             an IPv6 numeric address.
+ *
+ *     path
+ *             The hierarchical path to the URL's resource.
+ *             Examples:  "/index.htm", "/scripts/page.php".
+ *
+ *     query
+ *             The data for a query.  Examples:  "?search=google.com".
+ *
+ *     fragment
+ *             The name of a secondary resource relative to that named
+ *             by the path.  Examples:  "#section1", "#header".
+ *
+ * An "absolute" URL must include a scheme and path.  The authority, query,
+ * and fragment components are optional.
+ *
+ * A "relative" URL does not include a scheme and must include a path.  The
+ * authority, query, and fragment components are optional.
+ *
+ * This function splits the $url argument into the following components
+ * and returns them in an associative array.  Keys to that array include:
+ *
+ *     "scheme"        The scheme, such as "http".
+ *     "host"          The host name, IPv4, or IPv6 address.
+ *     "port"          The port number.
+ *     "user"          The user name.
+ *     "pass"          The user password.
+ *     "path"          The path, such as a file path for "http".
+ *     "query"         The query.
+ *     "fragment"      The fragment.
+ *
+ * One or more of these may not be present, depending upon the URL.
+ *
+ * Optionally, the "user", "pass", "host" (if a name, not an IP address),
+ * "path", "query", and "fragment" may have percent-encoded characters
+ * decoded.  The "scheme" and "port" cannot include percent-encoded
+ * characters and are never decoded.  Decoding occurs after the URL has
+ * been parsed.
+ *
+ * Parameters:
+ *     url             the URL to parse.
+ *
+ *     decode          an optional boolean flag selecting whether
+ *                     to decode percent encoding or not.  Default = TRUE.
+ *
+ * Return values:
+ *     the associative array of URL parts, or FALSE if the URL is
+ *     too malformed to recognize any parts.
+ */
+function split_url( $url, $decode=TRUE )
+{
+       // Character sets from RFC3986.
+       $xunressub     = 'a-zA-Z\d\-._~\!$&\'()*+,;=';
+       $xpchar        = $xunressub . ':@%';
+
+       // Scheme from RFC3986.
+       $xscheme        = '([a-zA-Z][a-zA-Z\d+-.]*)';
+
+       // User info (user + password) from RFC3986.
+       $xuserinfo     = '((['  . $xunressub . '%]*)' .
+                        '(:([' . $xunressub . ':%]*))?)';
+
+       // IPv4 from RFC3986 (without digit constraints).
+       $xipv4         = '(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})';
+
+       // IPv6 from RFC2732 (without digit and grouping constraints).
+       $xipv6         = '(\[([a-fA-F\d.:]+)\])';
+
+       // Host name from RFC1035.  Technically, must start with a letter.
+       // Relax that restriction to better parse URL structure, then
+       // leave host name validation to application.
+       $xhost_name    = '([a-zA-Z\d-.%]+)';
+
+       // Authority from RFC3986.  Skip IP future.
+       $xhost         = '(' . $xhost_name . '|' . $xipv4 . '|' . $xipv6 . ')';
+       $xport         = '(\d*)';
+       $xauthority    = '((' . $xuserinfo . '@)?' . $xhost .
+                        '?(:' . $xport . ')?)';
+
+       // Path from RFC3986.  Blend absolute & relative for efficiency.
+       $xslash_seg    = '(/[' . $xpchar . ']*)';
+       $xpath_authabs = '((//' . $xauthority . ')((/[' . $xpchar . ']*)*))';
+       $xpath_rel     = '([' . $xpchar . ']+' . $xslash_seg . '*)';
+       $xpath_abs     = '(/(' . $xpath_rel . ')?)';
+       $xapath        = '(' . $xpath_authabs . '|' . $xpath_abs .
+                        '|' . $xpath_rel . ')';
+
+       // Query and fragment from RFC3986.
+       $xqueryfrag    = '([' . $xpchar . '/?' . ']*)';
+
+       // URL.
+       $xurl          = '^(' . $xscheme . ':)?' .  $xapath . '?' .
+                        '(\?' . $xqueryfrag . ')?(#' . $xqueryfrag . ')?$';
+
+
+       // Split the URL into components.
+       if ( !preg_match( '!' . $xurl . '!', $url, $m ) )
+               return FALSE;
+
+       if ( !empty($m[2]) )            $parts['scheme']  = strtolower($m[2]);
+
+       if ( !empty($m[7]) ) {
+               if ( isset( $m[9] ) )   $parts['user']    = $m[9];
+               else                    $parts['user']    = '';
+       }
+       if ( !empty($m[10]) )           $parts['pass']    = $m[11];
+
+       if ( !empty($m[13]) )           $h=$parts['host'] = $m[13];
+       else if ( !empty($m[14]) )      $parts['host']    = $m[14];
+       else if ( !empty($m[16]) )      $parts['host']    = $m[16];
+       else if ( !empty( $m[5] ) )     $parts['host']    = '';
+       if ( !empty($m[17]) )           $parts['port']    = $m[18];
+
+       if ( !empty($m[19]) )           $parts['path']    = $m[19];
+       else if ( !empty($m[21]) )      $parts['path']    = $m[21];
+       else if ( !empty($m[25]) )      $parts['path']    = $m[25];
+
+       if ( !empty($m[27]) )           $parts['query']   = $m[28];
+       if ( !empty($m[29]) )           $parts['fragment']= $m[30];
+
+       if ( !$decode )
+               return $parts;
+       if ( !empty($parts['user']) )
+               $parts['user']     = rawurldecode( $parts['user'] );
+       if ( !empty($parts['pass']) )
+               $parts['pass']     = rawurldecode( $parts['pass'] );
+       if ( !empty($parts['path']) )
+               $parts['path']     = rawurldecode( $parts['path'] );
+       if ( isset($h) )
+               $parts['host']     = rawurldecode( $parts['host'] );
+       if ( !empty($parts['query']) )
+               $parts['query']    = rawurldecode( $parts['query'] );
+       if ( !empty($parts['fragment']) )
+               $parts['fragment'] = rawurldecode( $parts['fragment'] );
+       return $parts;
+}
+
+/**
+ * This function joins together URL components to form a complete URL.
+ *
+ * RFC3986 specifies the components of a Uniform Resource Identifier (URI).
+ * This function implements the specification's "component recomposition"
+ * algorithm for combining URI components into a full URI string.
+ *
+ * The $parts argument is an associative array containing zero or
+ * more of the following:
+ *
+ *     "scheme"        The scheme, such as "http".
+ *     "host"          The host name, IPv4, or IPv6 address.
+ *     "port"          The port number.
+ *     "user"          The user name.
+ *     "pass"          The user password.
+ *     "path"          The path, such as a file path for "http".
+ *     "query"         The query.
+ *     "fragment"      The fragment.
+ *
+ * The "port", "user", and "pass" values are only used when a "host"
+ * is present.
+ *
+ * The optional $encode argument indicates if appropriate URL components
+ * should be percent-encoded as they are assembled into the URL.  Encoding
+ * is only applied to the "user", "pass", "host" (if a host name, not an
+ * IP address), "path", "query", and "fragment" components.  The "scheme"
+ * and "port" are never encoded.  When a "scheme" and "host" are both
+ * present, the "path" is presumed to be hierarchical and encoding
+ * processes each segment of the hierarchy separately (i.e., the slashes
+ * are left alone).
+ *
+ * The assembled URL string is returned.
+ *
+ * Parameters:
+ *     parts           an associative array of strings containing the
+ *                     individual parts of a URL.
+ *
+ *     encode          an optional boolean flag selecting whether
+ *                     to do percent encoding or not.  Default = true.
+ *
+ * Return values:
+ *     Returns the assembled URL string.  The string is an absolute
+ *     URL if a scheme is supplied, and a relative URL if not.  An
+ *     empty string is returned if the $parts array does not contain
+ *     any of the needed values.
+ */
+function join_url( $parts, $encode=TRUE )
+{
+       if ( $encode )
+       {
+               if ( isset( $parts['user'] ) )
+                       $parts['user']     = rawurlencode( $parts['user'] );
+               if ( isset( $parts['pass'] ) )
+                       $parts['pass']     = rawurlencode( $parts['pass'] );
+               if ( isset( $parts['host'] ) &&
+                       !preg_match( '!^(\[[\da-f.:]+\]])|([\da-f.:]+)$!ui', $parts['host'] ) )
+                       $parts['host']     = rawurlencode( $parts['host'] );
+               if ( !empty( $parts['path'] ) )
+                       $parts['path']     = preg_replace( '!%2F!ui', '/',
+                               rawurlencode( $parts['path'] ) );
+               if ( isset( $parts['query'] ) )
+                       $parts['query']    = rawurlencode( $parts['query'] );
+               if ( isset( $parts['fragment'] ) )
+                       $parts['fragment'] = rawurlencode( $parts['fragment'] );
+       }
+
+       $url = '';
+       if ( !empty( $parts['scheme'] ) )
+               $url .= $parts['scheme'] . ':';
+       if ( isset( $parts['host'] ) )
+       {
+               $url .= '//';
+               if ( isset( $parts['user'] ) )
+               {
+                       $url .= $parts['user'];
+                       if ( isset( $parts['pass'] ) )
+                               $url .= ':' . $parts['pass'];
+                       $url .= '@';
+               }
+               if ( preg_match( '!^[\da-f]*:[\da-f.:]+$!ui', $parts['host'] ) )
+                       $url .= '[' . $parts['host'] . ']';     // IPv6
+               else
+                       $url .= $parts['host'];                 // IPv4 or name
+               if ( isset( $parts['port'] ) )
+                       $url .= ':' . $parts['port'];
+               if ( !empty( $parts['path'] ) && $parts['path'][0] != '/' )
+                       $url .= '/';
+       }
+       if ( !empty( $parts['path'] ) )
+               $url .= $parts['path'];
+       if ( isset( $parts['query'] ) )
+               $url .= '?' . $parts['query'];
+       if ( isset( $parts['fragment'] ) )
+               $url .= '#' . $parts['fragment'];
+       return $url;
+}
+/**
+ * Extract URLs from a web page.
+ *
+ * URLs are extracted from a long list of tags and attributes as defined
+ * by the HTML 2.0, HTML 3.2, HTML 4.01, and draft HTML 5.0 specifications.
+ * URLs are also extracted from tags and attributes that are common
+ * extensions of HTML, from the draft Forms 2.0 specification, from XHTML,
+ * and from WML 1.3 and 2.0.
+ *
+ * The function returns an associative array of associative arrays of
+ * arrays of URLs.  The outermost array's keys are the tag (element) name,
+ * such as "a" for <a> or "img" for <img>.  The values for these entries
+ * are associative arrays where the keys are attribute names for those
+ * tags, such as "href" for <a href="...">.  Finally, the values for
+ * those arrays are URLs found in those tags and attributes throughout
+ * the text.
+ *
+ * Parameters:
+ *     text            the UTF-8 text to scan
+ *
+ * Return values:
+ *     an associative array where keys are tags and values are an
+ *     associative array where keys are attributes and values are
+ *     an array of URLs.
+ *
+ * See:
+ *     http://nadeausoftware.com/articles/2008/01/php_tip_how_extract_urls_web_page
+ */
+function extract_html_urls( $text )
+{
+       $match_elements = array(
+               // HTML
+               array('element'=>'a',           'attribute'=>'href'),           // 2.0
+               array('element'=>'a',           'attribute'=>'urn'),            // 2.0
+               array('element'=>'base',        'attribute'=>'href'),           // 2.0
+               array('element'=>'form',        'attribute'=>'action'),         // 2.0
+               array('element'=>'img',         'attribute'=>'src'),            // 2.0
+               array('element'=>'link',        'attribute'=>'href'),           // 2.0
+
+               array('element'=>'applet',      'attribute'=>'code'),           // 3.2
+               array('element'=>'applet',      'attribute'=>'codebase'),       // 3.2
+               array('element'=>'area',        'attribute'=>'href'),           // 3.2
+               array('element'=>'body',        'attribute'=>'background'),     // 3.2
+               array('element'=>'img',         'attribute'=>'usemap'),         // 3.2
+               array('element'=>'input',       'attribute'=>'src'),            // 3.2
+
+               array('element'=>'applet',      'attribute'=>'archive'),        // 4.01
+               array('element'=>'applet',      'attribute'=>'object'),         // 4.01
+               array('element'=>'blockquote',  'attribute'=>'cite'),           // 4.01
+               array('element'=>'del',         'attribute'=>'cite'),           // 4.01
+               array('element'=>'frame',       'attribute'=>'longdesc'),       // 4.01
+               array('element'=>'frame',       'attribute'=>'src'),            // 4.01
+               array('element'=>'head',        'attribute'=>'profile'),        // 4.01
+               array('element'=>'iframe',      'attribute'=>'longdesc'),       // 4.01
+               array('element'=>'iframe',      'attribute'=>'src'),            // 4.01
+               array('element'=>'img',         'attribute'=>'longdesc'),       // 4.01
+               array('element'=>'input',       'attribute'=>'usemap'),         // 4.01
+               array('element'=>'ins',         'attribute'=>'cite'),           // 4.01
+               array('element'=>'object',      'attribute'=>'archive'),        // 4.01
+               array('element'=>'object',      'attribute'=>'classid'),        // 4.01
+               array('element'=>'object',      'attribute'=>'codebase'),       // 4.01
+               array('element'=>'object',      'attribute'=>'data'),           // 4.01
+               array('element'=>'object',      'attribute'=>'usemap'),         // 4.01
+               array('element'=>'q',           'attribute'=>'cite'),           // 4.01
+               array('element'=>'script',      'attribute'=>'src'),            // 4.01
+
+               array('element'=>'audio',       'attribute'=>'src'),            // 5.0
+               array('element'=>'command',     'attribute'=>'icon'),           // 5.0
+               array('element'=>'embed',       'attribute'=>'src'),            // 5.0
+               array('element'=>'event-source','attribute'=>'src'),            // 5.0
+               array('element'=>'html',        'attribute'=>'manifest'),       // 5.0
+               array('element'=>'source',      'attribute'=>'src'),            // 5.0
+               array('element'=>'video',       'attribute'=>'src'),            // 5.0
+               array('element'=>'video',       'attribute'=>'poster'),         // 5.0
+
+               array('element'=>'bgsound',     'attribute'=>'src'),            // Extension
+               array('element'=>'body',        'attribute'=>'credits'),        // Extension
+               array('element'=>'body',        'attribute'=>'instructions'),   // Extension
+               array('element'=>'body',        'attribute'=>'logo'),           // Extension
+               array('element'=>'div',         'attribute'=>'href'),           // Extension
+               array('element'=>'div',         'attribute'=>'src'),            // Extension
+               array('element'=>'embed',       'attribute'=>'code'),           // Extension
+               array('element'=>'embed',       'attribute'=>'pluginspage'),    // Extension
+               array('element'=>'html',        'attribute'=>'background'),     // Extension
+               array('element'=>'ilayer',      'attribute'=>'src'),            // Extension
+               array('element'=>'img',         'attribute'=>'dynsrc'),         // Extension
+               array('element'=>'img',         'attribute'=>'lowsrc'),         // Extension
+               array('element'=>'input',       'attribute'=>'dynsrc'),         // Extension
+               array('element'=>'input',       'attribute'=>'lowsrc'),         // Extension
+               array('element'=>'table',       'attribute'=>'background'),     // Extension
+               array('element'=>'td',          'attribute'=>'background'),     // Extension
+               array('element'=>'th',          'attribute'=>'background'),     // Extension
+               array('element'=>'layer',       'attribute'=>'src'),            // Extension
+               array('element'=>'xml',         'attribute'=>'src'),            // Extension
+
+               array('element'=>'button',      'attribute'=>'action'),         // Forms 2.0
+               array('element'=>'datalist',    'attribute'=>'data'),           // Forms 2.0
+               array('element'=>'form',        'attribute'=>'data'),           // Forms 2.0
+               array('element'=>'input',       'attribute'=>'action'),         // Forms 2.0
+               array('element'=>'select',      'attribute'=>'data'),           // Forms 2.0
+
+               // XHTML
+               array('element'=>'html',        'attribute'=>'xmlns'),
+
+               // WML
+               array('element'=>'access',      'attribute'=>'path'),           // 1.3
+               array('element'=>'card',        'attribute'=>'onenterforward'), // 1.3
+               array('element'=>'card',        'attribute'=>'onenterbackward'),// 1.3
+               array('element'=>'card',        'attribute'=>'ontimer'),        // 1.3
+               array('element'=>'go',          'attribute'=>'href'),           // 1.3
+               array('element'=>'option',      'attribute'=>'onpick'),         // 1.3
+               array('element'=>'template',    'attribute'=>'onenterforward'), // 1.3
+               array('element'=>'template',    'attribute'=>'onenterbackward'),// 1.3
+               array('element'=>'template',    'attribute'=>'ontimer'),        // 1.3
+               array('element'=>'wml',         'attribute'=>'xmlns'),          // 2.0
+       );
+
+       $match_metas = array(
+               'content-base',
+               'content-location',
+               'referer',
+               'location',
+               'refresh',
+       );
+
+       // Extract all elements
+       if ( !preg_match_all( '/<([a-z][^>]*)>/iu', $text, $matches ) )
+               return array( );
+       $elements = $matches[1];
+       $value_pattern = '=(("([^"]*)")|([^\s]*))';
+
+       // Match elements and attributes
+       foreach ( $match_elements as $match_element )
+       {
+               $name = $match_element['element'];
+               $attr = $match_element['attribute'];
+               $pattern = '/^' . $name . '\s.*' . $attr . $value_pattern . '/iu';
+               if ( $name == 'object' )
+                       $split_pattern = '/\s*/u';      // Space-separated URL list
+               else if ( $name == 'archive' )
+                       $split_pattern = '/,\s*/u';     // Comma-separated URL list
+               else
+                       unset( $split_pattern );        // Single URL
+               foreach ( $elements as $element )
+               {
+                       if ( !preg_match( $pattern, $element, $match ) )
+                               continue;
+                       $m = empty($match[3]) ? (!empty($match[4])?$match[4]:'') : $match[3];
+                       if ( !isset( $split_pattern ) )
+                               $urls[$name][$attr][] = $m;
+                       else
+                       {
+                               $msplit = preg_split( $split_pattern, $m );
+                               foreach ( $msplit as $ms )
+                                       $urls[$name][$attr][] = $ms;
+                       }
+               }
+       }
+
+       // Match meta http-equiv elements
+       foreach ( $match_metas as $match_meta )
+       {
+               $attr_pattern    = '/http-equiv="?' . $match_meta . '"?/iu';
+               $content_pattern = '/content'  . $value_pattern . '/iu';
+               $refresh_pattern = '/\d*;\s*(url=)?(.*)$/iu';
+               foreach ( $elements as $element )
+               {
+                       if ( !preg_match( '/^meta/iu', $element ) ||
+                               !preg_match( $attr_pattern, $element ) ||
+                               !preg_match( $content_pattern, $element, $match ) )
+                               continue;
+                       $m = empty($match[3]) ? $match[4] : $match[3];
+                       if ( $match_meta != 'refresh' )
+                               $urls['meta']['http-equiv'][] = $m;
+                       else if ( preg_match( $refresh_pattern, $m, $match ) )
+                               $urls['meta']['http-equiv'][] = $match[2];
+               }
+       }
+
+       // Match style attributes
+       $urls['style'] = array( );
+       $style_pattern = '/style' . $value_pattern . '/iu';
+       foreach ( $elements as $element )
+       {
+               if ( !preg_match( $style_pattern, $element, $match ) )
+                       continue;
+               $m = empty($match[3]) ? $match[4] : $match[3];
+               $style_urls = extract_css_urls( $m );
+               if ( !empty( $style_urls ) )
+                       $urls['style'] = array_merge_recursive(
+                               $urls['style'], $style_urls );
+       }
+
+       // Match style bodies
+       if ( preg_match_all( '/<style[^>]*>(.*?)<\/style>/siu', $text, $style_bodies ) )
+       {
+               foreach ( $style_bodies[1] as $style_body )
+               {
+                       $style_urls = extract_css_urls( $style_body );
+                       if ( !empty( $style_urls ) )
+                               $urls['style'] = array_merge_recursive(
+                                       $urls['style'], $style_urls );
+               }
+       }
+       if ( empty($urls['style']) )
+               unset( $urls['style'] );
+
+       return $urls;
+}
+/**
+ * Extract URLs from UTF-8 CSS text.
+ *
+ * URLs within @import statements and url() property functions are extracted
+ * and returned in an associative array of arrays.  Array keys indicate
+ * the use context for the URL, including:
+ *
+ *     "import"
+ *     "property"
+ *
+ * Each value in the associative array is an array of URLs.
+ *
+ * Parameters:
+ *     text            the UTF-8 text to scan
+ *
+ * Return values:
+ *     an associative array of arrays of URLs.
+ *
+ * See:
+ *     http://nadeausoftware.com/articles/2008/01/php_tip_how_extract_urls_css_file
+ */
+function extract_css_urls( $text )
+{
+       $urls = array( );
+
+       $url_pattern     = '(([^\\\\\'", \(\)]*(\\\\.)?)+)';
+       $urlfunc_pattern = 'url\(\s*[\'"]?' . $url_pattern . '[\'"]?\s*\)';
+       $pattern         = '/(' .
+                '(@import\s*[\'"]' . $url_pattern     . '[\'"])' .
+               '|(@import\s*'      . $urlfunc_pattern . ')'      .
+               '|('                . $urlfunc_pattern . ')'      .  ')/iu';
+       if ( !preg_match_all( $pattern, $text, $matches ) )
+               return $urls;
+
+       // @import '...'
+       // @import "..."
+       foreach ( $matches[3] as $match )
+               if ( !empty($match) )
+                       $urls['import'][] =
+                               preg_replace( '/\\\\(.)/u', '\\1', $match );
+
+       // @import url(...)
+       // @import url('...')
+       // @import url("...")
+       foreach ( $matches[7] as $match )
+               if ( !empty($match) )
+                       $urls['import'][] =
+                               preg_replace( '/\\\\(.)/u', '\\1', $match );
+
+       // url(...)
+       // url('...')
+       // url("...")
+       foreach ( $matches[11] as $match )
+               if ( !empty($match) )
+                       $urls['property'][] =
+                               preg_replace( '/\\\\(.)/u', '\\1', $match );
+
+       return $urls;
+}
diff --git a/repository/url/repository.class.php b/repository/url/repository.class.php
deleted file mode 100755 (executable)
index 91ed08e..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-<?php
-
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * repository_url class
- * A subclass of repository, which is used to download a file from a specific url
- *
- * @since 2.0
- * @package moodlecore
- * @subpackage repository
- * @copyright 2009 Dongsheng Cai
- * @author Dongsheng Cai <dongsheng@moodle.com>
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require_once(dirname(__FILE__).'/lib.php');
-
-class repository_url extends repository {
-
-    /**
-     * @param int $repositoryid
-     * @param object $context
-     * @param array $options
-     */
-    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()){
-        global $CFG;
-        parent::__construct($repositoryid, $context, $options);
-        if (!empty($options['client_id'])) {
-            // will be used to construct download form
-            $this->client_id = $options['client_id'];
-        }
-        $this->file_url = optional_param('file', '', PARAM_RAW);
-    }
-
-    public function get_file($url, $file = '') {
-        global $CFG;
-        //$CFG->repository_no_delete = true;
-        $path = $this->prepare_file($file);
-        $fp = fopen($path, 'w');
-        $c = new curl;
-        $c->download(array(array('url'=>$url, 'file'=>$fp)));
-        return array('path'=>$path, 'url'=>$url);
-    }
-
-    public function check_login() {
-        if (!empty($this->file_url)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-    /**
-     * @return mixed
-     */
-    public function print_login() {
-        $strdownload = get_string('download', 'repository');
-        $strname     = get_string('rename', 'repository_url');
-        $strurl      = get_string('url', 'repository_url');
-        if ($this->options['ajax']) {
-            $url = new stdclass;
-            $url->label = $strurl.': ';
-            $url->id   = 'fileurl-'.$this->client_id;
-            $url->type = 'text';
-            $url->name = 'file';
-
-            $ret['login'] = array($url);
-            $ret['login_btn_label'] = get_string('download', 'repository_url');
-            return $ret;
-        } else {
-            echo <<<EOD
-<table>
-<tr>
-<td>{$strurl}: </td><td><input name="file" type="text" /></td>
-</tr>
-</table>
-<input type="submit" value="{$strdownload}" />
-EOD;
-
-        }
-    }
-
-    /**
-     * @param mixed $path
-     * @param string $search
-     * @return array
-     */
-    public function get_listing($path='', $page='') {
-        global $CFG, $OUTPUT;
-        $ret = array();
-        $curl = new curl;
-        $msg = $curl->head($this->file_url);
-        $info = $curl->get_info();
-        if ($info['http_code'] != 200) {
-            $ret['e'] = $msg;
-        } else {
-            $ret['list'] = array();
-            $ret['nosearch'] = true;
-            $ret['nologin'] = true;
-            $filename = $this->guess_filename($info['url'], $info['content_type']);
-            if (strstr($info['content_type'], 'text/html') || empty($info['content_type'])) {
-                // analysis this web page, general file list
-                $ret['list'] = array();
-                $content = $curl->get($info['url']);
-                $this->analyse_page($info['url'], $content, $ret);
-            } else {
-                // download this file
-                $ret['list'][] = array(
-                    'title'=>$filename,
-                    'source'=>$this->file_url,
-                    'thumbnail' => $OUTPUT->pix_url(file_extension_icon($filename, 32))
-                    );
-            }
-        }
-        return $ret;
-    }
-    public function analyse_page($baseurl, $content, &$list) {
-        global $CFG, $OUTPUT;
-        $urls = extract_html_urls($content);
-        $images = $urls['img']['src'];
-        $pattern = '#img(.+)src="?\'?([[:alnum:]:?=&@/._+-]+)"?\'?#i';
-        if (!empty($images)) {
-            foreach($images as $url) {
-                $list['list'][] = array(
-                    'title'=>$this->guess_filename($url, ''),
-                    'source'=>url_to_absolute($baseurl, $url),
-                    'thumbnail'=>url_to_absolute($baseurl, $url),
-                    'thumbnail_height'=>84,
-                    'thumbnail_width'=>84
-                );
-            }
-        }
-    }
-    public function guess_filename($url, $type) {
-        $pattern = '#\/([\w_\?\-.]+)$#';
-        $matches = null;
-        preg_match($pattern, $url, $matches);
-        if (empty($matches[1])) {
-            return $url;
-        } else {
-            return $matches[1];
-        }
-    }
-
-    public function get_name(){
-        return get_string('pluginname', 'repository_url');;
-    }
-    public function supported_returntypes() {
-        return (FILE_INTERNAL | FILE_EXTERNAL);
-    }
-}
-
similarity index 88%
rename from repository/user/repository.class.php
rename to repository/user/lib.php
index 8759505..e3eabc1 100755 (executable)
@@ -69,23 +69,19 @@ class repository_user extends repository {
         $ret['nologin'] = true;
         $list = array();
 
-        //TODO: this is weird, why not only user context? (skodak)
-
         if (!empty($encodedpath)) {
             $params = unserialize(base64_decode($encodedpath));
             if (is_array($params)) {
                 $itemid   = $params['itemid'];
                 $filename = $params['filename'];
                 $filearea = $params['filearea'];
-                $component = $params['component'];
                 $filepath = $params['filepath'];
                 $context  = get_context_instance_by_id($params['contextid']);
             }
         } else {
             $itemid   = 0;
             $filename = null;
-            $component = 'user';
-            $filearea = 'private';
+            $filearea = 'user_private';
             $filepath = '/';
             $context = get_context_instance(CONTEXT_USER, $USER->id);
         }
@@ -93,11 +89,11 @@ class repository_user extends repository {
         try {
             $browser = get_file_browser();
 
-            if ($fileinfo = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename)) {
+            if ($fileinfo = $browser->get_file_info($context, $filearea, $itemid, $filepath, $filename)) {
                 $pathnodes = array();
                 $level = $fileinfo;
                 $params = $fileinfo->get_params();
-                while ($level && $params['filearea'] == 'private' && $params['component'] == 'user') {
+                while ($level && $params['filearea'] == 'user_private') {
                     $encodedpath = base64_encode(serialize($level->get_params()));
                     $pathnodes[] = array('name'=>$level->get_visible_name(), 'path'=>$encodedpath);
                     $level = $level->get_parent();
@@ -170,7 +166,7 @@ class repository_user extends repository {
      * @param string $new_filepath the new path in draft area
      * @return array The information of file
      */
-    public function copy_to_area($encoded, $new_filearea='ignored', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
+    public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
         global $USER, $DB;
         $info = array();
 
@@ -179,15 +175,14 @@ class repository_user extends repository {
         $user_context = get_context_instance(CONTEXT_USER, $USER->id);
         // the final file
         $contextid  = $params['contextid'];
-        $component  = $params['component'];
         $filearea   = $params['filearea'];
         $filepath   = $params['filepath'];
         $filename   = $params['filename'];
         $fileitemid = $params['itemid'];
         $context    = get_context_instance_by_id($contextid);
         try {
-            $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename);
-            $file_info->copy_to_storage($user_context->id, 'user', 'draft', $new_itemid, $new_filepath, $new_filename);
+            $file_info = $browser->get_file_info($context, $filearea, $fileitemid, $filepath, $filename);
+            $file_info->copy_to_storage($user_context->id, $new_filearea, $new_itemid, $new_filepath, $new_filename);
         } catch (Exception $e) {
             throw $e;
         }