institutions.php 41.2 KB
Newer Older
1
2
3
4
5
<?php
/**
 *
 * @package    mahara
 * @subpackage admin
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
 *
 */
define('INTERNAL', 1);
12
define('INSTITUTIONALADMIN', 1);
13
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
14
define('TITLE', get_string('Institutions', 'admin'));
Penny Leach's avatar
Penny Leach committed
15
16
17
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'admin');
define('SECTION_PAGE', 'institutions');
18
require_once('pieforms/pieform.php');
19
require_once('license.php');
20
define('MENUITEM', 'manageinstitutions/institutions');
21
22
23

$institution = param_variable('i', '');
$add         = param_boolean('add');
24
25
$edit        = param_boolean('edit');
$delete      = param_boolean('delete');
26

27
28
29
30
$query = param_variable('query', '');
$offset = param_integer('offset', 0);
$limit  = 20;

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$customthemedefaults = array(
    'background'   => array('type' => 'color', 'value' => '#182768'),
    'backgroundfg' => array('type' => 'color', 'value' => '#FFFFFF'),
    'link'         => array('type' => 'color', 'value' => '#d66800'),
    'headings'     => array('type' => 'color', 'value' => '#182768'),
    'sidebarbg'    => array('type' => 'color', 'value' => '#182768'),
    'sidebarfg'    => array('type' => 'color', 'value' => '#f1f2f8'),
    'sidebarlink'  => array('type' => 'color', 'value' => '#182768'),
    'navbg'        => array('type' => 'color', 'value' => '#f6871f'),
    'navfg'        => array('type' => 'color', 'value' => '#FFFFFF'),
    'subbg'        => array('type' => 'color', 'value' => '#fff4ea'),
    'subfg'        => array('type' => 'color', 'value' => '#14336F'),
    'rowbg'        => array('type' => 'color', 'value' => '#fff4ea'),
);

46
47
48
49
50
51
52
53
54
55
56
if (!$USER->get('admin')) {
    // Institutional admins with only 1 institution go straight to the edit page for that institution
    // They cannot add or delete institutions, or edit an institution they don't administer
    $add = false;
    $delete = false;
    if (!empty($institution) && !$USER->is_institutional_admin($institution)) {
        $institution = '';
        $edit = false;
    }
    if (empty($institution) && count($USER->get('admininstitutions')) == 1) {
        redirect(get_config('wwwroot') . 'admin/users/institutions.php?i='
57
                 . key($USER->get('admininstitutions')));
58
59
60
    }
}

