diff --git a/mod/ping.php b/mod/ping.php index 7e426d1d66..5e6c478f7d 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -292,7 +292,7 @@ function ping_init(App $a) foreach ($regs as $reg) { $notif = [ 'id' => 0, - 'href' => DI::baseUrl() . '/admin/users/', + 'href' => DI::baseUrl() . '/admin/users/pending', 'name' => $reg['name'], 'url' => $reg['url'], 'photo' => $reg['micro'], diff --git a/src/Model/User.php b/src/Model/User.php index eda724efc7..39f9dc2a15 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1511,7 +1511,9 @@ class User $condition['blocked'] = false; break; case 'blocked': + $condition['account_removed'] = false; $condition['blocked'] = true; + $condition['verified'] = true; break; case 'removed': $condition['account_removed'] = true; diff --git a/src/Module/Admin/BaseUsers.php b/src/Module/Admin/BaseUsers.php new file mode 100644 index 0000000000..97b10f41fb --- /dev/null +++ b/src/Module/Admin/BaseUsers.php @@ -0,0 +1,129 @@ +. + * + */ + +namespace Friendica\Module\Admin; + +use Friendica\Core\Renderer; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Register; +use Friendica\Model\User; +use Friendica\Module\BaseAdmin; +use Friendica\Util\Temporal; + +abstract class BaseUsers extends BaseAdmin +{ + /** + * Get the users admin tabs menu + * + * @param string $selectedTab + * @return string HTML + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + protected static function getTabsHTML(string $selectedTab) + { + $active = DBA::count('user', ['blocked' => false, 'verified' => true, 'account_removed' => false]); + $pending = Register::getPendingCount(); + $blocked = DBA::count('user', ['blocked' => true, 'verified' => true]); + $deleted = DBA::count('user', ['account_removed' => true]); + + $tabs = [ + [ + 'label' => DI::l10n()->t('All') . ' (' . DBA::count('user') . ')', + 'url' => 'admin/users', + 'sel' => !$selectedTab || $selectedTab == 'all' ? 'active' : '', + 'title' => DI::l10n()->t('List of all users'), + 'id' => 'admin-users-all', + 'accesskey' => 'a', + ], + [ + 'label' => DI::l10n()->t('Active') . ' (' . $active . ')', + 'url' => 'admin/users/active', + 'sel' => $selectedTab == 'active' ? 'active' : '', + 'title' => DI::l10n()->t('List of active accounts'), + 'id' => 'admin-users-active', + 'accesskey' => 'k', + ], + [ + 'label' => DI::l10n()->t('Pending') . ($pending ? ' (' . $pending . ')' : ''), + 'url' => 'admin/users/pending', + 'sel' => $selectedTab == 'pending' ? 'active' : '', + 'title' => DI::l10n()->t('List of pending registrations'), + 'id' => 'admin-users-pending', + 'accesskey' => 'p', + ], + [ + 'label' => DI::l10n()->t('Blocked') . ($blocked ? ' (' . $blocked . ')' : ''), + 'url' => 'admin/users/blocked', + 'sel' => $selectedTab == 'blocked' ? 'active' : '', + 'title' => DI::l10n()->t('List of blocked users'), + 'id' => 'admin-users-blocked', + 'accesskey' => 'b', + ], + [ + 'label' => DI::l10n()->t('Deleted') . ($deleted ? ' (' . $deleted . ')' : ''), + 'url' => 'admin/users/deleted', + 'sel' => $selectedTab == 'deleted' ? 'active' : '', + 'title' => DI::l10n()->t('List of pending user deletions'), + 'id' => 'admin-users-deleted', + 'accesskey' => 'd', + ], + ]; + + $tpl = Renderer::getMarkupTemplate('common_tabs.tpl'); + return Renderer::replaceMacros($tpl, ['$tabs' => $tabs]); + } + + protected static function setupUserCallback() { + $adminlist = explode(',', str_replace(' ', '', DI::config()->get('config', 'admin_email'))); + return function ($user) use ($adminlist) { + $page_types = [ + User::PAGE_FLAGS_NORMAL => DI::l10n()->t('Normal Account Page'), + User::PAGE_FLAGS_SOAPBOX => DI::l10n()->t('Soapbox Page'), + User::PAGE_FLAGS_COMMUNITY => DI::l10n()->t('Public Forum'), + User::PAGE_FLAGS_FREELOVE => DI::l10n()->t('Automatic Friend Page'), + User::PAGE_FLAGS_PRVGROUP => DI::l10n()->t('Private Forum') + ]; + $account_types = [ + User::ACCOUNT_TYPE_PERSON => DI::l10n()->t('Personal Page'), + User::ACCOUNT_TYPE_ORGANISATION => DI::l10n()->t('Organisation Page'), + User::ACCOUNT_TYPE_NEWS => DI::l10n()->t('News Page'), + User::ACCOUNT_TYPE_COMMUNITY => DI::l10n()->t('Community Forum'), + User::ACCOUNT_TYPE_RELAY => DI::l10n()->t('Relay'), + ]; + + $user['page_flags_raw'] = $user['page-flags']; + $user['page_flags'] = $page_types[$user['page-flags']]; + + $user['account_type_raw'] = ($user['page_flags_raw'] == 0) ? $user['account-type'] : -1; + $user['account_type'] = ($user['page_flags_raw'] == 0) ? $account_types[$user['account-type']] : ''; + + $user['register_date'] = Temporal::getRelativeDate($user['register_date']); + $user['login_date'] = Temporal::getRelativeDate($user['login_date']); + $user['lastitem_date'] = Temporal::getRelativeDate($user['last-item']); + $user['is_admin'] = in_array($user['email'], $adminlist); + $user['is_deletable'] = (intval($user['uid']) != local_user()); + $user['deleted'] = ($user['account_removed'] ? Temporal::getRelativeDate($user['account_expires_on']) : False); + + return $user; + }; + } +} diff --git a/src/Module/Admin/Users.php b/src/Module/Admin/Users.php deleted file mode 100644 index f38c24d979..0000000000 --- a/src/Module/Admin/Users.php +++ /dev/null @@ -1,286 +0,0 @@ -. - * - */ - -namespace Friendica\Module\Admin; - -use Friendica\Content\Pager; -use Friendica\Core\Renderer; -use Friendica\Database\DBA; -use Friendica\DI; -use Friendica\Model\Register; -use Friendica\Model\User; -use Friendica\Module\BaseAdmin; -use Friendica\Util\Temporal; - -class Users extends BaseAdmin -{ - public static function post(array $parameters = []) - { - self::checkAdminAccess(); - - self::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users'); - - $pending = $_POST['pending'] ?? []; - $users = $_POST['user'] ?? []; - $nu_name = $_POST['new_user_name'] ?? ''; - $nu_nickname = $_POST['new_user_nickname'] ?? ''; - $nu_email = $_POST['new_user_email'] ?? ''; - $nu_language = DI::config()->get('system', 'language'); - - if ($nu_name !== '' && $nu_email !== '' && $nu_nickname !== '') { - try { - User::createMinimal($nu_name, $nu_email, $nu_nickname, $nu_language); - } catch (\Exception $ex) { - notice($ex->getMessage()); - return; - } - } - - if (!empty($_POST['page_users_block'])) { - foreach ($users as $uid) { - User::block($uid); - } - info(DI::l10n()->tt('%s user blocked', '%s users blocked', count($users))); - } - - if (!empty($_POST['page_users_unblock'])) { - foreach ($users as $uid) { - User::block($uid, false); - } - info(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users))); - } - - if (!empty($_POST['page_users_delete'])) { - foreach ($users as $uid) { - if (local_user() != $uid) { - User::remove($uid); - } else { - notice(DI::l10n()->t('You can\'t remove yourself')); - } - } - - info(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users))); - } - - if (!empty($_POST['page_users_approve'])) { - foreach ($pending as $hash) { - User::allow($hash); - } - info(DI::l10n()->tt('%s user approved', '%s users approved', count($pending))); - } - - if (!empty($_POST['page_users_deny'])) { - foreach ($pending as $hash) { - User::deny($hash); - } - info(DI::l10n()->tt('%s registration revoked', '%s registrations revoked', count($pending))); - } - - DI::baseUrl()->redirect('admin/users'); - } - - public static function content(array $parameters = []) - { - parent::content($parameters); - - $action = $parameters['action'] ?? ''; - $uid = $parameters['uid'] ?? 0; - - if ($uid) { - $user = User::getById($uid, ['username', 'blocked']); - if (!DBA::isResult($user)) { - notice(DI::l10n()->t('User not found')); - DI::baseUrl()->redirect('admin/users'); - return ''; // NOTREACHED - } - } - - switch ($action) { - case 'delete': - if (local_user() != $uid) { - self::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't'); - // delete user - User::remove($uid); - - notice(DI::l10n()->t('User "%s" deleted', $user['username'])); - } else { - notice(DI::l10n()->t('You can\'t remove yourself')); - } - break; - case 'block': - self::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't'); - User::block($uid); - notice(DI::l10n()->t('User "%s" blocked', $user['username'])); - break; - case 'unblock': - self::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't'); - User::block($uid, false); - notice(DI::l10n()->t('User "%s" unblocked', $user['username'])); - break; - case 'allow': - self::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't'); - User::allow(Register::getPendingForUser($uid)['hash'] ?? ''); - notice(DI::l10n()->t('Account approved.')); - break; - case 'deny': - self::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users', 't'); - User::deny(Register::getPendingForUser($uid)['hash'] ?? ''); - notice(DI::l10n()->t('Registration revoked')); - break; - default: - /* get pending */ - $pending = Register::getPending(); - - $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100); - - $valid_orders = [ - 'name', - 'email', - 'register_date', - 'login_date', - 'last-item', - 'page-flags' - ]; - - $order = 'name'; - $order_direction = '+'; - if (!empty($_GET['o'])) { - $new_order = $_GET['o']; - if ($new_order[0] === '-') { - $order_direction = '-'; - $new_order = substr($new_order, 1); - } - - if (in_array($new_order, $valid_orders)) { - $order = $new_order; - } - } - - $users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'all', $order, ($order_direction == '-')); - - $adminlist = explode(',', str_replace(' ', '', DI::config()->get('config', 'admin_email'))); - $_setup_users = function ($e) use ($adminlist) { - $page_types = [ - User::PAGE_FLAGS_NORMAL => DI::l10n()->t('Normal Account Page'), - User::PAGE_FLAGS_SOAPBOX => DI::l10n()->t('Soapbox Page'), - User::PAGE_FLAGS_COMMUNITY => DI::l10n()->t('Public Forum'), - User::PAGE_FLAGS_FREELOVE => DI::l10n()->t('Automatic Friend Page'), - User::PAGE_FLAGS_PRVGROUP => DI::l10n()->t('Private Forum') - ]; - $account_types = [ - User::ACCOUNT_TYPE_PERSON => DI::l10n()->t('Personal Page'), - User::ACCOUNT_TYPE_ORGANISATION => DI::l10n()->t('Organisation Page'), - User::ACCOUNT_TYPE_NEWS => DI::l10n()->t('News Page'), - User::ACCOUNT_TYPE_COMMUNITY => DI::l10n()->t('Community Forum'), - User::ACCOUNT_TYPE_RELAY => DI::l10n()->t('Relay'), - ]; - - $e['page_flags_raw'] = $e['page-flags']; - $e['page-flags'] = $page_types[$e['page-flags']]; - - $e['account_type_raw'] = ($e['page_flags_raw'] == 0) ? $e['account-type'] : -1; - $e['account-type'] = ($e['page_flags_raw'] == 0) ? $account_types[$e['account-type']] : ''; - - $e['register_date'] = Temporal::getRelativeDate($e['register_date']); - $e['login_date'] = Temporal::getRelativeDate($e['login_date']); - $e['lastitem_date'] = Temporal::getRelativeDate($e['last-item']); - $e['is_admin'] = in_array($e['email'], $adminlist); - $e['is_deletable'] = (intval($e['uid']) != local_user()); - $e['deleted'] = ($e['account_removed'] ? Temporal::getRelativeDate($e['account_expires_on']) : False); - - return $e; - }; - - $tmp_users = array_map($_setup_users, $users); - - // Get rid of dashes in key names, Smarty3 can't handle them - // and extracting deleted users - - $deleted = []; - $users = []; - foreach ($tmp_users as $user) { - foreach ($user as $k => $v) { - $newkey = str_replace('-', '_', $k); - $user[$newkey] = $v; - } - - if ($user['deleted']) { - $deleted[] = $user; - } else { - $users[] = $user; - } - } - - $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 public item'), DI::l10n()->t('Type')], $valid_orders); - - $t = Renderer::getMarkupTemplate('admin/users.tpl'); - $o = Renderer::replaceMacros($t, [ - // strings // - '$title' => DI::l10n()->t('Administration'), - '$page' => DI::l10n()->t('Users'), - '$submit' => DI::l10n()->t('Add User'), - '$select_all' => DI::l10n()->t('select all'), - '$h_pending' => DI::l10n()->t('User registrations waiting for confirm'), - '$h_deleted' => DI::l10n()->t('User waiting for permanent deletion'), - '$th_pending' => [DI::l10n()->t('Request date'), DI::l10n()->t('Name'), DI::l10n()->t('Email')], - '$no_pending' => DI::l10n()->t('No registrations.'), - '$pendingnotetext' => DI::l10n()->t('Note from the user'), - '$approve' => DI::l10n()->t('Approve'), - '$deny' => DI::l10n()->t('Deny'), - '$delete' => DI::l10n()->t('Delete'), - '$block' => DI::l10n()->t('Block'), - '$blocked' => DI::l10n()->t('User blocked'), - '$unblock' => DI::l10n()->t('Unblock'), - '$siteadmin' => DI::l10n()->t('Site admin'), - '$accountexpired' => DI::l10n()->t('Account expired'), - - '$h_users' => DI::l10n()->t('Users'), - '$h_newuser' => DI::l10n()->t('New User'), - '$th_deleted' => [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last public item'), DI::l10n()->t('Permanent deletion')], - '$th_users' => $th_users, - '$order_users' => $order, - '$order_direction_users' => $order_direction, - - '$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?'), - '$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?'), - - '$form_security_token' => self::getFormSecurityToken('admin_users'), - - // values // - '$baseurl' => DI::baseUrl()->get(true), - - '$pending' => $pending, - 'deleted' => $deleted, - '$users' => $users, - '$newusername' => ['new_user_name', DI::l10n()->t('Name'), '', DI::l10n()->t('Name of the new user.')], - '$newusernickname' => ['new_user_nickname', DI::l10n()->t('Nickname'), '', DI::l10n()->t('Nickname of the new user.')], - '$newuseremail' => ['new_user_email', DI::l10n()->t('Email'), '', DI::l10n()->t('Email address of the new user.'), '', '', 'email'], - ]); - - $o .= $pager->renderFull(DBA::count('user')); - - return $o; - } - - DI::baseUrl()->redirect('admin/users'); - return ''; - } -} diff --git a/src/Module/Admin/Users/Active.php b/src/Module/Admin/Users/Active.php new file mode 100644 index 0000000000..1a12ad786c --- /dev/null +++ b/src/Module/Admin/Users/Active.php @@ -0,0 +1,164 @@ +. + * + */ + +namespace Friendica\Module\Admin\Users; + +use Friendica\Content\Pager; +use Friendica\Core\Renderer; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\User; +use Friendica\Module\Admin\BaseUsers; + +class Active extends BaseUsers +{ + public static function post(array $parameters = []) + { + self::checkAdminAccess(); + + self::checkFormSecurityTokenRedirectOnError(DI::baseUrl()->get(true), 'admin_users_active'); + + $users = $_POST['user'] ?? []; + + if (!empty($_POST['page_users_block'])) { + foreach ($users as $uid) { + User::block($uid); + } + info(DI::l10n()->tt('%s user blocked', '%s users blocked', count($users))); + } + + if (!empty($_POST['page_users_delete'])) { + foreach ($users as $uid) { + if (local_user() != $uid) { + User::remove($uid); + } else { + notice(DI::l10n()->t('You can\'t remove yourself')); + } + } + + info(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users))); + } + + DI::baseUrl()->redirect(DI::args()->getQueryString()); + } + + public static function content(array $parameters = []) + { + parent::content($parameters); + + $action = $parameters['action'] ?? ''; + $uid = $parameters['uid'] ?? 0; + + if ($uid) { + $user = User::getById($uid, ['username', 'blocked']); + if (!DBA::isResult($user)) { + notice(DI::l10n()->t('User not found')); + DI::baseUrl()->redirect('admin/users'); + return ''; // NOTREACHED + } + } + + switch ($action) { + case 'delete': + if (local_user() != $uid) { + self::checkFormSecurityTokenRedirectOnError('admin/users/active', 'admin_users_active', 't'); + // delete user + User::remove($uid); + + notice(DI::l10n()->t('User "%s" deleted', $user['username'])); + } else { + notice(DI::l10n()->t('You can\'t remove yourself')); + } + + DI::baseUrl()->redirect('admin/users'); + break; + case 'block': + self::checkFormSecurityTokenRedirectOnError('admin/users/active', 'admin_users_active', 't'); + User::block($uid); + notice(DI::l10n()->t('User "%s" blocked', $user['username'])); + DI::baseUrl()->redirect(DI::baseUrl()->get(true)); + break; + } + $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100); + + $valid_orders = [ + 'name', + 'email', + 'register_date', + 'login_date', + 'last-item', + 'page-flags' + ]; + + $order = 'name'; + $order_direction = '+'; + if (!empty($_GET['o'])) { + $new_order = $_GET['o']; + if ($new_order[0] === '-') { + $order_direction = '-'; + $new_order = substr($new_order, 1); + } + + if (in_array($new_order, $valid_orders)) { + $order = $new_order; + } + } + + $users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'active', $order, ($order_direction == '-')); + + $users = array_map(self::setupUserCallback(), $users); + + $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 public item'), DI::l10n()->t('Type')], $valid_orders); + + $count = DBA::count('user', ['blocked' => false, 'account_removed' => false]); + + $t = Renderer::getMarkupTemplate('admin/users/active.tpl'); + return self::getTabsHTML('active') . Renderer::replaceMacros($t, [ + // strings // + '$title' => DI::l10n()->t('Administration'), + '$page' => DI::l10n()->t('Active Accounts'), + '$select_all' => DI::l10n()->t('select all'), + '$delete' => DI::l10n()->t('Delete'), + '$block' => DI::l10n()->t('Block'), + '$blocked' => DI::l10n()->t('User blocked'), + '$siteadmin' => DI::l10n()->t('Site admin'), + '$accountexpired' => DI::l10n()->t('Account expired'), + '$h_newuser' => DI::l10n()->t('Create a new user'), + + '$th_users' => $th_users, + '$order_users' => $order, + '$order_direction_users' => $order_direction, + + '$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?'), + '$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?'), + + '$form_security_token' => self::getFormSecurityToken('admin_users_active'), + + // values // + '$baseurl' => DI::baseUrl()->get(true), + '$query_string' => DI::baseUrl()->get(true), + + '$users' => $users, + '$count' => $count, + '$pager' => $pager->renderFull($count), + ]); + } +} diff --git a/src/Module/Admin/Users/Blocked.php b/src/Module/Admin/Users/Blocked.php new file mode 100644 index 0000000000..872ac0fa9e --- /dev/null +++ b/src/Module/Admin/Users/Blocked.php @@ -0,0 +1,164 @@ +. + * + */ + +namespace Friendica\Module\Admin\Users; + +use Friendica\Content\Pager; +use Friendica\Core\Renderer; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\User; +use Friendica\Module\Admin\BaseUsers; +use Friendica\Util\Temporal; + +class Blocked extends BaseUsers +{ + public static function post(array $parameters = []) + { + self::checkAdminAccess(); + + self::checkFormSecurityTokenRedirectOnError('/admin/users/blocked', 'admin_users_blocked'); + + $users = $_POST['user'] ?? []; + + if (!empty($_POST['page_users_unblock'])) { + foreach ($users as $uid) { + User::block($uid, false); + } + info(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users))); + } + + if (!empty($_POST['page_users_delete'])) { + foreach ($users as $uid) { + if (local_user() != $uid) { + User::remove($uid); + } else { + notice(DI::l10n()->t('You can\'t remove yourself')); + } + } + + info(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users))); + } + + DI::baseUrl()->redirect('admin/users/blocked'); + } + + public static function content(array $parameters = []) + { + parent::content($parameters); + + $action = $parameters['action'] ?? ''; + $uid = $parameters['uid'] ?? 0; + + if ($uid) { + $user = User::getById($uid, ['username', 'blocked']); + if (!DBA::isResult($user)) { + notice(DI::l10n()->t('User not found')); + DI::baseUrl()->redirect('admin/users'); + return ''; // NOTREACHED + } + } + + switch ($action) { + case 'delete': + if (local_user() != $uid) { + self::checkFormSecurityTokenRedirectOnError('/admin/users/blocked', 'admin_users_blocked', 't'); + // delete user + User::remove($uid); + + notice(DI::l10n()->t('User "%s" deleted', $user['username'])); + } else { + notice(DI::l10n()->t('You can\'t remove yourself')); + } + DI::baseUrl()->redirect('admin/users/blocked'); + break; + case 'unblock': + self::checkFormSecurityTokenRedirectOnError('/admin/users/blocked', 'admin_users_blocked', 't'); + User::block($uid, false); + notice(DI::l10n()->t('User "%s" unblocked', $user['username'])); + DI::baseUrl()->redirect('admin/users/blocked'); + break; + } + + $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100); + + $valid_orders = [ + 'name', + 'email', + 'register_date', + 'login_date', + 'last-item', + 'page-flags' + ]; + + $order = 'name'; + $order_direction = '+'; + if (!empty($_GET['o'])) { + $new_order = $_GET['o']; + if ($new_order[0] === '-') { + $order_direction = '-'; + $new_order = substr($new_order, 1); + } + + if (in_array($new_order, $valid_orders)) { + $order = $new_order; + } + } + + $users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'blocked', $order, ($order_direction == '-')); + + $users = array_map(self::setupUserCallback(), $users); + + $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 public item'), DI::l10n()->t('Type')], $valid_orders); + + $count = DBA::count('user', ['blocked' => true, 'verified' => true]); + + $t = Renderer::getMarkupTemplate('admin/users/blocked.tpl'); + return self::getTabsHTML('blocked') . Renderer::replaceMacros($t, [ + // strings // + '$title' => DI::l10n()->t('Administration'), + '$page' => DI::l10n()->t('Blocked Users'), + '$select_all' => DI::l10n()->t('select all'), + '$delete' => DI::l10n()->t('Delete'), + '$blocked' => DI::l10n()->t('User blocked'), + '$unblock' => DI::l10n()->t('Unblock'), + '$siteadmin' => DI::l10n()->t('Site admin'), + '$accountexpired' => DI::l10n()->t('Account expired'), + + '$th_users' => $th_users, + '$order_users' => $order, + '$order_direction_users' => $order_direction, + + '$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?'), + '$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?'), + + '$form_security_token' => self::getFormSecurityToken('admin_users_blocked'), + + // values // + '$baseurl' => DI::baseUrl()->get(true), + '$query_string' => DI::args()->getQueryString(), + + '$users' => $users, + '$count' => $count, + '$pager' => $pager->renderFull($count) + ]); + } +} diff --git a/src/Module/Admin/Users/Create.php b/src/Module/Admin/Users/Create.php new file mode 100644 index 0000000000..f5c9b3a4ad --- /dev/null +++ b/src/Module/Admin/Users/Create.php @@ -0,0 +1,76 @@ +. + * + */ + +namespace Friendica\Module\Admin\Users; + +use Friendica\Core\Renderer; +use Friendica\DI; +use Friendica\Model\User; +use Friendica\Module\Admin\BaseUsers; + +class Create extends BaseUsers +{ + public static function post(array $parameters = []) + { + self::checkAdminAccess(); + + self::checkFormSecurityTokenRedirectOnError('/admin/users/create', 'admin_users_create'); + + $nu_name = $_POST['new_user_name'] ?? ''; + $nu_nickname = $_POST['new_user_nickname'] ?? ''; + $nu_email = $_POST['new_user_email'] ?? ''; + $nu_language = DI::config()->get('system', 'language'); + + if ($nu_name !== '' && $nu_email !== '' && $nu_nickname !== '') { + try { + User::createMinimal($nu_name, $nu_email, $nu_nickname, $nu_language); + DI::baseUrl()->redirect('admin/users'); + } catch (\Exception $ex) { + notice($ex->getMessage()); + } + } + + DI::baseUrl()->redirect('admin/users/create'); + } + + public static function content(array $parameters = []) + { + parent::content($parameters); + + $t = Renderer::getMarkupTemplate('admin/users/create.tpl'); + return self::getTabsHTML('all') . Renderer::replaceMacros($t, [ + // strings // + '$title' => DI::l10n()->t('Administration'), + '$page' => DI::l10n()->t('New User'), + '$submit' => DI::l10n()->t('Add User'), + + '$form_security_token' => self::getFormSecurityToken('admin_users_create'), + + // values // + '$baseurl' => DI::baseUrl()->get(true), + '$query_string' => DI::args()->getQueryString(), + + '$newusername' => ['new_user_name', DI::l10n()->t('Name'), '', DI::l10n()->t('Name of the new user.')], + '$newusernickname' => ['new_user_nickname', DI::l10n()->t('Nickname'), '', DI::l10n()->t('Nickname of the new user.')], + '$newuseremail' => ['new_user_email', DI::l10n()->t('Email'), '', DI::l10n()->t('Email address of the new user.'), '', '', 'email'], + ]); + } +} diff --git a/src/Module/Admin/Users/Deleted.php b/src/Module/Admin/Users/Deleted.php new file mode 100644 index 0000000000..1615848ce7 --- /dev/null +++ b/src/Module/Admin/Users/Deleted.php @@ -0,0 +1,101 @@ +. + * + */ + +namespace Friendica\Module\Admin\Users; + +use Friendica\Content\Pager; +use Friendica\Core\Renderer; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Register; +use Friendica\Model\User; +use Friendica\Module\Admin\BaseUsers; +use Friendica\Module\BaseAdmin; +use Friendica\Util\Temporal; + +class Deleted extends BaseUsers +{ + public static function post(array $parameters = []) + { + self::checkAdminAccess(); + + self::checkFormSecurityTokenRedirectOnError('/admin/users/deleted', 'admin_users_deleted'); + + // @TODO: Implement user deletion cancellation + + DI::baseUrl()->redirect('admin/users/deleted'); + } + + public static function content(array $parameters = []) + { + parent::content($parameters); + + $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100); + + $valid_orders = [ + 'name', + 'email', + 'register_date', + 'login_date', + 'last-item', + 'page-flags' + ]; + + $order = 'name'; + $order_direction = '+'; + if (!empty($_GET['o'])) { + $new_order = $_GET['o']; + if ($new_order[0] === '-') { + $order_direction = '-'; + $new_order = substr($new_order, 1); + } + + if (in_array($new_order, $valid_orders)) { + $order = $new_order; + } + } + + $users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'removed', $order, ($order_direction == '-')); + + $users = array_map(self::setupUserCallback(), $users); + + $count = DBA::count('user', ['account_removed' => true]); + + $t = Renderer::getMarkupTemplate('admin/users/deleted.tpl'); + return self::getTabsHTML('deleted') . Renderer::replaceMacros($t, [ + // strings // + '$title' => DI::l10n()->t('Administration'), + '$page' => DI::l10n()->t('Users awaiting permanent deletion'), + + '$th_deleted' => [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last public item'), DI::l10n()->t('Permanent deletion')], + + '$form_security_token' => self::getFormSecurityToken('admin_users_deleted'), + + // values // + '$baseurl' => DI::baseUrl()->get(true), + '$query_string' => DI::args()->getQueryString(), + + '$users' => $users, + '$count' => $count, + '$pager' => $pager->renderFull($count), + ]); + } +} diff --git a/src/Module/Admin/Users/Index.php b/src/Module/Admin/Users/Index.php new file mode 100644 index 0000000000..cc453a0731 --- /dev/null +++ b/src/Module/Admin/Users/Index.php @@ -0,0 +1,181 @@ +. + * + */ + +namespace Friendica\Module\Admin\Users; + +use Friendica\Content\Pager; +use Friendica\Core\Renderer; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\User; +use Friendica\Module\Admin\BaseUsers; + +class Index extends BaseUsers +{ + public static function post(array $parameters = []) + { + self::checkAdminAccess(); + + self::checkFormSecurityTokenRedirectOnError('admin/users', 'admin_users'); + + $users = $_POST['user'] ?? []; + + if (!empty($_POST['page_users_block'])) { + foreach ($users as $uid) { + User::block($uid); + } + info(DI::l10n()->tt('%s user blocked', '%s users blocked', count($users))); + } + + if (!empty($_POST['page_users_unblock'])) { + foreach ($users as $uid) { + User::block($uid, false); + } + info(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users))); + } + + if (!empty($_POST['page_users_delete'])) { + foreach ($users as $uid) { + if (local_user() != $uid) { + User::remove($uid); + } else { + notice(DI::l10n()->t('You can\'t remove yourself')); + } + } + + info(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users))); + } + + DI::baseUrl()->redirect(DI::args()->getQueryString()); + } + + public static function content(array $parameters = []) + { + parent::content($parameters); + + $action = $parameters['action'] ?? ''; + $uid = $parameters['uid'] ?? 0; + + if ($uid) { + $user = User::getById($uid, ['username', 'blocked']); + if (!DBA::isResult($user)) { + notice(DI::l10n()->t('User not found')); + DI::baseUrl()->redirect('admin/users'); + return ''; // NOTREACHED + } + } + + switch ($action) { + case 'delete': + if (local_user() != $uid) { + self::checkFormSecurityTokenRedirectOnError(DI::baseUrl()->get(true), 'admin_users', 't'); + // delete user + User::remove($uid); + + notice(DI::l10n()->t('User "%s" deleted', $user['username'])); + } else { + notice(DI::l10n()->t('You can\'t remove yourself')); + } + + DI::baseUrl()->redirect('admin/users'); + break; + case 'block': + self::checkFormSecurityTokenRedirectOnError('admin/users', 'admin_users', 't'); + User::block($uid); + notice(DI::l10n()->t('User "%s" blocked', $user['username'])); + DI::baseUrl()->redirect(DI::baseUrl()->get(true)); + break; + case 'unblock': + self::checkFormSecurityTokenRedirectOnError('admin/users', 'admin_users', 't'); + User::block($uid, false); + notice(DI::l10n()->t('User "%s" unblocked', $user['username'])); + DI::baseUrl()->redirect('admin/users'); + break; + } + $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100); + + $valid_orders = [ + 'name', + 'email', + 'register_date', + 'login_date', + 'last-item', + 'page-flags' + ]; + + $order = 'name'; + $order_direction = '+'; + if (!empty($_GET['o'])) { + $new_order = $_GET['o']; + if ($new_order[0] === '-') { + $order_direction = '-'; + $new_order = substr($new_order, 1); + } + + if (in_array($new_order, $valid_orders)) { + $order = $new_order; + } + } + + $users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'all', $order, ($order_direction == '-')); + + $users = array_map(self::setupUserCallback(), $users); + + $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 public item'), DI::l10n()->t('Type')], $valid_orders); + + $count = DBA::count('user'); + + $t = Renderer::getMarkupTemplate('admin/users/index.tpl'); + return self::getTabsHTML('all') . Renderer::replaceMacros($t, [ + // strings // + '$title' => DI::l10n()->t('Administration'), + '$page' => DI::l10n()->t('Users'), + '$select_all' => DI::l10n()->t('select all'), + '$h_deleted' => DI::l10n()->t('User waiting for permanent deletion'), + '$delete' => DI::l10n()->t('Delete'), + '$block' => DI::l10n()->t('Block'), + '$blocked' => DI::l10n()->t('User blocked'), + '$unblock' => DI::l10n()->t('Unblock'), + '$siteadmin' => DI::l10n()->t('Site admin'), + '$accountexpired' => DI::l10n()->t('Account expired'), + + '$h_users' => DI::l10n()->t('Users'), + '$h_newuser' => DI::l10n()->t('Create a new user'), + '$th_deleted' => [DI::l10n()->t('Name'), DI::l10n()->t('Email'), DI::l10n()->t('Register date'), DI::l10n()->t('Last login'), DI::l10n()->t('Last public item'), DI::l10n()->t('Permanent deletion')], + '$th_users' => $th_users, + '$order_users' => $order, + '$order_direction_users' => $order_direction, + + '$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?'), + '$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?'), + + '$form_security_token' => self::getFormSecurityToken('admin_users'), + + // values // + '$baseurl' => DI::baseUrl()->get(true), + '$query_string' => DI::baseUrl()->get(true), + + '$users' => $users, + '$count' => $count, + '$pager' => $pager->renderFull($count), + ]); + } +} diff --git a/src/Module/Admin/Users/Pending.php b/src/Module/Admin/Users/Pending.php new file mode 100644 index 0000000000..1a1efe3ef6 --- /dev/null +++ b/src/Module/Admin/Users/Pending.php @@ -0,0 +1,121 @@ +. + * + */ + +namespace Friendica\Module\Admin\Users; + +use Friendica\Content\Pager; +use Friendica\Core\Renderer; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Register; +use Friendica\Model\User; +use Friendica\Module\Admin\BaseUsers; +use Friendica\Module\BaseAdmin; +use Friendica\Util\Temporal; + +class Pending extends BaseUsers +{ + public static function post(array $parameters = []) + { + self::checkAdminAccess(); + + self::checkFormSecurityTokenRedirectOnError('/admin/users/pending', 'admin_users_pending'); + + $pending = $_POST['pending'] ?? []; + + if (!empty($_POST['page_users_approve'])) { + foreach ($pending as $hash) { + User::allow($hash); + } + info(DI::l10n()->tt('%s user approved', '%s users approved', count($pending))); + } + + if (!empty($_POST['page_users_deny'])) { + foreach ($pending as $hash) { + User::deny($hash); + } + info(DI::l10n()->tt('%s registration revoked', '%s registrations revoked', count($pending))); + } + + DI::baseUrl()->redirect('admin/users/pending'); + } + + public static function content(array $parameters = []) + { + parent::content($parameters); + + $action = $parameters['action'] ?? ''; + $uid = $parameters['uid'] ?? 0; + + if ($uid) { + $user = User::getById($uid, ['username', 'blocked']); + if (!DBA::isResult($user)) { + notice(DI::l10n()->t('User not found')); + DI::baseUrl()->redirect('admin/users'); + return ''; // NOTREACHED + } + } + + switch ($action) { + case 'allow': + self::checkFormSecurityTokenRedirectOnError('/admin/users/pending', 'admin_users_pending', 't'); + User::allow(Register::getPendingForUser($uid)['hash'] ?? ''); + notice(DI::l10n()->t('Account approved.')); + DI::baseUrl()->redirect('admin/users/pending'); + break; + case 'deny': + self::checkFormSecurityTokenRedirectOnError('/admin/users/pending', 'admin_users_pending', 't'); + User::deny(Register::getPendingForUser($uid)['hash'] ?? ''); + notice(DI::l10n()->t('Registration revoked')); + DI::baseUrl()->redirect('admin/users/pending'); + break; + } + + $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100); + + $pending = Register::getPending($pager->getStart(), $pager->getItemsPerPage()); + + $count = Register::getPendingCount(); + + $t = Renderer::getMarkupTemplate('admin/users/pending.tpl'); + return self::getTabsHTML('pending') . Renderer::replaceMacros($t, [ + // strings // + '$title' => DI::l10n()->t('Administration'), + '$page' => DI::l10n()->t('User registrations awaiting review'), + '$select_all' => DI::l10n()->t('select all'), + '$th_pending' => [DI::l10n()->t('Request date'), DI::l10n()->t('Name'), DI::l10n()->t('Email')], + '$no_pending' => DI::l10n()->t('No registrations.'), + '$pendingnotetext' => DI::l10n()->t('Note from the user'), + '$approve' => DI::l10n()->t('Approve'), + '$deny' => DI::l10n()->t('Deny'), + + '$form_security_token' => self::getFormSecurityToken('admin_users_pending'), + + // values // + '$baseurl' => DI::baseUrl()->get(true), + '$query_string' => DI::args()->getQueryString(), + + '$pending' => $pending, + '$count' => $count, + '$pager' => $pager->renderFull($count), + ]); + } +} diff --git a/src/Module/Delegation.php b/src/Module/Delegation.php index b6451c85af..f68b9db8d5 100644 --- a/src/Module/Delegation.php +++ b/src/Module/Delegation.php @@ -144,7 +144,8 @@ class Delegation extends BaseModule } $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('delegation.tpl'), [ - '$title' => DI::l10n()->t('Manage Identities and/or Pages'), + '$title' => DI::l10n()->t('Switch between your accounts'), + '$settings_label' => DI::l10n()->t('Manage your accounts'), '$desc' => DI::l10n()->t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'), '$choose' => DI::l10n()->t('Select an identity to manage: '), '$identities' => $identities, diff --git a/src/Module/Register.php b/src/Module/Register.php index dd603ad206..2a74894b18 100644 --- a/src/Module/Register.php +++ b/src/Module/Register.php @@ -184,8 +184,6 @@ class Register extends BaseModule { BaseModule::checkFormSecurityTokenRedirectOnError('/register', 'register'); - $a = DI::app(); - $arr = ['post' => $_POST]; Hook::callAll('register_post', $arr); diff --git a/static/routes.config.php b/static/routes.config.php index 8466aec672..f0627b6126 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -110,7 +110,12 @@ return [ '/tos' => [Module\Admin\Tos::class, [R::GET, R::POST]], - '/users[/{action}/{uid}]' => [Module\Admin\Users::class, [R::GET, R::POST]], + '/users[/{action}/{uid}]' => [Module\Admin\Users\Index::class, [R::GET, R::POST]], + '/users/active[/{action}/{uid}]' => [Module\Admin\Users\Active::class, [R::GET, R::POST]], + '/users/pending[/{action}/{uid}]' => [Module\Admin\Users\Pending::class, [R::GET, R::POST]], + '/users/blocked[/{action}/{uid}]' => [Module\Admin\Users\Blocked::class, [R::GET, R::POST]], + '/users/deleted' => [Module\Admin\Users\Deleted::class, [R::GET ]], + '/users/create' => [Module\Admin\Users\Create::class, [R::GET, R::POST]], ], '/amcd' => [Module\AccountManagementControlDocument::class, [R::GET]], '/acctlink' => [Module\Acctlink::class, [R::GET]], diff --git a/view/templates/admin/users.tpl b/view/templates/admin/users.tpl deleted file mode 100644 index d2850519ab..0000000000 --- a/view/templates/admin/users.tpl +++ /dev/null @@ -1,179 +0,0 @@ - -
-

{{$title}} - {{$page}}

- -
- - -

{{$h_pending}}

- {{if $pending}} - - - - {{foreach $th_pending as $th}} - {{/foreach}} - - - - - - {{foreach $pending as $u}} - - - - - - - - - - - {{/foreach}} - -
{{$th}}
{{$u.created}}{{$u.name}} - - - - - - - - -

{{$pendingnotetext}}: {{$u.note}}

- -
- - -
- {{else}} -

{{$no_pending}}

- {{/if}} - -

{{$h_users}}

- {{if $users}} - - - - - {{foreach $th_users as $th}} - - {{/foreach}} - - - - - - {{foreach $users as $u}} - - - - - - - - - - - - - {{/foreach}} - -
- - {{if $order_users == $th.1}} - {{if $order_direction_users == "+"}} - ↓ - {{else}} - ↑ - {{/if}} - {{else}} - ↕ - {{/if}} - {{$th.0}} - -
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} - {{if $u.is_deletable}} - - {{else}} -   - {{/if}} - - {{if $u.is_deletable}} - - - - - - - {{else}} -   - {{/if}} -
- -
- - - -
- {{else}} - NO USERS?!? - {{/if}} -
-{{if $deleted}} -

{{$h_deleted}}

- - - - - {{foreach $th_deleted as $th}} - - {{/foreach}} - - - - {{foreach $deleted as $u}} - - - - - - - - - - {{/foreach}} - -
{{$th}}
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}}
-{{/if}} -

