3 namespace Friendica\Module\Admin;
5 use Friendica\Content\Pager;
6 use Friendica\Core\Config;
7 use Friendica\Core\Renderer;
8 use Friendica\Database\DBA;
10 use Friendica\Model\Register;
11 use Friendica\Model\User;
12 use Friendica\Module\BaseAdminModule;
13 use Friendica\Util\Strings;
14 use Friendica\Util\Temporal;
16 class Users extends BaseAdminModule
18 public static function post(array $parameters = [])
20 parent::post($parameters);
22 $pending = $_POST['pending'] ?? [];
23 $users = $_POST['user'] ?? [];
24 $nu_name = $_POST['new_user_name'] ?? '';
25 $nu_nickname = $_POST['new_user_nickname'] ?? '';
26 $nu_email = $_POST['new_user_email'] ?? '';
27 $nu_language = DI::config()->get('system', 'language');
29 parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users');
31 if ($nu_name !== '' && $nu_email !== '' && $nu_nickname !== '') {
33 $result = User::create([
34 'username' => $nu_name,
36 'nickname' => $nu_nickname,
38 'language' => $nu_language
40 } catch (\Exception $ex) {
41 notice($ex->getMessage());
45 $user = $result['user'];
46 $preamble = Strings::deindent(DI::l10n()->t('
48 the administrator of %2$s has set up an account for you.'));
49 $body = Strings::deindent(DI::l10n()->t('
50 The login details are as follows:
56 You may change your password from your account "Settings" page after logging
59 Please take a few moments to review the other account settings on that page.
61 You may also wish to add some basic information to your default profile
62 (on the "Profiles" page) so that other people can easily find you.
64 We recommend setting your full name, adding a profile photo,
65 adding some profile "keywords" (very useful in making new friends) - and
66 perhaps what country you live in; if you do not wish to be more specific
69 We fully respect your right to privacy, and none of these items are necessary.
70 If you are new and do not know anybody here, they may help
71 you to make some new and interesting friends.
73 If you ever want to delete your account, you can do so at %1$s/removeme
75 Thank you and welcome to %4$s.'));
77 $preamble = sprintf($preamble, $user['username'], DI::config()->get('config', 'sitename'));
78 $body = sprintf($body, DI::baseUrl()->get(), $user['nickname'], $result['password'], DI::config()->get('config', 'sitename'));
81 'type' => SYSTEM_EMAIL,
82 'language' => $user['language'],
83 'to_name' => $user['username'],
84 'to_email' => $user['email'],
85 'uid' => $user['uid'],
86 'subject' => DI::l10n()->t('Registration details for %s', DI::config()->get('config', 'sitename')),
87 'preamble' => $preamble,
91 if (!empty($_POST['page_users_block'])) {
92 // @TODO Move this to Model\User:block($users);
93 DBA::update('user', ['blocked' => 1], ['uid' => $users]);
94 notice(DI::l10n()->tt('%s user blocked', '%s users blocked', count($users)));
97 if (!empty($_POST['page_users_unblock'])) {
98 // @TODO Move this to Model\User:unblock($users);
99 DBA::update('user', ['blocked' => 0], ['uid' => $users]);
100 notice(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users)));
103 if (!empty($_POST['page_users_delete'])) {
104 foreach ($users as $uid) {
105 if (local_user() != $uid) {
108 notice(DI::l10n()->t('You can\'t remove yourself'));
112 notice(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users)));
115 if (!empty($_POST['page_users_approve'])) {
116 require_once 'mod/regmod.php';
117 foreach ($pending as $hash) {
122 if (!empty($_POST['page_users_deny'])) {
123 require_once 'mod/regmod.php';
124 foreach ($pending as $hash) {
129 DI::baseUrl()->redirect('admin/users');
132 public static function content(array $parameters = [])
134 parent::content($parameters);
139 // @TODO: Replace with parameter from router
140 $action = $a->argv[2];
142 $user = User::getById($uid, ['username', 'blocked']);
143 if (!DBA::isResult($user)) {
144 notice('User not found' . EOL);
145 DI::baseUrl()->redirect('admin/users');
146 return ''; // NOTREACHED
151 if (local_user() != $uid) {
152 parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
156 notice(DI::l10n()->t('User "%s" deleted', $user['username']));
158 notice(DI::l10n()->t('You can\'t remove yourself'));
162 parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
163 // @TODO Move this to Model\User:block([$uid]);
164 DBA::update('user', ['blocked' => 1], ['uid' => $uid]);
165 notice(DI::l10n()->t('User "%s" blocked', $user['username']));
168 parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't');
169 // @TODO Move this to Model\User:unblock([$uid]);
170 DBA::update('user', ['blocked' => 0], ['uid' => $uid]);
171 notice(DI::l10n()->t('User "%s" unblocked', $user['username']));
175 DI::baseUrl()->redirect('admin/users');
179 $pending = Register::getPending();
181 $pager = new Pager(DI::args()->getQueryString(), 100);
183 // @TODO Move below block to Model\User::getUsers($start, $count, $order = 'contact.name', $order_direction = '+')
187 'user.register_date',
193 $order = 'contact.name';
194 $order_direction = '+';
195 if (!empty($_GET['o'])) {
196 $new_order = $_GET['o'];
197 if ($new_order[0] === '-') {
198 $order_direction = '-';
199 $new_order = substr($new_order, 1);
202 if (in_array($new_order, $valid_orders)) {
206 $sql_order = '`' . str_replace('.', '`.`', $order) . '`';
207 $sql_order_direction = ($order_direction === '+') ? 'ASC' : 'DESC';
209 $usersStmt = DBA::p("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`, `contact`.`last-item` AS `lastitem_date`
211 INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
212 WHERE `user`.`verified`
213 ORDER BY $sql_order $sql_order_direction LIMIT ?, ?", $pager->getStart(), $pager->getItemsPerPage()
215 $users = DBA::toArray($usersStmt);
217 $adminlist = explode(',', str_replace(' ', '', DI::config()->get('config', 'admin_email')));
218 $_setup_users = function ($e) use ($adminlist) {
220 User::PAGE_FLAGS_NORMAL => DI::l10n()->t('Normal Account Page'),
221 User::PAGE_FLAGS_SOAPBOX => DI::l10n()->t('Soapbox Page'),
222 User::PAGE_FLAGS_COMMUNITY => DI::l10n()->t('Public Forum'),
223 User::PAGE_FLAGS_FREELOVE => DI::l10n()->t('Automatic Friend Page'),
224 User::PAGE_FLAGS_PRVGROUP => DI::l10n()->t('Private Forum')
227 User::ACCOUNT_TYPE_PERSON => DI::l10n()->t('Personal Page'),
228 User::ACCOUNT_TYPE_ORGANISATION => DI::l10n()->t('Organisation Page'),
229 User::ACCOUNT_TYPE_NEWS => DI::l10n()->t('News Page'),
230 User::ACCOUNT_TYPE_COMMUNITY => DI::l10n()->t('Community Forum'),
231 User::ACCOUNT_TYPE_RELAY => DI::l10n()->t('Relay'),
234 $e['page_flags_raw'] = $e['page-flags'];
235 $e['page-flags'] = $page_types[$e['page-flags']];
237 $e['account_type_raw'] = ($e['page_flags_raw'] == 0) ? $e['account-type'] : -1;
238 $e['account-type'] = ($e['page_flags_raw'] == 0) ? $account_types[$e['account-type']] : '';
240 $e['register_date'] = Temporal::getRelativeDate($e['register_date']);
241 $e['login_date'] = Temporal::getRelativeDate($e['login_date']);
242 $e['lastitem_date'] = Temporal::getRelativeDate($e['lastitem_date']);
243 $e['is_admin'] = in_array($e['email'], $adminlist);
244 $e['is_deletable'] = (intval($e['uid']) != local_user());
245 $e['deleted'] = ($e['account_removed'] ? Temporal::getRelativeDate($e['account_expires_on']) : False);
250 $tmp_users = array_map($_setup_users, $users);
252 // Get rid of dashes in key names, Smarty3 can't handle them
253 // and extracting deleted users
257 foreach ($tmp_users as $user) {
258 foreach ($user as $k => $v) {
259 $newkey = str_replace('-', '_', $k);
263 if ($user['deleted']) {
270 $th_users = array_map(null, [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last item'), DI::l10n()->t('Type')], $valid_orders);
272 $t = Renderer::getMarkupTemplate('admin/users.tpl');
273 $o = Renderer::replaceMacros($t, [
275 '$title' => DI::l10n()->t('Administration'),
276 '$page' => DI::l10n()->t('Users'),
277 '$submit' => DI::l10n()->t('Add User'),
278 '$select_all' => DI::l10n()->t('select all'),
279 '$h_pending' => DI::l10n()->t('User registrations waiting for confirm'),
280 '$h_deleted' => DI::l10n()->t('User waiting for permanent deletion'),
281 '$th_pending' => [DI::l10n()->t('Request date'), DI::l10n()->t('Name'), DI::l10n()->t('Email')],
282 '$no_pending' => DI::l10n()->t('No registrations.'),
283 '$pendingnotetext' => DI::l10n()->t('Note from the user'),
284 '$approve' => DI::l10n()->t('Approve'),
285 '$deny' => DI::l10n()->t('Deny'),
286 '$delete' => DI::l10n()->t('Delete'),
287 '$block' => DI::l10n()->t('Block'),
288 '$blocked' => DI::l10n()->t('User blocked'),
289 '$unblock' => DI::l10n()->t('Unblock'),
290 '$siteadmin' => DI::l10n()->t('Site admin'),
291 '$accountexpired' => DI::l10n()->t('Account expired'),
293 '$h_users' => DI::l10n()->t('Users'),
294 '$h_newuser' => DI::l10n()->t('New User'),
295 '$th_deleted' => [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last item'), DI::l10n()->t('Permanent deletion')],
296 '$th_users' => $th_users,
297 '$order_users' => $order,
298 '$order_direction_users' => $order_direction,
300 '$confirm_delete_multi' => DI::l10n()->t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'),
301 '$confirm_delete' => DI::l10n()->t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'),
303 '$form_security_token' => parent::getFormSecurityToken('admin_users'),
306 '$baseurl' => DI::baseUrl()->get(true),
308 '$pending' => $pending,
309 'deleted' => $deleted,
311 '$newusername' => ['new_user_name', DI::l10n()->t('Name'), '', DI::l10n()->t('Name of the new user.')],
312 '$newusernickname' => ['new_user_nickname', DI::l10n()->t('Nickname'), '', DI::l10n()->t('Nickname of the new user.')],
313 '$newuseremail' => ['new_user_email', DI::l10n()->t('Email'), '', DI::l10n()->t('Email address of the new user.'), '', '', 'email'],
316 $o .= $pager->renderFull(DBA::count('user'));