MDL-15405: make itemid & filepath mandatory
[moodle.git] / repository / lib.php
CommitLineData
1cf56396 1<?php // $Id$
2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
10// Copyright (C) 2008 onwards Moodle Pty Ltd http://moodle.com //
11// //
12// This program is free software; you can redistribute it and/or modify //
13// it under the terms of the GNU General Public License as published by //
14// the Free Software Foundation; either version 2 of the License, or //
15// (at your option) any later version. //
16// //
17// This program is distributed in the hope that it will be useful, //
18// but WITHOUT ANY WARRANTY; without even the implied warranty of //
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
20// GNU General Public License for more details: //
21// //
22// http://www.gnu.org/copyleft/gpl.html //
23// //
24///////////////////////////////////////////////////////////////////////////
25
26/**
fca079c5 27 * This is the base class of the repository class
82669dc4 28 *
aa754fe3 29 * To use repository plugin, you need to create a new folder under repository/, named as the remote
82669dc4 30 * repository, the subclass must be defined in the name
31
32 *
33 * class repository is an abstract class, some functions must be implemented in subclass.
34 *
c9260130 35 * See an example of use of this library in repository/boxnet/repository.class.php
82669dc4 36 *
37 * A few notes :
aa754fe3 38 * // options are stored as serialized format in database
39 * $options = array('api_key'=>'dmls97d8j3i9tn7av8y71m9eb55vrtj4',
82669dc4 40 * 'auth_token'=>'', 'path_root'=>'/');
c9260130 41 * $repo = new repository_xxx($options);
82669dc4 42 * // print login page or a link to redirect to another page
43 * $repo->print_login();
44 * // call get_listing, and print result
45 * $repo->print_listing();
46 * // print a search box
47 * $repo->print_search();
48 *
49 * @version 1.0 dev
c425472d 50 * @package repository
82669dc4 51 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
1cf56396 52 */
19add4c0 53require_once(dirname(dirname(__FILE__)) . '/config.php');
c5704ec6 54require_once(dirname(dirname(__FILE__)).'/lib/filelib.php');
4a65c39a 55require_once(dirname(dirname(__FILE__)).'/lib/formslib.php');
1cf56396 56
fca079c5 57abstract class repository {
4a65c39a 58 public $id;
59 public $context;
60 public $options;
1cf56396 61
62 /**
3f24ea1e 63 * 1. Initialize context and options
64 * 2. Accept necessary parameters
65 *
8dcd5deb 66 * @param integer $repositoryid
67 * @param integer $contextid
68 * @param array $options
1cf56396 69 */
b6558c3b 70 public function __construct($repositoryid, $contextid = SITEID, $options = array()){
4a65c39a 71 $this->id = $repositoryid;
72 $this->context = get_context_instance_by_id($contextid);
73 $this->options = array();
fca079c5 74 if (is_array($options)) {
4a65c39a 75 $options = array_merge($this->get_option(), $options);
76 } else {
77 $options = $this->get_option();
78 }
b1339e98 79 $this->options = array();
4a65c39a 80 foreach ($options as $n => $v) {
81 $this->options[$n] = $v;
82669dc4 82 }
d31af46a 83 $this->name = $this->get_name();
1cf56396 84 }
85
8dcd5deb 86 /**
3f24ea1e 87 * set options for repository instance
88 *
8dcd5deb 89 * @param string $name
3f24ea1e 90 * @param mixed $value
8dcd5deb 91 */
fca079c5 92 public function __set($name, $value) {
82669dc4 93 $this->options[$name] = $value;
94 }
1cf56396 95
8dcd5deb 96 /**
3f24ea1e 97 * get options for repository instance
98 *
99 * @param string $name
100 * @return mixed
8dcd5deb 101 */
fca079c5 102 public function __get($name) {
82669dc4 103 if (array_key_exists($name, $this->options)){
104 return $this->options[$name];
105 }
106 trigger_error('Undefined property: '.$name, E_USER_NOTICE);
107 return null;
108 }
1cf56396 109
8dcd5deb 110 /**
3f24ea1e 111 * test option name
112 *
113 * @param string name
8dcd5deb 114 */
fca079c5 115 public function __isset($name) {
82669dc4 116 return isset($this->options[$name]);
1cf56396 117 }
118
8dcd5deb 119 /**
3f24ea1e 120 * Return the name of the repository class
8dcd5deb 121 * @return <type>
122 */
fca079c5 123 public function __toString() {
82669dc4 124 return 'Repository class: '.__CLASS__;
125 }
4a65c39a 126
c425472d 127 /**
3f24ea1e 128 * Download a file from a given url
129 *
8dcd5deb 130 * @global object $CFG
c425472d 131 * @param string $url the url of file
132 * @param string $file save location
3f24ea1e 133 * @return string the location of the file
b1339e98 134 * @see curl package
c425472d 135 */
bb2c046d 136 public function get_file($url, $file = '') {
c425472d 137 global $CFG;
c9260130 138 if (!file_exists($CFG->dataroot.'/temp/download')) {
139 mkdir($CFG->dataroot.'/temp/download/', 0777, true);
1e28c767 140 }
c9260130 141 if(is_dir($CFG->dataroot.'/temp/download')) {
142 $dir = $CFG->dataroot.'/temp/download/';
1e28c767 143 }
84df43de 144 if(empty($file)) {
145 $file = uniqid('repo').'_'.time().'.tmp';
146 }
147 if(file_exists($dir.$file)){
148 $file = uniqid('m').$file;
c425472d 149 }
84df43de 150 $fp = fopen($dir.$file, 'w');
151 $c = new curl;
152 $c->download(array(
153 array('url'=>$url, 'file'=>$fp)
154 ));
155 return $dir.$file;
82669dc4 156 }
1cf56396 157
1cf56396 158 /**
82669dc4 159 * Print a list or return string
160 *
161 * @param string $list
3f24ea1e 162 * @param boolean $print false, return html, otherwise, print it directly
8dcd5deb 163 * @return <type>
164 */
fca079c5 165 public function print_listing($listing = array(), $print=true) {
0f59046f 166 if(empty($listing)){
167 $listing = $this->get_listing();
168 }
fca079c5 169 if (empty($listing)) {
170 $str = '';
171 } else {
172 $count = 0;
173 $str = '<table>';
174 foreach ($listing as $v){
175 $str .= '<tr id="entry_'.$count.'">';
176 $str .= '<td><input type="checkbox" /></td>';
177 $str .= '<td>'.$v['name'].'</td>';
178 $str .= '<td>'.$v['size'].'</td>';
179 $str .= '<td>'.$v['date'].'</td>';
180 $str .= '</tr>';
181 $count++;
182 }
d1fe3452 183 $str .= '</table>';
82669dc4 184 }
fca079c5 185 if ($print){
82669dc4 186 echo $str;
187 return null;
188 } else {
189 return $str;
190 }
1cf56396 191 }
d31af46a 192 public function get_name(){
193 global $DB;
194 // We always verify instance id from database,
195 // so we always know repository name before init
196 // a repository, so we don't enquery repository
197 // name from database again here.
198 if (isset($this->options['name'])) {
199 return $this->options['name'];
200 } else {
201 if ( $repo = $DB->get_record('repository_instances', array('id'=>$this->id)) ) {
202 return $repo->name;
203 } else {
204 return '';
205 }
206 }
207 }
aa754fe3 208
82669dc4 209 /**
3f24ea1e 210 * Provide repository instance information for Ajax
8dcd5deb 211 * @global object $CFG
4a65c39a 212 * @return object
82669dc4 213 */
b1339e98 214 final public function ajax_info() {
4a65c39a 215 global $CFG;
216 $repo = new stdclass;
27051e43 217 $repo->id = $this->id;
d31af46a 218 $repo->name = $this->get_name();
4a65c39a 219 $repo->type = $this->options['type'];
4a65c39a 220 $repo->icon = $CFG->wwwroot.'/repository/'.$repo->type.'/icon.png';
221 return $repo;
222 }
1cf56396 223
b1339e98 224 /**
225 * Create an instance for this plug-in
8dcd5deb 226 * @global object $CFG
227 * @global object $DB
228 * @param string $type the type of the repository
229 * @param integer $userid the user id
230 * @param object $context the context
231 * @param array $params the options for this instance
232 * @return <type>
b1339e98 233 */
234 final public static function create($type, $userid, $context, $params) {
235 global $CFG, $DB;
236 $params = (array)$params;
237 require_once($CFG->dirroot . '/repository/'. $type . '/repository.class.php');
238 $classname = 'repository_' . $type;
3023078f 239 if ($repo = $DB->get_record('repository', array('type'=>$type))) {
240 $record = new stdclass;
241 $record->name = $params['name'];
242 $record->typeid = $repo->id;
243 $record->timecreated = time();
244 $record->timemodified = time();
245 $record->contextid = $context->id;
246 $record->userid = $userid;
247 $id = $DB->insert_record('repository_instances', $record);
248 if (call_user_func($classname . '::has_admin_config')) {
249 $configs = call_user_func($classname . '::get_option_names');
250 $options = array();
251 foreach ($configs as $config) {
252 $options[$config] = $params[$config];
253 }
254 }
255 if (!empty($id)) {
256 unset($options['name']);
c9f9f911 257 $instance = repository_get_instance($id);
3023078f 258 $instance->set_option($options);
259 return $id;
260 } else {
261 return null;
b1339e98 262 }
b1339e98 263 } else {
264 return null;
265 }
266 }
8dcd5deb 267
82669dc4 268 /**
4a65c39a 269 * delete a repository instance
8dcd5deb 270 * @global object $DB
271 * @return <type>
82669dc4 272 */
b1339e98 273 final public function delete(){
4a65c39a 274 global $DB;
122defc5 275 $DB->delete_records('repository_instances', array('id'=>$this->id));
4a65c39a 276 return true;
277 }
8dcd5deb 278
4a65c39a 279 /**
280 * Hide/Show a repository
8dcd5deb 281 * @global object $DB
282 * @param string $hide
283 * @return <type>
4a65c39a 284 */
b1339e98 285 final public function hide($hide = 'toggle'){
4a65c39a 286 global $DB;
287 if ($entry = $DB->get_record('repository', array('id'=>$this->id))) {
288 if ($hide === 'toggle' ) {
289 if (!empty($entry->visible)) {
290 $entry->visible = 0;
291 } else {
292 $entry->visible = 1;
293 }
294 } else {
295 if (!empty($hide)) {
296 $entry->visible = 0;
297 } else {
298 $entry->visible = 1;
299 }
300 }
301 return $DB->update_record('repository', $entry);
302 }
303 return false;
304 }
1cf56396 305
306 /**
82669dc4 307 * Cache login details for repositories
8dcd5deb 308 * @global object $DB
82669dc4 309 * @param string $username
310 * @param string $password
8dcd5deb 311 * @param integer $userid The id of specific user
312 * @return integer Id of the record
1cf56396 313 */
b6558c3b 314 public function store_login($username = '', $password = '', $userid = 1) {
fca079c5 315 global $DB;
316
317 $repository = new stdclass;
4a65c39a 318 if (!empty($this->id)) {
319 $repository->id = $this->id;
19add4c0 320 } else {
321 $repository->userid = $userid;
322 $repository->repositorytype = $this->type;
b6558c3b 323 $repository->contextid = $this->context->id;
19add4c0 324 }
fca079c5 325 if ($entry = $DB->get_record('repository', $repository)) {
326 $repository->id = $entry->id;
327 $repository->username = $username;
328 $repository->password = $password;
329 return $DB->update_record('repository', $repository);
330 } else {
331 $repository->username = $username;
332 $repository->password = $password;
333 return $DB->insert_record('repository', $repository);
334 }
1cf56396 335 }
336
1cf56396 337 /**
4a65c39a 338 * Save settings for repository instance
8dcd5deb 339 * $repo->set_option(array('api_key'=>'f2188bde132', 'name'=>'dongsheng'));
340 * @global object $DB
341 * @param array $options settings
4a65c39a 342 * @return int Id of the record
1cf56396 343 */
4a65c39a 344 public function set_option($options = array()){
345 global $DB;
122defc5 346 if (!empty($options['name'])) {
347 $r = new object();
348 $r->id = $this->id;
349 $r->name = $options['name'];
350 $DB->update_record('repository_instances', $r);
351 unset($options['name']);
352 }
27051e43 353 foreach ($options as $name=>$value) {
354 if ($id = $DB->get_field('repository_instance_config', 'id', array('name'=>$name, 'instanceid'=>$this->id))) {
355 if ($value===null) {
356 return $DB->delete_records('repository_instance_config', array('name'=>$name, 'instanceid'=>$this->id));
357 } else {
358 return $DB->set_field('repository_instance_config', 'value', $value, array('id'=>$id));
359 }
360 } else {
361 if ($value===null) {
362 return true;
363 }
364 $config = new object();
365 $config->instanceid = $this->id;
366 $config->name = $name;
367 $config->value = $value;
368 return $DB->insert_record('repository_instance_config', $config);
369 }
4a65c39a 370 }
27051e43 371 return true;
1cf56396 372 }
1cf56396 373
4a65c39a 374 /**
375 * Get settings for repository instance
8dcd5deb 376 * @global object $DB
377 * @param <type> $config
4a65c39a 378 * @return array Settings
379 */
380 public function get_option($config = ''){
381 global $DB;
27051e43 382 $entries = $DB->get_records('repository_instance_config', array('instanceid'=>$this->id));
383 $ret = array();
384 if (empty($entries)) {
385 return $ret;
4a65c39a 386 }
27051e43 387 foreach($entries as $entry){
388 $ret[$entry->name] = $entry->value;
4a65c39a 389 }
390 if (!empty($config)) {
391 return $ret[$config];
392 } else {
393 return $ret;
394 }
395 }
bf1fccf0 396
4a65c39a 397 /**
398 * Given a path, and perhaps a search, get a list of files.
399 *
e6be3a69 400 * The format of the returned array must be:
f7639c37 401 * array(
f6812a21 402 * 'path' => (string) path for the current folder
f7639c37 403 * 'dynload' => (bool) use dynamic loading,
f6812a21 404 * 'manage' => (string) link to file manager,
f7639c37 405 * 'nologin' => (bool) requires login,
d31af46a 406 * 'nosearch' => (bool) no search link,
f7639c37 407 * 'upload' => array( // upload manager
408 * 'name' => (string) label of the form element,
409 * 'id' => (string) id of the form element
410 * ),
411 * 'list' => array(
412 * array( // file
413 * 'title' => (string) file name,
3c9e53c0 414 * 'date' => (string) file last modification time, usually userdate(...),
f6812a21 415 * 'size' => (int) file size,
3c9e53c0 416 * 'thumbnail' => (string) url to thumbnail for the file,
336bb44b 417 * 'source' => plugin-dependent unique path to the file (id, url, path, etc.),
418 * 'url'=> the accessible url of file
f7639c37 419 * ),
3c9e53c0 420 * array( // folder - same as file, but no 'source'.
f7639c37 421 * 'title' => (string) folder name,
f6812a21 422 * 'path' => (string) path to this folder
3c9e53c0 423 * 'date' => (string) folder last modification time, usually userdate(...),
f6812a21 424 * 'size' => 0,
3c9e53c0 425 * 'thumbnail' => (string) url to thumbnail for the folder,
426 * 'children' => array( // an empty folder needs to have 'children' defined, but empty.
427 * // content (files and folders)
f7639c37 428 * )
e6be3a69 429 * ),
f7639c37 430 * )
431 * )
432 *
4a65c39a 433 * @param string $parent The parent path, this parameter can
434 * a folder name, or a identification of folder
435 * @param string $search The text will be searched.
436 * @return array the list of files, including meta infomation
437 */
438 abstract public function get_listing($parent = '/', $search = '');
1cf56396 439
1cf56396 440
4a65c39a 441 /**
442 * Show the login screen, if required
443 * This is an abstract function, it must be overriden.
4a65c39a 444 */
445 abstract public function print_login();
1cf56396 446
4a65c39a 447 /**
448 * Show the search screen, if required
4a65c39a 449 * @return null
450 */
451 abstract public function print_search();
452
8dcd5deb 453 /**
454 * TODO: write comment
455 * @return <type>
456 */
4a65c39a 457 public static function has_admin_config() {
458 return false;
459 }
460
4a65c39a 461
462 /**
463 * Defines operations that happen occasionally on cron
8dcd5deb 464 * @return <type>
4a65c39a 465 */
466 public function cron() {
467 return true;
8b65d45c 468 }
8b65d45c 469}
837ebb78 470
471/**
4a65c39a 472 * exception class for repository api
837ebb78 473 */
4a65c39a 474class repository_exception extends moodle_exception {
8b65d45c 475}
4ed43890 476
4a65c39a 477
837ebb78 478/**
4a65c39a 479 * Return repository instances
8dcd5deb 480 * @global object $DB
481 * @global object $CFG
482 * @global object $USER
483 * @param object $context
484 * @param integer $userid
485 * @param boolean $visible if visible == true, return visible instances only,
4a65c39a 486 * otherwise, return all instances
487 * @return array repository instances
837ebb78 488 */
e6be3a69 489function repository_get_instances($context, $userid = null, $visible = true){
38e55442 490 global $DB, $CFG, $USER;
38e55442 491 $params = array();
27051e43 492 $sql = 'SELECT i.*, r.type AS repositorytype, r.visible FROM {repository} r, {repository_instances} i WHERE ';
493 $sql .= 'i.typeid = r.id AND ';
4a65c39a 494 if (!empty($userid) && is_numeric($userid)) {
27051e43 495 $sql .= ' (i.userid = 0 or i.userid = ?) AND ';
4a65c39a 496 $params[] = $userid;
497 }
498 if($context->id == SYSCONTEXTID) {
27051e43 499 $sql .= ' (i.contextid = ?)';
4a65c39a 500 $params[] = SYSCONTEXTID;
38e55442 501 } else {
27051e43 502 $sql .= ' (i.contextid = ? or i.contextid = ?)';
4a65c39a 503 $params[] = SYSCONTEXTID;
b6558c3b 504 $params[] = $context->id;
38e55442 505 }
4a65c39a 506 if($visible == true) {
507 $sql .= ' AND (r.visible = 1)';
508 }
38e55442 509 if(!$repos = $DB->get_records_sql($sql, $params)) {
510 $repos = array();
511 }
4a65c39a 512 $ret = array();
513 foreach($repos as $repo) {
e6be3a69 514 require_once($CFG->dirroot . '/repository/'. $repo->repositorytype
4a65c39a 515 . '/repository.class.php');
27051e43 516 $options['visible'] = $repo->visible;
517 $options['name'] = $repo->name;
518 $options['type'] = $repo->repositorytype;
519 $options['typeid'] = $repo->typeid;
4a65c39a 520 $classname = 'repository_' . $repo->repositorytype;
27051e43 521 $ret[] = new $classname($repo->id, $repo->contextid, $options);
4a65c39a 522 }
523 return $ret;
38e55442 524}
4ed43890 525
837ebb78 526/**
527 * Get single repository instance
8dcd5deb 528 * @global object $DB
529 * @global object $CFG
530 * @param integer $id repository id
837ebb78 531 * @return object repository instance
532 */
c9f9f911 533function repository_get_instance($id){
19add4c0 534 global $DB, $CFG;
27051e43 535 $sql = 'SELECT i.*, r.type AS repositorytype, r.visible FROM {repository} r, {repository_instances} i WHERE ';
536 $sql .= 'i.typeid = r.id AND ';
537 $sql .= 'i.id = '.$id;
19add4c0 538
27051e43 539 if(!$instance = $DB->get_record_sql($sql)) {
19add4c0 540 return false;
541 }
e6be3a69 542 require_once($CFG->dirroot . '/repository/'. $instance->repositorytype
19add4c0 543 . '/repository.class.php');
544 $classname = 'repository_' . $instance->repositorytype;
27051e43 545 $options['typeid'] = $instance->typeid;
546 $options['type'] = $instance->repositorytype;
547 $options['name'] = $instance->name;
548 return new $classname($instance->id, $instance->contextid, $options);
19add4c0 549}
837ebb78 550
8dcd5deb 551/**
552 * TODO: write documentation
553 * @global <type> $CFG
554 * @param <type> $plugin
555 * @param <type> $function
556 * @return <type>
557 */
4a65c39a 558function repository_static_function($plugin, $function) {
97f7393d 559 global $CFG;
4a65c39a 560
561 $pname = null;
562 if (is_object($plugin) || is_array($plugin)) {
563 $plugin = (object)$plugin;
564 $pname = $plugin->name;
565 } else {
566 $pname = $plugin;
97f7393d 567 }
4a65c39a 568
569 $args = func_get_args();
570 if (count($args) <= 2) {
571 $args = array();
572 }
573 else {
574 array_shift($args);
575 array_shift($args);
576 }
577
578 require_once($CFG->dirroot . '/repository/' . $plugin . '/repository.class.php');
579 return call_user_func_array(array('repository_' . $plugin, $function), $args);
97f7393d 580}
d8eb6e18 581
837ebb78 582/**
583 * Move file from download folder to file pool using FILE API
b1339e98 584 * @TODO Need review
8dcd5deb 585 * @global object $DB
586 * @global object $CFG
587 * @global object $USER
588 * @param string $path file path in download folder
589 * @param string $name file name
590 * @param integer $itemid item id to identify a file in filepool
591 * @param string $filearea file area
592 * @param string $filepath filepath in file area
837ebb78 593 * @return array information of file in file pool
594 */
c9260130 595function repository_move_to_filepool($path, $name, $itemid, $filearea = 'user_draft') {
d8eb6e18 596 global $DB, $CFG, $USER;
597 $context = get_context_instance(CONTEXT_USER, $USER->id);
598 $entry = new object();
55b4bb1d 599 $entry->filearea = $filearea;
d8eb6e18 600 $entry->contextid = $context->id;
601 $entry->filename = $name;
c9260130 602 $entry->filepath = '/'.uniqid().'/';
d8eb6e18 603 $entry->timecreated = time();
604 $entry->timemodified = time();
c2762f06 605 if(is_numeric($itemid)) {
606 $entry->itemid = $itemid;
607 } else {
608 $entry->itemid = 0;
609 }
d8eb6e18 610 $entry->mimetype = mimeinfo('type', $path);
611 $entry->userid = $USER->id;
612 $fs = get_file_storage();
613 $browser = get_file_browser();
614 if ($file = $fs->create_file_from_pathname($entry, $path)) {
c9260130 615 $delete = unlink($path);
d8eb6e18 616 $ret = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
3023078f 617 if(!empty($ret)){
c0fa8cba 618 return array('url'=>$ret->get_url(),'id'=>$file->get_itemid(), 'file'=>$file->get_filename());
3023078f 619 } else {
620 return null;
621 }
d8eb6e18 622 } else {
623 return null;
624 }
625}
626
5a3b9db9 627/**
628 * Save file to local filesystem pool
629 * @param string $elname name of element
630 * @param int $contextid
631 * @param string $filearea
632 * @param string $filepath
633 * @param string $filename - use specified filename, if not specified name of uploaded file used
634 * @param bool $override override file if exists
635 * @param int $userid
636 * @return mixed stored_file object or false if error; may throw exception if duplicate found
637 */
638function repository_store_to_filepool($elname, $filearea='user_draft', $filepath='/') {
639 global $USER;
640 if (!isset($_FILES[$elname])) {
641 return false;
642 }
643
644 $filename = $_FILES[$elname]['name'];
645 $context = get_context_instance(CONTEXT_USER, $USER->id);
646 $itemid = (int)substr(hexdec(uniqid()), 0, 9)+rand(1,100);
647 $fs = get_file_storage();
648 $browser = get_file_browser();
649
650 if ($file = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
651 if ($override) {
652 $file->delete();
653 } else {
654 return false;
655 }
656 }
657
658 $file_record = new object();
659 $file_record->contextid = $context->id;
660 $file_record->filearea = $filearea;
661 $file_record->itemid = $itemid;
662 $file_record->filepath = $filepath;
663 $file_record->filename = $filename;
664 $file_record->userid = $USER->id;
665
666 $file = $fs->create_file_from_pathname($file_record, $_FILES[$elname]['tmp_name']);
667 $info = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
668 $ret = array('url'=>$info->get_url(),'id'=>$itemid, 'file'=>$file->get_filename());
669 return $ret;
670}
671
837ebb78 672/**
673 * Return javascript to create file picker to browse repositories
8dcd5deb 674 * @global object $CFG
675 * @global object $USER
676 * @param object $context the context
e6be3a69 677 * @return array
837ebb78 678 */
49a1ce19 679function repository_get_client($context){
f3a6f85b 680 global $CFG, $USER;
c2762f06 681 $suffix = uniqid();
0eaa8c5c 682 $sesskey = sesskey();
336bb44b 683 $strsaveas = get_string('saveas', 'repository').': ';
a347291c 684 $stradd = get_string('add', 'repository');
c5704ec6 685 $strback = get_string('back', 'repository');
686 $strclose = get_string('close', 'repository');
b82bcbcb 687 $strcopying = get_string('copying', 'repository');
55b4bb1d 688 $strdownbtn = get_string('getfile', 'repository');
64be2d6c 689 $strdownload = get_string('downloadsucc', 'repository');
a347291c 690 $strdate = get_string('date', 'repository').': ';
691 $strerror = get_string('error', 'repository');
9ccfe7aa 692 $strfilenotnull = get_string('filenotnull', 'repository');
a347291c 693 $strinvalidjson = get_string('invalidjson', 'repository');
694 $strlistview = get_string('listview', 'repository');
695 $strlogout = get_string('logout', 'repository');
696 $strloading = get_string('loading', 'repository');
697 $strthumbview = get_string('thumbview', 'repository');
698 $strtitle = get_string('title', 'repository');
ae8d6f23 699 $strmgr = get_string('manageurl', 'repository');
64be2d6c 700 $strnoenter = get_string('noenter', 'repository');
a347291c 701 $strsave = get_string('save', 'repository');
702 $strsaved = get_string('saved', 'repository');
703 $strsaving = get_string('saving', 'repository');
704 $strsize = get_string('size', 'repository').': ';
705 $strsync = get_string('sync', 'repository');
706 $strsearch = get_string('search', 'repository');
64be2d6c 707 $strsearching = get_string('searching', 'repository');
a347291c 708 $strsubmit = get_string('submit', 'repository');
8a1d4a46 709 $strpreview = get_string('preview', 'repository');
a347291c 710 $strupload = get_string('upload', 'repository');
711 $struploading = get_string('uploading', 'repository');
d373f63f 712 $css = <<<EOD
19f1d262 713<style type="text/css">
714#list-$suffix{line-height: 1.5em}
715#list-$suffix a{ padding: 3px }
716#list-$suffix li a:hover{ background: gray; color:white; }
717#repo-list-$suffix .repo-name{}
718#repo-list-$suffix li{margin-bottom: 1em}
27051e43 719#paging-$suffix{margin:10px 5px; clear:both;}
720#paging-$suffix a{padding: 4px;border: 1px solid #CCC}
31640be2 721#path-$suffix{margin: 4px;border-bottom: 1px dotted gray;}
722#path-$suffix a{padding: 4px;}
19f1d262 723#panel-$suffix{padding:0;margin:0; text-align:left;}
336bb44b 724#rename-form{text-align:center}
725#rename-form p{margin: 1em;}
19f1d262 726p.upload{text-align:right;margin: 5px}
727p.upload a{font-size: 14px;background: #ccc;color:black;padding: 3px}
728p.upload a:hover {background: grey;color:white}
729.file_name{color:green;}
730.file_date{color:blue}
731.file_size{color:gray}
732.grid{width:80px; float:left;text-align:center;}
336bb44b 733.grid div{width: 80px; overflow: hidden}
734.grid .label{height: 36px}
19f1d262 735.repo-opt{font-size: 10px;}
736</style>
737<style type="text/css">
738@import "$CFG->wwwroot/lib/yui/reset-fonts-grids/reset-fonts-grids.css";
739@import "$CFG->wwwroot/lib/yui/reset/reset-min.css";
740@import "$CFG->wwwroot/lib/yui/resize/assets/skins/sam/resize.css";
741@import "$CFG->wwwroot/lib/yui/container/assets/skins/sam/container.css";
742@import "$CFG->wwwroot/lib/yui/layout/assets/skins/sam/layout.css";
743@import "$CFG->wwwroot/lib/yui/button/assets/skins/sam/button.css";
744@import "$CFG->wwwroot/lib/yui/assets/skins/sam/treeview.css";
745</style>
d373f63f 746EOD;
747
748 $js = <<<EOD
19f1d262 749<script type="text/javascript" src="$CFG->wwwroot/lib/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
750<script type="text/javascript" src="$CFG->wwwroot/lib/yui/element/element-beta-min.js"></script>
751<script type="text/javascript" src="$CFG->wwwroot/lib/yui/treeview/treeview-min.js"></script>
752<script type="text/javascript" src="$CFG->wwwroot/lib/yui/dragdrop/dragdrop-min.js"></script>
753<script type="text/javascript" src="$CFG->wwwroot/lib/yui/container/container-min.js"></script>
754<script type="text/javascript" src="$CFG->wwwroot/lib/yui/resize/resize-beta-min.js"></script>
755<script type="text/javascript" src="$CFG->wwwroot/lib/yui/layout/layout-beta-min.js"></script>
756<script type="text/javascript" src="$CFG->wwwroot/lib/yui/connection/connection-min.js"></script>
757<script type="text/javascript" src="$CFG->wwwroot/lib/yui/json/json-min.js"></script>
758<script type="text/javascript" src="$CFG->wwwroot/lib/yui/button/button-min.js"></script>
759<script type="text/javascript" src="$CFG->wwwroot/lib/yui/selector/selector-beta-min.js"></script>
760<script type="text/javascript">
de57d6f5 761//<![CDATA[
19f1d262 762var repository_client_$suffix = (function() {
763// private static field
764var dver = '1.0';
765// private static methods
766function alert_version(){
767 alert(dver);
768}
769function _client(){
770 // public varible
771 this.name = 'repository_client_$suffix';
772 // private varible
773 var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, layout = null, resize = null;
774 var IE_QUIRKS = (YAHOO.env.ua.ie && document.compatMode == "BackCompat");
775 var IE_SYNC = (YAHOO.env.ua.ie == 6 || (YAHOO.env.ua.ie == 7 && IE_QUIRKS));
776 var PANEL_BODY_PADDING = (10*2);
777 var btn_list = {label: '$strlistview', value: 'l', checked: true, onclick: {fn: _client.viewlist}};
778 var btn_thumb = {label: '$strthumbview', value: 't', onclick: {fn: _client.viewthumb}};
779 var repo_list = null;
780 var resize = null;
781 var panel = new YAHOO.widget.Panel('file-picker-$suffix', {
782 draggable: true,
783 close: true,
784 modal: true,
785 underlay: 'none',
786 width: '510px',
787 zindex: 666666,
788 xy: [50, Dom.getDocumentScrollTop()+20]
789 });
790 // construct code section
791 {
792 panel.setHeader('$strtitle');
793 panel.setBody('<div id="layout-$suffix"></div>');
794 panel.beforeRenderEvent.subscribe(function() {
795 Event.onAvailable('layout-$suffix', function() {
796 layout = new YAHOO.widget.Layout('layout-$suffix', {
797 height: 400, width: 490,
798 units: [
e6be3a69 799 {position: 'top', height: 32, resize: false,
19f1d262 800 body:'<div class="yui-buttongroup" id="repo-viewbar-$suffix"></div>', gutter: '2'},
e6be3a69 801 {position: 'left', width: 150, resize: true,
19f1d262 802 body:'<ul id="repo-list-$suffix"></ul>', gutter: '0 5 0 2', minWidth: 150, maxWidth: 300 },
e6be3a69 803 {position: 'center', body: '<div id="panel-$suffix"></div>',
19f1d262 804 scroll: true, gutter: '0 2 0 0' }
805 ]
c5704ec6 806 });
19f1d262 807 layout.render();
808 });
809 });
810 resize = new YAHOO.util.Resize('file-picker-$suffix', {
811 handles: ['br'],
812 autoRatio: true,
813 status: true,
814 minWidth: 380,
815 minHeight: 400
816 });
817 resize.on('resize', function(args) {
818 var panelHeight = args.height;
819 var headerHeight = this.header.offsetHeight; // Content + Padding + Border
820 var bodyHeight = (panelHeight - headerHeight);
821 var bodyContentHeight = (IE_QUIRKS) ? bodyHeight : bodyHeight - PANEL_BODY_PADDING;
822 Dom.setStyle(this.body, 'height', bodyContentHeight + 'px');
823 if (IE_SYNC) {
824 this.sizeUnderlay();
825 this.syncIframe();
c5704ec6 826 }
19f1d262 827 layout.set('height', bodyContentHeight);
828 layout.set('width', (args.width - PANEL_BODY_PADDING));
829 layout.resize();
830
831 }, panel, true);
832 _client.viewbar = new YAHOO.widget.ButtonGroup({
833 id: 'btngroup-$suffix',
834 name: 'buttons',
835 disabled: true,
836 container: 'repo-viewbar-$suffix'
837 });
838 }
839 // public method
840 this.show = function(){
841 panel.show();
842 }
843 this.hide = function(){
844 panel.hide();
845 }
846 this.create_picker = function(){
847 // display UI
848 panel.render();
849 _client.viewbar.addButtons([btn_list, btn_thumb]);
850 // init repository list
851 repo_list = new YAHOO.util.Element('repo-list-$suffix');
852 repo_list.on('contentReady', function(e){
853 for(var i=0; i<_client.repos.length; i++) {
854 var repo = _client.repos[i];
c145b657 855 var li = document.createElement('li');
19f1d262 856 li.id = 'repo-$suffix-'+repo.id;
857 var icon = document.createElement('img');
858 icon.src = repo.icon;
859 icon.width = '16';
860 icon.height = '16';
861 li.appendChild(icon);
862 var link = document.createElement('a');
863 link.href = '###';
864 link.id = 'repo-call-$suffix-'+repo.id;
865 link.innerHTML = ' '+repo.name;
866 link.className = 'repo-name';
867 link.onclick = function(){
868 var re = /repo-call-$suffix-(\d+)/i;
869 var id = this.id.match(re);
c0fa8cba 870 repository_client_$suffix.req(id[1], '', 0);
19f1d262 871 }
872 li.appendChild(link);
873 var opt = document.createElement('div');
874 opt.id = 'repo-opt-$suffix-'+repo.id;
875 li.appendChild(opt);
876 this.appendChild(li);
877 repo = null;
e1f29368 878 }
19f1d262 879 });
880 }
881}
882
883// public static varible
884_client.repos = [];
885_client.repositoryid = 0;
886// _client.ds save all data received from server side
e6be3a69 887_client.ds = null;
19f1d262 888_client.viewmode = 0;
889_client.viewbar =null;
890
891// public static mehtod
892_client.postdata = function(obj) {
893 var str = '';
894 for(k in obj) {
895 if(obj[k] instanceof Array) {
896 for(i in obj[k]) {
897 str += (encodeURIComponent(k) +'[]='+encodeURIComponent(obj[k][i]));
898 str += '&';
c5704ec6 899 }
19f1d262 900 } else {
901 str += encodeURIComponent(k) +'='+encodeURIComponent(obj[k]);
902 str += '&';
c5704ec6 903 }
19f1d262 904 }
905 return str;
906}
b82bcbcb 907_client.loading = function(type, name){
19f1d262 908 var panel = new YAHOO.util.Element('panel-$suffix');
909 panel.get('element').innerHTML = '';
910 var content = document.createElement('div');
b82bcbcb 911 content.style.textAlign='center';
912 var para = document.createElement('P');
913 var img = document.createElement('IMG');
914 if(type=='load'){
915 img.src = '$CFG->pixpath/i/loading.gif';
916 para.innerHTML = '$strloading';
917 }else{
918 img.src = '$CFG->pixpath/i/progressbar.gif';
919 para.innerHTML = '$strcopying '+name;
920 }
921 content.appendChild(para);
922 content.appendChild(img);
923 //content.innerHTML = '';
19f1d262 924 panel.get('element').appendChild(content);
925}
a67af354 926_client.rename = function(oldname, url, icon){
19f1d262 927 var panel = new YAHOO.util.Element('panel-$suffix');
336bb44b 928 var html = '<div id="rename-form">';
a67af354 929 html += '<p><img src="'+icon+'" /></p>';
336bb44b 930 html += '<p><label for="newname-$suffix">$strsaveas</label>';
931 html += '<input type="text" id="newname-$suffix" value="'+oldname+'" /></p>';
a67af354 932 /**
0eaa8c5c 933 html += '<p><label for="syncfile-$suffix">$strsync</label> ';
336bb44b 934 html += '<input type="checkbox" id="syncfile-$suffix" /></p>';
a67af354 935 */
336bb44b 936 html += '<p><input type="hidden" id="fileurl-$suffix" value="'+url+'" />';
19f1d262 937 html += '<a href="###" onclick="repository_client_$suffix.viewfiles()">$strback</a> ';
b748c971 938 html += '<input type="button" onclick="repository_client_$suffix.download()" value="$strdownbtn" />';
336bb44b 939 html += '<input type="button" onclick="repository_client_$suffix.hide()" value="Cancle" /></p>';
19f1d262 940 html += '</div>';
941 panel.get('element').innerHTML = html;
942}
943_client.print_login = function(){
944 var panel = new YAHOO.util.Element('panel-$suffix');
945 var data = _client.ds.login;
946 var str = '';
947 for(var k in data){
948 str += '<p>';
949 var lable_id = '';
950 var field_id = '';
951 var field_value = '';
952 if(data[k].id){
953 lable_id = ' for="'+data[k].id+'"';
954 field_id = ' id="'+data[k].id+'"';
c5704ec6 955 }
19f1d262 956 if (data[k].label) {
957 str += '<label'+lable_id+'>'+data[k].label+'</label>';
c5704ec6 958 }
19f1d262 959 if(data[k].value){
960 field_value = ' value="'+data[k].value+'"';
c5704ec6 961 }
19f1d262 962 str += '<input type="'+data[k].type+'"'+' name="'+data[k].name+'"'+field_id+field_value+' />';
963 str += '</p>';
964 }
965 str += '<p><input type="button" onclick="repository_client_$suffix.login()" value="$strsubmit" /></p>';
966 panel.get('element').innerHTML = str;
967}
c5704ec6 968
19f1d262 969_client.viewfiles = function(){
970 if(_client.viewmode) {
971 _client.viewthumb();
972 } else {
973 _client.viewlist();
974 }
975}
976_client.navbar = function(){
c0fa8cba 977 var panel = new YAHOO.util.Element('panel-$suffix');
978 panel.get('element').innerHTML = _client.uploadcontrol();
979 panel.get('element').innerHTML += _client.makepage();
980 _client.makepath();
19f1d262 981}
982// TODO
983// Improve CSS
0291df49 984_client.viewthumb = function(ds){
c0fa8cba 985 _client.viewmode = 1;
19f1d262 986 var panel = new YAHOO.util.Element('panel-$suffix');
987 _client.viewbar.check(1);
0291df49 988 var list = null;
989 var args = arguments.length;
990 if(args == 1){
991 list = ds;
992 } else {
993 // from button
994 list = _client.ds.list;
995 }
c0fa8cba 996 _client.navbar();
0291df49 997 var count = 0;
19f1d262 998 for(k in list){
999 var el = document.createElement('div');
1000 el.className='grid';
c145b657 1001 var frame = document.createElement('DIV');
1002 frame.style.textAlign='center';
19f1d262 1003 var img = document.createElement('img');
1004 img.src = list[k].thumbnail;
c0fa8cba 1005 var link = document.createElement('A');
1006 link.href='###';
1007 link.id = 'img-id-'+String(count);
1008 link.appendChild(img);
1009 frame.appendChild(link);
19f1d262 1010 var title = document.createElement('div');
336bb44b 1011 if(list[k].children){
1012 title.innerHTML = '<i><u>'+list[k].title+'</i></u>';
1013 } else {
8a1d4a46 1014 if(list[k].url)
1015 title.innerHTML = '<p><a target="_blank" href="'+list[k].url+'">$strpreview</a></p>';
1016 title.innerHTML += list[k].title;
336bb44b 1017 }
1018 title.className = 'label';
c145b657 1019 el.appendChild(frame);
19f1d262 1020 el.appendChild(title);
1021 panel.get('element').appendChild(el);
0291df49 1022 if(list[k].children){
c0fa8cba 1023 var el = new YAHOO.util.Element(link.id);
0291df49 1024 el.ds = list[k].children;
1025 el.on('click', function(){
c0fa8cba 1026 if(_client.ds.dynload){
0291df49 1027 // TODO: get file list dymanically
1028 }else{
0291df49 1029 _client.viewthumb(this.ds);
1030 }
1031 });
1032 } else {
c0fa8cba 1033 var el = new YAHOO.util.Element(link.id);
1034 el.title = list[k].title;
1035 el.value = list[k].source;
a67af354 1036 el.icon = list[k].thumbnail;
c0fa8cba 1037 el.on('click', function(){
a67af354 1038 repository_client_$suffix.rename(this.title, this.value, this.icon);
c0fa8cba 1039 });
0291df49 1040 }
1041 count++;
19f1d262 1042 }
19f1d262 1043}
1044_client.buildtree = function(node, level){
19a10884 1045 if(node.children){
1046 node.title = '<i><u>'+node.title+'</u></i>';
1047 }
e6be3a69 1048 var info = {label:node.title, title:"$strdate"+node.date+' '+'$strsize'+node.size};
1049 var tmpNode = new YAHOO.widget.TextNode(info, level, false);
19f1d262 1050 var tooltip = new YAHOO.widget.Tooltip(tmpNode.labelElId, {
1051 context:tmpNode.labelElId, text:info.title});
1052 tmpNode.filename = node.title;
1053 tmpNode.value = node.source;
a67af354 1054 tmpNode.icon = node.thumbnail;
19f1d262 1055 if(node.children){
1056 tmpNode.isLeaf = false;
19f1d262 1057 if (node.path) {
1058 tmpNode.path = node.path;
1059 } else {
1060 tmpNode.path = '';
d373f63f 1061 }
19f1d262 1062 for(var c in node.children){
1063 _client.buildtree(node.children[c], tmpNode);
c5704ec6 1064 }
19f1d262 1065 } else {
1066 tmpNode.isLeaf = true;
1067 tmpNode.onLabelClick = function() {
a67af354 1068 repository_client_$suffix.rename(this.filename, this.value, this.icon);
d373f63f 1069 }
19f1d262 1070 }
1071}
d373f63f 1072_client.dynload = function (node, fnLoadComplete){
1073 var callback = {
1074 success: function(o) {
1075 try {
1076 var json = YAHOO.lang.JSON.parse(o.responseText);
1077 } catch(e) {
a347291c 1078 alert('$strinvalidjson - '+o.responseText);
d373f63f 1079 }
1c7bf190 1080 for(k in json.list){
1081 _client.buildtree(json.list[k], node);
1082 }
d373f63f 1083 o.argument.fnLoadComplete();
1084 },
1085 failure:function(oResponse){
a347291c 1086 alert('$strerror');
d373f63f 1087 oResponse.argument.fnLoadComplete();
1088 },
1089 argument:{"node":node, "fnLoadComplete": fnLoadComplete},
1090 timeout:600
1091 }
0eaa8c5c 1092 var params = [];
1093 params['p']=node.path;
1094 params['env']=_client.env;
1095 params['sesskey']='$sesskey';
1096 params['ctx_id']=$context->id;
1097 params['repo_id']=_client.repositoryid;
1098 var trans = YAHOO.util.Connect.asyncRequest('POST',
1099 '$CFG->wwwroot/repository/ws.php?action=list', callback, _client.postdata(params));
d373f63f 1100}
19f1d262 1101_client.viewlist = function(){
c0fa8cba 1102 _client.viewmode = 0;
19f1d262 1103 var panel = new YAHOO.util.Element('panel-$suffix');
1104 _client.viewbar.check(0);
1105 list = _client.ds.list;
c0fa8cba 1106 _client.navbar();
1107 panel.get('element').innerHTML += '<div id="treediv"></div>';
19f1d262 1108 var tree = new YAHOO.widget.TreeView('treediv');
1109 if(_client.ds.dynload) {
1110 tree.setDynamicLoad(_client.dynload, 1);
1111 } else {
1112 }
1113 for(k in list){
1114 _client.buildtree(list[k], tree.getRoot());
1115 }
1116 tree.draw();
19f1d262 1117}
1118_client.upload = function(){
1119 var u = _client.ds.upload;
19f1d262 1120 var aform = document.getElementById(u.id);
1121 var parent = document.getElementById(u.id+'_div');
9ccfe7aa 1122 var d = document.getElementById(_client.ds.upload.id+'-file');
1123 if(d.value!='' && d.value!=null){
1124 var container = document.createElement('DIV');
1125 container.id = u.id+'_loading';
1126 container.style.textAlign='center';
1127 var img = document.createElement('IMG');
1128 img.src = '$CFG->pixpath/i/progressbar.gif';
1129 var para = document.createElement('p');
1130 para.innerHTML = '$struploading';
1131 container.appendChild(para);
1132 container.appendChild(img);
1133 parent.appendChild(container);
1134 YAHOO.util.Connect.setForm(aform, true, true);
1135 var trans = YAHOO.util.Connect.asyncRequest('POST',
1136 '$CFG->wwwroot/repository/ws.php?action=upload&sesskey=$sesskey&ctx_id=$context->id&repo_id='
1137 +_client.repositoryid,
1138 _client.upload_cb);
1139 }else{
1140 alert('$strfilenotnull');
1141 }
19f1d262 1142}
1143_client.upload_cb = {
1144 upload: function(o){
5a3b9db9 1145 try {
1146 var ret = YAHOO.lang.JSON.parse(o.responseText);
1147 } catch(e) {
1148 alert('$strinvalidjson - '+o.responseText);
1149 }
1150 if(ret && ret.e){
1151 var panel = new YAHOO.util.Element('panel-$suffix');
1152 panel.get('element').innerHTML = ret.e;
1153 return;
1154 }
1155 if(ret){
1156 alert('$strsaved');
1157 repository_client_$suffix.end(ret);
1158 }else{
1159 alert('$strinvalidjson');
1160 }
19f1d262 1161 }
1162}
1163_client.uploadcontrol = function() {
1164 var str = '';
1165 if(_client.ds.upload){
1166 str += '<div id="'+_client.ds.upload.id+'_div">';
1167 str += '<form id="'+_client.ds.upload.id+'" onsubmit="return false">';
5a3b9db9 1168 str += '<label for="'+_client.ds.upload.id+'-file">'+_client.ds.upload.label+'</label>';
1169 str += '<input type="file" id="'+_client.ds.upload.id+'-file" name="repo_upload_file" />';
19f1d262 1170 str += '<p class="upload"><a href="###" onclick="return repository_client_$suffix.upload();">$strupload</a></p>';
1171 str += '</form>';
1172 str += '</div>';
19f1d262 1173 }
1174 return str;
1175}
1176_client.makepage = function(){
1177 var str = '';
1178 if(_client.ds.pages){
1179 str += '<div id="paging-$suffix">';
1180 for(var i = 1; i <= _client.ds.pages; i++) {
1181 str += '<a onclick="repository_client_$suffix.req('+_client.repositoryid+', '+i+', 0)" href="###">';
1182 str += String(i);
1183 str += '</a> ';
d373f63f 1184 }
19f1d262 1185 str += '</div>';
1186 }
1187 return str;
1188}
27051e43 1189_client.makepath = function(){
c0fa8cba 1190 if(_client.viewmode == 0) {
1191 return;
1192 }
1193 var panel = new YAHOO.util.Element('panel-$suffix');
27051e43 1194 var p = _client.ds.path;
1195 if(p && p.length!=0){
c0fa8cba 1196 var oDiv = document.createElement('DIV');
1197 oDiv.id = "path-$suffix";
1198 panel.get('element').appendChild(oDiv);
27051e43 1199 for(var i = 0; i < _client.ds.path.length; i++) {
31640be2 1200 var link = document.createElement('A');
1201 link.href = "###";
1202 link.innerHTML = _client.ds.path[i].name;
1203 link.id = 'path-'+i+'-el';
1204 var sep = document.createElement('SPAN');
1205 sep.innerHTML = '/';
1206 oDiv.appendChild(link);
1207 oDiv.appendChild(sep);
1208 var el = new YAHOO.util.Element(link.id);
1209 el.id = _client.repositoryid;
1210 el.path = _client.ds.path[i].path;
1211 el.on('click', function(){
1212 repository_client_$suffix.req(this.id, this.path, 0);
1213 });
27051e43 1214 }
27051e43 1215 }
27051e43 1216}
19f1d262 1217// send download request
1218_client.download = function(){
1219 var title = document.getElementById('newname-$suffix').value;
1220 var file = document.getElementById('fileurl-$suffix').value;
b82bcbcb 1221 _client.loading('download', title);
0eaa8c5c 1222 var params = [];
1223 params['env']=_client.env;
1224 params['file']=file;
1225 params['title']=title;
1226 params['sesskey']='$sesskey';
1227 params['ctx_id']=$context->id;
1228 params['repo_id']=_client.repositoryid;
e6be3a69 1229 var trans = YAHOO.util.Connect.asyncRequest('POST',
0eaa8c5c 1230 '$CFG->wwwroot/repository/ws.php?action=download', _client.dlfile, _client.postdata(params));
19f1d262 1231}
1232// send login request
1233_client.login = function(){
0eaa8c5c 1234 var params = [];
19f1d262 1235 var data = _client.ds.login;
1236 for (var k in data) {
1237 var el = document.getElementsByName(data[k].name)[0];
1238 params[data[k].name] = '';
1239 if(el.type == 'checkbox') {
1240 params[data[k].name] = el.checked;
1241 } else {
1242 params[data[k].name] = el.value;
d373f63f 1243 }
19f1d262 1244 }
1245 params['env'] = _client.env;
1246 params['ctx_id'] = $context->id;
0eaa8c5c 1247 params['sesskey']= '$sesskey';
b82bcbcb 1248 _client.loading('load');
e6be3a69 1249 var trans = YAHOO.util.Connect.asyncRequest('POST',
0eaa8c5c 1250 '$CFG->wwwroot/repository/ws.php?action=sign', _client.callback, _client.postdata(params));
19f1d262 1251}
1252_client.end = function(str){
c0fa8cba 1253 if(_client.env=='form'){
1254 _client.target.value = str['id'];
1255 }else{
1256 _client.target.value = str['url'];
1257 }
1258 _client.formcallback(str['file']);
19f1d262 1259 _client.instance.hide();
1260 _client.viewfiles();
1261}
122defc5 1262_client.hide = function(){
1263 _client.instance.hide();
1264 _client.viewfiles();
1265}
19f1d262 1266_client.callback = {
1267 success: function(o) {
1268 var panel = new YAHOO.util.Element('panel-$suffix');
1269 try {
1270 var ret = YAHOO.lang.JSON.parse(o.responseText);
1271 } catch(e) {
1272 alert('$strinvalidjson - '+o.responseText);
1273 };
c145b657 1274 if(ret && ret.e){
19f1d262 1275 panel.get('element').innerHTML = ret.e;
1276 return;
d373f63f 1277 }
19f1d262 1278 _client.ds = ret;
1279 var oDiv = document.getElementById('repo-opt-$suffix-'
1280 +_client.repositoryid);
1281 oDiv.innerHTML = '';
1282 var search = null;
1283 var logout = null;
1284 var mgr = null;
122defc5 1285 if(_client.ds && _client.ds.login){
19f1d262 1286 _client.print_login();
1287 } else if(_client.ds.list) {
1288 if(_client.viewmode) {
1289 _client.viewthumb();
1290 } else {
1291 _client.viewlist();
c5704ec6 1292 }
19f1d262 1293 search = document.createElement('a');
1294 search.href = '###';
1295 search.innerHTML = '$strsearch ';
1296 search.id = 'repo-search-$suffix-'+_client.repositoryid;
1297 search.onclick = function() {
1298 var re = /repo-search-$suffix-(\d+)/i;
1299 var id = this.id.match(re);
1300 repository_client_$suffix.search(id[1]);
c5704ec6 1301 }
19f1d262 1302 logout = document.createElement('a');
1303 logout.href = '###';
1304 logout.innerHTML = '$strlogout';
1305 logout.id = 'repo-logout-$suffix-'+_client.repositoryid;
1306 logout.onclick = function() {
1307 var re = /repo-logout-$suffix-(\d+)/i;
1308 var id = this.id.match(re);
1309 var oDiv = document.getElementById('repo-opt-$suffix-'+id[1]);
f692fb10 1310 oDiv.innerHTML = '';
b748c971 1311 _client.ds = null;
19f1d262 1312 repository_client_$suffix.req(id[1], 1, 1);
c5704ec6 1313 }
19f1d262 1314 if(_client.ds.manage){
1315 mgr = document.createElement('A');
1316 mgr.innerHTML = '$strmgr ';
1317 mgr.href = _client.ds.manage;
1318 mgr.id = 'repo-mgr-$suffix-'+_client.repositoryid;
1319 mgr.target = "_blank";
1320 }
d31af46a 1321 if(_client.ds.nosearch != true){
1322 oDiv.appendChild(search);
1323 }
19f1d262 1324 if(mgr != null) {
1325 oDiv.appendChild(mgr);
1326 }
1327 if(_client.ds.nologin != true){
1328 oDiv.appendChild(logout);
c5704ec6 1329 }
1330 }
19f1d262 1331 }
1332}
1333_client.dlfile = {
1334 success: function(o) {
1335 var panel = new YAHOO.util.Element('panel-$suffix');
1336 try {
1337 var ret = YAHOO.lang.JSON.parse(o.responseText);
1338 } catch(e) {
1339 alert('$strinvalidjson - '+o.responseText);
c5704ec6 1340 }
c145b657 1341 if(ret && ret.e){
19f1d262 1342 panel.get('element').innerHTML = ret.e;
1343 return;
1344 }
3023078f 1345 if(ret){
1346 repository_client_$suffix.end(ret);
1347 }else{
1348 alert('$strinvalidjson');
1349 }
19f1d262 1350 }
1351}
1352// request file list or login
1353_client.req = function(id, path, reset) {
1354 _client.viewbar.set('disabled', false);
b82bcbcb 1355 _client.loading('load');
19f1d262 1356 _client.repositoryid = id;
b748c971 1357 if (reset == 1) {
1358 action = 'logout';
1359 } else {
1360 action = 'list';
1361 }
0eaa8c5c 1362 var params = [];
1363 params['p'] = path;
1364 params['reset']=reset;
1365 params['env']=_client.env;
1366 params['action']=action;
1367 params['sesskey']='$sesskey';
1368 params['ctx_id']=$context->id;
1369 params['repo_id']=id;
1370 var trans = YAHOO.util.Connect.asyncRequest('POST', '$CFG->wwwroot/repository/ws.php?action='+action, _client.callback, _client.postdata(params));
19f1d262 1371}
1372_client.search = function(id){
1373 var data = window.prompt("$strsearching");
1374 if(data == '') {
1375 alert('$strnoenter');
1376 return;
1377 }
1378 _client.viewbar.set('disabled', false);
b82bcbcb 1379 _client.loading('load');
0eaa8c5c 1380 var params = [];
1381 params['s']=data;
1382 params['env']=_client.env;
1383 params['sesskey']='$sesskey';
1384 params['ctx_id']=$context->id;
1385 params['repo_id']=id;
1386 var trans = YAHOO.util.Connect.asyncRequest('POST', '$CFG->wwwroot/repository/ws.php?action=search', _client.callback, _client.postdata(params));
19f1d262 1387}
1388
1389return _client;
1390})();
c5704ec6 1391EOD;
1392
e6be3a69 1393 $repos = repository_get_instances($context);
c5704ec6 1394 foreach($repos as $repo) {
4b844d63 1395 $js .= "\r\n";
4a65c39a 1396 $js .= 'repository_client_'.$suffix.'.repos.push('.json_encode($repo->ajax_info()).');'."\n";
c5704ec6 1397 }
4b844d63 1398 $js .= "\r\n";
c5704ec6 1399
1400 $js .= <<<EOD
b748c971 1401function openpicker_$suffix(params) {
1402 if(!repository_client_$suffix.instance) {
1403 repository_client_$suffix.env = params.env;
1404 repository_client_$suffix.target = params.target;
c0fa8cba 1405 if(params.type){
1406 repository_client_$suffix.filetype = params.filetype;
1407 } else {
1408 repository_client_$suffix.filetype = 'all';
1409 }
b748c971 1410 repository_client_$suffix.instance = new repository_client_$suffix();
1411 repository_client_$suffix.instance.create_picker();
1412 if(params.callback){
1413 repository_client_$suffix.formcallback = params.callback;
c5704ec6 1414 } else {
b748c971 1415 repository_client_$suffix.formcallback = function(){};
c5704ec6 1416 }
b748c971 1417 } else {
1418 repository_client_$suffix.instance.show();
c5704ec6 1419 }
b748c971 1420}
de57d6f5 1421//]]>
1422</script>
c5704ec6 1423EOD;
d373f63f 1424 return array('css'=>$css, 'js'=>$js, 'suffix'=>$suffix);
c5704ec6 1425}
4a65c39a 1426
8dcd5deb 1427/**
1428 * TODO: write comment
1429 */
4a65c39a 1430final class repository_admin_form extends moodleform {
1431 protected $instance;
1432 protected $plugin;
1433
8dcd5deb 1434 /**
1435 * TODO: write comment
1436 * @global <type> $CFG
1437 */
4a65c39a 1438 public function definition() {
1439 global $CFG;
1440 // type of plugin, string
1441 $this->plugin = $this->_customdata['plugin'];
27051e43 1442 $this->typeid = $this->_customdata['typeid'];
4a65c39a 1443 $this->instance = (isset($this->_customdata['instance'])
1444 && is_subclass_of($this->_customdata['instance'], 'repository'))
1445 ? $this->_customdata['instance'] : null;
1446
1447 $mform =& $this->_form;
1448 $strrequired = get_string('required');
1449
1450 $mform->addElement('hidden', 'edit', ($this->instance) ? $this->instance->id : 0);
1451 $mform->addElement('hidden', 'new', $this->plugin);
1452 $mform->addElement('hidden', 'plugin', $this->plugin);
27051e43 1453 $mform->addElement('hidden', 'typeid', $this->typeid);
4a65c39a 1454
1455 $mform->addElement('text', 'name', get_string('name'), 'maxlength="100" size="30"');
1456 $mform->addRule('name', $strrequired, 'required', null, 'client');
1457
1458 // let the plugin add the fields they want (either statically or not)
1459 if (repository_static_function($this->plugin, 'has_admin_config')) {
1460 if (!$this->instance) {
1461 $result = repository_static_function($this->plugin, 'admin_config_form', $mform);
1462 } else {
1463 $result = $this->instance->admin_config_form($mform);
1464 }
1465 }
1466
1467 // and set the data if we have some.
1468 if ($this->instance) {
1469 $data = array();
1470 $data['name'] = $this->instance->name;
1471 foreach ($this->instance->get_option_names() as $config) {
27051e43 1472 if (!empty($this->instance->$config)) {
1473 $data[$config] = $this->instance->$config;
1474 } else {
1475 $data[$config] = '';
1476 }
4a65c39a 1477 }
1478 $this->set_data($data);
1479 }
1480 $this->add_action_buttons(true, get_string('submit'));
1481 }
1482
8dcd5deb 1483 /**
1484 * TODO: write comment
1485 * @global <type> $DB
1486 * @param <type> $data
1487 * @return <type>
1488 */
4a65c39a 1489 public function validation($data) {
1490 global $DB;
1491
1492 $errors = array();
27051e43 1493 if ($DB->count_records('repository_instances', array('name' => $data['name'], 'typeid' => $data['typeid'])) > 1) {
4a65c39a 1494 $errors = array('name' => get_string('err_uniquename', 'repository'));
1495 }
1496
1497 $pluginerrors = array();
1498 if ($this->instance) {
1499 //$pluginerrors = $this->instance->admin_config_validation($data);
1500 } else {
1501 //$pluginerrors = repository_static_function($this->plugin, 'admin_config_validation', $data);
1502 }
1503 if (is_array($pluginerrors)) {
1504 $errors = array_merge($errors, $pluginerrors);
1505 }
1506 return $errors;
1507 }
1508}