From 0ccb6afdb5ff764a02eb2e15e736583b4baf6868 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 27 Dec 2018 20:50:55 -0500 Subject: [PATCH] Add Register module in src/ - Update REGISTER_* constants definition - Update register template variable name --- boot.php | 6 +- src/Module/Register.php | 311 +++++++++++++++++++++++++ view/templates/register.tpl | 2 +- view/theme/frio/templates/register.tpl | 2 +- 4 files changed, 316 insertions(+), 5 deletions(-) create mode 100644 src/Module/Register.php diff --git a/boot.php b/boot.php index 1766e801ed..a1e5f44f89 100644 --- a/boot.php +++ b/boot.php @@ -103,9 +103,9 @@ define('SSL_POLICY_SELFSIGN', 2); * Registration policies * @{ */ -define('REGISTER_CLOSED', 0); -define('REGISTER_APPROVE', 1); -define('REGISTER_OPEN', 2); +define('REGISTER_CLOSED', \Friendica\Module\Register::CLOSED); +define('REGISTER_APPROVE', \Friendica\Module\Register::APPROVE); +define('REGISTER_OPEN', \Friendica\Module\Register::OPEN); /** * @} */ diff --git a/src/Module/Register.php b/src/Module/Register.php new file mode 100644 index 0000000000..6744a0a5f3 --- /dev/null +++ b/src/Module/Register.php @@ -0,0 +1,311 @@ + + */ +abstract class Register extends BaseModule +{ + const CLOSED = 0; + const APPROVE = 1; + const OPEN = 2; + + /** + * @brief Module GET method to display any content + * + * Extend this method if the module is supposed to return any display + * through a GET request. It can be an HTML page through templating or a + * XML feed or a JSON output. + * + * @return string + */ + public static function content() + { + // logged in users can register others (people/pages/groups) + // even with closed registrations, unless specifically prohibited by site policy. + // 'block_extended_register' blocks all registrations, period. + $block = Config::get('system', 'block_extended_register'); + + if (local_user() && ($block)) { + notice('Permission denied.' . EOL); + return ''; + } + + if ((!local_user()) && (intval(Config::get('config', 'register_policy')) === self::CLOSED)) { + notice('Permission denied.' . EOL); + return ''; + } + + $max_dailies = intval(Config::get('system', 'max_daily_registrations')); + if ($max_dailies) { + $count = DBA::count('user', ['`register_date` > UTC_TIMESTAMP - INTERVAL 1 day']); + if ($count >= $max_dailies) { + Logger::log('max daily registrations exceeded.'); + notice(L10n::t('This site has exceeded the number of allowed daily account registrations. Please try again tomorrow.') . EOL); + return ''; + } + } + + if (!empty($_SESSION['theme'])) { + unset($_SESSION['theme']); + } + if (!empty($_SESSION['mobile-theme'])) { + unset($_SESSION['mobile-theme']); + } + + $username = defaults($_REQUEST, 'username' , ''); + $email = defaults($_REQUEST, 'email' , ''); + $openid_url = defaults($_REQUEST, 'openid_url', ''); + $nickname = defaults($_REQUEST, 'nickname' , ''); + $photo = defaults($_REQUEST, 'photo' , ''); + $invite_id = defaults($_REQUEST, 'invite_id' , ''); + + if (Config::get('system', 'no_openid')) { + $fillwith = ''; + $fillext = ''; + $oidlabel = ''; + } else { + $fillwith = L10n::t('You may (optionally) fill in this form via OpenID by supplying your OpenID and clicking "Register".'); + $fillext = L10n::t('If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items.'); + $oidlabel = L10n::t('Your OpenID (optional): '); + } + + if (Config::get('system', 'publish_all')) { + $profile_publish = ''; + } else { + $publish_tpl = Renderer::getMarkupTemplate('profile_publish.tpl'); + $profile_publish = Renderer::replaceMacros($publish_tpl, [ + '$instance' => 'reg', + '$pubdesc' => L10n::t('Include your profile in member directory?'), + '$yes_selected' => '', + '$no_selected' => ' checked="checked"', + '$str_yes' => L10n::t('Yes'), + '$str_no' => L10n::t('No'), + ]); + } + + $ask_password = ! DBA::count('contact'); + + $tpl = Renderer::getMarkupTemplate('register.tpl'); + + $arr = ['template' => $tpl]; + + Hook::callAll('register_form', $arr); + + $tpl = $arr['template']; + + $tos = new Tos(); + + $o = Renderer::replaceMacros($tpl, [ + '$invitations' => Config::get('system', 'invitation_only'), + '$permonly' => intval(Config::get('config', 'register_policy')) === self::APPROVE, + '$permonlybox' => ['permonlybox', L10n::t('Note for the admin'), '', L10n::t('Leave a message for the admin, why you want to join this node')], + '$invite_desc' => L10n::t('Membership on this site is by invitation only.'), + '$invite_label' => L10n::t('Your invitation code: '), + '$invite_id' => $invite_id, + '$regtitle' => L10n::t('Registration'), + '$registertext' => BBCode::convert(Config::get('config', 'register_text', '')), + '$fillwith' => $fillwith, + '$fillext' => $fillext, + '$oidlabel' => $oidlabel, + '$openid' => $openid_url, + '$namelabel' => L10n::t('Your Full Name (e.g. Joe Smith, real or real-looking): '), + '$addrlabel' => L10n::t('Your Email Address: (Initial information will be send there, so this has to be an existing address.)'), + '$ask_password' => $ask_password, + '$password1' => ['password1', L10n::t('New Password:'), '', L10n::t('Leave empty for an auto generated password.')], + '$password2' => ['confirm', L10n::t('Confirm:'), '', ''], + '$nickdesc' => L10n::t('Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be "nickname@%s".', self::getApp()->getHostName()), + '$nicklabel' => L10n::t('Choose a nickname: '), + '$photo' => $photo, + '$publish' => $profile_publish, + '$regbutt' => L10n::t('Register'), + '$username' => $username, + '$email' => $email, + '$nickname' => $nickname, + '$sitename' => self::getApp()->getHostName(), + '$importh' => L10n::t('Import'), + '$importt' => L10n::t('Import your profile to this friendica instance'), + '$showtoslink' => Config::get('system', 'tosdisplay'), + '$tostext' => L10n::t('Terms of Service'), + '$showprivstatement' => Config::get('system', 'tosprivstatement'), + '$privstatement'=> $tos->privacy_complete, + '$baseurl' => System::baseurl(), + '$form_security_token' => BaseModule::getFormSecurityToken('register'), + '$explicit_content' => Config::get('system', 'explicit_content', false), + '$explicit_content_note' => L10n::t('Note: This node explicitly contains adult content') + ]); + + return $o; + } + + /** + * @brief Module POST method to process submitted data + * + * Extend this method if the module is supposed to process POST requests. + * Doesn't display any content + */ + public static function post() + { + BaseModule::checkFormSecurityTokenRedirectOnError('/register', 'register'); + + $a = self::getApp(); + + $arr = ['post' => $_POST]; + Hook::callAll('register_post', $arr); + + $max_dailies = intval(Config::get('system', 'max_daily_registrations')); + if ($max_dailies) { + $count = DBA::count('user', ['`register_date` > UTC_TIMESTAMP - INTERVAL 1 day']); + if ($count >= $max_dailies) { + return; + } + } + + switch (Config::get('config', 'register_policy')) { + case self::OPEN: + $blocked = 0; + $verified = 1; + break; + + case self::APPROVE: + $blocked = 1; + $verified = 0; + break; + + case self::CLOSED: + default: + if (empty($_SESSION['authenticated']) && empty($_SESSION['administrator'])) { + \notice(L10n::t('Permission denied.') . EOL); + return; + } + $blocked = 1; + $verified = 0; + break; + } + + $netpublish = !empty($_POST['profile_publish_reg']); + + $arr = $_POST; + + $arr['blocked'] = $blocked; + $arr['verified'] = $verified; + $arr['language'] = L10n::detectLanguage(); + + try { + $result = Model\User::create($arr); + } catch (\Exception $e) { + \notice($e->getMessage()); + return; + } + + $user = $result['user']; + + if ($netpublish && intval(Config::get('config', 'register_policy')) !== self::APPROVE) { + $url = $a->getBaseUrl() . '/profile/' . $user['nickname']; + Worker::add(PRIORITY_LOW, 'Directory', $url); + } + + $using_invites = Config::get('system', 'invitation_only'); + $num_invites = Config::get('system', 'number_invites'); + $invite_id = (!empty($_POST['invite_id']) ? Strings::escapeTags(trim($_POST['invite_id'])) : ''); + + if (intval(Config::get('config', 'register_policy')) === self::OPEN) { + if ($using_invites && $invite_id) { + Model\Register::deleteByHash($invite_id); + PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites); + } + + // Only send a password mail when the password wasn't manually provided + if (empty($_POST['password1']) || empty($_POST['confirm'])) { + $res = Model\User::sendRegisterOpenEmail( + $user, + Config::get('config', 'sitename'), + $a->getBaseUrl(), + $result['password'] + ); + + if ($res) { + \info(L10n::t('Registration successful. Please check your email for further instructions.') . EOL); + $a->internalRedirect(); + } else { + \notice( + L10n::t('Failed to send email message. Here your accout details:
login: %s
password: %s

You can change your password after login.', + $user['email'], + $result['password']) + . EOL + ); + } + } else { + \info(L10n::t('Registration successful.') . EOL); + $a->internalRedirect(); + } + } elseif (intval(Config::get('config', 'register_policy')) === self::APPROVE) { + if (!strlen(Config::get('config', 'admin_email'))) { + \notice(L10n::t('Your registration can not be processed.') . EOL); + $a->internalRedirect(); + } + + Model\Register::createForApproval($user['uid'], Config::get('system', 'language'), $_POST['permonlybox']); + + // invite system + if ($using_invites && $invite_id) { + Model\Register::deleteByHash($invite_id); + PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites); + } + + // send email to admins + $admins_stmt = DBA::select( + 'user', + ['uid', 'language', 'email'], + ['email' => explode(',', str_replace(' ', '', Config::get('config', 'admin_email')))] + ); + + // send notification to admins + while ($admin = DBA::fetch($admins_stmt)) { + \notification([ + 'type' => NOTIFY_SYSTEM, + 'event' => 'SYSTEM_REGISTER_REQUEST', + 'source_name' => $user['username'], + 'source_mail' => $user['email'], + 'source_nick' => $user['nickname'], + 'source_link' => $a->getBaseUrl() . '/admin/users/', + 'link' => $a->getBaseUrl() . '/admin/users/', + 'source_photo' => $a->getBaseUrl() . '/photo/avatar/' . $user['uid'] . '.jpg', + 'to_email' => $admin['email'], + 'uid' => $admin['uid'], + 'language' => defaults($admin, 'language', 'en'), + 'show_in_notification_page' => false + ]); + } + DBA::close($admins_stmt); + + // send notification to the user, that the registration is pending + Model\User::sendRegisterPendingEmail( + $user, + Config::get('config', 'sitename'), + $a->getBaseURL(), + $result['password'] + ); + + \info(L10n::t('Your registration is pending approval by the site owner.') . EOL); + $a->internalRedirect(); + } + + return; + } +} diff --git a/view/templates/register.tpl b/view/templates/register.tpl index 4da865d4cf..456fadaab8 100644 --- a/view/templates/register.tpl +++ b/view/templates/register.tpl @@ -41,7 +41,7 @@
-{{if $passwords}} +{{if $ask_password}} {{include file="field_password.tpl" field=$password1}} {{include file="field_password.tpl" field=$password2}} {{/if}} diff --git a/view/theme/frio/templates/register.tpl b/view/theme/frio/templates/register.tpl index feb8035fa3..4819c5ee81 100644 --- a/view/theme/frio/templates/register.tpl +++ b/view/theme/frio/templates/register.tpl @@ -42,7 +42,7 @@
- {{if $passwords}} + {{if $ask_password}} {{include file="field_password.tpl" field=$password1}} {{include file="field_password.tpl" field=$password2}} {{/if}}