lib.php 19.6 KB
Newer Older
1
2
3
4
5
6
<?php
/**
 *
 * @package    mahara
 * @subpackage blocktype-googleapps
 * @author     Gregor Anželj
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.
9
10
11
12
13
14
 * @copyright  (C) 2010 Gregor Anželj, gregor.anzelj@gmail.com
 *
 */

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

15
class PluginBlocktypeGoogleApps extends MaharaCoreBlocktype {
16
17
18
19
20
21
22
23
24
25
26
27

    private static $default_height = 500;

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

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

    public static function get_categories() {
28
        return array('external' => 36000);
29
30
    }

31
32
33
34
    public static function get_blocktype_type_content_types() {
        return array('googleapps' => array('media'));
    }

35
    public static function render_instance(BlockInstance $instance, $editing=false, $versioning=false) {
36
37
38
39
40
41
42
        $configdata = $instance->get('configdata');
        if (!isset($configdata['appsid'])) {
            return;
        }
        $apps = self::make_apps_url($configdata['appsid']);
        $url    = hsc($apps['url']);
        $type   = hsc($apps['type']);
43
        $height = (!empty($configdata['height'])) ? intval($configdata['height']) : self::$default_height;
44

45
        if (isset($configdata['appsid']) && !empty($type)) {
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
            $smarty = smarty_core();
            $smarty->assign('url', $apps['url']);
            switch ($type) {
                case 'iframe':
                    // Google Docs (documents, presentations, spreadsheets, forms), Google Calendar, Google Maps
                    $smarty->assign('height', $height);
                    return $smarty->fetch('blocktype:googleapps:iframe.tpl');
                case 'spanicon':
                    // Google Docs collections (folder icon)
                    $smarty->assign('img', get_config('wwwroot') . 'blocktype/googleapps/images/folder_documents.png');
                    return $smarty->fetch('blocktype:googleapps:spanicon.tpl');
                case 'image':
                    // Google Docs drawing
                    $smarty->assign('height', $height);
                    return $smarty->fetch('blocktype:googleapps:image.tpl');
            }
        }

64
        return get_string('badurlerror', 'blocktype.googleapps', $url);
65
66
67
68
69
70
    }

    public static function has_instance_config() {
        return true;
    }

Son Nguyen's avatar
Son Nguyen committed
71
    public static function instance_config_form(BlockInstance $instance) {
72
73
74
75
76
77
        $configdata = $instance->get('configdata');

        return array(
            'appsid' => array(
                'type'  => 'textarea',
                'title' => get_string('appscodeorurl','blocktype.googleapps'),
Kristina Hoeppner's avatar
Kristina Hoeppner committed
78
                'description' => get_string('appscodeorurldesc1','blocktype.googleapps', get_config('series')) . self::get_html_of_supported_googleapps(),
79
                'rows' => 5,
80
                'cols' => 76,
81
82
83
                'defaultvalue' => (!empty($configdata['appsid']) ? $configdata['appsid'] : null),
                'rules' => array(
                    'required' => true
84
                )
85
86
87
88
89
90
91
92
93
94
95
            ),
            'height' => array(
                'type' => 'text',
                'title' => get_string('height','blocktype.googleapps'),
                'size' => 3,
                'rules' => array(
                    'required' => true,
                    'integer'  => true,
                ),
                'defaultvalue' => (!empty($configdata['height'])) ? $configdata['height'] : self::$default_height,
            ),
96
97
98
99
100
101
102
            'tags'  => array(
                'type'         => 'tags',
                'title'        => get_string('tags'),
                'description'  => get_string('tagsdescblock'),
                'defaultvalue' => $instance->get('tags'),
                'help'         => false,
            )
103
104
105
        );
    }

Doris Tam's avatar
Doris Tam committed
106
    public static function make_apps_url($url) {
107
108
        $httpstr = is_https() ? 'https' : 'http';

109
110
111
112
        if (preg_match('#//goo\.gl/#', $url)) {
            $results = mahara_shorturl_request($url);
            $url = $results->fullurl;
        }
113
        $embedsources = array(
114
            // docs.google.com/leaf and (as of early 2012) docs.google.com/open - Google collections
115
116
117
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the collection
            array(
118
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)leaf\?id=([a-zA-Z0-9\_\-]+).*#',
119
                'url'   => $httpstr . '://drive.google.com/$1folderview?id=$2',
120
121
                'type'  => 'spanicon',
            ),
122
123
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)open\?id=([a-zA-Z0-9\_\-]+).*#',
124
125
126
127
128
129
130
131
132
133
134
135
136
                'url'   => $httpstr . '://drive.google.com/$1folderview?id=$2',
                'type'  => 'spanicon',
            ),
            // drive.google.com/folderview or drive.google.com/open - Google Drive folders
            // (formerly Google Docs collections)
            array(
                'match' => '#.*drive.google.com/([a-zA-Z0-9\_\-\.\/]*)open\?id=([a-zA-Z0-9\_\-]+).*#',
                'url'   => $httpstr . '://drive.google.com/$1folderview?id=$2',
                'type'  => 'spanicon',
            ),
            array(
                'match' => '#.*drive.google.com/([a-zA-Z0-9\_\-\.\/]*)folderview\?id=([a-zA-Z0-9\_\-]+).*#',
                'url'   => $httpstr . '://drive.google.com/$1folderview?id=$2',
137
138
                'type'  => 'spanicon',
            ),
