<?php
if(IN_MANAGER_MODE!="true") die("<b>INCLUDE_ORDERING_ERROR</b><br /><br />Please use the MODX Content Manager instead of accessing this file directly.");
if (!$modx->hasPermission('save_web_user')) {
	$modx->webAlertAndQuit($_lang["error_no_privileges"]);
}

$tbl_web_users           = $modx->getFullTableName('web_users');
$tbl_web_user_attributes = $modx->getFullTableName('web_user_attributes');
$tbl_web_groups          = $modx->getFullTableName('web_groups');

$input = $_POST;
foreach($input as $k=>$v) {
    if($k!=='comment') {
        $v = sanitize($v);
    }
    $input[$k] = $v;
}

$id                   = intval($input['id']);
$oldusername          = $input['oldusername'];
$newusername          = !empty ($input['newusername']) ? trim($input['newusername']) : "New User";
$esc_newusername      = $modx->db->escape($newusername);
$fullname             = $input['fullname'];
$genpassword          = $input['newpassword'];
$passwordgenmethod    = $input['passwordgenmethod'];
$passwordnotifymethod = $input['passwordnotifymethod'];
$specifiedpassword    = $input['specifiedpassword'];
$email                = $input['email'];
$esc_email            = $modx->db->escape($email);
$oldemail             = $input['oldemail'];
$phone                = $input['phone'];
$mobilephone          = $input['mobilephone'];
$fax                  = $input['fax'];
$dob                  = !empty ($input['dob']) ? $modx->toTimeStamp($input['dob']) : 0;
$country              = $input['country'];
$street               = $input['street'];
$city                 = $input['city'];
$state                = $input['state'];
$zip                  = $input['zip'];
$gender               = !empty($input['gender']) ? $input['gender'] : 0;
$photo                = $input['photo'];
$comment              = $input['comment'];
$role                 = !empty($input['role']) ? $input['role'] : 0;
$failedlogincount     = !empty($input['failedlogincount']) ? $input['failedlogincount'] : 0;
$blocked              = !empty($input['blocked']) ? $input['blocked'] : 0;
$blockeduntil         = !empty($input['blockeduntil']) ? $modx->toTimeStamp($input['blockeduntil']) : 0;
$blockedafter         = !empty($input['blockedafter']) ? $modx->toTimeStamp($input['blockedafter']) : 0;
$user_groups          = $input['user_groups'];

// verify password
if ($passwordgenmethod == "spec" && $input['specifiedpassword'] != $input['confirmpassword']) {
	webAlertAndQuit("Password typed is mismatched");
}

// verify email
if ($email == '' || !preg_match("/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,24}$/i", $email)) {
	webAlertAndQuit("E-mail address doesn't seem to be valid!");
}

