Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]

   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   * Flickr tag block.
  19   *
  20   * @package    block_tag_flickr
  21   * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  define('FLICKR_DEV_KEY', '4fddbdd7ff2376beec54d7f6afad425e');
  27  define('DEFAULT_NUMBER_OF_PHOTOS', 6);
  28  
  29  require_once("{$CFG->libdir}/flickrclient.php");
  30  
  31  class block_tag_flickr extends block_base {
  32  
  33      function init() {
  34          $this->title = get_string('pluginname','block_tag_flickr');
  35      }
  36  
  37      function applicable_formats() {
  38          return array('tag' => true);
  39      }
  40  
  41      function specialization() {
  42          $this->title = !empty($this->config->title) ? $this->config->title : get_string('pluginname', 'block_tag_flickr');
  43      }
  44  
  45      function instance_allow_multiple() {
  46          return true;
  47      }
  48  
  49      function get_content() {
  50          global $CFG, $USER;
  51  
  52          //note: do NOT include files at the top of this file
  53          require_once($CFG->libdir . '/filelib.php');
  54  
  55          if ($this->content !== NULL) {
  56              return $this->content;
  57          }
  58  
  59          $tagid = optional_param('id', 0, PARAM_INT);   // tag id - for backware compatibility
  60          $tag = optional_param('tag', '', PARAM_TAG); // tag
  61          $tc = optional_param('tc', 0, PARAM_INT); // Tag collection id.
  62  
  63          if ($tagid) {
  64              $tagobject = core_tag_tag::get($tagid);
  65          } else if ($tag) {
  66              $tagobject = core_tag_tag::get_by_name($tc, $tag);
  67          }
  68  
  69          if (empty($tagobject)) {
  70              $this->content = new stdClass;
  71              $this->content->text = '';
  72              $this->content->footer = '';
  73              return $this->content;
  74          }
  75  
  76          //include related tags in the photo query ?
  77          $tagscsv = $tagobject->name;
  78          if (!empty($this->config->includerelatedtags)) {
  79              foreach ($tagobject->get_related_tags() as $t) {
  80                  $tagscsv .= ',' . $t->get_display_name(false);
  81              }
  82          }
  83          $tagscsv = urlencode($tagscsv);
  84  
  85          //number of photos to display
  86          $numberofphotos = DEFAULT_NUMBER_OF_PHOTOS;
  87          if( !empty($this->config->numberofphotos)) {
  88              $numberofphotos = $this->config->numberofphotos;
  89          }
  90  
  91          //sort search results by
  92          $sortby = 'relevance';
  93          if( !empty($this->config->sortby)) {
  94              $sortby = $this->config->sortby;
  95          }
  96  
  97          //pull photos from a specific photoset
  98          if(!empty($this->config->photoset)){
  99  
 100              $request = 'https://api.flickr.com/services/rest/?method=flickr.photosets.getPhotos';
 101              $request .= '&api_key='.FLICKR_DEV_KEY;
 102              $request .= '&photoset_id='.$this->config->photoset;
 103              $request .= '&per_page='.$numberofphotos;
 104              $request .= '&format=php_serial';
 105  
 106              $response = $this->fetch_request($request);
 107  
 108              $search = @unserialize($response);
 109              if ($search === false && $search != serialize(false)) {
 110                  // The response didn't appear to be anything serialized, exit...
 111                  return;
 112              }
 113  
 114              foreach ($search['photoset']['photo'] as $p){
 115                  $p['owner'] = $search['photoset']['owner'];
 116              }
 117  
 118              $photos = array_values($search['photoset']['photo']);
 119  
 120          }
 121          //search for photos tagged with $tagscsv
 122          else{
 123  
 124              $request = 'https://api.flickr.com/services/rest/?method=flickr.photos.search';
 125              $request .= '&api_key='.FLICKR_DEV_KEY;
 126              $request .= '&tags='.$tagscsv;
 127              $request .= '&per_page='.$numberofphotos;
 128              $request .= '&sort='.$sortby;
 129              $request .= '&format=php_serial';
 130  
 131              $response = $this->fetch_request($request);
 132  
 133              $search = @unserialize($response);
 134              if ($search === false && $search != serialize(false)) {
 135                  // The response didn't appear to be anything serialized, exit...
 136                  return;
 137              }
 138              $photos = array_values($search['photos']['photo']);
 139          }
 140  
 141  
 142          if(strcmp($search['stat'], 'ok') != 0) return; //if no results were returned, exit...
 143  
 144          //Accessibility: render the list of photos
 145          $text = '<ul class="inline-list">';
 146           foreach ($photos as $photo) {
 147              $text .= '<li><a href="http://www.flickr.com/photos/' . $photo['owner'] . '/' . $photo['id'] . '/" title="'.s($photo['title']).'">';
 148              $text .= '<img alt="'.s($photo['title']).'" class="flickr-photos" src="'. $this->build_photo_url($photo, 'square') ."\" /></a></li>\n";
 149           }
 150          $text .= "</ul>\n";
 151  
 152          $this->content = new stdClass;
 153          $this->content->text = $text;
 154          $this->content->footer = '';
 155  
 156          return $this->content;
 157      }
 158  
 159      function fetch_request($request){
 160          $c =  new curl(array('cache' => true, 'module_cache'=> 'tag_flickr'));
 161          // Set custom user agent as Flickr blocks our "MoodleBot" agent string.
 162          $c->setopt([
 163              'CURLOPT_USERAGENT' => flickr_client::user_agent(),
 164          ]);
 165  
 166          $response = $c->get($request);
 167  
 168          return $response;
 169      }
 170  
 171      function build_photo_url ($photo, $size='medium') {
 172          //receives an array (can use the individual photo data returned
 173          //from an API call) and returns a URL (doesn't mean that the
 174          //file size exists)
 175          $sizes = array(
 176              'square' => '_s',
 177              'thumbnail' => '_t',
 178              'small' => '_m',
 179              'medium' => '',
 180              'large' => '_b',
 181              'original' => '_o'
 182          );
 183  
 184          $size = strtolower($size);
 185          if (!array_key_exists($size, $sizes)) {
 186              $size = 'medium';
 187          }
 188  
 189          if ($size == 'original') {
 190              $url = 'http://farm' . $photo['farm'] . '.static.flickr.com/' . $photo['server'] . '/' . $photo['id'] . '_' . $photo['originalsecret'] . '_o' . '.' . $photo['originalformat'];
 191          } else {
 192              $url = 'http://farm' . $photo['farm'] . '.static.flickr.com/' . $photo['server'] . '/' . $photo['id'] . '_' . $photo['secret'] . $sizes[$size] . '.jpg';
 193          }
 194          return $url;
 195      }
 196  
 197      /**
 198       * Return the plugin config settings for external functions.
 199       *
 200       * @return stdClass the configs for both the block instance and plugin
 201       * @since Moodle 3.8
 202       */
 203      public function get_config_for_external() {
 204          // Return all settings for all users since it is safe (no private keys, etc..).
 205          $configs = !empty($this->config) ? $this->config : new stdClass();
 206  
 207          return (object) [
 208              'instance' => $configs,
 209              'plugin' => new stdClass(),
 210          ];
 211      }
 212  }
 213  
 214