lib.php 20.2 KB
Newer Older
Penny Leach's avatar
Penny Leach committed
1
2
3
4
5
<?php
/**
 *
 * @package    mahara
 * @subpackage blocktype-internalmedia
6
 * @author     Catalyst IT Ltd
7
8
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
 * @copyright  For copyright information on Mahara, please see the README file distributed with this software.
Penny Leach's avatar
Penny Leach committed
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 */

defined('INTERNAL') || die();

class PluginBlocktypeInternalmedia extends PluginBlocktype {

    public static function get_title() {
        return get_string('title', 'blocktype.file/internalmedia');
    }

    public static function get_description() {
        return get_string('description', 'blocktype.file/internalmedia');
    }

    public static function get_categories() {
25
        return array('fileimagevideo' => 7000);
Penny Leach's avatar
Penny Leach committed
26
27
28
29
30
31
32
33
    }

    public static function has_config() {
        return true;
    }

    public static function postinst($oldversion) {
        if ($oldversion == 0) {
34
            set_config_plugin('blocktype', 'internalmedia', 'enabledtypes', serialize(array('flv', 'mp3')));
Penny Leach's avatar
Penny Leach committed
35
36
37
        }
    }

38
    public static function render_instance(BlockInstance $instance, $editing=false) {
Penny Leach's avatar
Penny Leach committed
39
        $configdata = $instance->get('configdata');
40
41
42
        $viewid = $instance->get('view');
        $artefactid = isset($configdata['artefactid']) ? $configdata['artefactid'] : null;
        if (empty($artefactid)) {
Penny Leach's avatar
Penny Leach committed
43
44
45
            return '';
        }
        $result = self::get_js_source();
46
        require_once(get_config('docroot') . 'artefact/lib.php');
47
        $artefact = $instance->get_artefact_instance($artefactid);
48
49
50
51
52
53
        $defaultwidth = get_config_plugin('blocktype', 'internalmedia', 'width') ?
                get_config_plugin('blocktype', 'internalmedia', 'width') : 300;
        $defaultheight = get_config_plugin('blocktype', 'internalmedia', 'height') ?
                get_config_plugin('blocktype', 'internalmedia', 'height') : 300;
        $width  = (!empty($configdata['width'])) ? hsc($configdata['width']) : $defaultwidth;
        $height = (!empty($configdata['height'])) ? hsc($configdata['height']) : $defaultheight;
54
55
56
        $mimetype = $artefact->get('filetype');
        $mimetypefiletypes = self::get_allowed_mimetype_filetypes();
        if (!isset($mimetypefiletypes[$mimetype])) {
57
            return get_string('typeremoved', 'blocktype.file/internalmedia');
Penny Leach's avatar
Penny Leach committed
58
        }
59
        $callbacks = self::get_all_filetype_players();
60
        $result .= '<div class="mediaplayer-container center"><div class="mediaplayer">' . call_static_method('PluginBlocktypeInternalmedia', $callbacks[$mimetypefiletypes[$mimetype]], $artefact, $instance, $width, $height) . '</div></div>';
61
62
63
64
65

        if ($artefactid) {
            require_once(get_config('docroot') . 'artefact/comment/lib.php');
            require_once(get_config('docroot') . 'lib/view.php');
            $view = new View($viewid);
66
            list($commentcount, $comments) = ArtefactTypeComment::get_artefact_comments_for_view($artefact, $view, $instance->get('id'), true, $editing);
67
68
69
70
71
72
73
74
        }
        $smarty = smarty_core();
        if ($artefactid) {
            $smarty->assign('commentcount', $commentcount);
            $smarty->assign('comments', $comments);
        }
        $smarty->assign('html', $result);
        return $smarty->fetch('blocktype:internalmedia:internalmedia.tpl');
Penny Leach's avatar
Penny Leach committed
75
76
77
78
79
80
    }