139
140
            // docs.google.com/present - Google presentation incl. custom domain presentation
            // $1 - domain, e.g. /a/domainname/
141
142
143
            // $2 - present or presentation
            // $3 - mode, e.g. pub, view or embed
            // $4 - id, key, etc. of the presentation
144
            array(
145
146
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)present([a-z]*)/([a-z]+).*?id=([a-zA-Z0-9\_\-\&\=]+).*#',
                'url'   => $httpstr . '://docs.google.com/$1present$2/embed?id=$4',
147
148
                'type'  => 'iframe',
            ),
149
150
151
152
153
154
155
156
157
158
            // docs.google.com - Google presentation URL format (updated on Mar 2013)
            // $1 - domain, e.g. /a/domainname/
            // $2 - storage path, e.g. d/<hashstring>
            // $3 - mode, e.g. pub, view or embed
            // $4 - url parameters: start, loop, delayms
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)presentation/([a-zA-Z0-9\_\-\/]+)/([a-z]+)\?([a-zA-Z0-9\_\-\&\=]*).*#',
                'url'   => $httpstr . '://docs.google.com/$1presentation/$2/embed?$4',
                'type'  => 'iframe',
            ),
159
160
161
162
163
            // docs.google.com/drawings - Google drawing incl. custom domain drawing
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the drawing
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)drawings.*id=([a-zA-Z0-9\_\-\&\=]+).*#',
164
                'url'   => $httpstr . '://docs.google.com/$1drawings/pub?id=$2',
165
166
                'type'  => 'image',
            ),
167
168
169
170
171
172
173
174
175
176
            // docs.google.com - Google drawing document URL format (updated on Mar 2013)
            // $1 - domain, e.g. /a/domainname/
            // $2 - storage path, e.g. d/<hashstring>
            // $3 - mode, e.g. pub, view or embed
            // $4 - url parameters: w, h
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)drawings/([a-zA-Z0-9\_\-\/]+)/([a-z]+)\?([a-zA-Z0-9\_\-\&\=]*).*#',
                'url'   => $httpstr . '://docs.google.com/$1drawings/$2/$3?$4',
                'type'  => 'image',
            ),
177
178
179
180
181
            // docs.google.com - Google document (before July 2010) incl. custom domain document
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the document
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)View.*id=([a-zA-Z0-9\_\-]+).*#',
182
                'url'   => $httpstr . '://docs.google.com/$1View?id=$2',
183
184
                'type'  => 'iframe',
            ),
