register.php 9.46 KB
Newer Older
Evan Prodromou's avatar
Evan Prodromou committed
1
<?php
Evan Prodromou's avatar
Evan Prodromou committed
2
/*
Evan Prodromou's avatar
Evan Prodromou committed
3 4
 * Laconica - a distributed open-source microblogging tool
 * Copyright (C) 2008, Controlez-Vous, Inc.
Evan Prodromou's avatar
Evan Prodromou committed
5
 *
Evan Prodromou's avatar
Evan Prodromou committed
6 7 8 9
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
Evan Prodromou's avatar
Evan Prodromou committed
10
 *
Evan Prodromou's avatar
Evan Prodromou 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 Affero General Public License for more details.
Evan Prodromou's avatar
Evan Prodromou committed
15
 *
Evan Prodromou's avatar
Evan Prodromou committed
16 17 18 19
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

Evan Prodromou's avatar
Evan Prodromou committed
20
if (!defined('LACONICA')) { exit(1); }
Evan Prodromou's avatar
Evan Prodromou committed
21 22

class RegisterAction extends Action {
Evan Prodromou's avatar
Evan Prodromou committed
23

Evan Prodromou's avatar
Evan Prodromou committed
24
	function handle($args) {
25
		parent::handle($args);
Evan Prodromou's avatar
Evan Prodromou committed
26

Evan Prodromou's avatar
Evan Prodromou committed
27
		if (common_logged_in()) {
28
			common_user_error(_('Already logged in.'));
Evan Prodromou's avatar
Evan Prodromou committed
29
		} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
Evan Prodromou's avatar
Evan Prodromou committed
30 31 32 33 34 35 36
			$this->try_register();
		} else {
			$this->show_form();
		}
	}

	function try_register() {
Evan Prodromou's avatar
Evan Prodromou committed
37 38
		$nickname = $this->trimmed('nickname');
		$email = $this->trimmed('email');
39 40 41 42
		$fullname = $this->trimmed('fullname');
		$homepage = $this->trimmed('homepage');
		$bio = $this->trimmed('bio');
		$location = $this->trimmed('location');
43

Evan Prodromou's avatar
Evan Prodromou committed
44
		# We don't trim these... whitespace is OK in a password!
45

Evan Prodromou's avatar
Evan Prodromou committed
46 47
		$password = $this->arg('password');
		$confirm = $this->arg('confirm');
Evan Prodromou's avatar
Evan Prodromou committed
48

Evan Prodromou's avatar
Evan Prodromou committed
49
		# Input scrubbing
Evan Prodromou's avatar
Evan Prodromou committed
50

Evan Prodromou's avatar
Evan Prodromou committed
51 52
		$nickname = common_canonical_nickname($nickname);
		$email = common_canonical_email($email);
Evan Prodromou's avatar
Evan Prodromou committed
53

54
		if (!$this->boolean('license')) {
55
			$this->show_form(_('You can\'t register if you don\'t agree to the license.'));
56
		} else if ($email && !Validate::email($email, true)) {
57
			$this->show_form(_('Not a valid email address.'));
Evan Prodromou's avatar
Evan Prodromou committed
58 59 60
		} else if (!Validate::string($nickname, array('min_length' => 1,
													  'max_length' => 64,
													  'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
61
			$this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
Evan Prodromou's avatar
Evan Prodromou committed
62
		} else if ($this->nickname_exists($nickname)) {
63
			$this->show_form(_('Nickname already in use. Try another one.'));
64
		} else if (!User::allowed_nickname($nickname)) {
65
			$this->show_form(_('Not a valid nickname.'));
Evan Prodromou's avatar
Evan Prodromou committed
66
		} else if ($this->email_exists($email)) {
67
			$this->show_form(_('Email address already exists.'));
68 69 70 71 72 73 74 75 76 77 78 79 80
		} else if (!is_null($homepage) && (strlen($homepage) > 0) &&
				   !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) {
			$this->show_form(_('Homepage is not a valid URL.'));
			return;
		} else if (!is_null($fullname) && strlen($fullname) > 255) {
			$this->show_form(_('Full name is too long (max 255 chars).'));
			return;
		} else if (!is_null($bio) && strlen($bio) > 140) {
			$this->show_form(_('Bio is too long (max 140 chars).'));
			return;
		} else if (!is_null($location) && strlen($location) > 255) {
			$this->show_form(_('Location is too long (max 255 chars).'));
			return;
Evan Prodromou's avatar
Evan Prodromou committed
81
		} else if ($password != $confirm) {
82
			$this->show_form(_('Passwords don\'t match.'));
83
		} else if ($user = $this->register_user($nickname, $password, $email, $fullname, $homepage, $bio, $location)) {
84
			if (!$user) {
85
				$this->show_form(_('Invalid username or password.'));
86
				return;
87
			}
88
			# success!
89
			if (!common_set_user($user)) {
90
				common_server_error(_('Error setting user.'));
91 92
				return;
			}
93
			# this is a real login
94 95
			common_real_login(true);
			if ($this->boolean('rememberme')) {
96
				common_debug('Adding rememberme cookie for ' . $nickname);
97
				common_rememberme($user);
98
			}
99
			$this->show_success();
100
		} else {
101
			$this->show_form(_('Invalid username or password.'));
Evan Prodromou's avatar
Evan Prodromou committed
102 103 104 105
		}
	}

	# checks if *CANONICAL* nickname exists
Evan Prodromou's avatar
Evan Prodromou committed
106

Evan Prodromou's avatar
Evan Prodromou committed
107 108 109 110 111 112
	function nickname_exists($nickname) {
		$user = User::staticGet('nickname', $nickname);
		return ($user !== false);
	}

	# checks if *CANONICAL* email exists
Evan Prodromou's avatar
Evan Prodromou committed
113

Evan Prodromou's avatar
Evan Prodromou committed
114
	function email_exists($email) {
Evan Prodromou's avatar
Evan Prodromou committed
115
		$email = common_canonical_email($email);
Evan Prodromou's avatar
Evan Prodromou committed
116 117 118 119
		$user = User::staticGet('email', $email);
		return ($user !== false);
	}

120
	function register_user($nickname, $password, $email, $fullname, $homepage, $bio, $location) {
121

Evan Prodromou's avatar
Evan Prodromou committed
122
		$profile = new Profile();
123

Evan Prodromou's avatar
Evan Prodromou committed
124
		$profile->query('BEGIN');
125

Evan Prodromou's avatar
Evan Prodromou committed
126
		$profile->nickname = $nickname;
Evan Prodromou's avatar
Evan Prodromou committed
127
		$profile->profileurl = common_profile_url($nickname);
128 129 130 131 132 133 134 135 136 137 138 139
		if ($fullname) {
			$profile->fullname = $fullname;
		}
		if ($homepage) {
			$profile->homepage = $homepage;
		}
		if ($bio) {
			$profile->bio = $bio;
		}
		if ($location) {
			$profile->location = $location;
		}
Evan Prodromou's avatar
Evan Prodromou committed
140
		$profile->created = DB_DataObject_Cast::dateTime(); # current time
141
		
Evan Prodromou's avatar
Evan Prodromou committed
142
		$id = $profile->insert();
143

Evan Prodromou's avatar
Evan Prodromou committed
144
		if (!$id) {
Evan Prodromou's avatar
Evan Prodromou committed
145 146
			common_log_db_error($profile, 'INSERT', __FILE__);
		    return FALSE;
Evan Prodromou's avatar
Evan Prodromou committed
147 148 149 150 151
		}
		$user = new User();
		$user->id = $id;
		$user->nickname = $nickname;
		$user->password = common_munge_password($password, $id);
Evan Prodromou's avatar
Evan Prodromou committed
152
		$user->created =  DB_DataObject_Cast::dateTime(); # current time
153
		$user->uri = common_user_uri($user);
154

Evan Prodromou's avatar
Evan Prodromou committed
155
		$result = $user->insert();
156

Evan Prodromou's avatar
Evan Prodromou committed
157
		if (!$result) {
Evan Prodromou's avatar
Evan Prodromou committed
158
			common_log_db_error($user, 'INSERT', __FILE__);
Evan Prodromou's avatar
Evan Prodromou committed
159
			return FALSE;
Evan Prodromou's avatar
Evan Prodromou committed
160
		}
Evan Prodromou's avatar
Evan Prodromou committed
161

162 163 164 165 166 167 168 169 170 171 172 173 174 175
		# Everyone is subscribed to themself

		$subscription = new Subscription();
		$subscription->subscriber = $user->id;
		$subscription->subscribed = $user->id;
		$subscription->created = $user->created;
		
		$result = $subscription->insert();
		
		if (!$result) {
			common_log_db_error($subscription, 'INSERT', __FILE__);
			return FALSE;
		}
		
Evan Prodromou's avatar
Evan Prodromou committed
176
		if ($email) {
177

Evan Prodromou's avatar
Evan Prodromou committed
178
			$confirm = new Confirm_address();
179
			$confirm->code = common_confirmation_code(128);
Evan Prodromou's avatar
Evan Prodromou committed
180
			$confirm->user_id = $user->id;
Evan Prodromou's avatar
Evan Prodromou committed
181 182
			$confirm->address = $email;
			$confirm->address_type = 'email';
183

Evan Prodromou's avatar
Evan Prodromou committed
184 185
			$result = $confirm->insert();
			if (!$result) {
Evan Prodromou's avatar
Evan Prodromou committed
186
				common_log_db_error($confirm, 'INSERT', __FILE__);
Evan Prodromou's avatar
Evan Prodromou committed
187 188 189
				return FALSE;
			}
		}
190

Evan Prodromou's avatar
Evan Prodromou committed
191 192 193
		$profile->query('COMMIT');

		if ($email) {
Evan Prodromou's avatar
Evan Prodromou committed
194
			mail_confirm_address($confirm->code,
Evan Prodromou's avatar
Evan Prodromou committed
195 196 197
								 $profile->nickname,
								 $email);
		}
198

199
		return $user;
Evan Prodromou's avatar
Evan Prodromou committed
200
	}
Evan Prodromou's avatar
Evan Prodromou committed
201

202
	function show_top($error=NULL) {
203
		if ($error) {
204
			common_element('p', 'error', $error);
Evan Prodromou's avatar
Evan Prodromou committed
205
		} else {
206
			common_element('div', 'instructions',
207
						   _('You can create a new account to start posting notices.'));
208
		}
209
	}
210

211 212 213
	function show_form($error=NULL) {
		global $config;

214
		common_show_header(_('Register'), NULL, $error, array($this, 'show_top'));
Evan Prodromou's avatar
method  
Evan Prodromou committed
215
		common_element_start('form', array('method' => 'post',
Evan Prodromou's avatar
Evan Prodromou committed
216
										   'id' => 'login',
217
										   'action' => common_local_url('register')));
218 219
		common_input('nickname', _('Nickname'), $this->trimmed('nickname'),
					 _('1-64 lowercase letters or numbers, no punctuation or spaces. Required.'));
220
		common_password('password', _('Password'),
221
						_('6 or more characters. Required.'));
222
		common_password('confirm', _('Confirm'),
223 224
						_('Same as password above. Required.'));
		common_input('email', _('Email'), $this->trimmed('email'),
225
					 _('Used only for updates, announcements, and password recovery'));
226 227 228 229 230 231 232 233 234 235 236 237 238 239
		common_input('fullname', _('Full name'),
					 $this->trimmed('fullname'),
					  _('Longer name, preferably your "real" name'));
		common_input('homepage', _('Homepage'),
					 $this->trimmed('homepage'),
					 _('URL of your homepage, blog, or profile on another site'));
		common_textarea('bio', _('Bio'),
						$this->trimmed('bio'),
						 _('Describe yourself and your interests in 140 chars'));
		common_input('location', _('Location'),
					 $this->trimmed('location'),
					 _('Where you are, like "City, State (or Region), Country"'));
		common_checkbox('rememberme', _('Remember me'), 
						$this->boolean('rememberme'),
240
		                _('Automatically login in the future; not for shared computers!'));
241
		common_element_start('p');
Evan Prodromou's avatar
Evan Prodromou committed
242 243 244 245 246 247 248 249
		$attrs = array('type' => 'checkbox',
					   'id' => 'license',
					   'name' => 'license',
					   'value' => 'true');
		if ($this->boolean('license')) {
			$attrs['checked'] = 'checked';
		}
		common_element('input', $attrs);
250
	    common_text(_('My text and files are available under '));
251 252
		common_element('a', array(href => $config['license']['url']),
					   $config['license']['title']);
253
		common_text(_(' except this private data: password, email address, IM address, phone number.'));
254
		common_element_end('p');
255
		common_submit('submit', _('Register'));
Evan Prodromou's avatar
Evan Prodromou committed
256
		common_element_end('form');
Evan Prodromou's avatar
Evan Prodromou committed
257
		common_show_footer();
Evan Prodromou's avatar
Evan Prodromou committed
258
	}
259 260 261 262 263
						
	function show_success() {
		$nickname = $this->arg('nickname');
		common_show_header(_('Registration successful'));
		common_element_start('div', 'success');
264
		$instr = sprintf(_('Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may want to...'. "\n\n" .
265 266
						   '* Go to [your profile](%s) and post your first message.' .  "\n" .
						   '* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send notices through instant messages.' . "\n" .
267
						   '* [Search for people](%%%%action.peoplesearch%%%%) that you may know or that share your interests. ' . "\n" .
268
						   '* Update your [profile settings](%%%%action.profilesettings%%%%) to tell others more about you. ' . "\n" .
Evan Prodromou's avatar
Evan Prodromou committed
269
						   '* Read over the [online docs](%%%%doc.help%%%%) for features you may have missed. ' . "\n\n" .
270 271 272 273 274
						   'Thanks for signing up and we hope you enjoy using this service.'),
						 $nickname, common_local_url('showstream', array('nickname' => $nickname)));
		common_raw(common_markup_to_html($instr));
		$have_email = $this->trimmed('email');
		if ($have_email) {
275 276
			$emailinstr = _('(You should receive a message by email momentarily, with ' .
							'instructions on how to confirm your email address.)');
277 278
			common_raw(common_markup_to_html($emailinstr));
		}
279 280
		common_element_end('div');
		common_show_footer();
281 282
	}
						
Evan Prodromou's avatar
Evan Prodromou committed
283
}