function create_user($arr) { // Required: { username, nickname, email } or { openid_url } $a = get_app(); $result = array('success' => false, 'user' => null, 'password' => '', 'message' => ''); $using_invites = get_config('system', 'invitation_only'); $num_invites = get_config('system', 'number_invites'); $invite_id = x($arr, 'invite_id') ? notags(trim($arr['invite_id'])) : ''; $username = x($arr, 'username') ? notags(trim($arr['username'])) : ''; $nickname = x($arr, 'nickname') ? notags(trim($arr['nickname'])) : ''; $email = x($arr, 'email') ? notags(trim($arr['email'])) : ''; $openid_url = x($arr, 'openid_url') ? notags(trim($arr['openid_url'])) : ''; $photo = x($arr, 'photo') ? notags(trim($arr['photo'])) : ''; $password = x($arr, 'password') ? trim($arr['password']) : ''; $blocked = x($arr, 'blocked') ? intval($arr['blocked']) : 0; $verified = x($arr, 'verified') ? intval($arr['verified']) : 0; $publish = x($arr, 'profile_publish_reg') && intval($arr['profile_publish_reg']) ? 1 : 0; $netpublish = strlen(get_config('system', 'directory_submit_url')) ? $publish : 0; $tmp_str = $openid_url; if ($using_invites) { if (!$invite_id) { $result['message'] .= t('An invitation is required.') . EOL; return $result; } $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id)); if (!results($r)) { $result['message'] .= t('Invitation could not be verified.') . EOL; return $result; } } if (!x($username) || !x($email) || !x($nickname)) { if ($openid_url) { if (!validate_url($tmp_str)) { $result['message'] .= t('Invalid OpenID url') . EOL; return $result; } $_SESSION['register'] = 1; $_SESSION['openid'] = $openid_url; require_once 'library/openid.php'; $openid = new LightOpenID(); $openid->identity = $openid_url; $openid->returnUrl = $a->get_baseurl() . '/openid'; $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson'); $openid->optional = array('namePerson/first', 'media/image/aspect11', 'media/image/default'); try { $authurl = $openid->authUrl(); } catch (Exception $e) { $result['message'] .= t("We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.") . EOL . EOL . t("The error message was:") . $e->getMessage() . EOL; return $result; } goaway($authurl); // NOTREACHED } notice(t('Please enter the required information.') . EOL); return; } if (!validate_url($tmp_str)) { $openid_url = ''; } $err = ''; // collapse multiple spaces in name $username = preg_replace('/ +/', ' ', $username); if (mb_strlen($username) > 48) { $result['message'] .= t('Please use a shorter name.') . EOL; } if (mb_strlen($username) < 3) { $result['message'] .= t('Name too short.') . EOL; } // I don't really like having this rule, but it cuts down // on the number of auto-registrations by Russian spammers // Using preg_match was completely unreliable, due to mixed UTF-8 regex support // $no_utf = get_config('system','no_utf'); // $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); // So now we are just looking for a space in the full name. $loose_reg = get_config('system', 'no_regfullname'); if (!$loose_reg) { $username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8'); if (!strpos($username, ' ')) { $result['message'] .= t("That doesn't appear to be your full (First Last) name.") . EOL; } } if (!allowed_email($email)) { $result['message'] .= t('Your email domain is not among those allowed on this site.') . EOL; } if (!valid_email($email) || !validate_email($email)) { $result['message'] .= t('Not a valid email address.') . EOL; } // Disallow somebody creating an account using openid that uses the admin email address, // since openid bypasses email verification. We'll allow it if there is not yet an admin account. $adminlist = explode(",", str_replace(" ", "", strtolower($a->config['admin_email']))); //if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) { if (x($a->config, 'admin_email') && in_array(strtolower($email), $adminlist) && strlen($openid_url)) { $r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($email)); if (count($r)) { $result['message'] .= t('Cannot use that email.') . EOL; } } $nickname = $arr['nickname'] = strtolower($nickname); if (!preg_match("/^[a-z][a-z0-9\\-\\_]*\$/", $nickname)) { $result['message'] .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL; } $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' LIMIT 1", dbesc($nickname)); if (count($r)) { $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL; } // Check deleted accounts that had this nickname. Doesn't matter to us, // but could be a security issue for federated platforms. $r = q("SELECT * FROM `userd`\n \tWHERE `username` = '%s' LIMIT 1", dbesc($nickname)); if (count($r)) { $result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL; } if (strlen($result['message'])) { return $result; } $new_password = strlen($password) ? $password : autoname(6) . mt_rand(100, 9999); $new_password_encoded = hash('whirlpool', $new_password); $result['password'] = $new_password; require_once 'include/crypto.php'; $keys = new_keypair(4096); if ($keys === false) { $result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL; return $result; } $default_service_class = get_config('system', 'default_service_class'); if (!$default_service_class) { $default_service_class = ''; } $prvkey = $keys['prvkey']; $pubkey = $keys['pubkey']; /** * * Create another keypair for signing/verifying * salmon protocol messages. We have to use a slightly * less robust key because this won't be using openssl * but the phpseclib. Since it is PHP interpreted code * it is not nearly as efficient, and the larger keys * will take several minutes each to process. * */ $sres = new_keypair(512); $sprvkey = $sres['prvkey']; $spubkey = $sres['pubkey']; $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,\n\t\t`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone`, `service_class`, `default-location` )\n\t\tVALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC', '%s', '' )", dbesc(generate_user_guid()), dbesc($username), dbesc($new_password_encoded), dbesc($email), dbesc($openid_url), dbesc($nickname), dbesc($pubkey), dbesc($prvkey), dbesc($spubkey), dbesc($sprvkey), dbesc(datetime_convert()), intval($verified), intval($blocked), dbesc($default_service_class)); if ($r) { $r = q("SELECT * FROM `user`\n\t\t\tWHERE `username` = '%s' AND `password` = '%s' LIMIT 1", dbesc($username), dbesc($new_password_encoded)); if ($r !== false && count($r)) { $u = $r[0]; $newuid = intval($r[0]['uid']); } } else { $result['message'] .= t('An error occurred during registration. Please try again.') . EOL; return $result; } /** * if somebody clicked submit twice very quickly, they could end up with two accounts * due to race condition. Remove this one. */ $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' ", dbesc($nickname)); if (count($r) > 1 && $newuid) { $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL; q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid)); return $result; } if (x($newuid) !== false) { $r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )\n\t\t\tVALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ", intval($newuid), t('default'), 1, dbesc($username), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), intval($publish), intval($netpublish)); if ($r === false) { $result['message'] .= t('An error occurred creating your default profile. Please try again.') . EOL; // Start fresh next time. $r = q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid)); return $result; } $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,\n\t\t\t`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness` )\n\t\t\tVALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ", intval($newuid), datetime_convert(), dbesc($username), dbesc($nickname), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/profile/{$nickname}"), dbesc(normalise_link($a->get_baseurl() . "/profile/{$nickname}")), dbesc($a->get_baseurl() . "/dfrn_request/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_notify/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_poll/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_confirm/{$nickname}"), dbesc($a->get_baseurl() . "/poco/{$nickname}"), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert())); // Create a group with no members. This allows somebody to use it // right away as a default group for new contacts. require_once 'include/group.php'; group_add($newuid, t('Friends')); $r = q("SELECT id FROM `group` WHERE uid = %d AND name = '%s'", intval($newuid), dbesc(t('Friends'))); if ($r && count($r)) { $def_gid = $r[0]['id']; q("UPDATE user SET def_gid = %d WHERE uid = %d", intval($r[0]['id']), intval($newuid)); } if (get_config('system', 'newuser_private') && $def_gid) { q("UPDATE user SET allow_gid = '%s' WHERE uid = %d", dbesc("<" . $def_gid . ">"), intval($newuid)); } } // if we have no OpenID photo try to look up an avatar if (!strlen($photo)) { $photo = avatar_img($email); } // unless there is no avatar-plugin loaded if (strlen($photo)) { require_once 'include/Photo.php'; $photo_failure = false; $filename = basename($photo); $img_str = fetch_url($photo, true); // guess mimetype from headers or filename $type = guess_image_type($photo, true); $img = new Photo($img_str, $type); if ($img->is_valid()) { $img->scaleImageSquare(175); $hash = photo_new_resource(); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5); if ($r === false) { $photo_failure = true; } $img->scaleImage(48); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6); if ($r === false) { $photo_failure = true; } if (!$photo_failure) { q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ", dbesc($hash)); } } } call_hooks('register_account', $newuid); $result['success'] = true; $result['user'] = $u; return $result; }
function register_post(&$a) { global $lang; $verified = 0; $blocked = 1; switch ($a->config['register_policy']) { case REGISTER_OPEN: $blocked = 0; $verified = 1; break; case REGISTER_APPROVE: $blocked = 1; $verified = 0; break; default: case REGISTER_CLOSED: if (!x($_SESSION, 'authenticated') && !x($_SESSION, 'administrator')) { notice(t('Permission denied.') . EOL); return; } $blocked = 1; $verified = 0; break; } $using_invites = get_config('system', 'invitation_only'); $num_invites = get_config('system', 'number_invites'); $invite_id = x($_POST, 'invite_id') ? notags(trim($_POST['invite_id'])) : ''; $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : ''; $nickname = x($_POST, 'nickname') ? notags(trim($_POST['nickname'])) : ''; $email = x($_POST, 'email') ? notags(trim($_POST['email'])) : ''; $openid_url = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : ''; $photo = x($_POST, 'photo') ? notags(trim($_POST['photo'])) : ''; $publish = x($_POST, 'profile_publish_reg') && intval($_POST['profile_publish_reg']) ? 1 : 0; $netpublish = strlen(get_config('system', 'directory_submit_url')) ? $publish : 0; $tmp_str = $openid_url; if ($using_invites) { if (!$invite_id) { notice(t('An invitation is required.') . EOL); return; } $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id)); if (!results($r)) { notice(t('Invitation could not be verified.') . EOL); return; } } if (!x($username) || !x($email) || !x($nickname)) { if ($openid_url) { if (!validate_url($tmp_str)) { notice(t('Invalid OpenID url') . EOL); return; } $_SESSION['register'] = 1; $_SESSION['openid'] = $openid_url; require_once 'library/openid.php'; $openid = new LightOpenID(); $openid->identity = $openid_url; $openid->returnUrl = $a->get_baseurl() . '/openid'; $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson'); $openid->optional = array('namePerson/first', 'media/image/aspect11', 'media/image/default'); goaway($openid->authUrl()); // NOTREACHED } notice(t('Please enter the required information.') . EOL); return; } if (!validate_url($tmp_str)) { $openid_url = ''; } $err = ''; // collapse multiple spaces in name $username = preg_replace('/ +/', ' ', $username); if (mb_strlen($username) > 48) { $err .= t('Please use a shorter name.') . EOL; } if (mb_strlen($username) < 3) { $err .= t('Name too short.') . EOL; } // I don't really like having this rule, but it cuts down // on the number of auto-registrations by Russian spammers // Using preg_match was completely unreliable, due to mixed UTF-8 regex support // $no_utf = get_config('system','no_utf'); // $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); // So now we are just looking for a space in the full name. $loose_reg = get_config('system', 'no_regfullname'); if (!$loose_reg) { $username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8'); if (!strpos($username, ' ')) { $err .= t("That doesn't appear to be your full (First Last) name.") . EOL; } } if (!allowed_email($email)) { $err .= t('Your email domain is not among those allowed on this site.') . EOL; } if (!valid_email($email) || !validate_email($email)) { $err .= t('Not a valid email address.') . EOL; } // Disallow somebody creating an account using openid that uses the admin email address, // since openid bypasses email verification. We'll allow it if there is not yet an admin account. if (x($a->config, 'admin_email') && strcasecmp($email, $a->config['admin_email']) == 0 && strlen($openid_url)) { $r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($email)); if (count($r)) { $err .= t('Cannot use that email.') . EOL; } } $nickname = $_POST['nickname'] = strtolower($nickname); if (!preg_match("/^[a-z][a-z0-9\\-\\_]*\$/", $nickname)) { $err .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL; } $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' LIMIT 1", dbesc($nickname)); if (count($r)) { $err .= t('Nickname is already registered. Please choose another.') . EOL; } if (strlen($err)) { notice($err); return; } $new_password = autoname(6) . mt_rand(100, 9999); $new_password_encoded = hash('whirlpool', $new_password); $res = openssl_pkey_new(array('digest_alg' => 'sha1', 'private_key_bits' => 4096, 'encrypt_key' => false)); // Get private key if (empty($res)) { notice(t('SERIOUS ERROR: Generation of security keys failed.') . EOL); return; } $prvkey = ''; openssl_pkey_export($res, $prvkey); // Get public key $pkey = openssl_pkey_get_details($res); $pubkey = $pkey["key"]; /** * * Create another keypair for signing/verifying * salmon protocol messages. We have to use a slightly * less robust key because this won't be using openssl * but the phpseclib. Since it is PHP interpreted code * it is not nearly as efficient, and the larger keys * will take several minutes each to process. * */ $sres = openssl_pkey_new(array('digest_alg' => 'sha1', 'private_key_bits' => 512, 'encrypt_key' => false)); // Get private key $sprvkey = ''; openssl_pkey_export($sres, $sprvkey); // Get public key $spkey = openssl_pkey_get_details($sres); $spubkey = $spkey["key"]; $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,\n\t\t`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked` )\n\t\tVALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )", dbesc(generate_user_guid()), dbesc($username), dbesc($new_password_encoded), dbesc($email), dbesc($openid_url), dbesc($nickname), dbesc($pubkey), dbesc($prvkey), dbesc($spubkey), dbesc($sprvkey), dbesc(datetime_convert()), intval($verified), intval($blocked)); if ($r) { $r = q("SELECT `uid` FROM `user` \n\t\t\tWHERE `username` = '%s' AND `password` = '%s' LIMIT 1", dbesc($username), dbesc($new_password_encoded)); if ($r !== false && count($r)) { $newuid = intval($r[0]['uid']); } } else { notice(t('An error occurred during registration. Please try again.') . EOL); return; } /** * if somebody clicked submit twice very quickly, they could end up with two accounts * due to race condition. Remove this one. */ $r = q("SELECT `uid` FROM `user`\n \tWHERE `nickname` = '%s' ", dbesc($nickname)); if (count($r) > 1 && $newuid) { $err .= t('Nickname is already registered. Please choose another.') . EOL; q("DELETE FROM `user` WHERE `uid` = %d LIMIT 1", intval($newuid)); notice($err); return; } if (x($newuid) !== false) { $r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )\n\t\t\tVALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ", intval($newuid), 'default', 1, dbesc($username), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), intval($publish), intval($netpublish)); if ($r === false) { notice(t('An error occurred creating your default profile. Please try again.') . EOL); // Start fresh next time. $r = q("DELETE FROM `user` WHERE `uid` = %d", intval($newuid)); return; } $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,\n\t\t\t`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date` )\n\t\t\tVALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($newuid), datetime_convert(), dbesc($username), dbesc($nickname), dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"), dbesc($a->get_baseurl() . "/profile/{$nickname}"), dbesc(normalise_link($a->get_baseurl() . "/profile/{$nickname}")), dbesc($a->get_baseurl() . "/dfrn_request/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_notify/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_poll/{$nickname}"), dbesc($a->get_baseurl() . "/dfrn_confirm/{$nickname}"), dbesc($a->get_baseurl() . "/poco/{$nickname}"), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert())); } $use_gravatar = get_config('system', 'no_gravatar') ? false : true; // if we have an openid photo use it. // otherwise unless it is disabled, use gravatar if ($use_gravatar || strlen($photo)) { require_once 'include/Photo.php'; if ($use_gravatar && !strlen($photo)) { $photo = gravatar_img($email); } $photo_failure = false; $filename = basename($photo); $img_str = fetch_url($photo, true); $img = new Photo($img_str); if ($img->is_valid()) { $img->scaleImageSquare(175); $hash = photo_new_resource(); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4); if ($r === false) { $photo_failure = true; } $img->scaleImage(80); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5); if ($r === false) { $photo_failure = true; } $img->scaleImage(48); $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6); if ($r === false) { $photo_failure = true; } if (!$photo_failure) { q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ", dbesc($hash)); } } } if ($netpublish && $a->config['register_policy'] != REGISTER_APPROVE) { $url = $a->get_baseurl() . "/profile/{$nickname}"; proc_run('php', "include/directory.php", "{$url}"); } call_hooks('register_account', $newuid); if ($a->config['register_policy'] == REGISTER_OPEN) { if ($using_invites && $invite_id) { q("delete * from register where hash = '%s' limit 1", dbesc($invite_id)); set_pconfig($newuid, 'system', 'invites_remaining', $num_invites); } $email_tpl = get_intltext_template("register_open_eml.tpl"); $email_tpl = replace_macros($email_tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $username, '$email' => $email, '$password' => $new_password, '$uid' => $newuid)); $res = mail($email, sprintf(t('Registration details for %s'), $a->config['sitename']), $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit'); if ($res) { info(t('Registration successful. Please check your email for further instructions.') . EOL); goaway(z_root()); } else { notice(t('Failed to send email message. Here is the message that failed.') . $email_tpl . EOL); } } elseif ($a->config['register_policy'] == REGISTER_APPROVE) { if (!strlen($a->config['admin_email'])) { notice(t('Your registration can not be processed.') . EOL); goaway(z_root()); } $hash = random_string(); $r = q("INSERT INTO `register` ( `hash`, `created`, `uid`, `password`, `language` ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ", dbesc($hash), dbesc(datetime_convert()), intval($newuid), dbesc($new_password), dbesc($lang)); $r = q("SELECT `language` FROM `user` WHERE `email` = '%s' LIMIT 1", dbesc($a->config['admin_email'])); if (count($r)) { push_lang($r[0]['language']); } else { push_lang('en'); } if ($using_invites && $invite_id) { q("delete * from register where hash = '%s' limit 1", dbesc($invite_id)); set_pconfig($newuid, 'system', 'invites_remaining', $num_invites); } $email_tpl = get_intltext_template("register_verify_eml.tpl"); $email_tpl = replace_macros($email_tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $username, '$email' => $email, '$password' => $new_password, '$uid' => $newuid, '$hash' => $hash)); $res = mail($a->config['admin_email'], sprintf(t('Registration request at %s'), $a->config['sitename']), $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit'); pop_lang(); if ($res) { info(t('Your registration is pending approval by the site owner.') . EOL); goaway(z_root()); } } return; }
function import_account(&$a, $file) { logger("Start user import from " . $file['tmp_name']); /* STEPS 1. checks 2. replace old baseurl with new baseurl 3. import data (look at user id and contacts id) 4. archive non-dfrn contacts 5. send message to dfrn contacts */ $account = json_decode(file_get_contents($file['tmp_name']), true); if ($account === null) { notice(t("Error decoding account file")); return; } if (!x($account, 'version')) { notice(t("Error! No version data in file! This is not a Friendica account file?")); return; } /* // this is not required as we remove columns in json not in current db schema if ($account['schema'] != DB_UPDATE_VERSION) { notice(t("Error! I can't import this file: DB schema version is not compatible.")); return; } */ // check for username $r = q("SELECT uid FROM user WHERE nickname='%s'", $account['user']['nickname']); if ($r === false) { logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL); notice(t('Error! Cannot check nickname')); return; } if (count($r) > 0) { notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname'])); return; } // check if username matches deleted account $r = q("SELECT id FROM userd WHERE username='******'", $account['user']['nickname']); if ($r === false) { logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL); notice(t('Error! Cannot check nickname')); return; } if (count($r) > 0) { notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname'])); return; } $oldbaseurl = $account['baseurl']; $newbaseurl = $a->get_baseurl(); $olduid = $account['user']['uid']; unset($account['user']['uid']); unset($account['user']['account_expired']); unset($account['user']['account_expires_on']); unset($account['user']['expire_notification_sent']); foreach ($account['user'] as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); } // import user $r = db_import_assoc('user', $account['user']); if ($r === false) { //echo "<pre>"; var_dump($r, $query, mysql_error()); killme(); logger("uimport:insert user : ERROR : " . last_error(), LOGGER_NORMAL); notice(t("User creation error")); return; } $newuid = last_insert_id(); //~ $newuid = 1; // Generate a new guid for the account. Otherwise there will be problems with diaspora q("UPDATE `user` SET `guid` = '%s' WHERE `uid` = %d", dbesc(generate_user_guid()), intval($newuid)); foreach ($account['profile'] as &$profile) { foreach ($profile as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); foreach (array("profile", "avatar") as $k) { $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v); } } $profile['uid'] = $newuid; $r = db_import_assoc('profile', $profile); if ($r === false) { logger("uimport:insert profile " . $profile['profile-name'] . " : ERROR : " . last_error(), LOGGER_NORMAL); info(t("User profile creation error")); import_cleanup($newuid); return; } } $errorcount = 0; foreach ($account['contact'] as &$contact) { if ($contact['uid'] == $olduid && $contact['self'] == '1') { foreach ($contact as $k => &$v) { $v = str_replace($oldbaseurl, $newbaseurl, $v); foreach (array("profile", "avatar", "micro") as $k) { $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v); } } } if ($contact['uid'] == $olduid && $contact['self'] == '0') { // set contacts 'avatar-date' to "0000-00-00 00:00:00" to let poller to update urls $contact["avatar-date"] = "0000-00-00 00:00:00"; switch ($contact['network']) { case NETWORK_DFRN: // send relocate message (below) break; case NETWORK_ZOT: // TODO handle zot network break; case NETWORK_MAIL2: // TODO ? break; case NETWORK_FEED: case NETWORK_MAIL: // Nothing to do break; default: // archive other contacts $contact['archive'] = "1"; } } $contact['uid'] = $newuid; $r = db_import_assoc('contact', $contact); if ($r === false) { logger("uimport:insert contact " . $contact['nick'] . "," . $contact['network'] . " : ERROR : " . last_error(), LOGGER_NORMAL); $errorcount++; } else { $contact['newid'] = last_insert_id(); } } if ($errorcount > 0) { notice(sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount)); } foreach ($account['group'] as &$group) { $group['uid'] = $newuid; $r = db_import_assoc('group', $group); if ($r === false) { logger("uimport:insert group " . $group['name'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } else { $group['newid'] = last_insert_id(); } } foreach ($account['group_member'] as &$group_member) { $group_member['uid'] = $newuid; $import = 0; foreach ($account['group'] as $group) { if ($group['id'] == $group_member['gid'] && isset($group['newid'])) { $group_member['gid'] = $group['newid']; $import++; break; } } foreach ($account['contact'] as $contact) { if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) { $group_member['contact-id'] = $contact['newid']; $import++; break; } } if ($import == 2) { $r = db_import_assoc('group_member', $group_member); if ($r === false) { logger("uimport:insert group member " . $group_member['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } } foreach ($account['photo'] as &$photo) { $photo['uid'] = $newuid; $photo['data'] = hex2bin($photo['data']); $p = new Photo($photo['data'], $photo['type']); $r = $p->store($photo['uid'], $photo['contact-id'], $photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], $photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']); if ($r === false) { logger("uimport:insert photo " . $photo['resource-id'] . "," . $photo['scale'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } foreach ($account['pconfig'] as &$pconfig) { $pconfig['uid'] = $newuid; $r = db_import_assoc('pconfig', $pconfig); if ($r === false) { logger("uimport:insert pconfig " . $pconfig['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL); } } // send relocate messages proc_run('php', 'include/notifier.php', 'relocate', $newuid); info(t("Done. You can now login with your username and password")); goaway($a->get_baseurl() . "/login"); }