MDL-22982
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
This commit is contained in:
@@ -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';
|
||||
|
||||
+16
-25
@@ -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;
|
||||
|
||||
@@ -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'));
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ';
|
||||
+260
-24
@@ -16,8 +16,13 @@
|
||||
// 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
|
||||
@@ -27,32 +32,263 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__).'/locallib.php');
|
||||
|
||||
require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
|
||||
require_once($CFG->libdir.'/oauthlib.php');
|
||||
class repository_dropbox extends repository {
|
||||
private $dropbox;
|
||||
public $files;
|
||||
public $logged=false;
|
||||
|
||||
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);
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
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;
|
||||
|
||||
/**
|
||||
* Check if moodle has got access token and secret
|
||||
* @return bool
|
||||
*/
|
||||
public function check_login() {
|
||||
return !empty($this->logged);
|
||||
}
|
||||
public function get_account_info($token, $secret) {
|
||||
$url = $this->dropbox_api.'/account/info';
|
||||
$content = $this->get($url, array(), $token, $secret);
|
||||
return $content;
|
||||
|
||||
/**
|
||||
* 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>';
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <[email protected]>
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
@@ -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 <[email protected]>
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
@@ -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>';
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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'];
|
||||
@@ -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;
|
||||
+46
-74
@@ -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 . '&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.'&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."&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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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);
|
||||
+114
-152
@@ -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)) {
|
||||
$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->error = 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 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;
|
||||
|
||||
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; // 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
|
||||
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 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;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -16,37 +16,21 @@
|
||||
// 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,44 +39,101 @@ 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;
|
||||
global $USER, $CFG;
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
return $this->info;
|
||||
|
||||
$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);
|
||||
|
||||
$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 = file_correct_filepath($record->filepath);
|
||||
}
|
||||
|
||||
if (!isset($_FILES[$elname])) {
|
||||
throw new moodle_exception('nofile');
|
||||
}
|
||||
|
||||
if (!empty($_FILES[$elname]['error'])) {
|
||||
throw new moodle_exception('maxbytes');
|
||||
}
|
||||
|
||||
if (empty($record->filename)) {
|
||||
$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 = $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->userid = $USER->id;
|
||||
$record->source = '';
|
||||
|
||||
$stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
|
||||
|
||||
return array(
|
||||
'url'=>file_draftfile_url($record->itemid, $record->filepath, $record->filename),
|
||||
'id'=>$record->itemid,
|
||||
'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;
|
||||
// define upload form in file picker
|
||||
$ret['upload'] = array('label'=>get_string('attachment', 'repository'), 'id'=>'repo-form');
|
||||
|
||||
if (has_capability('moodle/course:managefiles', $this->context)) {
|
||||
$ret['manage'] = $CFG->wwwroot .'/files/index.php';
|
||||
}
|
||||
$ret['list'] = array();
|
||||
$ret['dynload'] = false;
|
||||
$ret['upload'] = array('label'=>get_string('attachment', 'repository'), 'id'=>'repo-form');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the name of this repository
|
||||
* Define the readable name of this repository
|
||||
* @return string
|
||||
*/
|
||||
public function get_name(){
|
||||
@@ -110,63 +151,12 @@ class repository_upload extends repository {
|
||||
/**
|
||||
* Upload file to local filesystem pool
|
||||
* @param string $elname name of element
|
||||
* @param object $record
|
||||
* @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) {
|
||||
global $USER, $CFG;
|
||||
$context = get_context_instance(CONTEXT_USER, $USER->id);
|
||||
|
||||
$fs = get_file_storage();
|
||||
|
||||
if ($record->filepath !== '/') {
|
||||
$record->filepath = trim($record->filepath, '/');
|
||||
$record->filepath = '/'.$record->filepath.'/';
|
||||
}
|
||||
|
||||
if (!isset($_FILES[$elname])) {
|
||||
throw new moodle_exception('nofile');
|
||||
}
|
||||
|
||||
if (!empty($_FILES[$elname]['error'])) {
|
||||
throw new moodle_exception('maxbytes');
|
||||
}
|
||||
|
||||
if (empty($record->filename)) {
|
||||
$record->filename = $_FILES[$elname]['name'];
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
return array(
|
||||
'url'=>file_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename()),
|
||||
'id'=>$record->itemid,
|
||||
'file'=>$file->get_filename()
|
||||
);
|
||||
}
|
||||
}
|
||||
+152
-689
@@ -1,702 +1,165 @@
|
||||
<?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
|
||||
*/
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* repository_url class
|
||||
* A subclass of repository, which is used to download a file from a specific url
|
||||
*
|
||||
* 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.
|
||||
* @since 2.0
|
||||
* @package moodlecore
|
||||
* @subpackage repository
|
||||
* @copyright 2009 Dongsheng Cai
|
||||
* @author Dongsheng Cai <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
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'];
|
||||
require_once(dirname(__FILE__).'/locallib.php');
|
||||
|
||||
// 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'] );
|
||||
class repository_url extends repository {
|
||||
|
||||
// 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'];
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
// 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 );
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 );
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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", "[email protected]",
|
||||
* "example.com:80", "user:[email protected]: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;
|
||||
}
|
||||
|
||||
@@ -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", "[email protected]",
|
||||
* "example.com:80", "user:[email protected]: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;
|
||||
}
|
||||
@@ -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 <[email protected]>
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user