{{$h_newuser}}

-
- - - - - - - - - - - - - -
{{include file="field_input.tpl" field=$newusername}}
{{include file="field_input.tpl" field=$newusernickname}}
{{include file="field_input.tpl" field=$newuseremail}}
-
-
-
diff --git a/view/templates/admin/users/active.tpl b/view/templates/admin/users/active.tpl new file mode 100644 index 0000000000..8ec13e1fea --- /dev/null +++ b/view/templates/admin/users/active.tpl @@ -0,0 +1,88 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + {{foreach $th_users as $th}} + + {{/foreach}} + + + + + + {{foreach $users as $u}} + + + + + + + + + + + + + {{/foreach}} + +
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} + {{if $u.is_deletable}} + + {{else}} +   + {{/if}} + + {{if $u.is_deletable}} + + + + + + + {{else}} +   + {{/if}} +
+ +
+ + +
+
+ {{$pager nofilter}} +

+ {{$h_newuser}} +

+
diff --git a/view/templates/admin/users/blocked.tpl b/view/templates/admin/users/blocked.tpl new file mode 100644 index 0000000000..6defaf62f0 --- /dev/null +++ b/view/templates/admin/users/blocked.tpl @@ -0,0 +1,86 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + + {{foreach $th_users as $th}} + + {{/foreach}} + + + + + + {{foreach $users as $u}} + + + + + + + + + + + + + {{/foreach}} + +
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} + {{if $u.is_deletable}} + + {{else}} +   + {{/if}} + + {{if $u.is_deletable}} + + + + + + + {{else}} +   + {{/if}} +
+ +
+ + +
+ {{$pager nofilter}} +
+
diff --git a/view/templates/admin/users/create.tpl b/view/templates/admin/users/create.tpl new file mode 100644 index 0000000000..8581f1bb8f --- /dev/null +++ b/view/templates/admin/users/create.tpl @@ -0,0 +1,21 @@ +
+

