institutions.php 16.8 KB
Newer Older
1
2
<?php
/**
Francois Marier's avatar
Francois Marier committed
3
 * Mahara: Electronic portfolio, weblog, resume builder and social networking
4
 * Copyright (C) 2006-2008 Catalyst IT Ltd (http://www.catalyst.net.nz)
5
 *
Francois Marier's avatar
Francois Marier committed
6
7
8
9
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
10
 *
Francois Marier's avatar
Francois Marier committed
11
12
13
14
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
15
 *
Francois Marier's avatar
Francois Marier committed
16
17
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
20
 *
 * @package    mahara
 * @subpackage admin
21
 * @author     Catalyst IT Ltd
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
23
 * @copyright  (C) 2006-2008 Catalyst IT Ltd http://catalyst.net.nz
24
25
26
 *
 */
define('INTERNAL', 1);
27
define('INSTITUTIONALADMIN', 1);
28
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
Martyn Smith's avatar
Martyn Smith committed
29
define('TITLE', get_string('institutions', 'admin'));
Penny Leach's avatar
Penny Leach committed
30
31
32
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'admin');
define('SECTION_PAGE', 'institutions');
33
require_once('pieforms/pieform.php');
34
define('MENUITEM', 'manageinstitutions/institutions');
35
36
37
38
$smarty = smarty();

$institution = param_variable('i', '');
$add         = param_boolean('add');
39
40
$edit        = param_boolean('edit');
$delete      = param_boolean('delete');
41

42
43
44
45
46
47
48
49
50
51
52
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='
53
                 . key($USER->get('admininstitutions')));
54
55
56
    }
}

57
58
if ($institution || $add) {

59
60
61
62
63
    $authinstances = auth_get_auth_instances_for_institution($institution);
    if (false == $authinstances) {
        $authinstances = array();
    }

64
    if ($delete) {
65
        function delete_validate(Pieform $form, $values) {
66
            if (get_field('usr_institution', 'COUNT(*)', 'institution', $values['i'])) {
67
                // TODO: exception is of the wrong type
68
69
70
71
                throw new Exception('Attempt to delete an institution that has members');
            }
        }

72
        function delete_cancel_submit() {
73
            redirect('/admin/users/institutions.php');
74
75
        }

76
        function delete_submit(Pieform $form, $values) {
77
78
            global $SESSION;

79
80
            $authinstanceids = get_column('auth_instance', 'id', 'institution', $values['i']);

81
            db_begin();
82
83
84
85
86
            foreach ($authinstanceids as $id) {
                delete_records('auth_instance_config', 'instance', $id);
            }
            delete_records('auth_instance', 'institution', $values['i']);
            delete_records('host', 'institution', $values['i']);
87
            delete_records('institution_locked_profile_field', 'name', $values['i']);
88
            delete_records('usr_institution_request', 'institution', $values['i']);
89
90
91
92
            delete_records('institution', 'name', $values['i']);
            db_commit();

            $SESSION->add_ok_msg(get_string('institutiondeletedsuccessfully', 'admin'));
93
            redirect('/admin/users/institutions.php');
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
        }
        $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'))
                )
            )
        );
        $smarty->assign('delete_form', pieform($form));
113
        $smarty->display('admin/users/institutions.tpl');
114
115
116
        exit;
    }

117
118
119
    $instancearray = array();
    $instancestring = '';
    $c = count($authinstances);
120
    $inuse = '';
121

122
123
    if (!$add) {
        $data = get_record('institution', 'name', $institution);
124
        $lockedprofilefields = (array) get_column('institution_locked_profile_field', 'profilefield', 'name', $institution);
125
126
        
        // TODO: Find a better way to work around Smarty's minimal looping logic
127
128
129
130
131
132
        if (!empty($authinstances)) {
            foreach($authinstances as $key => $val) {
                $authinstances[$key]->index = $key;
                $authinstances[$key]->total = $c;
                $instancearray[] = $val->id;
            }
133

134
135
            $instancestring = implode(',',$instancearray);
            $inuserecords = array();
136
137
            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
138
                    $inuserecords[] = $record->authinstance;
139
                }
140
141
            }
            $inuse = implode(',',$inuserecords);
