PageRenderTime 49ms CodeModel.GetById 2ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 1ms

/admin/users/institutions.php

https://github.com/ybozhko/phd-mahara
PHP | 653 lines | 549 code | 55 blank | 49 comment | 98 complexity | 006a49f829fe721c296306dfe62f0ab5 MD5 | raw file
  1<?php
  2/**
  3 * Mahara: Electronic portfolio, weblog, resume builder and social networking
  4 * Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
  5 *                         http://wiki.mahara.org/Contributors
  6 *
  7 * This program is free software: you can redistribute it and/or modify
  8 * it under the terms of the GNU General Public License as published by
  9 * the Free Software Foundation, either version 3 of the License, or
 10 * (at your option) any later version.
 11 *
 12 * This program is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 * GNU General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU General Public License
 18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 19 *
 20 * @package    mahara
 21 * @subpackage admin
 22 * @author     Catalyst IT Ltd
 23 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
 24 * @copyright  (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
 25 *
 26 */
 27define('INTERNAL', 1);
 28define('INSTITUTIONALADMIN', 1);
 29require(dirname(dirname(dirname(__FILE__))) . '/init.php');
 30define('TITLE', get_string('institutions', 'admin'));
 31define('SECTION_PLUGINTYPE', 'core');
 32define('SECTION_PLUGINNAME', 'admin');
 33define('SECTION_PAGE', 'institutions');
 34require_once('pieforms/pieform.php');
 35define('MENUITEM', 'manageinstitutions/institutions');
 36
 37$institution = param_variable('i', '');
 38$add         = param_boolean('add');
 39$edit        = param_boolean('edit');
 40$delete      = param_boolean('delete');
 41
 42$query = param_variable('query', '');
 43$offset = param_integer('offset', 0);
 44$limit  = 20;
 45
 46if (!$USER->get('admin')) {
 47    // Institutional admins with only 1 institution go straight to the edit page for that institution
 48    // They cannot add or delete institutions, or edit an institution they don't administer
 49    $add = false;
 50    $delete = false;
 51    if (!empty($institution) && !$USER->is_institutional_admin($institution)) {
 52        $institution = '';
 53        $edit = false;
 54    }
 55    if (empty($institution) && count($USER->get('admininstitutions')) == 1) {
 56        redirect(get_config('wwwroot') . 'admin/users/institutions.php?i='
 57                 . key($USER->get('admininstitutions')));
 58    }
 59}
 60
 61if ($institution || $add) {
 62
 63    $authinstances = auth_get_auth_instances_for_institution($institution);
 64    if (false == $authinstances) {
 65        $authinstances = array();
 66    }
 67
 68    if ($delete) {
 69        function delete_validate(Pieform $form, $values) {
 70            if (get_field('usr_institution', 'COUNT(*)', 'institution', $values['i'])) {
 71                throw new ConfigException('Attempt to delete an institution that has members');
 72            }
 73        }
 74
 75        function delete_cancel_submit() {
 76            redirect('/admin/users/institutions.php');
 77        }
 78
 79        function delete_submit(Pieform $form, $values) {
 80            global $SESSION;
 81
 82            $authinstanceids = get_column('auth_instance', 'id', 'institution', $values['i']);
 83            $viewids = get_column('view', 'id', 'institution', $values['i']);
 84            $artefactids = get_column('artefact', 'id', 'institution', $values['i']);
 85
 86            db_begin();
 87            if ($viewids) {
 88                require_once(get_config('libroot') . 'view.php');
 89                foreach ($viewids as $viewid) {
 90                    $view = new View($viewid);
 91                    $view->delete();
 92                }
 93            }
 94            if ($artefactids) {
 95                foreach ($artefactids as $artefactid) {
 96                    try {
 97                        $a = artefact_instance_from_id($artefactid);
 98                        $a->delete();
 99                    }
100                    catch (ArtefactNotFoundException $e) {
101                        // Awesome, it's already gone.
102                    }
103                }
104            }
105            foreach ($authinstanceids as $id) {
106                delete_records('auth_instance_config', 'instance', $id);
107            }
108            delete_records('auth_instance', 'institution', $values['i']);
109            delete_records('host', 'institution', $values['i']);
110            delete_records('institution_locked_profile_field', 'name', $values['i']);
111            delete_records('usr_institution_request', 'institution', $values['i']);
112            delete_records('institution', 'name', $values['i']);
113            db_commit();
114
115            $SESSION->add_ok_msg(get_string('institutiondeletedsuccessfully', 'admin'));
116            redirect('/admin/users/institutions.php');
117        }
118        $form = array(
119            'name' => 'delete',
120            'elements' => array(
121                'i' => array(
122                    'type' => 'hidden',
123                    'value' => $institution
124                ),
125                'delete' => array(
126                    'type' => 'hidden',
127                    'value' => 1
128                ),
129                'submit' => array(
130                    'type' => 'submitcancel',
131                    'value' => array(get_string('yes'), get_string('no'))
132                )
133            )
134        );
135        $deleteform = pieform($form);
136        $smarty = smarty();
137        $smarty->assign('delete_form', $deleteform);
138        $smarty->assign('institutionname', get_field('institution', 'displayname', 'name', $institution));
139        $smarty->display('admin/users/institutions.tpl');
140        exit;
141    }
142
143    $instancearray = array();
144    $instancestring = '';
145    $c = count($authinstances);
146    $inuse = '';
147
148    $sitelockedfields = (array) get_column('institution_locked_profile_field', 'profilefield', 'name', 'mahara');
149
150    if (!$add) {
151        $data = get_record('institution', 'name', $institution);
152        $lockedprofilefields = (array) get_column('institution_locked_profile_field', 'profilefield', 'name', $institution);
153
154        // TODO: Find a better way to work around Smarty's minimal looping logic
155        if (!empty($authinstances)) {
156            foreach($authinstances as $key => $val) {
157                $authinstances[$key]->index = $key;
158                $authinstances[$key]->total = $c;
159                $instancearray[] = (int)$val->id;
160            }
161
162            $instancestring = implode(',',$instancearray);
163            $inuserecords = array();
164            if ($records = get_records_sql_assoc('select authinstance, count(id) from {usr} where authinstance in ('.$instancestring.') group by authinstance', array())) {
165                foreach ($records as $record) {
166                    $inuserecords[] = $record->authinstance;
167                }
168            }
169            $inuse = implode(',',$inuserecords);
170        }
171        $authtypes = auth_get_available_auth_types($institution);
172    }
173    else {
174        $data = new StdClass;
175        $data->displayname = '';
176        $data->expiry = null;
177        if (!get_config('usersuniquebyusername')) {
178            $data->registerallowed = 1;
179        }
180        $data->theme = 'sitedefault';
181        $data->defaultmembershipperiod = null;
182        $lockedprofilefields = array();
183
184        $authtypes = auth_get_available_auth_types();
185    }
186    $themeoptions = get_institution_themes($institution);
187    $themeoptions['sitedefault'] = '- ' . get_string('sitedefault', 'admin') . ' (' . $themeoptions[get_config('theme')] . ') -';
188    uksort($themeoptions, 'theme_sort');
189
190    $sitename = get_config('sitename');
191
192    safe_require('artefact', 'internal');
193    $elements = array(
194        'name' => array(
195            'type' => 'text',
196            'title' => get_string('institutionname', 'admin'),
197            'rules' => array(
198                'required'  => true,
199                'maxlength' => 255,
200                'regex'     => '/^[a-zA-Z]+$/'
201            ),
202            'ignore' => !$add,
203            'help'   => true,
204        ),
205        'add' => array(
206            'type'   => 'hidden',
207            'value'  => true,
208            'ignore' => !$add
209        ),
210        'inuse' => array(
211            'type'   => 'hidden',
212            'value'  => $inuse,
213            'id'     => 'inuse',
214            'ignore' => $add
215        ),
216        'i' => array(
217            'type'   => 'hidden',
218            'value'  => $institution,
219            'ignore' => $add
220        ),
221        'displayname' => array(
222            'type' => 'text',
223            'title' => get_string('institutiondisplayname', 'admin'),
224            'defaultvalue' => $data->displayname,
225            'rules' => array(
226                'required'  => true,
227                'maxlength' => 255
228            ),
229            'help'   => true,
230        ),
231    );
232    if ($USER->get('admin') && $institution != 'mahara') {
233       $elements['expiry'] = array(
234            'type'         => 'date',
235            'title'        => get_string('institutionexpiry', 'admin'),
236            'description'  => get_string('institutionexpirydescription', 'admin', hsc($sitename)),
237            'defaultvalue' => is_null($data->expiry) ? null : strtotime($data->expiry),
238            'help'         => true,
239            'minyear'      => date('Y') - 2,
240            'maxyear'      => date('Y') + 10,
241        );
242    }
243    if ($USER->get('admin')) {
244        $elements['authplugin'] = array(
245            'type'    => 'authlist',
246            'title'   => get_string('authplugin', 'admin'),
247            'options' => $authinstances,
248            'authtypes' => $authtypes,
249            'instancearray' => $instancearray,
250            'instancestring' => $instancestring,
251            'institution' => $institution,
252            'help'   => true,
253            'ignore' => count($authtypes) == 0 || $institution == ''
254        );
255    }
256
257    if (!$add && empty($authinstances)) {
258        if ($USER->get('admin')) {
259            $SESSION->add_error_msg(get_string('adminnoauthpluginforinstitution', 'admin'));
260        }
261        else {
262            $SESSION->add_error_msg(get_string('noauthpluginforinstitution', 'admin'));
263        }
264    }
265
266    if (!get_config('usersuniquebyusername')) {
267        $elements['registerallowed'] = array(
268            'type'         => 'checkbox',
269            'title'        => get_string('registrationallowed', 'admin'),
270            'description'  => get_string('registrationalloweddescription2', 'admin'),
271            'defaultvalue' => $data->registerallowed,
272            'help'   => true,
273        );
274    }
275
276    if (empty($data->name) || $data->name != 'mahara') {
277        $elements['defaultmembershipperiod'] = array(
278            'type'         => 'expiry',
279            'title'        => get_string('defaultmembershipperiod', 'admin'),
280            'description'  => get_string('defaultmembershipperioddescription', 'admin'),
281            'defaultvalue' => $data->defaultmembershipperiod,
282            'help'   => true,
283        );
284        $elements['theme'] = array(
285            'type'         => 'select',
286            'title'        => get_string('theme'),
287            'description'  => get_string('sitethemedescription','admin'),
288            'defaultvalue' => $data->theme ? $data->theme : 'sitedefault',
289            'collapseifoneoption' => true,
290            'options'      => $themeoptions,
291            'help'         => true,
292        );
293        if ($USER->get('admin')) {
294            $elements['maxuseraccounts'] = array(
295                'type'         => 'text',
296                'title'        => get_string('maxuseraccounts','admin'),
297                'description'  => get_string('maxuseraccountsdescription','admin'),
298                'defaultvalue' => empty($data->maxuseraccounts) ? '' : $data->maxuseraccounts,
299                'rules'        => array(
300                    'regex'     => '/^\d*$/',
301                    'maxlength' => 8,
302                ),
303                'size'         => 5,
304            );
305        }
306    }
307
308    $elements['lockedfields'] = array(
309        'type' => 'fieldset',
310        'legend' => get_string('Lockedfields', 'admin'),
311        'collapsible' => true,
312        'collapsed' => true,
313        'elements' => array(),
314    );
315    if ($institution != 'mahara') {
316        $elements['lockedfields']['elements']['description'] = array(
317            'type' => 'html',
318            'value' => get_string('disabledlockedfieldhelp', 'admin', get_field('institution', 'displayname', 'name', 'mahara')),
319        );
320    }
321    foreach (ArtefactTypeProfile::get_all_fields() as $field => $type) {
322        $elements['lockedfields']['elements'][$field] = array(
323            'type' => 'checkbox',
324            'title' => get_string($field, 'artefact.internal'),
325            'defaultvalue' => in_array($field, $lockedprofilefields) || ($institution != 'mahara' && in_array($field, $sitelockedfields)),
326            'disabled' => $institution != 'mahara' && in_array($field, $sitelockedfields)
327        );
328    }
329    $elements['lockedfieldshelp'] = array(
330        'value' => '<tr id="lockedfieldshelp"><th colspan="2">'
331        . get_help_icon('core', 'admin', 'institution', 'lockedfields') 
332        . '</th></tr>'
333    );
334
335    $elements['submit'] = array(
336        'type' => 'submitcancel',
337        'value' => array(get_string('submit'), get_string('cancel'))
338    );
339
340    $institutionform = pieform(array(
341        'name'     => 'institution',
342        'renderer' => 'table',
343        'plugintype' => 'core',
344        'pluginname' => 'admin',
345        'elements' => $elements
346    ));
347
348}
349else {
350    // Get a list of institutions
351    require_once(get_config('libroot') . 'institution.php');
352    if (!$USER->get('admin')) { // Filter the list for institutional admins
353        $filter      = $USER->get('admininstitutions');
354        $showdefault = false;
355    }
356    else {
357        $filter      = false;
358        $showdefault = true;
359    }
360    $data = build_institutions_html($filter, $showdefault, $query, $limit, $offset, $count);
361
362    $smarty = smarty(array('lib/pieforms/static/core/pieforms.js', 'paginator'));
363    $smarty->assign('results', $data);
364    $smarty->assign('countinstitutions', $count);
365
366    /*search institution form*/
367    $searchform = pieform(array(
368        'name' => 'search',
369        'renderer' => 'oneline',
370        'elements' => array(
371            'query' => array(
372                'type' => 'text',
373                'defaultvalue' => $query
374            ),
375            'submit' => array(
376                'type' => 'submit',
377                'value' => get_string('search')
378            )
379        )
380    ));
381    $smarty->assign('searchform', $searchform);
382
383    $js = <<< EOF
384    addLoadEvent(function () {
385    p = {$data['pagination_js']}
386    connect('search_submit', 'onclick', function (event) {
387        replaceChildNodes('messages');
388        var params = {'query': $('search_query').value};
389        p.sendQuery(params);
390        event.stop();
391        });
392    });
393EOF;
394
395    $smarty->assign('INLINEJAVASCRIPT', $js);
396    $smarty->assign('siteadmin', $USER->get('admin'));
397    $smarty->assign('PAGEHEADING', get_string('admininstitutions', 'admin'));
398    $smarty->display('admin/users/institutions.tpl');
399    exit;
400}
401
402function institution_validate(Pieform $form, $values) {
403    if (!empty($values['name']) && !$form->get_error('name') && record_exists('institution', 'name', $values['name'])) {
404        $form->set_error('name', get_string('institutionnamealreadytaken', 'admin'));
405    }
406}
407
408function institution_submit(Pieform $form, $values) {
409    global $SESSION, $institution, $add, $instancearray, $USER, $authinstances;
410
411    db_begin();
412    // Update the basic institution record...
413    $newinstitution = new StdClass;
414    if ($add) {
415        $institution = $newinstitution->name = strtolower($values['name']);
416    }
417
418    $newinstitution->displayname                  = $values['displayname'];
419    $newinstitution->authplugin                   = empty($values['authplugin']) ? null : $values['authplugin'];
420    if (get_config('usersuniquebyusername')) {
421        // Registering absolutely not allowed when this setting is on, it's a 
422        // security risk. See the documentation for the usersuniquebyusername 
423        // setting for more information
424        $newinstitution->registerallowed = 0;
425    }
426    else {
427        $newinstitution->registerallowed              = ($values['registerallowed']) ? 1 : 0;
428    }
429    $newinstitution->theme                        = (empty($values['theme']) || $values['theme'] == 'sitedefault') ? null : $values['theme'];
430    if ($institution != 'mahara') {
431        $newinstitution->defaultmembershipperiod  = ($values['defaultmembershipperiod']) ? intval($values['defaultmembershipperiod']) : null;
432        if ($USER->get('admin')) {
433            $newinstitution->maxuseraccounts      = ($values['maxuseraccounts']) ? intval($values['maxuseraccounts']) : null;
434            $newinstitution->expiry               = db_format_timestamp($values['expiry']);
435        }
436    }
437
438    if (!empty($values['authplugin'])) {
439        $allinstances = array_merge($values['authplugin']['instancearray'], $values['authplugin']['deletearray']);
440
441        if (array_diff($allinstances, $instancearray)) {
442            throw new ConfigException('Attempt to delete or update another institution\'s auth instance');
443        }
444
445        if (array_diff($instancearray, $allinstances)) {
446            throw new ConfigException('One of your instances is unaccounted for in this transaction');
447        }
448
449        foreach($values['authplugin']['instancearray'] as $priority => $instanceid) {
450            if (in_array($instanceid, $values['authplugin']['deletearray'])) {
451                // Should never happen:
452                throw new SystemException('Attempt to update AND delete an auth instance');
453            }
454            $record = new StdClass;
455            $record->priority = $priority;
456            $record->id = $instanceid;
457            update_record('auth_instance', $record,  array('id' => $instanceid));
458        }
459
460        foreach($values['authplugin']['deletearray'] as $instanceid) {
461            // If this authinstance is the only xmlrpc authinstance that references a host, delete the host record.
462            $hostwwwroot = null;
463            foreach ($authinstances as $ai) {
464                if ($ai->id == $instanceid && $ai->authname == 'xmlrpc') {
465                    $hostwwwroot = get_field_sql("SELECT \"value\" FROM {auth_instance_config} WHERE \"instance\" = ? AND field = 'wwwroot'", array($instanceid));
466                    if ($hostwwwroot && count_records_select('auth_instance_config', "field = 'wwwroot' AND \"value\" = ?", array($hostwwwroot)) == 1) {
467                        // Unfortunately, it's possible that this host record could belong to a different institution,
468                        // so specify the institution here.
469                        delete_records('host', 'wwwroot', $hostwwwroot, 'institution', $institution);
470                        // We really need to fix this, either by removing the institution from the host table, or refusing to allow the
471                        // institution to be changed in the host record when another institution's authinstance is still pointing at it.
472                    }
473                    break;
474                }
475            }
476            delete_records('auth_remote_user', 'authinstance', $instanceid);
477            delete_records('auth_instance_config', 'instance', $instanceid);
478            delete_records('auth_instance', 'id', $instanceid);
479        }
480    }
481
482    if ($add) {
483        insert_record('institution', $newinstitution);
484        // If registration has been turned on, then we automatically insert an 
485        // internal authentication authinstance
486        if ($newinstitution->registerallowed) {
487            $authinstance = (object)array(
488                'instancename' => 'internal',
489                'priority'     => 0,
490                'institution'  => $newinstitution->name,
491                'authname'     => 'internal',
492            );
493            insert_record('auth_instance', $authinstance);
494        }
495    }
496    else {
497        $where = new StdClass;
498        $where->name = $institution;
499        $oldtheme = get_field('institution', 'theme', 'name', $institution);
500        update_record('institution', $newinstitution, $where);
501    }
502
503    delete_records('institution_locked_profile_field', 'name', $institution);
504    foreach (ArtefactTypeProfile::get_all_fields() as $field => $type) {
505        if ($values[$field]) {
506            $profilefield = new StdClass;
507            $profilefield->name         = $institution;
508            $profilefield->profilefield = $field;
509            insert_record('institution_locked_profile_field', $profilefield);
510        }
511    }
512    db_commit();
513
514    if ($add) {
515        if ($newinstitution->registerallowed) {
516            // If registration is not allowed, then an authinstance will not 
517            // have been created, and thus cause the institution page to add 
518            // its own error message on the next page load
519            $SESSION->add_ok_msg(get_string('institutionaddedsuccessfully2', 'admin'));
520        }
521        $nexturl = '/admin/users/institutions.php?i='.urlencode($institution);
522    }
523    else {
524        $message = get_string('institutionupdatedsuccessfully', 'admin');
525        if (isset($values['theme']) && $oldtheme != $values['theme']
526            && (!empty($oldtheme) || $values['theme'] != 'sitedefault')) {
527            $USER->update_theme();
528            $message .= '  ' . get_string('usersseenewthemeonlogin', 'admin');
529        }
530        $SESSION->add_ok_msg($message);
531        $nexturl = '/admin/users/institutions.php';
532    }
533
534    redirect($nexturl);
535}
536
537function institution_cancel_submit() {
538    redirect('/admin/users/institutions.php');
539}
540
541if ($institution && $institution != 'mahara') {
542    $_institution = get_record('institution', 'name', $institution);
543    $suspended = $_institution->suspended;
544    if ($USER->get('admin')) {
545        function institution_suspend_submit(Pieform $form, $values) {
546            global $SESSION, $USER;
547            if (!$USER->get('admin')) {
548                $SESSION->add_error_msg(get_string('errorwhilesuspending', 'admin'));
549            }
550            else {
551                set_field('institution', 'suspended', 1, 'name', $values['i']);
552                $SESSION->add_ok_msg(get_string('institutionsuspended', 'admin'));
553            }
554            redirect('/admin/users/institutions.php?i=' . $values['i']);
555        }
556
557        function institution_unsuspend_submit(Pieform $form, $values) {
558            global $SESSION, $USER;
559            if (!$USER->get('admin')) {
560                $SESSION->add_error_msg(get_string('errorwhileunsuspending', 'admin'));
561            }
562            else {
563                set_field('institution', 'suspended', 0, 'name', $values['i']);
564                $SESSION->add_ok_msg(get_string('institutionunsuspended', 'admin'));
565            }
566            redirect('/admin/users/institutions.php?i=' . $values['i']);
567        }
568
569        // Suspension controls
570        if (empty($suspended)) {
571            $suspendformdef = array(
572                'name'       => 'institution_suspend',
573                'plugintype' => 'core',
574                'pluginname' => 'admin',
575                'elements'   => array(
576                    'i' => array(
577                        'type'    => 'hidden',
578                        'value'   => $institution,
579                    ),
580                    'submit' => array(
581                        'type'        => 'submit',
582                        'value'       => get_string('suspendinstitution','admin'),
583                        'description' => get_string('suspendinstitutiondescription','admin'),
584                    ),
585                )
586            );
587
588            $suspendform  = pieform($suspendformdef);
589        }
590        else {
591            $suspendformdef = array(
592                'name'       => 'institution_unsuspend',
593                'plugintype' => 'core',
594                'pluginname' => 'admin',
595                'elements'   => array(
596                    'i' => array(
597                        'type'    => 'hidden',
598                        'value'   => $institution,
599                    ),
600                    'submit' => array(
601                        'type'        => 'submit',
602                        'value'       => get_string('unsuspendinstitution','admin'),
603                        'description' => get_string('unsuspendinstitutiondescription','admin'),
604                    ),
605                )
606            );
607            $suspendform  = pieform($suspendformdef);
608
609            // Create a second forms for unsuspension to go in the suspend message.
610            // This keeps the HTML IDs unique
611            $suspendformdef['name'] = 'institution_unsuspend_top';
612            $suspendformdef['renderer'] = 'oneline';
613            $suspendformdef['successcallback'] = 'institution_unsuspend_submit';
614            $suspendform_top = pieform($suspendformdef);
615        }
616    }
617}
618
619function search_submit(Pieform $form, $values) {
620    redirect('/admin/users/institutions.php' . (!empty($values['query']) ? '?query=' . urlencode($values['query']) : ''));
621}
622
623$smarty = smarty();
624$smarty->assign('institution_form', $institutionform);
625$smarty->assign('instancestring', $instancestring);
626$smarty->assign('add', $add);
627
628if (isset($suspended)) {
629    if ($suspended) {
630        $smarty->assign('suspended', get_string('suspendedinstitutionmessage', 'admin'));
631    }
632    if (isset($suspendform)) {
633        $smarty->assign('suspendform', $suspendform);
634        if (isset($suspendform_top)) {
635            $smarty->assign('suspendform_top', $suspendform_top);
636        }
637    }
638}
639
640$smarty->assign('PAGEHEADING', get_string('admininstitutions', 'admin'));
641$smarty->display('admin/users/institutions.tpl');
642
643function theme_sort($a, $b) {
644    if ($a == 'sitedefault') {
645        return -1;
646    }
647    if ($b == 'sitedefault') {
648        return 1;
649    }
650    return $a > $b;
651}
652
653?>