{{$title}} - {{$page}}

+ +
+ + + + + + + + + + + + + +
{{include file="field_input.tpl" field=$newusername}}
{{include file="field_input.tpl" field=$newusernickname}}
{{include file="field_input.tpl" field=$newuseremail}}
+
+
+
diff --git a/view/templates/admin/users/deleted.tpl b/view/templates/admin/users/deleted.tpl new file mode 100644 index 0000000000..ae43400356 --- /dev/null +++ b/view/templates/admin/users/deleted.tpl @@ -0,0 +1,46 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + + {{foreach $th_deleted as $th}} + + {{/foreach}} + + + + {{foreach $users as $u}} + + + + + + + + + + {{/foreach}} + +
{{$th}}
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}}
+ {{$pager nofilter}} +
+
diff --git a/view/templates/admin/users/index.tpl b/view/templates/admin/users/index.tpl new file mode 100644 index 0000000000..091940ccc1 --- /dev/null +++ b/view/templates/admin/users/index.tpl @@ -0,0 +1,89 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + {{foreach $th_users as $th}} + + {{/foreach}} + + + + + + {{foreach $users as $u}} + + + + + + + + + + + + + {{/foreach}} + +
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} + {{if $u.is_deletable}} + + {{else}} +   + {{/if}} + + {{if $u.is_deletable}} + + + + + + + {{else}} +   + {{/if}} +
+ +
+ + + +
+
+ {{$pager nofilter}} +