142
        }
143
        $authtypes = auth_get_available_auth_types($institution);
144
145
146
147
148
    }
    else {
        $data = new StdClass;
        $data->displayname = '';
        $data->registerallowed = 1;
149
        $data->theme = 'sitedefault';
150
        $data->defaultmembershipperiod = null;
151
152
        $lockedprofilefields = array();
        $smarty->assign('add', true);
153
154

        $authtypes = auth_get_available_auth_types();
155
    }
156
    $themeoptions = get_themes();
157
    $themeoptions['sitedefault'] = '- ' . get_string('sitedefault', 'admin') . ' (' . $themeoptions[get_config('theme')] . ') -';
158
    uksort($themeoptions, 'theme_sort');
159
160
    
    safe_require('artefact', 'internal');
161
162
    $elements = array(
        'name' => array(
163
            'type' => 'text',
164
            'title' => get_string('institutionname', 'admin'),
165
166
167
            'rules' => array(
                'required'  => true,
                'maxlength' => 255,
168
                'regex'     => '/^[a-zA-Z]+$/'
169
            ),
Penny Leach's avatar
Penny Leach committed
170
171
            'ignore' => !$add,
            'help'   => true,
172
173
174
175
176
177
        ),
        'add' => array(
            'type'   => 'hidden',
            'value'  => true,
            'ignore' => !$add
        ),
178
179
180
        'inuse' => array(
            'type'   => 'hidden',
            'value'  => $inuse,
181
182
            'id'     => 'inuse',
            'ignore' => $add
183
        ),
184
185
186
187
188
189
190
191
192
193
194
195
        '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
196
197
            ),
            'help'   => true,
198
199
200
201
202
203
204
        ),
        'authplugin' => array(
            'type'    => 'authlist',
            'title'   => get_string('authplugin', 'admin'),
            'options' => $authinstances,
            'authtypes' => $authtypes,
            'instancearray' => $instancearray,
205
            'instancestring' => $instancestring,
206
207
            'institution' => $institution,
            'help'   => true,
208
            'ignore' => count($authtypes) == 0 || $institution == ''
209
        ),
210
211
212
213
        'registerallowed' => array(
            'type'         => 'checkbox',
            'title'        => get_string('registrationallowed', 'admin'),
            'description'  => get_string('registrationalloweddescription', 'admin'),
214
            'defaultvalue' => $data->registerallowed,
Penny Leach's avatar
Penny Leach committed
215
            'help'   => true,
216
        ),
217
218
    );

219
    if (empty($data->name) || $data->name != 'mahara') {
220
        $elements['defaultmembershipperiod'] = array(
221
            'type'         => 'expiry',
222
223
224
            'title'        => get_string('defaultmembershipperiod', 'admin'),
            'description'  => get_string('defaultmembershipperioddescription', 'admin'),
            'defaultvalue' => $data->defaultmembershipperiod,
Penny Leach's avatar
Penny Leach committed
225
            'help'   => true,
226
227
        );
        $elements['theme'] = array(
228
229
230
            'type'         => 'select',
            'title'        => get_string('theme','admin'),
            'description'  => get_string('sitethemedescription','admin'),
231
            'defaultvalue' => $data->theme ? $data->theme : 'sitedefault',
232
233
234
            'collapseifoneoption' => true,
            'options'      => $themeoptions,
            'help'         => true,
235
        );
236
237
238
239
240
241
        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,
242
243
244
245
246
                'rules'        => array(
                    'regex'     => '/^\d*$/',
                    'maxlength' => 8,
                ),
                'size'         => 5,
247
248
            );
        }
249
    }
250

251
    $elements['lockedfields'] = array(
252
253
254
255
256
        'type' => 'fieldset',
        'legend' => 'Locked fields ',
        'collapsible' => true,
        'collapsed' => true,
        'elements' => array(),
257
    );