    public static function has_instance_config() {
        return true;
    }

Son Nguyen's avatar
Son Nguyen committed
81
    public static function get_instance_config_javascript(BlockInstance $instance) {
82
83
84
85
86
87
        $result = self::get_js_source(true);
        if (!empty($result)) {
            return $result;
        }
    }

Son Nguyen's avatar
Son Nguyen committed
88
    public static function instance_config_form(BlockInstance $instance) {
Penny Leach's avatar
Penny Leach committed
89
        $configdata = $instance->get('configdata');
90
91
92
        safe_require('artefact', 'file');
        $instance->set('artefactplugin', 'file');
        return array(
93
            'artefactid' => self::filebrowser_element($instance, (isset($configdata['artefactid'])) ? array($configdata['artefactid']) : null),
94
            'width' => array(
Penny Leach's avatar
Penny Leach committed
95
96
97
98
                'type' => 'text',
                'title' => get_string('width'),
                'size' => 3,
                'defaultvalue' => (isset($configdata['width'])) ? $configdata['width'] : '',
99
                'rules' => array('minvalue' => 1, 'maxvalue' => 2000),
100
101
            ),
            'height' => array(
Penny Leach's avatar
Penny Leach committed
102
103
104
105
                'type' => 'text',
                'title' => get_string('height'),
                'size' => 3,
                'defaultvalue' => (isset($configdata['height'])) ? $configdata['height'] : '',
106
                'rules' => array('minvalue' => 1, 'maxvalue' => 2000),
107
            ),
Penny Leach's avatar
Penny Leach committed
108
        );
109
110
    }

111
112
    public static function filebrowser_element(&$instance, $default=array()) {
        $element = ArtefactTypeFileBase::blockconfig_filebrowser_element($instance, $default);
113
        $element['title'] = get_string('media', 'blocktype.file/internalmedia');
114
        $element['name'] = 'artefactid';
115
116
        $element['config']['selectone'] = true;
        $element['filters'] = array(
117
            'artefacttype'    => array('file', 'audio', 'video'),
118
            'filetype'        => self::get_allowed_mimetypes(),
119
120
121
122
        );
        return $element;
    }

123
    public static function artefactchooser_element($default=null) {
Penny Leach's avatar
Penny Leach committed
124
125
126
127
128
129
130
131
        return array(
            'name' => 'artefactid',
            'type'  => 'artefactchooser',
            'title' => get_string('media', 'blocktype.file/internalmedia'),
            'defaultvalue' => $default,
            'blocktype' => 'internalmedia',
            'limit' => 5,
            'selectone' => true,
132
            'artefacttypes' => array('file', 'audio', 'video'),
Penny Leach's avatar
Penny Leach committed
133
134
135
136
            'template' => 'artefact:file:artefactchooser-element.tpl',
        );
    }

137
138
139
140
141
    public static function artefactchooser_get_element_data($artefact) {
        $artefact->icon = call_static_method(generate_artefact_class_name($artefact->artefacttype), 'get_icon', array('id' => $artefact->id));
        return $artefact;
    }

Son Nguyen's avatar
Son Nguyen committed
142
    public static function save_config_options(Pieform $form, $values) {
Penny Leach's avatar
Penny Leach committed
143
144
        $enabledtypes = array();
        foreach ($values as $type => $enabled) {
145
            if (!in_array($type, self::get_all_filetypes())) {
146
147
                continue;
            }
Penny Leach's avatar
Penny Leach committed
148
149
150
151
152
            if (!empty($enabled)) {
                $enabledtypes[] = $type;
            }
        }
        set_config_plugin('blocktype', 'internalmedia', 'enabledtypes', serialize($enabledtypes));
153
154
        set_config_plugin('blocktype', 'internalmedia', 'height', $values['height']);
        set_config_plugin('blocktype', 'internalmedia', 'width',  $values['width']);
Penny Leach's avatar
Penny Leach committed
155
156
157
158
159
160
    }

