lib.php 30.5 KB
Newer Older
1
2
3
4
5
<?php
/**
 *
 * @package    mahara
 * @subpackage blocktype-textbox
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.
9
10
11
12
13
 *
 */

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

14
class PluginBlocktypeTextbox extends MaharaCoreBlocktype {
15
16

    public static function get_title() {
Ghada El-Zoghbi's avatar
Ghada El-Zoghbi committed
17
        return get_string('title', 'blocktype.internal/textbox');
18
19
20
    }

    public static function get_description() {
21
        return get_string('description', 'blocktype.internal/textbox');
22
23
24
    }

    public static function get_categories() {
25
        return array('general' => 24000);
26
27
    }

28
29
30
31
    public function can_have_attachments() {
        return true;
    }

Lisa Seeto's avatar
Lisa Seeto committed
32
33
34
35
    public static function single_artefact_per_block() {
        return true;
    }

36
    public static function render_instance(BlockInstance $instance, $editing=false, $versioning=false) {
37
        $configdata = $instance->get('configdata');
38
39
40
41
42
43
        if (!empty($configdata['artefactid'])) {
            safe_require('artefact', 'file');
            safe_require('artefact', 'comment');

            $artefact = $instance->get_artefact_instance($configdata['artefactid']);
            $viewid = $instance->get('view');
44
45
46
47
48
49
            if ($versioning) {
                $text = $configdata['text'];
            }
            else {
                $text = ArtefactTypeFolder::append_view_url($artefact->get('description'), $viewid);
            }
50
51
52
            $smarty = smarty_core();
            $smarty->assign('text', $text);

53
54
55
56
57
58
            $attachments = $artefact->get_attachments();
            if ($attachments) {
                require_once(get_config('docroot') . 'artefact/lib.php');
                foreach ($attachments as &$attachment) {
                    $f = artefact_instance_from_id($attachment->id);
                    $attachment->size = $f->describe_size();
59
                    $attachment->iconpath = $f->get_icon(array('id' => $attachment->id, 'viewid' => $instance->get('view')));
60
61
62
63
64
65
66
                    $attachment->downloadpath = get_config('wwwroot') . 'artefact/file/download.php?file=' . $attachment->id;
                    if (isset($viewid)) {
                        $attachment->downloadpath .= '&view=' . $viewid;
                    }
                }
                $smarty->assign('count', count($attachments));
            }
67
            $smarty->assign('attachments', $attachments);
68
69
            require_once(get_config('docroot') . 'lib/view.php');
            $view = new View($viewid);
70
            list($commentcount, $comments) = ArtefactTypeComment::get_artefact_comments_for_view($artefact, $view, $instance->get('id'), true, $editing, $versioning);
71
72
            $smarty->assign('commentcount', $commentcount);
            $smarty->assign('comments', $comments);
Lisa Seeto's avatar
Lisa Seeto committed
73
            $smarty->assign('license', (int)get_config('licensemetadata'));
74
            $smarty->assign('blockid', $instance->get('id'));
Lisa Seeto's avatar
Lisa Seeto committed
75
            $smarty->assign('artefactid', $artefact->get('id'));
Lisa Seeto's avatar
Lisa Seeto committed
76
            $smarty->assign('editing', $editing);
77
78
79
80
            return $smarty->fetch('blocktype:textbox:content.tpl');
        }

        return '';
81
82
    }

83
84
85
    /**
     * Returns a list of artefact IDs that are in this blockinstance.
     *
86
87
     * People may embed artefacts as images etc. They show up as links to the
     * download script, which isn't much to go on, but should be enough for us
88
89
90
91
     * to detect that the artefacts are therefore 'in' this blocktype.
     */
    public static function get_artefacts(BlockInstance $instance) {
        $configdata = $instance->get('configdata');
92
93
94
95
96
97
98
        $artefacts = array();
        if (isset($configdata['artefactid'])) {
            $artefacts[] = $configdata['artefactid'];

            // Add all artefacts found in the text
            $text = $instance->get_artefact_instance($configdata['artefactid'])->get('description');
            $artefacts = array_unique(array_merge($artefacts, artefact_get_references_in_html($text)));
99
100
101
102
        }
        return $artefacts;
    }

103
104
    public static function artefactchooser_element($default=null) {
        return array(
105
106
            'name'             => 'artefactid',
            'type'             => 'artefactchooser',
107
            'class'            => 'd-none',
108
109
110
111
112
113
            'defaultvalue'     => $default,
            'blocktype'        => 'textbox',
            'limit'            => 5,
            'selectone'        => true,
            'selectjscallback' => 'updateTextContent',
            'getblocks'        => true,
114
            'ownerinfo'        => true,
115
            'returnfields'     => array('id', 'title', 'description', 'tags', 'license', 'licensor', 'licensorurl', 'safedescription', 'safetags', 'safelicense', 'editable', 'attachments'),
116
117
            'artefacttypes'    => array('html'),
            'template'         => 'artefact:internal:html-artefactchooser-element.tpl',
118
            'lazyload'         => true,
119
120
121
        );
    }

122
123
124
125
126
    public static function artefactchooser_get_element_data($artefact) {

        require_once('license.php');
        $artefactobj = artefact_instance_from_id($artefact->id);
        $artefact->safelicense = render_license($artefactobj);
127
128
        $artefact->tags = ArtefactType::artefact_get_tags($artefact->id);
        $artefact->safetags = is_array($artefact->tags) ? hsc(join(', ', $artefact->tags)) : '';
129
130
131
132

        return $artefact;
    }

Son Nguyen's avatar
Son Nguyen committed
133
    public static function get_instance_config_javascript(BlockInstance $instance) {
134
135
136
137
138
        // When an artefact is selected in the artefactchooser, update the
        // contents of the wysiwyg editor and the message about the number
        // of blocks containing the new artefact.
        $blockid = $instance->get('id');
        return <<<EOF
139
formchangemanager.setFormStateById('instconf', FORM_CHANGED);
140
function updateTextContent(a) {
141
    jQuery('#instconf_title').prop('value', a.title);
142
143
144
    if (typeof(tinyMCE) != 'undefined') {
        tinyMCE.activeEditor.setContent(a.description);
    }
145
146
147
148
149
    jQuery('#instconf_license').prop('value', a.license);
    jQuery('#instconf_licensor').prop('value', a.licensor);
    jQuery('#instconf_licensorurl').prop('value', a.licensorurl);
    jQuery('#instconf_textreadonly_display').html(a.safedescription);
    jQuery('#instconf_licensereadonly_display').html(a.safelicense);
150
151
152
153
154
155
156
157
158
159
160
161
    if (a.tags && a.tags.length > 0) {
        for (var i = 0; i < a.tags.length; i++) {
            // Set the value, creating a new option if necessary
            if (!$('#instconf_tags').find("option[value='" + a.tags[i] + "']").length) {
                // Create a DOM Option and pre-select by default
                var newOption = new Option(a.tags[i], a.tags[i], true, true);
                // Append it to the select
                $('#instconf_tags').append(newOption);
            }
        }
        $('#instconf_tags').val(a.tags).trigger('change');
    }
162
163
    jQuery('#instconf_textreadonly_display').html(a.safedescription);
    jQuery('#instconf_tagsreadonly_display').html(a.safetags);
164
    jQuery('#instconf_makecopy').prop('checked', false);
165
    if (a.editable == 1) {
166
167
168
169
170
        jQuery('#instconf_textreadonly_container').addClass('d-none');
        jQuery('#instconf_readonlymsg_container').addClass('d-none');
        jQuery('#instconf_licensereadonly_container').addClass('d-none');
        jQuery('#instconf_tagsreadonly_container').addClass('d-none');
        jQuery('#instconf_text_container').removeClass('d-none');
171
        if (jQuery('#instconf_license_container').length) {
172
            // only deal with these if the license metadata is enabled
173
174
175
            jQuery('#instconf_license_container').removeClass('d-none');
            jQuery('#instconf_license_description').removeClass('d-none');
            jQuery('#instconf_license_advanced_fieldset').removeClass('d-none');
176
        }
177
178
        jQuery('#instconf_tags_container').removeClass('d-none');
        jQuery('#instconf_tags_description').removeClass('d-none');
179
180
        var blockcountmsg = jQuery('#instconf_otherblocksmsg_container');
        if (blockcountmsg && jQuery('#textbox_blockcount')) {
181
182
183
184
185
186
            var otherblockcount = 0;
            if (a.blocks && a.blocks.length > 0) {
                for (var i = 0; i < a.blocks.length; i++) {
                    if (a.blocks[i] != {$blockid}) {
                        otherblockcount++;
                    }
187
188
                }
            }
189
            if (otherblockcount) {
190
                jQuery('#textbox_blockcount').empty().append(otherblockcount);
191
                jQuery(blockcountmsg).removeClass('d-none');
192
193
            }
            else {
194
                jQuery(blockcountmsg).addClass('d-none');
195
            }
196
        }
197
198
199
200

        if (typeof a.attachments != 'undefined') {
            // remove any attached files
            for (var key in instconf_artefactids.selecteddata) {
201
              jQuery('#instconf_artefactids_unselect_' + key).triggerHandler('click', instconf_artefactids.unselect);
202
203
204
205
206
207
208
209
            }
            // add in ones we need
            if (a.attachments.length > 0) {
                for (var i = 0; i < a.attachments.length; i++) {
                    instconf_artefactids.add_to_selected_list(a.attachments[i]);
                }
            }
        }
210
211
    }
    else {
212
213
        jQuery('#instconf_text_container').addClass('d-none');
        jQuery('#instconf_otherblocksmsg_container').addClass('d-none');
214
        if (jQuery('#instconf_license_container').length) {
215
            // only deal with these if the license metadata is enabled
216
217
218
            jQuery('#instconf_license_container').addClass('d-none');
            jQuery('#instconf_license_description').addClass('d-none');
            jQuery('#instconf_license_advanced_fieldset').addClass('d-none');
219
        }
220
221
222
223
224
225
        jQuery('#instconf_tags_container').addClass('d-none');
        jQuery('#instconf_tags_description').addClass('d-none');
        jQuery('#instconf_textreadonly_container').removeClass('d-none');
        jQuery('#instconf_readonlymsg_container').removeClass('d-none');
        jQuery('#instconf_licensereadonly_container').removeClass('d-none');
        jQuery('#instconf_tagsreadonly_container').removeClass('d-none');
226
    }
227
228
    jQuery('#instconf_edit_container').removeClass('d-none');
    jQuery('#instconf_edit').trigger('change');
229
230
231
232
233
234
    jQuery('#instconf_otherblocksmsg_container').removeClass('d-none');
    jQuery('#artefactid_data input.radio').each(function() {
        if (jQuery(this).prop('checked')) {
            jQuery('#textbox_blockcount').html(jQuery(this).attr('data-count'));
        }
    });
235
}
236
237
jQuery('#chooseartefactlink').on('click', function(e) {
    e.preventDefault();
238
    // if the artefact chooser is hidden, use paginator p to populate it, then toggle its visibility
239
    if (jQuery('#instconf_artefactid_container').hasClass('d-none')) {
240
        var queryData = [];
241
        queryData.extradata = JSON.stringify(p.extraData);
242
243
        p.sendQuery(queryData, true);
    }
244
245
    jQuery('#instconf_artefactid_container').toggleClass('d-none');
    jQuery('#instconf_managenotes_container').toggleClass('d-none');
246
});
247
jQuery('#instconf #instconf_edit').on('change',function(){
248
249
250
251
252
253
254
    if (jQuery(this).prop('checked')) {
        jQuery('#instconf_textreadonly_container').addClass('d-none');
        jQuery('#instconf_text_container').removeClass('d-none');
    }
    else {
        jQuery('#instconf_textreadonly_container').removeClass('d-none');
        jQuery('#instconf_text_container').addClass('d-none');
255
        tinyMCE.activeEditor.getBody().innerHTML = jQuery('#instconf_textreadonly_display').html();
256
257
    }
});
258
259
260
261
262
263
jQuery('#instconf a.copytextboxnote').each(function() {
    jQuery(this).on('click', function(e) {
        e.preventDefault();
        jQuery('#artefactid_data input.radio').each(function() {
            if (jQuery(this).prop('checked')) {
                jQuery(this).prop('checked', false);
264
265
            }
        });
266
        jQuery('#instconf_edit_container').addClass('d-none');
267
        jQuery('#instconf_makecopy').prop('checked', true);
268
269
270
271
272
273
        jQuery('#instconf_textreadonly_container').addClass('d-none');
        jQuery('#instconf_readonlymsg_container').addClass('d-none');
        jQuery('#instconf_otherblocksmsg_container').addClass('d-none');
        jQuery('#instconf_licensereadonly_container').addClass('d-none');
        jQuery('#instconf_tagsreadonly_container').addClass('d-none');
        jQuery('#instconf_text_container').removeClass('d-none');
274
        if (jQuery('#instconf_license_container').length) {
275
            // only deal with these if the license metadata is enabled
276
277
278
            jQuery('#instconf_license_container').removeClass('d-none');
            jQuery('#instconf_license_description').removeClass('d-none');
            jQuery('#instconf_license_advanced_fieldset').removeClass('d-none');
279
        }
280
281
        jQuery('#instconf_tags_container').removeClass('d-none');
        jQuery('#instconf_tags_description').removeClass('d-none');
282
283
    });
});
284
if (jQuery('#instconf_license').length) {
285
    jQuery('#instconf_license').removeClass('d-none');
286
}
287
if (jQuery('#instconf_license_advanced_container').length) {
288
    jQuery('#instconf_license_advanced_container div').first().removeClass('d-none');
289
}
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
jQuery(function() {
    jQuery('#instconf_tags').on('change', function() {
        updatetagbuttons();
    });
    updatetagbuttons();

    function updatetagbuttons() {
        jQuery('#instconf_tags_container ul button').on('click', function(e) {
            e.stopPropagation();
            e.preventDefault();
            var li = jQuery(this).parent();
            var data = jQuery('#instconf_tags').select2('data');
            var value = null;
            for (var x in data) {
                if (li[0].title == data[x].text) {
                    value = data[x].id;
                    break;
                }
            }
            var val = jQuery('#instconf_tags').select2('val');
            var index = val.indexOf(value);
            if (index > -1) {
                val.splice(index, 1);
            }
            jQuery('#instconf_tags').select2('val', val);
        });
    }
});
318
319
320
EOF;
    }

321
    public static function has_instance_config(BlockInstance $instance) {
322
323
324
        return true;
    }

Son Nguyen's avatar
Son Nguyen committed
325
    public static function instance_config_form(BlockInstance $instance) {
326
        global $USER;
327
        require_once('license.php');
328
        safe_require('artefact', 'file');
329
        $instance->set('artefactplugin', 'internal');
330
        $configdata = $instance->get('configdata');
331
332
333
334
        if (!$height = get_config('blockeditorheight')) {
            $cfheight = param_integer('cfheight', 0);
            $height = $cfheight ? $cfheight * 0.7 : 150;
        }
335

336
        $otherblockcount = 0;
337
338
        $readonly = false;
        $text = '';
339
        $tags = '';
340
341
        $view = $instance->get_view();

342
343
        if (!empty($configdata['artefactid'])) {
            $artefactid = $configdata['artefactid'];
344
            try {
345
346
347
348
349
                $artefact = $instance->get_artefact_instance($artefactid);

                $readonly = $artefact->get('owner') !== $view->get('owner')
                    || $artefact->get('group') !== $view->get('group')
                    || $artefact->get('institution') !== $view->get('institution')
350
                    || $artefact->get('locked')
351
352
353
                    || !$USER->can_edit_artefact($artefact);

                $text = $artefact->get('description');
354
                $tags = $artefact->get('tags');
355
356
357
358
359

                if ($blocks = get_column('view_artefact', 'block', 'artefact', $artefactid)) {
                    $blocks = array_unique($blocks);
                    $otherblockcount = count($blocks) - 1;
                }
360
361
362
363
            }
            catch (ArtefactNotFoundException $e) {
                unset($artefactid);
            }
364
        }
365
366
367
368
369
370
371
372
373
374
375
376

        $otherblocksmsg = '<span id="textbox_blockcount">' . $otherblockcount . '</span>';
        $otherblocksmsg = get_string('textusedinotherblocks', 'blocktype.internal/textbox', $otherblocksmsg);

        $manageurl = get_config('wwwroot') . 'artefact/internal/notes.php';
        if ($group = $view->get('group')) {
            $manageurl .= '?group=' . $group;
        }
        else if ($institution = $view->get('institution')) {
            $manageurl .= '?institution=' . $institution;
        }

377
378
379
        // Update the attached files in block configdata as
        // it may change when attached files have been deleted
        $attachmentids = isset($artefact) ? $artefact->attachment_id_list() : false;
380
        if ($attachmentids !== false && isset($configdata['artefactids']) && $configdata['artefactids'] != $attachmentids) {
381
382
383
384
385
            $configdata['artefactids'] = $attachmentids;
            $instance->set('configdata', $configdata);
            $instance->commit();
        }

386
387
388
389
390
391
        // Get the default value for allowing comments on Notes
        if ($allowcomments = get_config_plugin('artefact', 'internal', 'allowcomments')) {
            $allowcomments = explode(',', $allowcomments);
            $allowcomments = in_array('notes', $allowcomments);
        }

392
        $elements = array(
393
394
395
            // Add a message whenever this text appears in some other block
            'otherblocksmsg' => array(
                'type' => 'html',
396
                'class' => 'message info' . (($otherblockcount && !$readonly) ? '' : ' d-none'),
397
                'value' => '<p class="alert alert-warning">' . $otherblocksmsg
398
                    . ' <a class="copytextboxnote nojs-hidden-inline" href="">' . get_string('makeacopy', 'blocktype.internal/textbox') . '</a></p>',
399
400
401
402
403
                'help' => true,
            ),
            // Add a message whenever this text cannot be edited here
            'readonlymsg' => array(
                'type' => 'html',
404
                'class' => 'message info' . ($readonly ? '' : ' d-none'),
405
                'value' => '<p class="alert alert-warning">' . get_string('readonlymessage', 'blocktype.internal/textbox')
406
                    . ' <a class="copytextboxnote nojs-hidden-inline" href="">' . get_string('makeacopy', 'blocktype.internal/textbox') . '</a></p>',
407
                'help' => true,
408
            ),
409
410
411
412
413
414
            'edit' => array(
                'type' => 'switchbox',
                'class' => $otherblockcount > 0 ? '' : 'd-none',
                'title' => get_string('editcontent', 'blocktype.internal/textbox'),
                'defaultvalue' => 0,
            ),
415
            'text' => array(
416
                'type' => 'wysiwyg',
417
                'class' => $readonly || $otherblockcount > 0 ? 'd-none' : '',
418
                'title' => get_string('blockcontent', 'blocktype.internal/textbox'),
419
                'width' => '100%',
420
                'height' => $height . 'px',
421
                'defaultvalue' => $text,
422
                'rules' => array('maxlength' => 1000000),
423
            ),
424
425
            'textreadonly' => array(
                'type' => 'html',
426
                'class' => $readonly || $otherblockcount > 0 ? '' : 'd-none',
427
                'title' => get_string('blockcontent', 'blocktype.internal/textbox'),
Pat Kira's avatar
Pat Kira committed
428
                'value' => '<div id="instconf_textreadonly_display" class="well text-midtone">' . $text . '</div>',
429
            ),
430
431
            'makecopy' => array(
                'type' => 'checkbox',
432
                'class' => 'd-none',
433
434
435
436
                'defaultvalue' => false,
            ),
            'chooseartefact' => array(
                'type'  => 'html',
437
                'value' => '<a id="chooseartefactlink" href="#" class="btn btn-secondary">'
438
                    . get_string('usecontentfromanothertextbox1', 'blocktype.internal/textbox') . '</a>',
439
440
441
            ),
            'managenotes' => array(
                'type'  => 'html',
442
                'class' => 'd-none text-right',
443
                'value' => '<a href="' . $manageurl . '" class="float-right">'
444
                    . get_string('managealltextboxcontent1', 'blocktype.internal/textbox') . ' <span class="icon icon-arrow-right right" role="presentation"></span></a>',
445
            ),
446
447
448
449
450
            'artefactid' => self::artefactchooser_element(isset($artefactid) ? $artefactid : null),
            'license' => license_form_el_basic(isset($artefact) ? $artefact : null),
            'license_advanced' => license_form_el_advanced(isset($artefact) ? $artefact : null),
            'licensereadonly' => array(
                'type' => 'html',
451
                'class' => $readonly ? '' : 'd-none',
452
                'title' => get_string('license'),
453
                'value' => '<div id="instconf_licensereadonly_display">' . (isset($artefact) ? render_license($artefact) : get_string('licensenone1')) . '</div>',
454
            ),
455
            'allowcomments' => array(
456
                'type'         => 'switchbox',
457
                'title'        => get_string('allowcomments', 'artefact.comment'),
458
                'defaultvalue' => (!empty($artefact) ? $artefact->get('allowcomments') : $allowcomments),
459
            ),
460
461
            'tags' => array(
                'type' => 'tags',
462
                'class' => $readonly ? 'd-none' : '',
463
464
465
466
467
468
                'title' => get_string('tags'),
                'description' => get_string('tagsdescprofile'),
                'defaultvalue' => $tags,
            ),
            'tagsreadonly' => array(
                'type' => 'html',
469
                'class' => $readonly ? '' : 'd-none',
470
471
472
                'title' => get_string('tags'),
                'value' => '<div id="instconf_tagsreadonly_display">' . (is_array($tags) ? hsc(join(', ', $tags)) : '') . '</div>',
            ),
473
474
475
476
477
            'artefactfieldset' => array(
                'type'         => 'fieldset',
                'collapsible'  => true,
                'collapsed'    => true,
                'legend'       => get_string('attachments', 'artefact.blog'),
478
                'class'        => 'last with-formgroup',
479
                'elements'     => array(
480
                    'artefactids' => self::filebrowser_element($instance, (isset($configdata['artefactids'])) ? $configdata['artefactids'] : null),
481
482
                )
            )
483
        );
484
        if ($readonly) {
485
486
            $elements['license']['class'] = 'd-none';
            $elements['license_advanced']['class'] = 'd-none';
487
        }
488
489
490
        return $elements;
    }

491
    public static function delete_instance(BlockInstance $instance) {
492
493
494
495
496
497
498
499
500
501
        require_once('embeddedimage.php');
        $configdata = $instance->get('configdata');
        if (!empty($configdata)) {
            $artefactid = $configdata['artefactid'];
            if (!empty($artefactid)) {
                EmbeddedImage::delete_embedded_images($instance->get('blocktype'), $artefactid);
            }
        }
    }

502
    public static function instance_config_save($values, $instance) {
503
        global $USER;
504
        require_once('embeddedimage.php');
505
        $data = array();
506
507
508
509
        $view = $instance->get_view();
        foreach (array('owner', 'group', 'institution') as $f) {
            $data[$f] = $view->get($f);
        }
510

511
        if (empty($values['artefactid']) || $values['makecopy']) {
512
513
514
515
516
517
518
519
520
521
522
523
524
            // The artefact title will be the same as the block title when the
            // artefact is first created, or, if there's no block title, generate
            // 'Note (1)', 'Note (2)', etc.  After that, the artefact title can't
            // be edited inside the block, but can be changed in the Notes area.
            if (empty($values['title'])) {
                $title = artefact_new_title(
                    get_string('Note', 'artefact.internal'), 'html',
                    $data['owner'], $data['group'], $data['institution']
                );
            }
            else {
                $title = $values['title'];
            }
525
            safe_require('artefact', 'internal');
526
527
528
            $artefact = new ArtefactTypeHtml(0, $data);
            $artefact->set('title', $title);
            $artefact->set('description', $values['text']);
529
530
531
532
533
            if (get_config('licensemetadata')) {
                $artefact->set('license', $values['license']);
                $artefact->set('licensor', $values['licensor']);
                $artefact->set('licensorurl', $values['licensorurl']);
            }
534
            $artefact->set('allowcomments', (!empty($values['allowcomments']) ? $values['allowcomments'] : 0));
535
            $artefact->set('tags', $values['tags']);
536
        }
537
538
        else {
            $artefact = new ArtefactTypeHtml((int)$values['artefactid']);
539

540
541
542
            if (!$USER->can_publish_artefact($artefact)) {
                throw new AccessDeniedException(get_string('nopublishpermissiononartefact', 'mahara', hsc($artefact->get('title'))));
            }
543

544
            // Stop users from editing textbox artefacts whose owner is not the same as the
545
            // view owner, even if they would normally be allowed to edit the artefact.
546
            // It's too confusing.  Textbox artefacts with other owners *can* be included in
547
548
549
550
551
            // the view read-only, provided the artefact has the correct republish
            // permission.
            if ($artefact->get('owner') === $data['owner']
                && $artefact->get('group') === $data['group']
                && $artefact->get('institution') === $data['institution']
552
                && !$artefact->get('locked')
553
                && $USER->can_edit_artefact($artefact)) {
554
555
                $newdescription = EmbeddedImage::prepare_embedded_images($values['text'], 'textbox', (int)$values['artefactid'], $view->get('group'));
                $artefact->set('description', $newdescription);
556
557
558
559
560
                if (get_config('licensemetadata')) {
                    $artefact->set('license', $values['license']);
                    $artefact->set('licensor', $values['licensor']);
                    $artefact->set('licensorurl', $values['licensorurl']);
                }
561
                $artefact->set('tags', $values['tags']);
562
                $artefact->set('allowcomments', !empty($values['allowcomments']) ? 1 : 0);
563
            }
564
        }
565

566
567
        $artefact->commit();

568
569
570
571
572
573
574
575
576
        $newdescription = EmbeddedImage::prepare_embedded_images($values['text'], 'textbox', $artefact->get('id'), $view->get('group'));

        if ($newdescription !== $values['text']) {
            $updatedartefact = new stdClass();
            $updatedartefact->id = $artefact->get('id');
            $updatedartefact->description = $newdescription;
            update_record('artefact', $updatedartefact, 'id');
        }

577
        // Add attachments, if there are any...
578
        update_attachments($artefact, $values['artefactids'], null, null, true);
579

580
581
582
583
        $values['artefactid'] = $artefact->get('id');
        $instance->save_artefact_instance($artefact);

        unset($values['text']);
584
        unset($values['otherblocksmsg']);
585
586
        unset($values['readonlymsg']);
        unset($values['textreadonly']);
587
        unset($values['makecopy']);
588
        unset($values['chooseartefact']);
589
        unset($values['managenotes']);
590
        unset($values['allowcomments']);
591
        unset($values['tags']); // We save the tags against the artefact so don't need to save again against the block
592
593
594
595
596
597
598
599
600

        // Pass back a list of any other blocks that need to be rendered
        // due to this change.
        $values['_redrawblocks'] = array_unique(get_column(
            'view_artefact', 'block',
            'artefact', $values['artefactid'],
            'view', $instance->get('view')
        ));

601
        return $values;
602
603
    }

604
605
606
607
    public static function filebrowser_element(&$instance, $default=array()) {
        $element = ArtefactTypeFileBase::blockconfig_filebrowser_element($instance, $default);
        $element['title'] = get_string('attachments', 'artefact.blog');
        $element['name'] = 'artefactids';
608
        $element['config']['select'] = true;
609
        $element['config']['selectone'] = false;
610
        $element['config']['selectmodal'] = true;
611
        $element['config']['alwaysopen'] = false;
612
613
614
        return $element;
    }

615
    public static function default_copy_type(BlockInstance $instance, View $view) {
616
617
618
        return 'full';
    }

619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
    /**
     * The content of this block is now stored as an html artefact, but older versions stored
     * the content directly in the 'text' property of the block config.  If this config has
     * 'text' but not 'artefactid', create an artefact.
     *
     * @param array $biconfig   The block instance config
     * @param array $viewconfig The view config
     * @return BlockInstance The newly made block instance
     */
    public static function import_create_blockinstance_leap(array $biconfig, array $viewconfig) {
        $configdata = $biconfig['config'];

        if (isset($configdata['text']) && !isset($configdata['artefactid'])) {
            $data = array(
                'title'       => $biconfig['title'],
                'description' => $configdata['text'],
635
636
637
                'license' => (!empty($configdata['license'])) ? $configdata['license'] : '',
                'licensor' => (!empty($configdata['licensor'])) ? $configdata['licensor'] : '',
                'licensorurl' => (!empty($configdata['licensorurl'])) ? $configdata['licensorurl'] : '',
638
                'tags'        => (!empty($configdata['tags'])) ? $configdata['tags'] : '',
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
                'owner'       => $viewconfig['owner'],
            );
            $artefact = new ArtefactTypeHtml(0, $data);
            $artefact->commit();
            $configdata['artefactid'] = $artefact->get('id');
            unset($configdata['text']);
        }

        $bi = new BlockInstance(0,
            array(
                'blocktype'  => $biconfig['type'],
                'configdata' => $configdata,
            )
        );

        return $bi;
    }

    /**
     * Set the text property of the block config so that exports can be imported
     * into older versions.
     *
     * @param BlockInstance $bi The blockinstance to export the config for.
     * @return array The config for the blockinstance
     */
    public static function export_blockinstance_config_leap(BlockInstance $bi) {
        $configdata = $bi->get('configdata');

        $result = array();

        $text = '';
670
671
672
        $license = '';
        $licensor = '';
        $licensorurl = '';
673
        $tags = '';
674
675
676

        if (!empty($configdata['artefactid'])) {
            $result['artefactid'] = json_encode(array($configdata['artefactid']));
677
678
            $note = $bi->get_artefact_instance($configdata['artefactid']);
            $text = $note->get('description');
679
            $tags = $note->get('tags');
680
681
682
            $license = $note->get('license');
            $licensor = $note->get('licensor');
            $licensorurl = $note->get('licensorurl');
683
684
685
        }

        $result['text'] = json_encode(array($text));
686
        $result['tags'] = json_encode(array($tags));
687
688
689
        $result['license '] = json_encode(array($license));
        $result['licensor'] = json_encode(array($licensor));
        $result['licensorurl'] = json_encode(array($licensorurl));
690
691
692

        return $result;
    }
693
}