Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

319 lines
11 KiB

  1. <?php
  2. namespace Friendica\Module;
  3. use Friendica\BaseModule;
  4. use Friendica\Content\Text\BBCode;
  5. use Friendica\Core\Config;
  6. use Friendica\Core\Hook;
  7. use Friendica\Core\L10n;
  8. use Friendica\Core\L10n\L10n as L10nClass;
  9. use Friendica\Core\Logger;
  10. use Friendica\Core\PConfig;
  11. use Friendica\Core\Renderer;
  12. use Friendica\Core\Worker;
  13. use Friendica\Database\DBA;
  14. use Friendica\Model;
  15. use Friendica\Util\Strings;
  16. /**
  17. * @author Hypolite Petovan <hypolite@mrpetovan.com>
  18. */
  19. class Register extends BaseModule
  20. {
  21. const CLOSED = 0;
  22. const APPROVE = 1;
  23. const OPEN = 2;
  24. /**
  25. * @brief Module GET method to display any content
  26. *
  27. * Extend this method if the module is supposed to return any display
  28. * through a GET request. It can be an HTML page through templating or a
  29. * XML feed or a JSON output.
  30. *
  31. * @return string
  32. */
  33. public static function content()
  34. {
  35. // logged in users can register others (people/pages/groups)
  36. // even with closed registrations, unless specifically prohibited by site policy.
  37. // 'block_extended_register' blocks all registrations, period.
  38. $block = Config::get('system', 'block_extended_register');
  39. if (local_user() && ($block)) {
  40. notice('Permission denied.' . EOL);
  41. return '';
  42. }
  43. if ((!local_user()) && (intval(Config::get('config', 'register_policy')) === self::CLOSED)) {
  44. notice('Permission denied.' . EOL);
  45. return '';
  46. }
  47. $max_dailies = intval(Config::get('system', 'max_daily_registrations'));
  48. if ($max_dailies) {
  49. $count = DBA::count('user', ['`register_date` > UTC_TIMESTAMP - INTERVAL 1 day']);
  50. if ($count >= $max_dailies) {
  51. Logger::log('max daily registrations exceeded.');
  52. notice(L10n::t('This site has exceeded the number of allowed daily account registrations. Please try again tomorrow.') . EOL);
  53. return '';
  54. }
  55. }
  56. if (!empty($_SESSION['theme'])) {
  57. unset($_SESSION['theme']);
  58. }
  59. if (!empty($_SESSION['mobile-theme'])) {
  60. unset($_SESSION['mobile-theme']);
  61. }
  62. $username = defaults($_REQUEST, 'username' , '');
  63. $email = defaults($_REQUEST, 'email' , '');
  64. $openid_url = defaults($_REQUEST, 'openid_url', '');
  65. $nickname = defaults($_REQUEST, 'nickname' , '');
  66. $photo = defaults($_REQUEST, 'photo' , '');
  67. $invite_id = defaults($_REQUEST, 'invite_id' , '');
  68. if (Config::get('system', 'no_openid')) {
  69. $fillwith = '';
  70. $fillext = '';
  71. $oidlabel = '';
  72. } else {
  73. $fillwith = L10n::t('You may (optionally) fill in this form via OpenID by supplying your OpenID and clicking "Register".');
  74. $fillext = L10n::t('If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items.');
  75. $oidlabel = L10n::t('Your OpenID (optional): ');
  76. }
  77. if (Config::get('system', 'publish_all')) {
  78. $profile_publish = '<input type="hidden" name="profile_publish_reg" value="1" />';
  79. } else {
  80. $publish_tpl = Renderer::getMarkupTemplate('profile_publish.tpl');
  81. $profile_publish = Renderer::replaceMacros($publish_tpl, [
  82. '$instance' => 'reg',
  83. '$pubdesc' => L10n::t('Include your profile in member directory?'),
  84. '$yes_selected' => '',
  85. '$no_selected' => ' checked="checked"',
  86. '$str_yes' => L10n::t('Yes'),
  87. '$str_no' => L10n::t('No'),
  88. ]);
  89. }
  90. $ask_password = ! DBA::count('contact');
  91. $tpl = Renderer::getMarkupTemplate('register.tpl');
  92. $arr = ['template' => $tpl];
  93. Hook::callAll('register_form', $arr);
  94. $tpl = $arr['template'];
  95. $tos = new Tos();
  96. $o = Renderer::replaceMacros($tpl, [
  97. '$invitations' => Config::get('system', 'invitation_only'),
  98. '$permonly' => intval(Config::get('config', 'register_policy')) === self::APPROVE,
  99. '$permonlybox' => ['permonlybox', L10n::t('Note for the admin'), '', L10n::t('Leave a message for the admin, why you want to join this node'), 'required'],
  100. '$invite_desc' => L10n::t('Membership on this site is by invitation only.'),
  101. '$invite_label' => L10n::t('Your invitation code: '),
  102. '$invite_id' => $invite_id,
  103. '$regtitle' => L10n::t('Registration'),
  104. '$registertext' => BBCode::convert(Config::get('config', 'register_text', '')),
  105. '$fillwith' => $fillwith,
  106. '$fillext' => $fillext,
  107. '$oidlabel' => $oidlabel,
  108. '$openid' => $openid_url,
  109. '$namelabel' => L10n::t('Your Full Name (e.g. Joe Smith, real or real-looking): '),
  110. '$addrlabel' => L10n::t('Your Email Address: (Initial information will be send there, so this has to be an existing address.)'),
  111. '$ask_password' => $ask_password,
  112. '$password1' => ['password1', L10n::t('New Password:'), '', L10n::t('Leave empty for an auto generated password.')],
  113. '$password2' => ['confirm', L10n::t('Confirm:'), '', ''],
  114. '$nickdesc' => L10n::t('Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be "<strong>nickname@%s</strong>".', self::getApp()->getHostName()),
  115. '$nicklabel' => L10n::t('Choose a nickname: '),
  116. '$photo' => $photo,
  117. '$publish' => $profile_publish,
  118. '$regbutt' => L10n::t('Register'),
  119. '$username' => $username,
  120. '$email' => $email,
  121. '$nickname' => $nickname,
  122. '$sitename' => self::getApp()->getHostName(),
  123. '$importh' => L10n::t('Import'),
  124. '$importt' => L10n::t('Import your profile to this friendica instance'),
  125. '$showtoslink' => Config::get('system', 'tosdisplay'),
  126. '$tostext' => L10n::t('Terms of Service'),
  127. '$showprivstatement' => Config::get('system', 'tosprivstatement'),
  128. '$privstatement'=> $tos->privacy_complete,
  129. '$form_security_token' => BaseModule::getFormSecurityToken('register'),
  130. '$explicit_content' => Config::get('system', 'explicit_content', false),
  131. '$explicit_content_note' => L10n::t('Note: This node explicitly contains adult content')
  132. ]);
  133. return $o;
  134. }
  135. /**
  136. * @brief Module POST method to process submitted data
  137. *
  138. * Extend this method if the module is supposed to process POST requests.
  139. * Doesn't display any content
  140. */
  141. public static function post()
  142. {
  143. BaseModule::checkFormSecurityTokenRedirectOnError('/register', 'register');
  144. $a = self::getApp();
  145. $arr = ['post' => $_POST];
  146. Hook::callAll('register_post', $arr);
  147. $max_dailies = intval(Config::get('system', 'max_daily_registrations'));
  148. if ($max_dailies) {
  149. $count = DBA::count('user', ['`register_date` > UTC_TIMESTAMP - INTERVAL 1 day']);
  150. if ($count >= $max_dailies) {
  151. return;
  152. }
  153. }
  154. switch (Config::get('config', 'register_policy')) {
  155. case self::OPEN:
  156. $blocked = 0;
  157. $verified = 1;
  158. break;
  159. case self::APPROVE:
  160. $blocked = 1;
  161. $verified = 0;
  162. break;
  163. case self::CLOSED:
  164. default:
  165. if (empty($_SESSION['authenticated']) && empty($_SESSION['administrator'])) {
  166. \notice(L10n::t('Permission denied.') . EOL);
  167. return;
  168. }
  169. $blocked = 1;
  170. $verified = 0;
  171. break;
  172. }
  173. $netpublish = !empty($_POST['profile_publish_reg']);
  174. $arr = $_POST;
  175. $arr['blocked'] = $blocked;
  176. $arr['verified'] = $verified;
  177. $arr['language'] = L10nClass::detectLanguage($a->getConfig()->get('system', 'language'));
  178. try {
  179. $result = Model\User::create($arr);
  180. } catch (\Exception $e) {
  181. \notice($e->getMessage());
  182. return;
  183. }
  184. $user = $result['user'];
  185. if ($netpublish && intval(Config::get('config', 'register_policy')) !== self::APPROVE) {
  186. $url = $a->getBaseUrl() . '/profile/' . $user['nickname'];
  187. Worker::add(PRIORITY_LOW, 'Directory', $url);
  188. }
  189. $using_invites = Config::get('system', 'invitation_only');
  190. $num_invites = Config::get('system', 'number_invites');
  191. $invite_id = (!empty($_POST['invite_id']) ? Strings::escapeTags(trim($_POST['invite_id'])) : '');
  192. if (intval(Config::get('config', 'register_policy')) === self::OPEN) {
  193. if ($using_invites && $invite_id) {
  194. Model\Register::deleteByHash($invite_id);
  195. PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites);
  196. }
  197. // Only send a password mail when the password wasn't manually provided
  198. if (empty($_POST['password1']) || empty($_POST['confirm'])) {
  199. $res = Model\User::sendRegisterOpenEmail(
  200. $user,
  201. Config::get('config', 'sitename'),
  202. $a->getBaseUrl(),
  203. $result['password']
  204. );
  205. if ($res) {
  206. \info(L10n::t('Registration successful. Please check your email for further instructions.') . EOL);
  207. $a->internalRedirect();
  208. } else {
  209. \notice(
  210. L10n::t('Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login.',
  211. $user['email'],
  212. $result['password'])
  213. . EOL
  214. );
  215. }
  216. } else {
  217. \info(L10n::t('Registration successful.') . EOL);
  218. $a->internalRedirect();
  219. }
  220. } elseif (intval(Config::get('config', 'register_policy')) === self::APPROVE) {
  221. if (!strlen(Config::get('config', 'admin_email'))) {
  222. \notice(L10n::t('Your registration can not be processed.') . EOL);
  223. $a->internalRedirect();
  224. }
  225. // Check if the note to the admin is actually filled out
  226. if (empty($_POST['permonlybox'])) {
  227. \notice(L10n::t('You have to leave a request note for the admin.')
  228. . L10n::t('Your registration can not be processed.') . EOL);
  229. $a->internalRedirect('register/');
  230. }
  231. Model\Register::createForApproval($user['uid'], Config::get('system', 'language'), $_POST['permonlybox']);
  232. // invite system
  233. if ($using_invites && $invite_id) {
  234. Model\Register::deleteByHash($invite_id);
  235. PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites);
  236. }
  237. // send email to admins
  238. $admins_stmt = DBA::select(
  239. 'user',
  240. ['uid', 'language', 'email'],
  241. ['email' => explode(',', str_replace(' ', '', Config::get('config', 'admin_email')))]
  242. );
  243. // send notification to admins
  244. while ($admin = DBA::fetch($admins_stmt)) {
  245. \notification([
  246. 'type' => NOTIFY_SYSTEM,
  247. 'event' => 'SYSTEM_REGISTER_REQUEST',
  248. 'source_name' => $user['username'],
  249. 'source_mail' => $user['email'],
  250. 'source_nick' => $user['nickname'],
  251. 'source_link' => $a->getBaseUrl() . '/admin/users/',
  252. 'link' => $a->getBaseUrl() . '/admin/users/',
  253. 'source_photo' => $a->getBaseUrl() . '/photo/avatar/' . $user['uid'] . '.jpg',
  254. 'to_email' => $admin['email'],
  255. 'uid' => $admin['uid'],
  256. 'language' => defaults($admin, 'language', 'en'),
  257. 'show_in_notification_page' => false
  258. ]);
  259. }
  260. DBA::close($admins_stmt);
  261. // send notification to the user, that the registration is pending
  262. Model\User::sendRegisterPendingEmail(
  263. $user,
  264. Config::get('config', 'sitename'),
  265. $a->getBaseURL(),
  266. $result['password']
  267. );
  268. \info(L10n::t('Your registration is pending approval by the site owner.') . EOL);
  269. $a->internalRedirect();
  270. }
  271. return;
  272. }
  273. }