a06588e5e98dc5c41e4e310490feba9aa105ebca
[moodle.git] / blocks / tag_youtube / block_tag_youtube.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  * Tag youtube block
19  *
20  * @package    block_tag_youtube
21  * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 define('DEFAULT_NUMBER_OF_VIDEOS', 5);
27 class block_tag_youtube extends block_base {
29     function init() {
30         $this->title = get_string('pluginname','block_tag_youtube');
31     }
33     function applicable_formats() {
34         return array('tag' => true);
35     }
37     function specialization() {
38         $this->title = !empty($this->config->title) ? $this->config->title : get_string('pluginname', 'block_tag_youtube');
39         // Convert numeric categories (old YouTube API) to
40         // textual ones (new Google Data API)
41         $this->config->category = !empty($this->config->category) ? $this->category_map_old2new($this->config->category) : '0';
42     }
44     function instance_allow_multiple() {
45         return true;
46     }
48     function get_content() {
49         global $CFG;
51         //note: do NOT include files at the top of this file
52         require_once($CFG->dirroot.'/tag/lib.php');
53         require_once($CFG->libdir . '/filelib.php');
55         if ($this->content !== NULL) {
56             return $this->content;
57         }
59         $text = '';
60         if(!empty($this->config->playlist)){
61             //videos from a playlist
62             $text = $this->get_videos_by_playlist();
63         }
64         else{
65             if(!empty($this->config->category)){
66                 //videos from category with tag
67                 $text = $this->get_videos_by_tag_and_category();
68             }
69             else {
70                 //videos with tag
71                 $text = $this->get_videos_by_tag();
72             }
73         }
75         $this->content = new stdClass;
76         $this->content->text = $text;
77         $this->content->footer = '';
79         return $this->content;
80     }
82     function get_videos_by_playlist(){
84         $numberofvideos = DEFAULT_NUMBER_OF_VIDEOS;
85         if( !empty($this->config->numberofvideos)) {
86             $numberofvideos = $this->config->numberofvideos;
87         }
89         $request = 'http://gdata.youtube.com/feeds/api/playlists/' .
90                    $this->config->playlist .
91                    '?start-index=1&max-results=' .
92                    $numberofvideos .
93                    '&format=5';
95         return $this->fetch_request($request);
96     }
98     function get_videos_by_tag(){
100         $tagid = optional_param('id', 0, PARAM_INT);   // tag id - for backware compatibility
101         $tag = optional_param('tag', '', PARAM_TAG); // tag
103         if ($tag) {
104             $tagobject = tag_get('name', $tag);
105         } else if ($tagid) {
106             $tagobject = tag_get('id', $tagid);
107         }
109         if (empty($tagobject)) {
110             return '';
111         }
113         $querytag = urlencode($tagobject->name);
115         $numberofvideos = DEFAULT_NUMBER_OF_VIDEOS;
116         if ( !empty($this->config->numberofvideos) ) {
117             $numberofvideos = $this->config->numberofvideos;
118         }
120         $request = 'http://gdata.youtube.com/feeds/api/videos?vq=' .
121                    $querytag .
122                    '&start-index=1&max-results=' .
123                    $numberofvideos .
124                    '&format=5';
126         return $this->fetch_request($request);
127     }
129     function get_videos_by_tag_and_category(){
131         $tagid = optional_param('id', 0, PARAM_INT);   // tag id - for backware compatibility
132         $tag = optional_param('tag', '', PARAM_TAG); // tag
134         if ($tag) {
135             $tagobject = tag_get('name', $tag);
136         } else if ($tagid) {
137             $tagobject = tag_get('id', $tagid);
138         }
140         if (empty($tagobject)) {
141             return '';
142         }
144         $querytag = urlencode($tagobject->name);
146         $numberofvideos = DEFAULT_NUMBER_OF_VIDEOS;
147         if( !empty($this->config->numberofvideos)) {
148             $numberofvideos = $this->config->numberofvideos;
149         }
151         $request = 'http://gdata.youtube.com/feeds/api/videos?category=' .
152                    $this->config->category .
153                    '&vq=' .
154                    $querytag .
155                    '&start-index=1&max-results=' .
156                    $numberofvideos .
157                    '&format=5';
160         return $this->fetch_request($request);
161     }
163     function fetch_request($request){
164         $c = new curl(array('cache' => true, 'module_cache'=>'tag_youtube'));
165         $c->setopt(array('CURLOPT_TIMEOUT' => 3, 'CURLOPT_CONNECTTIMEOUT' => 3));
167         $response = $c->get($request);
169         $xml = new SimpleXMLElement($response);
170         return $this->render_video_list($xml);
171     }
173     function render_video_list(SimpleXMLElement $xml){
175         $text = '';
176         $text .= '<ul class="yt-video-entry unlist img-text">';
178         foreach($xml->entry as $entry){
179             $media = $entry->children('http://search.yahoo.com/mrss/');
180             $playerattrs = $media->group->player->attributes();
181             $url = s($playerattrs['url']);
182             $thumbattrs = $media->group->thumbnail[0]->attributes();
183             $thumbnail = s($thumbattrs['url']);
184             $title = s($media->group->title);
185             $yt = $media->children('http://gdata.youtube.com/schemas/2007');
186             $secattrs = $yt->duration->attributes();
187             $seconds = $secattrs['seconds'];
189             $text .= '<li>';
190             $text .= '<div class="clearfix">';
191             $text .= '<a href="'. $url . '">';
192             $text .= '<img alt="" class="youtube-thumb" src="'. $thumbnail .'" /></a>';
193             $text .= '</div><span><a href="'. $url . '">'. $title .'</a></span>';
194             $text .= '<div>';
195             $text .= format_time($seconds);
196             $text .= "</div></li>\n";
197         }
198         $text .= "</ul><div class=\"clearer\"></div>\n";
199         return $text;
200     }
202     function get_categories() {
203         // TODO: Right now using sticky categories from
204         // http://gdata.youtube.com/schemas/2007/categories.cat
205         // This should be performed from time to time by the block insead
206         // and cached somewhere, avoiding deprecated ones and observing regions
207         return array (
208             '0' => get_string('anycategory', 'block_tag_youtube'),
209             'Film'  => get_string('filmsanimation', 'block_tag_youtube'),
210             'Autos' => get_string('autosvehicles', 'block_tag_youtube'),
211             'Music' => get_string('music', 'block_tag_youtube'),
212             'Animals'=> get_string('petsanimals', 'block_tag_youtube'),
213             'Sports' => get_string('sports', 'block_tag_youtube'),
214             'Travel' => get_string('travel', 'block_tag_youtube'),
215             'Games'  => get_string('gadgetsgames', 'block_tag_youtube'),
216             'Comedy' => get_string('comedy', 'block_tag_youtube'),
217             'People' => get_string('peopleblogs', 'block_tag_youtube'),
218             'News'   => get_string('newspolitics', 'block_tag_youtube'),
219             'Entertainment' => get_string('entertainment', 'block_tag_youtube'),
220             'Education' => get_string('education', 'block_tag_youtube'),
221             'Howto'  => get_string('howtodiy', 'block_tag_youtube'),
222             'Tech'   => get_string('scienceandtech', 'block_tag_youtube')
223         );
224     }
226     /**
227      * Provide conversion from old numeric categories available in youtube API
228      * to the new ones available in the Google API
229      *
230      * @param int $oldcat old category code
231      * @return mixed new category code or 0 (if no match found)
232      *
233      * TODO: Someday this should be applied on upgrade for all the existing
234      * block instances so we won't need the mapping any more. That would imply
235      * to implement restore handling to perform the conversion of old blocks.
236      */
237     function category_map_old2new($oldcat) {
238         $oldoptions = array (
239             0  => '0',
240             1  => 'Film',
241             2  => 'Autos',
242             23 => 'Comedy',
243             24 => 'Entertainment',
244             10 => 'Music',
245             25 => 'News',
246             22 => 'People',
247             15 => 'Animals',
248             26 => 'Howto',
249             17 => 'Sports',
250             19 => 'Travel',
251             20 => 'Games'
252         );
253         if (array_key_exists($oldcat, $oldoptions)) {
254             return $oldoptions[$oldcat];
255         } else {
256             return $oldcat;
257         }
258     }