+ {{$h_newuser}} +

+
diff --git a/view/templates/admin/users/pending.tpl b/view/templates/admin/users/pending.tpl new file mode 100644 index 0000000000..43d1e5248b --- /dev/null +++ b/view/templates/admin/users/pending.tpl @@ -0,0 +1,64 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + {{if $pending}} + + + + {{foreach $th_pending as $th}} + {{/foreach}} + + + + + + {{foreach $pending as $u}} + + + + + + + + + + + {{/foreach}} + +
{{$th}}
{{$u.created}}{{$u.name}} + + + + + + + + +

{{$pendingnotetext}}: {{$u.note}}

+ +
+ + +
+ {{else}} +

{{$no_pending}}

+ {{/if}} +
+
diff --git a/view/templates/delegation.tpl b/view/templates/delegation.tpl index 0e8e406d0c..e95bea3bb7 100644 --- a/view/templates/delegation.tpl +++ b/view/templates/delegation.tpl @@ -1,7 +1,6 @@ - -

{{$title}}

-
{{$desc nofilter}}
-
{{$choose}}
+

{{$title}}

+

{{$desc nofilter}}

+

{{$choose}}

+ +

+ {{$settings_label}} +

diff --git a/view/theme/frio/css/mod_admin.css b/view/theme/frio/css/mod_admin.css index 84a42ad6dc..35c2b4a009 100644 --- a/view/theme/frio/css/mod_admin.css +++ b/view/theme/frio/css/mod_admin.css @@ -1,16 +1,16 @@ - -#admin-users.adminpage > h1 { padding: 0 15px; } - #adminpage.adminpage > h1 { padding: 0 15px; } -#admin-users #users th:first-of-type { width: 1em; } -#admin-users #users th:nth-of-type(2) { width: 40px; } -#admin-users #users th:last-of-type { width: 1em; } -#admin-users .admin-settings-footer-elements { padding-left: 8px; padding-right: 8px; } +#users th:first-of-type { width: 1em; } +#users th:nth-of-type(2) { width: 40px; } +#users th:last-of-type { width: 1em; } +.admin-settings-footer-elements { padding-left: 8px; padding-right: 8px; } -#admin-users #deleted th:first-of-type { width: 40px; } +#deleted th:first-of-type { width: 40px; } -#admin-users #users img.avatar-nano, #deleted img.avatar-nano { height: 24px; width: 24px; } +#users img.avatar-nano, +#deleted img.avatar-nano { + height: 24px; width: 24px; +} .opened .caret { transform: rotate(180deg); } tr.details td, tr.details th { diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index 88397fb6cb..41ba31dc56 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -2936,17 +2936,7 @@ section.help-content-wrapper li { #adminpage .addon .desc { padding-left: 10px; } -.adminpage .admin-settings-action-link, -.adminpage .admin-settings-action-link:hover { - color: $font_color_darker; -} -.adminpage .admin-settings-action-link:hover { - opacity: 1; -} -.adminpage .admin-settings-action-link { - opacity: 0.8; -} -#admin-users tr.blocked { +#admin-users #users tr.blocked { background-color: #f8efc0; } .adminpage .table-hover > tbody > tr:hover + tr.details { diff --git a/view/theme/frio/js/mod_admin.js b/view/theme/frio/js/mod_admin.js index 5108800f19..d73b719d02 100644 --- a/view/theme/frio/js/mod_admin.js +++ b/view/theme/frio/js/mod_admin.js @@ -24,27 +24,6 @@ $(function() { } }); - // Use AJAX calls to reorder the table (so we don't need to reload the page). - $body.on('click', '.table-order', function(e) { - e.preventDefault(); - - // Get the parent table element. - var table = $(this).parents('table'); - var orderUrl = this.getAttribute("data-order-url"); - table.fadeTo("fast", 0.33); - - $body.css("cursor", "wait"); - - $.get(orderUrl, function(data) { - // Find the table element in the html we got. - var result = $(data).find('#' + table[0].id); - // And add the new table html to the parent. - $(table).replaceWith(result); - - $body.css("cursor", "auto"); - }); - }); - function selectall(cls) { $('.' + cls).prop('checked', true); return false; diff --git a/view/theme/frio/templates/admin/users.tpl b/view/theme/frio/templates/admin/users.tpl deleted file mode 100644 index 71d3638623..0000000000 --- a/view/theme/frio/templates/admin/users.tpl +++ /dev/null @@ -1,337 +0,0 @@ - - - -
-

