Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * This plugin is used to access flickr pictures 19 * 20 * @since Moodle 2.0 21 * @package repository_flickr_public 22 * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 require_once($CFG->dirroot . '/repository/lib.php'); 26 require_once($CFG->libdir.'/flickrlib.php'); 27 require_once (__DIR__ . '/image.php'); 28 29 /** 30 * repository_flickr_public class 31 * This one is used to create public repository 32 * You can set up a public account in admin page, so everyone can access 33 * flickr photos from this plugin 34 * 35 * @since Moodle 2.0 36 * @package repository_flickr_public 37 * @copyright 2009 Dongsheng Cai {@link http://dongsheng.org} 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class repository_flickr_public extends repository { 41 42 /** @var phpFlickr Flickr class. */ 43 private $flickr; 44 45 /** @var string Flick photos. */ 46 public $photos; 47 48 /** @var string API key. */ 49 protected $api_key; 50 51 /** @var string email address account. */ 52 protected $flickr_account; 53 54 /** @var string watermarks usage status. */ 55 protected $usewatermarks; 56 57 /** @var string session account. */ 58 protected $sess_account; 59 60 /** @var string session tag. */ 61 protected $sess_tag; 62 63 /** @var string session text. */ 64 protected $sess_text; 65 66 /** @var string Flickr user identifier. */ 67 protected $nsid; 68 69 /** 70 * Stores sizes of images to prevent multiple API call 71 */ 72 static private $sizes = array(); 73 74 /** 75 * constructor method 76 * 77 * @global object $CFG 78 * @global object $SESSION 79 * @param int $repositoryid 80 * @param int $context 81 * @param array $options 82 * @param boolean $readonly 83 */ 84 public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array(), $readonly=0) { 85 global $CFG, $SESSION; 86 parent::__construct($repositoryid, $context, $options,$readonly); 87 $this->api_key = $this->get_option('api_key'); 88 $this->flickr = new phpFlickr($this->api_key); 89 $this->flickr_account = $this->get_option('email_address'); 90 $this->usewatermarks = $this->get_option('usewatermarks'); 91 92 $account = optional_param('flickr_account', '', PARAM_RAW); 93 $fulltext = optional_param('flickr_fulltext', '', PARAM_RAW); 94 if (empty($fulltext)) { 95 $fulltext = optional_param('s', '', PARAM_RAW); 96 } 97 $tag = optional_param('flickr_tag', '', PARAM_RAW); 98 $license = optional_param('flickr_license', '', PARAM_RAW); 99 100 $this->sess_account = 'flickr_public_'.$this->id.'_account'; 101 $this->sess_tag = 'flickr_public_'.$this->id.'_tag'; 102 $this->sess_text = 'flickr_public_'.$this->id.'_text'; 103 104 if (!empty($account) or !empty($fulltext) or !empty($tag) or !empty($license)) { 105 $SESSION->{$this->sess_tag} = $tag; 106 $SESSION->{$this->sess_text} = $fulltext; 107 $SESSION->{$this->sess_account} = $account; 108 } 109 } 110 111 /** 112 * save api_key in config table 113 * @param array $options 114 * @return boolean 115 */ 116 public function set_option($options = array()) { 117 if (!empty($options['api_key'])) { 118 set_config('api_key', trim($options['api_key']), 'flickr_public'); 119 } 120 unset($options['api_key']); 121 return parent::set_option($options); 122 } 123 124 /** 125 * get api_key from config table 126 * 127 * @param string $config 128 * @return mixed 129 */ 130 public function get_option($config = '') { 131 if ($config==='api_key') { 132 return trim(get_config('flickr_public', 'api_key')); 133 } else { 134 $options['api_key'] = trim(get_config('flickr_public', 'api_key')); 135 } 136 return parent::get_option($config); 137 } 138 139 /** 140 * is global_search available? 141 * 142 * @return boolean 143 */ 144 public function global_search() { 145 if (empty($this->flickr_account)) { 146 return false; 147 } else { 148 return true; 149 } 150 } 151 152 /** 153 * check if flickr account 154 * @return boolean 155 */ 156 public function check_login() { 157 return !empty($this->flickr_account); 158 } 159 160 /** 161 * construct login form 162 * 163 * @param boolean $ajax 164 * @return array 165 */ 166 public function print_login() { 167 if ($this->options['ajax']) { 168 $ret = array(); 169 $fulltext = new stdClass(); 170 $fulltext->label = get_string('fulltext', 'repository_flickr_public').': '; 171 $fulltext->id = 'el_fulltext'; 172 $fulltext->type = 'text'; 173 $fulltext->name = 'flickr_fulltext'; 174 175 $tag = new stdClass(); 176 $tag->label = get_string('tag', 'repository_flickr_public').': '; 177 $tag->id = 'el_tag'; 178 $tag->type = 'text'; 179 $tag->name = 'flickr_tag'; 180 181 $email_field = new stdClass(); 182 $email_field->label = get_string('username', 'repository_flickr_public').': '; 183 $email_field->id = 'account'; 184 $email_field->type = 'text'; 185 $email_field->name = 'flickr_account'; 186 187 $commercial = new stdClass(); 188 $commercial->label = get_string('commercialuse', 'repository_flickr_public').': '; 189 $commercial->id = 'flickr_commercial_id'; 190 $commercial->type = 'checkbox'; 191 $commercial->name = 'flickr_commercial'; 192 $commercial->value = 'yes'; 193 194 $modification = new stdClass(); 195 $modification->label = get_string('modification', 'repository_flickr_public').': '; 196 $modification->id = 'flickr_modification_id'; 197 $modification->type = 'checkbox'; 198 $modification->name = 'flickr_modification'; 199 $modification->value = 'yes'; 200 201 $ret['login'] = array($fulltext, $tag, $email_field, $commercial, $modification); 202 $ret['login_btn_label'] = get_string('search'); 203 $ret['login_btn_action'] = 'search'; 204 return $ret; 205 } else { 206 echo '<table>'; 207 echo '<tr><td><label>'.get_string('fulltext', 'repository_flickr_public').'</label></td>'; 208 echo '<td><input type="text" name="flickr_fulltext" /></td></tr>'; 209 echo '<tr><td><label>'.get_string('tag', 'repository_flickr_public').'</label></td>'; 210 echo '<td><input type="text" name="flickr_tag" /></td></tr>'; 211 echo '<tr><td><label>'.get_string('username', 'repository_flickr_public').'</label></td>'; 212 echo '<td><input type="text" name="flickr_account" /></td></tr>'; 213 214 echo '<tr><td><label>'.get_string('commercialuse', 'repository_flickr_public').'</label></td>'; 215 echo '<td>'; 216 echo '<input type="checkbox" name="flickr_commercial" value="yes" />'; 217 echo '</td></tr>'; 218 219 echo '<tr><td><label>'.get_string('modification', 'repository_flickr_public').'</label></td>'; 220 echo '<td>'; 221 echo '<input type="checkbox" name="flickr_modification" value="yes" />'; 222 echo '</td></tr>'; 223 224 echo '</table>'; 225 226 echo '<input type="hidden" name="action" value="search" />'; 227 echo '<input type="submit" value="'.get_string('search', 'repository').'" />'; 228 } 229 } 230 231 /** 232 * destroy session 233 * 234 * @return object 235 */ 236 public function logout() { 237 global $SESSION; 238 unset($SESSION->{$this->sess_tag}); 239 unset($SESSION->{$this->sess_text}); 240 unset($SESSION->{$this->sess_account}); 241 return $this->print_login(); 242 } 243 244 public function license4moodle ($license_id) { 245 $license = array( 246 '0' => 'allrightsreserved', 247 '1' => 'cc-nc-sa', 248 '2' => 'cc-nc', 249 '3' => 'cc-nc-nd', 250 '4' => 'cc', 251 '5' => 'cc-sa', 252 '6' => 'cc-nd', 253 '7' => 'other' 254 ); 255 return $license[$license_id]; 256 } 257 258 /** 259 * search images on flickr 260 * 261 * @param string $search_text 262 * @return array 263 */ 264 public function search($search_text, $page = 0) { 265 global $SESSION; 266 $ret = array(); 267 if (empty($page)) { 268 $page = 1; 269 } 270 271 if (!empty($this->flickr_account)) { 272 $people = $this->flickr->people_findByEmail($this->flickr_account); 273 $this->nsid = $people['nsid']; 274 } 275 if (!empty($SESSION->{$this->sess_account})) { 276 $people = $this->flickr->people_findByEmail($SESSION->{$this->sess_account}); 277 $this->nsid = $people['nsid']; 278 } 279 if (empty($this->nsid)) { 280 $this->nsid = null; 281 // user specify a flickr account, but it is not valid 282 if (!empty($this->flickr_account) or !empty($SESSION->{$this->sess_account})) { 283 $ret['e'] = get_string('invalidemail', 'repository_flickr_public'); 284 return $ret; 285 } 286 } 287 288 // including all licenses by default 289 $licenses = array(1=>1, 2, 3, 4, 5, 6, 7); 290 291 $commercial = optional_param('flickr_commercial', '', PARAM_RAW); 292 $modification = optional_param('flickr_modification', '', PARAM_RAW); 293 294 if ($commercial == 'yes') { 295 // including 296 // 4: Attribution License 297 // 5: Attribution ShareAlike 298 // 6: Attribution NoDerives 299 // 7: unknown license 300 unset($licenses[1], $licenses[2], $licenses[3]); 301 } 302 if ($modification == 'yes') { 303 // including 304 // 1: Attribution NonCommercial ShareAlike 305 // 2: Attribution NonCommercial 306 // 4: Attribution License 307 // 5: Attribution ShareAlike 308 // 7: unknown license 309 unset($licenses[3], $licenses[6]); 310 } 311 //if ($modification == 'sharealike') { 312 // including 313 // 1: Attribution NonCommercial ShareAlike 314 // 5: Attribution ShareAlike 315 //unset($licenses[2], $licenses[3], $licenses[4], $licenses[6], $licenses[7]); 316 //} 317 318 $licenses = implode(',', $licenses); 319 320 $tag = !empty($SESSION->{$this->sess_tag}) ? $SESSION->{$this->sess_tag} : null; 321 $text = !empty($SESSION->{$this->sess_text}) ? $SESSION->{$this->sess_text} : null; 322 $nsid = !empty($this->nsid) ? $this->nsid : null; 323 324 $photos = $this->flickr->photos_search( 325 array( 326 'tags' => $tag, 327 'page' => $page, 328 'per_page' => 24, 329 'user_id' => $nsid, 330 'license' => $licenses, 331 'text' => $text, 332 'extras' => 'original_format,license,date_upload,last_update', 333 'media' => 'photos' 334 ) 335 ); 336 $ret['total'] = $photos['total']; 337 $ret['perpage'] = $photos['perpage']; 338 if (empty($photos)) { 339 $ret['list'] = array(); 340 return $ret; 341 } 342 $ret = $this->build_list($photos, $page, $ret); 343 $ret['list'] = array_filter($ret['list'], array($this, 'filter')); 344 return $ret; 345 } 346 347 /** 348 * return an image list 349 * 350 * @param string $path 351 * @param int $page 352 * @return array 353 */ 354 public function get_listing($path = '', $page = 1) { 355 $people = $this->flickr->people_findByEmail($this->flickr_account); 356 $this->nsid = $people['nsid']; 357 $photos = $this->flickr->people_getPublicPhotos($people['nsid'], 'original_format,license,date_upload,last_update', 358 24, $page); 359 $ret = array(); 360 361 return $this->build_list($photos, $page, $ret); 362 } 363 364 /** 365 * build an image list 366 * 367 * @param array $photos 368 * @param int $page 369 * @return array 370 */ 371 private function build_list($photos, $page, &$ret) { 372 global $OUTPUT; 373 374 if (!empty($this->nsid)) { 375 $photos_url = $this->flickr->urls_getUserPhotos($this->nsid); 376 $ret['manage'] = $photos_url; 377 } 378 $ret['list'] = array(); 379 $ret['nosearch'] = true; 380 $ret['norefresh'] = true; 381 $ret['logouttext'] = get_string('backtosearch', 'repository_flickr_public'); 382 $ret['pages'] = $photos['pages']; 383 if (is_int($page) && $page <= $ret['pages']) { 384 $ret['page'] = $page; 385 } else { 386 $ret['page'] = 1; 387 } 388 if (!empty($photos['photo'])) { 389 foreach ($photos['photo'] as $p) { 390 if(empty($p['title'])) { 391 $p['title'] = get_string('notitle', 'repository_flickr'); 392 } 393 if (isset($p['originalformat'])) { 394 $format = $p['originalformat']; 395 } else { 396 $format = 'jpg'; 397 } 398 $format = '.'.$format; 399 if (substr($p['title'], strlen($p['title'])-strlen($format)) != $format) { 400 // append author id 401 // $p['title'] .= '-'.$p['owner']; 402 // append file extension 403 $p['title'] .= $format; 404 } 405 // Get the thumbnail source URL. 406 $thumbnailsource = $this->flickr->buildPhotoURL($p, 'Square'); 407 if (!@getimagesize($thumbnailsource)) { 408 // Use the file extension icon as a thumbnail if the original thumbnail does not exist to avoid 409 // displaying broken thumbnails in the repository. 410 $thumbnailsource = $OUTPUT->image_url(file_extension_icon($p['title']))->out(false); 411 } 412 413 // Perform a HEAD request to the image to obtain it's Content-Length. 414 $curl = new curl(); 415 $curl->head($this->get_link($p['id'])); 416 417 // The photo sizes are statically cached, so we can retrieve image dimensions without another API call. 418 $bestsize = $this->get_best_size($p['id']); 419 420 $ret['list'][] = array( 421 'title' => $p['title'], 422 'source' => $p['id'], 423 'id' => $p['id'], 424 'thumbnail' => $thumbnailsource, 425 'datecreated' => $p['dateupload'], 426 'datemodified' => $p['lastupdate'], 427 'size' => (int)($curl->get_info()['download_content_length']), 428 'image_width' => $bestsize['width'], 429 'image_height' => $bestsize['height'], 430 'url' => 'http://www.flickr.com/photos/' . $p['owner'] . '/' . $p['id'], 431 'license' => $this->license4moodle($p['license']), 432 'author' => $p['owner'], 433 ); 434 } 435 } 436 return $ret; 437 } 438 439 /** 440 * Print a search form 441 * 442 * @return string 443 */ 444 public function print_search() { 445 $str = ''; 446 $str .= '<input type="hidden" name="repo_id" value="'.$this->id.'" />'; 447 $str .= '<input type="hidden" name="ctx_id" value="'.$this->context->id.'" />'; 448 $str .= '<input type="hidden" name="seekey" value="'.sesskey().'" />'; 449 $str .= '<label>'.get_string('fulltext', 'repository_flickr_public').'</label><br/><input name="s" value="" /><br/>'; 450 $str .= '<label>'.get_string('tag', 'repository_flickr_public').'</label><br /><input type="text" name="flickr_tag" /><br />'; 451 return $str; 452 } 453 454 /** 455 * Return photo url by given photo id 456 * @param string $photoid 457 * @return string 458 */ 459 private function build_photo_url($photoid) { 460 $bestsize = $this->get_best_size($photoid); 461 if (!isset($bestsize['source'])) { 462 throw new repository_exception('cannotdownload', 'repository'); 463 } 464 return $bestsize['source']; 465 } 466 467 /** 468 * Returns the best size for a photo 469 * 470 * @param string $photoid the photo identifier 471 * @return array of information provided by the API 472 */ 473 protected function get_best_size($photoid) { 474 if (!isset(self::$sizes[$photoid])) { 475 // Sizes are returned from smallest to greatest. 476 self::$sizes[$photoid] = $this->flickr->photos_getSizes($photoid); 477 } 478 $sizes = self::$sizes[$photoid]; 479 $bestsize = array(); 480 if (is_array($sizes)) { 481 while ($bestsize = array_pop($sizes)) { 482 // Make sure the source is set. Exit the loop if found. 483 if (isset($bestsize['source'])) { 484 break; 485 } 486 } 487 } 488 return $bestsize; 489 } 490 491 public function get_link($photoid) { 492 return $this->build_photo_url($photoid); 493 } 494 495 /** 496 * 497 * @global object $CFG 498 * @param string $photoid 499 * @param string $file 500 * @return string 501 */ 502 public function get_file($photoid, $file = '') { 503 global $CFG; 504 505 $info = $this->flickr->photos_getInfo($photoid); 506 507 // If we can read the original secret, it means that we have access to the original picture. 508 if (isset($info['originalsecret'])) { 509 $source = $this->flickr->buildPhotoURL($info, 'original'); 510 } else { 511 $source = $this->build_photo_url($photoid); 512 } 513 // Make sure the source image exists. 514 if (!@getimagesize($source)) { 515 throw new moodle_exception('cannotdownload', 'repository'); 516 } 517 518 if ($info['owner']['realname']) { 519 $author = $info['owner']['realname']; 520 } else { 521 $author = $info['owner']['username']; 522 } 523 $copyright = get_string('author', 'repository') . ': ' . $author; 524 525 $result = parent::get_file($source, $file); 526 $path = $result['path']; 527 528 if (!empty($this->usewatermarks)) { 529 $img = new moodle_image($path); 530 $img->watermark($copyright, array(10,10), array('ttf'=>true, 'fontsize'=>12))->saveas($path); 531 } 532 533 return array('path'=>$path, 'author'=>$info['owner']['realname'], 'license'=>$this->license4moodle($info['license'])); 534 } 535 536 /** 537 * Add Instance settings input to Moodle form 538 * @param object $mform 539 */ 540 public static function instance_config_form($mform) { 541 $mform->addElement('text', 'email_address', get_string('emailaddress', 'repository_flickr_public')); 542 $mform->setType('email_address', PARAM_RAW_TRIMMED); // This is for sending to flickr. Not our job to validate it. 543 $mform->addElement('checkbox', 'usewatermarks', get_string('watermark', 'repository_flickr_public')); 544 $mform->setDefault('usewatermarks', 0); 545 } 546 547 /** 548 * Names of the instance settings 549 * @return array 550 */ 551 public static function get_instance_option_names() { 552 return array('email_address', 'usewatermarks'); 553 } 554 555 /** 556 * Add Plugin settings input to Moodle form 557 * @param object $mform 558 */ 559 public static function type_config_form($mform, $classname = 'repository') { 560 $api_key = get_config('flickr_public', 'api_key'); 561 if (empty($api_key)) { 562 $api_key = ''; 563 } 564 $strrequired = get_string('required'); 565 566 $mform->addElement('text', 'api_key', get_string('apikey', 'repository_flickr_public'), array('value'=>$api_key,'size' => '40')); 567 $mform->setType('api_key', PARAM_RAW_TRIMMED); 568 $mform->addRule('api_key', $strrequired, 'required', null, 'client'); 569 570 $mform->addElement('static', null, '', get_string('information','repository_flickr_public')); 571 } 572 573 /** 574 * Names of the plugin settings 575 * @return array 576 */ 577 public static function get_type_option_names() { 578 return array('api_key', 'pluginname'); 579 } 580 581 /** 582 * is run when moodle administrator add the plugin 583 */ 584 public static function plugin_init() { 585 //here we create a default instance for this type 586 587 $id = repository::static_function('flickr_public','create', 'flickr_public', 0, context_system::instance(), array('name'=>'', 'email_address' => null, 'usewatermarks' => false), 0); 588 if (empty($id)) { 589 return false; 590 } else { 591 return true; 592 } 593 } 594 public function supported_filetypes() { 595 return array('web_image'); 596 } 597 public function supported_returntypes() { 598 return (FILE_INTERNAL | FILE_EXTERNAL); 599 } 600 601 /** 602 * Return the source information 603 * 604 * @param string $photoid photo id 605 * @return string|null 606 */ 607 public function get_file_source_info($photoid) { 608 return $this->build_photo_url($photoid); 609 } 610 611 /** 612 * Is this repository accessing private data? 613 * 614 * @return bool 615 */ 616 public function contains_private_data() { 617 return false; 618 } 619 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body