register.php 17 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
/**
 * This program is part of Mahara
 *
 *  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 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * @package    mahara
 * @subpackage core
 * @author     Nigel McNie <nigel@catalyst.net.nz>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
 * @copyright  (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
 *
 */

define('INTERNAL', 1);
define('PUBLIC', 1);
29
30
31
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'site');
define('SECTION_PAGE', 'register');
32
require('init.php');
33
require_once('pieforms/pieform.php');
Martyn Smith's avatar
Martyn Smith committed
34
define('TITLE', get_string('register'));
35

36
37
38
39
40
41
42
43
44
45
46
47
/*
 * This page handles three different tasks:
 *   1) Showing a visitor the registration form
 *   2) Telling the visitor to check their e-mail for a message
 *   3) Given a key, display profile information to edit
 *
 * It uses the session to store some state
 */
if (!session_id()) {
    session_start();
}

48
// Logged in people can't register
Nigel McNie's avatar
Nigel McNie committed
49
if (is_logged_in()) {
50
    redirect();
51
52
}

53
54
55
56
// Step two of registration (first as it's the easiest): the user has
// registered, show them a screen telling them this.
if (!empty($_SESSION['registered'])) {
    unset($_SESSION['registered']);
57
    die_info(get_string('registeredok', 'auth.internal'));
58
59
}

