diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 47b2f4bdaf..cd9fea3500 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -77,7 +77,7 @@ pipeline: when: matrix: PHP_MAJOR_VERSION: 7.4 - PHP_VERSION: 7.4.18 + PHP_VERSION: 7.4.33 repo: - friendica/friendica settings: diff --git a/bin/daemon.php b/bin/daemon.php index 7182cb8eca..e550aea891 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -76,8 +76,8 @@ DI::config()->reload(); if (empty(DI::config()->get('system', 'pidfile'))) { die(<< [ + + 'system' => [ 'pidfile' => '/path/to/daemon.pid', ], TXT @@ -247,5 +247,6 @@ while (true) { } function shutdown() { + posix_kill(posix_getpid(), SIGTERM); posix_kill(posix_getpid(), SIGHUP); } diff --git a/database.sql b/database.sql index eefd389840..42a6c1f2e6 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2023.03-rc (Giant Rhubarb) --- DB_UPDATE_VERSION 1517 +-- DB_UPDATE_VERSION 1518 -- ------------------------------------------ @@ -2849,7 +2849,9 @@ CREATE VIEW `account-view` AS SELECT `apcontact`.`statuses_count` AS `ap-statuses_count`, `gserver`.`site_name` AS `site_name`, `gserver`.`platform` AS `platform`, - `gserver`.`version` AS `version` + `gserver`.`version` AS `version`, + `gserver`.`blocked` AS `server-blocked`, + `gserver`.`failed` AS `server-failed` FROM `contact` LEFT JOIN `item-uri` ON `item-uri`.`id` = `contact`.`uri-id` LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `contact`.`uri-id` @@ -2953,7 +2955,9 @@ CREATE VIEW `account-user-view` AS SELECT `apcontact`.`statuses_count` AS `ap-statuses_count`, `gserver`.`site_name` AS `site_name`, `gserver`.`platform` AS `platform`, - `gserver`.`version` AS `version` + `gserver`.`version` AS `version`, + `gserver`.`blocked` AS `server-blocked`, + `gserver`.`failed` AS `server-failed` FROM `contact` AS `ucontact` INNER JOIN `contact` ON `contact`.`uri-id` = `ucontact`.`uri-id` AND `contact`.`uid` = 0 LEFT JOIN `item-uri` ON `item-uri`.`id` = `ucontact`.`uri-id` diff --git a/src/Core/Config/Capability/IManageConfigValues.php b/src/Core/Config/Capability/IManageConfigValues.php index 4f785d0077..18abdb6577 100644 --- a/src/Core/Config/Capability/IManageConfigValues.php +++ b/src/Core/Config/Capability/IManageConfigValues.php @@ -58,6 +58,16 @@ interface IManageConfigValues */ public function get(string $cat, string $key = null, $default_value = null); + /** + * Returns true, if the current config can be changed + * + * @param string $cat The category of the configuration value + * @param string $key The configuration key to query + * + * @return bool true, if writing is possible + */ + public function isWritable(string $cat, string $key): bool; + /** * Sets a configuration value for system config * diff --git a/src/Core/Config/Model/DatabaseConfig.php b/src/Core/Config/Model/DatabaseConfig.php index 7167ccbf8e..7b34eda975 100644 --- a/src/Core/Config/Model/DatabaseConfig.php +++ b/src/Core/Config/Model/DatabaseConfig.php @@ -80,6 +80,12 @@ class DatabaseConfig implements IManageConfigValues return $this->cache->get($cat, $key) ?? $default_value; } + /** {@inheritDoc} */ + public function isWritable(string $cat, string $key): bool + { + return $this->cache->getSource($cat, $key) < Cache::SOURCE_ENV; + } + /** {@inheritDoc} */ public function set(string $cat, string $key, $value): bool { diff --git a/src/Core/Config/Model/ReadOnlyFileConfig.php b/src/Core/Config/Model/ReadOnlyFileConfig.php index 4b32720f02..cc84a6c0d3 100644 --- a/src/Core/Config/Model/ReadOnlyFileConfig.php +++ b/src/Core/Config/Model/ReadOnlyFileConfig.php @@ -68,6 +68,12 @@ class ReadOnlyFileConfig implements IManageConfigValues return $this->configCache->get($cat, $key) ?? $default_value; } + /** {@inheritDoc} */ + public function isWritable(string $cat, string $key): bool + { + return $this->configCache->getSource($cat, $key) < Cache::SOURCE_ENV; + } + /** {@inheritDoc} */ public function set(string $cat, string $key, $value): bool { diff --git a/src/Core/Config/ValueObject/Cache.php b/src/Core/Config/ValueObject/Cache.php index acfac3ab9a..f80be18049 100644 --- a/src/Core/Config/ValueObject/Cache.php +++ b/src/Core/Config/ValueObject/Cache.php @@ -31,6 +31,15 @@ use ParagonIE\HiddenString\HiddenString; */ class Cache { + /** @var int[] A list of valid config source */ + const VALID_SOURCES = [ + self::SOURCE_STATIC, + self::SOURCE_FILE, + self::SOURCE_DATA, + self::SOURCE_ENV, + self::SOURCE_FIX, + ]; + /** @var int Indicates that the cache entry is a default value - Lowest Priority */ const SOURCE_STATIC = 0; /** @var int Indicates that the cache entry is set by file - Low Priority */ diff --git a/src/Core/Search.php b/src/Core/Search.php index 3c0ace3db5..7f05a3a947 100644 --- a/src/Core/Search.php +++ b/src/Core/Search.php @@ -79,7 +79,7 @@ class Search $user_data['url'] ?? '', $user_data['photo'] ?? '', $user_data['network'] ?? '', - $contactDetails['id'] ?? 0, + $contactDetails['cid'] ?? 0, $user_data['id'] ?? 0, $user_data['tags'] ?? '' ); @@ -146,7 +146,7 @@ class Search $profile['photo'] ?? '', Protocol::DFRN, $contactDetails['cid'] ?? 0, - 0, + $contactDetails['zid'] ?? 0, $profile['tags'] ?? '' ); @@ -171,7 +171,7 @@ class Search { Logger::info('Searching', ['search' => $search, 'type' => $type, 'start' => $start, 'itempage' => $itemPage]); - $contacts = Contact::searchByName($search, $type == self::TYPE_FORUM ? 'community' : ''); + $contacts = Contact::searchByName($search, $type == self::TYPE_FORUM ? 'community' : '', true); $resultList = new ResultList($start, $itemPage, count($contacts)); @@ -179,12 +179,12 @@ class Search $result = new ContactResult( $contact['name'], $contact['addr'], - $contact['addr'], + $contact['addr'] ?: $contact['url'], $contact['url'], $contact['photo'], $contact['network'], - $contact['cid'] ?? 0, - $contact['zid'] ?? 0, + 0, + $contact['pid'], $contact['keywords'] ); @@ -226,7 +226,7 @@ class Search // check if searching in the local global contact table is enabled if (DI::config()->get('system', 'poco_local_search')) { - $return = Contact::searchByName($search, $mode); + $return = Contact::searchByName($search, $mode, true); } else { $p = $page > 1 ? 'p=' . $page : ''; $curlResult = DI::httpClient()->get(self::getGlobalDirectory() . '/search/people?' . $p . '&q=' . urlencode($search), HttpClientAccept::JSON); diff --git a/src/Core/Session/Capability/IHandleUserSessions.php b/src/Core/Session/Capability/IHandleUserSessions.php index 507b9e0429..5734eafdf7 100644 --- a/src/Core/Session/Capability/IHandleUserSessions.php +++ b/src/Core/Session/Capability/IHandleUserSessions.php @@ -109,6 +109,8 @@ interface IHandleUserSessions extends IHandleSessions /** * Set the session variable that contains the contact IDs for the visitor's contact URL + * + * @param string $my_url */ - public function setVisitorsContacts(); + public function setVisitorsContacts(string $my_url); } diff --git a/src/Core/Session/Model/UserSession.php b/src/Core/Session/Model/UserSession.php index a544487bd2..8dfc3d8321 100644 --- a/src/Core/Session/Model/UserSession.php +++ b/src/Core/Session/Model/UserSession.php @@ -140,9 +140,9 @@ class UserSession implements IHandleUserSessions } /** {@inheritDoc} */ - public function setVisitorsContacts() + public function setVisitorsContacts(string $my_url) { - $this->session->set('remote', Contact::getVisitorByUrl($this->session->get('my_url'))); + $this->session->set('remote', Contact::getVisitorByUrl($my_url)); } /** {@inheritDoc} */ diff --git a/src/Factory/Api/Mastodon/Relationship.php b/src/Factory/Api/Mastodon/Relationship.php index f1ca4a1f9e..8ae72ae9b2 100644 --- a/src/Factory/Api/Mastodon/Relationship.php +++ b/src/Factory/Api/Mastodon/Relationship.php @@ -22,6 +22,7 @@ namespace Friendica\Factory\Api\Mastodon; use Exception; +use Friendica\Network\HTTPException; use Friendica\Object\Api\Mastodon\Relationship as RelationshipEntity; use Friendica\BaseFactory; use Friendica\Model\Contact; @@ -41,9 +42,15 @@ class Relationship extends BaseFactory $pcid = !empty($cdata['public']) ? $cdata['public'] : $contactId; $cid = !empty($cdata['user']) ? $cdata['user'] : $contactId; + $contact = Contact::getById($cid); + if (!$contact) { + $this->logger->warning('Target contact not found', ['contactId' => $contactId, 'uid' => $uid, 'pcid' => $pcid, 'cid' => $cid]); + throw new HTTPException\NotFoundException('Contact not found.'); + } + return new RelationshipEntity( $pcid, - Contact::getById($cid), + $contact, Contact\User::isBlocked($cid, $uid), Contact\User::isIgnored($cid, $uid) ); diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 8792273eef..cf1b528da8 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -3504,16 +3504,17 @@ class Contact /** * Search contact table by nick or name * - * @param string $search Name or nick - * @param string $mode Search mode (e.g. "community") - * @param int $uid User ID - * @param int $limit Maximum amount of returned values - * @param int $offset Limit offset + * @param string $search Name or nick + * @param string $mode Search mode (e.g. "community") + * @param bool $show_blocked Show users from blocked servers. Default is false + * @param int $uid User ID + * @param int $limit Maximum amount of returned values + * @param int $offset Limit offset * * @return array with search results * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function searchByName(string $search, string $mode = '', int $uid = 0, int $limit = 0, int $offset = 0): array + public static function searchByName(string $search, string $mode = '', bool $show_blocked = false, int $uid = 0, int $limit = 0, int $offset = 0): array { if (empty($search)) { return []; @@ -3529,7 +3530,18 @@ class Contact $networks[] = Protocol::OSTATUS; } - $condition = ['network' => $networks, 'failed' => false, 'deleted' => false, 'uid' => $uid]; + $condition = [ + 'network' => $networks, + 'server-failed' => false, + 'failed' => false, + 'deleted' => false, + 'unsearchable' => false, + 'uid' => $uid + ]; + + if (!$show_blocked) { + $condition['server-blocked'] = true; + } if ($uid == 0) { $condition['blocked'] = false; @@ -3553,10 +3565,9 @@ class Contact } $condition = DBA::mergeConditions($condition, - ["(NOT `unsearchable` OR `nurl` IN (SELECT `nurl` FROM `owner-view` WHERE `publish` OR `net-publish`)) - AND (`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)", $search, $search, $search]); + ["(`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)", $search, $search, $search]); - return self::selectToArray([], $condition, $params); + return DBA::selectToArray('account-user-view', [], $condition, $params); } /** diff --git a/src/Model/Profile.php b/src/Model/Profile.php index e2857947c0..e6c8e4822d 100644 --- a/src/Model/Profile.php +++ b/src/Model/Profile.php @@ -795,14 +795,16 @@ class Profile $visitor = Contact::getById($cid); // Authenticate the visitor. - $_SESSION['authenticated'] = 1; - $_SESSION['visitor_id'] = $visitor['id']; - $_SESSION['visitor_handle'] = $visitor['addr']; - $_SESSION['visitor_home'] = $visitor['url']; - $_SESSION['my_url'] = $visitor['url']; - $_SESSION['remote_comment'] = $visitor['subscribe']; + DI::userSession()->setMultiple([ + 'authenticated' => 1, + 'visitor_id' => $visitor['id'], + 'visitor_handle' => $visitor['addr'], + 'visitor_home' => $visitor['url'], + 'my_url' => $visitor['url'], + 'remote_comment' => $visitor['subscribe'], + ]); - DI::userSession()->setVisitorsContacts(); + DI::userSession()->setVisitorsContacts($visitor['url']); $a->setContactId($visitor['id']); diff --git a/src/Module/Admin/Logs/Settings.php b/src/Module/Admin/Logs/Settings.php index 91b2938710..54f929f090 100644 --- a/src/Module/Admin/Logs/Settings.php +++ b/src/Module/Admin/Logs/Settings.php @@ -48,9 +48,15 @@ class Settings extends BaseAdmin return; } - DI::config()->set('system', 'logfile', $logfile); - DI::config()->set('system', 'debugging', $debugging); - DI::config()->set('system', 'loglevel', $loglevel); + if (DI::config()->isWritable('system', 'logfile')) { + DI::config()->set('system', 'logfile', $logfile); + } + if (DI::config()->isWritable('system', 'debugging')) { + DI::config()->set('system', 'debugging', $debugging); + } + if (DI::config()->isWritable('system', 'loglevel')) { + DI::config()->set('system', 'loglevel', $loglevel); + } DI::baseUrl()->redirect('admin/logs'); } @@ -82,9 +88,9 @@ class Settings extends BaseAdmin '$clear' => DI::l10n()->t('Clear'), '$logname' => DI::config()->get('system', 'logfile'), // see /help/smarty3-templates#1_1 on any Friendica node - '$debugging' => ['debugging', DI::l10n()->t("Enable Debugging"), DI::config()->get('system', 'debugging'), ""], - '$logfile' => ['logfile', DI::l10n()->t("Log file"), DI::config()->get('system', 'logfile'), DI::l10n()->t("Must be writable by web server. Relative to your Friendica top-level directory.")], - '$loglevel' => ['loglevel', DI::l10n()->t("Log level"), DI::config()->get('system', 'loglevel'), "", $log_choices], + '$debugging' => ['debugging', DI::l10n()->t('Enable Debugging'), DI::config()->get('system', 'debugging'), !DI::config()->isWritable('system', 'debugging') ? DI::l10n()->t('Read-only because it is set by an environment variable') : '', !DI::config()->isWritable('system', 'debugging') ? 'disabled' : ''], + '$logfile' => ['logfile', DI::l10n()->t('Log file'), DI::config()->get('system', 'logfile'), DI::l10n()->t('Must be writable by web server. Relative to your Friendica top-level directory.') . (!DI::config()->isWritable('system', 'logfile') ? '
' . DI::l10n()->t('Read-only because it is set by an environment variable') : ''), '', !DI::config()->isWritable('system', 'logfile') ? 'disabled' : ''], + '$loglevel' => ['loglevel', DI::l10n()->t("Log level"), DI::config()->get('system', 'loglevel'), !DI::config()->isWritable('system', 'loglevel') ? DI::l10n()->t('Read-only because it is set by an environment variable') : '', $log_choices, !DI::config()->isWritable('system', 'loglevel') ? 'disabled' : ''], '$form_security_token' => self::getFormSecurityToken("admin_logs"), '$phpheader' => DI::l10n()->t("PHP logging"), '$phphint' => DI::l10n()->t("To temporarily enable logging of PHP errors and warnings you can prepend the following to the index.php file of your installation. The filename set in the 'error_log' line is relative to the friendica top-level directory and must be writeable by the web server. The option '1' for 'log_errors' and 'display_errors' is to enable these options, set to '0' to disable them."), diff --git a/src/Module/Admin/Site.php b/src/Module/Admin/Site.php index c867c04c97..4f5a35ab71 100644 --- a/src/Module/Admin/Site.php +++ b/src/Module/Admin/Site.php @@ -165,7 +165,9 @@ class Site extends BaseAdmin $transactionConfig->set('system', 'poco_discovery' , $poco_discovery); $transactionConfig->set('system', 'poco_local_search' , $poco_local_search); $transactionConfig->set('system', 'nodeinfo' , $nodeinfo); - $transactionConfig->set('config', 'sitename' , $sitename); + if (DI::config()->isWritable('config', 'sitename')) { + $transactionConfig->set('config', 'sitename', $sitename); + } $transactionConfig->set('config', 'sender_email' , $sender_email); $transactionConfig->set('system', 'suppress_tags' , $suppress_tags); $transactionConfig->set('system', 'shortcut_icon' , $shortcut_icon); @@ -188,7 +190,9 @@ class Site extends BaseAdmin } else { $transactionConfig->set('config', 'info', $additional_info); } - $transactionConfig->set('system', 'language', $language); + if (DI::config()->isWritable('system', 'language')) { + $transactionConfig->set('system', 'language', $language); + } $transactionConfig->set('system', 'theme', $theme); Theme::install($theme); @@ -413,7 +417,7 @@ class Site extends BaseAdmin '$relocate_cmd' => DI::l10n()->t('(Friendica directory)# bin/console relocate https://newdomain.com'), // name, label, value, help string, extra data... - '$sitename' => ['sitename', DI::l10n()->t('Site name'), DI::config()->get('config', 'sitename'), ''], + '$sitename' => ['sitename', DI::l10n()->t('Site name'), DI::config()->get('config', 'sitename'), !DI::config()->isWritable('config', 'sitename') ? DI::l10n()->t('Read-only because it is set by an environment variable') : '', '', !DI::config()->isWritable('config', 'sitename') ? 'disabled' : ''], '$sender_email' => ['sender_email', DI::l10n()->t('Sender Email'), DI::config()->get('config', 'sender_email'), DI::l10n()->t('The email address your server shall use to send notification emails from.'), '', '', 'email'], '$system_actor_name' => ['system_actor_name', DI::l10n()->t('Name of the system actor'), User::getActorName(), DI::l10n()->t("Name of the internal system account that is used to perform ActivityPub requests. This must be an unused username. If set, this can't be changed again.")], '$banner' => ['banner', DI::l10n()->t('Banner/Logo'), $banner, ''], @@ -421,7 +425,7 @@ class Site extends BaseAdmin '$shortcut_icon' => ['shortcut_icon', DI::l10n()->t('Shortcut icon'), DI::config()->get('system', 'shortcut_icon'), DI::l10n()->t('Link to an icon that will be used for browsers.')], '$touch_icon' => ['touch_icon', DI::l10n()->t('Touch icon'), DI::config()->get('system', 'touch_icon'), DI::l10n()->t('Link to an icon that will be used for tablets and mobiles.')], '$additional_info' => ['additional_info', DI::l10n()->t('Additional Info'), $additional_info, DI::l10n()->t('For public servers: you can add additional information here that will be listed at %s/servers.', Search::getGlobalDirectory())], - '$language' => ['language', DI::l10n()->t('System language'), DI::config()->get('system', 'language'), '', $lang_choices], + '$language' => ['language', DI::l10n()->t('System language'), DI::config()->get('system', 'language'), !DI::config()->isWritable('system', 'language') ? DI::l10n()->t("Read-only because it is set by an environment variable") : '', $lang_choices, !DI::config()->isWritable('system', 'language') ? 'disabled' : ''], '$theme' => ['theme', DI::l10n()->t('System theme'), DI::config()->get('system', 'theme'), DI::l10n()->t('Default system theme - may be over-ridden by user profiles - Change default theme settings', DI::baseUrl() . '/admin/themes'), $theme_choices], '$theme_mobile' => ['theme_mobile', DI::l10n()->t('Mobile system theme'), DI::config()->get('system', 'mobile-theme', '---'), DI::l10n()->t('Theme for mobile devices'), $theme_choices_mobile], '$force_ssl' => ['force_ssl', DI::l10n()->t('Force SSL'), DI::config()->get('system', 'force_ssl'), DI::l10n()->t('Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.')], diff --git a/src/Module/Admin/Storage.php b/src/Module/Admin/Storage.php index e31d7db390..434b43b32e 100644 --- a/src/Module/Admin/Storage.php +++ b/src/Module/Admin/Storage.php @@ -76,7 +76,7 @@ class Storage extends BaseAdmin } } - if (!empty($_POST['submit_save_set'])) { + if (!empty($_POST['submit_save_set']) && DI::config()->isWritable('storage', 'name') ) { try { $newstorage = DI::storageManager()->getWritableStorageByName($storagebackend); @@ -145,6 +145,8 @@ class Storage extends BaseAdmin '$save_reload' => DI::l10n()->t('Save & Reload'), '$noconfig' => DI::l10n()->t('This backend doesn\'t have custom settings'), '$form_security_token' => self::getFormSecurityToken("admin_storage"), + '$storagebackend_ro_txt' => !DI::config()->isWritable('storage', 'name') ? DI::l10n()->t('Changing the current backend is prohibited because it is set by an environment variable') : '', + '$is_writable' => DI::config()->isWritable('storage', 'name'), '$storagebackend' => $current_storage_backend instanceof ICanWriteToStorage ? $current_storage_backend::getName() : DI::l10n()->t('Database (legacy)'), '$availablestorageforms' => $available_storage_forms, ]); diff --git a/src/Module/Api/Mastodon/Accounts/Search.php b/src/Module/Api/Mastodon/Accounts/Search.php index 5a03cba196..5276161640 100644 --- a/src/Module/Api/Mastodon/Accounts/Search.php +++ b/src/Module/Api/Mastodon/Accounts/Search.php @@ -60,7 +60,7 @@ class Search extends BaseApi } if (empty($accounts)) { - $contacts = Contact::searchByName($request['q'], '', $request['following'] ? $uid : 0, $request['limit'], $request['offset']); + $contacts = Contact::searchByName($request['q'], '', false, $request['following'] ? $uid : 0, $request['limit'], $request['offset']); foreach ($contacts as $contact) { $accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid); } diff --git a/src/Module/Api/Mastodon/Search.php b/src/Module/Api/Mastodon/Search.php index 69e2627682..956e3d73b8 100644 --- a/src/Module/Api/Mastodon/Search.php +++ b/src/Module/Api/Mastodon/Search.php @@ -115,7 +115,7 @@ class Search extends BaseApi } $accounts = []; - foreach (Contact::searchByName($q, '', $following ? $uid : 0, $limit, $offset) as $contact) { + foreach (Contact::searchByName($q, '', $following ? $uid : 0, false, $limit, $offset) as $contact) { $accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid); } diff --git a/src/Module/Api/Mastodon/Statuses.php b/src/Module/Api/Mastodon/Statuses.php index f8f46a8956..a232112de8 100644 --- a/src/Module/Api/Mastodon/Statuses.php +++ b/src/Module/Api/Mastodon/Statuses.php @@ -71,7 +71,7 @@ class Statuses extends BaseApi 'origin' => true, ]; - $post = Post::selectFirst(['uri-id', 'id', 'gravity', 'uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'network'], $condition); + $post = Post::selectFirst(['uri-id', 'id', 'gravity', 'verb', 'uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'network'], $condition); if (empty($post['id'])) { throw new HTTPException\NotFoundException('Item with URI ID ' . $this->parameters['id'] . ' not found for user ' . $uid . '.'); } @@ -87,6 +87,8 @@ class Statuses extends BaseApi $item['uid'] = $post['uid']; $item['body'] = $body; $item['network'] = $post['network']; + $item['gravity'] = $post['gravity']; + $item['verb'] = $post['verb']; $item['app'] = $this->getApp(); if (!empty($request['language'])) { @@ -108,7 +110,7 @@ class Statuses extends BaseApi } } - $item = DI::contentItem()->expandTags($item, $request['visibility'] == 'direct'); + $item = DI::contentItem()->expandTags($item); /* The provided ids in the request value consists of these two sources: diff --git a/src/Module/Contact/Follow.php b/src/Module/Contact/Follow.php index 57e9ff634a..0199aca78f 100644 --- a/src/Module/Contact/Follow.php +++ b/src/Module/Contact/Follow.php @@ -40,6 +40,7 @@ use Friendica\Network\HTTPException\ForbiddenException; use Friendica\Network\Probe; use Friendica\Util\Profiler; use Friendica\Util\Strings; +use GuzzleHttp\Psr7\Uri; use Psr\Log\LoggerInterface; class Follow extends BaseModule @@ -223,17 +224,26 @@ class Follow extends BaseModule protected function followRemoteItem(string $url) { - $itemId = Item::fetchByLink($url, $this->session->getLocalUserId()); - if (!$itemId) { - // If the user-specific search failed, we search and probe a public post - $itemId = Item::fetchByLink($url); - } - - if (!empty($itemId)) { - $item = Post::selectFirst(['guid'], ['id' => $itemId]); - if (!empty($item['guid'])) { - $this->baseUrl->redirect('display/' . $item['guid']); + try { + $uri = new Uri($url); + if (!$uri->getScheme()) { + return; } + + $itemId = Item::fetchByLink($url, $this->session->getLocalUserId()); + if (!$itemId) { + // If the user-specific search failed, we search and probe a public post + $itemId = Item::fetchByLink($url); + } + + if (!empty($itemId)) { + $item = Post::selectFirst(['guid'], ['id' => $itemId]); + if (!empty($item['guid'])) { + $this->baseUrl->redirect('display/' . $item['guid']); + } + } + } catch (\InvalidArgumentException $e) { + return; } } } diff --git a/src/Module/Profile/Contacts.php b/src/Module/Profile/Contacts.php index dde138d8cc..3942ac5d80 100644 --- a/src/Module/Profile/Contacts.php +++ b/src/Module/Profile/Contacts.php @@ -121,11 +121,14 @@ class Contacts extends Module\BaseProfile ['uri-id' => $contact['uri-id'], 'uid' => [0, $this->userSession->getLocalUserId()]], ['order' => ['uid' => 'DESC']] ); - return Module\Contact::getContactTemplateVars($contact); + return $contact ? Module\Contact::getContactTemplateVars($contact) : null; }, Model\Contact::selectToArray(['uri-id'], $condition, $params) ); + // Remove nonexistent contacts + $contacts = array_filter($contacts); + $desc = ''; switch ($type) { case 'followers': diff --git a/src/Object/Api/Mastodon/Relationship.php b/src/Object/Api/Mastodon/Relationship.php index 42d0e73119..c042e81b5e 100644 --- a/src/Object/Api/Mastodon/Relationship.php +++ b/src/Object/Api/Mastodon/Relationship.php @@ -77,7 +77,7 @@ class Relationship extends BaseDataTransferObject * @param bool $blocked "true" if user is blocked * @param bool $muted "true" if user is muted */ - public function __construct(int $contactId, array $contactRecord = [], bool $blocked = false, bool $muted = false) + public function __construct(int $contactId, array $contactRecord, bool $blocked = false, bool $muted = false) { $this->id = (string)$contactId; $this->following = false; diff --git a/src/Protocol/ActivityPub/ClientToServer.php b/src/Protocol/ActivityPub/ClientToServer.php index 7c0919f636..48a5cfdec5 100644 --- a/src/Protocol/ActivityPub/ClientToServer.php +++ b/src/Protocol/ActivityPub/ClientToServer.php @@ -264,7 +264,7 @@ class ClientToServer $item['contact-id'] = $owner['id']; $item['author-id'] = $item['owner-id'] = Contact::getPublicIdByUserId($uid); $item['title'] = $object_data['name']; - $item['body'] = Markdown::toBBCode($object_data['content']); + $item['body'] = Markdown::toBBCode($object_data['content'] ?? ''); $item['app'] = $application['name'] ?? 'API'; if (!empty($object_data['target'][Receiver::TARGET_GLOBAL])) { @@ -354,6 +354,10 @@ class ClientToServer $apcontact = APContact::getByURL($owner['url']); + if (empty($apcontact)) { + throw new \Friendica\Network\HTTPException\NotFoundException(); + } + return self::getCollection($condition, DI::baseUrl() . '/outbox/' . $owner['nickname'], $page, $max_id, $uid, $apcontact['statuses_count']); } diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index d6dc834fc0..1963d7e057 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1278,8 +1278,10 @@ class Processor $name = Receiver::PUBLIC_COLLECTION; } elseif ($path = parse_url($receiver, PHP_URL_PATH)) { $name = trim($path, '/'); + } elseif ($host = parse_url($receiver, PHP_URL_HOST)) { + $name = $host; } else { - Logger::warning('Unable to coerce name from receiver', ['receiver' => $receiver]); + Logger::warning('Unable to coerce name from receiver', ['element' => $element, 'type' => $type, 'receiver' => $receiver]); $name = ''; } diff --git a/src/Security/Authentication.php b/src/Security/Authentication.php index 4db5fdfed5..91963ee399 100644 --- a/src/Security/Authentication.php +++ b/src/Security/Authentication.php @@ -323,19 +323,21 @@ class Authentication */ public function setForUser(App $a, array $user_record, bool $login_initial = false, bool $interactive = false, bool $login_refresh = false) { + $my_url = $this->baseUrl . '/profile/' . $user_record['nickname']; + $this->session->setMultiple([ 'uid' => $user_record['uid'], 'theme' => $user_record['theme'], 'mobile-theme' => $this->pConfig->get($user_record['uid'], 'system', 'mobile_theme'), 'authenticated' => 1, 'page_flags' => $user_record['page-flags'], - 'my_url' => $this->baseUrl . '/profile/' . $user_record['nickname'], + 'my_url' => $my_url, 'my_address' => $user_record['nickname'] . '@' . substr($this->baseUrl, strpos($this->baseUrl, '://') + 3), 'addr' => $this->remoteAddress, 'nickname' => $user_record['nickname'], ]); - $this->session->setVisitorsContacts(); + $this->session->setVisitorsContacts($my_url); $member_since = strtotime($user_record['register_date']); $this->session->set('new_member', time() < ($member_since + (60 * 60 * 24 * 14))); diff --git a/src/Worker/ExpireAndRemoveUsers.php b/src/Worker/ExpireAndRemoveUsers.php index a0c29fa68c..f29934596a 100644 --- a/src/Worker/ExpireAndRemoveUsers.php +++ b/src/Worker/ExpireAndRemoveUsers.php @@ -21,8 +21,10 @@ namespace Friendica\Worker; +use Friendica\Core\Logger; use Friendica\Database\DBA; use Friendica\Database\DBStructure; +use Friendica\Model\Contact; use Friendica\Model\Photo; use Friendica\Model\User; use Friendica\Util\DateTimeFormat; @@ -55,29 +57,97 @@ class ExpireAndRemoveUsers // delete user records for recently removed accounts $users = DBA::select('user', ['uid'], ["`account_removed` AND `account_expires_on` < ? AND `uid` != ?", DateTimeFormat::utcNow(), 0]); while ($user = DBA::fetch($users)) { + $pcid = Contact::getPublicIdByUserId($user['uid']); + + Logger::info('Removing user - start', ['uid' => $user['uid'], 'pcid' => $pcid]); // We have to delete photo entries by hand because otherwise the photo data won't be deleted - Photo::delete(['uid' => $user['uid']]); + $result = Photo::delete(['uid' => $user['uid']]); + if ($result) { + Logger::debug('Deleted user photos', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting user photos', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } + + if (!empty($pcid)) { + $result = DBA::delete('post-tag', ['cid' => $pcid]); + if ($result) { + Logger::debug('Deleted post-tag entries', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting post-tag entries', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } + + $tables = ['post', 'post-user', 'post-thread', 'post-thread-user']; + + if (DBStructure::existsTable('item')) { + $tables[] = 'item'; + } + + // Delete all entries with the public contact in post related tables + foreach ($tables as $table) { + foreach (['owner-id', 'author-id', 'causer-id'] as $field) { + $result = DBA::delete($table, [$field => $pcid]); + if ($result) { + Logger::debug('Deleted entries', ['table' => $table, 'field' => $field, 'result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting entries', ['table' => $table, 'field' => $field, 'errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } + } + } + } // Delete the contacts of this user $self = DBA::selectFirst('contact', ['nurl'], ['self' => true, 'uid' => $user['uid']]); if (DBA::isResult($self)) { - DBA::delete('contact', ['nurl' => $self['nurl'], 'self' => false]); + $result = DBA::delete('contact', ['nurl' => $self['nurl'], 'self' => false]); + if ($result) { + Logger::debug('Deleted the user contact for other users', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting the user contact for other users', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } } // Delete all contacts of this user - DBA::delete('contact', ['uid' => $user['uid']]); + $result = DBA::delete('contact', ['uid' => $user['uid']]); + if ($result) { + Logger::debug('Deleted user contacts', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting user contacts', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } // These tables contain the permissionset which will also be deleted when a user is deleted. // It seems that sometimes the system wants to delete the records in the wrong order. // So when the permissionset is deleted and these tables are still filled then an error is thrown. // So we now delete them before all other user related entries are deleted. if (DBStructure::existsTable('item')) { - DBA::delete('item', ['uid' => $user['uid']]); + $result = DBA::delete('item', ['uid' => $user['uid']]); + if ($result) { + Logger::debug('Deleted user items', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting user items', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } + } + $result = DBA::delete('post-user', ['uid' => $user['uid']]); + if ($result) { + Logger::debug('Deleted post-user entries', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting post-user entries', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); } - DBA::delete('post-user', ['uid' => $user['uid']]); - DBA::delete('profile_field', ['uid' => $user['uid']]); - DBA::delete('user', ['uid' => $user['uid']]); + $result = DBA::delete('profile_field', ['uid' => $user['uid']]); + if ($result) { + Logger::debug('Deleted profile_field entries', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting profile_field entries', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } + + $result = DBA::delete('user', ['uid' => $user['uid']]); + if ($result) { + Logger::debug('Deleted user record', ['result' => $result, 'rows' => DBA::affectedRows()]); + } else { + Logger::warning('Error deleting user record', ['errno' => DBA::errorNo(), 'errmsg' => DBA::errorMessage()]); + } + + Logger::info('Removing user - done', ['uid' => $user['uid']]); } DBA::close($users); } diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 9acfbfcf98..ffb66d9701 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1517); + define('DB_UPDATE_VERSION', 1518); } return [ diff --git a/static/dbview.config.php b/static/dbview.config.php index 0f2201953b..76278c9a24 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -1009,6 +1009,8 @@ "site_name" => ["gserver", "site_name"], "platform" => ["gserver", "platform"], "version" => ["gserver", "version"], + "server-blocked" => ["gserver", "blocked"], + "server-failed" => ["gserver", "failed"], ], "query" => "FROM `contact` LEFT JOIN `item-uri` ON `item-uri`.`id` = `contact`.`uri-id` @@ -1111,6 +1113,8 @@ "site_name" => ["gserver", "site_name"], "platform" => ["gserver", "platform"], "version" => ["gserver", "version"], + "server-blocked" => ["gserver", "blocked"], + "server-failed" => ["gserver", "failed"], ], "query" => "FROM `contact` AS `ucontact` INNER JOIN `contact` ON `contact`.`uri-id` = `ucontact`.`uri-id` AND `contact`.`uid` = 0 diff --git a/tests/Util/VFSTrait.php b/tests/Util/VFSTrait.php index 86b7c167ce..4c31a5e64e 100644 --- a/tests/Util/VFSTrait.php +++ b/tests/Util/VFSTrait.php @@ -65,7 +65,7 @@ trait VFSTrait * @param string $sourceFilePath The filename of the config file * @param bool $static True, if the folder `static` instead of `config` should be used */ - protected function setConfigFile(string $sourceFilePath, bool $static = false, string $targetFileName = null) + public function setConfigFile(string $sourceFilePath, bool $static = false, string $targetFileName = null) { $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . diff --git a/tests/src/Core/Config/ConfigTest.php b/tests/src/Core/Config/ConfigTest.php index b526fc13b5..99c2141b8a 100644 --- a/tests/src/Core/Config/ConfigTest.php +++ b/tests/src/Core/Config/ConfigTest.php @@ -566,4 +566,74 @@ class ConfigTest extends DatabaseTest $config->set('test', 'it', $value); self:self::assertEquals($assertion, $config->get('test', 'it')); } + + public function dataEnv(): array + { + $data = [ + 'config' => [ + 'admin_email' => 'value1', + 'timezone' => 'value2', + 'language' => 'value3', + 'sitename' => 'value', + ], + 'system' => [ + 'url' => 'value1a', + 'debugging' => true, + 'logfile' => 'value4', + 'loglevel' => 'notice', + 'proflier' => true, + ], + 'proxy' => [ + 'trusted_proxies' => 'value5', + ], + ]; + + return [ + 'empty' => [ + 'data' => $data, + 'server' => [], + 'assertDisabled' => [], + ], + 'mixed' => [ + 'data' => $data, + 'server' => [ + 'FRIENDICA_ADMIN_MAIL' => 'test@friendica.local', + 'FRIENDICA_DEBUGGING' => true, + ], + 'assertDisabled' => [ + 'config' => [ + 'admin_email' => true, + ], + 'system' => [ + 'debugging' => true, + ], + ], + ], + ]; + } + + /** + * Tests if environment variables can change the permission to write a config key + * + * @dataProvider dataEnv + */ + public function testIsWritable(array $data, array $server, array $assertDisabled) + { + $this->setConfigFile('static' . DIRECTORY_SEPARATOR . 'env.config.php', true); + $this->loadDirectFixture($this->configToDbArray($data), $this->getDbInstance()); + + $configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/', $server); + $configFileManager->setupCache($this->configCache); + $config = new DatabaseConfig($this->getDbInstance(), $this->configCache); + + foreach ($data as $category => $keyvalues) { + foreach ($keyvalues as $key => $value) { + if (empty($assertDisabled[$category][$key])) { + static::assertTrue($config->isWritable($category, $key), sprintf('%s.%s is not true', $category, $key)); + } else { + static::assertFalse($config->isWritable($category, $key), sprintf('%s.%s is not false', $category, $key)); + } + } + } + } } diff --git a/update.php b/update.php index 8dcd1b71dd..3cd0a45a7b 100644 --- a/update.php +++ b/update.php @@ -1315,3 +1315,14 @@ function update_1516() return Update::SUCCESS; } + +function update_1518() +{ + $users = DBA::select('user', ['uid']); + while ($user = DBA::fetch($users)) { + Contact::updateSelfFromUserID($user['uid']); + } + DBA::close($users); + + return Update::SUCCESS; +} diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index e7434b0aee..d4641d5647 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.03-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-24 08:56+0100\n" +"POT-Creation-Date: 2023-03-28 17:42+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1546,7 +1546,7 @@ msgstr "" msgid "show more" msgstr "" -#: src/Content/Item.php:326 src/Model/Item.php:2904 +#: src/Content/Item.php:326 src/Model/Item.php:2906 msgid "event" msgstr "" @@ -1554,7 +1554,7 @@ msgstr "" msgid "status" msgstr "" -#: src/Content/Item.php:335 src/Model/Item.php:2906 +#: src/Content/Item.php:335 src/Model/Item.php:2908 #: src/Module/Post/Tag/Add.php:123 msgid "photo" msgstr "" @@ -1960,8 +1960,8 @@ msgid "" "%2$s %3$s" msgstr "" -#: src/Content/Text/BBCode.php:955 src/Model/Item.php:3585 -#: src/Model/Item.php:3591 src/Model/Item.php:3592 +#: src/Content/Text/BBCode.php:955 src/Model/Item.php:3587 +#: src/Model/Item.php:3593 src/Model/Item.php:3594 msgid "Link to source" msgstr "" @@ -3130,81 +3130,81 @@ msgstr "" msgid "Edit groups" msgstr "" -#: src/Model/Item.php:2005 +#: src/Model/Item.php:2007 #, php-format msgid "Detected languages in this post:\\n%s" msgstr "" -#: src/Model/Item.php:2908 +#: src/Model/Item.php:2910 msgid "activity" msgstr "" -#: src/Model/Item.php:2910 +#: src/Model/Item.php:2912 msgid "comment" msgstr "" -#: src/Model/Item.php:2913 src/Module/Post/Tag/Add.php:123 +#: src/Model/Item.php:2915 src/Module/Post/Tag/Add.php:123 msgid "post" msgstr "" -#: src/Model/Item.php:3071 -#, php-format -msgid "%s is blocked" -msgstr "" - #: src/Model/Item.php:3073 #, php-format -msgid "%s is ignored" +msgid "%s is blocked" msgstr "" #: src/Model/Item.php:3075 #, php-format +msgid "%s is ignored" +msgstr "" + +#: src/Model/Item.php:3077 +#, php-format msgid "Content from %s is collapsed" msgstr "" -#: src/Model/Item.php:3079 +#: src/Model/Item.php:3081 #, php-format msgid "Content warning: %s" msgstr "" -#: src/Model/Item.php:3497 +#: src/Model/Item.php:3499 msgid "bytes" msgstr "" -#: src/Model/Item.php:3528 +#: src/Model/Item.php:3530 #, php-format msgid "%2$s (%3$d%%, %1$d vote)" msgid_plural "%2$s (%3$d%%, %1$d votes)" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3530 +#: src/Model/Item.php:3532 #, php-format msgid "%2$s (%1$d vote)" msgid_plural "%2$s (%1$d votes)" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3535 +#: src/Model/Item.php:3537 #, php-format msgid "%d voter. Poll end: %s" msgid_plural "%d voters. Poll end: %s" msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3537 +#: src/Model/Item.php:3539 #, php-format msgid "%d voter." msgid_plural "%d voters." msgstr[0] "" msgstr[1] "" -#: src/Model/Item.php:3539 +#: src/Model/Item.php:3541 #, php-format msgid "Poll end: %s" msgstr "" -#: src/Model/Item.php:3573 src/Model/Item.php:3574 +#: src/Model/Item.php:3575 src/Model/Item.php:3576 msgid "View on separate page" msgstr "" @@ -3644,9 +3644,9 @@ msgid "Enable" msgstr "" #: src/Module/Admin/Addons/Details.php:111 src/Module/Admin/Addons/Index.php:67 -#: src/Module/Admin/Federation.php:209 src/Module/Admin/Logs/Settings.php:79 +#: src/Module/Admin/Federation.php:209 src/Module/Admin/Logs/Settings.php:85 #: src/Module/Admin/Logs/View.php:83 src/Module/Admin/Queue.php:72 -#: src/Module/Admin/Site.php:394 src/Module/Admin/Storage.php:138 +#: src/Module/Admin/Site.php:398 src/Module/Admin/Storage.php:138 #: src/Module/Admin/Summary.php:220 src/Module/Admin/Themes/Details.php:90 #: src/Module/Admin/Themes/Index.php:111 src/Module/Admin/Tos.php:77 #: src/Module/Moderation/Users/Create.php:61 @@ -3684,7 +3684,7 @@ msgid "Addon %s failed to install." msgstr "" #: src/Module/Admin/Addons/Index.php:69 src/Module/Admin/Features.php:86 -#: src/Module/Admin/Logs/Settings.php:81 src/Module/Admin/Site.php:397 +#: src/Module/Admin/Logs/Settings.php:87 src/Module/Admin/Site.php:401 #: src/Module/Admin/Themes/Index.php:113 src/Module/Admin/Tos.php:86 #: src/Module/Settings/Account.php:560 src/Module/Settings/Addons.php:78 #: src/Module/Settings/Connectors.php:160 @@ -3860,46 +3860,52 @@ msgstr[1] "" msgid "The logfile '%s' is not writable. No logging possible" msgstr "" -#: src/Module/Admin/Logs/Settings.php:71 +#: src/Module/Admin/Logs/Settings.php:77 msgid "PHP log currently enabled." msgstr "" -#: src/Module/Admin/Logs/Settings.php:73 +#: src/Module/Admin/Logs/Settings.php:79 msgid "PHP log currently disabled." msgstr "" -#: src/Module/Admin/Logs/Settings.php:80 src/Module/BaseAdmin.php:102 +#: src/Module/Admin/Logs/Settings.php:86 src/Module/BaseAdmin.php:102 #: src/Module/BaseAdmin.php:103 msgid "Logs" msgstr "" -#: src/Module/Admin/Logs/Settings.php:82 +#: src/Module/Admin/Logs/Settings.php:88 msgid "Clear" msgstr "" -#: src/Module/Admin/Logs/Settings.php:85 +#: src/Module/Admin/Logs/Settings.php:91 msgid "Enable Debugging" msgstr "" -#: src/Module/Admin/Logs/Settings.php:86 +#: src/Module/Admin/Logs/Settings.php:91 src/Module/Admin/Logs/Settings.php:92 +#: src/Module/Admin/Logs/Settings.php:93 src/Module/Admin/Site.php:420 +#: src/Module/Admin/Site.php:428 +msgid "Read-only because it is set by an environment variable" +msgstr "" + +#: src/Module/Admin/Logs/Settings.php:92 msgid "Log file" msgstr "" -#: src/Module/Admin/Logs/Settings.php:86 +#: src/Module/Admin/Logs/Settings.php:92 msgid "" "Must be writable by web server. Relative to your Friendica top-level " "directory." msgstr "" -#: src/Module/Admin/Logs/Settings.php:87 +#: src/Module/Admin/Logs/Settings.php:93 msgid "Log level" msgstr "" -#: src/Module/Admin/Logs/Settings.php:89 +#: src/Module/Admin/Logs/Settings.php:95 msgid "PHP logging" msgstr "" -#: src/Module/Admin/Logs/Settings.php:90 +#: src/Module/Admin/Logs/Settings.php:96 msgid "" "To temporarily enable logging of PHP errors and warnings you can prepend the " "following to the index.php file of your installation. The filename set in " @@ -4036,269 +4042,269 @@ msgstr "" msgid "Priority" msgstr "" -#: src/Module/Admin/Site.php:208 +#: src/Module/Admin/Site.php:212 #, php-format msgid "%s is no valid input for maximum image size" msgstr "" -#: src/Module/Admin/Site.php:309 src/Module/Settings/Display.php:169 +#: src/Module/Admin/Site.php:313 src/Module/Settings/Display.php:169 msgid "No special theme for mobile devices" msgstr "" -#: src/Module/Admin/Site.php:326 src/Module/Settings/Display.php:179 +#: src/Module/Admin/Site.php:330 src/Module/Settings/Display.php:179 #, php-format msgid "%s - (Experimental)" msgstr "" -#: src/Module/Admin/Site.php:338 +#: src/Module/Admin/Site.php:342 msgid "No community page" msgstr "" -#: src/Module/Admin/Site.php:339 +#: src/Module/Admin/Site.php:343 msgid "No community page for visitors" msgstr "" -#: src/Module/Admin/Site.php:340 +#: src/Module/Admin/Site.php:344 msgid "Public postings from users of this site" msgstr "" -#: src/Module/Admin/Site.php:341 +#: src/Module/Admin/Site.php:345 msgid "Public postings from the federated network" msgstr "" -#: src/Module/Admin/Site.php:342 +#: src/Module/Admin/Site.php:346 msgid "Public postings from local users and the federated network" msgstr "" -#: src/Module/Admin/Site.php:348 +#: src/Module/Admin/Site.php:352 msgid "Multi user instance" msgstr "" -#: src/Module/Admin/Site.php:371 +#: src/Module/Admin/Site.php:375 msgid "Closed" msgstr "" -#: src/Module/Admin/Site.php:372 +#: src/Module/Admin/Site.php:376 msgid "Requires approval" msgstr "" -#: src/Module/Admin/Site.php:373 +#: src/Module/Admin/Site.php:377 msgid "Open" msgstr "" -#: src/Module/Admin/Site.php:377 +#: src/Module/Admin/Site.php:381 msgid "Don't check" msgstr "" -#: src/Module/Admin/Site.php:378 +#: src/Module/Admin/Site.php:382 msgid "check the stable version" msgstr "" -#: src/Module/Admin/Site.php:379 +#: src/Module/Admin/Site.php:383 msgid "check the development version" msgstr "" -#: src/Module/Admin/Site.php:383 +#: src/Module/Admin/Site.php:387 msgid "none" msgstr "" -#: src/Module/Admin/Site.php:384 +#: src/Module/Admin/Site.php:388 msgid "Local contacts" msgstr "" -#: src/Module/Admin/Site.php:385 +#: src/Module/Admin/Site.php:389 msgid "Interactors" msgstr "" -#: src/Module/Admin/Site.php:395 src/Module/BaseAdmin.php:90 +#: src/Module/Admin/Site.php:399 src/Module/BaseAdmin.php:90 msgid "Site" msgstr "" -#: src/Module/Admin/Site.php:396 +#: src/Module/Admin/Site.php:400 msgid "General Information" msgstr "" -#: src/Module/Admin/Site.php:398 +#: src/Module/Admin/Site.php:402 msgid "Republish users to directory" msgstr "" -#: src/Module/Admin/Site.php:399 src/Module/Register.php:152 +#: src/Module/Admin/Site.php:403 src/Module/Register.php:152 msgid "Registration" msgstr "" -#: src/Module/Admin/Site.php:400 +#: src/Module/Admin/Site.php:404 msgid "File upload" msgstr "" -#: src/Module/Admin/Site.php:401 +#: src/Module/Admin/Site.php:405 msgid "Policies" msgstr "" -#: src/Module/Admin/Site.php:402 src/Module/Calendar/Event/Form.php:252 +#: src/Module/Admin/Site.php:406 src/Module/Calendar/Event/Form.php:252 #: src/Module/Contact.php:516 src/Module/Profile/Profile.php:276 msgid "Advanced" msgstr "" -#: src/Module/Admin/Site.php:403 +#: src/Module/Admin/Site.php:407 msgid "Auto Discovered Contact Directory" msgstr "" -#: src/Module/Admin/Site.php:404 +#: src/Module/Admin/Site.php:408 msgid "Performance" msgstr "" -#: src/Module/Admin/Site.php:405 +#: src/Module/Admin/Site.php:409 msgid "Worker" msgstr "" -#: src/Module/Admin/Site.php:406 +#: src/Module/Admin/Site.php:410 msgid "Message Relay" msgstr "" -#: src/Module/Admin/Site.php:407 +#: src/Module/Admin/Site.php:411 msgid "" "Use the command \"console relay\" in the command line to add or remove " "relays." msgstr "" -#: src/Module/Admin/Site.php:408 +#: src/Module/Admin/Site.php:412 msgid "The system is not subscribed to any relays at the moment." msgstr "" -#: src/Module/Admin/Site.php:409 +#: src/Module/Admin/Site.php:413 msgid "The system is currently subscribed to the following relays:" msgstr "" -#: src/Module/Admin/Site.php:411 +#: src/Module/Admin/Site.php:415 msgid "Relocate Node" msgstr "" -#: src/Module/Admin/Site.php:412 +#: src/Module/Admin/Site.php:416 msgid "" "Relocating your node enables you to change the DNS domain of this node and " "keep all the existing users and posts. This process takes a while and can " "only be started from the relocate console command like this:" msgstr "" -#: src/Module/Admin/Site.php:413 +#: src/Module/Admin/Site.php:417 msgid "(Friendica directory)# bin/console relocate https://newdomain.com" msgstr "" -#: src/Module/Admin/Site.php:416 +#: src/Module/Admin/Site.php:420 msgid "Site name" msgstr "" -#: src/Module/Admin/Site.php:417 +#: src/Module/Admin/Site.php:421 msgid "Sender Email" msgstr "" -#: src/Module/Admin/Site.php:417 +#: src/Module/Admin/Site.php:421 msgid "" "The email address your server shall use to send notification emails from." msgstr "" -#: src/Module/Admin/Site.php:418 +#: src/Module/Admin/Site.php:422 msgid "Name of the system actor" msgstr "" -#: src/Module/Admin/Site.php:418 +#: src/Module/Admin/Site.php:422 msgid "" "Name of the internal system account that is used to perform ActivityPub " "requests. This must be an unused username. If set, this can't be changed " "again." msgstr "" -#: src/Module/Admin/Site.php:419 +#: src/Module/Admin/Site.php:423 msgid "Banner/Logo" msgstr "" -#: src/Module/Admin/Site.php:420 +#: src/Module/Admin/Site.php:424 msgid "Email Banner/Logo" msgstr "" -#: src/Module/Admin/Site.php:421 +#: src/Module/Admin/Site.php:425 msgid "Shortcut icon" msgstr "" -#: src/Module/Admin/Site.php:421 +#: src/Module/Admin/Site.php:425 msgid "Link to an icon that will be used for browsers." msgstr "" -#: src/Module/Admin/Site.php:422 +#: src/Module/Admin/Site.php:426 msgid "Touch icon" msgstr "" -#: src/Module/Admin/Site.php:422 +#: src/Module/Admin/Site.php:426 msgid "Link to an icon that will be used for tablets and mobiles." msgstr "" -#: src/Module/Admin/Site.php:423 +#: src/Module/Admin/Site.php:427 msgid "Additional Info" msgstr "" -#: src/Module/Admin/Site.php:423 +#: src/Module/Admin/Site.php:427 #, php-format msgid "" "For public servers: you can add additional information here that will be " "listed at %s/servers." msgstr "" -#: src/Module/Admin/Site.php:424 +#: src/Module/Admin/Site.php:428 msgid "System language" msgstr "" -#: src/Module/Admin/Site.php:425 +#: src/Module/Admin/Site.php:429 msgid "System theme" msgstr "" -#: src/Module/Admin/Site.php:425 +#: src/Module/Admin/Site.php:429 #, php-format msgid "" "Default system theme - may be over-ridden by user profiles - Change default theme settings" msgstr "" -#: src/Module/Admin/Site.php:426 +#: src/Module/Admin/Site.php:430 msgid "Mobile system theme" msgstr "" -#: src/Module/Admin/Site.php:426 +#: src/Module/Admin/Site.php:430 msgid "Theme for mobile devices" msgstr "" -#: src/Module/Admin/Site.php:427 +#: src/Module/Admin/Site.php:431 msgid "Force SSL" msgstr "" -#: src/Module/Admin/Site.php:427 +#: src/Module/Admin/Site.php:431 msgid "" "Force all Non-SSL requests to SSL - Attention: on some systems it could lead " "to endless loops." msgstr "" -#: src/Module/Admin/Site.php:428 +#: src/Module/Admin/Site.php:432 msgid "Show help entry from navigation menu" msgstr "" -#: src/Module/Admin/Site.php:428 +#: src/Module/Admin/Site.php:432 msgid "" "Displays the menu entry for the Help pages from the navigation menu. It is " "always accessible by calling /help directly." msgstr "" -#: src/Module/Admin/Site.php:429 +#: src/Module/Admin/Site.php:433 msgid "Single user instance" msgstr "" -#: src/Module/Admin/Site.php:429 +#: src/Module/Admin/Site.php:433 msgid "Make this instance multi-user or single-user for the named user" msgstr "" -#: src/Module/Admin/Site.php:431 +#: src/Module/Admin/Site.php:435 msgid "Maximum image size" msgstr "" -#: src/Module/Admin/Site.php:431 +#: src/Module/Admin/Site.php:435 #, php-format msgid "" "Maximum size in bytes of uploaded images. Default is 0, which means no " @@ -4310,35 +4316,35 @@ msgid "" "to %s (%s byte)" msgstr "" -#: src/Module/Admin/Site.php:435 +#: src/Module/Admin/Site.php:439 msgid "Maximum image length" msgstr "" -#: src/Module/Admin/Site.php:435 +#: src/Module/Admin/Site.php:439 msgid "" "Maximum length in pixels of the longest side of uploaded images. Default is " "-1, which means no limits." msgstr "" -#: src/Module/Admin/Site.php:436 +#: src/Module/Admin/Site.php:440 msgid "JPEG image quality" msgstr "" -#: src/Module/Admin/Site.php:436 +#: src/Module/Admin/Site.php:440 msgid "" "Uploaded JPEGS will be saved at this quality setting [0-100]. Default is " "100, which is full quality." msgstr "" -#: src/Module/Admin/Site.php:438 +#: src/Module/Admin/Site.php:442 msgid "Register policy" msgstr "" -#: src/Module/Admin/Site.php:439 +#: src/Module/Admin/Site.php:443 msgid "Maximum Users" msgstr "" -#: src/Module/Admin/Site.php:439 +#: src/Module/Admin/Site.php:443 msgid "" "If defined, the register policy is automatically closed when the given " "number of users is reached and reopens the registry when the number drops " @@ -4346,168 +4352,168 @@ msgid "" "not when the policy is set to approval." msgstr "" -#: src/Module/Admin/Site.php:440 +#: src/Module/Admin/Site.php:444 msgid "Maximum Daily Registrations" msgstr "" -#: src/Module/Admin/Site.php:440 +#: src/Module/Admin/Site.php:444 msgid "" "If registration is permitted above, this sets the maximum number of new user " "registrations to accept per day. If register is set to closed, this setting " "has no effect." msgstr "" -#: src/Module/Admin/Site.php:441 +#: src/Module/Admin/Site.php:445 msgid "Register text" msgstr "" -#: src/Module/Admin/Site.php:441 +#: src/Module/Admin/Site.php:445 msgid "" "Will be displayed prominently on the registration page. You can use BBCode " "here." msgstr "" -#: src/Module/Admin/Site.php:442 +#: src/Module/Admin/Site.php:446 msgid "Forbidden Nicknames" msgstr "" -#: src/Module/Admin/Site.php:442 +#: src/Module/Admin/Site.php:446 msgid "" "Comma separated list of nicknames that are forbidden from registration. " "Preset is a list of role names according RFC 2142." msgstr "" -#: src/Module/Admin/Site.php:443 +#: src/Module/Admin/Site.php:447 msgid "Accounts abandoned after x days" msgstr "" -#: src/Module/Admin/Site.php:443 +#: src/Module/Admin/Site.php:447 msgid "" "Will not waste system resources polling external sites for abandonded " "accounts. Enter 0 for no time limit." msgstr "" -#: src/Module/Admin/Site.php:444 +#: src/Module/Admin/Site.php:448 msgid "Allowed friend domains" msgstr "" -#: src/Module/Admin/Site.php:444 +#: src/Module/Admin/Site.php:448 msgid "" "Comma separated list of domains which are allowed to establish friendships " "with this site. Wildcards are accepted. Empty to allow any domains" msgstr "" -#: src/Module/Admin/Site.php:445 +#: src/Module/Admin/Site.php:449 msgid "Allowed email domains" msgstr "" -#: src/Module/Admin/Site.php:445 +#: src/Module/Admin/Site.php:449 msgid "" "Comma separated list of domains which are allowed in email addresses for " "registrations to this site. Wildcards are accepted. Empty to allow any " "domains" msgstr "" -#: src/Module/Admin/Site.php:446 +#: src/Module/Admin/Site.php:450 msgid "No OEmbed rich content" msgstr "" -#: src/Module/Admin/Site.php:446 +#: src/Module/Admin/Site.php:450 msgid "" "Don't show the rich content (e.g. embedded PDF), except from the domains " "listed below." msgstr "" -#: src/Module/Admin/Site.php:447 +#: src/Module/Admin/Site.php:451 msgid "Trusted third-party domains" msgstr "" -#: src/Module/Admin/Site.php:447 +#: src/Module/Admin/Site.php:451 msgid "" "Comma separated list of domains from which content is allowed to be embedded " "in posts like with OEmbed. All sub-domains of the listed domains are allowed " "as well." msgstr "" -#: src/Module/Admin/Site.php:448 +#: src/Module/Admin/Site.php:452 msgid "Block public" msgstr "" -#: src/Module/Admin/Site.php:448 +#: src/Module/Admin/Site.php:452 msgid "" "Check to block public access to all otherwise public personal pages on this " "site unless you are currently logged in." msgstr "" -#: src/Module/Admin/Site.php:449 +#: src/Module/Admin/Site.php:453 msgid "Force publish" msgstr "" -#: src/Module/Admin/Site.php:449 +#: src/Module/Admin/Site.php:453 msgid "" "Check to force all profiles on this site to be listed in the site directory." msgstr "" -#: src/Module/Admin/Site.php:449 +#: src/Module/Admin/Site.php:453 msgid "Enabling this may violate privacy laws like the GDPR" msgstr "" -#: src/Module/Admin/Site.php:450 +#: src/Module/Admin/Site.php:454 msgid "Global directory URL" msgstr "" -#: src/Module/Admin/Site.php:450 +#: src/Module/Admin/Site.php:454 msgid "" "URL to the global directory. If this is not set, the global directory is " "completely unavailable to the application." msgstr "" -#: src/Module/Admin/Site.php:451 +#: src/Module/Admin/Site.php:455 msgid "Private posts by default for new users" msgstr "" -#: src/Module/Admin/Site.php:451 +#: src/Module/Admin/Site.php:455 msgid "" "Set default post permissions for all new members to the default privacy " "group rather than public." msgstr "" -#: src/Module/Admin/Site.php:452 +#: src/Module/Admin/Site.php:456 msgid "Don't include post content in email notifications" msgstr "" -#: src/Module/Admin/Site.php:452 +#: src/Module/Admin/Site.php:456 msgid "" "Don't include the content of a post/comment/private message/etc. in the " "email notifications that are sent out from this site, as a privacy measure." msgstr "" -#: src/Module/Admin/Site.php:453 +#: src/Module/Admin/Site.php:457 msgid "Disallow public access to addons listed in the apps menu." msgstr "" -#: src/Module/Admin/Site.php:453 +#: src/Module/Admin/Site.php:457 msgid "" "Checking this box will restrict addons listed in the apps menu to members " "only." msgstr "" -#: src/Module/Admin/Site.php:454 +#: src/Module/Admin/Site.php:458 msgid "Don't embed private images in posts" msgstr "" -#: src/Module/Admin/Site.php:454 +#: src/Module/Admin/Site.php:458 msgid "" "Don't replace locally-hosted private photos in posts with an embedded copy " "of the image. This means that contacts who receive posts containing private " "photos will have to authenticate and load each image, which may take a while." msgstr "" -#: src/Module/Admin/Site.php:455 +#: src/Module/Admin/Site.php:459 msgid "Explicit Content" msgstr "" -#: src/Module/Admin/Site.php:455 +#: src/Module/Admin/Site.php:459 msgid "" "Set this to announce that your node is used mostly for explicit content that " "might not be suited for minors. This information will be published in the " @@ -4516,267 +4522,267 @@ msgid "" "will be shown at the user registration page." msgstr "" -#: src/Module/Admin/Site.php:456 +#: src/Module/Admin/Site.php:460 msgid "Proxify external content" msgstr "" -#: src/Module/Admin/Site.php:456 +#: src/Module/Admin/Site.php:460 msgid "" "Route external content via the proxy functionality. This is used for example " "for some OEmbed accesses and in some other rare cases." msgstr "" -#: src/Module/Admin/Site.php:457 +#: src/Module/Admin/Site.php:461 msgid "Cache contact avatars" msgstr "" -#: src/Module/Admin/Site.php:457 +#: src/Module/Admin/Site.php:461 msgid "" "Locally store the avatar pictures of the contacts. This uses a lot of " "storage space but it increases the performance." msgstr "" -#: src/Module/Admin/Site.php:458 +#: src/Module/Admin/Site.php:462 msgid "Allow Users to set remote_self" msgstr "" -#: src/Module/Admin/Site.php:458 +#: src/Module/Admin/Site.php:462 msgid "" "With checking this, every user is allowed to mark every contact as a " "remote_self in the repair contact dialog. Setting this flag on a contact " "causes mirroring every posting of that contact in the users stream." msgstr "" -#: src/Module/Admin/Site.php:459 +#: src/Module/Admin/Site.php:463 msgid "Enable multiple registrations" msgstr "" -#: src/Module/Admin/Site.php:459 +#: src/Module/Admin/Site.php:463 msgid "Enable users to register additional accounts for use as pages." msgstr "" -#: src/Module/Admin/Site.php:460 +#: src/Module/Admin/Site.php:464 msgid "Enable OpenID" msgstr "" -#: src/Module/Admin/Site.php:460 +#: src/Module/Admin/Site.php:464 msgid "Enable OpenID support for registration and logins." msgstr "" -#: src/Module/Admin/Site.php:461 +#: src/Module/Admin/Site.php:465 msgid "Enable Fullname check" msgstr "" -#: src/Module/Admin/Site.php:461 +#: src/Module/Admin/Site.php:465 msgid "" "Enable check to only allow users to register with a space between the first " "name and the last name in their full name." msgstr "" -#: src/Module/Admin/Site.php:462 +#: src/Module/Admin/Site.php:466 msgid "Email administrators on new registration" msgstr "" -#: src/Module/Admin/Site.php:462 +#: src/Module/Admin/Site.php:466 msgid "" "If enabled and the system is set to an open registration, an email for each " "new registration is sent to the administrators." msgstr "" -#: src/Module/Admin/Site.php:463 +#: src/Module/Admin/Site.php:467 msgid "Community pages for visitors" msgstr "" -#: src/Module/Admin/Site.php:463 +#: src/Module/Admin/Site.php:467 msgid "" "Which community pages should be available for visitors. Local users always " "see both pages." msgstr "" -#: src/Module/Admin/Site.php:464 +#: src/Module/Admin/Site.php:468 msgid "Posts per user on community page" msgstr "" -#: src/Module/Admin/Site.php:464 +#: src/Module/Admin/Site.php:468 msgid "" "The maximum number of posts per user on the community page. (Not valid for " "\"Global Community\")" msgstr "" -#: src/Module/Admin/Site.php:466 +#: src/Module/Admin/Site.php:470 msgid "Enable Mail support" msgstr "" -#: src/Module/Admin/Site.php:466 +#: src/Module/Admin/Site.php:470 msgid "" "Enable built-in mail support to poll IMAP folders and to reply via mail." msgstr "" -#: src/Module/Admin/Site.php:467 +#: src/Module/Admin/Site.php:471 msgid "" "Mail support can't be enabled because the PHP IMAP module is not installed." msgstr "" -#: src/Module/Admin/Site.php:468 +#: src/Module/Admin/Site.php:472 msgid "Enable OStatus support" msgstr "" -#: src/Module/Admin/Site.php:468 +#: src/Module/Admin/Site.php:472 msgid "" "Enable built-in OStatus (StatusNet, GNU Social etc.) compatibility. All " "communications in OStatus are public." msgstr "" -#: src/Module/Admin/Site.php:470 +#: src/Module/Admin/Site.php:474 msgid "" "Diaspora support can't be enabled because Friendica was installed into a sub " "directory." msgstr "" -#: src/Module/Admin/Site.php:471 +#: src/Module/Admin/Site.php:475 msgid "Enable Diaspora support" msgstr "" -#: src/Module/Admin/Site.php:471 +#: src/Module/Admin/Site.php:475 msgid "" "Enable built-in Diaspora network compatibility for communicating with " "diaspora servers." msgstr "" -#: src/Module/Admin/Site.php:472 +#: src/Module/Admin/Site.php:476 msgid "Verify SSL" msgstr "" -#: src/Module/Admin/Site.php:472 +#: src/Module/Admin/Site.php:476 msgid "" "If you wish, you can turn on strict certificate checking. This will mean you " "cannot connect (at all) to self-signed SSL sites." msgstr "" -#: src/Module/Admin/Site.php:473 +#: src/Module/Admin/Site.php:477 msgid "Proxy user" msgstr "" -#: src/Module/Admin/Site.php:473 +#: src/Module/Admin/Site.php:477 msgid "User name for the proxy server." msgstr "" -#: src/Module/Admin/Site.php:474 +#: src/Module/Admin/Site.php:478 msgid "Proxy URL" msgstr "" -#: src/Module/Admin/Site.php:474 +#: src/Module/Admin/Site.php:478 msgid "" "If you want to use a proxy server that Friendica should use to connect to " "the network, put the URL of the proxy here." msgstr "" -#: src/Module/Admin/Site.php:475 +#: src/Module/Admin/Site.php:479 msgid "Network timeout" msgstr "" -#: src/Module/Admin/Site.php:475 +#: src/Module/Admin/Site.php:479 msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." msgstr "" -#: src/Module/Admin/Site.php:476 +#: src/Module/Admin/Site.php:480 msgid "Maximum Load Average" msgstr "" -#: src/Module/Admin/Site.php:476 +#: src/Module/Admin/Site.php:480 #, php-format msgid "" "Maximum system load before delivery and poll processes are deferred - " "default %d." msgstr "" -#: src/Module/Admin/Site.php:477 +#: src/Module/Admin/Site.php:481 msgid "Minimal Memory" msgstr "" -#: src/Module/Admin/Site.php:477 +#: src/Module/Admin/Site.php:481 msgid "" "Minimal free memory in MB for the worker. Needs access to /proc/meminfo - " "default 0 (deactivated)." msgstr "" -#: src/Module/Admin/Site.php:478 +#: src/Module/Admin/Site.php:482 msgid "Periodically optimize tables" msgstr "" -#: src/Module/Admin/Site.php:478 +#: src/Module/Admin/Site.php:482 msgid "Periodically optimize tables like the cache and the workerqueue" msgstr "" -#: src/Module/Admin/Site.php:480 +#: src/Module/Admin/Site.php:484 msgid "Discover followers/followings from contacts" msgstr "" -#: src/Module/Admin/Site.php:480 +#: src/Module/Admin/Site.php:484 msgid "" "If enabled, contacts are checked for their followers and following contacts." msgstr "" -#: src/Module/Admin/Site.php:481 +#: src/Module/Admin/Site.php:485 msgid "None - deactivated" msgstr "" -#: src/Module/Admin/Site.php:482 +#: src/Module/Admin/Site.php:486 msgid "" "Local contacts - contacts of our local contacts are discovered for their " "followers/followings." msgstr "" -#: src/Module/Admin/Site.php:483 +#: src/Module/Admin/Site.php:487 msgid "" "Interactors - contacts of our local contacts and contacts who interacted on " "locally visible postings are discovered for their followers/followings." msgstr "" -#: src/Module/Admin/Site.php:485 +#: src/Module/Admin/Site.php:489 msgid "Synchronize the contacts with the directory server" msgstr "" -#: src/Module/Admin/Site.php:485 +#: src/Module/Admin/Site.php:489 msgid "" "if enabled, the system will check periodically for new contacts on the " "defined directory server." msgstr "" -#: src/Module/Admin/Site.php:487 +#: src/Module/Admin/Site.php:491 msgid "Days between requery" msgstr "" -#: src/Module/Admin/Site.php:487 +#: src/Module/Admin/Site.php:491 msgid "Number of days after which a server is requeried for his contacts." msgstr "" -#: src/Module/Admin/Site.php:488 +#: src/Module/Admin/Site.php:492 msgid "Discover contacts from other servers" msgstr "" -#: src/Module/Admin/Site.php:488 +#: src/Module/Admin/Site.php:492 msgid "" "Periodically query other servers for contacts. The system queries Friendica, " "Mastodon and Hubzilla servers." msgstr "" -#: src/Module/Admin/Site.php:489 +#: src/Module/Admin/Site.php:493 msgid "Search the local directory" msgstr "" -#: src/Module/Admin/Site.php:489 +#: src/Module/Admin/Site.php:493 msgid "" "Search the local directory instead of the global directory. When searching " "locally, every search will be executed on the global directory in the " "background. This improves the search results when the search is repeated." msgstr "" -#: src/Module/Admin/Site.php:491 +#: src/Module/Admin/Site.php:495 msgid "Publish server information" msgstr "" -#: src/Module/Admin/Site.php:491 +#: src/Module/Admin/Site.php:495 msgid "" "If enabled, general server and usage data will be published. The data " "contains the name and version of the server, number of users with public " @@ -4784,50 +4790,50 @@ msgid "" "href=\"http://the-federation.info/\">the-federation.info for details." msgstr "" -#: src/Module/Admin/Site.php:493 +#: src/Module/Admin/Site.php:497 msgid "Check upstream version" msgstr "" -#: src/Module/Admin/Site.php:493 +#: src/Module/Admin/Site.php:497 msgid "" "Enables checking for new Friendica versions at github. If there is a new " "version, you will be informed in the admin panel overview." msgstr "" -#: src/Module/Admin/Site.php:494 +#: src/Module/Admin/Site.php:498 msgid "Suppress Tags" msgstr "" -#: src/Module/Admin/Site.php:494 +#: src/Module/Admin/Site.php:498 msgid "Suppress showing a list of hashtags at the end of the posting." msgstr "" -#: src/Module/Admin/Site.php:495 +#: src/Module/Admin/Site.php:499 msgid "Clean database" msgstr "" -#: src/Module/Admin/Site.php:495 +#: src/Module/Admin/Site.php:499 msgid "" "Remove old remote items, orphaned database records and old content from some " "other helper tables." msgstr "" -#: src/Module/Admin/Site.php:496 +#: src/Module/Admin/Site.php:500 msgid "Lifespan of remote items" msgstr "" -#: src/Module/Admin/Site.php:496 +#: src/Module/Admin/Site.php:500 msgid "" "When the database cleanup is enabled, this defines the days after which " "remote items will be deleted. Own items, and marked or filed items are " "always kept. 0 disables this behaviour." msgstr "" -#: src/Module/Admin/Site.php:497 +#: src/Module/Admin/Site.php:501 msgid "Lifespan of unclaimed items" msgstr "" -#: src/Module/Admin/Site.php:497 +#: src/Module/Admin/Site.php:501 msgid "" "When the database cleanup is enabled, this defines the days after which " "unclaimed remote items (mostly content from the relay) will be deleted. " @@ -4835,144 +4841,144 @@ msgid "" "items if set to 0." msgstr "" -#: src/Module/Admin/Site.php:498 +#: src/Module/Admin/Site.php:502 msgid "Lifespan of raw conversation data" msgstr "" -#: src/Module/Admin/Site.php:498 +#: src/Module/Admin/Site.php:502 msgid "" "The conversation data is used for ActivityPub and OStatus, as well as for " "debug purposes. It should be safe to remove it after 14 days, default is 90 " "days." msgstr "" -#: src/Module/Admin/Site.php:499 +#: src/Module/Admin/Site.php:503 msgid "Maximum numbers of comments per post" msgstr "" -#: src/Module/Admin/Site.php:499 +#: src/Module/Admin/Site.php:503 msgid "How much comments should be shown for each post? Default value is 100." msgstr "" -#: src/Module/Admin/Site.php:500 +#: src/Module/Admin/Site.php:504 msgid "Maximum numbers of comments per post on the display page" msgstr "" -#: src/Module/Admin/Site.php:500 +#: src/Module/Admin/Site.php:504 msgid "" "How many comments should be shown on the single view for each post? Default " "value is 1000." msgstr "" -#: src/Module/Admin/Site.php:501 +#: src/Module/Admin/Site.php:505 msgid "Temp path" msgstr "" -#: src/Module/Admin/Site.php:501 +#: src/Module/Admin/Site.php:505 msgid "" "If you have a restricted system where the webserver can't access the system " "temp path, enter another path here." msgstr "" -#: src/Module/Admin/Site.php:502 +#: src/Module/Admin/Site.php:506 msgid "Only search in tags" msgstr "" -#: src/Module/Admin/Site.php:502 +#: src/Module/Admin/Site.php:506 msgid "On large systems the text search can slow down the system extremely." msgstr "" -#: src/Module/Admin/Site.php:503 +#: src/Module/Admin/Site.php:507 msgid "Generate counts per contact group when calculating network count" msgstr "" -#: src/Module/Admin/Site.php:503 +#: src/Module/Admin/Site.php:507 msgid "" "On systems with users that heavily use contact groups the query can be very " "expensive." msgstr "" -#: src/Module/Admin/Site.php:505 +#: src/Module/Admin/Site.php:509 msgid "Maximum number of parallel workers" msgstr "" -#: src/Module/Admin/Site.php:505 +#: src/Module/Admin/Site.php:509 #, php-format msgid "" "On shared hosters set this to %d. On larger systems, values of %d are great. " "Default value is %d." msgstr "" -#: src/Module/Admin/Site.php:506 +#: src/Module/Admin/Site.php:510 msgid "Enable fastlane" msgstr "" -#: src/Module/Admin/Site.php:506 +#: src/Module/Admin/Site.php:510 msgid "" "When enabed, the fastlane mechanism starts an additional worker if processes " "with higher priority are blocked by processes of lower priority." msgstr "" -#: src/Module/Admin/Site.php:508 +#: src/Module/Admin/Site.php:512 msgid "Direct relay transfer" msgstr "" -#: src/Module/Admin/Site.php:508 +#: src/Module/Admin/Site.php:512 msgid "" "Enables the direct transfer to other servers without using the relay servers" msgstr "" -#: src/Module/Admin/Site.php:509 +#: src/Module/Admin/Site.php:513 msgid "Relay scope" msgstr "" -#: src/Module/Admin/Site.php:509 +#: src/Module/Admin/Site.php:513 msgid "" "Can be \"all\" or \"tags\". \"all\" means that every public post should be " "received. \"tags\" means that only posts with selected tags should be " "received." msgstr "" -#: src/Module/Admin/Site.php:509 src/Module/Contact/Profile.php:286 +#: src/Module/Admin/Site.php:513 src/Module/Contact/Profile.php:286 #: src/Module/Settings/TwoFactor/Index.php:125 msgid "Disabled" msgstr "" -#: src/Module/Admin/Site.php:509 +#: src/Module/Admin/Site.php:513 msgid "all" msgstr "" -#: src/Module/Admin/Site.php:509 +#: src/Module/Admin/Site.php:513 msgid "tags" msgstr "" -#: src/Module/Admin/Site.php:510 +#: src/Module/Admin/Site.php:514 msgid "Server tags" msgstr "" -#: src/Module/Admin/Site.php:510 +#: src/Module/Admin/Site.php:514 msgid "Comma separated list of tags for the \"tags\" subscription." msgstr "" -#: src/Module/Admin/Site.php:511 +#: src/Module/Admin/Site.php:515 msgid "Deny Server tags" msgstr "" -#: src/Module/Admin/Site.php:511 +#: src/Module/Admin/Site.php:515 msgid "Comma separated list of tags that are rejected." msgstr "" -#: src/Module/Admin/Site.php:512 +#: src/Module/Admin/Site.php:516 msgid "Allow user tags" msgstr "" -#: src/Module/Admin/Site.php:512 +#: src/Module/Admin/Site.php:516 msgid "" "If enabled, the tags from the saved searches will used for the \"tags\" " "subscription in addition to the \"relay_server_tags\"." msgstr "" -#: src/Module/Admin/Site.php:515 +#: src/Module/Admin/Site.php:519 msgid "Start Relocation" msgstr "" @@ -5019,6 +5025,12 @@ msgid "This backend doesn't have custom settings" msgstr "" #: src/Module/Admin/Storage.php:148 +msgid "" +"Changing the current backend is prohibited because it is set by an " +"environment variable" +msgstr "" + +#: src/Module/Admin/Storage.php:150 msgid "Database (legacy)" msgstr "" diff --git a/view/templates/admin/storage.tpl b/view/templates/admin/storage.tpl index b1918c5a8b..787ec56045 100644 --- a/view/templates/admin/storage.tpl +++ b/view/templates/admin/storage.tpl @@ -2,6 +2,7 @@

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

{{$label_current}}: {{$storagebackend}}

+ {{$storagebackend_ro_txt nofilter}}

{{$label_config}}

@@ -19,12 +20,14 @@ {{if $storage.form}} - {{if $storage.active}} + {{if $is_writable}} + {{if $storage.active}} - {{else}} + {{else}} + {{/if}} {{/if}} - {{else}} + {{elseif $is_writable}}
{{/if}} diff --git a/view/templates/field_select.tpl b/view/templates/field_select.tpl index 16a796a444..9336ce3cc7 100644 --- a/view/templates/field_select.tpl +++ b/view/templates/field_select.tpl @@ -1,7 +1,7 @@
- {{foreach $field.4 as $opt=>$val}} {{/foreach}} diff --git a/view/theme/frio/css/dropzone.frio.css b/view/theme/frio/css/dropzone.frio.css index 5dd36e0316..74e52e8897 100644 --- a/view/theme/frio/css/dropzone.frio.css +++ b/view/theme/frio/css/dropzone.frio.css @@ -201,16 +201,19 @@ } .dropzone, .dropzone * { box-sizing: border-box; + overflow: auto; } .dropzone:not(textarea) { border: 1px solid rgba(0, 0, 0, 0.3); padding: 0px 0px 5px 0px; + color: #999; } .dropzone.dz-clickable { cursor: pointer; border-radius: 4px; background-color: $background_color; + margin-bottom: 10px; } .dropzone.dz-clickable * { cursor: default; diff --git a/view/theme/frio/css/dropzone.min.frio.css b/view/theme/frio/css/dropzone.min.frio.css index 10933a50f6..1132776806 100644 --- a/view/theme/frio/css/dropzone.min.frio.css +++ b/view/theme/frio/css/dropzone.min.frio.css @@ -1 +1 @@ -@-webkit-keyframes passing-through{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%,70%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}100%{opacity:0;-webkit-transform:translateY(-40px);-moz-transform:translateY(-40px);-ms-transform:translateY(-40px);-o-transform:translateY(-40px);transform:translateY(-40px)}}@-moz-keyframes passing-through{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%,70%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}100%{opacity:0;-webkit-transform:translateY(-40px);-moz-transform:translateY(-40px);-ms-transform:translateY(-40px);-o-transform:translateY(-40px);transform:translateY(-40px)}}@keyframes passing-through{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%,70%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}100%{opacity:0;-webkit-transform:translateY(-40px);-moz-transform:translateY(-40px);-ms-transform:translateY(-40px);-o-transform:translateY(-40px);transform:translateY(-40px)}}@-webkit-keyframes slide-in{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}}@-moz-keyframes slide-in{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}}@keyframes slide-in{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}10%{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}20%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-moz-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}10%{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}20%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}10%{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}20%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}.dropzone,.dropzone *{box-sizing:border-box}.dropzone:not(textarea){border:1px solid rgba(0,0,0,.3);padding:0px 0px 5px 0px}.dropzone.dz-clickable{cursor:pointer;border-radius: 4px;background-color: $background_color;}.dropzone.dz-clickable *{cursor:default}.dropzone.dz-clickable .dz-message,.dropzone.dz-clickable .dz-message *{cursor:pointer}.dropzone.dz-started .dz-message{display:none}.dropzone.dz-drag-hover{border-style:solid}.dropzone.dz-drag-hover .dz-message{opacity:.5}.dropzone .dz-message{text-align:center}.dropzone .dz-message .dz-button{background:none;color:inherit;border:none;padding:0;font:inherit;cursor:pointer;outline:inherit}.dropzone .dz-preview{position:relative;display:inline-block;vertical-align:top;margin:16px;min-height:100px}.dropzone .dz-preview:hover{z-index:1000}.dropzone .dz-preview:hover .dz-details{opacity:1}.dropzone .dz-preview.dz-file-preview .dz-image{border-radius:20px;background:#999;background:linear-gradient(to bottom, #eee, #ddd)}.dropzone .dz-preview.dz-file-preview .dz-details{opacity:1}.dropzone .dz-preview.dz-image-preview{background:#fff}.dropzone .dz-preview.dz-image-preview .dz-details{-webkit-transition:opacity 0.2s linear;-moz-transition:opacity 0.2s linear;-ms-transition:opacity 0.2s linear;-o-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.dropzone .dz-preview .dz-remove{font-size:14px;text-align:center;display:block;cursor:pointer;border:none}.dropzone .dz-preview .dz-remove:hover{text-decoration:underline}.dropzone .dz-preview:hover .dz-details{opacity:1}.dropzone .dz-preview .dz-details{z-index:20;position:absolute;top:0;left:0;opacity:0;font-size:13px;min-width:100%;max-width:100%;padding:2em 1em;text-align:center;color:rgba(0,0,0,.9);line-height:150%}.dropzone .dz-preview .dz-details .dz-size{margin-bottom:1em;font-size:16px}.dropzone .dz-preview .dz-details .dz-filename{white-space:nowrap}.dropzone .dz-preview .dz-details .dz-filename:hover span{border:1px solid rgba(200,200,200,.8);background-color:rgba(255,255,255,.8)}.dropzone .dz-preview .dz-details .dz-filename:not(:hover){overflow:hidden;text-overflow:ellipsis}.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span{border:1px solid transparent}.dropzone .dz-preview .dz-details .dz-filename span,.dropzone .dz-preview .dz-details .dz-size span{background-color:rgba(255,255,255,.4);padding:0 .4em;border-radius:3px}.dropzone .dz-preview:hover .dz-image img{-webkit-transform:scale(1.05, 1.05);-moz-transform:scale(1.05, 1.05);-ms-transform:scale(1.05, 1.05);-o-transform:scale(1.05, 1.05);transform:scale(1.05, 1.05);-webkit-filter:blur(8px);filter:blur(8px)}.dropzone .dz-preview .dz-image{border-radius:20px;overflow:hidden;width:120px;height:120px;position:relative;display:block;z-index:10}.dropzone .dz-preview .dz-image img{display:block}.dropzone .dz-preview.dz-success .dz-success-mark{-webkit-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);-moz-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);-ms-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);-o-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1)}.dropzone .dz-preview.dz-error .dz-error-mark{opacity:1;-webkit-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);-moz-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);-ms-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);-o-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1)}.dropzone .dz-preview .dz-success-mark,.dropzone .dz-preview .dz-error-mark{pointer-events:none;opacity:0;z-index:500;position:absolute;display:block;top:50%;left:50%;margin-left:-27px;margin-top:-27px}.dropzone .dz-preview .dz-success-mark svg,.dropzone .dz-preview .dz-error-mark svg{display:block;width:54px;height:54px}.dropzone .dz-preview.dz-processing .dz-progress{opacity:1;-webkit-transition:all 0.2s linear;-moz-transition:all 0.2s linear;-ms-transition:all 0.2s linear;-o-transition:all 0.2s linear;transition:all 0.2s linear}.dropzone .dz-preview.dz-complete .dz-progress{opacity:0;-webkit-transition:opacity 0.4s ease-in;-moz-transition:opacity 0.4s ease-in;-ms-transition:opacity 0.4s ease-in;-o-transition:opacity 0.4s ease-in;transition:opacity 0.4s ease-in}.dropzone .dz-preview:not(.dz-processing) .dz-progress{-webkit-animation:pulse 6s ease infinite;-moz-animation:pulse 6s ease infinite;-ms-animation:pulse 6s ease infinite;-o-animation:pulse 6s ease infinite;animation:pulse 6s ease infinite}.dropzone .dz-preview .dz-progress{opacity:1;z-index:1000;pointer-events:none;position:absolute;height:16px;left:50%;top:50%;margin-top:-8px;width:80px;margin-left:-40px;background:rgba(255,255,255,.9);-webkit-transform:scale(1);border-radius:8px;overflow:hidden}.dropzone .dz-preview .dz-progress .dz-upload{background:#333;background:linear-gradient(to bottom, #666, #444);position:absolute;top:0;left:0;bottom:0;width:0;-webkit-transition:width 300ms ease-in-out;-moz-transition:width 300ms ease-in-out;-ms-transition:width 300ms ease-in-out;-o-transition:width 300ms ease-in-out;transition:width 300ms ease-in-out}.dropzone .dz-preview.dz-error .dz-error-message{display:block}.dropzone .dz-preview.dz-error:hover .dz-error-message{opacity:1;pointer-events:auto}.dropzone .dz-preview .dz-error-message{pointer-events:none;z-index:1000;position:absolute;display:block;display:none;opacity:0;-webkit-transition:opacity 0.3s ease;-moz-transition:opacity 0.3s ease;-ms-transition:opacity 0.3s ease;-o-transition:opacity 0.3s ease;transition:opacity 0.3s ease;border-radius:8px;font-size:13px;top:130px;left:-10px;width:140px;background:#be2626;background:linear-gradient(to bottom, #be2626, #a92222);padding:.5em 1.2em;color:#fff}.dropzone .dz-preview .dz-error-message:after{content:"";position:absolute;top:-6px;left:64px;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #be2626} +@-webkit-keyframes passing-through{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%,70%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}100%{opacity:0;-webkit-transform:translateY(-40px);-moz-transform:translateY(-40px);-ms-transform:translateY(-40px);-o-transform:translateY(-40px);transform:translateY(-40px)}}@-moz-keyframes passing-through{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%,70%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}100%{opacity:0;-webkit-transform:translateY(-40px);-moz-transform:translateY(-40px);-ms-transform:translateY(-40px);-o-transform:translateY(-40px);transform:translateY(-40px)}}@keyframes passing-through{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%,70%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}100%{opacity:0;-webkit-transform:translateY(-40px);-moz-transform:translateY(-40px);-ms-transform:translateY(-40px);-o-transform:translateY(-40px);transform:translateY(-40px)}}@-webkit-keyframes slide-in{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}}@-moz-keyframes slide-in{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}}@keyframes slide-in{0%{opacity:0;-webkit-transform:translateY(40px);-moz-transform:translateY(40px);-ms-transform:translateY(40px);-o-transform:translateY(40px);transform:translateY(40px)}30%{opacity:1;-webkit-transform:translateY(0px);-moz-transform:translateY(0px);-ms-transform:translateY(0px);-o-transform:translateY(0px);transform:translateY(0px)}}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}10%{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}20%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-moz-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}10%{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}20%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}10%{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}20%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}.dropzone,.dropzone *{box-sizing:border-box;overflow:auto;}.dropzone:not(textarea){border:1px solid rgba(0,0,0,.3);padding:0px 0px 5px 0px;color: #999;}.dropzone.dz-clickable{cursor:pointer;border-radius: 4px;background-color: $background_color; margin-bottom: 10px;}.dropzone.dz-clickable *{cursor:default}.dropzone.dz-clickable .dz-message,.dropzone.dz-clickable .dz-message *{cursor:pointer}.dropzone.dz-started .dz-message{display:none}.dropzone.dz-drag-hover{border-style:solid}.dropzone.dz-drag-hover .dz-message{opacity:.5}.dropzone .dz-message{text-align:center}.dropzone .dz-message .dz-button{background:none;color:inherit;border:none;padding:0;font:inherit;cursor:pointer;outline:inherit}.dropzone .dz-preview{position:relative;display:inline-block;vertical-align:top;margin:16px;min-height:100px}.dropzone .dz-preview:hover{z-index:1000}.dropzone .dz-preview:hover .dz-details{opacity:1}.dropzone .dz-preview.dz-file-preview .dz-image{border-radius:20px;background:#999;background:linear-gradient(to bottom, #eee, #ddd)}.dropzone .dz-preview.dz-file-preview .dz-details{opacity:1}.dropzone .dz-preview.dz-image-preview{background:#fff}.dropzone .dz-preview.dz-image-preview .dz-details{-webkit-transition:opacity 0.2s linear;-moz-transition:opacity 0.2s linear;-ms-transition:opacity 0.2s linear;-o-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.dropzone .dz-preview .dz-remove{font-size:14px;text-align:center;display:block;cursor:pointer;border:none}.dropzone .dz-preview .dz-remove:hover{text-decoration:underline}.dropzone .dz-preview:hover .dz-details{opacity:1}.dropzone .dz-preview .dz-details{z-index:20;position:absolute;top:0;left:0;opacity:0;font-size:13px;min-width:100%;max-width:100%;padding:2em 1em;text-align:center;color:rgba(0,0,0,.9);line-height:150%}.dropzone .dz-preview .dz-details .dz-size{margin-bottom:1em;font-size:16px}.dropzone .dz-preview .dz-details .dz-filename{white-space:nowrap}.dropzone .dz-preview .dz-details .dz-filename:hover span{border:1px solid rgba(200,200,200,.8);background-color:rgba(255,255,255,.8)}.dropzone .dz-preview .dz-details .dz-filename:not(:hover){overflow:hidden;text-overflow:ellipsis}.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span{border:1px solid transparent}.dropzone .dz-preview .dz-details .dz-filename span,.dropzone .dz-preview .dz-details .dz-size span{background-color:rgba(255,255,255,.4);padding:0 .4em;border-radius:3px}.dropzone .dz-preview:hover .dz-image img{-webkit-transform:scale(1.05, 1.05);-moz-transform:scale(1.05, 1.05);-ms-transform:scale(1.05, 1.05);-o-transform:scale(1.05, 1.05);transform:scale(1.05, 1.05);-webkit-filter:blur(8px);filter:blur(8px)}.dropzone .dz-preview .dz-image{border-radius:20px;overflow:hidden;width:120px;height:120px;position:relative;display:block;z-index:10}.dropzone .dz-preview .dz-image img{display:block}.dropzone .dz-preview.dz-success .dz-success-mark{-webkit-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);-moz-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);-ms-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);-o-animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);animation:passing-through 3s cubic-bezier(0.77, 0, 0.175, 1)}.dropzone .dz-preview.dz-error .dz-error-mark{opacity:1;-webkit-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);-moz-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);-ms-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);-o-animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);animation:slide-in 3s cubic-bezier(0.77, 0, 0.175, 1)}.dropzone .dz-preview .dz-success-mark,.dropzone .dz-preview .dz-error-mark{pointer-events:none;opacity:0;z-index:500;position:absolute;display:block;top:50%;left:50%;margin-left:-27px;margin-top:-27px}.dropzone .dz-preview .dz-success-mark svg,.dropzone .dz-preview .dz-error-mark svg{display:block;width:54px;height:54px}.dropzone .dz-preview.dz-processing .dz-progress{opacity:1;-webkit-transition:all 0.2s linear;-moz-transition:all 0.2s linear;-ms-transition:all 0.2s linear;-o-transition:all 0.2s linear;transition:all 0.2s linear}.dropzone .dz-preview.dz-complete .dz-progress{opacity:0;-webkit-transition:opacity 0.4s ease-in;-moz-transition:opacity 0.4s ease-in;-ms-transition:opacity 0.4s ease-in;-o-transition:opacity 0.4s ease-in;transition:opacity 0.4s ease-in}.dropzone .dz-preview:not(.dz-processing) .dz-progress{-webkit-animation:pulse 6s ease infinite;-moz-animation:pulse 6s ease infinite;-ms-animation:pulse 6s ease infinite;-o-animation:pulse 6s ease infinite;animation:pulse 6s ease infinite}.dropzone .dz-preview .dz-progress{opacity:1;z-index:1000;pointer-events:none;position:absolute;height:16px;left:50%;top:50%;margin-top:-8px;width:80px;margin-left:-40px;background:rgba(255,255,255,.9);-webkit-transform:scale(1);border-radius:8px;overflow:hidden}.dropzone .dz-preview .dz-progress .dz-upload{background:#333;background:linear-gradient(to bottom, #666, #444);position:absolute;top:0;left:0;bottom:0;width:0;-webkit-transition:width 300ms ease-in-out;-moz-transition:width 300ms ease-in-out;-ms-transition:width 300ms ease-in-out;-o-transition:width 300ms ease-in-out;transition:width 300ms ease-in-out}.dropzone .dz-preview.dz-error .dz-error-message{display:block}.dropzone .dz-preview.dz-error:hover .dz-error-message{opacity:1;pointer-events:auto}.dropzone .dz-preview .dz-error-message{pointer-events:none;z-index:1000;position:absolute;display:block;display:none;opacity:0;-webkit-transition:opacity 0.3s ease;-moz-transition:opacity 0.3s ease;-ms-transition:opacity 0.3s ease;-o-transition:opacity 0.3s ease;transition:opacity 0.3s ease;border-radius:8px;font-size:13px;top:130px;left:-10px;width:140px;background:#be2626;background:linear-gradient(to bottom, #be2626, #a92222);padding:.5em 1.2em;color:#fff}.dropzone .dz-preview .dz-error-message:after{content:"";position:absolute;top:-6px;left:64px;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #be2626} diff --git a/view/theme/frio/templates/admin/storage.tpl b/view/theme/frio/templates/admin/storage.tpl index 1a63d1817f..c1bfe371bc 100644 --- a/view/theme/frio/templates/admin/storage.tpl +++ b/view/theme/frio/templates/admin/storage.tpl @@ -5,6 +5,9 @@
{{$label_current}}: {{$storagebackend}} + {{if $storagebackend_ro_txt}} +
{{$storagebackend_ro_txt nofilter}} + {{/if}}

{{$label_config}}

@@ -33,12 +36,14 @@ diff --git a/view/theme/frio/templates/comment_item.tpl b/view/theme/frio/templates/comment_item.tpl index 2d977d807c..45a6116aa3 100644 --- a/view/theme/frio/templates/comment_item.tpl +++ b/view/theme/frio/templates/comment_item.tpl @@ -38,7 +38,7 @@

-
+

diff --git a/view/theme/frio/templates/field_select.tpl b/view/theme/frio/templates/field_select.tpl index 25cfd652cd..d5bcfdad61 100644 --- a/view/theme/frio/templates/field_select.tpl +++ b/view/theme/frio/templates/field_select.tpl @@ -1,7 +1,7 @@
- {{foreach $field.4 as $opt=>$val}} {{/foreach}}