lib.php 21 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 panel-body"><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
        safe_require('artefact', 'file');
        $instance->set('artefactplugin', 'file');
92
        $filebrowser = self::filebrowser_element($instance, (isset($configdata['artefactid'])) ? array($configdata['artefactid']) : null);
93
        return array(
94
95
96
97
98
99
100
101
102
103
            'artefactfieldset' => array(
                'type'         => 'fieldset',
                'collapsible'  => true,
                'collapsed'    => true,
                'legend'       => get_string('media', 'blocktype.file/internalmedia'),
                'class'        => 'last select-file mtl',
                'elements'     => array(
                    'artefactid' => $filebrowser
                )
            ),
104
            'width' => array(
Penny Leach's avatar
Penny Leach committed
105
106
107
108
                'type' => 'text',
                'title' => get_string('width'),
                'size' => 3,
                'defaultvalue' => (isset($configdata['width'])) ? $configdata['width'] : '',
109
                'rules' => array('minvalue' => 1, 'maxvalue' => 2000),
110
111
            ),
            'height' => array(
Penny Leach's avatar
Penny Leach committed
112
113
114
115
                'type' => 'text',
                'title' => get_string('height'),
                'size' => 3,
                'defaultvalue' => (isset($configdata['height'])) ? $configdata['height'] : '',
116
                'rules' => array('minvalue' => 1, 'maxvalue' => 2000),
117
            ),
Penny Leach's avatar
Penny Leach committed
118
        );
119
120
    }

121
122
    public static function filebrowser_element(&$instance, $default=array()) {
        $element = ArtefactTypeFileBase::blockconfig_filebrowser_element($instance, $default);
123
        $element['title'] = get_string('media', 'blocktype.file/internalmedia');
124
        $element['name'] = 'artefactid';
125
126
        $element['config']['selectone'] = true;
        $element['filters'] = array(
127
            'artefacttype'    => array('file', 'audio', 'video'),
128
            'filetype'        => self::get_allowed_mimetypes(),
129
130
131
132
        );
        return $element;
    }

133
    public static function artefactchooser_element($default=null) {
Penny Leach's avatar
Penny Leach committed
134
135
136
137
138
139
140
141
        return array(
            'name' => 'artefactid',
            'type'  => 'artefactchooser',
            'title' => get_string('media', 'blocktype.file/internalmedia'),
            'defaultvalue' => $default,
            'blocktype' => 'internalmedia',
            'limit' => 5,
            'selectone' => true,
142
            'artefacttypes' => array('file', 'audio', 'video'),
Penny Leach's avatar
Penny Leach committed
143
144
145
146
            'template' => 'artefact:file:artefactchooser-element.tpl',
        );
    }

147
148
149
150
151
    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
152
    public static function save_config_options(Pieform $form, $values) {
Penny Leach's avatar
Penny Leach committed
153
154
        $enabledtypes = array();
        foreach ($values as $type => $enabled) {
155
            if (!in_array($type, self::get_all_filetypes())) {
156
157
                continue;
            }
Penny Leach's avatar
Penny Leach committed
158
159
160
161
162
            if (!empty($enabled)) {
                $enabledtypes[] = $type;
            }
        }
        set_config_plugin('blocktype', 'internalmedia', 'enabledtypes', serialize($enabledtypes));
163
164
        set_config_plugin('blocktype', 'internalmedia', 'height', $values['height']);
        set_config_plugin('blocktype', 'internalmedia', 'width',  $values['width']);
Penny Leach's avatar
Penny Leach committed
165
166
167
168
169
170
    }

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

173
        foreach (self::get_all_filetypes() as $filetype) {
174
            $filetypes[$filetype] = array(
175
                'type'  => 'switchbox',
176
177
178
                'title' => get_string($filetype, 'artefact.file'),
                'defaultvalue' => in_array($filetype, $currenttypes),
            );
Penny Leach's avatar
Penny Leach committed
179
180
        }
        uasort($filetypes, create_function('$a, $b', 'return $a["title"] > $b["title"];'));
181
        $options = array_merge(
Penny Leach's avatar
Penny Leach committed
182
183
            array(
                'description' => array(
184
                    'value' => get_string('configdesc1', 'blocktype.file/internalmedia'),
Penny Leach's avatar
Penny Leach committed
185
186
187
188
                ),
            ),
            $filetypes
        );
189
190
191
192
193
194
195
196
197
198
199
200
201
202
        $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
203
204

        return array(
205
            'elements' => $options,
Penny Leach's avatar
Penny Leach committed
206
207
208
209
            'renderer' => 'table'
        );
    }

