2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * This plugin is used to access flickr pictures
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
25 require_once($CFG->dirroot
. '/repository/lib.php');
26 require_once($CFG->libdir
.'/flickrlib.php');
27 require_once(dirname(__FILE__
) . '/image.php');
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
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
40 class repository_flickr_public
extends repository
{
45 * Stores sizes of images to prevent multiple API call
47 static private $sizes = array();
53 * @global object $SESSION
54 * @param int $repositoryid
56 * @param array $options
57 * @param boolean $readonly
59 public function __construct($repositoryid, $context = SYSCONTEXTID
, $options = array(), $readonly=0) {
60 global $CFG, $SESSION;
61 parent
::__construct($repositoryid, $context, $options,$readonly);
62 $this->api_key
= $this->get_option('api_key');
63 $this->flickr
= new phpFlickr($this->api_key
);
64 $this->flickr_account
= $this->get_option('email_address');
65 $this->usewatermarks
= $this->get_option('usewatermarks');
67 $account = optional_param('flickr_account', '', PARAM_RAW
);
68 $fulltext = optional_param('flickr_fulltext', '', PARAM_RAW
);
69 if (empty($fulltext)) {
70 $fulltext = optional_param('s', '', PARAM_RAW
);
72 $tag = optional_param('flickr_tag', '', PARAM_RAW
);
73 $license = optional_param('flickr_license', '', PARAM_RAW
);
75 $this->sess_account
= 'flickr_public_'.$this->id
.'_account';
76 $this->sess_tag
= 'flickr_public_'.$this->id
.'_tag';
77 $this->sess_text
= 'flickr_public_'.$this->id
.'_text';
79 if (!empty($account) or !empty($fulltext) or !empty($tag) or !empty($license)) {
80 $SESSION->{$this->sess_tag
} = $tag;
81 $SESSION->{$this->sess_text
} = $fulltext;
82 $SESSION->{$this->sess_account
} = $account;
87 * save api_key in config table
88 * @param array $options
91 public function set_option($options = array()) {
92 if (!empty($options['api_key'])) {
93 set_config('api_key', trim($options['api_key']), 'flickr_public');
95 unset($options['api_key']);
96 return parent
::set_option($options);
100 * get api_key from config table
102 * @param string $config
105 public function get_option($config = '') {
106 if ($config==='api_key') {
107 return trim(get_config('flickr_public', 'api_key'));
109 $options['api_key'] = trim(get_config('flickr_public', 'api_key'));
111 return parent
::get_option($config);
115 * is global_search available?
119 public function global_search() {
120 if (empty($this->flickr_account
)) {
128 * check if flickr account
131 public function check_login() {
132 return !empty($this->flickr_account
);
136 * construct login form
138 * @param boolean $ajax
141 public function print_login() {
142 if ($this->options
['ajax']) {
144 $fulltext = new stdClass();
145 $fulltext->label
= get_string('fulltext', 'repository_flickr_public').': ';
146 $fulltext->id
= 'el_fulltext';
147 $fulltext->type
= 'text';
148 $fulltext->name
= 'flickr_fulltext';
150 $tag = new stdClass();
151 $tag->label
= get_string('tag', 'repository_flickr_public').': ';
154 $tag->name
= 'flickr_tag';
156 $email_field = new stdClass();
157 $email_field->label
= get_string('username', 'repository_flickr_public').': ';
158 $email_field->id
= 'account';
159 $email_field->type
= 'text';
160 $email_field->name
= 'flickr_account';
162 $commercial = new stdClass();
163 $commercial->label
= get_string('commercialuse', 'repository_flickr_public').': ';
164 $commercial->id
= 'flickr_commercial_id';
165 $commercial->type
= 'checkbox';
166 $commercial->name
= 'flickr_commercial';
167 $commercial->value
= 'yes';
169 $modification = new stdClass();
170 $modification->label
= get_string('modification', 'repository_flickr_public').': ';
171 $modification->id
= 'flickr_modification_id';
172 $modification->type
= 'checkbox';
173 $modification->name
= 'flickr_modification';
174 $modification->value
= 'yes';
176 $ret['login'] = array($fulltext, $tag, $email_field, $commercial, $modification);
177 $ret['login_btn_label'] = get_string('search');
178 $ret['login_btn_action'] = 'search';
182 echo '<tr><td><label>'.get_string('fulltext', 'repository_flickr_public').'</label></td>';
183 echo '<td><input type="text" name="flickr_fulltext" /></td></tr>';
184 echo '<tr><td><label>'.get_string('tag', 'repository_flickr_public').'</label></td>';
185 echo '<td><input type="text" name="flickr_tag" /></td></tr>';
186 echo '<tr><td><label>'.get_string('username', 'repository_flickr_public').'</label></td>';
187 echo '<td><input type="text" name="flickr_account" /></td></tr>';
189 echo '<tr><td><label>'.get_string('commercialuse', 'repository_flickr_public').'</label></td>';
191 echo '<input type="checkbox" name="flickr_commercial" value="yes" />';
194 echo '<tr><td><label>'.get_string('modification', 'repository_flickr_public').'</label></td>';
196 echo '<input type="checkbox" name="flickr_modification" value="yes" />';
201 echo '<input type="hidden" name="action" value="search" />';
202 echo '<input type="submit" value="'.get_string('search', 'repository').'" />';
211 public function logout() {
213 unset($SESSION->{$this->sess_tag
});
214 unset($SESSION->{$this->sess_text
});
215 unset($SESSION->{$this->sess_account
});
216 return $this->print_login();
219 public function license4moodle ($license_id) {
221 '0' => 'allrightsreserved',
230 return $license[$license_id];
234 * search images on flickr
236 * @param string $search_text
239 public function search($search_text, $page = 0) {
246 if (!empty($this->flickr_account
)) {
247 $people = $this->flickr
->people_findByEmail($this->flickr_account
);
248 $this->nsid
= $people['nsid'];
250 if (!empty($SESSION->{$this->sess_account
})) {
251 $people = $this->flickr
->people_findByEmail($SESSION->{$this->sess_account
});
252 $this->nsid
= $people['nsid'];
254 if (empty($this->nsid
)) {
256 // user specify a flickr account, but it is not valid
257 if (!empty($this->flickr_account
) or !empty($SESSION->{$this->sess_account
})) {
258 $ret['e'] = get_string('invalidemail', 'repository_flickr_public');
263 // including all licenses by default
264 $licenses = array(1=>1, 2, 3, 4, 5, 6, 7);
266 $commercial = optional_param('flickr_commercial', '', PARAM_RAW
);
267 $modification = optional_param('flickr_modification', '', PARAM_RAW
);
269 if ($commercial == 'yes') {
271 // 4: Attribution License
272 // 5: Attribution ShareAlike
273 // 6: Attribution NoDerives
274 // 7: unknown license
275 unset($licenses[1], $licenses[2], $licenses[3]);
277 if ($modification == 'yes') {
279 // 1: Attribution NonCommercial ShareAlike
280 // 2: Attribution NonCommercial
281 // 4: Attribution License
282 // 5: Attribution ShareAlike
283 // 7: unknown license
284 unset($licenses[3], $licenses[6]);
286 //if ($modification == 'sharealike') {
288 // 1: Attribution NonCommercial ShareAlike
289 // 5: Attribution ShareAlike
290 //unset($licenses[2], $licenses[3], $licenses[4], $licenses[6], $licenses[7]);
293 $licenses = implode(',', $licenses);
295 $tag = !empty($SESSION->{$this->sess_tag
}) ?
$SESSION->{$this->sess_tag
} : null;
296 $text = !empty($SESSION->{$this->sess_text
}) ?
$SESSION->{$this->sess_text
} : null;
297 $nsid = !empty($this->nsid
) ?
$this->nsid
: null;
299 $photos = $this->flickr
->photos_search(array(
304 'license'=>$licenses,
308 $ret['total'] = $photos['total'];
309 $ret['perpage'] = $photos['perpage'];
310 if (empty($photos)) {
311 $ret['list'] = array();
314 $ret = $this->build_list($photos, $page, $ret);
315 $ret['list'] = array_filter($ret['list'], array($this, 'filter'));
320 * return an image list
322 * @param string $path
326 public function get_listing($path = '', $page = 1) {
327 $people = $this->flickr
->people_findByEmail($this->flickr_account
);
328 $this->nsid
= $people['nsid'];
329 $photos = $this->flickr
->people_getPublicPhotos($people['nsid'], 'original_format', 24, $page);
332 return $this->build_list($photos, $page, $ret);
336 * build an image list
338 * @param array $photos
342 private function build_list($photos, $page = 1, &$ret) {
343 if (!empty($this->nsid
)) {
344 $photos_url = $this->flickr
->urls_getUserPhotos($this->nsid
);
345 $ret['manage'] = $photos_url;
347 $ret['list'] = array();
348 $ret['nosearch'] = true;
349 $ret['norefresh'] = true;
350 $ret['logouttext'] = get_string('backtosearch', 'repository_flickr_public');
351 $ret['pages'] = $photos['pages'];
352 if (is_int($page) && $page <= $ret['pages']) {
353 $ret['page'] = $page;
357 if (!empty($photos['photo'])) {
358 foreach ($photos['photo'] as $p) {
359 if(empty($p['title'])) {
360 $p['title'] = get_string('notitle', 'repository_flickr');
362 if (isset($p['originalformat'])) {
363 $format = $p['originalformat'];
367 $format = '.'.$format;
368 if (substr($p['title'], strlen($p['title'])-strlen($format)) != $format) {
370 // $p['title'] .= '-'.$p['owner'];
371 // append file extension
372 $p['title'] .= $format;
374 $ret['list'][] = array(
375 'title'=>$p['title'],
378 'thumbnail'=>$this->flickr
->buildPhotoURL($p, 'Square'),
381 'url'=>'http://www.flickr.com/photos/'.$p['owner'].'/'.$p['id'],
391 * Print a search form
395 public function print_search() {
397 $str .= '<input type="hidden" name="repo_id" value="'.$this->id
.'" />';
398 $str .= '<input type="hidden" name="ctx_id" value="'.$this->context
->id
.'" />';
399 $str .= '<input type="hidden" name="seekey" value="'.sesskey().'" />';
400 $str .= '<label>'.get_string('fulltext', 'repository_flickr_public').': </label><br/><input name="s" value="" /><br/>';
401 $str .= '<label>'.get_string('tag', 'repository_flickr_public').'</label><br /><input type="text" name="flickr_tag" /><br />';
406 * Return photo url by given photo id
407 * @param string $photoid
410 private function build_photo_url($photoid) {
411 $bestsize = $this->get_best_size($photoid);
412 if (!isset($bestsize['source'])) {
413 throw new repository_exception('cannotdownload', 'repository');
415 return $bestsize['source'];
419 * Returns the best size for a photo
421 * @param string $photoid the photo identifier
422 * @return array of information provided by the API
424 protected function get_best_size($photoid) {
425 if (!isset(self
::$sizes[$photoid])) {
426 // Sizes are returned from smallest to greatest.
427 self
::$sizes[$photoid] = $this->flickr
->photos_getSizes($photoid);
429 $sizes = self
::$sizes[$photoid];
431 if (is_array($sizes)) {
432 while ($bestsize = array_pop($sizes)) {
433 // Make sure the source is set. Exit the loop if found.
434 if (isset($bestsize['source'])) {
442 public function get_link($photoid) {
443 return $this->build_photo_url($photoid);
448 * @global object $CFG
449 * @param string $photoid
450 * @param string $file
453 public function get_file($photoid, $file = '') {
455 $info = $this->flickr
->photos_getInfo($photoid);
456 if ($info['owner']['realname']) {
457 $author = $info['owner']['realname'];
459 $author = $info['owner']['username'];
461 $copyright = get_string('author', 'repository') . ': ' . $author;
463 // If we can read the original secret, it means that we have access to the original picture.
464 if (isset($info['originalsecret'])) {
465 $source = $this->flickr
->buildPhotoURL($info, 'original');
467 $source = $this->build_photo_url($photoid);
470 $result = parent
::get_file($source, $file);
471 $path = $result['path'];
473 if (!empty($this->usewatermarks
)) {
474 $img = new moodle_image($path);
475 $img->watermark($copyright, array(10,10), array('ttf'=>true, 'fontsize'=>12))->saveas($path);
478 return array('path'=>$path, 'author'=>$info['owner']['realname'], 'license'=>$this->license4moodle($info['license']));
482 * Add Instance settings input to Moodle form
483 * @param object $mform
485 public static function instance_config_form($mform) {
486 $mform->addElement('text', 'email_address', get_string('emailaddress', 'repository_flickr_public'));
487 $mform->addElement('checkbox', 'usewatermarks', get_string('watermark', 'repository_flickr_public'));
488 $mform->setDefault('usewatermarks', 0);
492 * Names of the instance settings
495 public static function get_instance_option_names() {
496 return array('email_address', 'usewatermarks');
500 * Add Plugin settings input to Moodle form
501 * @param object $mform
503 public static function type_config_form($mform, $classname = 'repository') {
504 $api_key = get_config('flickr_public', 'api_key');
505 if (empty($api_key)) {
508 $strrequired = get_string('required');
510 $mform->addElement('text', 'api_key', get_string('apikey', 'repository_flickr_public'), array('value'=>$api_key,'size' => '40'));
511 $mform->addRule('api_key', $strrequired, 'required', null, 'client');
513 $mform->addElement('static', null, '', get_string('information','repository_flickr_public'));
517 * Names of the plugin settings
520 public static function get_type_option_names() {
521 return array('api_key', 'pluginname');
525 * is run when moodle administrator add the plugin
527 public static function plugin_init() {
528 //here we create a default instance for this type
530 $id = repository
::static_function('flickr_public','create', 'flickr_public', 0, get_system_context(), array('name'=>'', 'email_address' => null, 'usewatermarks' => false), 0);
537 public function supported_filetypes() {
538 return array('web_image');
540 public function supported_returntypes() {
541 return (FILE_INTERNAL | FILE_EXTERNAL
);
545 * Return the source information
547 * @param string $photoid photo id
548 * @return string|null
550 public function get_file_source_info($photoid) {
551 return $this->build_photo_url($photoid);