60
$key = param_alphanum('key', null);
61
62
// Step three of registration - given a key, fill out mandatory profile fields,
// optional profile icon, and register the user
63
if (isset($key)) {
64

Nigel McNie's avatar
Nigel McNie committed
65
    function profileform_submit(Pieform $form, $values) {
66
        global $registration, $SESSION, $USER;
67

68
        db_begin();
69
70
71
72

        // Move the user record to the usr table from the registration table
        $registrationid = $registration->id;
        unset($registration->id);
73
        unset($registration->expiry);
74
        if ($expirytime = get_config('defaultaccountlifetime')) {
75
76
            $registration->expiry = db_format_timestamp(time() + $expirytime);
        }
77
        $registration->lastlogin = db_format_timestamp(time());
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

        $authinstance = get_record('auth_instance', 'institution', $registration->institution, 'authname', 'internal');
        if (false == $authinstance) {
            // TODO: Specify exception
            throw new Exception('No internal auth instance for institution');
        }

        $user = new User();
        $user->username         = $registration->username;
        $user->password         = $registration->password;
        $user->salt             = $registration->salt;
        $user->passwordchange   = 0;
        $user->active           = 1;
        $user->firstname        = $registration->firstname;
        $user->lastname         = $registration->lastname;
        $user->authinstance     = $authinstance->id;
        $user->lastname         = $registration->lastname;
        $user->firstname        = $registration->firstname;
        $user->lastname         = $registration->lastname;
        $user->commit();

99
        $user->add_institution_request($registration->institution);
100

101
        $registration->id = $user->id;
102
103

        // Insert standard stuff as artefacts
104
105
106
        set_profile_field($user->id, 'email', $registration->email);
        set_profile_field($user->id, 'firstname', $registration->firstname);
        set_profile_field($user->id, 'lastname', $registration->lastname);
107
108

        // Delete the old registration record
109
110
111
112
113
114
115
116
        delete_records('usr_registration', 'id', $registrationid);

        // Set mandatory profile fields 
        foreach(ArtefactTypeProfile::get_mandatory_fields() as $field => $type) {
            // @todo here and above, use the method for getting "always mandatory" fields
            if (in_array($field, array('firstname', 'lastname', 'email'))) {
                continue;
            }
117
            set_profile_field($user->id, $field, $values[$field]);
118
119
        }

Nigel McNie's avatar
Nigel McNie committed
120
121
122
123
        // Handle the profile image if uploaded
        if ($values['profileimg'] && $values['profileimg']['error'] == 0 && $values['profileimg']['size'] > 0) {
            // Entry in artefact table
            $artefact = new ArtefactTypeProfileIcon();
124
            $artefact->set('owner', $user->id);
125
            $artefact->set('title', ($values['profileimgtitle']) ? $values['profileimgtitle'] : $values['profileimg']['name']);
Nigel McNie's avatar
Nigel McNie committed
126
127
128
129
130
131
            $artefact->set('note', $values['profileimg']['name']);
            $artefact->commit();

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

            $filesize = filesize($values['profileimg']['tmp_name']);
132
            set_field('usr', 'quotaused', $filesize, 'id', $user->id);
Nigel McNie's avatar
Nigel McNie committed
133
134
            $registration->quotaused = $filesize;
            $registration->quota = get_config_plugin('artefact', 'file', 'defaultquota');
135
            set_field('usr', 'profileicon', $id, 'id', $user->id);
Nigel McNie's avatar
Nigel McNie committed
136
137
138
            $registration->profileicon = $id;

            // Move the file into the correct place.
139
            $directory = get_config('dataroot') . 'artefact/internal/profileicons/originals/' . ($id % 256) . '/';
Nigel McNie's avatar
Nigel McNie committed
140
141
142
            check_dir_exists($directory);
            move_uploaded_file($values['profileimg']['tmp_name'], $directory . $id);
        }
Martyn Smith's avatar
Martyn Smith committed
143
144
145
146
        else {
            $registration->quotaused = 0;
            $registration->quota = get_config_plugin('artefact', 'file', 'defaultquota');
        }
Nigel McNie's avatar
Nigel McNie committed
147

148
        db_commit();
Nigel McNie's avatar
Nigel McNie committed
149
        handle_event('createuser', $registration);
150

151
        // Log the user in and send them to the homepage
152
153
        $USER = new LiveUser();
        $USER->reanimate($user->id, $authinstance->id);
154
        redirect();
155
    }
156

Nigel McNie's avatar
Nigel McNie committed
157
158
159
160
161
162
163
164
    function profileform_validate(Pieform $form, $values) {
        // Profile icon, if uploaded
        if ($values['profileimg'] && $values['profileimg']['error'] == 0 && $values['profileimg']['size'] > 0) {
            require_once('file.php');
            if (!is_image_mime_type(get_mime_type($values['profileimg']['tmp_name']))) {
                $form->set_error('profileimg', get_string('filenotimage'));
            }

165
            // Check the file isn't greater than the maximum allowed size
Nigel McNie's avatar
Nigel McNie committed
166
            list($width, $height) = getimagesize($values['profileimg']['tmp_name']);
167
168
169
170
            $imagemaxwidth  = get_config('imagemaxwidth');
            $imagemaxheight = get_config('imagemaxheight');
            if ($width > $imagemaxwidth || $height > $imagemaxheight) {
                $form->set_error('profileimg', get_string('profileiconimagetoobig', 'artefact.internal', $width, $height, $imagemaxwidth, $imagemaxheight));
Nigel McNie's avatar
Nigel McNie committed
171
172
173
            }
        }

174
175
176
177
178
179
180
181
182
183
        foreach(ArtefactTypeProfile::get_mandatory_fields() as $field => $type) {
            // @todo here and above, use the method for getting "always mandatory" fields
            if (in_array($field, array('firstname', 'lastname', 'email'))) {
                continue;
            }
            // @todo here, validate the fields using their static validate method
        }
    }


Nigel McNie's avatar
Nigel McNie committed
184
    // Begin the registration form buliding
185
    if (!$registration = get_record_select('usr_registration', '"key" = ? AND expiry >= ?', array($key, db_format_timestamp(time())))) {
186
        die_info(get_string('registrationnosuchkey', 'auth.internal'));
187
188
    }

Nigel McNie's avatar
Nigel McNie committed
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    $elements = array(
        'optionalheader' => array(
            'type'  => 'html',
            'value' => get_string('registerstep3fieldsoptional')
        ),
        'profileimg' => array(
            'type' => 'file',
            'title' => 'Profile Image'
        ),
        'profileimgtitle' => array(
            'type' => 'text',
            'title' => 'Title'
        )
    );

    $mandatoryheaderadded = false;
205
206
207
208
209
    safe_require('artefact', 'internal');
    foreach(ArtefactTypeProfile::get_mandatory_fields() as $field => $type) {
        if (in_array($field, array('firstname', 'lastname', 'email'))) {
            continue;
        }
Nigel McNie's avatar
Nigel McNie committed
210
211
212
213
214
215
216
217
218

        if (!$mandatoryheaderadded) {
            $elements['mandatoryheader'] = array(
                'type'  => 'html',
                'value' => get_string('registerstep3fieldsmandatory')
            );
            $mandatoryheaderadded = true;
        }

219
220
221
222
223
        $elements[$field] = array(
            'type'  => $type,
            'title' => get_string($field, 'artefact.internal'),
            'rules' => array('required' => true)
        );
Nigel McNie's avatar
Nigel McNie committed
224
225
226
227
228
229
230
231
232
233
234
235
236
237

        // @todo ruthlessly stolen from artefact/internal/index.php, could be merged
        if ($type == 'wysiwyg') {
            $elements[$field]['rows'] = 10;
            $elements[$field]['cols'] = 60;
        }
        if ($type == 'textarea') {
            $elements[$field]['rows'] = 4;
            $elements[$field]['cols'] = 60;
        }
        if ($field == 'country') {
            $elements[$field]['options'] = getoptions_country();
            $elements[$field]['defaultvalue'] = 'nz';
        }
238
    }
239

240
241
242
    $elements['key'] = array(
        'type' => 'hidden',
        'name' => 'key',
243
        'value' => $key
244
245
246
247
248
    );
    $elements['submit'] = array(
        'type' => 'submit',
        'value' => get_string('completeregistration', 'auth.internal')
    );
249

Nigel McNie's avatar
Nigel McNie committed
250
251
    $form = pieform(array(
        'name'     => 'profileform',
252
253
254
        'method'   => 'post',
        'action'   => '',
        'elements' => $elements
Nigel McNie's avatar
Nigel McNie committed
255
    ));
256
257

    $smarty = smarty();
Nigel McNie's avatar
Nigel McNie committed
258
    $smarty->assign('register_profile_form', $form);
259
260
    $smarty->display('register.tpl');
    exit;
261
262
}