    public static function get_config_options() {
        $elements = array();
        // Allowed file types
        $filetypes = array();
161
        $currenttypes = self::get_allowed_filetypes();
Penny Leach's avatar
Penny Leach committed
162

163
        foreach (self::get_all_filetypes() as $filetype) {
164
            $filetypes[$filetype] = array(
165
                'type'  => 'switchbox',
166
167
168
                'title' => get_string($filetype, 'artefact.file'),
                'defaultvalue' => in_array($filetype, $currenttypes),
            );
Penny Leach's avatar
Penny Leach committed
169
170
        }
        uasort($filetypes, create_function('$a, $b', 'return $a["title"] > $b["title"];'));
171
        $options = array_merge(
Penny Leach's avatar
Penny Leach committed
172
173
            array(
                'description' => array(
174
                    'value' => get_string('configdesc1', 'blocktype.file/internalmedia'),
Penny Leach's avatar
Penny Leach committed
175
176
177
178
                ),
            ),
            $filetypes
        );
179
180
181
182
183
184
185
186
187
188
189
190
191
192
        $options['height'] = array(
            'type'          => 'text',
            'title'         => get_string('height'),
            'rules'        => array('integer' => true, 'minvalue' => 120, 'maxvalue' => 3072),
            'defaultvalue'  => get_config_plugin('blocktype', 'internalmedia', 'height')
                ? get_config_plugin('blocktype', 'internalmedia', 'height') : 240,
        );
        $options['width'] = array(
            'type'          => 'text',
            'title'         => get_string('width'),
            'rules'        => array('integer' => true, 'minvalue' => 160, 'maxvalue' => 4096),
            'defaultvalue'  => get_config_plugin('blocktype', 'internalmedia', 'width')
                ? get_config_plugin('blocktype', 'internalmedia', 'width') : 320,
        );
Penny Leach's avatar
Penny Leach committed
193
194

        return array(
195
            'elements' => $options,
Penny Leach's avatar
Penny Leach committed
196
197
198
199
            'renderer' => 'table'
        );
    }

200
201

    private static function get_allowed_filetypes() {
Penny Leach's avatar
Penny Leach committed
202
203
204
205
206
207
        if ($data = get_config_plugin('blocktype', 'internalmedia', 'enabledtypes')) {
            return unserialize($data);
        }
        return array();
    }

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

    private static function get_allowed_mimetypes() {
        return array_keys(self::get_allowed_mimetype_filetypes());
    }