185
186
187
188
189
190
191
192
            // docs.google.com - Google document (after march 2012) incl. custom domain document
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the document
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)viewer.*srcid=([a-zA-Z0-9\_\-\&\=]+).*#',
                'url'   => $httpstr . '://docs.google.com/$1viewer?srcid=$2',
                'type'  => 'iframe',
            ),
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
            // docs.google.com - Google document URL format (updated on Mar 2013)
            // $1 - domain, e.g. /a/domainname/
            // $2 - storage path, e.g. d/<hashstring>
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)document/([a-zA-Z0-9\_\-\/]+)/pub.*#',
                'url'   => $httpstr . '://docs.google.com/$1document/$2/pub?embedded=true',
                'type'  => 'iframe',
            ),
            // docs.google.com - Google document viewer URL format (updated on Mar 2013)
            // $1 - domain, e.g. /a/domainname/
            // $2 - storage path, e.g. d/<hashstring>
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)file/([a-zA-Z0-9\_\-\/]+)/([a-z]+).*#',
                'url'   => $httpstr . '://docs.google.com/$1file/$2/preview',
                'type'  => 'iframe',
            ),
209
210
211
212
213
214
215
216
217
            // docs.google.com/viewer created urls
            // $1 - domain, e.g. /a/domainname/
            // $2 - http or https
            // $3 - domain of document, non-google or googleapps
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)viewer.*url=http([a-zA-Z0-9\.\,\;\_\-\&\%\=\+/\:]+)\.(pdf|tif|tiff|ppt|doc|docx).*#',
                'url'   => $httpstr . '://docs.google.com/$1viewer?url=http$2.$3&embedded=true',
                'type'  => 'iframe',
            ),
218
219
220
221
222
            // docs.google.com - Google document (after July 2010) incl. custom domain document
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the document
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)document/pub.*id=([a-zA-Z0-9\_\-]+).*#',
223
                'url'   => $httpstr . '://docs.google.com/$1document/pub?id=$2',
224
225
                'type'  => 'iframe',
            ),
226
            // docs.google.com - Google document (updated on Mar 2014)
227
228
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the document
229
230
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)document/d/([a-zA-Z0-9\_\-]+).*#',
231
                'url'   => $httpstr . '://docs.google.com/$1document/d/$2/pub?embedded=true',
232
233
                'type'  => 'iframe',
            ),
234
235
236
237
238
239
240
241
            // docs.google.com/spreadsheets - Google document (updated on Mar 2015)
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the spreadsheet
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)spreadsheets/d/([a-zA-Z0-9\_\-]+).*#',
                'url'   => $httpstr . '://docs.google.com/$1spreadsheets/d/$2/pub?embedded=true',
                'type'  => 'iframe',
            ),
242
243
244
245
246
247
248
249
250
251
            // docs.google.com - Google spreadsheet document (updated on Mar 2013)
            // $1 - domain, e.g. /a/domainname/ (optional)
            // $2 - key of the document
            // $3 - other parameters: single, gid, output
            array(
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)spreadsheet/.*key=([a-zA-Z0-9\_\-]+)([a-zA-Z0-9\_\-\&\=]*).*#',
                'url'   => $httpstr . '://docs.google.com/$1spreadsheet/pub?key=$2$3&widget=true',
                'type'  => 'iframe',
            ),
            // docs.google.com - Google form (updated on Mar 2013)
252
            // $1 - domain, e.g. /a/domainname/
253
            array(
254
255
                'match' => '#.*docs.google.com/([a-zA-Z0-9\_\-\.\/]*)forms/([a-zA-Z0-9\_\-\.\/]*)/viewform\?embedded=true.*#',
                'url'   => $httpstr . '://docs.google.com/$1forms/$2/viewform?embedded=true',
256
257
                'type'  => 'iframe',
            ),