210
211

    private static function get_allowed_filetypes() {
Penny Leach's avatar
Penny Leach committed
212
213
214
215
216
217
        if ($data = get_config_plugin('blocktype', 'internalmedia', 'enabledtypes')) {
            return unserialize($data);
        }
        return array();
    }

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

    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;
                }
233
234
235
236
237
238
239
240
                // 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';
                }
241
242
243
244
245
246
247
248
249
250
251
252
253
254
                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
255
        return array(
256
            'mp3'       => 'flow_player', // tested
257
            'swf'       => 'flash_player', // tested
258
            'flv'       => 'flow_player', // tested
259
260
261
262
            'quicktime' => 'qt_player',  // tested
            'wmv'       => 'wmp_player', // tested
            'mpeg'      => 'qt_player',  // tested
            'avi'       => 'wmp_player', // tested
263
            'mp4_video' => 'flow_player', // tested
264
            /* commenting out for now
Penny Leach's avatar
Penny Leach committed
265
266
267
            'ram'   => 'real_player',
            'rm'    => 'real_player',
            'rpm'   => 'real_player',
268
            */
Penny Leach's avatar
Penny Leach committed
269
270
271
272
273
274
275
276
        );
    }

    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);
277
278
279
280
        $params = array('play' => 'true',
                        'allowscriptaccess' => 'never',
                        'allownetworking' => 'never'
                       );
281
        $html =  '<a class="media-link" href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>
282
               <span class="blocktype_internalmedia_mp3" id="' . $id . '">('
283
               . get_string('flashanimation', 'blocktype.file/internalmedia') . ')</span>
284
                <script type="application/javascript">
285
                    var so = new SWFObject("' . $url . '&embedded=1","player","' . $width . '","' . ($height + 20). '","7");
Penny Leach's avatar
Penny Leach committed
286
287
                    so.addParam("allowfullscreen","false");
                    so.addVariable("displayheight"," ' . $height . '");
288
                    so.addVariable("type", "swf");
Penny Leach's avatar
Penny Leach committed
289
290
                    so.addVariable("height", "' . $height . '");
                    so.addVariable("width", "' . $width . '");
291
                    so.addVariable("wmode", "transparent");
Penny Leach's avatar
Penny Leach committed
292
293
294
295
296
297
298
299
300
301
302
303
304
                ';
        foreach ($params as $key => $value) {
            $html .= '      so.addParam("' . $key . '", "' . $value . '"); '. "\n";
        }

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

    }

305
306
307
308
309
310
311
    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);
312
        $url = parse_url($url, PHP_URL_PATH) . '?' . parse_url($url, PHP_URL_QUERY);
313
        $escapedurl = str_replace('&', '%26', $url); // Flash needs these escaped
314

315
316
        $baseurlpath = parse_url(get_config('wwwroot'), PHP_URL_PATH);
        $baseurl = $baseurlpath . 'artefact/file/blocktype/internalmedia/';
317

318
        $playerurl = $baseurl . 'mahara-flashplayer/mahara-flashplayer.swf';
319
        $filesize = round($artefact->get('size') / 1000000, 2) . 'MB';
320
321
322
323
324
325
326
327
328
329
        $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: {
330
		                  url: "' . $baseurl . 'flowplayer.audio/flowplayer.audio-3.2.11.swf"
331
332
333
		             }';
        }

334
335
336
337
338
        $html =  '<span class="blocktype_internalmedia_mp3" id="' . $id . '" style="display:block;width:'.$width.'px;height:'.$height.'px;"></span>';
        $html .= '<span id="' . $id . '_h">' . get_string('flashanimation', 'blocktype.file/internalmedia') . '</span>';
        $html .= '<div class="ptm"><span class="fa fa-download prs"></span><span class="sr-only">'.get_string('Download', 'artefact.internal').'</span><a class="media-link" href="' . $url . '">' . hsc($artefact->get('title')) . '</a>';
        $html .= '<span class="text-muted"> ['.$filesize.'] </span></div>';
        $html .= '<script type="application/javascript">
339
340
               flowplayer("'.$id.'", "'.$playerurl.'", {
                   clip:  {
341
                       url: "'.$escapedurl.'",
342
343
344
345
346
347
                       '.$type.'
                       autoPlay: false,
                       autoBuffering: '.$buffering.'
                   },
                   plugins: {
	                  controls: {
348
                          url: "mahara-flashplayer.controls.swf",
349
350
351
352
353
354
                          play:true,
                          volume:true,
                          mute:true,
                          time:false,
                          stop:false,
                          playlist:false,
355
                          fullscreen:true,
356
357
358
359
360
                          scrubber: true,
                          autoHide: '.$autohide.'
                      }'.$audio.'
                   }
               }).load();