{{$title}} - {{$page}}

- -
- - - {{* We organize the settings in collapsable panel-groups *}} -
- - -
- - -
- {{if $pending}} - - - - - {{foreach $th_pending as $th}}{{/foreach}} - - - - - {{foreach $pending as $u}} - - - - - - - - {{if $u.note}} - - - - - - {{/if}} - {{/foreach}} - -
-
- - -
-
{{$th}}
-
- - -
-
{{$u.created}}{{$u.name}}{{$u.email}} - - -
{{$pendingnotetext}}{{$u.note}}
- - {{else}} -
{{$no_pending}}
- {{/if}} -
-
- - -
- - -
- - {{if $users}} - - - - - - {{foreach $th_users as $k=>$th}} - {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} - - {{/if}} - {{/foreach}} - - - - - {{foreach $users as $u}} - - - - - - {{if $order_users == $th_users.2.1}} - - {{/if}} - - {{if $order_users == $th_users.3.1}} - - {{/if}} - - {{if $order_users == $th_users.4.1}} - - {{/if}} - - {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} - - {{/if}} - - - - - - - - - {{/foreach}} - -
-
- - -
-
- -
- {{if $u.is_deletable}} -
- - -
- {{else}} -   - {{/if}} -
{{$u.name}}{{$u.email}}{{$u.register_date}}{{$u.login_date}}{{$u.lastitem_date}} - - - {{if $u.page_flags_raw==0 && $u.account_type_raw > 0}} - - {{/if}} - {{if $u.is_admin}}{{/if}} - {{if $u.account_expired}}{{/if}} - - -
- - {{else}} -
NO USERS?!?
- {{/if}} -
-
- - - {{if $deleted}} -
- - -
- - - - - {{foreach $th_deleted as $k=>$th}} - {{if in_array($k,[0,1,5])}} - - {{/if}} - {{/foreach}} - - - - {{foreach $deleted as $u}} - - - - - - - {{/foreach}} - -
{{$th}}
{{$u.name}}{{$u.email}}{{$u.deleted}}
-
-
- {{/if}} - - - - -
- - -
-
- {{include file="field_input.tpl" field=$newusername}} - {{include file="field_input.tpl" field=$newusernickname}} - {{include file="field_input.tpl" field=$newuseremail}} -
- -
-
-
-
-
diff --git a/view/theme/frio/templates/admin/users/active.tpl b/view/theme/frio/templates/admin/users/active.tpl new file mode 100644 index 0000000000..c2909088ac --- /dev/null +++ b/view/theme/frio/templates/admin/users/active.tpl @@ -0,0 +1,162 @@ + + + +
+

