block_tag_youtube.php 8.84 KB
Newer Older
1
<?php
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Tag youtube block
 *
 * @package    block_tag_youtube
 * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
24
25
26
27
28
29

define('DEFAULT_NUMBER_OF_VIDEOS', 5);

class block_tag_youtube extends block_base {

    function init() {
30
        $this->title = get_string('pluginname','block_tag_youtube');
31
32
33
34
35
36
37
    }

    function applicable_formats() {
        return array('tag' => true);
    }

    function specialization() {
38
        $this->title = !empty($this->config->title) ? $this->config->title : get_string('pluginname', 'block_tag_youtube');
39
40
41
        // Convert numeric categories (old YouTube API) to
        // textual ones (new Google Data API)
        $this->config->category = !empty($this->config->category) ? $this->category_map_old2new($this->config->category) : '0';
42
43
44
45
46
47
48
    }

    function instance_allow_multiple() {
        return true;
    }

    function get_content() {
49
50
51
52
53
        global $CFG;

        //note: do NOT include files at the top of this file
        require_once($CFG->dirroot.'/tag/lib.php');
        require_once($CFG->libdir . '/filelib.php');
54
55
56
57
58

        if ($this->content !== NULL) {
            return $this->content;
        }

59
        $text = '';
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
        if(!empty($this->config->playlist)){
            //videos from a playlist
            $text = $this->get_videos_by_playlist();
        }
        else{
            if(!empty($this->config->category)){
                //videos from category with tag
                $text = $this->get_videos_by_tag_and_category();
            }
            else {
                //videos with tag
                $text = $this->get_videos_by_tag();
            }
        }

        $this->content = new stdClass;
        $this->content->text = $text;
        $this->content->footer = '';

        return $this->content;
    }

    function get_videos_by_playlist(){

        $numberofvideos = DEFAULT_NUMBER_OF_VIDEOS;
        if( !empty($this->config->numberofvideos)) {
            $numberofvideos = $this->config->numberofvideos;
        }

89
90
91
92
93
        $request = 'http://gdata.youtube.com/feeds/api/playlists/' .
                   $this->config->playlist .
                   '?start-index=1&max-results=' .
                   $numberofvideos .
                   '&format=5';
94
95
96
97
98
99

        return $this->fetch_request($request);
    }

    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
102
103

        if ($tag) {
104
            $tagobject = tag_get('name', $tag);
105
        } else if ($tagid) {
106
            $tagobject = tag_get('id', $tagid);
107
108
        }

109
        if (empty($tagobject)) {
110
            return '';
111
        }
112

113
        $querytag = urlencode($tagobject->name);
114
115

        $numberofvideos = DEFAULT_NUMBER_OF_VIDEOS;
116
        if ( !empty($this->config->numberofvideos) ) {
117
118
119
            $numberofvideos = $this->config->numberofvideos;
        }

120
121
122
123
124
        $request = 'http://gdata.youtube.com/feeds/api/videos?vq=' .
                   $querytag .
                   '&start-index=1&max-results=' .
                   $numberofvideos .
                   '&format=5';
125
126
127
128
129
130

        return $this->fetch_request($request);
    }

    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
133
134

        if ($tag) {
135
            $tagobject = tag_get('name', $tag);
136
        } else if ($tagid) {
137
            $tagobject = tag_get('id', $tagid);
138
139
        }

140
        if (empty($tagobject)) {
141
            return '';
142
        }
143

144
        $querytag = urlencode($tagobject->name);
145
146
147
148
149
150

        $numberofvideos = DEFAULT_NUMBER_OF_VIDEOS;
        if( !empty($this->config->numberofvideos)) {
            $numberofvideos = $this->config->numberofvideos;
        }

151
        $request = 'http://gdata.youtube.com/feeds/api/videos?category=' .
152
                   $this->config->category .
153
154
155
156
157
158
                   '&vq=' .
                   $querytag .
                   '&start-index=1&max-results=' .
                   $numberofvideos .
                   '&format=5';