361
               addElementClass("' . $id . '_h", "hidden");
362
363
364
365
366
367
               </script>
';
        return $html;

    }

Penny Leach's avatar
Penny Leach committed
368
369
370
371
372
    public static function real_player($artefact, $block, $width, $height) {

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

        require_once('file.php');
373
        $mimetype = $artefact->get('filetype');
Penny Leach's avatar
Penny Leach committed
374
375
        $autostart = 'false';

376
        return '<a class="media-link" href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>'
Penny Leach's avatar
Penny Leach committed
377
    . '<span class="blocktype_internalmedia_real">
378
    <script type="application/javascript">
Penny Leach's avatar
Penny Leach committed
379
380
    //<![CDATA[
    document.write(\'<object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="180">\\
381
382
383
384
385
386
387
      <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
388
      <object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="30">\\
389
390
391
392
393
      <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
394
395
396
397
398
399
400
      </object>\');
    //]]>
    </script></span>';
    }

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

401
        $url = hsc(self::get_download_link($artefact, $block));
Penny Leach's avatar
Penny Leach committed
402
403
404
405
406
407
408

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

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

409
        return '<a class="media-link" href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>'
Penny Leach's avatar
Penny Leach committed
410
411
412
413
    . '<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">
414
415
416
417
418
419
420
421
422
423
424
425
     <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">
426
     <param name="Wmode" value="opaque">
Penny Leach's avatar
Penny Leach committed
427
428
    <!--[if !IE]>-->
      <object data="' . $url . '" type="' . $mimetype . '" ' . $size . '>
429
430
431
432
433
434
       <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">
435
       <param name="wmode" value="opaque">
Penny Leach's avatar
Penny Leach committed
436
437
438
439
440
441
442
443
444
445
446
447
      </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');
448
        $mimetype = $artefact->get('filetype');
Penny Leach's avatar
Penny Leach committed
449
450
        $autostart = 'false';

451
        return '<a class="media-link" href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>'
Penny Leach's avatar
Penny Leach committed
452
453
454
    . '<span class="mediaplugin mediaplugin_qt">
    <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
      codebase="http://www.apple.com/qtactivex/qtplugin.cab" ' . $size . '>
455
456
     <param name="pluginspage" value="http://www.apple.com/quicktime/download/">
     <param name="src" value="' . $url . '">
457
     <param name="controller" value="true">
458
459
460
461
     <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
462
463
    <!--[if !IE]>-->
      <object data="' . $url . '" type="' . $mimetype . '" ' . $size . '>
464
465
466
467
468
469
470
       <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">
471
       <param name="wmode" value="transparent">
Penny Leach's avatar
Penny Leach committed
472
473
474
475
476
      </object>
    <!--<![endif]-->
    </object></span>';
    }

477
    private static function get_download_link(ArtefactTypeFile $artefact, BlockInstance $instance) {
478
        return get_config('wwwroot') . 'artefact/file/download.php?file='
479
            . $artefact->get('id') . '&view=' . $instance->get('view');
Penny Leach's avatar
Penny Leach committed
480
481
    }

482
    private static function get_js_source($asarray = false) {
Penny Leach's avatar
Penny Leach committed
483
484
485
486
        if (defined('BLOCKTYPE_INTERNALMEDIA_JS_INCLUDED')) {
            return '';
        }
        define('BLOCKTYPE_INTERNALMEDIA_JS_INCLUDED', true);
487
        if ($asarray) {
488
            return array(get_config('wwwroot').'artefact/file/blocktype/internalmedia/mahara-flashplayer/mahara-flashplayer.js',
489
490
491
                         get_config('wwwroot') . 'artefact/file/blocktype/internalmedia/swfobject.js',
                         );
        }
492
        return '<script src="'.get_config('wwwroot').'artefact/file/blocktype/internalmedia/mahara-flashplayer/mahara-flashplayer.js"></script>
493
             <script src="' . get_config('wwwroot') . 'artefact/file/blocktype/internalmedia/swfobject.js" type="application/javascript"></script>';
Penny Leach's avatar
Penny Leach committed
494
495
    }

496
497
498
499
    public static function default_copy_type() {
        return 'full';
    }

Penny Leach's avatar
Penny Leach committed
500
}