258
259
260
261
262
            // spreadsheets.google.com/viewform - Google form incl. custom domain form
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the form
            array(
                'match' => '#.*spreadsheets[0-9]?.google.com/([a-zA-Z0-9\_\-\.\/]*)viewform.*formkey=([a-zA-Z0-9\_\-]+).*#',
263
                'url'   => $httpstr . '://spreadsheets.google.com/$1embeddedform?formkey=$2',
264
265
266
267
268
269
270
                'type'  => 'iframe',
            ),
            // spreadsheets.google.com/embeddedform - Google form incl. custom domain form
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the form
            array(
                'match' => '#.*spreadsheets[0-9]?.google.com/([a-zA-Z0-9\_\-\.\/]*)embeddedform.*formkey=([a-zA-Z0-9\_\-]+).*#',
271
                'url'   => $httpstr . '://spreadsheets.google.com/$1embeddedform?formkey=$2',
272
273
274
275
276
277
278
                'type'  => 'iframe',
            ),
            // spreadsheets.google.com - Google spreadsheet incl. custom domain spreadsheet
            // $1 - domain, e.g. /a/domainname/
            // $2 - id, key, etc. of the spreadsheet
            array(
                'match' => '#.*spreadsheets[0-9]?.google.com/([a-zA-Z0-9\_\-\.\/]*)pub.*key=([a-zA-Z0-9\_\-]+).*#',
279
                'url'   => $httpstr . '://spreadsheets.google.com/$1pub?key=$2',
280
281
                'type'  => 'iframe',
            ),
282
283
284
285
286
287
288
            // drive.google.com - Google uploaded file (updated on Mar 2014)
            // $1 - id, key, etc. of the file
            array(
                'match' => '#.*drive.google.com/.*file/d/([a-zA-Z0-9\_\-]+).*#',
                'url'   => $httpstr . '://docs.google.com/file/d/$1/preview',
                'type'  => 'iframe',
            ),
289
            // www.google.com/calendar - Google calendar
290
291
            array(
                'match' => '#.*www.google.com/calendar.*src=([a-zA-Z0-9\.\_\-\&\%\=/]+).*#',
292
293
294
295
296
297
298
                'url'   => $httpstr . '://calendar.google.com/calendar/embed?src=$1',
                'type'  => 'iframe',
            ),
            // calendar.google.com - Google Calendar (mid-2016)
            array(
                'match' => '#.*calendar.google.com/calendar.*src=([a-zA-Z0-9\.\_\-\&\%\=/]+).*#',
                'url'   => $httpstr . '://calendar.google.com/calendar/embed?src=$1',
299
300
                'type'  => 'iframe',
            ),
301
            // (maps|www).google.com - Google My Maps (IMPORTANT: this is ONLY for My Maps)
302
            array(
303
304
                'match' => '#.*google.[^/]*/maps/ms\?([a-zA-Z0-9\.\,\;\_\-\&\%\=\+/]+).*#',
                'url'   => $httpstr . '://maps.google.com/maps/ms?$1&output=embed',
305
306
                'type'  => 'iframe',
            ),
307
            // maps.google.com - Other maps.google.map URLs.
308
309
            array(
                'match' => '#.*maps.google.[^/]*/(maps)?\?([a-zA-Z0-9\.\,\;\_\-\&\%\=\+/]+).*#',
310
311
312
                'url'   => $httpstr . '://maps.google.com/maps?$2&output=embed',
                'type'  => 'iframe',
            ),
313
314
315
316
317
318
319
320
321
322
            // (maps|www).google.com/maps/place - Google Map for a place URLs.
            array(
                'match' => '#.*google.[^/]*/maps/place/([^/]+)/@([0-9\-\.]+),([0-9\-\.]+),([0-9]+)z/data=.+!1s([0-9xa-f]+):([0-9xa-f]+).*#',
                'url'   =>  function ($m) {
                                $zoomlevel = min(max($m[4], 3), 21);
                                $height = 188 * pow(2, (21 - $zoomlevel));
                                return "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d${height}!2d${m[3]}!3d${m[2]}!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s${m[5]}%3A${m[6]}!2s${m[1]}!5e0";
                            },
                'type'  => 'iframe',
            ),