switch ($input['mode']) {
	case '87' : // new user
		// check if this user name already exist
		$rs = $modx->db->select('count(id)', $tbl_web_users, "username='{$esc_newusername}'");
		$limit = $modx->db->getValue($rs);
		if ($limit > 0) {
			webAlertAndQuit("User name is already in use!");
		}

		// check if the email address already exist
		$rs = $modx->db->select('count(id)', $tbl_web_user_attributes, "email='{$esc_email}' AND id!='{$id}'");
		$limit = $modx->db->getValue($rs);
		if ($limit > 0) {
				webAlertAndQuit("Email is already in use!");
		}

		// generate a new password for this user
		if ($specifiedpassword != "" && $passwordgenmethod == "spec") {
			if (strlen($specifiedpassword) < 6) {
				webAlertAndQuit("Password is too short!");
			} else {
				$newpassword = $specifiedpassword;
			}
		}
		elseif ($specifiedpassword == "" && $passwordgenmethod == "spec") {
			webAlertAndQuit("You didn't specify a password for this user!");
		}
		elseif ($passwordgenmethod == 'g') {
			$newpassword = generate_password(8);
		} else {
			webAlertAndQuit("No password generation method specified!");
		}

		// invoke OnBeforeWUsrFormSave event
		$modx->invokeEvent("OnBeforeWUsrFormSave", array (
			"mode" => "new",
		));

		// create the user account
		$field = array();
		$field['username'] = $esc_newusername;
		$field['password'] = md5($newpassword);
		$internalKey = $modx->db->insert($field, $tbl_web_users);

        $field = compact('internalKey','fullname','role','email','phone','mobilephone','fax','zip','street','city','state','country','gender','dob','photo','comment','blocked','blockeduntil','blockedafter');
        $field = $modx->db->escape($field);
		$modx->db->insert($field, $tbl_web_user_attributes);

		// Save User Settings
		saveUserSettings($internalKey);

		// invoke OnWebSaveUser event
		$modx->invokeEvent("OnWebSaveUser", array (
			"mode" => "new",
			"userid" => $internalKey,
			"username" => $newusername,
			"userpassword" => $newpassword,
			"useremail" => $email,
			"userfullname" => $fullname
		));

		// invoke OnWUsrFormSave event
		$modx->invokeEvent("OnWUsrFormSave", array (
			"mode" => "new",
			"id" => $internalKey
		));

		// Set the item name for logger
		$_SESSION['itemname'] = $newusername;

		/*******************************************************************************/
		// put the user in the user_groups he/ she should be in
		// first, check that up_perms are switched on!
		if ($use_udperms == 1) {
			if (count($user_groups) > 0) {
				for ($i = 0; $i < count($user_groups); $i++) {
					$f = array();
					$f['webgroup'] = intval($user_groups[$i]);
					$f['webuser']  = $internalKey;
					$modx->db->insert($f, $tbl_web_groups);
				}
			}
		}
		// end of user_groups stuff!

		if ($passwordnotifymethod == 'e') {
			sendMailMessage($email, $newusername, $newpassword, $fullname);
			if ($input['stay'] != '') {
				$a = ($input['stay'] == '2') ? "88&id={$internalKey}" : "87";
				$header = "Location: index.php?a={$a}&r=2&stay=" . $input['stay'];
				header($header);
			} else {
				$header = "Location: index.php?a=99&r=2";
				header($header);
			}
		} else {
			if ($input['stay'] != '') {
				$a = ($input['stay'] == '2') ? "88&id={$internalKey}" : "87";
				$stayUrl = "index.php?a={$a}&r=2&stay=" . $input['stay'];
			} else {
				$stayUrl = "index.php?a=99&r=2";
			}
			
			include_once "header.inc.php";
?>
			<h1><?php echo $_lang['web_user_title']; ?></h1>

			<div id="actions">
			<ul class="actionButtons">
				<li class="transition"><a href="<?php echo $stayUrl ?>"><img src="<?php echo $_style["icons_save"] ?>" /> <?php echo $_lang['edit']; ?></a></li>
			</ul>
			</div>
            <div class="section">
			<div class="sectionHeader"><?php echo $_lang['web_user_title']; ?></div>
			<div class="sectionBody">
			<div id="disp">
			<p>
			<?php echo sprintf($_lang["password_msg"], $newusername, $newpassword); ?>
			</p>
			</div>
			</div>
            </div>
		<?php

			include_once "footer.inc.php";
		}
		break;
	case '88' : // edit user
		// generate a new password for this user
		if ($genpassword == 1) {
			if ($specifiedpassword != "" && $passwordgenmethod == "spec") {
				if (strlen($specifiedpassword) < 6) {
					webAlertAndQuit("Password is too short!");
				} else {
					$newpassword = $specifiedpassword;
				}
			}
			elseif ($specifiedpassword == "" && $passwordgenmethod == "spec") {
				webAlertAndQuit("You didn't specify a password for this user!");
			}
			elseif ($passwordgenmethod == 'g') {
				$newpassword = generate_password(8);
			} else {
				webAlertAndQuit("No password generation method specified!");
			}
		}
		if ($passwordnotifymethod == 'e') {
			sendMailMessage($email, $newusername, $newpassword, $fullname);
		}

		// check if the username already exist
		$rs = $modx->db->select('count(id)', $tbl_web_users, "username='{$esc_newusername}' AND id!='{$id}'");
		$limit = $modx->db->getValue($rs);
		if ($limit > 0) {
				webAlertAndQuit("User name is already in use!");
		}

		// check if the email address already exists
		$rs = $modx->db->select('count(internalKey)', $tbl_web_user_attributes, "email='{$esc_email}' AND internalKey!='{$id}'");
		$limit = $modx->db->getValue($rs);
		if ($limit > 0) {
				webAlertAndQuit("Email is already in use!");
		}

		// invoke OnBeforeWUsrFormSave event
		$modx->invokeEvent("OnBeforeWUsrFormSave", array (
			"mode" => "upd",
			"id" => $id
		));

		// update user name and password
		$field = array();
		$field['username'] = $esc_newusername;
		if($genpassword == 1) {
		    $field['password'] = md5($newpassword);
		}
		$modx->db->update($field, $tbl_web_users, "id='{$id}'");
		$field = compact('fullname','role','email','phone','mobilephone','fax','zip','street','city','state','country','gender','dob','photo','comment','failedlogincount','blocked','blockeduntil','blockedafter');
		$field = $modx->db->escape($field);
		$modx->db->update($field, $tbl_web_user_attributes, "internalKey='{$id}'");

		// Save User Settings
		saveUserSettings($id);

		// Set the item name for logger
		$_SESSION['itemname'] = $newusername;

		// invoke OnWebSaveUser event
		$modx->invokeEvent("OnWebSaveUser", array (
			"mode" => "upd",
			"userid" => $id,
			"username" => $newusername,
			"userpassword" => $newpassword,
			"useremail" => $email,
			"userfullname" => $fullname,
			"oldusername" => (($oldusername != $newusername) ? $oldusername : ""),
			"olduseremail" => (($oldemail != $email) ? $oldemail : "")
			));

		// invoke OnWebChangePassword event
		if ($genpassword == 1) {
			$modx->invokeEvent("OnWebChangePassword", array (
				"userid" => $id,
				"username" => $newusername,
				"userpassword" => $newpassword
			));
		}

		// invoke OnWUsrFormSave event
		$modx->invokeEvent("OnWUsrFormSave", array (
			"mode" => "upd",
			"id" => $id
		));

		/*******************************************************************************/
		// put the user in the user_groups he/ she should be in
		// first, check that up_perms are switched on!
		if ($use_udperms == 1) {
			// as this is an existing user, delete his/ her entries in the groups before saving the new groups
			$modx->db->delete($tbl_web_groups, "webuser='{$id}'");
			if (count($user_groups) > 0) {
				for ($i = 0; $i < count($user_groups); $i++) {
					$field = array();
					$field['webgroup'] = intval($user_groups[$i]);
					$field['webuser']  = $id;
					$modx->db->insert($field, $tbl_web_groups);
				}
			}
		}
		// end of user_groups stuff!
		/*******************************************************************************/

		if ($genpassword == 1 && $passwordnotifymethod == 's') {
			if ($input['stay'] != '') {
				$a = ($input['stay'] == '2') ? "88&id={$id}" : "87";
				$stayUrl = "index.php?a={$a}&r=2&stay=" . $input['stay'];
			} else {
				$stayUrl = "index.php?a=99&r=2";
			}
			
			include_once "header.inc.php";
?>
			<h1><?php echo $_lang['web_user_title']; ?></h1>

			<div id="actions">
			<ul class="actionButtons">
				<li class="transition"><a href="<?php echo $stayUrl ?>"><img src="<?php echo $_style["icons_save"] ?>" /> <?php echo $_lang['edit']; ?></a></li>
			</ul>
			</div>
            <div class="section">
			<div class="sectionHeader"><?php echo $_lang['web_user_title']; ?></div>
			<div class="sectionBody">
			<div id="disp">
				<p><?php echo sprintf($_lang["password_msg"], $newusername, $newpassword); ?></p>
			</div>
			</div>
            </div>
		<?php

			include_once "footer.inc.php";
		} else {
			if ($input['stay'] != '') {
				$a = ($input['stay'] == '2') ? "88&id={$id}" : "87";
				$header = "Location: index.php?a={$a}&r=2&stay=" . $input['stay'];
				header($header);
			} else {
				$header = "Location: index.php?a=99&r=2";
				header($header);
			}
		}
		break;
	default :
		webAlertAndQuit("No operation set in request.");
}