263
264
265

// Default page - show the registration form

266
267
268
269
270
271
$elements = array(
    'username' => array(
        'type' => 'text',
        'title' => get_string('username'),
        'rules' => array(
            'required' => true
Penny Leach's avatar
Penny Leach committed
272
273
        ),
        'help' => true,
274
275
276
277
    ),
    'password1' => array(
        'type' => 'password',
        'title' => get_string('password'),
278
        'description' => get_string('passwordformdescription', 'auth.internal'),
279
280
        'rules' => array(
            'required' => true
Penny Leach's avatar
Penny Leach committed
281
282
        ),
        'help' => true,
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
    ),
    'password2' => array(
        'type' => 'password',
        'title' => get_string('confirmpassword'),
        'rules' => array(
            'required' => true
        )
    ),
    'firstname' => array(
        'type' => 'text',
        'title' => get_string('firstname'),
        'rules' => array(
            'required' => true
        )
    ),
    'lastname' => array(
        'type' => 'text',
        'title' => get_string('lastname'),
        'rules' => array(
            'required' => true
        )
    ),
    'email' => array(
        'type' => 'text',
        'title' => get_string('emailaddress'),
        'rules' => array(
            'required' => true,
            'email' => true
        )
    )
);
314
315
316
$sql = 'SELECT
            i.*
        FROM
317
318
            {institution} i,
            {auth_instance} ai
319
320
321
322
323
        WHERE
            ai.authname = \'internal\' AND
            ai.institution = i.name';
$institutions = get_records_sql_array($sql, array());

324
325
326
327
328
329
330
331
if (count($institutions) > 1) {
    $options = array();
    foreach ($institutions as $institution) {
        $options[$institution->name] = $institution->displayname;
    }
    $elements['institution'] = array(
        'type' => 'select',
        'title' => get_string('institution'),
332
333
334
335
        'options' => $options,
        'rules' => array(
            'required' => true
        )
336
337
    );
}
338
else if ($institutions) {
339
340
341
342
343
    $elements['institution'] = array(
        'type' => 'hidden',
        'value' => 'mahara'
    );
}
344
345
346
else {
    die_info(get_string('registeringdisallowed'));
}
347
348
349

$elements['tandc'] = array(
    'type' => 'radio',
350
351
    'title' => get_string('iagreetothetermsandconditions', 'auth.internal'),
    'description' => get_string('youmustagreetothetermsandconditions', 'auth.internal'),
352
353
354
    'options' => array(
        'yes' => get_string('yes'),
        'no'  => get_string('no')
355
356
357
358
359
    ),
    'defaultvalue' => 'no',
    'rules' => array(
        'required' => true
    ),
360
361
362
363
364
365
    'separator' => ' &nbsp; '
);

$elements['captcha'] = array(
    'type' => 'html',
    'title' => get_string('captchatitle'),
366
    'description' => get_string('captchadescription'),
367
    'value' => '<img src="' . get_config('wwwroot') . 'captcha.php" alt="' . get_string('captchaimage') . '" style="padding: 2px 0;"><br>'
368
        . '<input type="text" class="text required" name="captcha" style="width: 137px;" tabindex="4">',
369
    'rules' => array('required' => true)
370
371
372
);

$elements['submit'] = array(
373
374
    'type' => 'submitcancel',
    'value' => array(get_string('register'), get_string('cancel'))
375
376
377
378
379
);