61
62
if ($institution || $add) {

63
64
65
66
67
    $authinstances = auth_get_auth_instances_for_institution($institution);
    if (false == $authinstances) {
        $authinstances = array();
    }

68
    if ($delete) {
69
        function delete_validate(Pieform $form, $values) {
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
            // Ensure the institution has no members left
            if ($members = get_field('usr_institution', 'COUNT(*)', 'institution', $values['i'])) {
                $form->set_error('submit', get_string('institutionstillhas', 'admin', get_string('nmembers', 'group', $members)));
            }

            // If some users are still using one of this institution's authinstances, it's okay if
            // we can find a default authinstance for those users, otherwise it's an error.
            if ($authinstanceids = get_column('auth_instance', 'id', 'institution', $values['i'])) {
                $badusers = count_records_select(
                    'usr',
                    'authinstance IN (' . join(',', array_fill(0, count($authinstanceids), '?')) . ')',
                    $authinstanceids
                );
                if ($badusers) {
                    $defaultauth = record_exists('auth_instance', 'institution', 'mahara', 'authname', 'internal');
                    if ($values['i'] == 'mahara' || !$defaultauth) {
                        $form->set_error(
                            'submit',
                            get_string('institutionauthinuseby', 'admin', get_string('nusers', 'mahara', $badusers))
                        );
                    }
                }
92
93
94
            }
        }

95
        function delete_cancel_submit() {
96
            redirect('/admin/users/institutions.php');
97
98
        }

99
        function delete_submit(Pieform $form, $values) {
100
101
            global $SESSION;

102
            $authinstanceids = get_column('auth_instance', 'id', 'institution', $values['i']);
103
104
            $viewids = get_column('view', 'id', 'institution', $values['i']);
            $artefactids = get_column('artefact', 'id', 'institution', $values['i']);
105
            $regdataids = get_column('institution_registration', 'id', 'institution', $values['i']);
106

107
            db_begin();
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
            if ($viewids) {
                require_once(get_config('libroot') . 'view.php');
                foreach ($viewids as $viewid) {
                    $view = new View($viewid);
                    $view->delete();
                }
            }
            if ($artefactids) {
                foreach ($artefactids as $artefactid) {
                    try {
                        $a = artefact_instance_from_id($artefactid);
                        $a->delete();
                    }
                    catch (ArtefactNotFoundException $e) {
                        // Awesome, it's already gone.
                    }
                }
            }
126
127
128
129
130
131
132
133
134
135
136
137
138

            // If any users are still using this institution's authinstances, change them now.
            if ($authinstanceids) {
                execute_sql("
                    UPDATE {usr}
                    SET authinstance = (
                        SELECT MIN(id) FROM {auth_instance} WHERE institution = 'mahara' AND authname = 'internal'
                    )
                    WHERE authinstance IN (" . join(',', array_fill(0, count($authinstanceids), '?')) . ')',
                    $authinstanceids
                );
            }

139
140
141
            foreach ($authinstanceids as $id) {
                delete_records('auth_instance_config', 'instance', $id);
            }
142

143
144
145
146
            foreach ($regdataids as $id) {
                delete_records('institution_registration_data', 'registration_id', $id);
            }

147
148
149
150
151
            // The institution should have been removed from favourites lists when the members were removed,
            // but make sure it's gone.
            execute_sql('DELETE FROM {favorite_usr} WHERE favorite IN (SELECT id FROM {favorite} WHERE institution = ?)', array($values['i']));
            delete_records('favorite', 'institution', $values['i']);

152
            execute_sql("UPDATE {group} SET institution = NULL, shortname = NULL WHERE institution = ?", array($values['i']));
153
154
            delete_records('auth_instance', 'institution', $values['i']);
            delete_records('host', 'institution', $values['i']);
155
            delete_records('institution_locked_profile_field', 'name', $values['i']);
156
            delete_records('usr_institution_request', 'institution', $values['i']);
157
            delete_records('view_access', 'institution', $values['i']);
158
159
            delete_records('institution_data', 'institution', $values['i']);
            delete_records('institution_registration', 'institution', $values['i']);
160
161
162
163
            delete_records('institution', 'name', $values['i']);
            db_commit();

            $SESSION->add_ok_msg(get_string('institutiondeletedsuccessfully', 'admin'));
164
            redirect('/admin/users/institutions.php');
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        }
        $form = array(
            'name' => 'delete',
            'elements' => array(
                'i' => array(
                    'type' => 'hidden',
                    'value' => $institution
                ),
                'delete' => array(
                    'type' => 'hidden',
                    'value' => 1
                ),
                'submit' => array(
                    'type' => 'submitcancel',
                    'value' => array(get_string('yes'), get_string('no'))
                )
            )
        );
183
184
185
        $deleteform = pieform($form);
        $smarty = smarty();
        $smarty->assign('delete_form', $deleteform);
186
        $smarty->assign('institutionname', get_field('institution', 'displayname', 'name', $institution));
187
        $smarty->display('admin/users/institutions.tpl');
188
189
190
        exit;
    }

191
192
193
    $instancearray = array();
    $instancestring = '';
    $c = count($authinstances);
194
    $inuse = '';
195

196
197
    $sitelockedfields = (array) get_column('institution_locked_profile_field', 'profilefield', 'name', 'mahara');

198
199
    if (!$add) {
        $data = get_record('institution', 'name', $institution);
200
        $lockedprofilefields = (array) get_column('institution_locked_profile_field', 'profilefield', 'name', $institution);
201

202
        // TODO: Find a better way to work around Smarty's minimal looping logic
203
204
205
206
        if (!empty($authinstances)) {
            foreach($authinstances as $key => $val) {
                $authinstances[$key]->index = $key;
                $authinstances[$key]->total = $c;
207
                $instancearray[] = (int)$val->id;
208
            }
209

210
211
            $instancestring = implode(',',$instancearray);
            $inuserecords = array();
212
213
            if ($records = get_records_sql_assoc('select authinstance, count(id) from {usr} where authinstance in ('.$instancestring.') group by authinstance', array())) {
                foreach ($records as $record) {
Richard Mansfield's avatar
Richard Mansfield committed
214
                    $inuserecords[] = $record->authinstance;
215
                }
216
217
            }
            $inuse = implode(',',$inuserecords);
218
        }
219
        $authtypes = auth_get_available_auth_types($institution);
220
221
222
223
    }
    else {
        $data = new StdClass;
        $data->displayname = '';
224
        $data->expiry = null;
225
226
        if (!get_config('usersuniquebyusername')) {
            $data->registerallowed = 1;
227
            $data->registerconfirm = 1;
228
        }
229
        $data->theme = 'sitedefault';
230
        $data->defaultmembershipperiod = null;
231
        $data->showonlineusers = 2;
232
        $data->allowinstitutionpublicviews = get_config('allowpublicviews') ? 1 : 0;
233
234
        $data->licensemandatory = 0;
        $data->licensedefault = '';
235
        $data->dropdownmenu = get_config('dropdownmenu') ? 1 : 0;
236
        $data->skins = get_config('skins') ? 1 : 0;
237
        $lockedprofilefields = array();
238
239

        $authtypes = auth_get_available_auth_types();
240
    }
241
    $themeoptions = get_institution_themes($institution);
242
    $themeoptions['sitedefault'] = '- ' . get_string('sitedefault', 'admin') . ' (' . $themeoptions[get_config('theme')] . ') -';
243
    uksort($themeoptions, 'theme_sort');
244

245
    $showonlineusersoptions = array('0' => get_string('none'), '1' => get_string('institutiononly', 'admin'), '2' => get_string('all', 'admin'));
246
247
    $sitename = get_config('sitename');

248
    safe_require('artefact', 'internal');
249
250
    $elements = array(
        'name' => array(
251
            'type' => 'text',
252
            'title' => get_string('institutionname', 'admin'),
253
254
255
            'rules' => array(
                'required'  => true,
                'maxlength' => 255,
256
                'regex'     => '/^[a-zA-Z]+$/'
257
            ),
Penny Leach's avatar
Penny Leach committed
258
259
            'ignore' => !$add,
            'help'   => true,
260
261
262
263
264
265
        ),
        'add' => array(
            'type'   => 'hidden',
            'value'  => true,
            'ignore' => !$add
        ),
266
267
268
        'inuse' => array(
            'type'   => 'hidden',
            'value'  => $inuse,
269
270
            'id'     => 'inuse',
            'ignore' => $add
271
        ),
272
273
274
275
276
277
278
279
280
281
282
283
        'i' => array(
            'type'   => 'hidden',
            'value'  => $institution,
            'ignore' => $add
        ),
        'displayname' => array(
            'type' => 'text',
            'title' => get_string('institutiondisplayname', 'admin'),
            'defaultvalue' => $data->displayname,
            'rules' => array(
                'required'  => true,
                'maxlength' => 255
Penny Leach's avatar
Penny Leach committed
284
285
            ),
            'help'   => true,
286
        ),
287
    );
288
    if ($USER->get('admin') && $institution != 'mahara') {
289
       $elements['expiry'] = array(
290
291
            'type'         => 'date',
            'title'        => get_string('institutionexpiry', 'admin'),
292
            'description'  => get_string('institutionexpirydescription', 'admin', hsc($sitename)),
293
294
295
296
            'defaultvalue' => is_null($data->expiry) ? null : strtotime($data->expiry),
            'help'         => true,
            'minyear'      => date('Y') - 2,
            'maxyear'      => date('Y') + 10,
297
298
        );
    }
299
300
    if ($USER->get('admin')) {
        $elements['authplugin'] = array(
301
302
303
304
305
            'type'    => 'authlist',
            'title'   => get_string('authplugin', 'admin'),
            'options' => $authinstances,
            'authtypes' => $authtypes,
            'instancearray' => $instancearray,
306
            'instancestring' => $instancestring,
307
308
            'institution' => $institution,
            'help'   => true,
309
            'ignore' => count($authtypes) == 0 || $institution == ''
310
311
312
        );
    }

313
    if (!$add && empty($authinstances)) {
314
        if ($USER->get('admin')) {
315
            $SESSION->add_error_msg(get_string('adminnoauthpluginforinstitution', 'admin'));
316
317
        }
        else {
318
            $SESSION->add_error_msg(get_string('noauthpluginforinstitution', 'admin'));
319
320
321
        }
    }

322
323
324
325
    if (!get_config('usersuniquebyusername')) {
        $elements['registerallowed'] = array(
            'type'         => 'checkbox',
            'title'        => get_string('registrationallowed', 'admin'),
326
            'description'  => get_string('registrationalloweddescription3', 'admin'),
327
328
329
            'defaultvalue' => $data->registerallowed,
            'help'   => true,
        );
330
331
332
333
334
335
        $elements['registerconfirm'] = array(
            'type'         => 'checkbox',
            'title'        => get_string('registrationconfirm', 'admin'),
            'description'  => get_string('registrationconfirmdescription', 'admin'),
            'defaultvalue' => $data->registerconfirm,
        );
336
    }
337

338
    // Some fields to hide from the default institution config screen
339
    if (empty($data->name) || $data->name != 'mahara') {
340
        $elements['defaultmembershipperiod'] = array(
341
            'type'         => 'expiry',
342
343
344
            'title'        => get_string('defaultmembershipperiod', 'admin'),
            'description'  => get_string('defaultmembershipperioddescription', 'admin'),
            'defaultvalue' => $data->defaultmembershipperiod,
Penny Leach's avatar
Penny Leach committed
345
            'help'   => true,
346
        );
347
348
349
350
351
352
353
354
355
356
357
358
        $elements['logo'] = array(
            'type'        => 'file',
            'title'       => get_string('Logo', 'admin'),
            'description' => get_string('logodescription', 'admin'),
            'maxfilesize' => get_max_upload_size(false),
        );
        if (!empty($data->logo)) {
            $logourl = get_config('wwwroot') . 'thumb.php?type=logobyid&id=' . $data->logo;
            $elements['logohtml'] = array(
                'type'        => 'html',
                'value'       => '<img src="' . $logourl . '" alt="' . get_string('Logo', 'admin') . '">',
            );
359
360
361
362
363
            $elements['deletelogo'] = array(
                'type'        => 'checkbox',
                'title'       => get_string('deletelogo', 'admin'),
                'description' => get_string('deletelogodescription', 'admin'),
            );
364
        }
365
366
367
        if (!empty($data->style)) {
            $customtheme = get_records_menu('style_property', 'style', $data->style, '', 'field,value');
        }
368
        $elements['theme'] = array(
369
            'type'         => 'select',
370
            'title'        => get_string('theme'),
371
            'description'  => get_string('sitethemedescription','admin'),
372
            'defaultvalue' => $data->theme ? $data->theme : 'sitedefault',
373
374
375
            'collapseifoneoption' => true,
            'options'      => $themeoptions,
            'help'         => true,
376
        );
377
378
379
380
381
382
383
384
385
386
387
388
389
        $elements['customthemefs'] = array(
            'type'         => 'fieldset',
            'class'        => 'customtheme' . ($elements['theme']['defaultvalue'] != 'custom' ? ' js-hidden' : ''),
            'legend'       => get_string('customtheme', 'admin'),
            'elements'     => array(),
        );
        foreach ($customthemedefaults as $name => $styledata) {
            $elements['customthemefs']['elements'][$name] = array(
                'type'         => $styledata['type'],
                'title'        => get_string('customtheme.' . $name, 'admin'),
                'defaultvalue' => isset($customtheme[$name]) ? $customtheme[$name] : $styledata['value'],
            );
        }
390
391
392
393
394
395
        $elements['customthemefs']['elements']['resetcustom'] = array(
            'type'         => 'checkbox',
            'class'        => 'nojs-hidden-inline',
            'title'        => get_string('resetcolours', 'admin'),
            'description'  => get_string('resetcoloursdesc', 'admin'),
        );
396
397
398
399
400
401
402
        $elements['dropdownmenu'] = array(
            'type'         => 'checkbox',
            'title'        => get_string('dropdownmenu', 'admin'),
            'description'  => get_string('dropdownmenudescriptioninstitution','admin'),
            'defaultvalue' => $data->dropdownmenu,
            'help'         => true,
        );
403
404
405
406
407
408
409
410
411
412
413
414
    }
    // The skins checkbox should be shown for the default institution
    if (get_config('skins')) {
        $elements['skins'] = array(
            'type' => 'checkbox',
            'title' => get_string('skins', 'admin'),
            'description' => get_string('skinsinstitutiondescription', 'admin'),
            'defaultvalue' => $data->skins,
        );
    }
    // Some more fields that are hidden from the default institution
    if (empty($data->name) || $data->name != 'mahara') {
415
416
        $elements['showonlineusers'] = array(
            'type'                  => 'select',
417
            'disabled'              => get_config('showonlineuserssideblock') ? '' : 'disabled',
418
            'title'                 => get_string('showonlineusers', 'admin'),
419
            'description'           => get_string('showonlineusersdescription','admin'),
420
421
422
423
            'defaultvalue'          => $data->showonlineusers,
            'collapseifoneoption'   => true,
            'options'               => $showonlineusersoptions,
        );
424
425
426
427
428
429
430
431
432
433
434
435
436
437
        if (get_config('licensemetadata')) {
            $elements['licensemandatory'] = array(
                'type'         => 'checkbox',
                'title'        => get_string('licensemandatory', 'admin'),
                'description'  => get_string('licensemandatorydescription','admin'),
                'defaultvalue' => $data->licensemandatory,
            );
            $elements['licensedefault'] = license_form_el_basic(null, true);
            $elements['licensedefault']['title'] = get_string('licensedefault','admin');
            $elements['licensedefault']['description'] = get_string('licensedefaultdescription','admin');
            if ($data->licensedefault) {
                $elements['licensedefault']['defaultvalue'] = $data->licensedefault;
            }
        }
438
439
440
441
442
443
444
        if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
            $elements['defaultquota'] = array(
               'type'         => 'bytes',
               'title'        => get_string('defaultquota', 'artefact.file'),
               'description'  => get_string('defaultinstitutionquotadescription', 'admin'),
               'defaultvalue' => !empty($data->defaultquota) ? $data->defaultquota : get_config_plugin('artefact', 'file', 'defaultquota'),
            );
445
446
447
448
449
            $elements['updateuserquotas'] = array(
                'title'        => get_string('updateuserquotas', 'artefact.file'),
                'description'  => get_string('updateinstitutionuserquotasdesc', 'admin'),
                'type'         => 'checkbox',
            );
450
451
452
453
454
455
456
457
458
        }
        else {
            $elements['defaultquota'] = array(
                'type' => 'text',
                'title' => get_string('defaultquota', 'artefact.file'),
                'value' => display_size(!empty($data->defaultquota) ? $data->defaultquota : get_config_plugin('artefact', 'file', 'defaultquota')),
                'disabled' => true,
            );
        }
459
460
461
462
463
464
465
466
467
468

        $elements['allowinstitutionpublicviews'] = array(
            'type'         => 'checkbox',
            'title'        => get_string('allowinstitutionpublicviews', 'admin'),
            'description'  => get_string('allowinstitutionpublicviewsdescription','admin'),
            'defaultvalue' => get_config('allowpublicviews') && $data->allowinstitutionpublicviews,
            'disabled'     => get_config('allowpublicviews') == false,
            'help'         => true,
        );

469
470
471
472
473
474
        if ($USER->get('admin')) {
            $elements['maxuseraccounts'] = array(
                'type'         => 'text',
                'title'        => get_string('maxuseraccounts','admin'),
                'description'  => get_string('maxuseraccountsdescription','admin'),
                'defaultvalue' => empty($data->maxuseraccounts) ? '' : $data->maxuseraccounts,
475
476
477
478
479
                'rules'        => array(
                    'regex'     => '/^\d*$/',
                    'maxlength' => 8,
                ),
                'size'         => 5,
480
481
            );
        }
482
    }
483

484
    $elements['lockedfields'] = array(
485
        'type' => 'fieldset',
486
        'legend' => get_string('Lockedfields', 'admin'),
487
488
489
        'collapsible' => true,
        'collapsed' => true,
        'elements' => array(),
490
    );
491
492
493
494
495
496
    if ($institution != 'mahara') {
        $elements['lockedfields']['elements']['description'] = array(
            'type' => 'html',
            'value' => get_string('disabledlockedfieldhelp', 'admin', get_field('institution', 'displayname', 'name', 'mahara')),
        );
    }
497
    foreach (ArtefactTypeProfile::get_all_fields() as $field => $type) {
498
        $elements['lockedfields']['elements'][$field] = array(
499
            'type' => 'checkbox',
500
            'title' => get_string($field, 'artefact.internal'),
501
502
            'defaultvalue' => in_array($field, $lockedprofilefields) || ($institution != 'mahara' && in_array($field, $sitelockedfields)),
            'disabled' => $institution != 'mahara' && in_array($field, $sitelockedfields)
503
504
        );
    }
505
    $elements['lockedfieldshelp'] = array(
Evonne Cheung's avatar
Evonne Cheung committed
506
        'value' => '<tr id="lockedfieldshelp"><th colspan="2">'
507
        . get_help_icon('core', 'admin', 'institution', 'lockedfields')
508
509
510
        . '</th></tr>'
    );

511
512
513
514
515
    $elements['submit'] = array(
        'type' => 'submitcancel',
        'value' => array(get_string('submit'), get_string('cancel'))
    );

516
    $institutionform = pieform(array(
517
        'name'     => 'institution',
518
        'renderer' => 'table',
Penny Leach's avatar
Penny Leach committed
519
520
        'plugintype' => 'core',
        'pluginname' => 'admin',
521
        'elements' => $elements
522
    ));
523
524
525
526

}
else {
    // Get a list of institutions
527
    require_once(get_config('libroot') . 'institution.php');
528
    if (!$USER->get('admin')) { // Filter the list for institutional admins
529
530
        $filter      = $USER->get('admininstitutions');
        $showdefault = false;
531
532
    }
    else {
533
534
        $filter      = false;
        $showdefault = true;
535
    }
536
    $data = build_institutions_html($filter, $showdefault, $query, $limit, $offset, $count);
537
538

    $smarty = smarty(array('lib/pieforms/static/core/pieforms.js', 'paginator'));
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
    $smarty->assign('results', $data);
    $smarty->assign('countinstitutions', $count);

    /*search institution form*/
    $searchform = pieform(array(
        'name' => 'search',
        'renderer' => 'oneline',
        'elements' => array(
            'query' => array(
                'type' => 'text',
                'defaultvalue' => $query
            ),
            'submit' => array(
                'type' => 'submit',
                'value' => get_string('search')
            )
        )
    ));
    $smarty->assign('searchform', $searchform);

    $js = <<< EOF
    addLoadEvent(function () {
    p = {$data['pagination_js']}
    connect('search_submit', 'onclick', function (event) {
        replaceChildNodes('messages');
        var params = {'query': $('search_query').value};
        p.sendQuery(params);
        event.stop();
        });
    });
EOF;

    $smarty->assign('INLINEJAVASCRIPT', $js);
572
573
574
575
    $smarty->assign('siteadmin', $USER->get('admin'));
    $smarty->assign('PAGEHEADING', get_string('admininstitutions', 'admin'));
    $smarty->display('admin/users/institutions.tpl');
    exit;
576
577
}