258
    foreach (ArtefactTypeProfile::get_all_fields() as $field => $type) {
259
        $elements['lockedfields']['elements'][$field] = array(
260
            'type' => 'checkbox',
261
            'title' => get_string($field, 'artefact.internal'),
262
            'defaultvalue' => in_array($field, $lockedprofilefields)
263
264
        );
    }
265
266
267
268
269
270
    $elements['lockedfieldshelp'] = array(
        'value' => '<tr><th colspan="2">'
        . get_help_icon('core', 'admin', 'institution', 'lockedfields') 
        . '</th></tr>'
    );

271
272
273
274
275
    $elements['submit'] = array(
        'type' => 'submitcancel',
        'value' => array(get_string('submit'), get_string('cancel'))
    );

276
    $smarty->assign('instancestring', $instancestring);
277

278
279
    $smarty->assign('institution_form', pieform(array(
        'name'     => 'institution',
280
        'renderer' => 'table',
Penny Leach's avatar
Penny Leach committed
281
282
        'plugintype' => 'core',
        'pluginname' => 'admin',
283
284
285
286
287
288
        'elements' => $elements
    )));

}
else {
    // Get a list of institutions
289
290
    if (!$USER->get('admin')) { // Filter the list for institutional admins
        $where = '
291
        WHERE ii.name IN (' . join(',', array_map('db_quote', $USER->get('admininstitutions'))) . ')';
292
293
294
295
    }
    else {
        $where = '';
        $smarty->assign('siteadmin', true);
296
297
        $defaultinstmembers = count_records_sql('
            SELECT COUNT(u.id) FROM {usr} u LEFT OUTER JOIN {usr_institution} i ON u.id = i.usr
298
            WHERE u.deleted = 0 AND i.usr IS NULL AND u.id != 0
299
        ');
300
    }
301
302
    $institutions = get_records_sql_assoc('
        SELECT
303
304
305
306
307
308
309
            ii.name,
            ii.displayname,
            ii.maxuseraccounts,
            COALESCE(a.members, 0) AS members,
            COALESCE(a.staff, 0) AS staff,
            COALESCE(a.admins, 0) AS admins
        FROM
310
            {institution} ii
311
312
313
314
315
            LEFT JOIN
                (SELECT
                    i.name, i.displayname, i.maxuseraccounts,
                    COUNT(ui.usr) AS members, SUM(ui.staff) AS staff, SUM(ui.admin) AS admins
                FROM
316
317
318
                    {institution} i
                    LEFT OUTER JOIN {usr_institution} ui ON (ui.institution = i.name)
                    LEFT OUTER JOIN {usr} u ON (u.id = ui.usr)
319
                WHERE
320
                    (u.deleted = 0 OR u.id IS NULL)
321
322
323
324
                GROUP BY
                    i.name, i.displayname, i.maxuseraccounts
                ORDER BY
                    i.name = \'mahara\', i.displayname
325
             ) a ON (a.name = ii.name)' . $where, array());
326
327
    if (isset($defaultinstmembers)) {
        $institutions['mahara']->members = $defaultinstmembers;
328
329
        $institutions['mahara']->staff   = '';
        $institutions['mahara']->admins  = '';
330
    }
331
332
333
    $smarty->assign('institutions', $institutions);
}

334
function institution_validate(Pieform $form, $values) {
335
    if (!empty($values['name']) && !$form->get_error('name') && record_exists('institution', 'name', $values['name'])) {
336
337
338
339
        $form->set_error('name', get_string('institutionnamealreadytaken', 'admin'));
    }
}

340
function institution_submit(Pieform $form, $values) {
341
    global $SESSION, $institution, $add, $instancearray, $USER;
342
343
344
345
346

    db_begin();
    // Update the basic institution record...
    $newinstitution = new StdClass;
    if ($add) {
347
        $institution = $newinstitution->name = strtolower($values['name']);
348
349
350
    }

    $newinstitution->displayname                  = $values['displayname'];
351
    $newinstitution->authplugin                   = empty($values['authplugin']) ? null : $values['authplugin'];
352
    $newinstitution->registerallowed              = ($values['registerallowed']) ? 1 : 0;
353
    $newinstitution->theme                        = (empty($values['theme']) || $values['theme'] == 'sitedefault') ? null : $values['theme'];
354
355
356
357
358
    if ($institution != 'mahara') {
        $newinstitution->defaultmembershipperiod  = ($values['defaultmembershipperiod']) ? intval($values['defaultmembershipperiod']) : null;
        if ($USER->get('admin')) {
            $newinstitution->maxuseraccounts      = ($values['maxuseraccounts']) ? intval($values['maxuseraccounts']) : null;
        }
359
360
    }

361
362
    if (!empty($values['authplugin'])) {
        $allinstances = array_merge($values['authplugin']['instancearray'], $values['authplugin']['deletearray']);
363

364
365
366
367
        if (array_diff($allinstances, $instancearray)) {
            // TODO wrong exception type
            throw new Exception('Attempt to delete or update another institution\'s auth instance');
        }
368

369
        if (array_diff($instancearray, $allinstances)) {
370
            // TODO wrong exception type
371
            throw new Exception('One of your instances is unaccounted for in this transaction');
372
373
        }

374
375
376
377
378
379
380
381
382
383
384
385
386
        foreach($values['authplugin']['instancearray'] as $priority => $instanceid) {
            if (in_array($instanceid, $values['authplugin']['deletearray'])) {
                // Should never happen:
                // TODO wrong exception type
                throw new Exception('Attempt to update AND delete an auth instance');
            }
            $record = new StdClass;
            $record->priority = $priority;
            $record->id = $instanceid;
            update_record('auth_instance', $record,  array('id' => $instanceid));
        }

        foreach($values['authplugin']['deletearray'] as $instanceid) {
387
            execute_sql('UPDATE {usr} SET lastauthinstance = NULL WHERE lastauthinstance = ?', array($instanceid));
388
389
390
391
            delete_records('auth_remote_user', 'authinstance', $instanceid);
            delete_records('auth_instance_config', 'instance', $instanceid);
            delete_records('auth_instance', 'id', $instanceid);
        }
392
393
    }

394
395
396
    if ($add) {
        insert_record('institution', $newinstitution);
    }
397
    else {
398
399
        $where = new StdClass;
        $where->name = $institution;
400
        $oldtheme = get_field('institution', 'theme', 'name', $institution);
401
402
403
404
405
406
407
408
409
410
411
412
413
414
        update_record('institution', $newinstitution, $where);
    }

    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();

415
    if ($add) {
416
        $message = get_string('institutionaddedsuccessfully', 'admin');
417
418
419
        $nexturl = '/admin/users/institutions.php?i='.urlencode($institution);
    }
    else {
420
        $message = get_string('institutionupdatedsuccessfully', 'admin');
421
        if (isset($values['theme']) && $oldtheme != $values['theme']
422
423
424
            && (!empty($oldtheme) || $values['theme'] != 'sitedefault')) {
            $message .= '  ' . get_string('usersseenewthemeonlogin', 'admin');
        }
425
426
427
        $nexturl = '/admin/users/institutions.php';
    }

428
    $SESSION->add_ok_msg($message);
429
    redirect($nexturl);
430
431
432
}

function institution_cancel_submit() {
433
    redirect('/admin/users/institutions.php');
434
435
}

436
$smarty->assign('heading', get_string('admininstitutions', 'admin'));			
437
$smarty->display('admin/users/institutions.tpl');
438

439
440
441
442
443
444
445
446
447
448
function theme_sort($a, $b) {
    if ($a == 'sitedefault') {
        return -1;
    }
    if ($b == 'sitedefault') {
        return 1;
    }
    return $a > $b;
}

449
?>