1
0
Fork 0

Merge pull request #12107 from annando/moderation

New area "moderation"
This commit is contained in:
Philipp 2022-11-08 08:46:06 +01:00 committed by GitHub
commit 939a80ceb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 2636 additions and 2289 deletions

View file

@ -19,6 +19,7 @@ General
* c - Community
* s - Search
* a - Admin
* m - Moderation
* f - Notifications
* u - User menu

View file

@ -162,6 +162,7 @@ class Nav
$nav = [
'admin' => null,
'moderation' => null,
'apps' => null,
'community' => null,
'home' => null,
@ -298,7 +299,8 @@ class Nav
// Show the link to the admin configuration page if user is admin
if ($a->isSiteAdmin()) {
$nav['admin'] = ['admin/', DI::l10n()->t('Admin'), '', DI::l10n()->t('Site setup and configuration')];
$nav['admin'] = ['admin/', DI::l10n()->t('Admin'), '', DI::l10n()->t('Site setup and configuration')];
$nav['moderation'] = ['moderation/', DI::l10n()->t('Moderation'), '', DI::l10n()->t('Content and user moderation')];
}
$nav['navigation'] = ['navigation/', DI::l10n()->t('Navigation'), '', DI::l10n()->t('Site map')];

View file

@ -1,130 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
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)
{
$all = DBA::count('user', ["`uid` != ?", 0]);
$active = DBA::count('user', ["NOT `blocked` AND `verified` AND NOT `account_removed` AND `uid` != ?", 0]);
$pending = Register::getPendingCount();
$blocked = DBA::count('user', ['blocked' => true, 'verified' => true, 'account_removed' => false]);
$deleted = DBA::count('user', ['account_removed' => true]);
$tabs = [
[
'label' => DI::l10n()->t('All') . ' (' . $all . ')',
'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'] = !$user['account_removed'] && intval($user['uid']) != DI::userSession()->getLocalUserId();
$user['deleted'] = ($user['account_removed'] ? Temporal::getRelativeDate($user['account_expires_on']) : False);
return $user;
};
}
}

View file

@ -1,122 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Admin\Blocklist;
use Friendica\Content\Pager;
use Friendica\Core\Renderer;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model;
use Friendica\Module\BaseAdmin;
use Friendica\Util\Network;
class Contact extends BaseAdmin
{
protected function post(array $request = [])
{
self::checkAdminAccess();
self::checkFormSecurityTokenRedirectOnError('/admin/blocklist/contact', 'admin_contactblock');
$contact_url = $_POST['contact_url'] ?? '';
$block_reason = $_POST['contact_block_reason'] ?? '';
$block_purge = $_POST['contact_block_purge'] ?? false;
$contacts = $_POST['contacts'] ?? [];
if (!empty($_POST['page_contactblock_block'])) {
$contact = Model\Contact::getByURL($contact_url, null, ['id', 'nurl']);
if (empty($contact)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Could not find any contact entry for this URL (%s)', $contact_url));
DI::baseUrl()->redirect('admin/blocklist/contact');
}
if (Network::isLocalLink($contact['nurl'])) {
DI::sysmsg()->addNotice(DI::l10n()->t('You can\'t block a local contact, please block the user instead'));
DI::baseUrl()->redirect('admin/blocklist/contact');
}
Model\Contact::block($contact['id'], $block_reason);
if ($block_purge) {
foreach (Model\Contact::selectToArray(['id'], ['nurl' => $contact['nurl']]) as $contact) {
Worker::add(Worker::PRIORITY_LOW, 'Contact\RemoveContent', $contact['id']);
}
}
DI::sysmsg()->addInfo(DI::l10n()->t('The contact has been blocked from the node'));
}
if (!empty($_POST['page_contactblock_unblock'])) {
foreach ($contacts as $uid) {
Model\Contact::unblock($uid);
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s contact unblocked', '%s contacts unblocked', count($contacts)));
}
DI::baseUrl()->redirect('admin/blocklist/contact');
}
protected function content(array $request = []): string
{
parent::content();
$condition = ['uid' => 0, 'blocked' => true];
$total = DBA::count('contact', $condition);
$pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 30);
$contacts = Model\Contact::selectToArray([], $condition, ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]);
$t = Renderer::getMarkupTemplate('admin/blocklist/contact.tpl');
$o = Renderer::replaceMacros($t, [
// strings //
'$title' => DI::l10n()->t('Administration'),
'$page' => DI::l10n()->t('Remote Contact Blocklist'),
'$description' => DI::l10n()->t('This page allows you to prevent any message from a remote contact to reach your node.'),
'$submit' => DI::l10n()->t('Block Remote Contact'),
'$select_all' => DI::l10n()->t('select all'),
'$select_none' => DI::l10n()->t('select none'),
'$block' => DI::l10n()->t('Block'),
'$unblock' => DI::l10n()->t('Unblock'),
'$no_data' => DI::l10n()->t('No remote contact is blocked from this node.'),
'$h_contacts' => DI::l10n()->t('Blocked Remote Contacts'),
'$h_newblock' => DI::l10n()->t('Block New Remote Contact'),
'$th_contacts' => [DI::l10n()->t('Photo'), DI::l10n()->t('Name'), DI::l10n()->t('Reason')],
'$form_security_token' => self::getFormSecurityToken('admin_contactblock'),
// values //
'$baseurl' => DI::baseUrl()->get(true),
'$contacts' => $contacts,
'$total_contacts' => DI::l10n()->tt('%s total blocked contact', '%s total blocked contacts', $total),
'$paginate' => $pager->renderFull($total),
'$contacturl' => ['contact_url', DI::l10n()->t('Profile URL'), '', DI::l10n()->t('URL of the remote contact to block.')],
'$contact_block_purge' => ['contact_block_purge', DI::l10n()->t('Also purge contact'), false, DI::l10n()->t('Removes all content related to this contact from the node. Keeps the contact record. This action cannot be undone.')],
'$contact_block_reason' => ['contact_block_reason', DI::l10n()->t('Block Reason')],
]);
return $o;
}
}

View file

@ -1,145 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Admin\Blocklist\Server;
use Friendica\App;
use Friendica\Content\ContactSelector;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Worker;
use Friendica\Model\Contact;
use Friendica\Model\GServer;
use Friendica\Moderation\DomainPatternBlocklist;
use Friendica\Module\BaseAdmin;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Util\Profiler;
use GuzzleHttp\Psr7\Uri;
use Psr\Log\LoggerInterface;
class Add extends BaseAdmin
{
/** @var SystemMessages */
private $sysmsg;
/** @var DomainPatternBlocklist */
private $blocklist;
public function __construct(SystemMessages $sysmsg, DomainPatternBlocklist $blocklist, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->sysmsg = $sysmsg;
$this->blocklist = $blocklist;
}
/**
* @param array $request
* @return void
* @throws \Friendica\Network\HTTPException\ForbiddenException
* @throws \Friendica\Network\HTTPException\FoundException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \Friendica\Network\HTTPException\MovedPermanentlyException
* @throws \Friendica\Network\HTTPException\TemporaryRedirectException
* @throws \Exception
*/
protected function post(array $request = [])
{
self::checkAdminAccess();
if (empty($request['page_blocklist_add'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/admin/blocklist/server/add', 'admin_blocklist_add');
$pattern = trim($request['pattern']);
// Add new item to blocklist
$this->blocklist->addPattern($pattern, trim($request['reason']));
$this->sysmsg->addInfo($this->l10n->t('Server domain pattern added to the blocklist.'));
if (!empty($request['purge'])) {
$gservers = GServer::listByDomainPattern($pattern);
foreach (Contact::selectToArray(['id'], ['gsid' => array_column($gservers, 'id')]) as $contact) {
Worker::add(Worker::PRIORITY_LOW, 'Contact\RemoveContent', $contact['id']);
}
$this->sysmsg->addInfo($this->l10n->tt('%s server scheduled to be purged.', '%s servers scheduled to be purged.', count($gservers)));
}
$this->baseUrl->redirect('admin/blocklist/server');
}
/**
* @param array $request
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \Friendica\Network\HTTPException\ServiceUnavailableException
* @throws \Exception
*/
protected function content(array $request = []): string
{
parent::content();
$gservers = [];
if ($pattern = trim($request['pattern'] ?? '')) {
$gservers = GServer::listByDomainPattern($pattern);
}
array_walk($gservers, function (array &$gserver) {
$gserver['domain'] = (new Uri($gserver['url']))->getHost();
$gserver['network_icon'] = ContactSelector::networkToIcon($gserver['network']);
$gserver['network_name'] = ContactSelector::networkToName($gserver['network']);
});
$t = Renderer::getMarkupTemplate('admin/blocklist/server/add.tpl');
return Renderer::replaceMacros($t, [
'$l10n' => [
'return_list' => $this->l10n->t('← Return to the list'),
'title' => $this->l10n->t('Administration'),
'page' => $this->l10n->t('Block A New Server Domain Pattern'),
'syntax' => $this->l10n->t('<p>The server domain pattern syntax is case-insensitive shell wildcard, comprising the following special characters:</p>
<ul>
<li><code>*</code>: Any number of characters</li>
<li><code>?</code>: Any single character</li>
</ul>'),
'submit' => $this->l10n->t('Check pattern'),
'matching_servers' => $this->l10n->t('Matching known servers'),
'server_name' => $this->l10n->t('Server Name'),
'server_domain' => $this->l10n->t('Server Domain'),
'known_contacts' => $this->l10n->t('Known Contacts'),
'server_count' => $this->l10n->tt('%d known server', '%d known servers', count($gservers)),
'add_pattern' => $this->l10n->t('Add pattern to the blocklist'),
],
'$newdomain' => ['pattern', $this->l10n->t('Server Domain Pattern'), $pattern, $this->l10n->t('The domain pattern of the new server to add to the blocklist. Do not include the protocol.'), $this->l10n->t('Required'), '', ''],
'$newpurge' => ['purge', $this->l10n->t('Purge server'), $request['purge'] ?? false, $this->l10n->tt('Also purges all the locally stored content authored by the known contacts registered on that server. Keeps the contacts and the server records. This action cannot be undone.', 'Also purges all the locally stored content authored by the known contacts registered on these servers. Keeps the contacts and the servers records. This action cannot be undone.', count($gservers))],
'$newreason' => ['reason', $this->l10n->t('Block reason'), $request['reason'] ?? '', $this->l10n->t('The reason why you blocked this server domain pattern. This reason will be shown publicly in the server information page.'), $this->l10n->t('Required'), '', ''],
'$pattern' => $pattern,
'$gservers' => $gservers,
'$baseurl' => $this->baseUrl->get(true),
'$form_security_token' => self::getFormSecurityToken('admin_blocklist_add')
]);
}
}

View file

@ -1,136 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Admin\Blocklist\Server;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Moderation\DomainPatternBlocklist;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Import extends \Friendica\Module\BaseAdmin
{
/** @var DomainPatternBlocklist */
private $localBlocklist;
/** @var SystemMessages */
private $sysmsg;
/** @var array of blocked server domain patterns */
private $blocklist = [];
public function __construct(DomainPatternBlocklist $localBlocklist, SystemMessages $sysmsg, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->localBlocklist = $localBlocklist;
$this->sysmsg = $sysmsg;
}
/**
* @param array $request
* @return void
* @throws \Friendica\Network\HTTPException\ForbiddenException
* @throws \Friendica\Network\HTTPException\FoundException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \Friendica\Network\HTTPException\MovedPermanentlyException
* @throws \Friendica\Network\HTTPException\TemporaryRedirectException
*/
protected function post(array $request = [])
{
self::checkAdminAccess();
if (!isset($request['page_blocklist_upload']) && !isset($request['page_blocklist_import'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/admin/blocklist/server/import', 'admin_blocklist_import');
if (isset($request['page_blocklist_upload'])) {
try {
$this->blocklist = $this->localBlocklist::extractFromCSVFile($_FILES['listfile']['tmp_name']);
} catch (\Throwable $e) {
$this->sysmsg->addNotice($this->l10n->t('Error importing pattern file'));
}
return;
}
if (isset($request['page_blocklist_import'])) {
$blocklist = json_decode($request['blocklist'], true);
if ($blocklist === null) {
$this->sysmsg->addNotice($this->l10n->t('Error importing pattern file'));
return;
}
if (($request['mode'] ?? 'append') == 'replace') {
$this->localBlocklist->set($blocklist);
$this->sysmsg->addNotice($this->l10n->t('Local blocklist replaced with the provided file.'));
} else {
$count = $this->localBlocklist->append($blocklist);
if ($count) {
$this->sysmsg->addNotice($this->l10n->tt('%d pattern was added to the local blocklist.', '%d patterns were added to the local blocklist.', $count));
} else {
$this->sysmsg->addNotice($this->l10n->t('No pattern was added to the local blocklist.'));
}
}
$this->baseUrl->redirect('/admin/blocklist/server');
}
}
/**
* @param array $request
* @return string
* @throws \Friendica\Network\HTTPException\ServiceUnavailableException
*/
protected function content(array $request = []): string
{
parent::content();
$t = Renderer::getMarkupTemplate('admin/blocklist/server/import.tpl');
return Renderer::replaceMacros($t, [
'$l10n' => [
'return_list' => $this->l10n->t('← Return to the list'),
'title' => $this->l10n->t('Administration'),
'page' => $this->l10n->t('Import a Server Domain Pattern Blocklist'),
'download' => $this->l10n->t('<p>This file can be downloaded from the <code>/friendica</code> path of any Friendica server.</p>'),
'upload' => $this->l10n->t('Upload file'),
'patterns' => $this->l10n->t('Patterns to import'),
'domain_pattern' => $this->l10n->t('Domain Pattern'),
'block_reason' => $this->l10n->t('Block Reason'),
'mode' => $this->l10n->t('Import Mode'),
'import' => $this->l10n->t('Import Patterns'),
'pattern_count' => $this->l10n->tt('%d total pattern', '%d total patterns', count($this->blocklist)),
],
'$listfile' => ['listfile', $this->l10n->t('Server domain pattern blocklist CSV file'), '', '', $this->l10n->t('Required'), '', 'file'],
'$mode_append' => ['mode', $this->l10n->t('Append'), 'append', $this->l10n->t('Imports patterns from the file that weren\'t already existing in the current blocklist.'), 'checked="checked"'],
'$mode_replace' => ['mode', $this->l10n->t('Replace'), 'replace', $this->l10n->t('Replaces the current blocklist by the imported patterns.')],
'$blocklist' => $this->blocklist,
'$baseurl' => $this->baseUrl->get(true),
'$form_security_token' => self::getFormSecurityToken('admin_blocklist_import')
]);
}
}

View file

@ -1,119 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Admin\Blocklist\Server;
use Friendica\App;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Moderation\DomainPatternBlocklist;
use Friendica\Module\BaseAdmin;
use Friendica\Module\Response;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Index extends BaseAdmin
{
/** @var DomainPatternBlocklist */
private $blocklist;
public function __construct(DomainPatternBlocklist $blocklist, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->blocklist = $blocklist;
}
protected function post(array $request = [])
{
self::checkAdminAccess();
if (empty($request['page_blocklist_edit'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/admin/blocklist/server', 'admin_blocklist');
// Edit the entries from blocklist
$blocklist = [];
foreach ($request['domain'] as $id => $domain) {
// Trimming whitespaces as well as any lingering slashes
$domain = trim($domain);
$reason = trim($request['reason'][$id]);
if (empty($request['delete'][$id])) {
$blocklist[] = [
'domain' => $domain,
'reason' => $reason
];
}
}
$this->blocklist->set($blocklist);
$this->baseUrl->redirect('admin/blocklist/server');
}
protected function content(array $request = []): string
{
parent::content();
$blocklistform = [];
foreach ($this->blocklist->get() as $id => $b) {
$blocklistform[] = [
'domain' => ["domain[$id]", $this->l10n->t('Blocked server domain pattern'), $b['domain'], '', $this->l10n->t('Required'), '', ''],
'reason' => ["reason[$id]", $this->l10n->t("Reason for the block"), $b['reason'], '', $this->l10n->t('Required'), '', ''],
'delete' => ["delete[$id]", $this->l10n->t("Delete server domain pattern") . ' (' . $b['domain'] . ')', false, $this->l10n->t("Check to delete this entry from the blocklist")]
];
}
$t = Renderer::getMarkupTemplate('admin/blocklist/server/index.tpl');
return Renderer::replaceMacros($t, [
'$l10n' => [
'title' => $this->l10n->t('Administration'),
'page' => $this->l10n->t('Server Domain Pattern Blocklist'),
'intro' => $this->l10n->t('This page can be used to define a blocklist of server domain patterns from the federated network that are not allowed to interact with your node. For each domain pattern you should also provide the reason why you block it.'),
'public' => $this->l10n->t('The list of blocked server domain patterns will be made publically available on the <a href="/friendica">/friendica</a> page so that your users and people investigating communication problems can find the reason easily.'),
'syntax' => $this->l10n->t('<p>The server domain pattern syntax is case-insensitive shell wildcard, comprising the following special characters:</p>
<ul>
<li><code>*</code>: Any number of characters</li>
<li><code>?</code>: Any single character</li>
</ul>'),
'importtitle' => $this->l10n->t('Import server domain pattern blocklist'),
'addtitle' => $this->l10n->t('Add new entry to the blocklist'),
'importsubmit' => $this->l10n->t('Upload file'),
'addsubmit' => $this->l10n->t('Check pattern'),
'savechanges' => $this->l10n->t('Save changes to the blocklist'),
'currenttitle' => $this->l10n->t('Current Entries in the Blocklist'),
'thurl' => $this->l10n->t('Blocked server domain pattern'),
'threason' => $this->l10n->t('Reason for the block'),
'delentry' => $this->l10n->t('Delete entry from the blocklist'),
'confirm_delete' => $this->l10n->t('Delete entry from the blocklist?'),
],
'$listfile' => ['listfile', $this->l10n->t('Server domain pattern blocklist CSV file'), '', '', $this->l10n->t('Required'), '', 'file'],
'$newdomain' => ['pattern', $this->l10n->t('Server Domain Pattern'), '', $this->l10n->t('The domain pattern of the new server to add to the blocklist. Do not include the protocol.'), $this->l10n->t('Required'), '', ''],
'$entries' => $blocklistform,
'$baseurl' => $this->baseUrl->get(true),
'$form_security_token' => self::getFormSecurityToken('admin_blocklist'),
'$form_security_token_import' => self::getFormSecurityToken('admin_blocklist_import'),
]);
}
}

View file

@ -1,73 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Admin\Item;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model\Item;
use Friendica\Module\BaseAdmin;
class Delete extends BaseAdmin
{
protected function post(array $request = [])
{
self::checkAdminAccess();
if (empty($_POST['page_deleteitem_submit'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/admin/item/delete', 'admin_deleteitem');
if (!empty($_POST['page_deleteitem_submit'])) {
$guid = trim($_POST['deleteitemguid']);
// The GUID should not include a "/", so if there is one, we got an URL
// and the last part of it is most likely the GUID.
if (strpos($guid, '/')) {
$guid = substr($guid, strrpos($guid, '/') + 1);
}
// Now that we have the GUID, drop those items, which will also delete the
// associated threads.
Item::markForDeletion(['guid' => $guid]);
}
DI::sysmsg()->addInfo(DI::l10n()->t('Item marked for deletion.'));
DI::baseUrl()->redirect('admin/item/delete');
}
protected function content(array $request = []): string
{
parent::content();
$t = Renderer::getMarkupTemplate('admin/item/delete.tpl');
return Renderer::replaceMacros($t, [
'$title' => DI::l10n()->t('Administration'),
'$page' => DI::l10n()->t('Delete Item'),
'$submit' => DI::l10n()->t('Delete this Item'),
'$intro1' => DI::l10n()->t('On this page you can delete an item from your node. If the item is a top level posting, the entire thread will be deleted.'),
'$intro2' => DI::l10n()->t('You need to know the GUID of the item. You can find it e.g. by looking at the display URL. The last part of http://example.com/display/123456 is the GUID, here 123456.'),
'$deleteitemguid' => ['deleteitemguid', DI::l10n()->t("GUID"), '', DI::l10n()->t("The GUID of the item you want to delete."), DI::l10n()->t('Required'), 'autofocus'],
'$form_security_token' => self::getFormSecurityToken("admin_deleteitem")
]);
}
}

View file

@ -187,27 +187,6 @@ class Summary extends BaseAdmin
}
}
$accounts = [
[DI::l10n()->t('Normal Account'), 0],
[DI::l10n()->t('Automatic Follower Account'), 0],
[DI::l10n()->t('Public Forum Account'), 0],
[DI::l10n()->t('Automatic Friend Account'), 0],
[DI::l10n()->t('Blog Account'), 0],
[DI::l10n()->t('Private Forum Account'), 0]
];
$users = 0;
$pageFlagsCountStmt = DBA::p('SELECT `page-flags`, COUNT(`uid`) AS `count` FROM `user` WHERE `uid` != ? GROUP BY `page-flags`', 0);
while ($pageFlagsCount = DBA::fetch($pageFlagsCountStmt)) {
$accounts[$pageFlagsCount['page-flags']][1] = $pageFlagsCount['count'];
$users += $pageFlagsCount['count'];
}
DBA::close($pageFlagsCountStmt);
Logger::debug('accounts', ['accounts' => $accounts]);
$pending = Register::getPendingCount();
$deferred = DBA::count('workerqueue', ['NOT `done` AND `retrial` > ?', 0]);
$workerqueue = DBA::count('workerqueue', ['NOT `done` AND `retrial` = ?', 0]);
@ -235,9 +214,6 @@ class Summary extends BaseAdmin
'$title' => DI::l10n()->t('Administration'),
'$page' => DI::l10n()->t('Summary'),
'$queues' => $queues,
'$users' => [DI::l10n()->t('Registered users'), $users],
'$accounts' => $accounts,
'$pending' => [DI::l10n()->t('Pending registrations'), $pending],
'$version' => [DI::l10n()->t('Version'), App::VERSION],
'$platform' => App::PLATFORM,
'$codename' => App::CODENAME,

View file

@ -1,164 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
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
{
protected function post(array $request = [])
{
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);
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s user blocked', '%s users blocked', count($users)));
}
if (!empty($_POST['page_users_delete'])) {
foreach ($users as $uid) {
if (DI::userSession()->getLocalUserId() != $uid) {
User::remove($uid);
} else {
DI::sysmsg()->addNotice(DI::l10n()->t('You can\'t remove yourself'));
}
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users)));
}
DI::baseUrl()->redirect(DI::args()->getQueryString());
}
protected function content(array $request = []): string
{
parent::content();
$action = $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0;
if ($uid) {
$user = User::getById($uid, ['username', 'blocked']);
if (!DBA::isResult($user)) {
DI::sysmsg()->addNotice(DI::l10n()->t('User not found'));
DI::baseUrl()->redirect('admin/users');
return ''; // NOTREACHED
}
}
switch ($action) {
case 'delete':
if (DI::userSession()->getLocalUserId() != $uid) {
self::checkFormSecurityTokenRedirectOnError('admin/users/active', 'admin_users_active', 't');
// delete user
User::remove($uid);
DI::sysmsg()->addNotice(DI::l10n()->t('User "%s" deleted', $user['username']));
} else {
DI::sysmsg()->addNotice(DI::l10n()->t('You can\'t remove yourself'));
}
DI::baseUrl()->redirect('admin/users/active');
break;
case 'block':
self::checkFormSecurityTokenRedirectOnError('admin/users/active', 'admin_users_active', 't');
User::block($uid);
DI::sysmsg()->addNotice(DI::l10n()->t('User "%s" blocked', $user['username']));
DI::baseUrl()->redirect('admin/users/active');
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', ["NOT `blocked` AND `verified` AND NOT `account_removed` AND `uid` != ?", 0]);
$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::args()->getQueryString(),
'$users' => $users,
'$count' => $count,
'$pager' => $pager->renderFull($count),
]);
}
}

View file

@ -1,164 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
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
{
protected function post(array $request = [])
{
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);
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users)));
}
if (!empty($_POST['page_users_delete'])) {
foreach ($users as $uid) {
if (DI::userSession()->getLocalUserId() != $uid) {
User::remove($uid);
} else {
DI::sysmsg()->addNotice(DI::l10n()->t('You can\'t remove yourself'));
}
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users)));
}
DI::baseUrl()->redirect('admin/users/blocked');
}
protected function content(array $request = []): string
{
parent::content();
$action = $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0;
if ($uid) {
$user = User::getById($uid, ['username', 'blocked']);
if (!DBA::isResult($user)) {
DI::sysmsg()->addNotice(DI::l10n()->t('User not found'));
DI::baseUrl()->redirect('admin/users');
return ''; // NOTREACHED
}
}
switch ($action) {
case 'delete':
if (DI::userSession()->getLocalUserId() != $uid) {
self::checkFormSecurityTokenRedirectOnError('/admin/users/blocked', 'admin_users_blocked', 't');
// delete user
User::remove($uid);
DI::sysmsg()->addNotice(DI::l10n()->t('User "%s" deleted', $user['username']));
} else {
DI::sysmsg()->addNotice(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);
DI::sysmsg()->addNotice(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)
]);
}
}