578
function institution_validate(Pieform $form, $values) {
579
580
    global $USER;

581
    if (!empty($values['name']) && !$form->get_error('name') && record_exists('institution', 'name', $values['name'])) {
582
583
        $form->set_error('name', get_string('institutionnamealreadytaken', 'admin'));
    }
584
585
586
587
    if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
        if (get_config_plugin('artefact', 'file', 'maxquotaenabled') && get_config_plugin('artefact', 'file', 'maxquota') < $values['defaultquota']) {
            $form->set_error('defaultquota', get_string('maxquotatoolow', 'artefact.file'));
        }
588
    }
589

590
591
    if (get_config('licensemetadata') && !empty($values['licensemandatory']) &&
        (isset($values['licensedefault']) && $values['licensedefault'] == '')) {
592
593
594
        $form->set_error('licensedefault', get_string('licensedefaultmandatory', 'admin'));
    }

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
    // Check uploaded logo
    if (!empty($values['logo'])) {
        require_once('file.php');
        require_once('uploadmanager.php');
        $um = new upload_manager('logo');
        if ($error = $um->preprocess_file()) {
            $form->set_error('logo', $error);
            return false;
        }

        $imageinfo = getimagesize($values['logo']['tmp_name']);
        if (!$imageinfo || !is_image_type($imageinfo[2])) {
            $form->set_error('logo', get_string('filenotimage'));
            return false;
        }

        // Check the file isn't greater than the max allowable size
        $width          = $imageinfo[0];
        $height         = $imageinfo[1];
        $imagemaxwidth  = get_config('imagemaxwidth');
        $imagemaxheight = get_config('imagemaxheight');
        if ($width > $imagemaxwidth || $height > $imagemaxheight) {
            $form->set_error('logo', get_string('profileiconimagetoobig', 'artefact.file', $width, $height, $imagemaxwidth, $imagemaxheight));
        }
    }