159

160
        return $this->fetch_request($request);
161
162
    }

163
    function fetch_request($request){
164
165
        $c = new curl(array('cache' => true, 'module_cache'=>'tag_youtube'));
        $c->setopt(array('CURLOPT_TIMEOUT' => 3, 'CURLOPT_CONNECTTIMEOUT' => 3));
166

167
        $response = $c->get($request);
168

169
170
        $xml = new SimpleXMLElement($response);
        return $this->render_video_list($xml);
171
    }
172

173
    function render_video_list(SimpleXMLElement $xml){
174
175

        $text = '';
176
        $text .= '<ul class="yt-video-entry unlist img-text">';
177

178
179
180
181
182
183
184
185
186
187
188
        foreach($xml->entry as $entry){
            $media = $entry->children('http://search.yahoo.com/mrss/');
            $playerattrs = $media->group->player->attributes();
            $url = s($playerattrs['url']);
            $thumbattrs = $media->group->thumbnail[0]->attributes();
            $thumbnail = s($thumbattrs['url']);
            $title = s($media->group->title);
            $yt = $media->children('http://gdata.youtube.com/schemas/2007');
            $secattrs = $yt->duration->attributes();
            $seconds = $secattrs['seconds'];

189
190
            $text .= '<li>';
            $text .= '<div class="clearfix">';
191
192
193
            $text .= '<a href="'. $url . '">';
            $text .= '<img alt="" class="youtube-thumb" src="'. $thumbnail .'" /></a>';
            $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
200
        return $text;
    }
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

    function get_categories() {
        // TODO: Right now using sticky categories from
        // http://gdata.youtube.com/schemas/2007/categories.cat
        // This should be performed from time to time by the block insead
        // and cached somewhere, avoiding deprecated ones and observing regions
        return array (
            '0' => get_string('anycategory', 'block_tag_youtube'),
            'Film'  => get_string('filmsanimation', 'block_tag_youtube'),
            'Autos' => get_string('autosvehicles', 'block_tag_youtube'),
            'Music' => get_string('music', 'block_tag_youtube'),
            'Animals'=> get_string('petsanimals', 'block_tag_youtube'),
            'Sports' => get_string('sports', 'block_tag_youtube'),
            'Travel' => get_string('travel', 'block_tag_youtube'),
            'Games'  => get_string('gadgetsgames', 'block_tag_youtube'),
            'Comedy' => get_string('comedy', 'block_tag_youtube'),
            'People' => get_string('peopleblogs', 'block_tag_youtube'),
            'News'   => get_string('newspolitics', 'block_tag_youtube'),
            'Entertainment' => get_string('entertainment', 'block_tag_youtube'),
            'Education' => get_string('education', 'block_tag_youtube'),
            'Howto'  => get_string('howtodiy', 'block_tag_youtube'),
            'Tech'   => get_string('scienceandtech', 'block_tag_youtube')
        );
    }

    /**
     * Provide conversion from old numeric categories available in youtube API
     * to the new ones available in the Google API
     *
     * @param int $oldcat old category code
     * @return mixed new category code or 0 (if no match found)
     *
     * TODO: Someday this should be applied on upgrade for all the existing
     * block instances so we won't need the mapping any more. That would imply
     * to implement restore handling to perform the conversion of old blocks.
     */
    function category_map_old2new($oldcat) {
        $oldoptions = array (
            0  => '0',
            1  => 'Film',
            2  => 'Autos',
            23 => 'Comedy',
            24 => 'Entertainment',
            10 => 'Music',
            25 => 'News',
            22 => 'People',
            15 => 'Animals',
            26 => 'Howto',
            17 => 'Sports',
            19 => 'Travel',
            20 => 'Games'
        );
        if (array_key_exists($oldcat, $oldoptions)) {
            return $oldoptions[$oldcat];
        } else {
            return $oldcat;
        }
    }
259
}
260