View file

@ -1,181 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
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
{
protected function post(array $request = [])
{
self::checkAdminAccess();
self::checkFormSecurityTokenRedirectOnError('admin/users', 'admin_users');
$users = $_POST['user'] ?? [];
if (!empty($_POST['page_users_block'])) {
foreach ($users as $uid) {
User::block($uid);
}
DI::sysmsg()->addInfo(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);
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s user unblocked', '%s users unblocked', count($users)));
}
if (!empty($_POST['page_users_delete'])) {
foreach ($users as $uid) {
if (DI::userSession()->getLocalUserId() != $uid) {
User::remove($uid);
} else {
DI::sysmsg()->addNotice(DI::l10n()->t('You can\'t remove yourself'));
}
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s user deleted', '%s users deleted', count($users)));
}
DI::baseUrl()->redirect(DI::args()->getQueryString());
}
protected function content(array $request = []): string
{
parent::content();
$action = $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0;
if ($uid) {
$user = User::getById($uid, ['username', 'blocked']);
if (!DBA::isResult($user)) {
DI::sysmsg()->addNotice(DI::l10n()->t('User not found'));
DI::baseUrl()->redirect('admin/users');
return ''; // NOTREACHED
}
}
switch ($action) {
case 'delete':
if (DI::userSession()->getLocalUserId() != $uid) {
self::checkFormSecurityTokenRedirectOnError(DI::baseUrl()->get(true), 'admin_users', 't');
// delete user
User::remove($uid);
DI::sysmsg()->addNotice(DI::l10n()->t('User "%s" deleted', $user['username']));
} else {
DI::sysmsg()->addNotice(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);
DI::sysmsg()->addNotice(DI::l10n()->t('User "%s" blocked', $user['username']));
DI::baseUrl()->redirect('admin/users');
break;
case 'unblock':
self::checkFormSecurityTokenRedirectOnError('admin/users', 'admin_users', 't');
User::block($uid, false);
DI::sysmsg()->addNotice(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', ["`uid` != ?", 0]);
$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::args()->getQueryString(),
'$users' => $users,
'$count' => $count,
'$pager' => $pager->renderFull($count),
]);
}
}

View file

@ -89,7 +89,6 @@ abstract class BaseAdmin extends BaseModule
'configuration' => [DI::l10n()->t('Configuration'), [
'site' => ['admin/site' , DI::l10n()->t('Site') , 'site'],
'storage' => ['admin/storage' , DI::l10n()->t('Storage') , 'storage'],
'users' => ['admin/users' , DI::l10n()->t('Users') , 'users'],
'addons' => ['admin/addons' , DI::l10n()->t('Addons') , 'addons'],
'themes' => ['admin/themes' , DI::l10n()->t('Themes') , 'themes'],
'features' => ['admin/features' , DI::l10n()->t('Additional features') , 'features'],
@ -100,11 +99,6 @@ abstract class BaseAdmin extends BaseModule
'deferred' => ['admin/queue/deferred', DI::l10n()->t('Inspect Deferred Workers'), 'deferred'],
'workerqueue' => ['admin/queue' , DI::l10n()->t('Inspect worker Queue') , 'workerqueue'],
]],
'tools' => [DI::l10n()->t('Tools'), [
'contactblock' => ['admin/blocklist/contact', DI::l10n()->t('Contact Blocklist') , 'contactblock'],
'blocklist' => ['admin/blocklist/server' , DI::l10n()->t('Server Blocklist') , 'blocklist'],
'deleteitem' => ['admin/item/delete' , DI::l10n()->t('Delete Item') , 'deleteitem'],
]],
'logs' => [DI::l10n()->t('Logs'), [
'logsconfig' => ['admin/logs/', DI::l10n()->t('Logs') , 'logs'],
'logsview' => ['admin/logs/view' , DI::l10n()->t('View Logs') , 'viewlogs'],
@ -113,7 +107,6 @@ abstract class BaseAdmin extends BaseModule
'phpinfo' => ['admin/phpinfo' , DI::l10n()->t('PHP Info') , 'phpinfo'],
'probe' => ['probe' , DI::l10n()->t('probe address') , 'probe'],
'webfinger' => ['webfinger' , DI::l10n()->t('check webfinger') , 'webfinger'],
'itemsource' => ['admin/item/source' , DI::l10n()->t('Item Source') , 'itemsource'],
'babel' => ['babel' , DI::l10n()->t('Babel') , 'babel'],
'debug/ap' => ['debug/ap' , DI::l10n()->t('ActivityPub Conversion') , 'debug/ap'],
]],

View file

@ -0,0 +1,134 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module;
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* This abstract module is meant to be extended by all modules that are reserved to moderator users.
*
* It performs a blanket permission check in all the module methods as long as the relevant `parent::method()` is
* called in the inheriting module.
*
* Additionally, it puts together the moderation page aside with all the moderation links.
*
* @package Friendica\Module
*/
abstract class BaseModeration extends BaseModule
{
/** @var IHandleUserSessions */
protected $session;
/** @var SystemMessages */
protected $systemMessages;
/** @var App */
protected $app;
/** @var App\Page */
protected $page;
public function __construct(App\Page $page, App $app, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->session = $session;
$this->systemMessages = $systemMessages;
$this->app = $app;
$this->page = $page;
}
/**
* Checks moderator access and throws exceptions if not logged-in moderator
*
* @param bool $interactive
* @return void
* @throws HTTPException\ForbiddenException
* @throws HTTPException\InternalServerErrorException
*/
public function checkModerationAccess(bool $interactive = false)
{
if (!$this->session->getLocalUserId()) {
if ($interactive) {
$this->systemMessages->addNotice($this->t('Please login to continue.'));
$this->session->set('return_path', $this->args->getQueryString());
$this->baseUrl->redirect('login');
} else {
throw new HTTPException\UnauthorizedException($this->t('Please login to continue.'));
}
}
if (!$this->app->isSiteAdmin()) {
throw new HTTPException\ForbiddenException($this->t('You don\'t have access to administration pages.'));
}
if ($this->session->getSubManagedUserId()) {
throw new HTTPException\ForbiddenException($this->t('Submanaged account can\'t access the administration pages. Please log back in as the main account.'));
}
}
protected function content(array $request = []): string
{
$this->checkModerationAccess(true);
// Header stuff
$this->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('moderation/settings_head.tpl'), []);
/*
* Side bar links
*/
// array(url, name, extra css classes)
// not part of $aside to make the template more adjustable
$aside_sub = [
'information' => [$this->t('Information'), [
'overview' => ['moderation', $this->t('Overview'), 'overview'],
]],
'configuration' => [$this->t('Configuration'), [
'users' => ['moderation/users', $this->t('Users'), 'users'],
]],
'tools' => [$this->t('Tools'), [
'contactblock' => ['moderation/blocklist/contact', $this->t('Contact Blocklist'), 'contactblock'],
'blocklist' => ['moderation/blocklist/server', $this->t('Server Blocklist'), 'blocklist'],
'deleteitem' => ['moderation/item/delete', $this->t('Delete Item'), 'deleteitem'],
]],
'diagnostics' => [$this->t('Diagnostics'), [
'itemsource' => ['moderation/item/source', $this->t('Item Source'), 'itemsource'],
]],
];
$t = Renderer::getMarkupTemplate('moderation/aside.tpl');
$this->page['aside'] .= Renderer::replaceMacros($t, [
'$subpages' => $aside_sub,
'$admtxt' => $this->t('Moderation'),
'$h_pending' => $this->t('User registrations waiting for confirmation'),
'$modurl' => 'moderation/'
]);
return '';
}
}

View file

@ -0,0 +1,149 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\DI;
use Friendica\Model\Register;
use Friendica\Model\User;
use Friendica\Module\BaseModeration;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Util\Profiler;
use Friendica\Util\Temporal;
use Psr\Log\LoggerInterface;
abstract class BaseUsers extends BaseModeration
{
/** @var Database */
protected $database;
public function __construct(Database $database, App\Page $page, App $app, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($page, $app, $systemMessages, $session, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->database = $database;
}
/**
* Get the users moderation tabs menu
*
* @param string $selectedTab
* @return string HTML
* @throws ServiceUnavailableException
*/
protected function getTabsHTML(string $selectedTab): string
{
$all = $this->database->count('user', ["`uid` != ?", 0]);
$active = $this->database->count('user', ["NOT `blocked` AND `verified` AND NOT `account_removed` AND `uid` != ?", 0]);
$pending = Register::getPendingCount();
$blocked = $this->database->count('user', ['blocked' => true, 'verified' => true, 'account_removed' => false]);
$deleted = $this->database->count('user', ['account_removed' => true]);
$tabs = [
[
'label' => $this->t('All') . ' (' . $all . ')',
'url' => 'moderation/users',
'sel' => !$selectedTab || $selectedTab == 'all' ? 'active' : '',
'title' => $this->t('List of all users'),
'id' => 'admin-users-all',
'accesskey' => 'a',
],
[
'label' => $this->t('Active') . ' (' . $active . ')',
'url' => 'moderation/users/active',
'sel' => $selectedTab == 'active' ? 'active' : '',
'title' => $this->t('List of active accounts'),
'id' => 'admin-users-active',
'accesskey' => 'k',
],
[
'label' => $this->t('Pending') . ($pending ? ' (' . $pending . ')' : ''),
'url' => 'moderation/users/pending',
'sel' => $selectedTab == 'pending' ? 'active' : '',
'title' => $this->t('List of pending registrations'),
'id' => 'admin-users-pending',
'accesskey' => 'p',
],
[
'label' => $this->t('Blocked') . ($blocked ? ' (' . $blocked . ')' : ''),
'url' => 'moderation/users/blocked',
'sel' => $selectedTab == 'blocked' ? 'active' : '',
'title' => $this->t('List of blocked users'),
'id' => 'admin-users-blocked',
'accesskey' => 'b',
],
[
'label' => $this->t('Deleted') . ($deleted ? ' (' . $deleted . ')' : ''),
'url' => 'moderation/users/deleted',
'sel' => $selectedTab == 'deleted' ? 'active' : '',
'title' => $this->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 function setupUserCallback(): \Closure
{
$adminlist = explode(',', str_replace(' ', '', DI::config()->get('config', 'admin_email')));
return function ($user) use ($adminlist) {
$page_types = [
User::PAGE_FLAGS_NORMAL => $this->t('Normal Account Page'),
User::PAGE_FLAGS_SOAPBOX => $this->t('Soapbox Page'),
User::PAGE_FLAGS_COMMUNITY => $this->t('Public Forum'),
User::PAGE_FLAGS_FREELOVE => $this->t('Automatic Friend Page'),
User::PAGE_FLAGS_PRVGROUP => $this->t('Private Forum')
];
$account_types = [
User::ACCOUNT_TYPE_PERSON => $this->t('Personal Page'),
User::ACCOUNT_TYPE_ORGANISATION => $this->t('Organisation Page'),
User::ACCOUNT_TYPE_NEWS => $this->t('News Page'),
User::ACCOUNT_TYPE_COMMUNITY => $this->t('Community Forum'),
User::ACCOUNT_TYPE_RELAY => $this->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'] = !$user['account_removed'] && intval($user['uid']) != $this->session->getLocalUserId();
$user['deleted'] = $user['account_removed'] ? Temporal::getRelativeDate($user['account_expires_on']) : false;
return $user;
};
}
}

View file

@ -0,0 +1,138 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Blocklist;
use Friendica\App;
use Friendica\Content\Pager;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\Worker;
use Friendica\Database\Database;
use Friendica\Model;
use Friendica\Module\BaseModeration;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Util\Network;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Contact extends BaseModeration
{
/** @var Database */
private $database;
public function __construct(Database $database, App\Page $page, App $app, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($page, $app, $systemMessages, $session, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->database = $database;
}
protected function post(array $request = [])
{
$this->checkModerationAccess();
self::checkFormSecurityTokenRedirectOnError('/moderation/blocklist/contact', 'moderation_contactblock');
$contact_url = $request['contact_url'] ?? '';
$block_reason = $request['contact_block_reason'] ?? '';
$block_purge = $request['contact_block_purge'] ?? false;
$contacts = $request['contacts'] ?? [];
if (!empty($request['page_contactblock_block'])) {
$contact = Model\Contact::getByURL($contact_url, null, ['id', 'nurl']);
if (empty($contact)) {
$this->systemMessages->addNotice($this->t('Could not find any contact entry for this URL (%s)', $contact_url));
$this->baseUrl->redirect('moderation/blocklist/contact');
}
if (Network::isLocalLink($contact['nurl'])) {
$this->systemMessages->addNotice($this->t('You can\'t block a local contact, please block the user instead'));
$this->baseUrl->redirect('moderation/blocklist/contact');
}
Model\Contact::block($contact['id'], $block_reason);
if ($block_purge) {
foreach (Model\Contact::selectToArray(['id'], ['nurl' => $contact['nurl']]) as $contact) {
Worker::add(Worker::PRIORITY_LOW, 'Contact\RemoveContent', $contact['id']);
}
}
$this->systemMessages->addInfo($this->t('The contact has been blocked from the node'));
}
if (!empty($request['page_contactblock_unblock'])) {
foreach ($contacts as $uid) {
Model\Contact::unblock($uid);
}
$this->systemMessages->addInfo($this->tt('%s contact unblocked', '%s contacts unblocked', count($contacts)));
}
$this->baseUrl->redirect('moderation/blocklist/contact');
}
protected function content(array $request = []): string
{
parent::content();
$condition = ['uid' => 0, 'blocked' => true];
$total = $this->database->count('contact', $condition);
$pager = new Pager($this->l10n, $this->args->getQueryString(), 30);
$contacts = Model\Contact::selectToArray([], $condition, ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]]);
$t = Renderer::getMarkupTemplate('moderation/blocklist/contact.tpl');
return Renderer::replaceMacros($t, [
// strings //
'$title' => $this->t('Moderation'),
'$page' => $this->t('Remote Contact Blocklist'),
'$description' => $this->t('This page allows you to prevent any message from a remote contact to reach your node.'),
'$submit' => $this->t('Block Remote Contact'),
'$select_all' => $this->t('select all'),
'$select_none' => $this->t('select none'),
'$block' => $this->t('Block'),
'$unblock' => $this->t('Unblock'),
'$no_data' => $this->t('No remote contact is blocked from this node.'),
'$h_contacts' => $this->t('Blocked Remote Contacts'),
'$h_newblock' => $this->t('Block New Remote Contact'),
'$th_contacts' => [$this->t('Photo'), $this->t('Name'), $this->t('Reason')],
'$form_security_token' => self::getFormSecurityToken('moderation_contactblock'),
// values //
'$baseurl' => $this->baseUrl->get(true),
'$contacts' => $contacts,
'$total_contacts' => $this->tt('%s total blocked contact', '%s total blocked contacts', $total),
'$paginate' => $pager->renderFull($total),
'$contacturl' => ['contact_url', $this->t('Profile URL'), '', $this->t('URL of the remote contact to block.')],
'$contact_block_purge' => ['contact_block_purge', $this->t('Also purge contact'), false, $this->t('Removes all content related to this contact from the node. Keeps the contact record. This action cannot be undone.')],
'$contact_block_reason' => ['contact_block_reason', $this->t('Block Reason')],
]);
}
}

View file

@ -0,0 +1,143 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Blocklist\Server;
use Friendica\App;
use Friendica\Content\ContactSelector;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\Worker;
use Friendica\Model\Contact;
use Friendica\Model\GServer;
use Friendica\Moderation\DomainPatternBlocklist;
use Friendica\Module\BaseModeration;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException;
use Friendica\Util\Profiler;
use GuzzleHttp\Psr7\Uri;
use Psr\Log\LoggerInterface;
class Add extends BaseModeration
{
/** @var DomainPatternBlocklist */
private $blocklist;
public function __construct(DomainPatternBlocklist $blocklist, App\Page $page, App $app, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($page, $app, $systemMessages, $session, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->blocklist = $blocklist;
}
/**
* @param array $request
* @return void
* @throws HTTPException\ForbiddenException
* @throws HTTPException\FoundException
* @throws HTTPException\InternalServerErrorException
* @throws HTTPException\MovedPermanentlyException
* @throws HTTPException\TemporaryRedirectException
* @throws \Exception
*/
protected function post(array $request = [])
{
$this->checkModerationAccess();
if (empty($request['page_blocklist_add'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/moderation/blocklist/server/add', 'moderation_blocklist_add');
$pattern = trim($request['pattern']);
// Add new item to blocklist
$this->blocklist->addPattern($pattern, trim($request['reason']));
$this->systemMessages->addInfo($this->t('Server domain pattern added to the blocklist.'));
if (!empty($request['purge'])) {
$gservers = GServer::listByDomainPattern($pattern);
foreach (Contact::selectToArray(['id'], ['gsid' => array_column($gservers, 'id')]) as $contact) {
Worker::add(Worker::PRIORITY_LOW, 'Contact\RemoveContent', $contact['id']);
}
$this->systemMessages->addInfo($this->tt('%s server scheduled to be purged.', '%s servers scheduled to be purged.', count($gservers)));
}
$this->baseUrl->redirect('moderation/blocklist/server');
}
/**
* @param array $request
* @return string
* @throws HTTPException\InternalServerErrorException
* @throws HTTPException\ServiceUnavailableException
* @throws \Exception
*/
protected function content(array $request = []): string
{
parent::content();
$gservers = [];
if ($pattern = trim($request['pattern'] ?? '')) {
$gservers = GServer::listByDomainPattern($pattern);
}
array_walk($gservers, function (array &$gserver) {
$gserver['domain'] = (new Uri($gserver['url']))->getHost();
$gserver['network_icon'] = ContactSelector::networkToIcon($gserver['network']);
$gserver['network_name'] = ContactSelector::networkToName($gserver['network']);
});
$t = Renderer::getMarkupTemplate('moderation/blocklist/server/add.tpl');
return Renderer::replaceMacros($t, [
'$l10n' => [
'return_list' => $this->t('← Return to the list'),
'title' => $this->t('Moderation'),
'page' => $this->t('Block A New Server Domain Pattern'),
'syntax' => $this->t('<p>The server domain pattern syntax is case-insensitive shell wildcard, comprising the following special characters:</p>
<ul>
<li><code>*</code>: Any number of characters</li>
<li><code>?</code>: Any single character</li>
</ul>'),
'submit' => $this->t('Check pattern'),
'matching_servers' => $this->t('Matching known servers'),
'server_name' => $this->t('Server Name'),
'server_domain' => $this->t('Server Domain'),
'known_contacts' => $this->t('Known Contacts'),
'server_count' => $this->tt('%d known server', '%d known servers', count($gservers)),
'add_pattern' => $this->t('Add pattern to the blocklist'),
],
'$newdomain' => ['pattern', $this->t('Server Domain Pattern'), $pattern, $this->t('The domain pattern of the new server to add to the blocklist. Do not include the protocol.'), $this->t('Required'), '', ''],
'$newpurge' => ['purge', $this->t('Purge server'), $request['purge'] ?? false, $this->tt('Also purges all the locally stored content authored by the known contacts registered on that server. Keeps the contacts and the server records. This action cannot be undone.', 'Also purges all the locally stored content authored by the known contacts registered on these servers. Keeps the contacts and the servers records. This action cannot be undone.', count($gservers))],
'$newreason' => ['reason', $this->t('Block reason'), $request['reason'] ?? '', $this->t('The reason why you blocked this server domain pattern. This reason will be shown publicly in the server information page.'), $this->t('Required'), '', ''],
'$pattern' => $pattern,
'$gservers' => $gservers,
'$baseurl' => $this->baseUrl->get(true),
'$form_security_token' => self::getFormSecurityToken('moderation_blocklist_add')
]);
}
}

View file

@ -0,0 +1,134 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Blocklist\Server;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Moderation\DomainPatternBlocklist;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Import extends \Friendica\Module\BaseModeration
{
/** @var DomainPatternBlocklist */
private $localBlocklist;
/** @var array of blocked server domain patterns */
private $blocklist = [];
public function __construct(DomainPatternBlocklist $localBlocklist, App\Page $page, App $app, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($page, $app, $systemMessages, $session, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->localBlocklist = $localBlocklist;
}
/**
* @param array $request
* @return void
* @throws HTTPException\ForbiddenException
* @throws HTTPException\FoundException
* @throws HTTPException\InternalServerErrorException
* @throws HTTPException\MovedPermanentlyException
* @throws HTTPException\TemporaryRedirectException
*/
protected function post(array $request = [])
{
$this->checkModerationAccess();
if (!isset($request['page_blocklist_upload']) && !isset($request['page_blocklist_import'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/moderation/blocklist/server/import', 'moderation_blocklist_import');
if (isset($request['page_blocklist_upload'])) {
try {
$this->blocklist = $this->localBlocklist::extractFromCSVFile($_FILES['listfile']['tmp_name']);
} catch (\Throwable $e) {
$this->systemMessages->addNotice($this->t('Error importing pattern file'));
}
return;
}
if (isset($request['page_blocklist_import'])) {
$blocklist = json_decode($request['blocklist'], true);
if ($blocklist === null) {
$this->systemMessages->addNotice($this->t('Error importing pattern file'));
return;
}
if (($request['mode'] ?? 'append') == 'replace') {
$this->localBlocklist->set($blocklist);
$this->systemMessages->addNotice($this->t('Local blocklist replaced with the provided file.'));
} else {
$count = $this->localBlocklist->append($blocklist);
if ($count) {
$this->systemMessages->addNotice($this->tt('%d pattern was added to the local blocklist.', '%d patterns were added to the local blocklist.', $count));
} else {
$this->systemMessages->addNotice($this->t('No pattern was added to the local blocklist.'));
}
}
$this->baseUrl->redirect('/moderation/blocklist/server');
}
}
/**
* @param array $request
* @return string
* @throws HTTPException\ServiceUnavailableException
*/
protected function content(array $request = []): string
{
parent::content();
$t = Renderer::getMarkupTemplate('moderation/blocklist/server/import.tpl');
return Renderer::replaceMacros($t, [
'$l10n' => [
'return_list' => $this->t('← Return to the list'),
'title' => $this->t('Moderation'),
'page' => $this->t('Import a Server Domain Pattern Blocklist'),
'download' => $this->t('<p>This file can be downloaded from the <code>/friendica</code> path of any Friendica server.</p>'),
'upload' => $this->t('Upload file'),
'patterns' => $this->t('Patterns to import'),
'domain_pattern' => $this->t('Domain Pattern'),
'block_reason' => $this->t('Block Reason'),
'mode' => $this->t('Import Mode'),
'import' => $this->t('Import Patterns'),
'pattern_count' => $this->tt('%d total pattern', '%d total patterns', count($this->blocklist)),
],
'$listfile' => ['listfile', $this->t('Server domain pattern blocklist CSV file'), '', '', $this->t('Required'), '', 'file'],
'$mode_append' => ['mode', $this->t('Append'), 'append', $this->t('Imports patterns from the file that weren\'t already existing in the current blocklist.'), 'checked="checked"'],
'$mode_replace' => ['mode', $this->t('Replace'), 'replace', $this->t('Replaces the current blocklist by the imported patterns.')],
'$blocklist' => $this->blocklist,
'$baseurl' => $this->baseUrl->get(true),
'$form_security_token' => self::getFormSecurityToken('moderation_blocklist_import')
]);
}
}

View file

@ -0,0 +1,121 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Blocklist\Server;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Moderation\DomainPatternBlocklist;
use Friendica\Module\BaseModeration;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Index extends BaseModeration
{
/** @var DomainPatternBlocklist */
private $blocklist;
public function __construct(DomainPatternBlocklist $blocklist, App\Page $page, App $app, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($page, $app, $systemMessages, $session, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->blocklist = $blocklist;
}
protected function post(array $request = [])
{
$this->checkModerationAccess();
if (empty($request['page_blocklist_edit'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/moderation/blocklist/server', 'moderation_blocklist');
// Edit the entries from blocklist
$blocklist = [];
foreach ($request['domain'] as $id => $domain) {
// Trimming whitespaces as well as any lingering slashes
$domain = trim($domain);
$reason = trim($request['reason'][$id]);
if (empty($request['delete'][$id])) {
$blocklist[] = [
'domain' => $domain,
'reason' => $reason
];
}
}
$this->blocklist->set($blocklist);
$this->baseUrl->redirect('moderation/blocklist/server');
}
protected function content(array $request = []): string
{
parent::content();
$blocklistform = [];
foreach ($this->blocklist->get() as $id => $b) {
$blocklistform[] = [
'domain' => ["domain[$id]", $this->t('Blocked server domain pattern'), $b['domain'], '', $this->t('Required'), '', ''],
'reason' => ["reason[$id]", $this->t("Reason for the block"), $b['reason'], '', $this->t('Required'), '', ''],
'delete' => ["delete[$id]", $this->t("Delete server domain pattern") . ' (' . $b['domain'] . ')', false, $this->t("Check to delete this entry from the blocklist")]
];
}
$t = Renderer::getMarkupTemplate('moderation/blocklist/server/index.tpl');
return Renderer::replaceMacros($t, [
'$l10n' => [
'title' => $this->t('Moderation'),
'page' => $this->t('Server Domain Pattern Blocklist'),
'intro' => $this->t('This page can be used to define a blocklist of server domain patterns from the federated network that are not allowed to interact with your node. For each domain pattern you should also provide the reason why you block it.'),
'public' => $this->t('The list of blocked server domain patterns will be made publically available on the <a href="/friendica">/friendica</a> page so that your users and people investigating communication problems can find the reason easily.'),
'syntax' => $this->t('<p>The server domain pattern syntax is case-insensitive shell wildcard, comprising the following special characters:</p>
<ul>
<li><code>*</code>: Any number of characters</li>
<li><code>?</code>: Any single character</li>
</ul>'),
'importtitle' => $this->t('Import server domain pattern blocklist'),
'addtitle' => $this->t('Add new entry to the blocklist'),
'importsubmit' => $this->t('Upload file'),
'addsubmit' => $this->t('Check pattern'),
'savechanges' => $this->t('Save changes to the blocklist'),
'currenttitle' => $this->t('Current Entries in the Blocklist'),
'thurl' => $this->t('Blocked server domain pattern'),
'threason' => $this->t('Reason for the block'),
'delentry' => $this->t('Delete entry from the blocklist'),
'confirm_delete' => $this->t('Delete entry from the blocklist?'),
],
'$listfile' => ['listfile', $this->t('Server domain pattern blocklist CSV file'), '', '', $this->t('Required'), '', 'file'],
'$newdomain' => ['pattern', $this->t('Server Domain Pattern'), '', $this->t('The domain pattern of the new server to add to the blocklist. Do not include the protocol.'), $this->t('Required'), '', ''],
'$entries' => $blocklistform,
'$baseurl' => $this->baseUrl->get(true),
'$form_security_token' => self::getFormSecurityToken('moderation_blocklist'),
'$form_security_token_import' => self::getFormSecurityToken('moderation_blocklist_import'),
]);
}
}

View file

@ -0,0 +1,71 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Item;
use Friendica\Core\Renderer;
use Friendica\Model\Item;
use Friendica\Module\BaseModeration;
class Delete extends BaseModeration
{
protected function post(array $request = [])
{
$this->checkModerationAccess();
if (empty($request['page_deleteitem_submit'])) {
return;
}
self::checkFormSecurityTokenRedirectOnError('/moderation/item/delete', 'moderation_deleteitem');
$guid = trim($request['deleteitemguid']);
// The GUID should not include a "/", so if there is one, we got an URL
// and the last part of it is most likely the GUID.
if (strpos($guid, '/')) {
$guid = substr($guid, strrpos($guid, '/') + 1);
}
// Now that we have the GUID, drop those items, which will also delete the
// associated threads.
Item::markForDeletion(['guid' => $guid]);
$this->systemMessages->addInfo($this->t('Item marked for deletion.'));
$this->baseUrl->redirect('moderation/item/delete');
}
protected function content(array $request = []): string
{
parent::content();
$t = Renderer::getMarkupTemplate('moderation/item/delete.tpl');
return Renderer::replaceMacros($t, [
'$title' => $this->t('Moderation'),
'$page' => $this->t('Delete Item'),
'$submit' => $this->t('Delete this Item'),
'$intro1' => $this->t('On this page you can delete an item from your node. If the item is a top level posting, the entire thread will be deleted.'),
'$intro2' => $this->t('You need to know the GUID of the item. You can find it e.g. by looking at the display URL. The last part of http://example.com/display/123456 is the GUID, here 123456.'),
'$deleteitemguid' => ['deleteitemguid', $this->t("GUID"), '', $this->t("The GUID of the item you want to delete."), $this->t('Required'), 'autofocus'],
'$form_security_token' => self::getFormSecurityToken("moderation_deleteitem")
]);
}
}

View file

@ -19,21 +19,19 @@
*
*/
namespace Friendica\Module\Admin\Item;
namespace Friendica\Module\Moderation\Item;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model;
use Friendica\Module\BaseAdmin;
class Source extends BaseAdmin
use Friendica\Module\BaseModeration;
class Source extends BaseModeration
{
protected function content(array $request = []): string
{
parent::content();
$guid = basename($_REQUEST['guid'] ?? $this->parameters['guid'] ?? '');
$guid = basename($request['guid'] ?? $this->parameters['guid'] ?? '');
$item_uri = '';
$item_id = '';
@ -48,25 +46,23 @@ class Source extends BaseAdmin
}
}
$tpl = Renderer::getMarkupTemplate('admin/item/source.tpl');
$o = Renderer::replaceMacros($tpl, [
'$title' => DI::l10n()->t('Item Source'),
'$guid' => ['guid', DI::l10n()->t('Item Guid'), $guid, ''],
$tpl = Renderer::getMarkupTemplate('moderation/item/source.tpl');
return Renderer::replaceMacros($tpl, [
'$title' => $this->t('Item Source'),
'$guid' => ['guid', $this->t('Item Guid'), $guid, ''],
'$item_uri' => $item_uri,
'$item_id' => $item_id,
'$terms' => $terms,
'$itemidlbl' => DI::l10n()->t('Item Id'),
'$itemurilbl' => DI::l10n()->t('Item URI'),
'$submit' => DI::l10n()->t('Submit'),
'$termslbl' => DI::l10n()->t('Terms'),
'$taglbl' => DI::l10n()->t('Tag'),
'$typelbl' => DI::l10n()->t('Type'),
'$termlbl' => DI::l10n()->t('Term'),
'$urllbl' => DI::l10n()->t('URL'),
'$mentionlbl' => DI::l10n()->t('Mention'),
'$implicitlbl' => DI::l10n()->t('Implicit Mention'),
'$itemidlbl' => $this->t('Item Id'),
'$itemurilbl' => $this->t('Item URI'),
'$submit' => $this->t('Submit'),
'$termslbl' => $this->t('Terms'),
'$taglbl' => $this->t('Tag'),
'$typelbl' => $this->t('Type'),
'$termlbl' => $this->t('Term'),
'$urllbl' => $this->t('URL'),
'$mentionlbl' => $this->t('Mention'),
'$implicitlbl' => $this->t('Implicit Mention'),
]);
return $o;
}
}

View file

@ -0,0 +1,84 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\Model\Register;
use Friendica\Module\BaseModeration;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
class Summary extends BaseModeration
{
/** @var Database */
private $database;
public function __construct(Database $database, App\Page $page, App $app, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($page, $app, $systemMessages, $session, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->database = $database;
}
protected function content(array $request = []): string
{
parent::content();
$accounts = [
[$this->t('Normal Account'), 0],
[$this->t('Automatic Follower Account'), 0],
[$this->t('Public Forum Account'), 0],
[$this->t('Automatic Friend Account'), 0],
[$this->t('Blog Account'), 0],
[$this->t('Private Forum Account'), 0]
];
$users = 0;
$pageFlagsCountStmt = $this->database->p('SELECT `page-flags`, COUNT(`uid`) AS `count` FROM `user` WHERE `uid` != ? GROUP BY `page-flags`', 0);
while ($pageFlagsCount = $this->database->fetch($pageFlagsCountStmt)) {
$accounts[$pageFlagsCount['page-flags']][1] = $pageFlagsCount['count'];
$users += $pageFlagsCount['count'];
}
$this->database->close($pageFlagsCountStmt);
$this->logger->debug('accounts', ['accounts' => $accounts]);
$pending = Register::getPendingCount();
$t = Renderer::getMarkupTemplate('moderation/summary.tpl');
return Renderer::replaceMacros($t, [
'$title' => $this->t('Moderation'),
'$page' => $this->t('Summary'),
'$users' => [$this->t('Registered users'), $users],
'$accounts' => $accounts,
'$pending' => [$this->t('Pending registrations'), $pending],
'$warningtext' => [],
]);
}
}

View file

@ -0,0 +1,161 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Users;
use Friendica\Content\Pager;
use Friendica\Core\Renderer;
use Friendica\Model\User;
use Friendica\Module\Moderation\BaseUsers;
class Active extends BaseUsers
{
protected function post(array $request = [])
{
$this->checkModerationAccess();
self::checkFormSecurityTokenRedirectOnError($this->baseUrl->get(true), 'moderation_users_active');
$users = $request['user'] ?? [];
if (!empty($request['page_users_block'])) {
foreach ($users as $uid) {
User::block($uid);
}
$this->systemMessages->addInfo($this->tt('%s user blocked', '%s users blocked', count($users)));
}
if (!empty($request['page_users_delete'])) {
foreach ($users as $uid) {
if ($this->session->getLocalUserId() != $uid) {
User::remove($uid);
} else {
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
}
}
$this->systemMessages->addInfo($this->tt('%s user deleted', '%s users deleted', count($users)));
}
$this->baseUrl->redirect($this->args->getQueryString());
}
protected function content(array $request = []): string
{
parent::content();
$action = $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0;
if ($uid) {
$user = User::getById($uid, ['username', 'blocked']);
if (!$user) {
$this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users');
}
}
switch ($action) {
case 'delete':
if ($this->session->getLocalUserId() != $uid) {
self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't');
// delete user
User::remove($uid);
$this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username']));
} else {
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
}
$this->baseUrl->redirect('moderation/users/active');
break;
case 'block':
self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't');
User::block($uid);
$this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username']));
$this->baseUrl->redirect('moderation/users/active');
break;
}
$pager = new Pager($this->l10n, $this->args->getQueryString(), 100);
$valid_orders = [
'name',
'email',
'register_date',
'login_date',
'last-item',
'page-flags',
];
$order = 'name';
$order_direction = '+';
if (!empty($request['o'])) {
$new_order = $request['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($this->setupUserCallback(), $users);
$th_users = array_map(null, [$this->t('Name'), $this->t('Email'), $this->t('Register date'), $this->t('Last login'), $this->t('Last public item'), $this->t('Type')], $valid_orders);
$count = $this->database->count('user', ["NOT `blocked` AND `verified` AND NOT `account_removed` AND `uid` != ?", 0]);
$t = Renderer::getMarkupTemplate('moderation/users/active.tpl');
return self::getTabsHTML('active') . Renderer::replaceMacros($t, [
// strings //
'$title' => $this->t('Moderation'),
'$page' => $this->t('Active Accounts'),
'$select_all' => $this->t('select all'),
'$delete' => $this->t('Delete'),
'$block' => $this->t('Block'),
'$blocked' => $this->t('User blocked'),
'$siteadmin' => $this->t('Site admin'),
'$accountexpired' => $this->t('Account expired'),
'$h_newuser' => $this->t('Create a new user'),
'$th_users' => $th_users,
'$order_users' => $order,
'$order_direction_users' => $order_direction,
'$confirm_delete_multi' => $this->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' => $this->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('moderation_users_active'),
// values //
'$baseurl' => $this->baseUrl->get(true),
'$query_string' => $this->args->getQueryString(),
'$users' => $users,
'$count' => $count,
'$pager' => $pager->renderFull($count),
]);
}
}

View file

@ -0,0 +1,160 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Users;
use Friendica\Content\Pager;
use Friendica\Core\Renderer;
use Friendica\Model\User;
use Friendica\Module\Moderation\BaseUsers;
class Blocked extends BaseUsers
{
protected function post(array $request = [])
{
$this->checkModerationAccess();
self::checkFormSecurityTokenRedirectOnError('/moderation/users/blocked', 'moderation_users_blocked');
$users = $request['user'] ?? [];
if (!empty($request['page_users_unblock'])) {
foreach ($users as $uid) {
User::block($uid, false);
}
$this->systemMessages->addInfo($this->tt('%s user unblocked', '%s users unblocked', count($users)));
}
if (!empty($request['page_users_delete'])) {
foreach ($users as $uid) {
if ($this->session->getLocalUserId() != $uid) {
User::remove($uid);
} else {
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
}
}
$this->systemMessages->addInfo($this->tt('%s user deleted', '%s users deleted', count($users)));
}
$this->baseUrl->redirect('moderation/users/blocked');
}
protected function content(array $request = []): string
{
parent::content();
$action = $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0;
if ($uid) {
$user = User::getById($uid, ['username', 'blocked']);
if (!$user) {
$this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users');
}
}
switch ($action) {
case 'delete':
if ($this->session->getLocalUserId() != $uid) {
self::checkFormSecurityTokenRedirectOnError('/moderation/users/blocked', 'moderation_users_blocked', 't');
// delete user
User::remove($uid);
$this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username']));
} else {
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
}
$this->baseUrl->redirect('moderation/users/blocked');
break;
case 'unblock':
self::checkFormSecurityTokenRedirectOnError('/moderation/users/blocked', 'moderation_users_blocked', 't');
User::block($uid, false);
$this->systemMessages->addNotice($this->t('User "%s" unblocked', $user['username']));
$this->baseUrl->redirect('moderation/users/blocked');
break;
}
$pager = new Pager($this->l10n, $this->args->getQueryString(), 100);
$valid_orders = [
'name',
'email',
'register_date',
'login_date',
'last-item',
'page-flags',
];
$order = 'name';
$order_direction = '+';
if (!empty($request['o'])) {
$new_order = $request['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($this->setupUserCallback(), $users);
$th_users = array_map(null, [$this->t('Name'), $this->t('Email'), $this->t('Register date'), $this->t('Last login'), $this->t('Last public item'), $this->t('Type')], $valid_orders);
$count = $this->database->count('user', ['blocked' => true, 'verified' => true]);
$t = Renderer::getMarkupTemplate('moderation/users/blocked.tpl');
return self::getTabsHTML('blocked') . Renderer::replaceMacros($t, [
// strings //
'$title' => $this->t('Moderation'),
'$page' => $this->t('Blocked Users'),
'$select_all' => $this->t('select all'),
'$delete' => $this->t('Delete'),
'$blocked' => $this->t('User blocked'),
'$unblock' => $this->t('Unblock'),
'$siteadmin' => $this->t('Site admin'),
'$accountexpired' => $this->t('Account expired'),
'$th_users' => $th_users,
'$order_users' => $order,
'$order_direction_users' => $order_direction,
'$confirm_delete_multi' => $this->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' => $this->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('moderation_users_blocked'),
// values //
'$baseurl' => $this->baseUrl->get(true),
'$query_string' => $this->args->getQueryString(),
'$users' => $users,
'$count' => $count,
'$pager' => $pager->renderFull($count)
]);
}
}

View file

@ -19,36 +19,36 @@
*
*/
namespace Friendica\Module\Admin\Users;
namespace Friendica\Module\Moderation\Users;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model\User;
use Friendica\Module\Admin\BaseUsers;
use Friendica\Module\Moderation\BaseUsers;
class Create extends BaseUsers
{
protected function post(array $request = [])
{
self::checkAdminAccess();
$this->checkModerationAccess();
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_name = $request['new_user_name'] ?? '';
$nu_nickname = $request['new_user_nickname'] ?? '';
$nu_email = $request['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');
$this->baseUrl->redirect('admin/users');
} catch (\Exception $ex) {
DI::sysmsg()->addNotice($ex->getMessage());
$this->systemMessages->addNotice($ex->getMessage());
}
}
DI::baseUrl()->redirect('admin/users/create');
$this->baseUrl->redirect('admin/users/create');
}
protected function content(array $request = []): string
@ -58,19 +58,19 @@ class Create extends BaseUsers
$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'),
'$title' => $this->t('Administration'),
'$page' => $this->t('New User'),
'$submit' => $this->t('Add User'),
'$form_security_token' => self::getFormSecurityToken('admin_users_create'),
// values //
'$baseurl' => DI::baseUrl()->get(true),
'$query_string' => DI::args()->getQueryString(),
'$baseurl' => $this->baseUrl->get(true),
'$query_string' => $this->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'],
'$newusername' => ['new_user_name', $this->t('Name'), '', $this->t('Name of the new user.')],
'$newusernickname' => ['new_user_nickname', $this->t('Nickname'), '', $this->t('Nickname of the new user.')],
'$newuseremail' => ['new_user_email', $this->t('Email'), '', $this->t('Email address of the new user.'), '', '', 'email'],
]);
}
}

View file

@ -19,36 +19,31 @@
*
*/
namespace Friendica\Module\Admin\Users;
namespace Friendica\Module\Moderation\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;
use Friendica\Module\Moderation\BaseUsers;
class Deleted extends BaseUsers
{
protected function post(array $request = [])
{
self::checkAdminAccess();
$this->checkModerationAccess();
self::checkFormSecurityTokenRedirectOnError('/admin/users/deleted', 'admin_users_deleted');
self::checkFormSecurityTokenRedirectOnError('/moderation/users/deleted', 'moderation_users_deleted');
// @TODO: Implement user deletion cancellation
DI::baseUrl()->redirect('admin/users/deleted');
$this->baseUrl->redirect('moderation/users/deleted');
}
protected function content(array $request = []): string
{
parent::content();
$pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100);
$pager = new Pager($this->l10n, $this->args->getQueryString(), 100);
$valid_orders = [
'name',
@ -56,13 +51,13 @@ class Deleted extends BaseUsers
'register_date',
'login_date',
'last-item',
'page-flags'
'page-flags',
];
$order = 'name';
$order_direction = '+';
if (!empty($_GET['o'])) {
$new_order = $_GET['o'];
if (!empty($request['o'])) {
$new_order = $request['o'];
if ($new_order[0] === '-') {
$order_direction = '-';
$new_order = substr($new_order, 1);
@ -75,23 +70,23 @@ class Deleted extends BaseUsers
$users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'removed', $order, ($order_direction == '-'));
$users = array_map(self::setupUserCallback(), $users);
$users = array_map($this->setupUserCallback(), $users);
$count = DBA::count('user', ['account_removed' => true]);
$count = $this->database->count('user', ['account_removed' => true]);
$t = Renderer::getMarkupTemplate('admin/users/deleted.tpl');
$t = Renderer::getMarkupTemplate('moderation/users/deleted.tpl');
return self::getTabsHTML('deleted') . Renderer::replaceMacros($t, [
// strings //
'$title' => DI::l10n()->t('Administration'),
'$page' => DI::l10n()->t('Users awaiting permanent deletion'),
'$title' => $this->t('Moderation'),
'$page' => $this->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')],
'$th_deleted' => [$this->t('Name'), $this->t('Email'), $this->t('Register date'), $this->t('Last login'), $this->t('Last public item'), $this->t('Permanent deletion')],
'$form_security_token' => self::getFormSecurityToken('admin_users_deleted'),
'$form_security_token' => self::getFormSecurityToken('moderation_users_deleted'),
// values //
'$baseurl' => DI::baseUrl()->get(true),
'$query_string' => DI::args()->getQueryString(),
'$baseurl' => $this->baseUrl->get(true),
'$query_string' => $this->args->getQueryString(),
'$users' => $users,
'$count' => $count,

View file

@ -0,0 +1,179 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Module\Moderation\Users;
use Friendica\Content\Pager;
use Friendica\Core\Renderer;
use Friendica\Model\User;
use Friendica\Module\Moderation\BaseUsers;
class Index extends BaseUsers
{
protected function post(array $request = [])
{
$this->checkModerationAccess();
self::checkFormSecurityTokenRedirectOnError('moderation/users', 'moderation_users');
$users = $request['user'] ?? [];
if (!empty($request['page_users_block'])) {
foreach ($users as $uid) {
User::block($uid);
}
$this->systemMessages->addInfo($this->tt('%s user blocked', '%s users blocked', count($users)));
}
if (!empty($request['page_users_unblock'])) {
foreach ($users as $uid) {
User::block($uid, false);
}
$this->systemMessages->addInfo($this->tt('%s user unblocked', '%s users unblocked', count($users)));
}
if (!empty($request['page_users_delete'])) {
foreach ($users as $uid) {
if ($this->session->getLocalUserId() != $uid) {
User::remove($uid);
} else {
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
}
}
$this->systemMessages->addInfo($this->tt('%s user deleted', '%s users deleted', count($users)));
}
$this->baseUrl->redirect($this->args->getQueryString());
}
protected function content(array $request = []): string
{
parent::content();
$action = $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0;
if ($uid) {
$user = User::getById($uid, ['username', 'blocked']);
if (!$user) {
$this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users');
}
}
switch ($action) {
case 'delete':
if ($this->session->getLocalUserId() != $uid) {
self::checkFormSecurityTokenRedirectOnError($this->baseUrl->get(true), 'moderation_users', 't');
// delete user
User::remove($uid);
$this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username']));
} else {
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
}
$this->baseUrl->redirect('moderation/users');
break;
case 'block':
self::checkFormSecurityTokenRedirectOnError('moderation/users', 'moderation_users', 't');
User::block($uid);
$this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username']));
$this->baseUrl->redirect('moderation/users');
break;
case 'unblock':
self::checkFormSecurityTokenRedirectOnError('moderation/users', 'moderation_users', 't');
User::block($uid, false);
$this->systemMessages->addNotice($this->t('User "%s" unblocked', $user['username']));
$this->baseUrl->redirect('moderation/users');
break;
}
$pager = new Pager($this->l10n, $this->args->getQueryString(), 100);
$valid_orders = [
'name',
'email',
'register_date',
'login_date',
'last-item',
'page-flags',
];
$order = 'name';
$order_direction = '+';
if (!empty($request['o'])) {
$new_order = $request['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($this->setupUserCallback(), $users);
$th_users = array_map(null, [$this->t('Name'), $this->t('Email'), $this->t('Register date'), $this->t('Last login'), $this->t('Last public item'), $this->t('Type')], $valid_orders);
$count = $this->database->count('user', ["`uid` != ?", 0]);
$t = Renderer::getMarkupTemplate('moderation/users/index.tpl');
return self::getTabsHTML('all') . Renderer::replaceMacros($t, [
// strings //
'$title' => $this->t('Moderation'),
'$page' => $this->t('Users'),
'$select_all' => $this->t('select all'),
'$h_deleted' => $this->t('User waiting for permanent deletion'),
'$delete' => $this->t('Delete'),
'$block' => $this->t('Block'),
'$blocked' => $this->t('User blocked'),
'$unblock' => $this->t('Unblock'),
'$siteadmin' => $this->t('Site admin'),
'$accountexpired' => $this->t('Account expired'),
'$h_users' => $this->t('Users'),
'$h_newuser' => $this->t('Create a new user'),
'$th_deleted' => [$this->t('Name'), $this->t('Email'), $this->t('Register date'), $this->t('Last login'), $this->t('Last public item'), $this->t('Permanent deletion')],
'$th_users' => $th_users,
'$order_users' => $order,
'$order_direction_users' => $order_direction,
'$confirm_delete_multi' => $this->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' => $this->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('moderation_users'),
// values //
'$baseurl' => $this->baseUrl->get(true),
'$query_string' => $this->args->getQueryString(),
'$users' => $users,
'$count' => $count,
'$pager' => $pager->renderFull($count),
]);
}
}

View file

@ -19,43 +19,39 @@
*
*/
namespace Friendica\Module\Admin\Users;
namespace Friendica\Module\Moderation\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;
use Friendica\Module\Moderation\BaseUsers;
class Pending extends BaseUsers
{
protected function post(array $request = [])
{
self::checkAdminAccess();
$this->checkModerationAccess();
self::checkFormSecurityTokenRedirectOnError('/admin/users/pending', 'admin_users_pending');
$pending = $_POST['pending'] ?? [];
$pending = $request['pending'] ?? [];
if (!empty($_POST['page_users_approve'])) {
if (!empty($request['page_users_approve'])) {
foreach ($pending as $hash) {
User::allow($hash);
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s user approved', '%s users approved', count($pending)));
$this->systemMessages->addInfo($this->tt('%s user approved', '%s users approved', count($pending)));
}
if (!empty($_POST['page_users_deny'])) {
if (!empty($request['page_users_deny'])) {
foreach ($pending as $hash) {
User::deny($hash);
}
DI::sysmsg()->addInfo(DI::l10n()->tt('%s registration revoked', '%s registrations revoked', count($pending)));
$this->systemMessages->addInfo($this->tt('%s registration revoked', '%s registrations revoked', count($pending)));
}
DI::baseUrl()->redirect('admin/users/pending');
$this->baseUrl->redirect('admin/users/pending');
}
protected function content(array $request = []): string
@ -63,14 +59,13 @@ class Pending extends BaseUsers
parent::content();
$action = $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0;
$uid = $this->parameters['uid'] ?? 0;
if ($uid) {
$user = User::getById($uid, ['username', 'blocked']);
if (!DBA::isResult($user)) {
DI::sysmsg()->addNotice(DI::l10n()->t('User not found'));
DI::baseUrl()->redirect('admin/users');
return ''; // NOTREACHED
if (!$user) {
$this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('admin/users');
}
}
@ -78,18 +73,18 @@ class Pending extends BaseUsers
case 'allow':
self::checkFormSecurityTokenRedirectOnError('/admin/users/pending', 'admin_users_pending', 't');
User::allow(Register::getPendingForUser($uid)['hash'] ?? '');
DI::sysmsg()->addNotice(DI::l10n()->t('Account approved.'));
DI::baseUrl()->redirect('admin/users/pending');
$this->systemMessages->addNotice($this->t('Account approved.'));
$this->baseUrl->redirect('admin/users/pending');
break;
case 'deny':
self::checkFormSecurityTokenRedirectOnError('/admin/users/pending', 'admin_users_pending', 't');
User::deny(Register::getPendingForUser($uid)['hash'] ?? '');
DI::sysmsg()->addNotice(DI::l10n()->t('Registration revoked'));
DI::baseUrl()->redirect('admin/users/pending');
$this->systemMessages->addNotice($this->t('Registration revoked'));
$this->baseUrl->redirect('admin/users/pending');
break;
}
$pager = new Pager(DI::l10n(), DI::args()->getQueryString(), 100);
$pager = new Pager($this->l10n, $this->args->getQueryString(), 100);
$pending = Register::getPending($pager->getStart(), $pager->getItemsPerPage());
@ -98,20 +93,20 @@ class Pending extends BaseUsers
$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'),
'$title' => $this->t('Administration'),
'$page' => $this->t('User registrations awaiting review'),
'$select_all' => $this->t('select all'),
'$th_pending' => [$this->t('Request date'), $this->t('Name'), $this->t('Email')],
'$no_pending' => $this->t('No registrations.'),
'$pendingnotetext' => $this->t('Note from the user'),
'$approve' => $this->t('Approve'),
'$deny' => $this->t('Deny'),
'$form_security_token' => self::getFormSecurityToken('admin_users_pending'),
// values //
'$baseurl' => DI::baseUrl()->get(true),
'$query_string' => DI::args()->getQueryString(),
'$baseurl' => $this->baseUrl->get(true),
'$query_string' => $this->args->getQueryString(),
'$pending' => $pending,
'$count' => $count,

View file

@ -315,20 +315,11 @@ return [
'/addons' => [Module\Admin\Addons\Index::class, [R::GET, R::POST]],
'/addons/{addon}' => [Module\Admin\Addons\Details::class, [R::GET, R::POST]],
'/blocklist/contact' => [Module\Admin\Blocklist\Contact::class, [R::GET, R::POST]],
'/blocklist/server' => [Module\Admin\Blocklist\Server\Index::class, [R::GET, R::POST]],
'/blocklist/server/add' => [Module\Admin\Blocklist\Server\Add::class, [R::GET, R::POST]],
'/blocklist/server/import' => [Module\Admin\Blocklist\Server\Import::class, [R::GET, R::POST]],
'/dbsync[/{action}[/{update:\d+}]]' => [Module\Admin\DBSync::class, [R::GET]],
'/features' => [Module\Admin\Features::class, [R::GET, R::POST]],
'/federation' => [Module\Admin\Federation::class, [R::GET]],
'/item/delete' => [Module\Admin\Item\Delete::class, [R::GET, R::POST]],
'/item/source[/{guid}]' => [Module\Admin\Item\Source::class, [R::GET, R::POST]],
'/logs/view' => [Module\Admin\Logs\View::class, [R::GET]],
'/logs' => [Module\Admin\Logs\Settings::class, [R::GET, R::POST]],
@ -346,13 +337,6 @@ return [
'/themes/{theme}/embed' => [Module\Admin\Themes\Embed::class, [R::GET, R::POST]],
'/tos' => [Module\Admin\Tos::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]],
@ -474,6 +458,24 @@ return [
'/magic' => [Module\Magic::class, [R::GET]],
'/manifest' => [Module\Manifest::class, [R::GET]],
'/friendica.webmanifest' => [Module\Manifest::class, [R::GET]],
'/moderation' => [
'[/]' => [Module\Moderation\Summary::class, [R::GET]],
'/blocklist/contact' => [Module\Moderation\Blocklist\Contact::class, [R::GET, R::POST]],
'/blocklist/server' => [Module\Moderation\Blocklist\Server\Index::class, [R::GET, R::POST]],
'/blocklist/server/add' => [Module\Moderation\Blocklist\Server\Add::class, [R::GET, R::POST]],
'/blocklist/server/import' => [Module\Moderation\Blocklist\Server\Import::class, [R::GET, R::POST]],
'/item/delete' => [Module\Moderation\Item\Delete::class, [R::GET, R::POST]],
'/item/source[/{guid}]' => [Module\Moderation\Item\Source::class, [R::GET, R::POST]],
'/users[/{action}/{uid}]' => [Module\Moderation\Users\Index::class, [R::GET, R::POST]],
'/users/active[/{action}/{uid}]' => [Module\Moderation\Users\Active::class, [R::GET, R::POST]],
'/users/pending[/{action}/{uid}]' => [Module\Moderation\Users\Pending::class, [R::GET, R::POST]],
'/users/blocked[/{action}/{uid}]' => [Module\Moderation\Users\Blocked::class, [R::GET, R::POST]],
'/users/deleted' => [Module\Moderation\Users\Deleted::class, [R::GET ]],
'/users/create' => [Module\Moderation\Users\Create::class, [R::GET, R::POST]],
],
'/modexp/{nick}' => [Module\PublicRSAKey::class, [R::GET]],
'/newmember' => [Module\Welcome::class, [R::GET]],
'/nodeinfo/1.0' => [Module\NodeInfo110::class, [R::GET]],

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2022.12-dev\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-07 21:47-0500\n"
"POT-Creation-Date: 2022-11-08 02:32-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -256,7 +256,7 @@ msgstr ""
msgid "Open Compose page"
msgstr ""
#: mod/fbrowser.php:61 src/Content/Nav.php:194 src/Module/BaseProfile.php:64
#: mod/fbrowser.php:61 src/Content/Nav.php:195 src/Module/BaseProfile.php:64
#: view/theme/frio/theme.php:239
msgid "Photos"
msgstr ""
@ -446,7 +446,7 @@ msgstr ""
msgid "Profile Match"
msgstr ""
#: mod/message.php:46 mod/message.php:129 src/Content/Nav.php:288
#: mod/message.php:46 mod/message.php:129 src/Content/Nav.php:289
msgid "New Message"
msgstr ""
@ -472,7 +472,7 @@ msgstr ""
msgid "Discard"
msgstr ""
#: mod/message.php:136 src/Content/Nav.php:285 view/theme/frio/theme.php:246
#: mod/message.php:136 src/Content/Nav.php:286 view/theme/frio/theme.php:246
msgid "Messages"
msgstr ""
@ -510,7 +510,7 @@ msgstr ""
#: mod/message.php:204 mod/message.php:359 mod/photos.php:916
#: mod/photos.php:1020 mod/photos.php:1292 mod/photos.php:1333
#: mod/photos.php:1389 mod/photos.php:1463 src/Module/Admin/Item/Source.php:60
#: mod/photos.php:1389 mod/photos.php:1463
#: src/Module/Calendar/Event/Form.php:250 src/Module/Contact/Advanced.php:132
#: src/Module/Contact/Profile.php:328
#: src/Module/Debug/ActivityPubConversion.php:140
@ -519,11 +519,11 @@ msgstr ""
#: src/Module/Delegation.php:147 src/Module/FriendSuggest.php:145
#: src/Module/Install.php:252 src/Module/Install.php:294
#: src/Module/Install.php:331 src/Module/Invite.php:178
#: src/Module/Item/Compose.php:189 src/Module/Profile/Profile.php:246
#: src/Module/Profile/UnkMail.php:156 src/Module/Settings/Profile/Index.php:231
#: src/Object/Post.php:986 view/theme/duepuntozero/config.php:85
#: view/theme/frio/config.php:171 view/theme/quattro/config.php:87
#: view/theme/vier/config.php:135
#: src/Module/Item/Compose.php:189 src/Module/Moderation/Item/Source.php:58
#: src/Module/Profile/Profile.php:246 src/Module/Profile/UnkMail.php:156
#: src/Module/Settings/Profile/Index.php:231 src/Object/Post.php:986
#: view/theme/duepuntozero/config.php:85 view/theme/frio/config.php:171
#: view/theme/quattro/config.php:87 view/theme/vier/config.php:135
msgid "Submit"
msgstr ""
@ -872,8 +872,9 @@ msgid "Select"
msgstr ""
#: mod/photos.php:1422 mod/settings.php:350 src/Content/Conversation.php:634
#: src/Module/Admin/Users/Active.php:139 src/Module/Admin/Users/Blocked.php:140
#: src/Module/Admin/Users/Index.php:153
#: src/Module/Moderation/Users/Active.php:136
#: src/Module/Moderation/Users/Blocked.php:136
#: src/Module/Moderation/Users/Index.php:151
msgid "Delete"
msgstr ""
@ -968,15 +969,19 @@ msgstr ""
msgid "Connected Apps"
msgstr ""
#: mod/settings.php:176 src/Module/Admin/Blocklist/Contact.php:106
#: src/Module/Admin/Users/Active.php:129 src/Module/Admin/Users/Blocked.php:130
#: src/Module/Admin/Users/Create.php:71 src/Module/Admin/Users/Deleted.php:88
#: src/Module/Admin/Users/Index.php:142 src/Module/Admin/Users/Index.php:162
#: src/Module/Admin/Users/Pending.php:104 src/Module/Contact/Advanced.php:134
#: mod/settings.php:176 src/Module/Contact/Advanced.php:134
#: src/Module/Moderation/Blocklist/Contact.php:122
#: src/Module/Moderation/Users/Active.php:126
#: src/Module/Moderation/Users/Blocked.php:126
#: src/Module/Moderation/Users/Create.php:71
#: src/Module/Moderation/Users/Deleted.php:83
#: src/Module/Moderation/Users/Index.php:140
#: src/Module/Moderation/Users/Index.php:160
#: src/Module/Moderation/Users/Pending.php:99
msgid "Name"
msgstr ""
#: mod/settings.php:177 src/Content/Nav.php:214
#: mod/settings.php:177 src/Content/Nav.php:215
msgid "Home Page"
msgstr ""
@ -1174,7 +1179,7 @@ msgstr ""
msgid "Action after import:"
msgstr ""
#: mod/settings.php:350 src/Content/Nav.php:282
#: mod/settings.php:350 src/Content/Nav.php:283
msgid "Mark as seen"
msgstr ""
@ -1271,13 +1276,13 @@ msgid "The contact entries have been archived"
msgstr ""
#: src/Console/GlobalCommunityBlock.php:96
#: src/Module/Admin/Blocklist/Contact.php:49
#: src/Module/Moderation/Blocklist/Contact.php:65
#, php-format
msgid "Could not find any contact entry for this URL (%s)"
msgstr ""
#: src/Console/GlobalCommunityBlock.php:101
#: src/Module/Admin/Blocklist/Contact.php:66
#: src/Module/Moderation/Blocklist/Contact.php:82
msgid "The contact has been blocked from the node"
msgstr ""
@ -1396,9 +1401,11 @@ msgid "Enter user nickname: "
msgstr ""
#: src/Console/User.php:182 src/Model/User.php:663
#: src/Module/Admin/Users/Active.php:73 src/Module/Admin/Users/Blocked.php:74
#: src/Module/Admin/Users/Index.php:80 src/Module/Admin/Users/Pending.php:71
#: src/Module/Api/Twitter/ContactEndpoint.php:74
#: src/Module/Moderation/Users/Active.php:71
#: src/Module/Moderation/Users/Blocked.php:71
#: src/Module/Moderation/Users/Index.php:78
#: src/Module/Moderation/Users/Pending.php:67
msgid "User not found"
msgstr ""
@ -1501,10 +1508,14 @@ msgstr ""
msgid "RSS/Atom"
msgstr ""
#: src/Content/ContactSelector.php:129 src/Module/Admin/Users/Active.php:129
#: src/Module/Admin/Users/Blocked.php:130 src/Module/Admin/Users/Create.php:73
#: src/Module/Admin/Users/Deleted.php:88 src/Module/Admin/Users/Index.php:142
#: src/Module/Admin/Users/Index.php:162 src/Module/Admin/Users/Pending.php:104
#: src/Content/ContactSelector.php:129
#: src/Module/Moderation/Users/Active.php:126
#: src/Module/Moderation/Users/Blocked.php:126
#: src/Module/Moderation/Users/Create.php:73
#: src/Module/Moderation/Users/Deleted.php:83
#: src/Module/Moderation/Users/Index.php:140
#: src/Module/Moderation/Users/Index.php:160
#: src/Module/Moderation/Users/Pending.php:99
msgid "Email"
msgstr ""
@ -1918,7 +1929,7 @@ msgstr ""
msgid "Display membership date in profile"
msgstr ""
#: src/Content/ForumManager.php:151 src/Content/Nav.php:241
#: src/Content/ForumManager.php:151 src/Content/Nav.php:242
#: src/Content/Text/HTML.php:903 src/Content/Widget.php:524
msgid "Forums"
msgstr ""
@ -1987,10 +1998,11 @@ msgstr ""
msgid "Send PM"
msgstr ""
#: src/Content/Item.php:393 src/Module/Admin/Blocklist/Contact.php:100
#: src/Module/Admin/Users/Active.php:140 src/Module/Admin/Users/Index.php:154
#: src/Module/Contact.php:401 src/Module/Contact/Profile.php:349
#: src/Module/Contact/Profile.php:468
#: src/Content/Item.php:393 src/Module/Contact.php:401
#: src/Module/Contact/Profile.php:349 src/Module/Contact/Profile.php:468
#: src/Module/Moderation/Blocklist/Contact.php:116
#: src/Module/Moderation/Users/Active.php:137
#: src/Module/Moderation/Users/Index.php:152
msgid "Block"
msgstr ""
@ -2028,60 +2040,60 @@ msgstr ""
msgid "@name, !forum, #tags, content"
msgstr ""
#: src/Content/Nav.php:185 src/Module/Security/Login.php:158
#: src/Content/Nav.php:186 src/Module/Security/Login.php:158
msgid "Logout"
msgstr ""
#: src/Content/Nav.php:185
#: src/Content/Nav.php:186
msgid "End this session"
msgstr ""
#: src/Content/Nav.php:187 src/Module/Bookmarklet.php:44
#: src/Content/Nav.php:188 src/Module/Bookmarklet.php:44
#: src/Module/Security/Login.php:159
msgid "Login"
msgstr ""
#: src/Content/Nav.php:187
#: src/Content/Nav.php:188
msgid "Sign in"
msgstr ""
#: src/Content/Nav.php:192 src/Module/BaseProfile.php:56
#: src/Content/Nav.php:193 src/Module/BaseProfile.php:56
#: src/Module/Contact.php:436 src/Module/Contact/Profile.php:381
#: src/Module/Settings/TwoFactor/Index.php:119 view/theme/frio/theme.php:237
msgid "Status"
msgstr ""
#: src/Content/Nav.php:192 src/Content/Nav.php:275
#: src/Content/Nav.php:193 src/Content/Nav.php:276
#: view/theme/frio/theme.php:237
msgid "Your posts and conversations"
msgstr ""
#: src/Content/Nav.php:193 src/Module/BaseProfile.php:48
#: src/Content/Nav.php:194 src/Module/BaseProfile.php:48
#: src/Module/BaseSettings.php:55 src/Module/Contact.php:460
#: src/Module/Contact/Profile.php:383 src/Module/Profile/Profile.php:240
#: src/Module/Welcome.php:57 view/theme/frio/theme.php:238
msgid "Profile"
msgstr ""
#: src/Content/Nav.php:193 view/theme/frio/theme.php:238
#: src/Content/Nav.php:194 view/theme/frio/theme.php:238
msgid "Your profile page"
msgstr ""
#: src/Content/Nav.php:194 view/theme/frio/theme.php:239
#: src/Content/Nav.php:195 view/theme/frio/theme.php:239
msgid "Your photos"
msgstr ""
#: src/Content/Nav.php:195 src/Module/BaseProfile.php:72
#: src/Content/Nav.php:196 src/Module/BaseProfile.php:72
#: src/Module/BaseProfile.php:75 src/Module/Contact.php:452
#: view/theme/frio/theme.php:240
msgid "Media"
msgstr ""
#: src/Content/Nav.php:195 view/theme/frio/theme.php:240
#: src/Content/Nav.php:196 view/theme/frio/theme.php:240
msgid "Your postings with media"
msgstr ""
#: src/Content/Nav.php:196 src/Content/Nav.php:260
#: src/Content/Nav.php:197 src/Content/Nav.php:261
#: src/Module/BaseProfile.php:84 src/Module/BaseProfile.php:87
#: src/Module/BaseProfile.php:95 src/Module/BaseProfile.php:98
#: src/Module/Settings/Display.php:205 view/theme/frio/theme.php:241
@ -2089,32 +2101,32 @@ msgstr ""
msgid "Calendar"
msgstr ""
#: src/Content/Nav.php:196 view/theme/frio/theme.php:241
#: src/Content/Nav.php:197 view/theme/frio/theme.php:241
msgid "Your calendar"
msgstr ""
#: src/Content/Nav.php:197
#: src/Content/Nav.php:198
msgid "Personal notes"
msgstr ""
#: src/Content/Nav.php:197
#: src/Content/Nav.php:198
msgid "Your personal notes"
msgstr ""
#: src/Content/Nav.php:214 src/Content/Nav.php:275
#: src/Content/Nav.php:215 src/Content/Nav.php:276
msgid "Home"
msgstr ""
#: src/Content/Nav.php:218 src/Module/Register.php:168
#: src/Content/Nav.php:219 src/Module/Register.php:168
#: src/Module/Security/Login.php:124
msgid "Register"
msgstr ""
#: src/Content/Nav.php:218
#: src/Content/Nav.php:219
msgid "Create an account"
msgstr ""
#: src/Content/Nav.php:224 src/Module/Help.php:67
#: src/Content/Nav.php:225 src/Module/Help.php:67
#: src/Module/Settings/TwoFactor/AppSpecific.php:128
#: src/Module/Settings/TwoFactor/Index.php:118
#: src/Module/Settings/TwoFactor/Recovery.php:106
@ -2122,153 +2134,172 @@ msgstr ""
msgid "Help"
msgstr ""
#: src/Content/Nav.php:224
#: src/Content/Nav.php:225
msgid "Help and documentation"
msgstr ""
#: src/Content/Nav.php:228
#: src/Content/Nav.php:229
msgid "Apps"
msgstr ""
#: src/Content/Nav.php:228
#: src/Content/Nav.php:229
msgid "Addon applications, utilities, games"
msgstr ""
#: src/Content/Nav.php:232 src/Content/Text/HTML.php:888
#: src/Content/Nav.php:233 src/Content/Text/HTML.php:888
#: src/Module/Admin/Logs/View.php:87 src/Module/Search/Index.php:111
msgid "Search"
msgstr ""
#: src/Content/Nav.php:232
#: src/Content/Nav.php:233
msgid "Search site content"
msgstr ""
#: src/Content/Nav.php:235 src/Content/Text/HTML.php:897
#: src/Content/Nav.php:236 src/Content/Text/HTML.php:897
msgid "Full Text"
msgstr ""
#: src/Content/Nav.php:236 src/Content/Text/HTML.php:898
#: src/Content/Nav.php:237 src/Content/Text/HTML.php:898
#: src/Content/Widget/TagCloud.php:68
msgid "Tags"
msgstr ""
#: src/Content/Nav.php:237 src/Content/Nav.php:296
#: src/Content/Nav.php:238 src/Content/Nav.php:297
#: src/Content/Text/HTML.php:899 src/Module/BaseProfile.php:125
#: src/Module/BaseProfile.php:128 src/Module/Contact.php:373
#: src/Module/Contact.php:467 view/theme/frio/theme.php:248
msgid "Contacts"
msgstr ""
#: src/Content/Nav.php:256
#: src/Content/Nav.php:257
msgid "Community"
msgstr ""
#: src/Content/Nav.php:256
#: src/Content/Nav.php:257
msgid "Conversations on this and other servers"
msgstr ""
#: src/Content/Nav.php:263
#: src/Content/Nav.php:264
msgid "Directory"
msgstr ""
#: src/Content/Nav.php:263
#: src/Content/Nav.php:264
msgid "People directory"
msgstr ""
#: src/Content/Nav.php:265 src/Module/BaseAdmin.php:85
#: src/Content/Nav.php:266 src/Module/BaseAdmin.php:85
#: src/Module/BaseModeration.php:108
msgid "Information"
msgstr ""
#: src/Content/Nav.php:265
#: src/Content/Nav.php:266
msgid "Information about this friendica instance"
msgstr ""
#: src/Content/Nav.php:268 src/Module/Admin/Tos.php:76
#: src/Module/BaseAdmin.php:96 src/Module/Register.php:176
#: src/Content/Nav.php:269 src/Module/Admin/Tos.php:76
#: src/Module/BaseAdmin.php:95 src/Module/Register.php:176
#: src/Module/Tos.php:87
msgid "Terms of Service"
msgstr ""
#: src/Content/Nav.php:268
#: src/Content/Nav.php:269
msgid "Terms of Service of this Friendica instance"
msgstr ""
#: src/Content/Nav.php:273 view/theme/frio/theme.php:244
#: src/Content/Nav.php:274 view/theme/frio/theme.php:244
msgid "Network"
msgstr ""
#: src/Content/Nav.php:273 view/theme/frio/theme.php:244
#: src/Content/Nav.php:274 view/theme/frio/theme.php:244
msgid "Conversations from your friends"
msgstr ""
#: src/Content/Nav.php:279
#: src/Content/Nav.php:280
msgid "Introductions"
msgstr ""
#: src/Content/Nav.php:279
#: src/Content/Nav.php:280
msgid "Friend Requests"
msgstr ""
#: src/Content/Nav.php:280 src/Module/BaseNotifications.php:149
#: src/Content/Nav.php:281 src/Module/BaseNotifications.php:149
#: src/Module/Notifications/Introductions.php:75
msgid "Notifications"
msgstr ""
#: src/Content/Nav.php:281
#: src/Content/Nav.php:282
msgid "See all notifications"
msgstr ""
#: src/Content/Nav.php:282
#: src/Content/Nav.php:283
msgid "Mark all system notifications as seen"
msgstr ""
#: src/Content/Nav.php:285 view/theme/frio/theme.php:246
#: src/Content/Nav.php:286 view/theme/frio/theme.php:246
msgid "Private mail"
msgstr ""
#: src/Content/Nav.php:286
#: src/Content/Nav.php:287
msgid "Inbox"
msgstr ""
#: src/Content/Nav.php:287
#: src/Content/Nav.php:288
msgid "Outbox"
msgstr ""
#: src/Content/Nav.php:291
#: src/Content/Nav.php:292
msgid "Accounts"
msgstr ""
#: src/Content/Nav.php:291
#: src/Content/Nav.php:292
msgid "Manage other pages"
msgstr ""
#: src/Content/Nav.php:294 src/Module/Admin/Addons/Details.php:114
#: src/Content/Nav.php:295 src/Module/Admin/Addons/Details.php:114
#: src/Module/Admin/Themes/Details.php:93 src/Module/BaseSettings.php:122
#: src/Module/Welcome.php:52 view/theme/frio/theme.php:247
msgid "Settings"
msgstr ""
#: src/Content/Nav.php:294 view/theme/frio/theme.php:247
#: src/Content/Nav.php:295 view/theme/frio/theme.php:247
msgid "Account settings"
msgstr ""
#: src/Content/Nav.php:296 view/theme/frio/theme.php:248
#: src/Content/Nav.php:297 view/theme/frio/theme.php:248
msgid "Manage/edit friends and contacts"
msgstr ""
#: src/Content/Nav.php:301 src/Module/BaseAdmin.php:126
#: src/Content/Nav.php:302 src/Module/BaseAdmin.php:119
msgid "Admin"
msgstr ""
#: src/Content/Nav.php:301
#: src/Content/Nav.php:302
msgid "Site setup and configuration"
msgstr ""
#: src/Content/Nav.php:304
#: src/Content/Nav.php:303 src/Module/BaseModeration.php:127
#: src/Module/Moderation/Blocklist/Contact.php:110
#: src/Module/Moderation/Blocklist/Server/Add.php:119
#: src/Module/Moderation/Blocklist/Server/Import.php:115
#: src/Module/Moderation/Blocklist/Server/Index.php:92
#: src/Module/Moderation/Item/Delete.php:61
#: src/Module/Moderation/Summary.php:76
#: src/Module/Moderation/Users/Active.php:133
#: src/Module/Moderation/Users/Blocked.php:133
#: src/Module/Moderation/Users/Deleted.php:80
#: src/Module/Moderation/Users/Index.php:147
msgid "Moderation"
msgstr ""
#: src/Content/Nav.php:303
msgid "Content and user moderation"
msgstr ""
#: src/Content/Nav.php:306
msgid "Navigation"
msgstr ""
#: src/Content/Nav.php:304
#: src/Content/Nav.php:306
msgid "Site map"
msgstr ""
@ -2476,7 +2507,7 @@ msgstr ""
msgid "Account Types"
msgstr ""
#: src/Content/Widget.php:528 src/Module/Admin/BaseUsers.php:51
#: src/Content/Widget.php:528 src/Module/Moderation/BaseUsers.php:69
msgid "All"
msgstr ""
@ -3240,7 +3271,7 @@ msgstr ""
msgid "Legacy module file not found: %s"
msgstr ""
#: src/Model/Contact.php:1212 src/Module/Admin/Users/Pending.php:107
#: src/Model/Contact.php:1212 src/Module/Moderation/Users/Pending.php:102
#: src/Module/Notifications/Introductions.php:132
#: src/Module/Notifications/Introductions.php:204
msgid "Approve"
@ -3624,7 +3655,8 @@ msgstr ""
msgid "Title/Description:"
msgstr ""
#: src/Model/Profile.php:1018 src/Module/Admin/Summary.php:236
#: src/Model/Profile.php:1018 src/Module/Admin/Summary.php:215
#: src/Module/Moderation/Summary.php:77
msgid "Summary"
msgstr ""
@ -3947,24 +3979,18 @@ msgid "Enable"
msgstr ""
#: src/Module/Admin/Addons/Details.php:111 src/Module/Admin/Addons/Index.php:67
#: src/Module/Admin/Blocklist/Contact.php:94
#: src/Module/Admin/Blocklist/Server/Add.php:121
#: src/Module/Admin/Blocklist/Server/Import.php:117
#: src/Module/Admin/Blocklist/Server/Index.php:91
#: src/Module/Admin/Federation.php:202 src/Module/Admin/Item/Delete.php:64
#: src/Module/Admin/Logs/Settings.php:79 src/Module/Admin/Logs/View.php:84
#: src/Module/Admin/Queue.php:72 src/Module/Admin/Site.php:431
#: src/Module/Admin/Storage.php:138 src/Module/Admin/Summary.php:235
#: src/Module/Admin/Themes/Details.php:90 src/Module/Admin/Themes/Index.php:111
#: src/Module/Admin/Tos.php:75 src/Module/Admin/Users/Active.php:136
#: src/Module/Admin/Users/Blocked.php:137 src/Module/Admin/Users/Create.php:61
#: src/Module/Admin/Users/Deleted.php:85 src/Module/Admin/Users/Index.php:149
#: src/Module/Admin/Users/Pending.php:101
#: src/Module/Admin/Federation.php:202 src/Module/Admin/Logs/Settings.php:79
#: src/Module/Admin/Logs/View.php:84 src/Module/Admin/Queue.php:72
#: src/Module/Admin/Site.php:431 src/Module/Admin/Storage.php:138
#: src/Module/Admin/Summary.php:214 src/Module/Admin/Themes/Details.php:90
#: src/Module/Admin/Themes/Index.php:111 src/Module/Admin/Tos.php:75
#: src/Module/Moderation/Users/Create.php:61
#: src/Module/Moderation/Users/Pending.php:96
msgid "Administration"
msgstr ""
#: src/Module/Admin/Addons/Details.php:112 src/Module/Admin/Addons/Index.php:68
#: src/Module/BaseAdmin.php:93 src/Module/BaseSettings.php:85
#: src/Module/BaseAdmin.php:92 src/Module/BaseSettings.php:85
msgid "Addons"
msgstr ""
@ -4004,442 +4030,6 @@ msgid ""
"the open addon registry at %2$s"
msgstr ""
#: src/Module/Admin/BaseUsers.php:54
msgid "List of all users"
msgstr ""
#: src/Module/Admin/BaseUsers.php:59
msgid "Active"
msgstr ""
#: src/Module/Admin/BaseUsers.php:62
msgid "List of active accounts"
msgstr ""
#: src/Module/Admin/BaseUsers.php:67 src/Module/Contact.php:317
#: src/Module/Contact.php:377
msgid "Pending"
msgstr ""
#: src/Module/Admin/BaseUsers.php:70
msgid "List of pending registrations"
msgstr ""
#: src/Module/Admin/BaseUsers.php:75 src/Module/Contact.php:325
#: src/Module/Contact.php:378
msgid "Blocked"
msgstr ""
#: src/Module/Admin/BaseUsers.php:78
msgid "List of blocked users"
msgstr ""
#: src/Module/Admin/BaseUsers.php:83
msgid "Deleted"
msgstr ""
#: src/Module/Admin/BaseUsers.php:86
msgid "List of pending user deletions"
msgstr ""
#: src/Module/Admin/BaseUsers.php:100 src/Module/Settings/Account.php:494
msgid "Normal Account Page"
msgstr ""
#: src/Module/Admin/BaseUsers.php:101 src/Module/Settings/Account.php:501
msgid "Soapbox Page"
msgstr ""
#: src/Module/Admin/BaseUsers.php:102 src/Module/Settings/Account.php:508
msgid "Public Forum"
msgstr ""
#: src/Module/Admin/BaseUsers.php:103 src/Module/Settings/Account.php:515
msgid "Automatic Friend Page"
msgstr ""
#: src/Module/Admin/BaseUsers.php:104
msgid "Private Forum"
msgstr ""
#: src/Module/Admin/BaseUsers.php:107 src/Module/Settings/Account.php:466
msgid "Personal Page"
msgstr ""
#: src/Module/Admin/BaseUsers.php:108 src/Module/Settings/Account.php:473
msgid "Organisation Page"
msgstr ""
#: src/Module/Admin/BaseUsers.php:109 src/Module/Settings/Account.php:480
msgid "News Page"
msgstr ""
#: src/Module/Admin/BaseUsers.php:110 src/Module/Settings/Account.php:487
msgid "Community Forum"
msgstr ""
#: src/Module/Admin/BaseUsers.php:111
msgid "Relay"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:54
msgid "You can't block a local contact, please block the user instead"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:73
#, php-format
msgid "%s contact unblocked"
msgid_plural "%s contacts unblocked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Blocklist/Contact.php:95
msgid "Remote Contact Blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:96
msgid ""
"This page allows you to prevent any message from a remote contact to reach "
"your node."
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:97
msgid "Block Remote Contact"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:98
#: src/Module/Admin/Users/Active.php:138 src/Module/Admin/Users/Blocked.php:139
#: src/Module/Admin/Users/Index.php:151 src/Module/Admin/Users/Pending.php:103
msgid "select all"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:99
msgid "select none"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:101
#: src/Module/Admin/Users/Blocked.php:142 src/Module/Admin/Users/Index.php:156
#: src/Module/Contact.php:401 src/Module/Contact/Profile.php:349
#: src/Module/Contact/Profile.php:468
msgid "Unblock"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:102
msgid "No remote contact is blocked from this node."
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:104
msgid "Blocked Remote Contacts"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:105
msgid "Block New Remote Contact"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:106
msgid "Photo"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:106
msgid "Reason"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:114
#, php-format
msgid "%s total blocked contact"
msgid_plural "%s total blocked contacts"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Blocklist/Contact.php:116 src/Module/Contact/Follow.php:168
#: src/Module/Contact/Profile.php:366 src/Module/Contact/Unfollow.php:129
#: src/Module/Notifications/Introductions.php:129
#: src/Module/Notifications/Introductions.php:198
msgid "Profile URL"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:116
msgid "URL of the remote contact to block."
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:117
msgid "Also purge contact"
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:117
msgid ""
"Removes all content related to this contact from the node. Keeps the contact "
"record. This action cannot be undone."
msgstr ""
#: src/Module/Admin/Blocklist/Contact.php:118
#: src/Module/Admin/Blocklist/Server/Import.php:123
msgid "Block Reason"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:80
msgid "Server domain pattern added to the blocklist."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:88
#, php-format
msgid "%s server scheduled to be purged."
msgid_plural "%s servers scheduled to be purged."
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Blocklist/Server/Add.php:120
#: src/Module/Admin/Blocklist/Server/Import.php:116
msgid "← Return to the list"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:122
msgid "Block A New Server Domain Pattern"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:123
#: src/Module/Admin/Blocklist/Server/Index.php:95
msgid ""
"<p>The server domain pattern syntax is case-insensitive shell wildcard, "
"comprising the following special characters:</p>\n"
"<ul>\n"
"\t<li><code>*</code>: Any number of characters</li>\n"
"\t<li><code>?</code>: Any single character</li>\n"
"</ul>"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:128
#: src/Module/Admin/Blocklist/Server/Index.php:103
msgid "Check pattern"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:129
msgid "Matching known servers"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:130
msgid "Server Name"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:131
msgid "Server Domain"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:132
msgid "Known Contacts"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:133
#, php-format
msgid "%d known server"
msgid_plural "%d known servers"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Blocklist/Server/Add.php:134
msgid "Add pattern to the blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:136
#: src/Module/Admin/Blocklist/Server/Index.php:112
msgid "Server Domain Pattern"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:136
#: src/Module/Admin/Blocklist/Server/Index.php:112
msgid ""
"The domain pattern of the new server to add to the blocklist. Do not include "
"the protocol."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:136
#: src/Module/Admin/Blocklist/Server/Add.php:138
#: src/Module/Admin/Blocklist/Server/Import.php:128
#: src/Module/Admin/Blocklist/Server/Index.php:82
#: src/Module/Admin/Blocklist/Server/Index.php:83
#: src/Module/Admin/Blocklist/Server/Index.php:111
#: src/Module/Admin/Blocklist/Server/Index.php:112
#: src/Module/Admin/Item/Delete.php:69 src/Module/Calendar/Event/Form.php:209
#: src/Module/Calendar/Event/Form.php:241 src/Module/Debug/Probe.php:59
#: src/Module/Install.php:207 src/Module/Install.php:240
#: src/Module/Install.php:245 src/Module/Install.php:264
#: src/Module/Install.php:275 src/Module/Install.php:280
#: src/Module/Install.php:286 src/Module/Install.php:291
#: src/Module/Install.php:305 src/Module/Install.php:320
#: src/Module/Install.php:347 src/Module/Register.php:148
#: src/Module/Security/TwoFactor/Verify.php:101
#: src/Module/Settings/TwoFactor/Index.php:140
#: src/Module/Settings/TwoFactor/Verify.php:154
msgid "Required"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:137
msgid "Purge server"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:137
msgid ""
"Also purges all the locally stored content authored by the known contacts "
"registered on that server. Keeps the contacts and the server records. This "
"action cannot be undone."
msgid_plural ""
"Also purges all the locally stored content authored by the known contacts "
"registered on these servers. Keeps the contacts and the servers records. "
"This action cannot be undone."
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Blocklist/Server/Add.php:138
msgid "Block reason"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Add.php:138
msgid ""
"The reason why you blocked this server domain pattern. This reason will be "
"shown publicly in the server information page."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:75
#: src/Module/Admin/Blocklist/Server/Import.php:84
msgid "Error importing pattern file"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:90
msgid "Local blocklist replaced with the provided file."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:94
#, php-format
msgid "%d pattern was added to the local blocklist."
msgid_plural "%d patterns were added to the local blocklist."
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Blocklist/Server/Import.php:96
msgid "No pattern was added to the local blocklist."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:118
msgid "Import a Server Domain Pattern Blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:119
msgid ""
"<p>This file can be downloaded from the <code>/friendica</code> path of any "
"Friendica server.</p>"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:120
#: src/Module/Admin/Blocklist/Server/Index.php:102
msgid "Upload file"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:121
msgid "Patterns to import"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:122
msgid "Domain Pattern"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:124
msgid "Import Mode"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:125
msgid "Import Patterns"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:126
#, php-format
msgid "%d total pattern"
msgid_plural "%d total patterns"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Blocklist/Server/Import.php:128
#: src/Module/Admin/Blocklist/Server/Index.php:111
msgid "Server domain pattern blocklist CSV file"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:129
msgid "Append"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:129
msgid ""
"Imports patterns from the file that weren't already existing in the current "
"blocklist."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:130
msgid "Replace"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Import.php:130
msgid "Replaces the current blocklist by the imported patterns."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:82
#: src/Module/Admin/Blocklist/Server/Index.php:106
msgid "Blocked server domain pattern"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:83
#: src/Module/Admin/Blocklist/Server/Index.php:107 src/Module/Friendica.php:83
msgid "Reason for the block"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:84
msgid "Delete server domain pattern"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:84
msgid "Check to delete this entry from the blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:92
msgid "Server Domain Pattern Blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:93
msgid ""
"This page can be used to define a blocklist of server domain patterns from "
"the federated network that are not allowed to interact with your node. For "
"each domain pattern you should also provide the reason why you block it."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:94
msgid ""
"The list of blocked server domain patterns will be made publically available "
"on the <a href=\"/friendica\">/friendica</a> page so that your users and "
"people investigating communication problems can find the reason easily."
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:100
msgid "Import server domain pattern blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:101
msgid "Add new entry to the blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:104
msgid "Save changes to the blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:105
msgid "Current Entries in the Blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:108
msgid "Delete entry from the blocklist"
msgstr ""
#: src/Module/Admin/Blocklist/Server/Index.php:109
msgid "Delete entry from the blocklist?"
msgstr ""
#: src/Module/Admin/DBSync.php:51
msgid "Update has been marked successful"
msgstr ""
@ -4589,84 +4179,6 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Item/Delete.php:53
msgid "Item marked for deletion."
msgstr ""
#: src/Module/Admin/Item/Delete.php:65 src/Module/BaseAdmin.php:106
msgid "Delete Item"
msgstr ""
#: src/Module/Admin/Item/Delete.php:66
msgid "Delete this Item"
msgstr ""
#: src/Module/Admin/Item/Delete.php:67
msgid ""
"On this page you can delete an item from your node. If the item is a top "
"level posting, the entire thread will be deleted."
msgstr ""
#: src/Module/Admin/Item/Delete.php:68
msgid ""
"You need to know the GUID of the item. You can find it e.g. by looking at "
"the display URL. The last part of http://example.com/display/123456 is the "
"GUID, here 123456."
msgstr ""
#: src/Module/Admin/Item/Delete.php:69
msgid "GUID"
msgstr ""
#: src/Module/Admin/Item/Delete.php:69
msgid "The GUID of the item you want to delete."
msgstr ""
#: src/Module/Admin/Item/Source.php:53 src/Module/BaseAdmin.php:116
msgid "Item Source"
msgstr ""
#: src/Module/Admin/Item/Source.php:54
msgid "Item Guid"
msgstr ""
#: src/Module/Admin/Item/Source.php:58
msgid "Item Id"
msgstr ""
#: src/Module/Admin/Item/Source.php:59
msgid "Item URI"
msgstr ""
#: src/Module/Admin/Item/Source.php:61
msgid "Terms"
msgstr ""
#: src/Module/Admin/Item/Source.php:62
msgid "Tag"
msgstr ""
#: src/Module/Admin/Item/Source.php:63 src/Module/Admin/Users/Active.php:129
#: src/Module/Admin/Users/Blocked.php:130 src/Module/Admin/Users/Index.php:142
msgid "Type"
msgstr ""
#: src/Module/Admin/Item/Source.php:64
msgid "Term"
msgstr ""
#: src/Module/Admin/Item/Source.php:65
msgid "URL"
msgstr ""
#: src/Module/Admin/Item/Source.php:66
msgid "Mention"
msgstr ""
#: src/Module/Admin/Item/Source.php:67
msgid "Implicit Mention"
msgstr ""
#: src/Module/Admin/Logs/Settings.php:47
#, php-format
msgid "The logfile '%s' is not writable. No logging possible"
@ -4680,8 +4192,8 @@ msgstr ""
msgid "PHP log currently disabled."
msgstr ""
#: src/Module/Admin/Logs/Settings.php:80 src/Module/BaseAdmin.php:108
#: src/Module/BaseAdmin.php:109
#: src/Module/Admin/Logs/Settings.php:80 src/Module/BaseAdmin.php:102
#: src/Module/BaseAdmin.php:103
msgid "Logs"
msgstr ""
@ -4734,7 +4246,7 @@ msgid ""
"is readable."
msgstr ""
#: src/Module/Admin/Logs/View.php:85 src/Module/BaseAdmin.php:110
#: src/Module/Admin/Logs/View.php:85 src/Module/BaseAdmin.php:104
msgid "View Logs"
msgstr ""
@ -5951,51 +5463,19 @@ msgid ""
"'%s'. Please fix your configuration."
msgstr ""
#: src/Module/Admin/Summary.php:191
msgid "Normal Account"
msgstr ""
#: src/Module/Admin/Summary.php:192
msgid "Automatic Follower Account"
msgstr ""
#: src/Module/Admin/Summary.php:193
msgid "Public Forum Account"
msgstr ""
#: src/Module/Admin/Summary.php:194
msgid "Automatic Friend Account"
msgstr ""
#: src/Module/Admin/Summary.php:195
msgid "Blog Account"
msgstr ""
#: src/Module/Admin/Summary.php:196
msgid "Private Forum Account"
msgstr ""
#: src/Module/Admin/Summary.php:216
msgid "Message queues"
msgstr ""
#: src/Module/Admin/Summary.php:222
#: src/Module/Admin/Summary.php:201
msgid "Server Settings"
msgstr ""
#: src/Module/Admin/Summary.php:238
msgid "Registered users"
msgstr ""
#: src/Module/Admin/Summary.php:240
msgid "Pending registrations"
msgstr ""
#: src/Module/Admin/Summary.php:241
#: src/Module/Admin/Summary.php:217
msgid "Version"
msgstr ""
#: src/Module/Admin/Summary.php:245
#: src/Module/Admin/Summary.php:221
msgid "Active addons"
msgstr ""
@ -6019,7 +5499,7 @@ msgid "Screenshot"
msgstr ""
#: src/Module/Admin/Themes/Details.php:91 src/Module/Admin/Themes/Index.php:112
#: src/Module/BaseAdmin.php:94
#: src/Module/BaseAdmin.php:93
msgid "Themes"
msgstr ""
@ -6084,192 +5564,6 @@ msgid ""
"of sections should be [h2] and below."
msgstr ""
#: src/Module/Admin/Users/Active.php:45 src/Module/Admin/Users/Index.php:45
#, php-format
msgid "%s user blocked"
msgid_plural "%s users blocked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Users/Active.php:53 src/Module/Admin/Users/Active.php:88
#: src/Module/Admin/Users/Blocked.php:54 src/Module/Admin/Users/Blocked.php:89
#: src/Module/Admin/Users/Index.php:60 src/Module/Admin/Users/Index.php:95
msgid "You can't remove yourself"
msgstr ""
#: src/Module/Admin/Users/Active.php:57 src/Module/Admin/Users/Blocked.php:58
#: src/Module/Admin/Users/Index.php:64
#, php-format
msgid "%s user deleted"
msgid_plural "%s users deleted"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Users/Active.php:86 src/Module/Admin/Users/Blocked.php:87
#: src/Module/Admin/Users/Index.php:93
#, php-format
msgid "User \"%s\" deleted"
msgstr ""
#: src/Module/Admin/Users/Active.php:96 src/Module/Admin/Users/Index.php:103
#, php-format
msgid "User \"%s\" blocked"
msgstr ""
#: src/Module/Admin/Users/Active.php:129 src/Module/Admin/Users/Blocked.php:130
#: src/Module/Admin/Users/Deleted.php:88 src/Module/Admin/Users/Index.php:142
#: src/Module/Admin/Users/Index.php:162
msgid "Register date"
msgstr ""
#: src/Module/Admin/Users/Active.php:129 src/Module/Admin/Users/Blocked.php:130
#: src/Module/Admin/Users/Deleted.php:88 src/Module/Admin/Users/Index.php:142
#: src/Module/Admin/Users/Index.php:162
msgid "Last login"
msgstr ""
#: src/Module/Admin/Users/Active.php:129 src/Module/Admin/Users/Blocked.php:130
#: src/Module/Admin/Users/Deleted.php:88 src/Module/Admin/Users/Index.php:142
#: src/Module/Admin/Users/Index.php:162
msgid "Last public item"
msgstr ""
#: src/Module/Admin/Users/Active.php:137
msgid "Active Accounts"
msgstr ""
#: src/Module/Admin/Users/Active.php:141 src/Module/Admin/Users/Blocked.php:141
#: src/Module/Admin/Users/Index.php:155
msgid "User blocked"
msgstr ""
#: src/Module/Admin/Users/Active.php:142 src/Module/Admin/Users/Blocked.php:143
#: src/Module/Admin/Users/Index.php:157
msgid "Site admin"
msgstr ""
#: src/Module/Admin/Users/Active.php:143 src/Module/Admin/Users/Blocked.php:144
#: src/Module/Admin/Users/Index.php:158
msgid "Account expired"
msgstr ""
#: src/Module/Admin/Users/Active.php:144 src/Module/Admin/Users/Index.php:161
msgid "Create a new user"
msgstr ""
#: src/Module/Admin/Users/Active.php:150 src/Module/Admin/Users/Blocked.php:150
#: src/Module/Admin/Users/Index.php:167
msgid ""
"Selected users will be deleted!\\n\\nEverything these users had posted on "
"this site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
#: src/Module/Admin/Users/Active.php:151 src/Module/Admin/Users/Blocked.php:151
#: src/Module/Admin/Users/Index.php:168
msgid ""
"The user {0} will be deleted!\\n\\nEverything this user has posted on this "
"site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
#: src/Module/Admin/Users/Blocked.php:46 src/Module/Admin/Users/Index.php:52
#, php-format
msgid "%s user unblocked"
msgid_plural "%s users unblocked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Users/Blocked.php:96 src/Module/Admin/Users/Index.php:109
#, php-format
msgid "User \"%s\" unblocked"
msgstr ""
#: src/Module/Admin/Users/Blocked.php:138
msgid "Blocked Users"
msgstr ""
#: src/Module/Admin/Users/Create.php:62
msgid "New User"
msgstr ""
#: src/Module/Admin/Users/Create.php:63
msgid "Add User"
msgstr ""
#: src/Module/Admin/Users/Create.php:71
msgid "Name of the new user."
msgstr ""
#: src/Module/Admin/Users/Create.php:72
msgid "Nickname"
msgstr ""
#: src/Module/Admin/Users/Create.php:72
msgid "Nickname of the new user."
msgstr ""
#: src/Module/Admin/Users/Create.php:73
msgid "Email address of the new user."
msgstr ""
#: src/Module/Admin/Users/Deleted.php:86
msgid "Users awaiting permanent deletion"
msgstr ""
#: src/Module/Admin/Users/Deleted.php:88 src/Module/Admin/Users/Index.php:162
msgid "Permanent deletion"
msgstr ""
#: src/Module/Admin/Users/Index.php:150 src/Module/Admin/Users/Index.php:160
#: src/Module/BaseAdmin.php:92
msgid "Users"
msgstr ""
#: src/Module/Admin/Users/Index.php:152
msgid "User waiting for permanent deletion"
msgstr ""
#: src/Module/Admin/Users/Pending.php:48
#, php-format
msgid "%s user approved"
msgid_plural "%s users approved"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Users/Pending.php:55
#, php-format
msgid "%s registration revoked"
msgid_plural "%s registrations revoked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Admin/Users/Pending.php:81
msgid "Account approved."
msgstr ""
#: src/Module/Admin/Users/Pending.php:87
msgid "Registration revoked"
msgstr ""
#: src/Module/Admin/Users/Pending.php:102
msgid "User registrations awaiting review"
msgstr ""
#: src/Module/Admin/Users/Pending.php:104
msgid "Request date"
msgstr ""
#: src/Module/Admin/Users/Pending.php:105
msgid "No registrations."
msgstr ""
#: src/Module/Admin/Users/Pending.php:106
msgid "Note from the user"
msgstr ""
#: src/Module/Admin/Users/Pending.php:108
msgid "Deny"
msgstr ""
#: src/Module/Api/ApiResponse.php:279
#, php-format
msgid "API endpoint %s %s is not implemented"
@ -6327,88 +5621,77 @@ msgid "Item was not found."
msgstr ""
#: src/Module/BaseAdmin.php:54 src/Module/BaseAdmin.php:58
#: src/Module/BaseModeration.php:77 src/Module/BaseModeration.php:81
msgid "Please login to continue."
msgstr ""
#: src/Module/BaseAdmin.php:63
#: src/Module/BaseAdmin.php:63 src/Module/BaseModeration.php:86
msgid "You don't have access to administration pages."
msgstr ""
#: src/Module/BaseAdmin.php:67
#: src/Module/BaseAdmin.php:67 src/Module/BaseModeration.php:90
msgid ""
"Submanaged account can't access the administration pages. Please log back in "
"as the main account."
msgstr ""
#: src/Module/BaseAdmin.php:86
#: src/Module/BaseAdmin.php:86 src/Module/BaseModeration.php:109
msgid "Overview"
msgstr ""
#: src/Module/BaseAdmin.php:89
#: src/Module/BaseAdmin.php:89 src/Module/BaseModeration.php:111
msgid "Configuration"
msgstr ""
#: src/Module/BaseAdmin.php:95 src/Module/BaseSettings.php:63
#: src/Module/BaseAdmin.php:94 src/Module/BaseSettings.php:63
msgid "Additional features"
msgstr ""
#: src/Module/BaseAdmin.php:98
#: src/Module/BaseAdmin.php:97
msgid "Database"
msgstr ""
#: src/Module/BaseAdmin.php:99
#: src/Module/BaseAdmin.php:98
msgid "DB updates"
msgstr ""
#: src/Module/BaseAdmin.php:100
#: src/Module/BaseAdmin.php:99
msgid "Inspect Deferred Workers"
msgstr ""
#: src/Module/BaseAdmin.php:101
#: src/Module/BaseAdmin.php:100
msgid "Inspect worker Queue"
msgstr ""
#: src/Module/BaseAdmin.php:103
msgid "Tools"
msgstr ""
#: src/Module/BaseAdmin.php:104
msgid "Contact Blocklist"
msgstr ""
#: src/Module/BaseAdmin.php:105
msgid "Server Blocklist"
msgstr ""
#: src/Module/BaseAdmin.php:112
#: src/Module/BaseAdmin.php:106 src/Module/BaseModeration.php:119
msgid "Diagnostics"
msgstr ""
#: src/Module/BaseAdmin.php:113
#: src/Module/BaseAdmin.php:107
msgid "PHP Info"
msgstr ""
#: src/Module/BaseAdmin.php:114
#: src/Module/BaseAdmin.php:108
msgid "probe address"
msgstr ""
#: src/Module/BaseAdmin.php:115
#: src/Module/BaseAdmin.php:109
msgid "check webfinger"
msgstr ""
#: src/Module/BaseAdmin.php:117
#: src/Module/BaseAdmin.php:110
msgid "Babel"
msgstr ""
#: src/Module/BaseAdmin.php:118 src/Module/Debug/ActivityPubConversion.php:137
#: src/Module/BaseAdmin.php:111 src/Module/Debug/ActivityPubConversion.php:137
msgid "ActivityPub Conversion"
msgstr ""
#: src/Module/BaseAdmin.php:127
#: src/Module/BaseAdmin.php:120
msgid "Addon Features"
msgstr ""
#: src/Module/BaseAdmin.php:128
#: src/Module/BaseAdmin.php:121 src/Module/BaseModeration.php:128
msgid "User registrations waiting for confirmation"
msgstr ""
@ -6439,6 +5722,31 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
#: src/Module/BaseModeration.php:112 src/Module/Moderation/Users/Index.php:148
#: src/Module/Moderation/Users/Index.php:158
msgid "Users"
msgstr ""
#: src/Module/BaseModeration.php:114
msgid "Tools"
msgstr ""
#: src/Module/BaseModeration.php:115
msgid "Contact Blocklist"
msgstr ""
#: src/Module/BaseModeration.php:116
msgid "Server Blocklist"
msgstr ""
#: src/Module/BaseModeration.php:117 src/Module/Moderation/Item/Delete.php:62
msgid "Delete Item"
msgstr ""
#: src/Module/BaseModeration.php:120 src/Module/Moderation/Item/Source.php:51
msgid "Item Source"
msgstr ""
#: src/Module/BaseProfile.php:51 src/Module/Contact.php:463
msgid "Profile Details"
msgstr ""
@ -6541,6 +5849,28 @@ msgstr ""
msgid "Event Starts:"
msgstr ""
#: src/Module/Calendar/Event/Form.php:209
#: src/Module/Calendar/Event/Form.php:241 src/Module/Debug/Probe.php:59
#: src/Module/Install.php:207 src/Module/Install.php:240
#: src/Module/Install.php:245 src/Module/Install.php:264
#: src/Module/Install.php:275 src/Module/Install.php:280
#: src/Module/Install.php:286 src/Module/Install.php:291
#: src/Module/Install.php:305 src/Module/Install.php:320
#: src/Module/Install.php:347
#: src/Module/Moderation/Blocklist/Server/Add.php:134
#: src/Module/Moderation/Blocklist/Server/Add.php:136
#: src/Module/Moderation/Blocklist/Server/Import.php:126
#: src/Module/Moderation/Blocklist/Server/Index.php:83
#: src/Module/Moderation/Blocklist/Server/Index.php:84
#: src/Module/Moderation/Blocklist/Server/Index.php:112
#: src/Module/Moderation/Blocklist/Server/Index.php:113
#: src/Module/Moderation/Item/Delete.php:67 src/Module/Register.php:148
#: src/Module/Security/TwoFactor/Verify.php:101
#: src/Module/Settings/TwoFactor/Index.php:140
#: src/Module/Settings/TwoFactor/Verify.php:154
msgid "Required"
msgstr ""
#: src/Module/Calendar/Event/Form.php:223
#: src/Module/Calendar/Event/Form.php:247
msgid "Finish date/time is not known or not relevant"
@ -6609,10 +5939,20 @@ msgstr[1] ""
msgid "Show all contacts"
msgstr ""
#: src/Module/Contact.php:317 src/Module/Contact.php:377
#: src/Module/Moderation/BaseUsers.php:85
msgid "Pending"
msgstr ""
#: src/Module/Contact.php:320
msgid "Only show pending contacts"
msgstr ""
#: src/Module/Contact.php:325 src/Module/Contact.php:378
#: src/Module/Moderation/BaseUsers.php:93
msgid "Blocked"
msgstr ""
#: src/Module/Contact.php:328
msgid "Only show blocked contacts"
msgstr ""
@ -6659,6 +5999,14 @@ msgstr ""
msgid "Update"
msgstr ""
#: src/Module/Contact.php:401 src/Module/Contact/Profile.php:349
#: src/Module/Contact/Profile.php:468
#: src/Module/Moderation/Blocklist/Contact.php:117
#: src/Module/Moderation/Users/Blocked.php:138
#: src/Module/Moderation/Users/Index.php:154
msgid "Unblock"
msgstr ""
#: src/Module/Contact.php:402 src/Module/Contact/Profile.php:350
#: src/Module/Contact/Profile.php:476
msgid "Unignore"
@ -6826,6 +6174,14 @@ msgstr ""
msgid "Your Identity Address:"
msgstr ""
#: src/Module/Contact/Follow.php:168 src/Module/Contact/Profile.php:366
#: src/Module/Contact/Unfollow.php:129
#: src/Module/Moderation/Blocklist/Contact.php:133
#: src/Module/Notifications/Introductions.php:129
#: src/Module/Notifications/Introductions.php:198
msgid "Profile URL"
msgstr ""
#: src/Module/Contact/Follow.php:169 src/Module/Contact/Profile.php:378
#: src/Module/Notifications/Introductions.php:191
#: src/Module/Profile/Profile.php:206
@ -7586,6 +6942,12 @@ msgstr ""
msgid "On this server the following remote servers are blocked."
msgstr ""
#: src/Module/Friendica.php:83
#: src/Module/Moderation/Blocklist/Server/Index.php:84
#: src/Module/Moderation/Blocklist/Server/Index.php:108
msgid "Reason for the block"
msgstr ""
#: src/Module/Friendica.php:85
msgid "Download this list in CSV format"
msgstr ""
@ -8036,6 +7398,701 @@ msgstr ""
msgid "A Decentralized Social Network"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:72
msgid "List of all users"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:77
msgid "Active"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:80
msgid "List of active accounts"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:88
msgid "List of pending registrations"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:96
msgid "List of blocked users"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:101
msgid "Deleted"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:104
msgid "List of pending user deletions"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:119 src/Module/Settings/Account.php:494
msgid "Normal Account Page"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:120 src/Module/Settings/Account.php:501
msgid "Soapbox Page"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:121 src/Module/Settings/Account.php:508
msgid "Public Forum"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:122 src/Module/Settings/Account.php:515
msgid "Automatic Friend Page"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:123
msgid "Private Forum"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:126 src/Module/Settings/Account.php:466
msgid "Personal Page"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:127 src/Module/Settings/Account.php:473
msgid "Organisation Page"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:128 src/Module/Settings/Account.php:480
msgid "News Page"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:129 src/Module/Settings/Account.php:487
msgid "Community Forum"
msgstr ""
#: src/Module/Moderation/BaseUsers.php:130
msgid "Relay"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:70
msgid "You can't block a local contact, please block the user instead"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:89
#, php-format
msgid "%s contact unblocked"
msgid_plural "%s contacts unblocked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Blocklist/Contact.php:111
msgid "Remote Contact Blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:112
msgid ""
"This page allows you to prevent any message from a remote contact to reach "
"your node."
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:113
msgid "Block Remote Contact"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:114
#: src/Module/Moderation/Users/Active.php:135
#: src/Module/Moderation/Users/Blocked.php:135
#: src/Module/Moderation/Users/Index.php:149
#: src/Module/Moderation/Users/Pending.php:98
msgid "select all"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:115
msgid "select none"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:118
msgid "No remote contact is blocked from this node."
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:120
msgid "Blocked Remote Contacts"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:121
msgid "Block New Remote Contact"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:122
msgid "Photo"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:122
msgid "Reason"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:130
#, php-format
msgid "%s total blocked contact"
msgid_plural "%s total blocked contacts"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Blocklist/Contact.php:133
msgid "URL of the remote contact to block."
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:134
msgid "Also purge contact"
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:134
msgid ""
"Removes all content related to this contact from the node. Keeps the contact "
"record. This action cannot be undone."
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:135
#: src/Module/Moderation/Blocklist/Server/Import.php:121
msgid "Block Reason"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:78
msgid "Server domain pattern added to the blocklist."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:86
#, php-format
msgid "%s server scheduled to be purged."
msgid_plural "%s servers scheduled to be purged."
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Blocklist/Server/Add.php:118
#: src/Module/Moderation/Blocklist/Server/Import.php:114
msgid "← Return to the list"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:120
msgid "Block A New Server Domain Pattern"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:121
#: src/Module/Moderation/Blocklist/Server/Index.php:96
msgid ""
"<p>The server domain pattern syntax is case-insensitive shell wildcard, "
"comprising the following special characters:</p>\n"
"<ul>\n"
"\t<li><code>*</code>: Any number of characters</li>\n"
"\t<li><code>?</code>: Any single character</li>\n"
"</ul>"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:126
#: src/Module/Moderation/Blocklist/Server/Index.php:104
msgid "Check pattern"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:127
msgid "Matching known servers"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:128
msgid "Server Name"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:129
msgid "Server Domain"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:130
msgid "Known Contacts"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:131
#, php-format
msgid "%d known server"
msgid_plural "%d known servers"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Blocklist/Server/Add.php:132
msgid "Add pattern to the blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:134
#: src/Module/Moderation/Blocklist/Server/Index.php:113
msgid "Server Domain Pattern"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:134
#: src/Module/Moderation/Blocklist/Server/Index.php:113
msgid ""
"The domain pattern of the new server to add to the blocklist. Do not include "
"the protocol."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:135
msgid "Purge server"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:135
msgid ""
"Also purges all the locally stored content authored by the known contacts "
"registered on that server. Keeps the contacts and the server records. This "
"action cannot be undone."
msgid_plural ""
"Also purges all the locally stored content authored by the known contacts "
"registered on these servers. Keeps the contacts and the servers records. "
"This action cannot be undone."
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Blocklist/Server/Add.php:136
msgid "Block reason"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Add.php:136
msgid ""
"The reason why you blocked this server domain pattern. This reason will be "
"shown publicly in the server information page."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:73
#: src/Module/Moderation/Blocklist/Server/Import.php:82
msgid "Error importing pattern file"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:88
msgid "Local blocklist replaced with the provided file."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:92
#, php-format
msgid "%d pattern was added to the local blocklist."
msgid_plural "%d patterns were added to the local blocklist."
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Blocklist/Server/Import.php:94
msgid "No pattern was added to the local blocklist."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:116
msgid "Import a Server Domain Pattern Blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:117
msgid ""
"<p>This file can be downloaded from the <code>/friendica</code> path of any "
"Friendica server.</p>"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:118
#: src/Module/Moderation/Blocklist/Server/Index.php:103
msgid "Upload file"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:119
msgid "Patterns to import"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:120
msgid "Domain Pattern"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:122
msgid "Import Mode"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:123
msgid "Import Patterns"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:124
#, php-format
msgid "%d total pattern"
msgid_plural "%d total patterns"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Blocklist/Server/Import.php:126
#: src/Module/Moderation/Blocklist/Server/Index.php:112
msgid "Server domain pattern blocklist CSV file"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:127
msgid "Append"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:127
msgid ""
"Imports patterns from the file that weren't already existing in the current "
"blocklist."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:128
msgid "Replace"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Import.php:128
msgid "Replaces the current blocklist by the imported patterns."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:83
#: src/Module/Moderation/Blocklist/Server/Index.php:107
msgid "Blocked server domain pattern"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:85
msgid "Delete server domain pattern"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:85
msgid "Check to delete this entry from the blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:93
msgid "Server Domain Pattern Blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:94
msgid ""
"This page can be used to define a blocklist of server domain patterns from "
"the federated network that are not allowed to interact with your node. For "
"each domain pattern you should also provide the reason why you block it."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:95
msgid ""
"The list of blocked server domain patterns will be made publically available "
"on the <a href=\"/friendica\">/friendica</a> page so that your users and "
"people investigating communication problems can find the reason easily."
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:101
msgid "Import server domain pattern blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:102
msgid "Add new entry to the blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:105
msgid "Save changes to the blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:106
msgid "Current Entries in the Blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:109
msgid "Delete entry from the blocklist"
msgstr ""
#: src/Module/Moderation/Blocklist/Server/Index.php:110
msgid "Delete entry from the blocklist?"
msgstr ""
#: src/Module/Moderation/Item/Delete.php:50
msgid "Item marked for deletion."
msgstr ""
#: src/Module/Moderation/Item/Delete.php:63
msgid "Delete this Item"
msgstr ""
#: src/Module/Moderation/Item/Delete.php:64
msgid ""
"On this page you can delete an item from your node. If the item is a top "
"level posting, the entire thread will be deleted."
msgstr ""
#: src/Module/Moderation/Item/Delete.php:65
msgid ""
"You need to know the GUID of the item. You can find it e.g. by looking at "
"the display URL. The last part of http://example.com/display/123456 is the "
"GUID, here 123456."
msgstr ""
#: src/Module/Moderation/Item/Delete.php:67
msgid "GUID"
msgstr ""
#: src/Module/Moderation/Item/Delete.php:67
msgid "The GUID of the item you want to delete."
msgstr ""
#: src/Module/Moderation/Item/Source.php:52
msgid "Item Guid"
msgstr ""
#: src/Module/Moderation/Item/Source.php:56
msgid "Item Id"
msgstr ""
#: src/Module/Moderation/Item/Source.php:57
msgid "Item URI"
msgstr ""
#: src/Module/Moderation/Item/Source.php:59
msgid "Terms"
msgstr ""
#: src/Module/Moderation/Item/Source.php:60
msgid "Tag"
msgstr ""
#: src/Module/Moderation/Item/Source.php:61
#: src/Module/Moderation/Users/Active.php:126
#: src/Module/Moderation/Users/Blocked.php:126
#: src/Module/Moderation/Users/Index.php:140
msgid "Type"
msgstr ""
#: src/Module/Moderation/Item/Source.php:62
msgid "Term"
msgstr ""
#: src/Module/Moderation/Item/Source.php:63
msgid "URL"
msgstr ""
#: src/Module/Moderation/Item/Source.php:64
msgid "Mention"
msgstr ""
#: src/Module/Moderation/Item/Source.php:65
msgid "Implicit Mention"
msgstr ""
#: src/Module/Moderation/Summary.php:53
msgid "Normal Account"
msgstr ""
#: src/Module/Moderation/Summary.php:54
msgid "Automatic Follower Account"
msgstr ""
#: src/Module/Moderation/Summary.php:55
msgid "Public Forum Account"
msgstr ""
#: src/Module/Moderation/Summary.php:56
msgid "Automatic Friend Account"
msgstr ""
#: src/Module/Moderation/Summary.php:57
msgid "Blog Account"
msgstr ""
#: src/Module/Moderation/Summary.php:58
msgid "Private Forum Account"
msgstr ""
#: src/Module/Moderation/Summary.php:78
msgid "Registered users"
msgstr ""
#: src/Module/Moderation/Summary.php:80
msgid "Pending registrations"
msgstr ""
#: src/Module/Moderation/Users/Active.php:43
#: src/Module/Moderation/Users/Index.php:43
#, php-format
msgid "%s user blocked"
msgid_plural "%s users blocked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Users/Active.php:51
#: src/Module/Moderation/Users/Active.php:85
#: src/Module/Moderation/Users/Blocked.php:51
#: src/Module/Moderation/Users/Blocked.php:85
#: src/Module/Moderation/Users/Index.php:58
#: src/Module/Moderation/Users/Index.php:92
msgid "You can't remove yourself"
msgstr ""
#: src/Module/Moderation/Users/Active.php:55
#: src/Module/Moderation/Users/Blocked.php:55
#: src/Module/Moderation/Users/Index.php:62
#, php-format
msgid "%s user deleted"
msgid_plural "%s users deleted"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Users/Active.php:83
#: src/Module/Moderation/Users/Blocked.php:83
#: src/Module/Moderation/Users/Index.php:90
#, php-format
msgid "User \"%s\" deleted"
msgstr ""
#: src/Module/Moderation/Users/Active.php:93
#: src/Module/Moderation/Users/Index.php:100
#, php-format
msgid "User \"%s\" blocked"
msgstr ""
#: src/Module/Moderation/Users/Active.php:126
#: src/Module/Moderation/Users/Blocked.php:126
#: src/Module/Moderation/Users/Deleted.php:83
#: src/Module/Moderation/Users/Index.php:140
#: src/Module/Moderation/Users/Index.php:160
msgid "Register date"
msgstr ""
#: src/Module/Moderation/Users/Active.php:126
#: src/Module/Moderation/Users/Blocked.php:126
#: src/Module/Moderation/Users/Deleted.php:83
#: src/Module/Moderation/Users/Index.php:140
#: src/Module/Moderation/Users/Index.php:160
msgid "Last login"
msgstr ""
#: src/Module/Moderation/Users/Active.php:126
#: src/Module/Moderation/Users/Blocked.php:126
#: src/Module/Moderation/Users/Deleted.php:83
#: src/Module/Moderation/Users/Index.php:140
#: src/Module/Moderation/Users/Index.php:160
msgid "Last public item"
msgstr ""
#: src/Module/Moderation/Users/Active.php:134
msgid "Active Accounts"
msgstr ""
#: src/Module/Moderation/Users/Active.php:138
#: src/Module/Moderation/Users/Blocked.php:137
#: src/Module/Moderation/Users/Index.php:153
msgid "User blocked"
msgstr ""
#: src/Module/Moderation/Users/Active.php:139
#: src/Module/Moderation/Users/Blocked.php:139
#: src/Module/Moderation/Users/Index.php:155
msgid "Site admin"
msgstr ""
#: src/Module/Moderation/Users/Active.php:140
#: src/Module/Moderation/Users/Blocked.php:140
#: src/Module/Moderation/Users/Index.php:156
msgid "Account expired"
msgstr ""
#: src/Module/Moderation/Users/Active.php:141
#: src/Module/Moderation/Users/Index.php:159
msgid "Create a new user"
msgstr ""
#: src/Module/Moderation/Users/Active.php:147
#: src/Module/Moderation/Users/Blocked.php:146
#: src/Module/Moderation/Users/Index.php:165
msgid ""
"Selected users will be deleted!\\n\\nEverything these users had posted on "
"this site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
#: src/Module/Moderation/Users/Active.php:148
#: src/Module/Moderation/Users/Blocked.php:147
#: src/Module/Moderation/Users/Index.php:166
msgid ""
"The user {0} will be deleted!\\n\\nEverything this user has posted on this "
"site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
#: src/Module/Moderation/Users/Blocked.php:43
#: src/Module/Moderation/Users/Index.php:50
#, php-format
msgid "%s user unblocked"
msgid_plural "%s users unblocked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Users/Blocked.php:92
#: src/Module/Moderation/Users/Index.php:106
#, php-format
msgid "User \"%s\" unblocked"
msgstr ""
#: src/Module/Moderation/Users/Blocked.php:134
msgid "Blocked Users"
msgstr ""
#: src/Module/Moderation/Users/Create.php:62
msgid "New User"
msgstr ""
#: src/Module/Moderation/Users/Create.php:63
msgid "Add User"
msgstr ""
#: src/Module/Moderation/Users/Create.php:71
msgid "Name of the new user."
msgstr ""
#: src/Module/Moderation/Users/Create.php:72
msgid "Nickname"
msgstr ""
#: src/Module/Moderation/Users/Create.php:72
msgid "Nickname of the new user."
msgstr ""
#: src/Module/Moderation/Users/Create.php:73
msgid "Email address of the new user."
msgstr ""
#: src/Module/Moderation/Users/Deleted.php:81
msgid "Users awaiting permanent deletion"
msgstr ""
#: src/Module/Moderation/Users/Deleted.php:83
#: src/Module/Moderation/Users/Index.php:160
msgid "Permanent deletion"
msgstr ""
#: src/Module/Moderation/Users/Index.php:150
msgid "User waiting for permanent deletion"
msgstr ""
#: src/Module/Moderation/Users/Pending.php:44
#, php-format
msgid "%s user approved"
msgid_plural "%s users approved"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Users/Pending.php:51
#, php-format
msgid "%s registration revoked"
msgid_plural "%s registrations revoked"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Moderation/Users/Pending.php:76
msgid "Account approved."
msgstr ""
#: src/Module/Moderation/Users/Pending.php:82
msgid "Registration revoked"
msgstr ""
#: src/Module/Moderation/Users/Pending.php:97
msgid "User registrations awaiting review"
msgstr ""
#: src/Module/Moderation/Users/Pending.php:99
msgid "Request date"
msgstr ""
#: src/Module/Moderation/Users/Pending.php:100
msgid "No registrations."
msgstr ""
#: src/Module/Moderation/Users/Pending.php:101
msgid "Note from the user"
msgstr ""
#: src/Module/Moderation/Users/Pending.php:103
msgid "Deny"
msgstr ""
#: src/Module/Notifications/Introductions.php:99
msgid "Show Ignored Requests"
msgstr ""

View file

@ -13,22 +13,6 @@
<dt>{{$queues.label}}</dt>
<dd><a href="{{$baseurl}}/admin/queue/deferred">{{$queues.deferred}}</a> - <a href="{{$baseurl}}/admin/queue">{{$queues.workerq}}</a></dd>
</dl>
<dl>
<dt>{{$pending.0}}</dt>
<dd>{{$pending.1}}</dt>
</dl>
<dl>
<dt>{{$users.0}}</dt>
<dd>{{$users.1}}</dd>
</dl>
{{foreach $accounts as $p}}
<dl>
<dt>{{$p.0}}</dt>
<dd>{{if $p.1}}{{$p.1}}{{else}}0{{/if}}</dd>
</dl>
{{/foreach}}
<dl>
<dt>{{$addons.0}}</dt>

View file

@ -0,0 +1,21 @@
<script>
// update pending count //
$(function(){
$("nav").bind('nav-update', function(e,data){
var elm = $('#pending-update');
var register = $(data).find('register').html();
if (register=="0") { register=""; elm.hide();} else { elm.show(); }
elm.html(register);
});
});
</script>
{{foreach $subpages as $page}}
<h4>{{$page.0}}</h4>
<ul class="admin linklist" role="menu">
{{foreach $page.1 as $item}}
<li class='admin link button {{$item.2}}' role="menuitem"><a href='{{$item.0}}'>{{$item.1}}</a></li>
{{/foreach}}
</ul>
{{/foreach}}

View file

@ -0,0 +1,9 @@
<script>
$(document).ready(function() {
$('.settings-content-block').hide();
$('.settings-heading').click(function(){
$('.settings-content-block').hide();
$(this).next('.settings-content-block').toggle();
});
});
</script>

View file

@ -0,0 +1,16 @@
<div id='adminpage'>
<h1>{{$title}} - {{$page}}</h1>
<dl>
<dt>{{$users.0}}</dt>
<dd>{{$users.1}}</dd>
</dl>
{{foreach $accounts as $p}}
<dl>
<dt>{{$p.0}}</dt>
<dd>{{if $p.1}}{{$p.1}}{{else}}0{{/if}}</dd>
</dl>
{{/foreach}}
</div>

View file

@ -22,6 +22,8 @@
{{if $nav.admin}}<a accesskey="a" id="nav-admin-link" class="nav-link {{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}">{{$nav.admin.1}}</a>{{/if}}
{{if $nav.moderation}}<a accesskey="m" id="nav-moderation-link" class="nav-link {{$nav.moderation.2}}" href="{{$nav.moderation.0}}" title="{{$nav.moderation.3}}">{{$nav.moderation.1}}</a>{{/if}}
{{if $nav.network}}
<a accesskey="n" id="nav-network-link" class="nav-commlink {{$nav.network.2}} {{$sel.network}}" href="{{$nav.network.0}}" title="{{$nav.network.3}}">{{$nav.network.1}}</a>
<span id="net-update" class="nav-ajax-left"></span>

View file

@ -22,6 +22,8 @@
{{if $nav.admin}}<a accesskey="a" id="nav-admin-link" class="nav-link {{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}">{{$nav.admin.1}}</a>{{/if}}
{{if $nav.moderation}}<a accesskey="m" id="nav-moderation-link" class="nav-link {{$nav.moderation.2}}" href="{{$nav.moderation.0}}" title="{{$nav.moderation.3}}">{{$nav.moderation.1}}</a>{{/if}}
{{if $nav.network}}
<a accesskey="n" id="nav-network-link" class="nav-commlink {{$nav.network.2}} {{$sel.network}}" href="{{$nav.network.0}}" title="{{$nav.network.3}}">{{$nav.network.1}}</a>
<span id="net-update" class="nav-ajax-left"></span>

View file

@ -17,29 +17,6 @@
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 admin-summary-entry"><a href="{{$baseurl}}/admin/queue/deferred">{{$queues.deferred}}</a> - <a href="{{$baseurl}}/admin/queue">{{$queues.workerq}}</a></div>
</div>
{{* Number of pending registrations. *}}
<div id="admin-summary-pending" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 admin-summary">
<hr class="admin-summary-separator">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 admin-summary-label-name text-muted">{{$pending.0}}</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 admin-summary-entry">{{$pending.1}}</div>
</div>
{{* Number of registered users *}}
<div id="admin-summary-users" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 admin-summary">
<hr class="admin-summary-separator">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 admin-summary-label-name text-muted">{{$users.0}}</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 admin-summary-entry">{{$users.1}}</div>
</div>
{{* Account types of registered users. *}}
{{foreach $accounts as $p}}
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 admin-summary">
<hr class="admin-summary-separator">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 admin-summary-label-name text-muted">{{$p.0}}</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 admin-summary-entry">{{if $p.1}}{{$p.1}}{{else}}0{{/if}}</div>
</div>
{{/foreach}}
{{* List enabled addons. *}}
<div id="admin-summary-addons" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 admin-summary">
<hr class="admin-summary-separator">

View file

@ -0,0 +1,30 @@
<script type="text/javascript">
// update pending count //
$(function(){
$("nav").bind('nav-update', function(e,data){
var elm = $('#pending-update');
var register = parseInt($(data).find('register').text());
if (register > 0) {
elm.html(register);
}
});
});
</script>
{{foreach $subpages as $page}}
<div class="widget">
<h3>{{$page.0}}</h3>
<ul role="menu">
{{foreach $page.1 as $item}}
<li role="menuitem" class="{{$item.2}}">
<a href="{{$item.0}}" {{if $item.accesskey}}accesskey="{{$item.accesskey}}"{{/if}}>
{{$item.1}}
{{if $name == "users"}}
<span id="pending-update" class="badge pull-right"></span>
{{/if}}
</a>
</li>
{{/foreach}}
</ul>
</div>
{{/foreach}}

View file

@ -0,0 +1,33 @@
<div id='adminpage-summery' class="adminpage generic-page-wrapper">
<h1>{{$title}} - {{$page}}</h1>
<div id="admin-summary-wrapper">
{{* Number of pending registrations. *}}
<div id="admin-summary-pending" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 admin-summary">
<hr class="admin-summary-separator">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 admin-summary-label-name text-muted">{{$pending.0}}</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 admin-summary-entry">{{$pending.1}}</div>
</div>
{{* Number of registered users *}}
<div id="admin-summary-users" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 admin-summary">
<hr class="admin-summary-separator">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 admin-summary-label-name text-muted">{{$users.0}}</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 admin-summary-entry">{{$users.1}}</div>
</div>
{{* Account types of registered users. *}}
{{foreach $accounts as $p}}
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 admin-summary">
<hr class="admin-summary-separator">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 admin-summary-label-name text-muted">{{$p.0}}</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 admin-summary-entry">{{if $p.1}}{{$p.1}}{{else}}0{{/if}}</div>
</div>
{{/foreach}}
</div>
<div class="clear"></div>
</div>

View file

@ -265,6 +265,15 @@
</a>
</li>
{{/if}}
{{if $nav.moderation}}
<li role="presentation">
<a accesskey="m" role="menuitem" id="nav-moderation-link"
class="nav-link {{$nav.moderation.2}}" href="{{$nav.moderation.0}}"
title="{{$nav.moderation.3}}"><i class="fa fa-user-secret fa-fw" aria-hidden="true"></i>
{{$nav.moderation.1}}
</a>
</li>
{{/if}}
{{if $nav.tos}}
<li role="presentation" class="divider"></li>
<li role="presentation">

View file

@ -75,6 +75,7 @@
{{if $nav.settings}}<li><a class="{{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}">{{$nav.settings.1}}</a></li>{{/if}}
{{if $nav.admin}}<li><a accesskey="a" class="{{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}">{{$nav.admin.1}}</a></li>{{/if}}
{{if $nav.moderation}}<li><a accesskey="m" class="{{$nav.moderation.2}}" href="{{$nav.moderation.0}}" title="{{$nav.moderation.3}}">{{$nav.moderation.1}}</a></li>{{/if}}
{{if $nav.logout}}<li><a class="menu-sep {{$nav.logout.2}}" href="{{$nav.logout.0}}" title="{{$nav.logout.3}}">{{$nav.logout.1}}</a></li>{{/if}}
{{if $nav.login}}<li><a class="{{$nav.login.2}}" href="{{$nav.login.0}}" title="{{$nav.login.3}}">{{$nav.login.1}}</a><li>{{/if}}

View file

@ -48,6 +48,7 @@
{{if $nav.delegation}}<li><a id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}}" href="{{$nav.delegation.0}}">{{$nav.delegation.1}}</a></li>{{/if}}
{{if $nav.admin}}<li><a id="nav-admin-link" class="nav-commlink {{$nav.admin.2}}" href="{{$nav.admin.0}}">{{$nav.admin.1}}</a></li>{{/if}}
{{if $nav.moderation}}<li><a id="nav-moderation-link" class="nav-commlink {{$nav.moderation.2}}" href="{{$nav.moderation.0}}">{{$nav.moderation.1}}</a></li>{{/if}}
{{if $nav.help}}<li><a id="nav-help-link" class="nav-link {{$nav.help.2}}" href="{{$nav.help.0}}">{{$nav.help.1}}</a></li>{{/if}}
{{if $nav.tos}}<li><a id="nav-tos-link" class="nav-link {{$nav.tos.2}}" href="{{$nav.tos.0}}">{{$nav.tos.1}}</a></li>{{/if}}

View file

@ -92,7 +92,12 @@
<a accesskey="a" class="{{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}">{{$nav.admin.1}}</a>
</li>
{{/if}}
{{if $nav.logout}}<li role="menuitem"><a class="menu-sep {{$nav.logout.2}}" href="{{$nav.logout.0}}" title="{{$nav.logout.3}}">{{$nav.logout.1}}</a></li>{{/if}}
{{if $nav.moderation}}
<li role="menuitem">
<a accesskey="m" class="{{$nav.moderation.2}}" href="{{$nav.moderation.0}}" title="{{$nav.moderation.3}}">{{$nav.moderation.1}}</a>
</li>
{{/if}}
{{if $nav.logout}}<li role="menuitem"><a class="menu-sep {{$nav.logout.2}}" href="{{$nav.logout.0}}" title="{{$nav.logout.3}}">{{$nav.logout.1}}</a></li>{{/if}}
</ul>
</li>
{{/if}}