PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/repository/flickr_public/lib.php

https://bitbucket.org/synergylearning/campusconnect
PHP | 564 lines | 335 code | 53 blank | 176 comment | 42 complexity | a3c7cdb77d1d8150e9c9f768e23d3097 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, Apache-2.0, BSD-3-Clause, AGPL-3.0
  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. * This plugin is used to access flickr pictures
  18. *
  19. * @since 2.0
  20. * @package repository_flickr_public
  21. * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org}
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. require_once($CFG->dirroot . '/repository/lib.php');
  25. require_once($CFG->libdir.'/flickrlib.php');
  26. require_once(dirname(__FILE__) . '/image.php');
  27. /**
  28. * repository_flickr_public class
  29. * This one is used to create public repository
  30. * You can set up a public account in admin page, so everyone can access
  31. * flickr photos from this plugin
  32. *
  33. * @since 2.0
  34. * @package repository_flickr_public
  35. * @copyright 2009 Dongsheng Cai {@link http://dongsheng.org}
  36. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37. */
  38. class repository_flickr_public extends repository {
  39. private $flickr;
  40. public $photos;
  41. /**
  42. * Stores sizes of images to prevent multiple API call
  43. */
  44. static private $sizes = array();
  45. /**
  46. * constructor method
  47. *
  48. * @global object $CFG
  49. * @global object $SESSION
  50. * @param int $repositoryid
  51. * @param int $context
  52. * @param array $options
  53. * @param boolean $readonly
  54. */
  55. public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array(), $readonly=0) {
  56. global $CFG, $SESSION;
  57. parent::__construct($repositoryid, $context, $options,$readonly);
  58. $this->api_key = $this->get_option('api_key');
  59. $this->flickr = new phpFlickr($this->api_key);
  60. $this->flickr_account = $this->get_option('email_address');
  61. $this->usewatermarks = $this->get_option('usewatermarks');
  62. $account = optional_param('flickr_account', '', PARAM_RAW);
  63. $fulltext = optional_param('flickr_fulltext', '', PARAM_RAW);
  64. if (empty($fulltext)) {
  65. $fulltext = optional_param('s', '', PARAM_RAW);
  66. }
  67. $tag = optional_param('flickr_tag', '', PARAM_RAW);
  68. $license = optional_param('flickr_license', '', PARAM_RAW);
  69. $this->sess_account = 'flickr_public_'.$this->id.'_account';
  70. $this->sess_tag = 'flickr_public_'.$this->id.'_tag';
  71. $this->sess_text = 'flickr_public_'.$this->id.'_text';
  72. if (!empty($account) or !empty($fulltext) or !empty($tag) or !empty($license)) {
  73. $SESSION->{$this->sess_tag} = $tag;
  74. $SESSION->{$this->sess_text} = $fulltext;
  75. $SESSION->{$this->sess_account} = $account;
  76. }
  77. }
  78. /**
  79. * save api_key in config table
  80. * @param array $options
  81. * @return boolean
  82. */
  83. public function set_option($options = array()) {
  84. if (!empty($options['api_key'])) {
  85. set_config('api_key', trim($options['api_key']), 'flickr_public');
  86. }
  87. unset($options['api_key']);
  88. return parent::set_option($options);
  89. }
  90. /**
  91. * get api_key from config table
  92. *
  93. * @param string $config
  94. * @return mixed
  95. */
  96. public function get_option($config = '') {
  97. if ($config==='api_key') {
  98. return trim(get_config('flickr_public', 'api_key'));
  99. } else {
  100. $options['api_key'] = trim(get_config('flickr_public', 'api_key'));
  101. }
  102. return parent::get_option($config);
  103. }
  104. /**
  105. * is global_search available?
  106. *
  107. * @return boolean
  108. */
  109. public function global_search() {
  110. if (empty($this->flickr_account)) {
  111. return false;
  112. } else {
  113. return true;
  114. }
  115. }
  116. /**
  117. * check if flickr account
  118. * @return boolean
  119. */
  120. public function check_login() {
  121. return !empty($this->flickr_account);
  122. }
  123. /**
  124. * construct login form
  125. *
  126. * @param boolean $ajax
  127. * @return array
  128. */
  129. public function print_login() {
  130. if ($this->options['ajax']) {
  131. $ret = array();
  132. $fulltext = new stdClass();
  133. $fulltext->label = get_string('fulltext', 'repository_flickr_public').': ';
  134. $fulltext->id = 'el_fulltext';
  135. $fulltext->type = 'text';
  136. $fulltext->name = 'flickr_fulltext';
  137. $tag = new stdClass();
  138. $tag->label = get_string('tag', 'repository_flickr_public').': ';
  139. $tag->id = 'el_tag';
  140. $tag->type = 'text';
  141. $tag->name = 'flickr_tag';
  142. $email_field = new stdClass();
  143. $email_field->label = get_string('username', 'repository_flickr_public').': ';
  144. $email_field->id = 'account';
  145. $email_field->type = 'text';
  146. $email_field->name = 'flickr_account';
  147. $commercial = new stdClass();
  148. $commercial->label = get_string('commercialuse', 'repository_flickr_public').': ';
  149. $commercial->id = 'flickr_commercial_id';
  150. $commercial->type = 'checkbox';
  151. $commercial->name = 'flickr_commercial';
  152. $commercial->value = 'yes';
  153. $modification = new stdClass();
  154. $modification->label = get_string('modification', 'repository_flickr_public').': ';
  155. $modification->id = 'flickr_modification_id';
  156. $modification->type = 'checkbox';
  157. $modification->name = 'flickr_modification';
  158. $modification->value = 'yes';
  159. $ret['login'] = array($fulltext, $tag, $email_field, $commercial, $modification);
  160. $ret['login_btn_label'] = get_string('search');
  161. $ret['login_btn_action'] = 'search';
  162. return $ret;
  163. } else {
  164. echo '<table>';
  165. echo '<tr><td><label>'.get_string('fulltext', 'repository_flickr_public').'</label></td>';
  166. echo '<td><input type="text" name="flickr_fulltext" /></td></tr>';
  167. echo '<tr><td><label>'.get_string('tag', 'repository_flickr_public').'</label></td>';
  168. echo '<td><input type="text" name="flickr_tag" /></td></tr>';
  169. echo '<tr><td><label>'.get_string('username', 'repository_flickr_public').'</label></td>';
  170. echo '<td><input type="text" name="flickr_account" /></td></tr>';
  171. echo '<tr><td><label>'.get_string('commercialuse', 'repository_flickr_public').'</label></td>';
  172. echo '<td>';
  173. echo '<input type="checkbox" name="flickr_commercial" value="yes" />';
  174. echo '</td></tr>';
  175. echo '<tr><td><label>'.get_string('modification', 'repository_flickr_public').'</label></td>';
  176. echo '<td>';
  177. echo '<input type="checkbox" name="flickr_modification" value="yes" />';
  178. echo '</td></tr>';
  179. echo '</table>';
  180. echo '<input type="hidden" name="action" value="search" />';
  181. echo '<input type="submit" value="'.get_string('search', 'repository').'" />';
  182. }
  183. }
  184. /**
  185. * destroy session
  186. *
  187. * @return object
  188. */
  189. public function logout() {
  190. global $SESSION;
  191. unset($SESSION->{$this->sess_tag});
  192. unset($SESSION->{$this->sess_text});
  193. unset($SESSION->{$this->sess_account});
  194. return $this->print_login();
  195. }
  196. public function license4moodle ($license_id) {
  197. $license = array(
  198. '0' => 'allrightsreserved',
  199. '1' => 'cc-nc-sa',
  200. '2' => 'cc-nc',
  201. '3' => 'cc-nc-nd',
  202. '4' => 'cc',
  203. '5' => 'cc-sa',
  204. '6' => 'cc-nd',
  205. '7' => 'other'
  206. );
  207. return $license[$license_id];
  208. }
  209. /**
  210. * search images on flickr
  211. *
  212. * @param string $search_text
  213. * @return array
  214. */
  215. public function search($search_text, $page = 0) {
  216. global $SESSION;
  217. $ret = array();
  218. if (empty($page)) {
  219. $page = 1;
  220. }
  221. if (!empty($this->flickr_account)) {
  222. $people = $this->flickr->people_findByEmail($this->flickr_account);
  223. $this->nsid = $people['nsid'];
  224. }
  225. if (!empty($SESSION->{$this->sess_account})) {
  226. $people = $this->flickr->people_findByEmail($SESSION->{$this->sess_account});
  227. $this->nsid = $people['nsid'];
  228. }
  229. if (empty($this->nsid)) {
  230. $this->nsid = null;
  231. // user specify a flickr account, but it is not valid
  232. if (!empty($this->flickr_account) or !empty($SESSION->{$this->sess_account})) {
  233. $ret['e'] = get_string('invalidemail', 'repository_flickr_public');
  234. return $ret;
  235. }
  236. }
  237. // including all licenses by default
  238. $licenses = array(1=>1, 2, 3, 4, 5, 6, 7);
  239. $commercial = optional_param('flickr_commercial', '', PARAM_RAW);
  240. $modification = optional_param('flickr_modification', '', PARAM_RAW);
  241. if ($commercial == 'yes') {
  242. // including
  243. // 4: Attribution License
  244. // 5: Attribution ShareAlike
  245. // 6: Attribution NoDerives
  246. // 7: unknown license
  247. unset($licenses[1], $licenses[2], $licenses[3]);
  248. }
  249. if ($modification == 'yes') {
  250. // including
  251. // 1: Attribution NonCommercial ShareAlike
  252. // 2: Attribution NonCommercial
  253. // 4: Attribution License
  254. // 5: Attribution ShareAlike
  255. // 7: unknown license
  256. unset($licenses[3], $licenses[6]);
  257. }
  258. //if ($modification == 'sharealike') {
  259. // including
  260. // 1: Attribution NonCommercial ShareAlike
  261. // 5: Attribution ShareAlike
  262. //unset($licenses[2], $licenses[3], $licenses[4], $licenses[6], $licenses[7]);
  263. //}
  264. $licenses = implode(',', $licenses);
  265. $tag = !empty($SESSION->{$this->sess_tag}) ? $SESSION->{$this->sess_tag} : null;
  266. $text = !empty($SESSION->{$this->sess_text}) ? $SESSION->{$this->sess_text} : null;
  267. $nsid = !empty($this->nsid) ? $this->nsid : null;
  268. $photos = $this->flickr->photos_search(array(
  269. 'tags'=>$tag,
  270. 'page'=>$page,
  271. 'per_page'=>24,
  272. 'user_id'=>$nsid,
  273. 'license'=>$licenses,
  274. 'text'=>$text
  275. )
  276. );
  277. $ret['total'] = $photos['total'];
  278. $ret['perpage'] = $photos['perpage'];
  279. if (empty($photos)) {
  280. $ret['list'] = array();
  281. return $ret;
  282. }
  283. $ret = $this->build_list($photos, $page, $ret);
  284. $ret['list'] = array_filter($ret['list'], array($this, 'filter'));
  285. return $ret;
  286. }
  287. /**
  288. * return an image list
  289. *
  290. * @param string $path
  291. * @param int $page
  292. * @return array
  293. */
  294. public function get_listing($path = '', $page = 1) {
  295. $people = $this->flickr->people_findByEmail($this->flickr_account);
  296. $this->nsid = $people['nsid'];
  297. $photos = $this->flickr->people_getPublicPhotos($people['nsid'], 'original_format', 24, $page);
  298. $ret = array();
  299. return $this->build_list($photos, $page, $ret);
  300. }
  301. /**
  302. * build an image list
  303. *
  304. * @param array $photos
  305. * @param int $page
  306. * @return array
  307. */
  308. private function build_list($photos, $page = 1, &$ret) {
  309. if (!empty($this->nsid)) {
  310. $photos_url = $this->flickr->urls_getUserPhotos($this->nsid);
  311. $ret['manage'] = $photos_url;
  312. }
  313. $ret['list'] = array();
  314. $ret['nosearch'] = true;
  315. $ret['norefresh'] = true;
  316. $ret['logouttext'] = get_string('backtosearch', 'repository_flickr_public');
  317. $ret['pages'] = $photos['pages'];
  318. if (is_int($page) && $page <= $ret['pages']) {
  319. $ret['page'] = $page;
  320. } else {
  321. $ret['page'] = 1;
  322. }
  323. if (!empty($photos['photo'])) {
  324. foreach ($photos['photo'] as $p) {
  325. if(empty($p['title'])) {
  326. $p['title'] = get_string('notitle', 'repository_flickr');
  327. }
  328. if (isset($p['originalformat'])) {
  329. $format = $p['originalformat'];
  330. } else {
  331. $format = 'jpg';
  332. }
  333. $format = '.'.$format;
  334. if (substr($p['title'], strlen($p['title'])-strlen($format)) != $format) {
  335. // append author id
  336. // $p['title'] .= '-'.$p['owner'];
  337. // append file extension
  338. $p['title'] .= $format;
  339. }
  340. $ret['list'][] = array(
  341. 'title'=>$p['title'],
  342. 'source'=>$p['id'],
  343. 'id'=>$p['id'],
  344. 'thumbnail'=>$this->flickr->buildPhotoURL($p, 'Square'),
  345. 'date'=>'',
  346. 'size'=>'unknown',
  347. 'url'=>'http://www.flickr.com/photos/'.$p['owner'].'/'.$p['id'],
  348. 'haslicense'=>true,
  349. 'hasauthor'=>true
  350. );
  351. }
  352. }
  353. return $ret;
  354. }
  355. /**
  356. * Print a search form
  357. *
  358. * @return string
  359. */
  360. public function print_search() {
  361. $str = '';
  362. $str .= '<input type="hidden" name="repo_id" value="'.$this->id.'" />';
  363. $str .= '<input type="hidden" name="ctx_id" value="'.$this->context->id.'" />';
  364. $str .= '<input type="hidden" name="seekey" value="'.sesskey().'" />';
  365. $str .= '<label>'.get_string('fulltext', 'repository_flickr_public').': </label><br/><input name="s" value="" /><br/>';
  366. $str .= '<label>'.get_string('tag', 'repository_flickr_public').'</label><br /><input type="text" name="flickr_tag" /><br />';
  367. return $str;
  368. }
  369. /**
  370. * Return photo url by given photo id
  371. * @param string $photoid
  372. * @return string
  373. */
  374. private function build_photo_url($photoid) {
  375. $bestsize = $this->get_best_size($photoid);
  376. if (!isset($bestsize['source'])) {
  377. throw new repository_exception('cannotdownload', 'repository');
  378. }
  379. return $bestsize['source'];
  380. }
  381. /**
  382. * Returns the best size for a photo
  383. *
  384. * @param string $photoid the photo identifier
  385. * @return array of information provided by the API
  386. */
  387. protected function get_best_size($photoid) {
  388. if (!isset(self::$sizes[$photoid])) {
  389. // Sizes are returned from smallest to greatest.
  390. self::$sizes[$photoid] = $this->flickr->photos_getSizes($photoid);
  391. }
  392. $sizes = self::$sizes[$photoid];
  393. $bestsize = array();
  394. if (is_array($sizes)) {
  395. while ($bestsize = array_pop($sizes)) {
  396. // Make sure the source is set. Exit the loop if found.
  397. if (isset($bestsize['source'])) {
  398. break;
  399. }
  400. }
  401. }
  402. return $bestsize;
  403. }
  404. public function get_link($photoid) {
  405. return $this->build_photo_url($photoid);
  406. }
  407. /**
  408. *
  409. * @global object $CFG
  410. * @param string $photoid
  411. * @param string $file
  412. * @return string
  413. */
  414. public function get_file($photoid, $file = '') {
  415. global $CFG;
  416. $info = $this->flickr->photos_getInfo($photoid);
  417. if ($info['owner']['realname']) {
  418. $author = $info['owner']['realname'];
  419. } else {
  420. $author = $info['owner']['username'];
  421. }
  422. $copyright = get_string('author', 'repository') . ': ' . $author;
  423. // If we can read the original secret, it means that we have access to the original picture.
  424. if (isset($info['originalsecret'])) {
  425. $source = $this->flickr->buildPhotoURL($info, 'original');
  426. } else {
  427. $source = $this->build_photo_url($photoid);
  428. }
  429. $result = parent::get_file($source, $file);
  430. $path = $result['path'];
  431. if (!empty($this->usewatermarks)) {
  432. $img = new moodle_image($path);
  433. $img->watermark($copyright, array(10,10), array('ttf'=>true, 'fontsize'=>12))->saveas($path);
  434. }
  435. return array('path'=>$path, 'author'=>$info['owner']['realname'], 'license'=>$this->license4moodle($info['license']));
  436. }
  437. /**
  438. * Add Instance settings input to Moodle form
  439. * @param object $mform
  440. */
  441. public static function instance_config_form($mform) {
  442. $mform->addElement('text', 'email_address', get_string('emailaddress', 'repository_flickr_public'));
  443. $mform->setType('email_address', PARAM_RAW_TRIMMED); // This is for sending to flickr. Not our job to validate it.
  444. $mform->addElement('checkbox', 'usewatermarks', get_string('watermark', 'repository_flickr_public'));
  445. $mform->setDefault('usewatermarks', 0);
  446. }
  447. /**
  448. * Names of the instance settings
  449. * @return array
  450. */
  451. public static function get_instance_option_names() {
  452. return array('email_address', 'usewatermarks');
  453. }
  454. /**
  455. * Add Plugin settings input to Moodle form
  456. * @param object $mform
  457. */
  458. public static function type_config_form($mform, $classname = 'repository') {
  459. $api_key = get_config('flickr_public', 'api_key');
  460. if (empty($api_key)) {
  461. $api_key = '';
  462. }
  463. $strrequired = get_string('required');
  464. $mform->addElement('text', 'api_key', get_string('apikey', 'repository_flickr_public'), array('value'=>$api_key,'size' => '40'));
  465. $mform->setType('api_key', PARAM_RAW_TRIMMED);
  466. $mform->addRule('api_key', $strrequired, 'required', null, 'client');
  467. $mform->addElement('static', null, '', get_string('information','repository_flickr_public'));
  468. }
  469. /**
  470. * Names of the plugin settings
  471. * @return array
  472. */
  473. public static function get_type_option_names() {
  474. return array('api_key', 'pluginname');
  475. }
  476. /**
  477. * is run when moodle administrator add the plugin
  478. */
  479. public static function plugin_init() {
  480. //here we create a default instance for this type
  481. $id = repository::static_function('flickr_public','create', 'flickr_public', 0, context_system::instance(), array('name'=>'', 'email_address' => null, 'usewatermarks' => false), 0);
  482. if (empty($id)) {
  483. return false;
  484. } else {
  485. return true;
  486. }
  487. }
  488. public function supported_filetypes() {
  489. return array('web_image');
  490. }
  491. public function supported_returntypes() {
  492. return (FILE_INTERNAL | FILE_EXTERNAL);
  493. }
  494. /**
  495. * Return the source information
  496. *
  497. * @param string $photoid photo id
  498. * @return string|null
  499. */
  500. public function get_file_source_info($photoid) {
  501. return $this->build_photo_url($photoid);
  502. }
  503. /**
  504. * Is this repository accessing private data?
  505. *
  506. * @return bool
  507. */
  508. public function contains_private_data() {
  509. return false;
  510. }
  511. }