1<?php
2/*
3 * e107 website system
4 *
5 * Copyright (C) 2008-2014 e107 Inc (e107.org)
6 * Released under the terms and conditions of the
7 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
8 *
9 * User signup
10 *
11 */
12
13require_once("class2.php");
14
15if(vartrue($_POST['email2'])) // spam-trap.
16{
17	exit;
18}
19
20$qs = explode(".", e_QUERY);
21
22if($qs[0] != 'activate')
23{   // multi-language fix.
24	e107::coreLan('signup');
25	//include_lan(e_LANGUAGEDIR.e_LANGUAGE.'/lan_'.e_PAGE);
26//	include_lan(e_LANGUAGEDIR.e_LANGUAGE."/lan_usersettings.php");		Shouldn't need this now
27}
28
29e107::coreLan('user'); // Generic user-related language defines
30
31	$bcLans = array(
32	"LAN_7"=> "LAN_SIGNUP_89", // "Display Name: ");
33	"LAN_8"=> "LAN_SIGNUP_90", // "the name that will be displayed on site");
34	"LAN_9"=> "LAN_SIGNUP_81", // "Username: ");
35	"LAN_10"=> "LAN_SIGNUP_82", // "the name that you use to login");
36	"LAN_17"=> "LAN_SIGNUP_83", // "Password: ");
37	"LAN_109"=> "LAN_SIGNUP_77", // "This site complies with The Children's Online Privacy Protection Act of 1998 (COPPA) and as such cannot accept registrations from users under the age of 13 without a written permission document from their parent or guardian. For more information you can read the legislation");
38	"LAN_111"=> "LAN_SIGNUP_84", // "Re-type Password: ");
39	"LAN_112"=> "LAN_USER_60",  // "Email Address: ");
40	"LAN_113"=> "LAN_USER_83", // "Hide email address?: ");
41	"LAN_120"=> "LAN_USER_71", // "Signature: ");
42	"LAN_121"=> "LAN_SIGNUP_94", // "Avatar: ");
43	"LAN_122"=> "", // "Timezone:");
44	"LAN_123"=> "LAN_SIGNUP_79", // "Register");
45	"LAN_308"=> "LAN_SIGNUP_91", // "Real Name: ");
46	"LAN_309"=> "LAN_SIGNUP_80", // "Please enter your details below.");
47	"LAN_400"=> "LAN_SIGNUP_85", // "Usernames and passwords are <b>case-sensitive</b>.");
48	"LAN_410"=> "LAN_SIGNUP_95", // "Enter code visible in the image");
49	);
50
51e107::getLanguage()->bcDefs($bcLans); // Backward compatibility fix.
52
53
54define('SIGNUP_DEBUG', FALSE);
55
56e107::js('core', 'jquery.mailcheck.min.js','jquery',2);
57
58include_once(e_HANDLER.'user_extended_class.php');
59$usere = new e107_user_extended;
60
61require_once(e_HANDLER.'validator_class.php');
62// require_once(e_HANDLER.'user_handler.php');
63$userMethods = e107::getUserSession();
64$userMethods->deleteExpired();				// Delete time-expired partial registrations
65
66
67$SIGNUP_BEGIN = null;
68$SIGNUP_BODY = null;
69$SIGNUP_END  = null;
70$COPPA_TEMPLATE = null;
71$COPPA_FAIL = null;
72
73require_once(e107::coreTemplatePath('signup')); //correct way to load a core template.
74$signup_shortcodes = e107::getScBatch('signup');
75// $facebook_shortcodes = e107::getScBatch('facebook',TRUE);
76
77$signup_imagecode = ($pref['signcode'] && extension_loaded('gd'));
78$text = '';
79$extraErrors = array();
80$error = FALSE;
81
82// ------------------------------------------------------------------
83
84if(!$_POST)
85{
86	$error = '';
87	$text = ' ';
88	$password1 = '';
89	$password2 = '';
90	$email = '';				// Used in shortcodes
91	$loginname = '';
92	$realname = '';
93	$image = '';
94	$avatar_upload = '';
95	$photo_upload = '';
96	$_POST['ue'] = '';
97	$signature = '';
98}
99
100
101
102if (!empty($pref['membersonly_enabled']))
103{
104	$template = e107::getCoreTemplate('membersonly','signup');
105	define('e_IFRAME',true);
106	define('e_IFRAME_HEADER', $template['header'] );
107	define('e_IFRAME_FOOTER', $template['footer'] );
108	unset($template);
109
110}
111
112/*
113if($signup_imagecode)
114{
115	// require_once(e_HANDLER."secure_img_handler.php");
116	// $sec_img = new secure_image;
117}
118*/
119
120if ((USER || (intval($pref['user_reg']) !== 1) || (vartrue($pref['auth_method'],'e107') != 'e107')) && !getperms('0'))
121{
122	e107::redirect();
123
124}
125
126
127//----------------------------------------
128// After clicking the activation link
129//----------------------------------------
130require_once(e_HANDLER."e_signup_class.php");
131
132if(e_QUERY && e_QUERY != 'stage1')
133{
134	require_once(HEADERF);
135	$suObj = new e_signup;
136	$suObj->run();
137	require_once(FOOTERF);
138	exit;
139}
140
141
142
143
144
145//----------------------------------------
146// 		Initial signup (registration)
147// TODO - move all of this into the class above.
148if (isset($_POST['register']) && intval($pref['user_reg']) === 1)
149{
150	e107::getCache()->clear("online_menu_totals");
151
152	if ($signup_imagecode)
153	{
154		if ($badCodeMsg = e107::getSecureImg()->invalidCode($_POST['rand_num'], $_POST['code_verify'])) // better: allows class to return the error.
155		{
156			//$extraErrors[] = LAN_SIGNUP_3."\\n";
157			$extraErrors[] = $badCodeMsg."\\n";
158			$error = TRUE;
159		}
160	}
161
162	if($invalid = e107::getEvent()->trigger("usersup_veri", $_POST))
163	{
164    	$extraErrors[] = $invalid."\\n";
165        $error = TRUE;
166	}
167
168	if (!$error)
169	{
170		if (vartrue($pref['predefinedLoginName']))
171		{
172		  $_POST['loginname'] = $userMethods->generateUserLogin($pref['predefinedLoginName']);
173		}
174
175		if(!isset($_POST['hideemail'])) // For when it is disabled - default is to hide-email.
176		{
177			$_POST['hideemail'] = 1;
178		}
179
180		if(!isset($_POST['email_confirm']))
181		{
182			$_POST['email_confirm'] = $_POST['email'];
183		}
184
185
186		// Use LoginName for DisplayName if restricted
187		if (!check_class($pref['displayname_class'],e_UC_PUBLIC.','.e_UC_MEMBER))
188		{
189			$_POST['username'] = $_POST['loginname'];
190		}
191
192		// generate password if passwords are disabled and email validation is enabled.
193		$noPasswordInput = e107::getPref('signup_option_password', 2); //0 = generate it.
194		if(empty($noPasswordInput) && !isset($_POST['password1']) && $this->pref['user_reg_veri'] === 1)
195		{
196			$_POST['password1'] = $userMethods->generateRandomString("#*******#");
197			$_POST['password2'] = $_POST['password1'];
198		}
199
200		// posted class subscription - check it's only from the public classes.
201		if(!empty($_POST['class']))
202		{
203			$publicClasses = e107::getUserClass()->get_editable_classes(e_UC_PUBLIC, true);
204			$_POST['class'] = array_intersect($publicClasses, $_POST['class']);
205			unset($publicClasses);
206		}
207
208		// Now validate everything
209		$allData = validatorClass::validateFields($_POST,$userMethods->userVettingInfo, TRUE);		// Do basic validation
210		validatorClass::checkMandatory('user_name,user_loginname', $allData);						// Check for missing fields (email done in userValidation() )
211		validatorClass::dbValidateArray($allData, $userMethods->userVettingInfo, 'user', 0);		// Do basic DB-related checks
212		$userMethods->userValidation($allData);
213
214
215		$savePassword = null;
216
217		if (!isset($allData['errors']['user_password']))
218		{
219			// No errors in password - keep it outside the main data array
220			$savePassword = $allData['data']['user_password'];
221			unset($allData['data']['user_password']); // Delete the password value in the output array
222		}
223
224		unset($_POST['password1']); // Restrict the scope of this
225		unset($_POST['password2']);
226
227		$allData['user_ip'] = e107::getIPHandler()->getIP(FALSE);
228
229
230		// check for multiple signups from the same IP address. But ignore localhost
231		if ($allData['user_ip'] != e107::LOCALHOST_IP && $allData['user_ip'] != e107::LOCALHOST_IP2)
232		{
233			if($ipcount = $sql->select('user', '*', "user_ip='".$allData['user_ip']."' and user_ban !='2' "))
234			{
235				if($ipcount >= $pref['signup_maxip'] && trim($pref['signup_maxip']) != "")
236				{
237					$allData['errors']['user_email'] = ERR_GENERIC;
238					$allData['errortext']['user_email'] =  LAN_SIGNUP_71;
239					e107::getLog()->add('USET_15',LAN_SIGNUP_103.e107::getIPHandler()->getIP(FALSE), 4);
240				}
241			}
242		}
243
244		// Email address confirmation.
245		if (!isset($allData['errors']['user_email']))
246		{	// Obviously nothing wrong with the email address so far (or maybe its not required)
247			if ($_POST['email'] != $_POST['email_confirm'])
248			{
249				$allData['errors']['user_email'] = ERR_GENERIC;
250				$allData['errortext']['user_email'] =  LAN_SIGNUP_38;
251				unset($allData['data']['user_email']);
252			}
253		}
254
255
256		// Verify Custom Signup options if selected - need specific loop since the need for them is configuration-dependent
257		$signup_option_title = array(LAN_USER_63, LAN_USER_71, LAN_USER_72, LAN_USER_73, LAN_USER_74);
258		$signup_option_names = array('realname', 'signature', 'image', 'class', 'customtitle');
259
260		foreach($signup_option_names as $key => $value)
261		{
262			if ($pref['signup_option_'.$value] == 2 && !isset($alldata['data']['user_'.$value]) && !isset($alldata['errors']['user_'.$value]))
263			{
264				$alldata['errors']['user_'.$value] = ERR_GENERIC;
265				$alldata['errortext']['user_'.$value] = str_replace('[x]',$signup_option_title[$key],LAN_USER_75);
266			}
267		}
268
269
270		// Validate Extended User Fields.
271		$eufVals = array();
272		if (isset($_POST['ue']))
273		{
274			$eufVals = $usere->sanitizeAll($_POST['ue']);
275			$eufVals = $usere->userExtendedValidateAll(varset($eufVals, array()), varset($_POST['hide'],array()), TRUE); // Validate the extended user fields
276		}
277
278
279		// Determine whether we have an error
280		$error = ((isset($allData['errors']) && count($allData['errors'])) || (isset($eufVals['errors']) && count($eufVals['errors'])) || count($extraErrors));
281
282		// All validated here - handle any errors
283		if ($error) //FIXME - this ignores the errors caused by invalid image-code.
284		{
285			$temp = array();
286			if (count($extraErrors))
287			{
288				$temp[] = implode('<br />', $extraErrors);
289			}
290			if (count($allData['errors']))
291			{
292				$temp[] = validatorClass::makeErrorList($allData,'USER_ERR_','%n - %x - %t: %v', '<br />', $userMethods->userVettingInfo);
293			}
294			if (vartrue($eufVals['errors']))
295			{
296				$temp[] = validatorClass::makeErrorList($eufVals,'USER_ERR_','%n - %t: %v', '<br />');
297			}
298
299
300			if(deftrue('BOOTSTRAP'))
301			{
302				e107::getMessage()->addError(implode('<br />', $temp));
303			}
304			else
305			{
306				message_handler('P_ALERT', implode('<br />', $temp));
307			}
308
309		}
310	}		// End of data validation
311	else
312	{
313		if(deftrue('BOOTSTRAP'))
314		{
315			e107::getMessage()->addError(implode('<br />', $extraErrors));
316		}
317		else
318		{
319			message_handler('P_ALERT', implode('<br />', $extraErrors));	// Workaround for image-code errors.
320		}
321
322	}
323
324
325	// ========== End of verification.. ==============
326	// If no errors, we can enter the new member in the DB
327	// At this point we have two data arrays:
328	//		$allData['data'] - the 'core' user data
329	//		$eufVals['data'] - any extended user fields
330
331	if (!$error)
332	{
333		$error_message = '';
334		$fp = new floodprotect;
335		if ($fp->flood("user", "user_join") == FALSE)
336		{
337			e107::redirect();
338			exit;
339		}
340
341		if ($_POST['email'] && $sql->select("user", "*", "user_email='".$_POST['email']."' AND user_ban='".USER_BANNED."'"))
342		{
343			exit;
344		}
345
346
347		$u_key = e_user_model::randomKey();		// Key for signup completion
348		$allData['data']['user_sess'] = $u_key;	// Validation key
349
350		$userMethods->userClassUpdate($allData['data'], 'usersup');
351
352		if ($pref['user_reg_veri'])
353		{
354			$allData['data']['user_ban'] = USER_REGISTERED_NOT_VALIDATED;
355		}
356		else
357		{
358			$allData['data']['user_ban'] = USER_VALIDATED;
359		}
360
361		// Work out data to be written to user audit trail
362		$signup_data = array('user_name', 'user_loginname', 'user_email', 'user_ip');
363//		foreach (array() as $f)
364		foreach ($signup_data as $f)
365		{
366			$signup_data[$f] = $allData['data'][$f]; // Just copy across selected fields
367		}
368
369		$allData['data']['user_password'] = $userMethods->HashPassword($savePassword,$allData['data']['user_loginname']);
370
371		if (vartrue($pref['allowEmailLogin']))
372		{  // Need to create separate password for email login
373			//$allData['data']['user_prefs'] = serialize(array('email_password' => $userMethods->HashPassword($savePassword, $allData['data']['user_email'])));
374			$allData['data']['user_prefs'] = e107::serialize(array('email_password' => $userMethods->HashPassword($savePassword, $allData['data']['user_email'])));
375		}
376
377		$allData['data']['user_join'] = time();
378		$allData['data']['user_ip'] = e107::getIPHandler()->getIP(FALSE);
379
380
381
382		if(!vartrue($allData['data']['user_name']))
383		{
384			$allData['data']['user_name'] = $allData['data']['user_loginname'];
385			$signup_data['user_name'] = $allData['data']['user_loginname'];
386		}
387
388		// The user_class, user_perms, user_prefs, user_realm fields don't have default value,
389		//   so we put apropriate ones, otherwise - broken DB Insert
390
391		if(empty($allData['data']['user_class']))
392		{
393			$allData['data']['user_class'] = '';
394		}
395
396		$allData['data']['user_perms'] = '';
397		$allData['data']['user_prefs'] = '';
398		$allData['data']['user_realm'] = '';
399
400		if(empty($allData['data']['user_signature']))
401		{
402			$allData['data']['user_signature'] = ''; // as above - default required in MYsQL strict mode.
403		}
404
405
406		// Actually write data to DB
407		validatorClass::addFieldTypes($userMethods->userVettingInfo, $allData);
408
409		$nid = $sql->insert('user', $allData);
410
411		if (isset($eufVals['data']) && count($eufVals['data']))
412		{
413			$usere->addFieldTypes($eufVals);		// Add in the data types for storage
414			$eufVals['WHERE'] = '`user_extended_id` = '.intval($nid);
415			//$usere->addDefaultFields($eufVals);		// Add in defaults for anything not explicitly set (commented out for now - will slightly modify behaviour)
416			$sql->gen("INSERT INTO `#user_extended` (user_extended_id) values ('{$nid}')");
417			$sql->update('user_extended', $eufVals);
418		}
419
420	//	if (SIGNUP_DEBUG)
421	//	{
422		//	 $admin_log->e_log_event(10,debug_backtrace(),"DEBUG","Signup new user",array_merge($allData['data'],$eufVals) ,FALSE,LOG_TO_ROLLING);
423	//	}
424
425		// Log to user audit log if enabled
426		$signup_data['user_id'] = $nid;
427		$signup_data['signup_key'] = $u_key;
428		$signup_data['user_realname'] = $tp->toDB($_POST['realname']);
429
430		$admin_log->user_audit(USER_AUDIT_SIGNUP,$signup_data);
431
432		if (!$nid)
433		{
434			require_once(HEADERF);
435			$message = e107::getMessage()->addError(LAN_SIGNUP_36)->render();
436			$ns->tablerender("", $message);
437
438			require_once(FOOTERF);
439		}
440
441		$adviseLoginName = '';
442		if (vartrue($pref['predefinedLoginName']) && (integer) $pref['allowEmailLogin'] === 0)
443		{
444			$adviseLoginName = LAN_SIGNUP_65.': '.$allData['data']['user_loginname'].'<br />'.LAN_SIGNUP_66.'<br />';
445		}
446
447		// Verification required (may be by email or by admin)
448		if ($pref['user_reg_veri'])
449		{
450			// ========== Send Email =========>
451			if (((int) $pref['user_reg_veri'] !== 2) && $allData['data']['user_email'])		// Don't send if email address blank - means that its not compulsory
452			{
453				$allData['data']['user_id'] = $nid;					// User ID
454				// FIXME build while rendering - user::renderEmail()
455				$allData['data']['activation_url'] = SITEURL."signup.php?activate.".$allData['data']['user_id'].".".$allData['data']['user_sess'];
456				// FIX missing user_name
457				if(!vartrue($allData['data']['user_name'])) $allData['data']['user_name'] = $allData['data']['user_login'];
458
459				// prefered way to send user emails
460
461				if(getperms('0') && !empty($_POST['simulation']))
462				{
463					$simulation = true;
464					$check = true; //removes error message below.
465				}
466				else
467				{
468					$simulation = false;
469				}
470
471				if($simulation !== true) // Alow logged in main-admin to test signup procedure.
472				{
473					$sysuser = e107::getSystemUser(false, false);
474					$sysuser->setData($allData['data']);
475					$sysuser->setId($nid);
476					$check = $sysuser->email('signup', array(
477						'user_id'       => $nid,
478						'user_password' => $savePassword, // for security reasons - password passed ONLY through options
479					));
480				}
481
482				if(getperms('0'))
483				{
484					e107::getMessage()->addDebug(print_a($allData,true));
485					e107::getMessage()->addDebug("Password: <b>".$savePassword."</b>");
486				}
487
488				/*
489                $eml = render_email($allData['data']);
490				$eml['e107_header'] = $eml['userid'];
491				require_once(e_HANDLER.'mail.php');
492				$mailer = new e107Email();
493
494				// FIX - sendEmail returns TRUE or error message...
495				$check = $mailer->sendEmail($allData['data']['user_email'], $allData['data']['user_name'], $eml,FALSE);*/
496
497				if(true !== $check)
498				{
499					$error_message = LAN_SIGNUP_42; // There was a problem, the registration mail was not sent, please contact the website administrator.
500				}
501				unset($allData['data']['user_password']);
502			}
503
504			e107::getEvent()->trigger('usersup', $_POST);  // Old trigger - send everything in the template, including extended fields.
505			e107::getEvent()->trigger('userpartial', array_merge($allData['data'],$eufVals['data']));  // New trigger - send everything in the template, including extended fields.
506			e107::getEvent()->trigger('user_signup_submitted', $_POST);
507
508
509			require_once(HEADERF);
510
511			$after_signup = e_signup::render_after_signup($error_message);
512			$ns->tablerender($after_signup['caption'], $after_signup['text']);
513
514			require_once(FOOTERF);
515			exit;
516		}
517		// User can be signed up immediately
518		else
519		{
520			require_once(HEADERF);
521
522			if(!$sql->select("user", "user_id", "user_loginname='".$allData['data']['user_loginname']."' AND user_password='".$allData['data']['user_password']."'"))
523			{
524				// Error looking up newly created user
525				$ns->tablerender("", LAN_SIGNUP_36);
526				require_once(FOOTERF);
527				exit;
528			}
529
530			// Set initial classes, and any which the user can opt to join
531			if ($init_class = $userMethods->userClassUpdate($row, 'userpartial'))
532			{
533				$allData['data']['user_class'] = $init_class;
534				$user_class_update = $sql->update("user", "user_class = '{$allData['data']['user_class']}' WHERE user_name='{$allData['data']['user_name']}' LIMIT 1");
535
536				if($user_class_update === FALSE)
537				{
538					//$admin_log->e_log_event(10,debug_backtrace(),'USER','Userclass update fail',print_r($row,TRUE),FALSE,LOG_TO_ROLLING);
539					require_once(HEADERF);
540					$ns->tablerender(LAN_SIGNUP_75, LAN_SIGNUP_101);
541					require_once(FOOTERF);
542					exit;
543				}
544			}
545
546			e107::getEvent()->trigger('usersup', $_POST);  // send everything in the template, including extended fields.
547			e107::getEvent()->trigger('userfull', array_merge($allData['data'],$eufVals['data']));  // New trigger - send everything in the template, including extended fields.
548
549			if (isset($pref['signup_text_after']) && (strlen($pref['signup_text_after']) > 2))
550			{
551				$text = $tp->toHTML(str_replace('{NEWLOGINNAME}', $loginname, $pref['signup_text_after']), TRUE, 'parse_sc,defs')."<br />";
552			}
553			else
554			{
555				$text = LAN_SIGNUP_76."&nbsp;".SITENAME.", ".LAN_SIGNUP_12."<br /><br />";
556				$text .= str_replace(array('[',']'), array("<a href='".e_LOGIN."'>", "</a>"), LAN_SIGNUP_13);
557			}
558
559			$ns->tablerender(LAN_SIGNUP_8,$text);
560			require_once(FOOTERF);
561			exit;
562		}
563	}		// End - if (!$error)
564	else
565	{	// 'Recirculate' selected values so they are retained on the form when an error occurs
566		foreach (array('user_class') as $a)
567		{
568			$signupData[$a] = $tp->toForm(varset($allData['data'][$a],''));
569		}
570	}
571}
572
573// Disable the signup form - if either there was an error, or starting from scratch
574require_once(HEADERF);
575
576$qs = ($error ? "stage" : e_QUERY);
577if ($pref['use_coppa'] == 1 && strpos($qs, "stage") === FALSE)
578{
579	$text = $tp->parseTemplate($COPPA_TEMPLATE, TRUE, $signup_shortcodes);
580	$ns->tablerender(LAN_SIGNUP_78, $text, 'coppa');
581	require_once(FOOTERF);
582	exit;
583}
584
585
586if ($qs == 'stage1' && $pref['use_coppa'] == 1)
587{
588	if(isset($_POST['newver']))
589	{
590		if(!vartrue($_POST['coppa']))
591		{
592			$text = $tp->parseTemplate($COPPA_FAIL);
593			$ns->tablerender(LAN_SIGNUP_78, $text, 'coppa');
594			require_once(FOOTERF);
595			exit;
596		}
597	}
598	else
599	{
600		e107::redirect();
601		exit;
602	}
603}
604
605require_once(e_HANDLER."form_handler.php");
606$rs = new form;
607
608// e107::getCoreTemplate('signup', 'signup');
609
610$text = $tp->parseTemplate($SIGNUP_BEGIN.$SIGNUP_BODY.$SIGNUP_END, TRUE, $signup_shortcodes);
611$ns->tablerender(LAN_SIGNUP_79, e107::getMessage()->render('default', true).$text, 'signup' );
612
613require_once(FOOTERF);
614exit;
615
616
617
618//----------------------------------
619// Function returns an image if a field is required.
620function req($field)
621{
622	return ($field == 2 ? "<span class='required'></span>" : "");
623}
624//----------------------------------
625
626function headerjs()
627{
628	return "
629	<script type=\"text/javascript\">
630	function addtext3(sc){
631		document.getElementById('signupform').image.value = sc;
632	}
633
634	function addsig(sc){
635		document.getElementById('signupform').signature.value += sc;
636	}
637	function help(help){
638		document.getElementById('signupform').helpb.value = help;
639	}
640	</script>\n";
641
642}
643