620
621
}

622
function institution_submit(Pieform $form, $values) {
623
    global $SESSION, $institution, $add, $instancearray, $USER, $authinstances, $customthemedefaults;
624
625
626
627

    db_begin();
    // Update the basic institution record...
    if ($add) {
628
629
630
        $newinstitution = new Institution();
        $newinstitution->initialise($values['name'], $values['displayname']);
        $institution = $newinstitution->name;
631
    }
632
    else {
633
634
        $newinstitution = new Institution($institution);
        $newinstitution->displayname = $values['displayname'];
635
636
        $oldinstitution = get_record('institution', 'name', $institution);
    }
637

638
    $newinstitution->showonlineusers              = !isset($values['showonlineusers']) ? 2 : $values['showonlineusers'];
639
640
641
642
643
644
645
646
    if (get_config('usersuniquebyusername')) {
        // Registering absolutely not allowed when this setting is on, it's a 
        // security risk. See the documentation for the usersuniquebyusername 
        // setting for more information
        $newinstitution->registerallowed = 0;
    }
    else {
        $newinstitution->registerallowed              = ($values['registerallowed']) ? 1 : 0;
647
        $newinstitution->registerconfirm              = ($values['registerconfirm']) ? 1 : 0;
648
    }
649
    $newinstitution->theme                        = (empty($values['theme']) || $values['theme'] == 'sitedefault') ? null : $values['theme'];
650
651
    $newinstitution->dropdownmenu                 = (!empty($values['dropdownmenu'])) ? 1 : 0;
    $newinstitution->skins                 = (!empty($values['skins'])) ? 1 : 0;
652

653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
    if ($newinstitution->theme == 'custom') {
        if (!empty($oldinstitution->style)) {
            $styleid = $oldinstitution->style;
            delete_records('style_property', 'style', $styleid);
        }
        else {
            $record = (object) array('title' => get_string('customstylesforinstitution', 'admin', $newinstitution->displayname));
            $styleid = insert_record('style', $record, 'id', true);
        }

        $properties = array();
        $record = (object) array('style' => $styleid);
        foreach (array_keys($customthemedefaults) as $name) {
            $record->field = $name;
            $record->value = $values[$name];
            insert_record('style_property', $record);
            $properties[$name] = $values[$name];
        }

        // Cache the css
        $smarty = smarty_core();
        $smarty->assign('data', $properties);
        set_field('style', 'css', $smarty->fetch('customcss.tpl'), 'id', $styleid);

        $newinstitution->style = $styleid;
    }
    else {
        $newinstitution->style = null;
    }

683
    if (get_config('licensemetadata')) {
684
685
        $newinstitution->licensemandatory = (!empty($values['licensemandatory'])) ? 1 : 0;
        $newinstitution->licensedefault = (isset($values['licensedefault'])) ? $values['licensedefault'] : '';
686
687
    }

688
689
690
691
    if (!empty($values['resetcustom']) && !empty($oldinstitution->style)) {
        $newinstitution->style = null;
    }

692
    if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
693
694
695
696
697
698
        if (!empty($values['updateuserquotas']) && !empty($values['defaultquota'])) {
            execute_sql(
                "UPDATE {usr} SET quota = ? WHERE id IN (SELECT usr FROM {usr_institution} WHERE institution = ?)",
                array($values['defaultquota'], $institution)
            );
        }
699
        $newinstitution->defaultquota = empty($values['defaultquota']) ? get_config_plugin('artefact', 'file', 'defaultquota') : $values['defaultquota'];
700
    }