// in case any plugins include a quoted_printable function
function save_user_quoted_printable($string) {
	$crlf = "\n" ;
	$string = preg_replace('!(\r\n|\r|\n)!', $crlf, $string) . $crlf ;
	$f[] = '/([\000-\010\013\014\016-\037\075\177-\377])/e' ;
	$r[] = "'=' . sprintf('%02X', ord('\\1'))" ; $f[] = '/([\011\040])' . $crlf . '/e' ;
	$r[] = "'=' . sprintf('%02X', ord('\\1')) . '" . $crlf . "'" ;
	$string = preg_replace($f, $r, $string) ;
	return trim(wordwrap($string, 70, ' =' . $crlf)) ;
}

// Send an email to the user
function sendMailMessage($email, $uid, $pwd, $ufn) {
	global $modx,$_lang,$websignupemail_message;
	global $emailsubject, $emailsender;
	global $site_name, $site_url;
	$message = sprintf($websignupemail_message, $uid, $pwd); // use old method
	// replace placeholders
	$message = str_replace("[+uid+]", $uid, $message);
	$message = str_replace("[+pwd+]", $pwd, $message);
	$message = str_replace("[+ufn+]", $ufn, $message);
	$message = str_replace("[+sname+]", $site_name, $message);
	$message = str_replace("[+saddr+]", $emailsender, $message);
	$message = str_replace("[+semail+]", $emailsender, $message);
	$message = str_replace("[+surl+]", $site_url, $message);

	$param = array();
	$param['from']    = "{$site_name}<{$emailsender}>";
	$param['subject'] = $emailsubject;
	$param['body']    = $message;
	$param['to']      = $email;
	$param['type']    = 'text';
	$rs = $modx->sendmail($param);
	if (!$rs) {
		$modx->manager->saveFormValues();
		$modx->messageQuit("{$email} - {$_lang['error_sending_email']}");
	}
}