{{$title}} - {{$page}} ({{$count}})

+

+ {{$h_newuser}} +

+
+ + + + + + + {{foreach $th_users as $k=>$th}} + {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} + + {{/if}} + {{/foreach}} + + + + + {{foreach $users as $u}} + + + + + + {{if $order_users == $th_users.2.1}} + + {{/if}} + + {{if $order_users == $th_users.3.1}} + + {{/if}} + + {{if $order_users == $th_users.4.1}} + + {{/if}} + + {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} + + {{/if}} + + + + + + + + + {{/foreach}} + +
+
+ + +
+
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
+ {{if $u.is_deletable}} +
+ + +
+ {{else}} +   + {{/if}} +
{{$u.name}}{{$u.email}}{{$u.register_date}}{{$u.login_date}}{{$u.lastitem_date}} + + + {{if $u.page_flags_raw==0 && $u.account_type_raw > 0}} + + {{/if}} + {{if $u.is_admin}}{{/if}} + {{if $u.account_expired}}{{/if}} + + +
+ + {{$pager nofilter}} +
+
diff --git a/view/theme/frio/templates/admin/users/blocked.tpl b/view/theme/frio/templates/admin/users/blocked.tpl new file mode 100644 index 0000000000..3b80556518 --- /dev/null +++ b/view/theme/frio/templates/admin/users/blocked.tpl @@ -0,0 +1,157 @@ + + + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + + + {{foreach $th_users as $k=>$th}} + {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} + + {{/if}} + {{/foreach}} + + + + + {{foreach $users as $u}} + + + + + + {{if $order_users == $th_users.2.1}} + + {{/if}} + + {{if $order_users == $th_users.3.1}} + + {{/if}} + + {{if $order_users == $th_users.4.1}} + + {{/if}} + + {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} + + {{/if}} + + + + + + + + + {{/foreach}} + +
+
+ + +
+
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
+ {{if $u.is_deletable}} +
+ + +
+ {{else}} +   + {{/if}} +
{{$u.name}}{{$u.email}}{{$u.register_date}}{{$u.login_date}}{{$u.lastitem_date}} + + + {{if $u.page_flags_raw==0 && $u.account_type_raw > 0}} + + {{/if}} + {{if $u.is_admin}}{{/if}} + {{if $u.account_expired}}{{/if}} + + +
+ + {{$pager nofilter}} +
+
diff --git a/view/theme/frio/templates/admin/users/create.tpl b/view/theme/frio/templates/admin/users/create.tpl new file mode 100644 index 0000000000..4b036e08f4 --- /dev/null +++ b/view/theme/frio/templates/admin/users/create.tpl @@ -0,0 +1,14 @@ +
+