701
702
703
704
    if ($institution != 'mahara') {
        $newinstitution->defaultmembershipperiod  = ($values['defaultmembershipperiod']) ? intval($values['defaultmembershipperiod']) : null;
        if ($USER->get('admin')) {
            $newinstitution->maxuseraccounts      = ($values['maxuseraccounts']) ? intval($values['maxuseraccounts']) : null;
705
            $newinstitution->expiry               = db_format_timestamp($values['expiry']);
706
        }
707
708
    }

709
710
    $newinstitution->allowinstitutionpublicviews  = (isset($values['allowinstitutionpublicviews']) && $values['allowinstitutionpublicviews']) ? 1 : 0;

711
    // TODO: Move handling of authentication instances within the Institution class as well?
712
713
    if (!empty($values['authplugin'])) {
        $allinstances = array_merge($values['authplugin']['instancearray'], $values['authplugin']['deletearray']);
714

715
        if (array_diff($allinstances, $instancearray)) {
716
            throw new ConfigException('Attempt to delete or update another institution\'s auth instance');
717
        }
718

719
        if (array_diff($instancearray, $allinstances)) {
720
            throw new ConfigException('One of your instances is unaccounted for in this transaction');
721
722
        }

723
724
725
        foreach($values['authplugin']['instancearray'] as $priority => $instanceid) {
            if (in_array($instanceid, $values['authplugin']['deletearray'])) {
                // Should never happen:
726
                throw new SystemException('Attempt to update AND delete an auth instance');
727
728
729
730
731
732
733
734
            }
            $record = new StdClass;
            $record->priority = $priority;
            $record->id = $instanceid;
            update_record('auth_instance', $record,  array('id' => $instanceid));
        }

        foreach($values['authplugin']['deletearray'] as $instanceid) {
735
736
737
738
            // If this authinstance is the only xmlrpc authinstance that references a host, delete the host record.
            $hostwwwroot = null;
            foreach ($authinstances as $ai) {
                if ($ai->id == $instanceid && $ai->authname == 'xmlrpc') {
Francois Marier's avatar
Francois Marier committed
739
740
                    $hostwwwroot = get_field_sql("SELECT \"value\" FROM {auth_instance_config} WHERE \"instance\" = ? AND field = 'wwwroot'", array($instanceid));
                    if ($hostwwwroot && count_records_select('auth_instance_config', "field = 'wwwroot' AND \"value\" = ?", array($hostwwwroot)) == 1) {
741
742
743
744
745
746
747
748
749
                        // Unfortunately, it's possible that this host record could belong to a different institution,
                        // so specify the institution here.
                        delete_records('host', 'wwwroot', $hostwwwroot, 'institution', $institution);
                        // We really need to fix this, either by removing the institution from the host table, or refusing to allow the
                        // institution to be changed in the host record when another institution's authinstance is still pointing at it.
                    }
                    break;
                }
            }
750
751
752
            delete_records('auth_remote_user', 'authinstance', $instanceid);
            delete_records('auth_instance_config', 'instance', $instanceid);
            delete_records('auth_instance', 'id', $instanceid);
753
754
            // Make it no longer be the parent authority to any auth instances
            delete_records('auth_instance_config', 'field', 'parent', 'value', $instanceid);
755
        }
756
757
    }

