84bac4bb2844d8b7c7ad6c6aaf48079dcbdde5e6
[moodle.git] / repository / flickr / lib.php
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/>.
17 /**
18  * This plugin is used to access flickr pictures
19  *
20  * @since 2.0
21  * @package    repository_flickr
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');
28 /**
29  * This plugin is used to access user's private flickr repository
30  *
31  * @since 2.0
32  * @package    repository_flickr
33  * @copyright  2009 Dongsheng Cai {@link http://dongsheng.org}
34  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35  */
36 class repository_flickr extends repository {
37     private $flickr;
38     public $photos;
40     /**
41      * Stores sizes of images to prevent multiple API call
42      */
43     static private $sizes = array();
45     /**
46      *
47      * @param int $repositoryid
48      * @param object $context
49      * @param array $options
50      */
51     public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
52         global $SESSION, $CFG;
53         $options['page']    = optional_param('p', 1, PARAM_INT);
54         parent::__construct($repositoryid, $context, $options);
56         $this->setting = 'flickr_';
58         $this->api_key = $this->get_option('api_key');
59         $this->secret  = $this->get_option('secret');
61         $this->token = get_user_preferences($this->setting, '');
62         $this->nsid  = get_user_preferences($this->setting.'_nsid', '');
64         $this->flickr = new phpFlickr($this->api_key, $this->secret, $this->token);
66         $frob  = optional_param('frob', '', PARAM_RAW);
67         if (empty($this->token) && !empty($frob)) {
68             $auth_info = $this->flickr->auth_getToken($frob);
69             $this->token = $auth_info['token'];
70             $this->nsid  = $auth_info['user']['nsid'];
71             set_user_preference($this->setting, $auth_info['token']);
72             set_user_preference($this->setting.'_nsid', $auth_info['user']['nsid']);
73         }
75     }
77     /**
78      *
79      * @return bool
80      */
81     public function check_login() {
82         return !empty($this->token);
83     }
85     /**
86      *
87      * @return mixed
88      */
89     public function logout() {
90         set_user_preference($this->setting, '');
91         set_user_preference($this->setting.'_nsid', '');
92         $this->token = '';
93         $this->nsid  = '';
94         return $this->print_login();
95     }
97     /**
98      *
99      * @param array $options
100      * @return mixed
101      */
102     public function set_option($options = array()) {
103         if (!empty($options['api_key'])) {
104             set_config('api_key', trim($options['api_key']), 'flickr');
105         }
106         if (!empty($options['secret'])) {
107             set_config('secret', trim($options['secret']), 'flickr');
108         }
109         unset($options['api_key']);
110         unset($options['secret']);
111         $ret = parent::set_option($options);
112         return $ret;
113     }
115     /**
116      *
117      * @param string $config
118      * @return mixed
119      */
120     public function get_option($config = '') {
121         if ($config==='api_key') {
122             return trim(get_config('flickr', 'api_key'));
123         } elseif ($config ==='secret') {
124             return trim(get_config('flickr', 'secret'));
125         } else {
126             $options['api_key'] = trim(get_config('flickr', 'api_key'));
127             $options['secret']  = trim(get_config('flickr', 'secret'));
128         }
129         $options = parent::get_option($config);
130         return $options;
131     }
133     /**
134      *
135      * @return bool
136      */
137     public function global_search() {
138         if (empty($this->token)) {
139             return false;
140         } else {
141             return true;
142         }
143     }
145     /**
146      *
147      * @return null
148      */
149     public function print_login() {
150         if ($this->options['ajax']) {
151             $ret = array();
152             $popup_btn = new stdClass();
153             $popup_btn->type = 'popup';
154             $popup_btn->url = $this->flickr->auth();
155             $ret['login'] = array($popup_btn);
156             return $ret;
157         } else {
158             echo '<a target="_blank" href="'.$this->flickr->auth().'">'.get_string('login', 'repository').'</a>';
159         }
160     }
162     /**
163      * Converts result received from phpFlickr::photo_search to Filepicker/repository format
164      *
165      * @param mixed $photos
166      * @return array
167      */
168     private function build_list($photos) {
169         $photos_url = $this->flickr->urls_getUserPhotos($this->nsid);
170         $ret = array();
171         $ret['manage'] = $photos_url;
172         $ret['list']  = array();
173         $ret['pages'] = $photos['pages'];
174         $ret['total'] = $photos['total'];
175         $ret['perpage'] = $photos['perpage'];
176         $ret['page'] = $photos['page'];
177         if (!empty($photos['photo'])) {
178             foreach ($photos['photo'] as $p) {
179                 if(empty($p['title'])) {
180                     $p['title'] = get_string('notitle', 'repository_flickr');
181                 }
182                 if (isset($p['originalformat'])) {
183                     $format = $p['originalformat'];
184                 } else {
185                     $format = 'jpg';
186                 }
187                 $format = '.'.$format;
188                 // append extensions to the files
189                 if (substr($p['title'], strlen($p['title'])-strlen($format)) != $format) {
190                     $p['title'] .= $format;
191                 }
192                 $ret['list'][] = array('title'=>$p['title'],'source'=>$p['id'],
193                     'id'=>$p['id'],'thumbnail'=>$this->flickr->buildPhotoURL($p, 'Square'),
194                     'thumbnail_width'=>75, 'thumbnail_height'=>75,
195                     'date'=>'', 'size'=>'unknown', 'url'=>$photos_url.$p['id']);
196             }
197         }
198         return $ret;
199     }
201     /**
202      *
203      * @param string $search_text
204      * @param int $page
205      * @return array
206      */
207     public function search($search_text, $page = 0) {
208         $photos = $this->flickr->photos_search(array(
209             'user_id'=>$this->nsid,
210             'per_page'=>24,
211             'extras'=>'original_format',
212             'page'=>$page,
213             'text'=>$search_text
214             ));
215         $ret = $this->build_list($photos);
216         $ret['list'] = array_filter($ret['list'], array($this, 'filter')); // TODO this breaks pagination
217         return $ret;
218     }
220     /**
221      *
222      * @param string $path
223      * @param int $page
224      * @return array
225      */
226     public function get_listing($path = '', $page = '') {
227         return $this->search('', $page);
228     }
230     /**
231      * Return photo url by given photo id
232      * @param string $photoid
233      * @return string
234      */
235     private function build_photo_url($photoid) {
236         $bestsize = $this->get_best_size($photoid);
237         if (!isset($bestsize['source'])) {
238             throw new repository_exception('cannotdownload', 'repository');
239         }
240         return $bestsize['source'];
241     }
243     /**
244      * Returns the best size for a photo
245      *
246      * @param string $photoid the photo identifier
247      * @return array of information provided by the API
248      */
249     protected function get_best_size($photoid) {
250         if (!isset(self::$sizes[$photoid])) {
251             // Sizes are returned from smallest to greatest.
252             self::$sizes[$photoid] = $this->flickr->photos_getSizes($photoid);
253         }
254         $sizes = self::$sizes[$photoid];
255         $bestsize = array();
256         if (is_array($sizes)) {
257             while ($bestsize = array_pop($sizes)) {
258                 // Make sure the source is set. Exit the loop if found.
259                 if (isset($bestsize['source'])) {
260                     break;
261                 }
262             }
263         }
264         return $bestsize;
265     }
267     public function get_link($photoid) {
268         return $this->build_photo_url($photoid);
269     }
271     /**
272      *
273      * @param string $photoid
274      * @param string $file
275      * @return string
276      */
277     public function get_file($photoid, $file = '') {
278         $url = $this->build_photo_url($photoid);
279         return parent::get_file($url, $file);
280     }
282     /**
283      * Add Plugin settings input to Moodle form
284      * @param object $mform
285      */
286     public static function type_config_form($mform, $classname = 'repository') {
287         global $CFG;
288         $api_key = get_config('flickr', 'api_key');
289         $secret = get_config('flickr', 'secret');
291         if (empty($api_key)) {
292             $api_key = '';
293         }
294         if (empty($secret)) {
295             $secret = '';
296         }
298         parent::type_config_form($mform);
300         $strrequired = get_string('required');
301         $mform->addElement('text', 'api_key', get_string('apikey', 'repository_flickr'), array('value'=>$api_key,'size' => '40'));
302         $mform->addElement('text', 'secret', get_string('secret', 'repository_flickr'), array('value'=>$secret,'size' => '40'));
304         //retrieve the flickr instances
305         $params = array();
306         $params['context'] = array();
307         //$params['currentcontext'] = $this->context;
308         $params['onlyvisible'] = false;
309         $params['type'] = 'flickr';
310         $instances = repository::get_instances($params);
311         if (empty($instances)) {
312             $callbackurl = get_string('callbackwarning', 'repository_flickr');
313             $mform->addElement('static', null, '',  $callbackurl);
314         } else {
315             $instance = array_shift($instances);
316             $callbackurl = $CFG->wwwroot.'/repository/repository_callback.php?repo_id='.$instance->id;
317             $mform->addElement('static', 'callbackurl', '', get_string('callbackurltext', 'repository_flickr', $callbackurl));
318         }
320         $mform->addRule('api_key', $strrequired, 'required', null, 'client');
321         $mform->addRule('secret', $strrequired, 'required', null, 'client');
322     }
324     /**
325      * Names of the plugin settings
326      * @return array
327      */
328     public static function get_type_option_names() {
329         return array('api_key', 'secret', 'pluginname');
330     }
331     public function supported_filetypes() {
332         return array('web_image');
333     }
334     public function supported_returntypes() {
335         return (FILE_INTERNAL | FILE_EXTERNAL);
336     }
338     /**
339      * Return the source information
340      *
341      * @param string $photoid
342      * @return string|null
343      */
344     public function get_file_source_info($photoid) {
345         return $this->build_photo_url($photoid);
346     }