{{$title}} - {{$page}}

+ +
+ + + {{include file="field_input.tpl" field=$newusername}} + {{include file="field_input.tpl" field=$newusernickname}} + {{include file="field_input.tpl" field=$newuseremail}} +

+ +

+
+
diff --git a/view/theme/frio/templates/admin/users/deleted.tpl b/view/theme/frio/templates/admin/users/deleted.tpl new file mode 100644 index 0000000000..9ec127267a --- /dev/null +++ b/view/theme/frio/templates/admin/users/deleted.tpl @@ -0,0 +1,34 @@ + + + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + + {{foreach $th_deleted as $k=>$th}} + {{if in_array($k,[0,1,5])}} + + {{/if}} + {{/foreach}} + + + + {{foreach $users as $u}} + + + + + + + {{/foreach}} + +
{{$th}}
{{$u.name}}{{$u.email}}{{$u.deleted}}
+ {{$pager nofilter}} +
+
diff --git a/view/theme/frio/templates/admin/users/index.tpl b/view/theme/frio/templates/admin/users/index.tpl new file mode 100644 index 0000000000..41226eb44c --- /dev/null +++ b/view/theme/frio/templates/admin/users/index.tpl @@ -0,0 +1,165 @@ + + + +
+

{{$title}} - {{$page}} ({{$count}})

+

+ {{$h_newuser}} +