758
759
760
    // Save the changes to the DB
    $newinstitution->commit();

761
    if ($add) {
762
        // If registration has been turned on, then we automatically insert an
763
764
765
766
767
768
769
770
771
772
        // internal authentication authinstance
        if ($newinstitution->registerallowed) {
            $authinstance = (object)array(
                'instancename' => 'internal',
                'priority'     => 0,
                'institution'  => $newinstitution->name,
                'authname'     => 'internal',
            );
            insert_record('auth_instance', $authinstance);
        }
773
774
    }

775
776
777
778
779
    if (is_null($newinstitution->style) && !empty($oldinstitution->style)) {
        delete_records('style_property', 'style', $oldinstitution->style);
        delete_records('style', 'id', $oldinstitution->style);
    }

780
781
    // Set the logo after updating the institution, because the institution
    // needs to exist before it can own the logo artefact.
782
    if (!empty($values['logo'])) {
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
        safe_require('artefact', 'file');

        // Entry in artefact table
        $data = (object) array(
            'institution' => $institution,
            'title'       => 'logo',
            'description' => 'Institution logo',
            'note'        => $values['logo']['name'],
            'size'        => $values['logo']['size'],
        );

        $imageinfo      = getimagesize($values['logo']['tmp_name']);
        $data->width    = $imageinfo[0];
        $data->height   = $imageinfo[1];
        $data->filetype = $imageinfo['mime'];
        $artefact = new ArtefactTypeProfileIcon(0, $data);
        if (preg_match("/\.([^\.]+)$/", $values['logo']['name'], $saved)) {
            $artefact->set('oldextension', $saved[1]);
        }
        $artefact->commit();

        $id = $artefact->get('id');

        // Move the file into the correct place.
        $directory = get_config('dataroot') . 'artefact/file/profileicons/originals/' . ($id % 256) . '/';
        check_dir_exists($directory);
        move_uploaded_file($values['logo']['tmp_name'], $directory . $id);

        // Delete the old logo
        if (!empty($oldinstitution->logo)) {
            $oldlogo = new ArtefactTypeProfileIcon($oldinstitution->logo);
            $oldlogo->delete();
        }

        set_field('institution', 'logo', $id, 'name', $institution);
    }