323
324
325
326
327
328
            // mapsengine.google.com/map/embed URLs.
            array(
                'match' => '#.*mapsengine.google.com[^/]*/map/[^?]*\?([a-zA-Z0-9\.\,\;\_\-\&\%\=\+\?/]+).*#',
                'url'   => $httpstr . '://mapsengine.google.com/map/embed?$1',
                'type'  => 'iframe',
            ),
329
            // www.google.com/maps? URLs.
330
331
332
333
334
335
336
337
338
            array(
                'match' => '#.*www.google.com[^/]*/maps\?([a-zA-Z0-9\.\,\;\_\-\&\%\=\+\!/]+).*#',
                'url'   => $httpstr . '://www.google.com/maps?$1&output=embed',
                'type'  => 'iframe',
            ),
            // www.google.com/maps/embed URLs - these must be https.
            array(
                'match' => '#.*www.google.com[^/]*/maps/embed\?([a-zA-Z0-9\.\,\;\_\-\&\%\=\+\!/]+).*#',
                'url'   => 'https://www.google.com/maps/embed?$1',
339
340
                'type'  => 'iframe',
            ),
341
342
343
344
345
346
            // www.google.com/maps/@ URLs.
            array(
                'match' => '#.*www.google.com.*?/\@([a-zA-Z0-9\.\-]+)\,([a-zA-Z0-9\.\-]+)\,([0-9]+).*#',
                'url'   => 'https://maps.google.com/maps?ll=$1,$2&z=$3&output=embed',
                'type'  => 'iframe',
            ),
347
348
349
350
351
352
            // books.google.com - Google Books
            array(
                'match' => '#.*books.google.[^/]*/books.*id=([a-zA-Z0-9\_\-\&\%\=]+).*#',
                'url'   => 'http://books.google.com/books?id=$1',
                'type'  => 'iframe',
            ),
353
            // If everything else fails, match if it is a valid link to a file... and than show that file with Google Docs Viewer
354
355
356
            // Google Docs Viewer supported files: PDF, TIFF, PPT, DOC, DOCX
            array(
                'match' => '#http([a-zA-Z0-9\.\,\;\_\-\&\%\=\+/\:]+)\.(pdf|tif|tiff|ppt|doc|docx)#',
357
                'url'   => $httpstr . '://docs.google.com/gview?url=http$1.$2&embedded=true',
358
359
360
361
362
363
364
                'type'  => 'iframe',
            ),
        );

        foreach ($embedsources as $source) {
            $url = htmlspecialchars_decode($url); // convert &amp; back to &, etc.
            if (preg_match($source['match'], $url)) {
365
366
367
368
369
370
                if (is_string($source['url'])) {
                    $apps_url = preg_replace($source['match'], $source['url'], $url);
                }
                else if (is_callable($source['url'])) {
                    $apps_url = preg_replace_callback($source['match'], $source['url'], $url);
                }
371
372
373
374
375
376
                // For correctly embed Google maps...
                $apps_url = str_replace('source=embed', 'output=embed', $apps_url);
                $apps_type = $source['type'];
                return array('url' => $apps_url, 'type' => $apps_type);
            }
        }
377
378
        // if we reach here then mahara does not understand the url
        return array('url' => $url, 'type' => false);
379
380
381
382
383
384
385
386
387
388
    }


    /**
     * Returns a block of HTML that the Google Apps block can use to list
     * which Google services  are supported.
     */
    private static function get_html_of_supported_googleapps() {
        $smarty = smarty_core();
        $smarty->assign('lang', substr(get_config('lang'), 0, 2));
389
        if (is_https() === true) {
390
391
392
393
394
            $smarty->assign('protocol', 'https');
        }
        else {
            $smarty->assign('protocol', 'http');
        }
395
396
397
398
399
400
401
        return $smarty->fetch('blocktype:googleapps:supported.tpl');
    }

    public static function default_copy_type() {
        return 'full';
    }

402
403
404
405
406
407
408
409
410
    /**
     * Shouldn't be linked to any artefacts via the view_artefacts table.
     *
     * @param BlockInstance $instance
     * @return multitype:
     */
    public static function get_artefacts(BlockInstance $instance) {
        return array();
    }
411
}