$form = array(
    'name' => 'register',
    'method' => 'post',
380
381
    'plugintype' => 'core',
    'pluginname' => 'register',
382
    'action' => '',
383
    'showdescriptiononerror' => false,
384
    'renderer' => 'table',
385
386
387
    'elements' => $elements
);

388
389
390
391
392
393
/**
 * @todo add note: because the form select thing will eventually enforce
 * that the result for $values['institution'] was in the original lot,
 * and because that only allows authmethods that use 'internal' auth, we
 * can guarantee that the auth method is internal
 */
394
function register_validate(Pieform $form, $values) {
395
    global $SESSION;
396
    $institution = $values['institution'];
397
    safe_require('auth', 'internal');
398
399

    if (!$form->get_error('username') && !AuthInternal::is_username_valid($values['username'])) {
400
        $form->set_error('username', get_string('usernameinvalidform', 'auth.internal'));
401
    }
402

403
    if (!$form->get_error('username') && record_exists('usr', 'username', $values['username'])) {
404
        $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal'));
405
406
    }

407
408
409
    $user =(object) $values;
    $user->authinstance = 1; // Internal
    password_validate($form, $values, $user);
410
411
412
413

    // First name and last name must contain at least one non whitespace
    // character, so that there's something to read
    if (!$form->get_error('firstname') && !preg_match('/\S/', $values['firstname'])) {
414
        $form->set_error('firstname', $form->i18n('required'));
415
416
417
    }

    if (!$form->get_error('lastname') && !preg_match('/\S/', $values['lastname'])) {
418
        $form->set_error('lastname', $form->i18n('required'));
419
420
421
422
423
    }

    // The e-mail address cannot already be in the system
    if (!$form->get_error('email')
        && (record_exists('usr', 'email', $values['email'])
424
        || record_exists('artefact_internal_profile_email', 'email', $values['email']))) {
425
        $form->set_error('email', get_string('emailalreadytaken', 'auth.internal'));
426
427
428
429
    }
    
    // If the user hasn't agreed to the terms and conditions, don't bother
    if ($values['tandc'] != 'yes') {
430
        $form->set_error('tandc', get_string('youmaynotregisterwithouttandc', 'auth.internal'));
431
    }
432
433
434
435
436

    // CAPTCHA image
    if (!isset($_POST['captcha']) || strtolower($_POST['captcha']) != strtolower($SESSION->get('captcha'))) {
        $form->set_error('captcha', get_string('captchaincorrect'));
    }
437
438
}

439
function register_submit(Pieform $form, $values) {
440
    global $SESSION;
441
442
443
444

    // store password encrypted
    // don't die_info, since reloading the page shows the login form.
    // instead, redirect to some other page that says this
445
    safe_require('auth', 'internal');
446
447
    $values['salt']     = substr(md5(rand(1000000, 9999999)), 2, 8);
    $values['password'] = AuthInternal::encrypt_password($values['password1'], $values['salt']);
448
    $values['key']   = get_random_key();
449
    // @todo the expiry date should be configurable
450
    $values['expiry'] = db_format_timestamp(time() + 86400);
451
452
453
    try {
        insert_record('usr_registration', $values);

454
455
456
        $f = fopen('/tmp/donal.txt','w');
        fwrite($f, get_string('registeredemailmessagetext', 'auth.internal', $values['firstname'], get_config('sitename'), $values['key'], get_config('sitename')));

457
        $user =(object) $values;
458
        $user->admin = 0;
459
        $user->staff = 0;
460
        email_user($user, null,
461
            get_string('registeredemailsubject', 'auth.internal', get_config('sitename')),
Nigel McNie's avatar
Nigel McNie committed
462
463
            get_string('registeredemailmessagetext', 'auth.internal', $values['firstname'], get_config('sitename'), $values['key'], get_config('sitename')),
            get_string('registeredemailmessagehtml', 'auth.internal', $values['firstname'], get_config('sitename'), $values['key'], $values['key'], get_config('sitename')));
464
465
    }
    catch (EmailException $e) {
466
        log_warn($e);
467
        die_info(get_string('registrationunsuccessful', 'auth.internal'));
468
469
    }
    catch (SQLException $e) {
470
        log_warn($e);
471
        die_info(get_string('registrationunsuccessful', 'auth.internal'));
472
473
474
475
476
    }

    // Add a marker in the session to say that the user has registered
    $_SESSION['registered'] = true;

477
    redirect('/register.php');
478
479
480
}

function register_cancel_submit() {
Nigel McNie's avatar
Nigel McNie committed
481
    redirect();
482
483
484
}

$smarty = smarty();
485
$smarty->assign('register_form', pieform($form));
486
487
488
$smarty->display('register.tpl');

?>