// Save User Settings
function saveUserSettings($id) {
	global $modx;
    $tbl_web_user_settings = $modx->getFullTableName('web_user_settings');
    
	$settings = array (
		"login_home",
		"allowed_ip",
		"allowed_days"
	);

	$modx->db->delete($tbl_web_user_settings,"webuser='{$id}'");

	foreach ($settings as $n) {
		$vl = $_POST[$n];
		if (is_array($vl)) {
			$vl = implode(",", $vl);
		}
		if ($vl != '') {
		    $f = array();
		    $f['webuser']       = $id;
		    $f['setting_name']  = $n;
		    $f['setting_value'] = $vl;
		    $f = $modx->db->escape($f);
		    $modx->db->insert($f, $tbl_web_user_settings);
		}
	}
}

// Web alert -  sends an alert to web browser
function webAlertAndQuit($msg) {
	global $id, $modx;
	$mode = $_POST['mode'];
	$modx->manager->saveFormValues($mode);
	$modx->webAlertAndQuit($msg, "index.php?a={$mode}" . ($mode == '88' ? "&id={$id}" : ''));
}

// Generate password
function generate_password($length = 10) {
	$allowable_characters = "abcdefghjkmnpqrstuvxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
	$ps_len = strlen($allowable_characters);
	mt_srand((double) microtime() * 1000000);
	$pass = "";
	for ($i = 0; $i < $length; $i++) {
		$pass .= $allowable_characters[mt_rand(0, $ps_len -1)];
	}
	return $pass;
}

function sanitize($str='',$safecount=0) {
	global $modx;
	$safecount++;
	if (1000 < $safecount) {
		exit("error too many loops '{$safecount}'");
	}
	if(is_array($str)) {
		foreach($str as $i=>$v) {
			$str[$i] = sanitize($v,$safecount);
		}
	}
	else {
		// $str = strip_tags($str); // LEAVE < and > intact
		$str = htmlspecialchars($str, ENT_NOQUOTES, $modx->config['modx_charset']);
	}
	return $str;
}