820
821
822
823
    if (!empty($values['deletelogo'])) {
        execute_sql("UPDATE {institution} SET logo = NULL WHERE name = ?", array($institution));
    }

824
825
826
827
828
829
830
831
832
833
834
    delete_records('institution_locked_profile_field', 'name', $institution);
    foreach (ArtefactTypeProfile::get_all_fields() as $field => $type) {
        if ($values[$field]) {
            $profilefield = new StdClass;
            $profilefield->name         = $institution;
            $profilefield->profilefield = $field;
            insert_record('institution_locked_profile_field', $profilefield);
        }
    }
    db_commit();

835
    if ($add) {
836
        if (!$newinstitution->registerallowed) {
837
838
839
840
841
            // If registration is not allowed, then an authinstance will not 
            // have been created, and thus cause the institution page to add 
            // its own error message on the next page load
            $SESSION->add_ok_msg(get_string('institutionaddedsuccessfully2', 'admin'));
        }
842
843
844
        $nexturl = '/admin/users/institutions.php?i='.urlencode($institution);
    }
    else {
845
        $message = get_string('institutionupdatedsuccessfully', 'admin');
846
847
848
849
850
851
        if (isset($values['theme'])) {
            $changedtheme = $oldinstitution->theme != $values['theme']
                && (!empty($oldinstitution->theme) || $values['theme'] != 'sitedefault');
            if ($changedtheme || $values['theme'] == 'custom') {
                $message .= '  ' . get_string('usersseenewthemeonlogin', 'admin');
            }
852
            $USER->reset_institutions();
853
        }
854
        $SESSION->add_ok_msg($message);
855
856
857
858
        $nexturl = '/admin/users/institutions.php';
    }

    redirect($nexturl);