+
+ + + + + + + {{foreach $th_users as $k=>$th}} + {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} + + {{/if}} + {{/foreach}} + + + + + {{foreach $users as $u}} + + + + + + {{if $order_users == $th_users.2.1}} + + {{/if}} + + {{if $order_users == $th_users.3.1}} + + {{/if}} + + {{if $order_users == $th_users.4.1}} + + {{/if}} + + {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} + + {{/if}} + + + + + + + + + {{/foreach}} + +
+
+ + +
+
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
+ {{if $u.is_deletable}} +
+ + +
+ {{else}} +   + {{/if}} +
{{$u.name}}{{$u.email}}{{$u.register_date}}{{$u.login_date}}{{$u.lastitem_date}} + + + {{if $u.page_flags_raw==0 && $u.account_type_raw > 0}} + + {{/if}} + {{if $u.is_admin}}{{/if}} + {{if $u.account_expired}}{{/if}} + + +
+ + {{$pager nofilter}} +
+
diff --git a/view/theme/frio/templates/admin/users/pending.tpl b/view/theme/frio/templates/admin/users/pending.tpl new file mode 100644 index 0000000000..dfb8d7e101 --- /dev/null +++ b/view/theme/frio/templates/admin/users/pending.tpl @@ -0,0 +1,58 @@ + + + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + + {{foreach $th_pending as $th}}{{/foreach}} + + + + + {{foreach $pending as $u}} + + + + + + + + {{if $u.note}} + + + + + + {{/if}} + {{/foreach}} + +
+
+ + +
+
{{$th}}
+
+ + +
+
{{$u.created}}{{$u.name}}{{$u.email}} + + +
{{$pendingnotetext}}{{$u.note}}
+ + + {{$pager nofilter}} +
+
diff --git a/view/theme/quattro/templates/admin/users.tpl b/view/theme/quattro/templates/admin/users.tpl deleted file mode 100644 index 9057a53d2d..0000000000 --- a/view/theme/quattro/templates/admin/users.tpl +++ /dev/null @@ -1,178 +0,0 @@ - -
-

{{$title}} - {{$page}}

- -
- - -

{{$h_pending}}

- {{if $pending}} - - - - {{foreach $th_pending as $th}} - - {{/foreach}} - - - - - - {{foreach $pending as $u}} - - - - - - - - - - - {{/foreach}} - -
{{$th}}
{{$u.created}}{{$u.name}} - - - - - - - - -

{{$pendingnotetext}}: {{$u.note}}

- -
- -
- {{else}} -

{{$no_pending}}

- {{/if}} - -

{{$h_users}}

- {{if $users}} - - - - - {{foreach $th_users as $th}} - - {{/foreach}} - - - - - - {{foreach $users as $u}} - - - - - - - - - - - - {{/foreach}} - -
- - {{if $order_users == $th.1}} - {{if $order_direction_users == "+"}} - ↓ - {{else}} - ↑ - {{/if}} - {{else}} - ↕ - {{/if}} - {{$th.0}} - -
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} - {{if $u.is_deletable}} - - {{else}} -   - {{/if}} - - {{if $u.is_deletable}} - - - - - - - {{else}} -   - {{/if}} -
- -
- - - -
- {{else}} - NO USERS?!? - {{/if}} -
- {{if $deleted}} -

{{$h_deleted}}

- - - - - {{foreach $th_deleted as $th}} - - {{/foreach}} - - - - {{foreach $deleted as $u}} - - - - - - - - - - {{/foreach}} - -
{{$th}}
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}}
- {{/if}} -

{{$h_newuser}}

-
- - - - - - - - - - - - - -
{{include file="field_input.tpl" field=$newusername}}
{{include file="field_input.tpl" field=$newusernickname}}
{{include file="field_input.tpl" field=$newuseremail}}
-
-
-
diff --git a/view/theme/quattro/templates/admin/users/active.tpl b/view/theme/quattro/templates/admin/users/active.tpl new file mode 100644 index 0000000000..7aef3f3d1c --- /dev/null +++ b/view/theme/quattro/templates/admin/users/active.tpl @@ -0,0 +1,83 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + {{foreach $th_users as $th}} + + {{/foreach}} + + + + + + {{foreach $users as $u}} + + + + + + + + + + + + {{/foreach}} + +
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} + {{if $u.is_deletable}} + + {{else}} +   + {{/if}} + + {{if $u.is_deletable}} + + + + + + + {{else}} +   + {{/if}} +
+ +
+ + +
+ {{$pager nofilter}} +
+
diff --git a/view/theme/quattro/templates/admin/users/blocked.tpl b/view/theme/quattro/templates/admin/users/blocked.tpl new file mode 100644 index 0000000000..09d84b33bc --- /dev/null +++ b/view/theme/quattro/templates/admin/users/blocked.tpl @@ -0,0 +1,85 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + + {{foreach $th_users as $th}} + + {{/foreach}} + + + + + + {{foreach $users as $u}} + + + + + + + + + + + + {{/foreach}} + +
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} + {{if $u.is_deletable}} + + {{else}} +   + {{/if}} + + {{if $u.is_deletable}} + + + + + + + {{else}} +   + {{/if}} +
+ +
+ + +
+ {{$pager nofilter}} +
+
diff --git a/view/theme/quattro/templates/admin/users/create.tpl b/view/theme/quattro/templates/admin/users/create.tpl new file mode 100644 index 0000000000..8581f1bb8f --- /dev/null +++ b/view/theme/quattro/templates/admin/users/create.tpl @@ -0,0 +1,21 @@ +
+

{{$title}} - {{$page}}

+ +
+ + + + + + + + + + + + + +
{{include file="field_input.tpl" field=$newusername}}
{{include file="field_input.tpl" field=$newusernickname}}
{{include file="field_input.tpl" field=$newuseremail}}
+
+
+
diff --git a/view/theme/quattro/templates/admin/users/deleted.tpl b/view/theme/quattro/templates/admin/users/deleted.tpl new file mode 100644 index 0000000000..ae43400356 --- /dev/null +++ b/view/theme/quattro/templates/admin/users/deleted.tpl @@ -0,0 +1,46 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + + {{foreach $th_deleted as $th}} + + {{/foreach}} + + + + {{foreach $users as $u}} + + + + + + + + + + {{/foreach}} + +
{{$th}}
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}}
+ {{$pager nofilter}} +
+
diff --git a/view/theme/quattro/templates/admin/users/index.tpl b/view/theme/quattro/templates/admin/users/index.tpl new file mode 100644 index 0000000000..a666274761 --- /dev/null +++ b/view/theme/quattro/templates/admin/users/index.tpl @@ -0,0 +1,87 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + {{foreach $th_users as $th}} + + {{/foreach}} + + + + + + {{foreach $users as $u}} + + + + + + + + + + + + {{/foreach}} + +
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
{{$u.nickname}}{{$u.name}}{{$u.register_date}}{{$u.lastitem_date}} + {{if $u.is_deletable}} + + {{else}} +   + {{/if}} + + {{if $u.is_deletable}} + + + + + + + {{else}} +   + {{/if}} +
+ +
+ + + +
+ {{$pager nofilter}} +
+

+ {{$h_newuser}} +

+
diff --git a/view/theme/quattro/templates/admin/users/pending.tpl b/view/theme/quattro/templates/admin/users/pending.tpl new file mode 100644 index 0000000000..a2f9950148 --- /dev/null +++ b/view/theme/quattro/templates/admin/users/pending.tpl @@ -0,0 +1,64 @@ + +
+

{{$title}} - {{$page}} ({{$count}})

+ +
+ + + + + + {{foreach $th_pending as $th}} + + {{/foreach}} + + + + + + {{foreach $pending as $u}} + + + + + + + + + + + {{/foreach}} + +
{{$th}}
{{$u.created}}{{$u.name}} + + + + + + + + +

{{$pendingnotetext}}: {{$u.note}}

+ +
+ + +
+ {{$pager nofilter}} +
+