    private static function get_allowed_mimetype_filetypes() {
        if ($data = self::get_allowed_filetypes()) {
            if ($mimetypes = get_records_sql_assoc('
                SELECT mimetype, description
                FROM {artefact_file_mime_types}
                WHERE description IN (' . join(',', array_map('db_quote', $data)) . ')', array())) {
                foreach ($mimetypes as &$m) {
                    $m = $m->description;
                }
223
224
225
226
227
228
229
230
                // Hack to allow .wmv and .wma files to also use the .asf mimetype as well
                // See http://en.wikipedia.org/wiki/Advanced_Systems_Format
                if (in_array('wmv', $data)) {
                    $mimetypes['video/x-ms-asf'] = 'wmv';
                }
                if (in_array('wma', $data)) {
                    $mimetypes['video/x-ms-asf'] = 'wma';
                }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
                return $mimetypes;
            }
        }
        return array();
    }


    private static function get_all_filetypes() {
        return array_keys(self::get_all_filetype_players());
    }


    private static function get_all_filetype_players() {
        /* Keyed by the file type descriptions from the artefact_file_mime_types table */
Penny Leach's avatar
Penny Leach committed
245
        return array(
246
            'mp3'       => 'flow_player', // tested
247
            'swf'       => 'flash_player', // tested
248
            'flv'       => 'flow_player', // tested
249
250
251
252
            'quicktime' => 'qt_player',  // tested
            'wmv'       => 'wmp_player', // tested
            'mpeg'      => 'qt_player',  // tested
            'avi'       => 'wmp_player', // tested
253
            'mp4_video' => 'flow_player', // tested
254
            /* commenting out for now
Penny Leach's avatar
Penny Leach committed
255
256
257
            'ram'   => 'real_player',
            'rm'    => 'real_player',
            'rpm'   => 'real_player',
258
            */
Penny Leach's avatar
Penny Leach committed
259
260
261
262
263
264
265
266
        );
    }

    public static function flash_player($artefact, $block, $width, $height) {
        static $count = 0;
        $count++;
        $id = 'blocktype_internalmedia_flash_' . time() . $count;
        $url = self::get_download_link($artefact, $block);
267
268
269
270
        $params = array('play' => 'true',
                        'allowscriptaccess' => 'never',
                        'allownetworking' => 'never'
                       );
271
        $html =  '<a href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>
272
               <span class="blocktype_internalmedia_mp3" id="' . $id . '">('
273
               . get_string('flashanimation', 'blocktype.file/internalmedia') . ')</span>
274
                <script type="application/javascript">
275
                    var so = new SWFObject("' . $url . '&embedded=1","player","' . $width . '","' . ($height + 20). '","7");
Penny Leach's avatar
Penny Leach committed
276
277
                    so.addParam("allowfullscreen","false");
                    so.addVariable("displayheight"," ' . $height . '");
278
                    so.addVariable("type", "swf");
Penny Leach's avatar
Penny Leach committed
279
280
                    so.addVariable("height", "' . $height . '");
                    so.addVariable("width", "' . $width . '");
281
                    so.addVariable("wmode", "transparent");
Penny Leach's avatar
Penny Leach committed
282
283
284
285
286
287
288
289
290
291
292
293
294
                ';
        foreach ($params as $key => $value) {
            $html .= '      so.addParam("' . $key . '", "' . $value . '"); '. "\n";
        }

        $html .= '
                    so.write("' . $id . '");
                </script>
        ';
        return $html;

    }

295
296
297
298
299
300
301
    public static function flow_player($artefact, $block, $width, $height) {
        static $count = 0;
        $count++;
        $extn = $artefact->get('oldextension');

        $id = 'blocktype_internalmedia_flow_' . time() . $count;
        $url = self::get_download_link($artefact, $block);
302
        $url = parse_url($url, PHP_URL_PATH) . '?' . parse_url($url, PHP_URL_QUERY);
303
        $escapedurl = str_replace('&', '%26', $url); // Flash needs these escaped
304

305
306
        $baseurlpath = parse_url(get_config('wwwroot'), PHP_URL_PATH);
        $baseurl = $baseurlpath . 'artefact/file/blocktype/internalmedia/';
307

308
        $playerurl = $baseurl . 'mahara-flashplayer/mahara-flashplayer.swf';
309
310
311
312
313
314
315
316
317
318
        $autohide = 'true';
        $type = '';
        $audio = '';
        $buffering = 'true';
        if ($extn == 'mp3') {
            $height = 25; // only show the controls
            $autohide = 'false';
            $type = 'type: "audio",'; // force the player to use the audio plugin
            $buffering = 'false'; // without this autoPlay will also be set to true
            $audio = ', audio: {
319
		                  url: "' . $baseurl . 'flowplayer.audio/flowplayer.audio-3.2.11.swf"
320
321
322
323
		             }';
        }

        $html =  '<a href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>
324
325
               <span class="blocktype_internalmedia_mp3" id="' . $id . '" style="display:block;width:'.$width.'px;height:'.$height.'px;"></span>
               <span id="' . $id . '_h">' . get_string('flashanimation', 'blocktype.file/internalmedia') . '</span>
326
               <script type="application/javascript">
327
328
               flowplayer("'.$id.'", "'.$playerurl.'", {
                   clip:  {
329
                       url: "'.$escapedurl.'",
330
331
332
333
334
335
                       '.$type.'
                       autoPlay: false,
                       autoBuffering: '.$buffering.'
                   },
                   plugins: {
	                  controls: {
336
                          url: "mahara-flashplayer.controls.swf",
337
338
339
340
341
342
                          play:true,
                          volume:true,
                          mute:true,
                          time:false,
                          stop:false,
                          playlist:false,
343
                          fullscreen:true,
344
345
346
347
348
                          scrubber: true,
                          autoHide: '.$autohide.'
                      }'.$audio.'
                   }
               }).load();
349
               addElementClass("' . $id . '_h", "hidden");
350
351
352
353
354
355
               </script>
';
        return $html;

    }

Penny Leach's avatar
Penny Leach committed
356
357
358
359
360
    public static function real_player($artefact, $block, $width, $height) {

        $url = self::get_download_link($artefact, $block);

        require_once('file.php');
361
        $mimetype = $artefact->get('filetype');
Penny Leach's avatar
Penny Leach committed
362
363
        $autostart = 'false';

364
        return '<a href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>'
Penny Leach's avatar
Penny Leach committed
365
    . '<span class="blocktype_internalmedia_real">
366
    <script type="application/javascript">
Penny Leach's avatar
Penny Leach committed
367
368
    //<![CDATA[
    document.write(\'<object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="180">\\
369
370
371
372
373
374
375
      <param name="src" value="' . $url . '">\\
      <param name="autostart" value="' . $autostart . '">\\
      <param name="controls" value="imagewindow">\\
      <param name="console" value="video">\\
      <param name="loop" value="true">\\
      <embed src="' . $url . '" width=240" height="180" loop="true" type="' . $mimetype . '" controls="imagewindow" console="video" autostart="' . $autostart . '">\\
      </object><br>\\
Penny Leach's avatar
Penny Leach committed
376
      <object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="30">\\
377
378
379
380
381
      <param name="src" value="' . $url . '">\\
      <param name="autostart" value="' . $autostart . '">\\
      <param name="controls" value="ControlPanel">\\
      <param name="console" value="video">\\
      <embed src="' . $url . '" width="240" height="30" controls="ControlPanel" type="' . $mimetype . '" console="video" autostart="' . $autostart . '">\\
Penny Leach's avatar
Penny Leach committed
382
383
384
385
386
387
388
      </object>\');
    //]]>
    </script></span>';
    }

    public static function wmp_player($artefact, $block, $width, $height) {

389
        $url = hsc(self::get_download_link($artefact, $block));
Penny Leach's avatar
Penny Leach committed
390
391
392
393
394
395
396

        $size = 'width="' . $width . '" height="' . $height . '"';
        $autosize = 'false';

        $mimetype = 'video/x-ms-wmv'; // hardcode this
        $autostart = 'false';

397
        return '<a href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>'
Penny Leach's avatar
Penny Leach committed
398
399
400
401
    . '<span class="mediaplugin mediaplugin_wmp">
    <object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" ' . $size . '
      standby="Loading Microsoft(R) Windows(R) Media Player components..."
      type="application/x-oleobject">
402
403
404
405
406
407
408
409
410
411
412
413
     <param name="Filename" value="' . $url . '">' /* hsc($artefact->get('title')) . '"> */ . '
     <param name="src" value="' . $url . '">
     <param name="url" value="' . $url . '">
     <param name="ShowControls" value="true">
     <param name="AutoRewind" value="true">
     <param name="AutoStart" value="' . $autostart . '">
     <param name="Autosize" value="' . $autosize . '">
     <param name="EnableContextMenu" value="true">
     <param name="TransparentAtStart" value="false">
     <param name="AnimationAtStart" value="false">
     <param name="ShowGotoBar" value="false">
     <param name="EnableFullScreenControls" value="true">
414
     <param name="Wmode" value="opaque">
Penny Leach's avatar
Penny Leach committed
415
416
    <!--[if !IE]>-->
      <object data="' . $url . '" type="' . $mimetype . '" ' . $size . '>
417
418
419
420
421
422
       <param name="src" value="' . $url . '">
       <param name="url" value="' . $url . '">
       <param name="controller" value="true">
       <param name="autoplay" value="' . $autostart . '">
       <param name="autostart" value="' . $autostart . '">
       <param name="resize" value="scale">
423
       <param name="wmode" value="opaque">
Penny Leach's avatar
Penny Leach committed
424
425
426
427
428
429
430
431
432
433
434
435
      </object>
    <!--<![endif]-->
    </object></span>';
    }

    public static function qt_player($artefact, $block, $width, $height) {

        $url = self::get_download_link($artefact, $block);

        $size = 'width="' . $width . '" height="' . $height . '"';

        require_once('file.php');
436
        $mimetype = $artefact->get('filetype');
Penny Leach's avatar
Penny Leach committed
437
438
        $autostart = 'false';

439
        return '<a href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>'
Penny Leach's avatar
Penny Leach committed
440
441
442
    . '<span class="mediaplugin mediaplugin_qt">
    <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
      codebase="http://www.apple.com/qtactivex/qtplugin.cab" ' . $size . '>
443
444
     <param name="pluginspage" value="http://www.apple.com/quicktime/download/">
     <param name="src" value="' . $url . '">
445
     <param name="controller" value="true">
446
447
448
449
     <param name="loop" value="false">
     <param name="autoplay" value="' . $autostart . '">
     <param name="autostart" value="' . $autostart . '">
     <param name="scale" value="aspect">
Penny Leach's avatar
Penny Leach committed
450
451
    <!--[if !IE]>-->
      <object data="' . $url . '" type="' . $mimetype . '" ' . $size . '>
452
453
454
455
456
457
458
       <param name="src" value="'.$url.'">
       <param name="pluginurl" value="http://www.apple.com/quicktime/download/">
       <param name="controller" value="true">
       <param name="loop" value="false">
       <param name="autoplay" value="' . $autostart . '">
       <param name="autostart" value="' . $autostart . '">
       <param name="scale" value="aspect">
459
       <param name="wmode" value="transparent">
Penny Leach's avatar
Penny Leach committed
460
461
462
463
464
      </object>
    <!--<![endif]-->
    </object></span>';
    }

465
    private static function get_download_link(ArtefactTypeFile $artefact, BlockInstance $instance) {
466
        return get_config('wwwroot') . 'artefact/file/download.php?file='
467
            . $artefact->get('id') . '&view=' . $instance->get('view');
Penny Leach's avatar
Penny Leach committed
468
469
    }

470
    private static function get_js_source($asarray = false) {
Penny Leach's avatar
Penny Leach committed
471
472
473
474
        if (defined('BLOCKTYPE_INTERNALMEDIA_JS_INCLUDED')) {
            return '';
        }
        define('BLOCKTYPE_INTERNALMEDIA_JS_INCLUDED', true);
475
        if ($asarray) {
476
            return array(get_config('wwwroot').'artefact/file/blocktype/internalmedia/mahara-flashplayer/mahara-flashplayer.js',
477
478
479
                         get_config('wwwroot') . 'artefact/file/blocktype/internalmedia/swfobject.js',
                         );
        }
480
        return '<script src="'.get_config('wwwroot').'artefact/file/blocktype/internalmedia/mahara-flashplayer/mahara-flashplayer.js"></script>
481
             <script src="' . get_config('wwwroot') . 'artefact/file/blocktype/internalmedia/swfobject.js" type="application/javascript"></script>';
Penny Leach's avatar
Penny Leach committed
482
483
    }

484
485
486
487
    public static function default_copy_type() {
        return 'full';
    }

Penny Leach's avatar
Penny Leach committed
488
}