859
860
861
}

function institution_cancel_submit() {
862
    redirect('/admin/users/institutions.php');
863
864
}

865
866
867
868
869
870
871
872
873
874
875
876
877
878
if ($institution && $institution != 'mahara') {
    $_institution = get_record('institution', 'name', $institution);
    $suspended = $_institution->suspended;
    if ($USER->get('admin')) {
        function institution_suspend_submit(Pieform $form, $values) {
            global $SESSION, $USER;
            if (!$USER->get('admin')) {
                $SESSION->add_error_msg(get_string('errorwhilesuspending', 'admin'));
            }
            else {
                set_field('institution', 'suspended', 1, 'name', $values['i']);
                $SESSION->add_ok_msg(get_string('institutionsuspended', 'admin'));
            }
            redirect('/admin/users/institutions.php?i=' . $values['i']);
879
        }
880
881
882
883
884
885
886
887
888
889
890

        function institution_unsuspend_submit(Pieform $form, $values) {
            global $SESSION, $USER;
            if (!$USER->get('admin')) {
                $SESSION->add_error_msg(get_string('errorwhileunsuspending', 'admin'));
            }
            else {
                set_field('institution', 'suspended', 0, 'name', $values['i']);
                $SESSION->add_ok_msg(get_string('institutionunsuspended', 'admin'));
            }
            redirect('/admin/users/institutions.php?i=' . $values['i']);
891
        }
892

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
        // Suspension controls
        if (empty($suspended)) {
            $suspendformdef = array(
                'name'       => 'institution_suspend',
                'plugintype' => 'core',
                'pluginname' => 'admin',
                'elements'   => array(
                    'i' => array(
                        'type'    => 'hidden',
                        'value'   => $institution,
                    ),
                    'submit' => array(
                        'type'        => 'submit',
                        'value'       => get_string('suspendinstitution','admin'),
                        'description' => get_string('suspendinstitutiondescription','admin'),
                    ),
                )
            );

            $suspendform  = pieform($suspendformdef);
913
914
        }
        else {
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
            $suspendformdef = array(
                'name'       => 'institution_unsuspend',
                'plugintype' => 'core',
                'pluginname' => 'admin',
                'elements'   => array(
                    'i' => array(
                        'type'    => 'hidden',
                        'value'   => $institution,
                    ),
                    'submit' => array(
                        'type'        => 'submit',
                        'value'       => get_string('unsuspendinstitution','admin'),
                        'description' => get_string('unsuspendinstitutiondescription','admin'),
                    ),
                )
            );
            $suspendform  = pieform($suspendformdef);

            // Create a second forms for unsuspension to go in the suspend message.
            // This keeps the HTML IDs unique
            $suspendformdef['name'] = 'institution_unsuspend_top';
            $suspendformdef['renderer'] = 'oneline';
            $suspendformdef['successcallback'] = 'institution_unsuspend_submit';
            $suspendform_top = pieform($suspendformdef);
        }
940
941
942
    }
}

943
function search_submit(Pieform $form, $values) {
944
    redirect('/admin/users/institutions.php' . ((isset($values['query']) && ($values['query'] != '')) ? '?query=' . urlencode($values['query']) : ''));
945
946
}

947
948
949
950
951
952
953
954
955
956
957
958
959
960
// Hide custom colour boxes unless theme selector is on 'custom'
$customthemejs = '
$j(function() {
    $j("#institution_theme").change(function() {
        if ($(this).value == "custom") {
            $j(".customtheme").removeClass("js-hidden");
        }
        else {
            $j(".customtheme").addClass("js-hidden");
        }
    });
});
';

961
$smarty = smarty();
962
$smarty->assign('INLINEJAVASCRIPT', $customthemejs);
963
964
965
$smarty->assign('institution_form', $institutionform);
$smarty->assign('instancestring', $instancestring);
$smarty->assign('add', $add);
966
967
968
969
970
971

if (isset($suspended)) {
    if ($suspended) {
        $smarty->assign('suspended', get_string('suspendedinstitutionmessage', 'admin'));
    }
    if (isset($suspendform)) {
972
973
974
        $smarty->assign('suspendform', $suspendform);
        if (isset($suspendform_top)) {
            $smarty->assign('suspendform_top', $suspendform_top);
975
        }
976
977
978
    }
}

979
$smarty->assign('PAGEHEADING', get_string('admininstitutions', 'admin'));
980
$smarty->display('admin/users/institutions.tpl');
981

982
983
984
985
986
987
988
989
990
function theme_sort($a, $b) {
    if ($a == 'sitedefault') {
        return -1;
    }
    if ($b == 'sitedefault') {
        return 1;
    }
    return $a > $b;
}