diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index f81ab960f7..0c951d7018 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -1,4 +1,4 @@ -pipeline: +steps: restore_cache: image: meltwater/drone-cache:dev settings: diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index 767fffde3d..4ff956b3b6 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -11,11 +11,11 @@ labels: skip_clone: true -pipeline: +steps: clone: image: alpine/git commands: - - git clone $CI_REPO_LINK . + - git clone $CI_REPO_CLONE_URL . - git checkout $CI_COMMIT_BRANCH - git fetch origin $CI_COMMIT_REF - git merge $CI_COMMIT_SHA diff --git a/.woodpecker/.database_checks.yml b/.woodpecker/.database_checks.yml index 04bdeed620..7d25536749 100644 --- a/.woodpecker/.database_checks.yml +++ b/.woodpecker/.database_checks.yml @@ -6,7 +6,11 @@ matrix: branches: exclude: [ stable ] -pipeline: +# This forces CI executions at the "opensocial" labeled location (because of much more power...) +labels: + location: opensocial + +steps: db_version_match: image: friendicaci/transifex commands: diff --git a/.woodpecker/.license_check.yml b/.woodpecker/.license_check.yml index 777986544a..e7545f5f43 100644 --- a/.woodpecker/.license_check.yml +++ b/.woodpecker/.license_check.yml @@ -1,4 +1,4 @@ -pipeline: +steps: check: image: friendicaci/php-cs commands: diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index c5b283e1d3..9c25095940 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -1,4 +1,4 @@ -pipeline: +steps: build_xgettext: image: friendicaci/transifex commands: @@ -9,4 +9,4 @@ pipeline: - /check-messages.sh branches: - exclude: [ stable ] \ No newline at end of file + exclude: [ stable ] diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 8f89e4b5b4..302bd911d7 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -15,12 +15,12 @@ matrix: labels: location: opensocial -pipeline: +steps: php-lint: image: php:${PHP_MAJOR_VERSION} group: lint commands: - - ./bin/composer.phar run lint + - find . -name \*.php -not -path './vendor/*' -not -path './view/asset/*' -print0 | xargs -0 -n1 php -l restore_cache: image: meltwater/drone-cache:dev settings: diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index 482ea5429d..006bcfec37 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -9,11 +9,11 @@ labels: skip_clone: true -pipeline: +steps: clone: image: alpine/git commands: - - git clone $CI_REPO_LINK . + - git clone $CI_REPO_CLONE_URL . - git checkout $CI_COMMIT_BRANCH - git fetch origin $CI_COMMIT_REF - git merge $CI_COMMIT_SHA diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php index b923009e64..3a95532464 100755 --- a/bin/auth_ejabberd.php +++ b/bin/auth_ejabberd.php @@ -58,7 +58,7 @@ if (php_sapi_name() !== 'cli') { use Dice\Dice; use Friendica\App\Mode; -use Friendica\Core\Logger\Capabilities\LogChannel; +use Friendica\Core\Logger\Capability\LogChannel; use Friendica\Security\ExAuth; use Psr\Log\LoggerInterface; @@ -79,8 +79,8 @@ chdir($directory); require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php'); -/** @var \Friendica\Core\Addon\Capabilities\ICanLoadAddons $addonLoader */ -$addonLoader = $dice->create(\Friendica\Core\Addon\Capabilities\ICanLoadAddons::class); +/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */ +$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class); $dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies')); $dice = $dice->addRule(LoggerInterface::class,['constructParams' => [LogChannel::AUTH_JABBERED]]); diff --git a/bin/console.php b/bin/console.php index b2cde10823..b797e6ba99 100755 --- a/bin/console.php +++ b/bin/console.php @@ -26,15 +26,15 @@ if (php_sapi_name() !== 'cli') { } use Dice\Dice; -use Friendica\Core\Logger\Capabilities\LogChannel; +use Friendica\Core\Logger\Capability\LogChannel; use Friendica\DI; use Psr\Log\LoggerInterface; require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php'); -/** @var \Friendica\Core\Addon\Capabilities\ICanLoadAddons $addonLoader */ -$addonLoader = $dice->create(\Friendica\Core\Addon\Capabilities\ICanLoadAddons::class); +/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */ +$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class); $dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies')); $dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [LogChannel::CONSOLE]]); diff --git a/bin/daemon.php b/bin/daemon.php index 11bad2b11a..cd774fe25e 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -60,10 +60,10 @@ if (!file_exists('index.php') && (sizeof($_SERVER['argv']) != 0)) { require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php'); -/** @var \Friendica\Core\Addon\Capabilities\ICanLoadAddons $addonLoader */ -$addonLoader = $dice->create(\Friendica\Core\Addon\Capabilities\ICanLoadAddons::class); +/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */ +$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class); $dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies')); -$dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [Logger\Capabilities\LogChannel::DAEMON]]); +$dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [Logger\Capability\LogChannel::DAEMON]]); DI::init($dice); \Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class)); diff --git a/bin/worker.php b/bin/worker.php index 42a8f533d3..c855f9bc55 100755 --- a/bin/worker.php +++ b/bin/worker.php @@ -29,7 +29,7 @@ if (php_sapi_name() !== 'cli') { use Dice\Dice; use Friendica\App; use Friendica\App\Mode; -use Friendica\Core\Logger\Capabilities\LogChannel; +use Friendica\Core\Logger\Capability\LogChannel; use Friendica\Core\Update; use Friendica\Core\Worker; use Friendica\DI; @@ -55,8 +55,8 @@ if (!file_exists("index.php") && (sizeof($_SERVER["argv"]) != 0)) { require dirname(__DIR__) . '/vendor/autoload.php'; $dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php'); -/** @var \Friendica\Core\Addon\Capabilities\ICanLoadAddons $addonLoader */ -$addonLoader = $dice->create(\Friendica\Core\Addon\Capabilities\ICanLoadAddons::class); +/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */ +$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class); $dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies')); $dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [LogChannel::WORKER]]); diff --git a/composer.json b/composer.json index 60094d5bd2..9a86ebc2cc 100644 --- a/composer.json +++ b/composer.json @@ -77,6 +77,12 @@ "npm-asset/textcomplete": "^0.18.2", "npm-asset/typeahead.js": "^0.11.1" }, + "suggest": { + "ext-imagick": "For faster image processing", + "ext-redis": "To use Redis as a locking or caching provider", + "ext-pdo": "To use PDO as a database driver, has priority over mysqli unless database.disable_pdo is set", + "ext-mysqli": "To use mysqli as a databse driver" + }, "repositories": [ { "type": "vcs", diff --git a/database.sql b/database.sql index 5a8cee23c4..74b7552c30 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2023.09-dev (Giant Rhubarb) --- DB_UPDATE_VERSION 1523 +-- DB_UPDATE_VERSION 1524 -- ------------------------------------------ @@ -1834,8 +1834,8 @@ CREATE TABLE IF NOT EXISTS `user-contact` ( `rel` tinyint unsigned COMMENT 'The kind of the relation between the user and the contact', `info` mediumtext COMMENT '', `notify_new_posts` boolean COMMENT '', - `remote_self` boolean COMMENT '', - `fetch_further_information` tinyint unsigned COMMENT '', + `remote_self` tinyint unsigned COMMENT '0 => No mirroring, 1-2 => Mirror as own post, 3 => Mirror as reshare', + `fetch_further_information` tinyint unsigned COMMENT '0 => None, 1 => Fetch information, 3 => Fetch keywords, 2 => Fetch both', `ffi_keyword_denylist` text COMMENT '', `subhub` boolean COMMENT '', `hub-verify` varbinary(383) COMMENT '', diff --git a/doc/StrategyHooks.md b/doc/StrategyHooks.md index 39fc1bd8df..2960ceeaad 100644 --- a/doc/StrategyHooks.md +++ b/doc/StrategyHooks.md @@ -10,9 +10,9 @@ This type of hook is based on the [Strategy Design Pattern](https://refactoring. A strategy class defines a possible implementation of a given interface based on a unique name. Every name is possible as long as it's unique and not `null`. Using an empty name (`''`) is possible as well and should be used as the "default" implementation. -To register a strategy, use the [`ICanRegisterInstance`](../src/Core/Hooks/Capabilities/ICanRegisterInstances.php) interface. +To register a strategy, use the [`ICanRegisterInstance`](../src/Core/Hooks/Capability/ICanRegisterInstances.php) interface. -After registration, a caller can automatically create this instance with the [`ICanCreateInstances`](../src/Core/Hooks/Capabilities/ICanCreateInstances.php) interface and the chosen name. +After registration, a caller can automatically create this instance with the [`ICanCreateInstances`](../src/Core/Hooks/Capability/ICanCreateInstances.php) interface and the chosen name. This is useful in case there are different, possible implementations for the same purpose, like for logging, locking, caching, ... @@ -43,11 +43,11 @@ public class ConcreteClassB implements ExampleInterface } } -/** @var \Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies $instanceRegister */ +/** @var \Friendica\Core\Hooks\Capability\ICanRegisterStrategies $instanceRegister */ $instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassA::class, 'A'); $instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassB::class, 'B'); -/** @var \Friendica\Core\Hooks\Capabilities\ICanCreateInstances $instanceManager */ +/** @var \Friendica\Core\Hooks\Capability\ICanCreateInstances $instanceManager */ /** @var ConcreteClassA $concreteClass */ $concreteClass = $instanceManager->create(ExampleInterface::class, 'A'); @@ -62,14 +62,14 @@ To avoid registering all strategies manually inside the code, Friendica introduc There, you can register all kind of strategies in one file. -### [`HookType::STRATEGY`](../src/Core/Hooks/Capabilities/HookType.php) +### [`HookType::STRATEGY`](../src/Core/Hooks/Capability/HookType.php) For each given interface, a list of key-value pairs can be set, where the key is the concrete implementation class and the value is an array of unique names. ### Example ```php -use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H; +use Friendica\Core\Hooks\Capability\BehavioralHookType as H; return [ H::STRATEGY => [ diff --git a/index.php b/index.php index ce82470b64..87778308a5 100644 --- a/index.php +++ b/index.php @@ -30,8 +30,8 @@ if (!file_exists(__DIR__ . '/vendor/autoload.php')) { require __DIR__ . '/vendor/autoload.php'; $dice = (new Dice())->addRules(include __DIR__ . '/static/dependencies.config.php'); -/** @var \Friendica\Core\Addon\Capabilities\ICanLoadAddons $addonLoader */ -$addonLoader = $dice->create(\Friendica\Core\Addon\Capabilities\ICanLoadAddons::class); +/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */ +$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class); $dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies')); $dice = $dice->addRule(Friendica\App\Mode::class, ['call' => [['determineRunMode', [false, $_SERVER], Dice::CHAIN_CALL]]]); diff --git a/mod/item.php b/mod/item.php index e15ca639c4..72c2ed8c5d 100644 --- a/mod/item.php +++ b/mod/item.php @@ -266,6 +266,7 @@ function item_process(array $post, array $request, bool $preview, string $return $post['uri-id'] = -1; $post['author-network'] = Protocol::DFRN; $post['author-updated'] = ''; + $post['author-alias'] = ''; $post['author-gsid'] = 0; $post['author-uri-id'] = ItemURI::getIdByURI($post['author-link']); $post['owner-updated'] = ''; diff --git a/src/App/BaseURL.php b/src/App/BaseURL.php index 4030306849..cc20343d1c 100644 --- a/src/App/BaseURL.php +++ b/src/App/BaseURL.php @@ -127,4 +127,14 @@ class BaseURL extends Uri implements UriInterface $redirectTo = $this->__toString() . '/' . ltrim($toUrl, '/'); System::externalRedirect($redirectTo); } + + public function isLocalUrl(string $url): bool + { + return strpos(Strings::normaliseLink($url), Strings::normaliseLink((string)$this)) === 0; + } + + public function isLocalUri(UriInterface $uri): bool + { + return $this->isLocalUrl((string)$uri); + } } diff --git a/src/Console/PostUpdate.php b/src/Console/PostUpdate.php index 742197e732..42cc63e109 100644 --- a/src/Console/PostUpdate.php +++ b/src/Console/PostUpdate.php @@ -22,7 +22,7 @@ namespace Friendica\Console; use Friendica\App; -use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Core\L10n; use Friendica\Core\Update; diff --git a/src/Console/Relay.php b/src/Console/Relay.php index 52682241e6..11d1dbf821 100644 --- a/src/Console/Relay.php +++ b/src/Console/Relay.php @@ -23,8 +23,8 @@ namespace Friendica\Console; use Asika\SimpleConsole\CommandArgsException; use Friendica\Model\APContact; -use Friendica\Model\Contact; use Friendica\Protocol\ActivityPub\Transmitter; +use Friendica\Protocol\Relay as ProtocolRelay; /** * tool to control the list of ActivityPub relay servers from the CLI @@ -90,13 +90,9 @@ HELP; } if ((count($this->args) == 1) && ($this->getArgument(0) == 'list')) { - $contacts = $this->dba->select('apcontact', ['url'], - ["`type` IN (?, ?) AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` = ?)", - 'Application', 'Service', 0, Contact::FRIEND]); - while ($contact = $this->dba->fetch($contacts)) { + foreach (ProtocolRelay::getList(['url']) as $contact) { $this->out($contact['url']); } - $this->dba->close($contacts); } elseif (count($this->args) == 0) { throw new CommandArgsException('too few arguments'); } elseif (count($this->args) == 1) { diff --git a/src/Contact/LocalRelationship/Entity/LocalRelationship.php b/src/Contact/LocalRelationship/Entity/LocalRelationship.php index 8a9c48745f..4fc7ae3660 100644 --- a/src/Contact/LocalRelationship/Entity/LocalRelationship.php +++ b/src/Contact/LocalRelationship/Entity/LocalRelationship.php @@ -36,7 +36,7 @@ use Friendica\Model\Contact; * @property-read int $rel * @property-read string $info * @property-read bool $notifyNewPosts - * @property-read bool $isRemoteSelf + * @property-read int $remoteSelf * @property-read int $fetchFurtherInformation * @property-read string $ffiKeywordDenylist * @property-read bool $subhub @@ -47,6 +47,16 @@ use Friendica\Model\Contact; */ class LocalRelationship extends \Friendica\BaseEntity { + // Fetch Further Information options, not a binary flag + const FFI_NONE = 0; + const FFI_INFORMATION = 1; + const FFI_KEYWORD = 3; + const FFI_BOTH = 2; + + const MIRROR_DEACTIVATED = 0; + const MIRROR_OWN_POST = 2; + const MIRROR_NATIVE_RESHARE = 3; + /** @var int */ protected $userId; /** @var int */ @@ -67,9 +77,9 @@ class LocalRelationship extends \Friendica\BaseEntity protected $info; /** @var bool */ protected $notifyNewPosts; - /** @var bool */ - protected $isRemoteSelf; - /** @var int */ + /** @var int One of MIRROR_* */ + protected $remoteSelf; + /** @var int One of FFI_* */ protected $fetchFurtherInformation; /** @var string */ protected $ffiKeywordDenylist; @@ -84,7 +94,7 @@ class LocalRelationship extends \Friendica\BaseEntity /** @var int */ protected $priority; - public function __construct(int $userId, int $contactId, bool $blocked = false, bool $ignored = false, bool $collapsed = false, bool $hidden = false, bool $pending = false, int $rel = Contact::NOTHING, string $info = '', bool $notifyNewPosts = false, bool $isRemoteSelf = false, int $fetchFurtherInformation = 0, string $ffiKeywordDenylist = '', bool $subhub = false, string $hubVerify = '', string $protocol = Protocol::PHANTOM, ?int $rating = null, ?int $priority = null) + public function __construct(int $userId, int $contactId, bool $blocked = false, bool $ignored = false, bool $collapsed = false, bool $hidden = false, bool $pending = false, int $rel = Contact::NOTHING, string $info = '', bool $notifyNewPosts = false, int $remoteSelf = self::MIRROR_DEACTIVATED, int $fetchFurtherInformation = self::FFI_NONE, string $ffiKeywordDenylist = '', bool $subhub = false, string $hubVerify = '', string $protocol = Protocol::PHANTOM, ?int $rating = null, ?int $priority = null) { $this->userId = $userId; $this->contactId = $contactId; @@ -96,7 +106,7 @@ class LocalRelationship extends \Friendica\BaseEntity $this->rel = $rel; $this->info = $info; $this->notifyNewPosts = $notifyNewPosts; - $this->isRemoteSelf = $isRemoteSelf; + $this->remoteSelf = $remoteSelf; $this->fetchFurtherInformation = $fetchFurtherInformation; $this->ffiKeywordDenylist = $ffiKeywordDenylist; $this->subhub = $subhub; diff --git a/src/Contact/LocalRelationship/Factory/LocalRelationship.php b/src/Contact/LocalRelationship/Factory/LocalRelationship.php index 455dbe1c3c..54fc86215c 100644 --- a/src/Contact/LocalRelationship/Factory/LocalRelationship.php +++ b/src/Contact/LocalRelationship/Factory/LocalRelationship.php @@ -45,8 +45,8 @@ class LocalRelationship extends BaseFactory implements ICanCreateFromTableRow $row['rel'] ?? Contact::NOTHING, $row['info'] ?? '', $row['notify_new_posts'] ?? false, - $row['remote_self'] ?? false, - $row['fetch_further_information'] ?? 0, + $row['remote_self'] ?? Entity\LocalRelationship::MIRROR_DEACTIVATED, + $row['fetch_further_information'] ?? Entity\LocalRelationship::FFI_NONE, $row['ffi_keyword_denylist'] ?? '', $row['subhub'] ?? false, $row['hub-verify'] ?? '', diff --git a/src/Contact/LocalRelationship/Repository/LocalRelationship.php b/src/Contact/LocalRelationship/Repository/LocalRelationship.php index a80a4f897b..490a84e44d 100644 --- a/src/Contact/LocalRelationship/Repository/LocalRelationship.php +++ b/src/Contact/LocalRelationship/Repository/LocalRelationship.php @@ -100,7 +100,7 @@ class LocalRelationship extends \Friendica\BaseRepository 'rel' => $localRelationship->rel, 'info' => $localRelationship->info, 'notify_new_posts' => $localRelationship->notifyNewPosts, - 'remote_self' => $localRelationship->isRemoteSelf, + 'remote_self' => $localRelationship->remoteSelf, 'fetch_further_information' => $localRelationship->fetchFurtherInformation, 'ffi_keyword_denylist' => $localRelationship->ffiKeywordDenylist, 'subhub' => $localRelationship->subhub, diff --git a/src/Content/ContactSelector.php b/src/Content/ContactSelector.php index e4585cd297..5d33aa59e4 100644 --- a/src/Content/ContactSelector.php +++ b/src/Content/ContactSelector.php @@ -220,7 +220,8 @@ class ContactSelector 'GNU Social' => 'gnu-social', 'gnusocial' => 'gnu-social', 'hubzilla' => 'hubzilla', 'mastodon' => 'mastodon', 'peertube' => 'peertube', 'pixelfed' => 'pixelfed', 'pleroma' => 'pleroma', 'red' => 'hubzilla', 'redmatrix' => 'hubzilla', - 'socialhome' => 'social-home', 'wordpress' => 'wordpress', 'lemmy' => 'users']; + 'socialhome' => 'social-home', 'wordpress' => 'wordpress', 'lemmy' => 'users', + 'firefish' => 'fire', 'calckey' => 'calculator', 'kbin' => 'check']; $search = array_keys($nets); $replace = array_values($nets); diff --git a/src/Content/Item.php b/src/Content/Item.php index f7dda6c65f..c25e5296f0 100644 --- a/src/Content/Item.php +++ b/src/Content/Item.php @@ -544,7 +544,7 @@ class Item unset($item['owner-name']); unset($item['owner-avatar']); } - + $item['postopts'] = ''; } diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index f40160c9de..ab7300da18 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1158,6 +1158,40 @@ class BBCode return $match[1] . '[url=' . $data['url'] . ']' . $data['nick'] . '[/url]'; } + /** + * Normalize links to Youtube and Vimeo to a unified format. + * + * @param string $text + * @return string + */ + private static function normalizeVideoLinks(string $text): string + { + $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); + $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); + $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/shorts\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); + $text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); + + $text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text); + $text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text); + + return $text; + } + + /** + * Expand Youtube and Vimeo links to + * + * @param string $text + * @return string + */ + public static function expandVideoLinks(string $text): string + { + $text = self::normalizeVideoLinks($text); + $text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '[url=https://www.youtube.com/watch?v=$1]https://www.youtube.com/watch?v=$1[/url]', $text); + $text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '[url=https://vimeo.com/$1]https://vimeo.com/$1[/url]', $text); + + return $text; + } + /** * Converts a BBCode message for a given URI-ID to a HTML message * @@ -1655,12 +1689,9 @@ class BBCode // Backward compatibility, [iframe] support has been removed in version 2020.12 $text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '$1', $text); - // Youtube extensions - $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); - $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); - $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/shorts\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); - $text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text); + $text = self::normalizeVideoLinks($text); + // Youtube extensions if ($try_oembed) { $text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '', $text); } else { @@ -1671,9 +1702,7 @@ class BBCode ); } - $text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text); - $text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text); - + // Vimeo extensions if ($try_oembed) { $text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '', $text); } else { diff --git a/src/Content/Widget.php b/src/Content/Widget.php index c8c0230c68..ce4548d1ad 100644 --- a/src/Content/Widget.php +++ b/src/Content/Widget.php @@ -102,7 +102,7 @@ class Widget public static function unavailableNetworks(): array { // Always hide content from these networks - $networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::ZOT]; + $networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::TWITTER, Protocol::ZOT]; if (!Addon::isEnabled("discourse")) { $networks[] = Protocol::DISCOURSE; @@ -116,10 +116,6 @@ class Widget $networks[] = Protocol::PUMPIO; } - if (!Addon::isEnabled("twitter")) { - $networks[] = Protocol::TWITTER; - } - if (!Addon::isEnabled("tumblr")) { $networks[] = Protocol::TUMBLR; } diff --git a/src/Core/Addon/Capabilities/ICanLoadAddons.php b/src/Core/Addon/Capability/ICanLoadAddons.php similarity index 96% rename from src/Core/Addon/Capabilities/ICanLoadAddons.php rename to src/Core/Addon/Capability/ICanLoadAddons.php index 9c9d1e841c..42af1a7b37 100644 --- a/src/Core/Addon/Capabilities/ICanLoadAddons.php +++ b/src/Core/Addon/Capability/ICanLoadAddons.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\Addon\Capabilities; +namespace Friendica\Core\Addon\Capability; /** * Interface for loading Addons specific content diff --git a/src/Core/Addon/Model/AddonLoader.php b/src/Core/Addon/Model/AddonLoader.php index 952246af0a..e808f21777 100644 --- a/src/Core/Addon/Model/AddonLoader.php +++ b/src/Core/Addon/Model/AddonLoader.php @@ -21,7 +21,7 @@ namespace Friendica\Core\Addon\Model; -use Friendica\Core\Addon\Capabilities\ICanLoadAddons; +use Friendica\Core\Addon\Capability\ICanLoadAddons; use Friendica\Core\Addon\Exception\AddonInvalidConfigFileException; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Util\Strings; diff --git a/src/Core/Cache/Factory/Cache.php b/src/Core/Cache/Factory/Cache.php index 107c6ab216..0c54bfe630 100644 --- a/src/Core/Cache/Factory/Cache.php +++ b/src/Core/Cache/Factory/Cache.php @@ -21,16 +21,13 @@ namespace Friendica\Core\Cache\Factory; -use Friendica\App\BaseURL; -use Friendica\Core\Cache\Enum; use Friendica\Core\Cache\Capability\ICanCache; use Friendica\Core\Cache\Exception\CachePersistenceException; use Friendica\Core\Cache\Exception\InvalidCacheDriverException; use Friendica\Core\Cache\Type; use Friendica\Core\Config\Capability\IManageConfigValues; -use Friendica\Database\Database; +use Friendica\Core\Hooks\Capability\ICanCreateInstances; use Friendica\Util\Profiler; -use Psr\Log\LoggerInterface; /** * Class CacheFactory @@ -44,59 +41,32 @@ class Cache /** * @var string The default cache if nothing set */ - const DEFAULT_TYPE = Enum\Type::DATABASE; + const DEFAULT_TYPE = Type\DatabaseCache::NAME; + /** @var ICanCreateInstances */ + protected $instanceCreator; + /** @var IManageConfigValues */ + protected $config; + /** @var Profiler */ + protected $profiler; - /** - * @var IManageConfigValues The IConfiguration to read parameters out of the config - */ - private $config; - - /** - * @var Database The database connection in case that the cache is used the dba connection - */ - private $dba; - - /** - * @var string The hostname, used as Prefix for Caching - */ - private $hostname; - - /** - * @var Profiler The optional profiler if the cached should be profiled - */ - private $profiler; - - /** - * @var LoggerInterface The Friendica Logger - */ - private $logger; - - public function __construct(BaseURL $baseURL, IManageConfigValues $config, Database $dba, Profiler $profiler, LoggerInterface $logger) + public function __construct(ICanCreateInstances $instanceCreator, IManageConfigValues $config, Profiler $profiler) { - $this->hostname = $baseURL->getHost(); - $this->config = $config; - $this->dba = $dba; - $this->profiler = $profiler; - $this->logger = $logger; + $this->config = $config; + $this->instanceCreator = $instanceCreator; + $this->profiler = $profiler; } /** - * This method creates a CacheDriver for distributed caching with the given cache driver name - * - * @param string|null $type The cache type to create (default is per config) + * This method creates a CacheDriver for distributed caching * * @return ICanCache The instance of the CacheDriver * * @throws InvalidCacheDriverException In case the underlying cache driver isn't valid or not configured properly * @throws CachePersistenceException In case the underlying cache has errors during persistence */ - public function createDistributed(string $type = null): ICanCache + public function createDistributed(): ICanCache { - if ($type === Enum\Type::APCU) { - throw new InvalidCacheDriverException('apcu doesn\'t support distributed caching.'); - } - - return $this->create($type ?? $this->config->get('system', 'distributed_cache_driver', self::DEFAULT_TYPE)); + return $this->create($this->config->get('system', 'distributed_cache_driver', self::DEFAULT_TYPE)); } /** @@ -117,31 +87,17 @@ class Cache /** * Creates a new Cache instance * - * @param string $type The type of cache + * @param string $strategy The strategy, which cache instance should be used * * @return ICanCache * * @throws InvalidCacheDriverException In case the underlying cache driver isn't valid or not configured properly * @throws CachePersistenceException In case the underlying cache has errors during persistence */ - protected function create(string $type): ICanCache + protected function create(string $strategy): ICanCache { - switch ($type) { - case Enum\Type::MEMCACHE: - $cache = new Type\MemcacheCache($this->hostname, $this->config); - break; - case Enum\Type::MEMCACHED: - $cache = new Type\MemcachedCache($this->hostname, $this->config, $this->logger); - break; - case Enum\Type::REDIS: - $cache = new Type\RedisCache($this->hostname, $this->config); - break; - case Enum\Type::APCU: - $cache = new Type\APCuCache($this->hostname); - break; - default: - $cache = new Type\DatabaseCache($this->hostname, $this->dba); - } + /** @var ICanCache $cache */ + $cache = $this->instanceCreator->create(ICanCache::class, $strategy); $profiling = $this->config->get('system', 'profiling', false); diff --git a/src/Core/Cache/Type/APCuCache.php b/src/Core/Cache/Type/APCuCache.php index 05eb2fa074..f35815c15a 100644 --- a/src/Core/Cache/Type/APCuCache.php +++ b/src/Core/Cache/Type/APCuCache.php @@ -23,7 +23,6 @@ namespace Friendica\Core\Cache\Type; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Cache\Capability\ICanCacheInMemory; -use Friendica\Core\Cache\Enum\Type; use Friendica\Core\Cache\Exception\InvalidCacheDriverException; /** @@ -31,12 +30,12 @@ use Friendica\Core\Cache\Exception\InvalidCacheDriverException; */ class APCuCache extends AbstractCache implements ICanCacheInMemory { + const NAME = 'apcu'; + use CompareSetTrait; use CompareDeleteTrait; /** - * @param string $hostname - * * @throws InvalidCacheDriverException */ public function __construct(string $hostname) @@ -173,12 +172,4 @@ class APCuCache extends AbstractCache implements ICanCacheInMemory return true; } - - /** - * {@inheritDoc} - */ - public function getName(): string - { - return Type::APCU; - } } diff --git a/src/Core/Cache/Type/AbstractCache.php b/src/Core/Cache/Type/AbstractCache.php index 5c00542a77..211f28b9a6 100644 --- a/src/Core/Cache/Type/AbstractCache.php +++ b/src/Core/Cache/Type/AbstractCache.php @@ -28,6 +28,8 @@ use Friendica\Core\Cache\Capability\ICanCache; */ abstract class AbstractCache implements ICanCache { + const NAME = ''; + /** * @var string The hostname */ @@ -105,4 +107,10 @@ abstract class AbstractCache implements ICanCache return $result; } } + + /** {@inheritDoc} */ + public function getName(): string + { + return static::NAME; + } } diff --git a/src/Core/Cache/Type/ArrayCache.php b/src/Core/Cache/Type/ArrayCache.php index 8886a886a7..34246afffa 100644 --- a/src/Core/Cache/Type/ArrayCache.php +++ b/src/Core/Cache/Type/ArrayCache.php @@ -29,6 +29,8 @@ use Friendica\Core\Cache\Enum; */ class ArrayCache extends AbstractCache implements ICanCacheInMemory { + const NAME = 'array'; + use CompareDeleteTrait; /** @var array Array with the cached data */ @@ -108,12 +110,4 @@ class ArrayCache extends AbstractCache implements ICanCacheInMemory return false; } } - - /** - * {@inheritDoc} - */ - public function getName(): string - { - return Enum\Type::ARRAY; - } } diff --git a/src/Core/Cache/Type/DatabaseCache.php b/src/Core/Cache/Type/DatabaseCache.php index fa7968b650..4959d6a751 100644 --- a/src/Core/Cache/Type/DatabaseCache.php +++ b/src/Core/Cache/Type/DatabaseCache.php @@ -32,6 +32,8 @@ use Friendica\Util\DateTimeFormat; */ class DatabaseCache extends AbstractCache implements ICanCache { + const NAME = 'database'; + /** * @var Database */ @@ -154,12 +156,4 @@ class DatabaseCache extends AbstractCache implements ICanCache throw new CachePersistenceException('Cannot clear cache', $exception); } } - - /** - * {@inheritDoc} - */ - public function getName(): string - { - return Enum\Type::DATABASE; - } } diff --git a/src/Core/Cache/Type/MemcacheCache.php b/src/Core/Cache/Type/MemcacheCache.php index d19e7deb1d..e8d3b07c8e 100644 --- a/src/Core/Cache/Type/MemcacheCache.php +++ b/src/Core/Cache/Type/MemcacheCache.php @@ -23,7 +23,6 @@ namespace Friendica\Core\Cache\Type; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Cache\Capability\ICanCacheInMemory; -use Friendica\Core\Cache\Enum\Type; use Friendica\Core\Cache\Exception\CachePersistenceException; use Friendica\Core\Cache\Exception\InvalidCacheDriverException; use Friendica\Core\Config\Capability\IManageConfigValues; @@ -34,6 +33,8 @@ use Memcache; */ class MemcacheCache extends AbstractCache implements ICanCacheInMemory { + const NAME = 'memcache'; + use CompareSetTrait; use CompareDeleteTrait; use MemcacheCommandTrait; @@ -169,12 +170,4 @@ class MemcacheCache extends AbstractCache implements ICanCacheInMemory $cacheKey = $this->getCacheKey($key); return $this->memcache->add($cacheKey, serialize($value), MEMCACHE_COMPRESSED, $ttl); } - - /** - * {@inheritDoc} - */ - public function getName(): string - { - return Type::MEMCACHE; - } } diff --git a/src/Core/Cache/Type/MemcachedCache.php b/src/Core/Cache/Type/MemcachedCache.php index 6d994ddf57..160c5a16f4 100644 --- a/src/Core/Cache/Type/MemcachedCache.php +++ b/src/Core/Cache/Type/MemcachedCache.php @@ -23,7 +23,6 @@ namespace Friendica\Core\Cache\Type; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Cache\Capability\ICanCacheInMemory; -use Friendica\Core\Cache\Enum\Type; use Friendica\Core\Cache\Exception\CachePersistenceException; use Friendica\Core\Cache\Exception\InvalidCacheDriverException; use Friendica\Core\Config\Capability\IManageConfigValues; @@ -35,6 +34,8 @@ use Psr\Log\LoggerInterface; */ class MemcachedCache extends AbstractCache implements ICanCacheInMemory { + const NAME = 'memcached'; + use CompareSetTrait; use CompareDeleteTrait; use MemcacheCommandTrait; @@ -185,12 +186,4 @@ class MemcachedCache extends AbstractCache implements ICanCacheInMemory $cacheKey = $this->getCacheKey($key); return $this->memcached->add($cacheKey, $value, $ttl); } - - /** - * {@inheritDoc} - */ - public function getName(): string - { - return Type::MEMCACHED; - } } diff --git a/src/Core/Cache/Type/RedisCache.php b/src/Core/Cache/Type/RedisCache.php index b1fb9ba9c3..a6ce7c44b2 100644 --- a/src/Core/Cache/Type/RedisCache.php +++ b/src/Core/Cache/Type/RedisCache.php @@ -21,10 +21,8 @@ namespace Friendica\Core\Cache\Type; -use Exception; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Cache\Capability\ICanCacheInMemory; -use Friendica\Core\Cache\Enum\Type; use Friendica\Core\Cache\Exception\CachePersistenceException; use Friendica\Core\Cache\Exception\InvalidCacheDriverException; use Friendica\Core\Config\Capability\IManageConfigValues; @@ -35,6 +33,8 @@ use Redis; */ class RedisCache extends AbstractCache implements ICanCacheInMemory { + const NAME = 'redis'; + /** * @var Redis */ @@ -57,20 +57,30 @@ class RedisCache extends AbstractCache implements ICanCacheInMemory $redis_host = $config->get('system', 'redis_host'); $redis_port = $config->get('system', 'redis_port'); $redis_pw = $config->get('system', 'redis_password'); - $redis_db = $config->get('system', 'redis_db', 0); + $redis_db = (int)$config->get('system', 'redis_db', 0); - if (!empty($redis_port) && !@$this->redis->connect($redis_host, $redis_port)) { - throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available'); - } elseif (!@$this->redis->connect($redis_host)) { - throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ' isn\'t available'); - } + try { + if (is_numeric($redis_port) && $redis_port > -1) { + $connection_string = $redis_host . ':' . $redis_port; + if (!@$this->redis->connect($redis_host, $redis_port)) { + throw new CachePersistenceException('Expected Redis server at ' . $connection_string . " isn't available"); + } + } else { + $connection_string = $redis_host; + if (!@$this->redis->connect($redis_host)) { + throw new CachePersistenceException('Expected Redis server at ' . $connection_string . ' isn\'t available'); + } + } - if (!empty($redis_pw) && !$this->redis->auth($redis_pw)) { - throw new CachePersistenceException('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port); - } + if (!empty($redis_pw) && !$this->redis->auth($redis_pw)) { + throw new CachePersistenceException('Cannot authenticate redis server at ' . $connection_string); + } - if ($redis_db !== 0 && !$this->redis->select($redis_db)) { - throw new CachePersistenceException('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port); + if ($redis_db !== 0 && !$this->redis->select($redis_db)) { + throw new CachePersistenceException('Cannot switch to redis db ' . $redis_db . ' at ' . $connection_string); + } + } catch (\RedisException $exception) { + throw new CachePersistenceException('Redis connection fails unexpectedly', $exception); } } @@ -211,12 +221,4 @@ class RedisCache extends AbstractCache implements ICanCacheInMemory $this->redis->unwatch(); return false; } - - /** - * {@inheritDoc} - */ - public function getName(): string - { - return Type::REDIS; - } } diff --git a/src/Core/Hooks/Capabilities/BehavioralHookType.php b/src/Core/Hooks/Capability/BehavioralHookType.php similarity index 96% rename from src/Core/Hooks/Capabilities/BehavioralHookType.php rename to src/Core/Hooks/Capability/BehavioralHookType.php index 6336406e63..6de875e557 100644 --- a/src/Core/Hooks/Capabilities/BehavioralHookType.php +++ b/src/Core/Hooks/Capability/BehavioralHookType.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\Hooks\Capabilities; +namespace Friendica\Core\Hooks\Capability; /** * An enum of hook types, based on behavioral design patterns diff --git a/src/Core/Hooks/Capabilities/ICanCreateInstances.php b/src/Core/Hooks/Capability/ICanCreateInstances.php similarity index 97% rename from src/Core/Hooks/Capabilities/ICanCreateInstances.php rename to src/Core/Hooks/Capability/ICanCreateInstances.php index 77d4c4b366..55740d2767 100644 --- a/src/Core/Hooks/Capabilities/ICanCreateInstances.php +++ b/src/Core/Hooks/Capability/ICanCreateInstances.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\Hooks\Capabilities; +namespace Friendica\Core\Hooks\Capability; /** * creates special instances for given classes diff --git a/src/Core/Hooks/Capabilities/ICanRegisterStrategies.php b/src/Core/Hooks/Capability/ICanRegisterStrategies.php similarity index 97% rename from src/Core/Hooks/Capabilities/ICanRegisterStrategies.php rename to src/Core/Hooks/Capability/ICanRegisterStrategies.php index 911eb3499f..875665764f 100644 --- a/src/Core/Hooks/Capabilities/ICanRegisterStrategies.php +++ b/src/Core/Hooks/Capability/ICanRegisterStrategies.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\Hooks\Capabilities; +namespace Friendica\Core\Hooks\Capability; use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException; diff --git a/src/Core/Hooks/Model/DiceInstanceManager.php b/src/Core/Hooks/Model/DiceInstanceManager.php index a8b0b540ce..07ea729794 100644 --- a/src/Core/Hooks/Model/DiceInstanceManager.php +++ b/src/Core/Hooks/Model/DiceInstanceManager.php @@ -22,8 +22,8 @@ namespace Friendica\Core\Hooks\Model; use Dice\Dice; -use Friendica\Core\Hooks\Capabilities\ICanCreateInstances; -use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; +use Friendica\Core\Hooks\Capability\ICanCreateInstances; +use Friendica\Core\Hooks\Capability\ICanRegisterStrategies; use Friendica\Core\Hooks\Exceptions\HookInstanceException; use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException; use Friendica\Core\Hooks\Util\StrategiesFileManager; @@ -49,11 +49,11 @@ class DiceInstanceManager implements ICanCreateInstances, ICanRegisterStrategies /** {@inheritDoc} */ public function registerStrategy(string $interface, string $class, ?string $name = null): ICanRegisterStrategies { - if (!empty($this->instance[$interface][$name])) { + if (!empty($this->instance[$interface][strtolower($name)])) { throw new HookRegisterArgumentException(sprintf('A class with the name %s is already set for the interface %s', $name, $interface)); } - $this->instance[$interface][$name] = $class; + $this->instance[$interface][strtolower($name)] = $class; return $this; } @@ -61,10 +61,10 @@ class DiceInstanceManager implements ICanCreateInstances, ICanRegisterStrategies /** {@inheritDoc} */ public function create(string $class, string $strategy, array $arguments = []): object { - if (empty($this->instance[$class][$strategy])) { + if (empty($this->instance[$class][strtolower($strategy)])) { throw new HookInstanceException(sprintf('The class with the name %s isn\'t registered for the class or interface %s', $strategy, $class)); } - return $this->dice->create($this->instance[$class][$strategy], $arguments); + return $this->dice->create($this->instance[$class][strtolower($strategy)], $arguments); } } diff --git a/src/Core/Hooks/Util/StrategiesFileManager.php b/src/Core/Hooks/Util/StrategiesFileManager.php index 700c401f2b..860166fb64 100644 --- a/src/Core/Hooks/Util/StrategiesFileManager.php +++ b/src/Core/Hooks/Util/StrategiesFileManager.php @@ -21,8 +21,8 @@ namespace Friendica\Core\Hooks\Util; -use Friendica\Core\Addon\Capabilities\ICanLoadAddons; -use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; +use Friendica\Core\Addon\Capability\ICanLoadAddons; +use Friendica\Core\Hooks\Capability\ICanRegisterStrategies; use Friendica\Core\Hooks\Exceptions\HookConfigException; /** @@ -30,6 +30,11 @@ use Friendica\Core\Hooks\Exceptions\HookConfigException; */ class StrategiesFileManager { + /** + * The default hook-file-key of strategies + * -> it's an empty string to cover empty/missing config values + */ + const STRATEGY_DEFAULT_KEY = ''; const STATIC_DIR = 'static'; const CONFIG_NAME = 'strategies'; diff --git a/src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php b/src/Core/KeyValueStorage/Capability/IManageKeyValuePairs.php similarity index 97% rename from src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php rename to src/Core/KeyValueStorage/Capability/IManageKeyValuePairs.php index c9d215c49c..5d9c8455ee 100644 --- a/src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php +++ b/src/Core/KeyValueStorage/Capability/IManageKeyValuePairs.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\KeyValueStorage\Capabilities; +namespace Friendica\Core\KeyValueStorage\Capability; use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException; diff --git a/src/Core/Cache/Enum/Type.php b/src/Core/KeyValueStorage/Factory/KeyValueStorage.php similarity index 62% rename from src/Core/Cache/Enum/Type.php rename to src/Core/KeyValueStorage/Factory/KeyValueStorage.php index 98ed9e41f7..467006614a 100644 --- a/src/Core/Cache/Enum/Type.php +++ b/src/Core/KeyValueStorage/Factory/KeyValueStorage.php @@ -19,17 +19,17 @@ * */ -namespace Friendica\Core\Cache\Enum; +namespace Friendica\Core\KeyValueStorage\Factory; -/** - * Enumeration for cache types - */ -abstract class Type +use Friendica\Core\Hooks\Capability\ICanCreateInstances; +use Friendica\Core\Hooks\Util\StrategiesFileManager; +use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; + +class KeyValueStorage { - const APCU = 'apcu'; - const REDIS = 'redis'; - const ARRAY = 'array'; - const MEMCACHE = 'memcache'; - const DATABASE = 'database'; - const MEMCACHED = 'memcached'; + public function create(ICanCreateInstances $instanceCreator): IManageKeyValuePairs + { + /** @var IManageKeyValuePairs */ + return $instanceCreator->create(IManageKeyValuePairs::class, StrategiesFileManager::STRATEGY_DEFAULT_KEY); + } } diff --git a/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php index a6924b61f5..5d1b1f9d45 100644 --- a/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php +++ b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php @@ -21,13 +21,15 @@ namespace Friendica\Core\KeyValueStorage\Type; -use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; /** * An abstract helper class for Key-Value storage classes */ abstract class AbstractKeyValueStorage implements IManageKeyValuePairs { + const NAME = ''; + /** {@inheritDoc} */ public function get(string $key) { diff --git a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php index d31f3c1ced..cc152f0c99 100644 --- a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php +++ b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php @@ -30,6 +30,7 @@ use Friendica\Database\Database; */ class DBKeyValueStorage extends AbstractKeyValueStorage { + const NAME = 'database'; const DB_KEY_VALUE_TABLE = 'key-value'; /** @var Database */ diff --git a/src/Core/Lock/Enum/Type.php b/src/Core/Lock/Enum/Type.php index 9e6e9194df..3a623b6372 100644 --- a/src/Core/Lock/Enum/Type.php +++ b/src/Core/Lock/Enum/Type.php @@ -21,7 +21,7 @@ namespace Friendica\Core\Lock\Enum; -use Friendica\Core\Cache\Enum\Type as CacheType; +use Friendica\Core\Cache\Type\DatabaseCache; /** * Enumeration for lock types @@ -30,6 +30,6 @@ use Friendica\Core\Cache\Enum\Type as CacheType; */ abstract class Type { - const DATABASE = CacheType::DATABASE; + const DATABASE = DatabaseCache::NAME; const SEMAPHORE = 'semaphore'; } diff --git a/src/Core/Lock/Factory/Lock.php b/src/Core/Lock/Factory/Lock.php index bc4650c97b..a60bc5a96c 100644 --- a/src/Core/Lock/Factory/Lock.php +++ b/src/Core/Lock/Factory/Lock.php @@ -23,10 +23,10 @@ namespace Friendica\Core\Lock\Factory; use Friendica\Core\Cache\Factory\Cache; use Friendica\Core\Cache\Capability\ICanCacheInMemory; -use Friendica\Core\Cache\Enum; +use Friendica\Core\Cache\Type as CacheType; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Lock\Capability\ICanLock; -use Friendica\Core\Lock\Type; +use Friendica\Core\Lock\Type as LockType; use Friendica\Database\Database; use Psr\Log\LoggerInterface; @@ -78,20 +78,20 @@ class Lock try { switch ($lock_type) { - case Enum\Type::MEMCACHE: - case Enum\Type::MEMCACHED: - case Enum\Type::REDIS: - case Enum\Type::APCU: + case CacheType\MemcacheCache::NAME: + case CacheType\MemcachedCache::NAME: + case CacheType\RedisCache::NAME: + case CacheType\APCuCache::NAME: $cache = $this->cacheFactory->createLocal($lock_type); if ($cache instanceof ICanCacheInMemory) { - return new Type\CacheLock($cache); + return new LockType\CacheLock($cache); } else { throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type)); } case 'database': - return new Type\DatabaseLock($this->dba); + return new LockType\DatabaseLock($this->dba); case 'semaphore': - return new Type\SemaphoreLock(); + return new LockType\SemaphoreLock(); default: return self::useAutoDriver(); } @@ -116,7 +116,7 @@ class Lock // 1. Try to use Semaphores for - local - locking if (function_exists('sem_get')) { try { - return new Type\SemaphoreLock(); + return new LockType\SemaphoreLock(); } catch (\Exception $exception) { $this->logger->warning('Using Semaphore driver for locking failed.', ['exception' => $exception]); } @@ -124,11 +124,11 @@ class Lock // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!) $cache_type = $this->config->get('system', 'cache_driver', 'database'); - if ($cache_type != Enum\Type::DATABASE) { + if ($cache_type != CacheType\DatabaseCache::NAME) { try { $cache = $this->cacheFactory->createLocal($cache_type); if ($cache instanceof ICanCacheInMemory) { - return new Type\CacheLock($cache); + return new LockType\CacheLock($cache); } } catch (\Exception $exception) { $this->logger->warning('Using Cache driver for locking failed.', ['exception' => $exception]); @@ -136,6 +136,6 @@ class Lock } // 3. Use Database Locking as a Fallback - return new Type\DatabaseLock($this->dba); + return new LockType\DatabaseLock($this->dba); } } diff --git a/src/Core/Lock/Type/AbstractLock.php b/src/Core/Lock/Type/AbstractLock.php index 3c47c0171a..25eb47fe91 100644 --- a/src/Core/Lock/Type/AbstractLock.php +++ b/src/Core/Lock/Type/AbstractLock.php @@ -36,7 +36,7 @@ abstract class AbstractLock implements ICanLock /** * Check if we've locally acquired a lock * - * @param string key The Name of the lock + * @param string $key The Name of the lock * * @return bool Returns true if the lock is set */ diff --git a/src/Core/Logger/Capabilities/ICheckLoggerSettings.php b/src/Core/Logger/Capability/ICheckLoggerSettings.php similarity index 96% rename from src/Core/Logger/Capabilities/ICheckLoggerSettings.php rename to src/Core/Logger/Capability/ICheckLoggerSettings.php index fb93d18e80..abdbc3b50a 100644 --- a/src/Core/Logger/Capabilities/ICheckLoggerSettings.php +++ b/src/Core/Logger/Capability/ICheckLoggerSettings.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\Logger\Capabilities; +namespace Friendica\Core\Logger\Capability; /** * Whenever a logging specific check is necessary, use this interface to encapsulate and centralize this logic diff --git a/src/Core/Logger/Capabilities/IHaveCallIntrospections.php b/src/Core/Logger/Capability/IHaveCallIntrospections.php similarity index 96% rename from src/Core/Logger/Capabilities/IHaveCallIntrospections.php rename to src/Core/Logger/Capability/IHaveCallIntrospections.php index 83d75f976f..918232af39 100644 --- a/src/Core/Logger/Capabilities/IHaveCallIntrospections.php +++ b/src/Core/Logger/Capability/IHaveCallIntrospections.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\Logger\Capabilities; +namespace Friendica\Core\Logger\Capability; interface IHaveCallIntrospections { diff --git a/src/Core/Logger/Capabilities/LogChannel.php b/src/Core/Logger/Capability/LogChannel.php similarity index 97% rename from src/Core/Logger/Capabilities/LogChannel.php rename to src/Core/Logger/Capability/LogChannel.php index 31915168b9..c3b6316440 100644 --- a/src/Core/Logger/Capabilities/LogChannel.php +++ b/src/Core/Logger/Capability/LogChannel.php @@ -19,7 +19,7 @@ * */ -namespace Friendica\Core\Logger\Capabilities; +namespace Friendica\Core\Logger\Capability; /** * An enum class for the Log channels diff --git a/src/Core/Logger/Factory/AbstractLoggerTypeFactory.php b/src/Core/Logger/Factory/AbstractLoggerTypeFactory.php index 402176d8e6..86dfeae63b 100644 --- a/src/Core/Logger/Factory/AbstractLoggerTypeFactory.php +++ b/src/Core/Logger/Factory/AbstractLoggerTypeFactory.php @@ -21,7 +21,7 @@ namespace Friendica\Core\Logger\Factory; -use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; +use Friendica\Core\Logger\Capability\IHaveCallIntrospections; use Psr\Log\LogLevel; /** diff --git a/src/Core/Logger/Factory/Logger.php b/src/Core/Logger/Factory/Logger.php index c370cc4dd7..f1086f5853 100644 --- a/src/Core/Logger/Factory/Logger.php +++ b/src/Core/Logger/Factory/Logger.php @@ -22,8 +22,8 @@ namespace Friendica\Core\Logger\Factory; use Friendica\Core\Config\Capability\IManageConfigValues; -use Friendica\Core\Hooks\Capabilities\ICanCreateInstances; -use Friendica\Core\Logger\Capabilities\LogChannel; +use Friendica\Core\Hooks\Capability\ICanCreateInstances; +use Friendica\Core\Logger\Capability\LogChannel; use Friendica\Core\Logger\Type\ProfilerLogger as ProfilerLoggerClass; use Friendica\Util\Profiler; use Psr\Log\LoggerInterface; diff --git a/src/Core/Logger/Factory/StreamLogger.php b/src/Core/Logger/Factory/StreamLogger.php index caad78e3b4..7f32d66b1d 100644 --- a/src/Core/Logger/Factory/StreamLogger.php +++ b/src/Core/Logger/Factory/StreamLogger.php @@ -22,7 +22,7 @@ namespace Friendica\Core\Logger\Factory; use Friendica\Core\Config\Capability\IManageConfigValues; -use Friendica\Core\Logger\Capabilities\LogChannel; +use Friendica\Core\Logger\Capability\LogChannel; use Friendica\Core\Logger\Exception\LoggerArgumentException; use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Core\Logger\Exception\LogLevelException; diff --git a/src/Core/Logger/Type/AbstractLogger.php b/src/Core/Logger/Type/AbstractLogger.php index 77a61e9206..7de0e41605 100644 --- a/src/Core/Logger/Type/AbstractLogger.php +++ b/src/Core/Logger/Type/AbstractLogger.php @@ -21,7 +21,7 @@ namespace Friendica\Core\Logger\Type; -use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; +use Friendica\Core\Logger\Capability\IHaveCallIntrospections; use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Util\Strings; use Psr\Log\LoggerInterface; @@ -38,6 +38,8 @@ use Psr\Log\LogLevel; */ abstract class AbstractLogger implements LoggerInterface { + const NAME = ''; + /** * The output channel of this logger * @var string diff --git a/src/Core/Logger/Type/StreamLogger.php b/src/Core/Logger/Type/StreamLogger.php index 87f1a3937f..8cadd8cc72 100644 --- a/src/Core/Logger/Type/StreamLogger.php +++ b/src/Core/Logger/Type/StreamLogger.php @@ -21,7 +21,7 @@ namespace Friendica\Core\Logger\Type; -use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; +use Friendica\Core\Logger\Capability\IHaveCallIntrospections; use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Core\Logger\Exception\LogLevelException; use Friendica\Util\DateTimeFormat; @@ -32,6 +32,8 @@ use Psr\Log\LogLevel; */ class StreamLogger extends AbstractLogger { + const NAME = 'stream'; + /** * The minimum loglevel at which this logger will be triggered * @var string diff --git a/src/Core/Logger/Type/SyslogLogger.php b/src/Core/Logger/Type/SyslogLogger.php index 88dc1964dd..556351a7e4 100644 --- a/src/Core/Logger/Type/SyslogLogger.php +++ b/src/Core/Logger/Type/SyslogLogger.php @@ -21,7 +21,7 @@ namespace Friendica\Core\Logger\Type; -use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; +use Friendica\Core\Logger\Capability\IHaveCallIntrospections; use Friendica\Core\Logger\Exception\LoggerException; use Friendica\Core\Logger\Exception\LogLevelException; use Psr\Log\LogLevel; @@ -32,6 +32,8 @@ use Psr\Log\LogLevel; */ class SyslogLogger extends AbstractLogger { + const NAME = 'syslog'; + const IDENT = 'Friendica'; /** @var int The default syslog flags */ diff --git a/src/Core/Logger/Util/Introspection.php b/src/Core/Logger/Util/Introspection.php index e0f7e85540..0b703da825 100644 --- a/src/Core/Logger/Util/Introspection.php +++ b/src/Core/Logger/Util/Introspection.php @@ -22,7 +22,7 @@ namespace Friendica\Core\Logger\Util; use Friendica\App\Request; -use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; +use Friendica\Core\Logger\Capability\IHaveCallIntrospections; /** * Get Introspection information about the current call diff --git a/src/Core/Logger/Util/LoggerSettingsCheck.php b/src/Core/Logger/Util/LoggerSettingsCheck.php index 7782216dab..cb598d5f2d 100644 --- a/src/Core/Logger/Util/LoggerSettingsCheck.php +++ b/src/Core/Logger/Util/LoggerSettingsCheck.php @@ -23,7 +23,7 @@ namespace Friendica\Core\Logger\Util; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\L10n; -use Friendica\Core\Logger\Capabilities\ICheckLoggerSettings; +use Friendica\Core\Logger\Capability\ICheckLoggerSettings; use Friendica\Core\Logger\Exception\LoggerUnusableException; /** {@inheritDoc} */ diff --git a/src/Core/PConfig/Factory/PConfig.php b/src/Core/PConfig/Factory/PConfig.php index cde97759e9..0596752899 100644 --- a/src/Core/PConfig/Factory/PConfig.php +++ b/src/Core/PConfig/Factory/PConfig.php @@ -22,28 +22,16 @@ namespace Friendica\Core\PConfig\Factory; use Friendica\Core\Config\Capability\IManageConfigValues; +use Friendica\Core\Hooks\Capability\ICanCreateInstances; use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; -use Friendica\Core\PConfig\Repository; -use Friendica\Core\PConfig\Type; -use Friendica\Core\PConfig\ValueObject; class PConfig { - /** - * @param IManageConfigValues $config The config - * @param ValueObject\Cache $pConfigCache The personal config cache - * @param Repository\PConfig $configRepo The configuration model - * - * @return IManagePersonalConfigValues - */ - public function create(IManageConfigValues $config, ValueObject\Cache $pConfigCache, Repository\PConfig $configRepo): IManagePersonalConfigValues + public function create(ICanCreateInstances $instanceCreator, IManageConfigValues $config): IManagePersonalConfigValues { - if ($config->get('system', 'config_adapter') === 'preload') { - $configuration = new Type\PreloadPConfig($pConfigCache, $configRepo); - } else { - $configuration = new Type\JitPConfig($pConfigCache, $configRepo); - } + $strategy = $config->get('system', 'config_adapter'); - return $configuration; + /** @var IManagePersonalConfigValues */ + return $instanceCreator->create(IManagePersonalConfigValues::class, $strategy); } } diff --git a/src/Core/PConfig/Type/AbstractPConfigValues.php b/src/Core/PConfig/Type/AbstractPConfigValues.php index 39be8f4e74..e567cbaed9 100644 --- a/src/Core/PConfig/Type/AbstractPConfigValues.php +++ b/src/Core/PConfig/Type/AbstractPConfigValues.php @@ -34,6 +34,8 @@ use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; */ abstract class AbstractPConfigValues implements IManagePersonalConfigValues { + const NAME = ''; + /** * @var Cache */ diff --git a/src/Core/PConfig/Type/JitPConfig.php b/src/Core/PConfig/Type/JitPConfig.php index c5c20577ef..b851015e79 100644 --- a/src/Core/PConfig/Type/JitPConfig.php +++ b/src/Core/PConfig/Type/JitPConfig.php @@ -33,6 +33,8 @@ use Friendica\Core\PConfig\ValueObject; */ class JitPConfig extends AbstractPConfigValues { + const NAME = 'jit'; + /** * @var array Array of already loaded db values (even if there was no value) */ diff --git a/src/Core/PConfig/Type/PreloadPConfig.php b/src/Core/PConfig/Type/PreloadPConfig.php index b3b709286a..6ae028c5ec 100644 --- a/src/Core/PConfig/Type/PreloadPConfig.php +++ b/src/Core/PConfig/Type/PreloadPConfig.php @@ -32,6 +32,8 @@ use Friendica\Core\PConfig\ValueObject; */ class PreloadPConfig extends AbstractPConfigValues { + const NAME = 'preload'; + /** @var array */ private $config_loaded; diff --git a/src/Core/Session/Capability/IHandleUserSessions.php b/src/Core/Session/Capability/IHandleUserSessions.php index 5734eafdf7..3b135b5212 100644 --- a/src/Core/Session/Capability/IHandleUserSessions.php +++ b/src/Core/Session/Capability/IHandleUserSessions.php @@ -93,6 +93,13 @@ interface IHandleUserSessions extends IHandleSessions */ public function isSiteAdmin(): bool; + /** + * Check if current user is a moderator. + * + * @return bool true if user is a moderator + */ + public function isModerator(): bool; + /** * Returns User ID of the managed user in case it's a different identity * diff --git a/src/Core/Session/Factory/Session.php b/src/Core/Session/Factory/Session.php index 239b050e77..e12dbd9af6 100644 --- a/src/Core/Session/Factory/Session.php +++ b/src/Core/Session/Factory/Session.php @@ -22,8 +22,8 @@ namespace Friendica\Core\Session\Factory; use Friendica\App; -use Friendica\Core\Cache\Enum; use Friendica\Core\Cache\Factory\Cache; +use Friendica\Core\Cache\Type\DatabaseCache; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Type; @@ -74,7 +74,7 @@ class Session $cache = $cacheFactory->createDistributed(); // In case we're using the db as cache driver, use the native db session, not the cache - if ($config->get('system', 'cache_driver') === Enum\Type::DATABASE) { + if ($config->get('system', 'cache_driver') === DatabaseCache::NAME) { $handler = new Handler\Database($dba, $logger, $server); } else { $handler = new Handler\Cache($cache, $logger); diff --git a/src/Core/Session/Model/UserSession.php b/src/Core/Session/Model/UserSession.php index 8dfc3d8321..c1a38dffae 100644 --- a/src/Core/Session/Model/UserSession.php +++ b/src/Core/Session/Model/UserSession.php @@ -139,6 +139,12 @@ class UserSession implements IHandleUserSessions return User::isSiteAdmin($this->getLocalUserId()); } + /** {@inheritDoc} */ + public function isModerator(): bool + { + return User::isModerator($this->getLocalUserId()); + } + /** {@inheritDoc} */ public function setVisitorsContacts(string $my_url) { diff --git a/src/DI.php b/src/DI.php index 1917f710d3..34cf1c68d5 100644 --- a/src/DI.php +++ b/src/DI.php @@ -22,7 +22,7 @@ namespace Friendica; use Dice\Dice; -use Friendica\Core\Logger\Capabilities\ICheckLoggerSettings; +use Friendica\Core\Logger\Capability\ICheckLoggerSettings; use Friendica\Core\Logger\Util\LoggerSettingsCheck; use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Capability\IHandleUserSessions; @@ -210,9 +210,9 @@ abstract class DI return self::$dice->create(Core\Config\Util\ConfigFileManager::class); } - public static function keyValue(): Core\KeyValueStorage\Capabilities\IManageKeyValuePairs + public static function keyValue(): Core\KeyValueStorage\Capability\IManageKeyValuePairs { - return self::$dice->create(Core\KeyValueStorage\Capabilities\IManageKeyValuePairs::class); + return self::$dice->create(Core\KeyValueStorage\Capability\IManageKeyValuePairs::class); } /** diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 2a5b89928f..c49017b595 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -584,6 +584,14 @@ class APContact */ public static function isRelay(array $apcontact): bool { + if (in_array($apcontact['type'], ['Person', 'Organization'])) { + return false; + } + + if (($apcontact['type'] == 'Service') && empty($apcontact['outbox']) && empty($apcontact['sharedinbox']) && empty($apcontact['following']) && empty($apcontact['followers']) && empty($apcontact['statuses_count'])) { + return true; + } + if (empty($apcontact['nick']) || $apcontact['nick'] != 'relay') { return false; } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 3ca84515a9..23e1f2cbff 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -23,6 +23,7 @@ namespace Friendica\Model; use Friendica\Contact\Avatar; use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException; +use Friendica\Contact\LocalRelationship\Entity\LocalRelationship; use Friendica\Content\Conversation as ConversationContent; use Friendica\Content\Pager; use Friendica\Content\Text\HTML; @@ -111,10 +112,14 @@ class Contact * @} */ - const MIRROR_DEACTIVATED = 0; - const MIRROR_FORWARDED = 1; // Deprecated, now does the same like MIRROR_OWN_POST - const MIRROR_OWN_POST = 2; - const MIRROR_NATIVE_RESHARE = 3; + /** @deprecated Use Entity\LocalRelationship::MIRROR_DEACTIVATED instead */ + const MIRROR_DEACTIVATED = LocalRelationship::MIRROR_DEACTIVATED; + /** @deprecated Now does the same as MIRROR_OWN_POST */ + const MIRROR_FORWARDED = 1; + /** @deprecated Use Entity\LocalRelationship::MIRROR_OWN_POST instead */ + const MIRROR_OWN_POST = LocalRelationship::MIRROR_OWN_POST; + /** @deprecated Use Entity\LocalRelationship::MIRROR_NATIVE_RESHARE instead */ + const MIRROR_NATIVE_RESHARE = LocalRelationship::MIRROR_NATIVE_RESHARE; /** * @param array $fields Array of selected fields, empty for all @@ -799,7 +804,7 @@ class Contact return false; } - $fields = ['uid', 'nickname', 'page-flags', 'account-type', 'prvkey', 'pubkey']; + $fields = ['uid', 'username', 'nickname', 'page-flags', 'account-type', 'prvkey', 'pubkey']; $user = DBA::selectFirst('user', $fields, ['uid' => $uid, 'account_expired' => false]); if (!DBA::isResult($user)) { return false; @@ -818,7 +823,7 @@ class Contact $url = DI::baseUrl() . '/profile/' . $user['nickname']; $fields = [ - 'name' => $profile['name'], + 'name' => $user['username'], 'nick' => $user['nickname'], 'avatar-date' => $self['avatar-date'], 'location' => Profile::formatLocation($profile), @@ -841,7 +846,6 @@ class Contact 'confirm' => DI::baseUrl() . '/dfrn_confirm/' . $user['nickname'], ]; - $avatar = Photo::selectFirst(['resource-id', 'type'], ['uid' => $uid, 'profile' => true]); if (DBA::isResult($avatar)) { if ($update_avatar) { diff --git a/src/Model/Item.php b/src/Model/Item.php index 9028c9f853..a2304056d3 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -21,6 +21,7 @@ namespace Friendica\Model; +use Friendica\Contact\LocalRelationship\Entity\LocalRelationship; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Hook; @@ -2333,12 +2334,7 @@ class Item return; } - $cdata = Contact::getPublicAndUserContactID($item['author-id'], $item['uid']); - if (empty($cdata['user']) || ($cdata['user'] != $item['contact-id'])) { - return; - } - - if (!DBA::exists('contact', ['id' => $cdata['user'], 'remote_self' => Contact::MIRROR_NATIVE_RESHARE])) { + if (!DBA::exists('contact', ['id' => $cdata['user'], 'remote_self' => LocalRelationship::MIRROR_NATIVE_RESHARE])) { return; } @@ -2346,6 +2342,10 @@ class Item return; } + if (User::getById($item['uid'], ['blocked'])['blocked'] ?? false) { + return; + } + Logger::info('Automatically reshare item', ['uid' => $item['uid'], 'id' => $item['id'], 'guid' => $item['guid'], 'uri-id' => $item['uri-id']]); self::performActivity($item['id'], 'announce', $item['uid']); @@ -2353,7 +2353,7 @@ class Item public static function isRemoteSelf(array $contact, array &$datarray): bool { - if ($contact['remote_self'] != Contact::MIRROR_OWN_POST) { + if ($contact['remote_self'] != LocalRelationship::MIRROR_OWN_POST) { return false; } @@ -2380,6 +2380,11 @@ class Item return false; } + if (User::getById($contact['uid'], ['blocked'])['blocked'] ?? false) { + Logger::info('User is blocked', ['contact' => $contact]); + return false; + } + $datarray2 = $datarray; Logger::info('remote-self start', ['contact' => $contact['url'], 'remote_self' => $contact['remote_self'], 'item' => $datarray]); @@ -3222,7 +3227,7 @@ class Item $shared_html = substr($s, $pos + strlen(BBCode::SHARED_ANCHOR)); $s = substr($s, 0, $pos); } - + $s = self::addGallery($s, $attachments, $item['uri-id']); $s = self::addVisualAttachments($attachments, $item, $s, false); $s = self::addLinkAttachment($item['uri-id'], $attachments, $body, $s, false, $shared_links); @@ -3628,9 +3633,9 @@ class Item } $author = [ - 'uid' => 0, + 'uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], + 'network' => $item['author-network'], 'url' => $item['author-link'], 'alias' => $item['author-alias'] ]; @@ -3721,9 +3726,9 @@ class Item if (!empty($plink) && ($item['private'] == self::PRIVATE)) { $author = [ - 'uid' => 0, + 'uid' => 0, 'id' => $item['author-id'], - 'network' => $item['author-network'], + 'network' => $item['author-network'], 'url' => $item['author-link'], 'alias' => $item['author-alias'], ]; diff --git a/src/Model/Nodeinfo.php b/src/Model/Nodeinfo.php index 4dbe06c9b3..825afb4a9a 100644 --- a/src/Model/Nodeinfo.php +++ b/src/Model/Nodeinfo.php @@ -109,8 +109,9 @@ class Nodeinfo 'outbound' => [], ]; - if (Addon::isEnabled('blogger')) { - $services['outbound'][] = 'blogger'; + if (Addon::isEnabled('bluesky')) { + $services['inbound'][] = 'bluesky'; + $services['outbound'][] = 'bluesky'; } if (Addon::isEnabled('dwpost')) { $services['outbound'][] = 'dreamwidth'; @@ -125,18 +126,9 @@ class Nodeinfo if (Addon::isEnabled('libertree')) { $services['outbound'][] = 'libertree'; } - if (Addon::isEnabled('buffer')) { - $services['outbound'][] = 'linkedin'; - } if (Addon::isEnabled('ljpost')) { $services['outbound'][] = 'livejournal'; } - if (Addon::isEnabled('buffer')) { - $services['outbound'][] = 'pinterest'; - } - if (Addon::isEnabled('posterous')) { - $services['outbound'][] = 'posterous'; - } if (Addon::isEnabled('pumpio')) { $services['inbound'][] = 'pumpio'; $services['outbound'][] = 'pumpio'; @@ -147,7 +139,7 @@ class Nodeinfo if (Addon::isEnabled('tumblr')) { $services['outbound'][] = 'tumblr'; } - if (Addon::isEnabled('twitter') || Addon::isEnabled('buffer')) { + if (Addon::isEnabled('twitter')) { $services['outbound'][] = 'twitter'; } if (Addon::isEnabled('wppost')) { diff --git a/src/Model/Photo.php b/src/Model/Photo.php index 2235137be2..f393211548 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -989,6 +989,35 @@ class Photo return DBA::exists('photo', ['resource-id' => $guid]); } + /** + * Resize to a given maximum file size + * + * @param Image $image + * @param integer $maximagesize + * @return Image + */ + public static function resizeToFileSize(Image $image, int $maximagesize): Image + { + $filesize = strlen($image->asString()); + $width = $image->getWidth(); + $height = $image->getHeight(); + + if ($maximagesize && ($filesize > $maximagesize)) { + // Scale down to multiples of 640 until the maximum size isn't exceeded anymore + foreach ([5120, 2560, 1280, 640, 320] as $pixels) { + if (($filesize > $maximagesize) && (max($width, $height) > $pixels)) { + Logger::info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]); + $image->scaleDown($pixels); + $filesize = strlen($image->asString()); + $width = $image->getWidth(); + $height = $image->getHeight(); + } + } + } + + return $image; + } + /** * Tries to resize image to wanted maximum size * @@ -1002,31 +1031,8 @@ class Photo $image->scaleDown($max_length); Logger::info('File upload: Scaling picture to new size', ['max-length' => $max_length]); } - - $filesize = strlen($image->asString()); - $width = $image->getWidth(); - $height = $image->getHeight(); - - $maximagesize = Strings::getBytesFromShorthand(DI::config()->get('system', 'maximagesize')); - - if ($maximagesize && ($filesize > $maximagesize)) { - // Scale down to multiples of 640 until the maximum size isn't exceeded anymore - foreach ([5120, 2560, 1280, 640] as $pixels) { - if (($filesize > $maximagesize) && (max($width, $height) > $pixels)) { - Logger::info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]); - $image->scaleDown($pixels); - $filesize = strlen($image->asString()); - $width = $image->getWidth(); - $height = $image->getHeight(); - } - } - if ($filesize > $maximagesize) { - Logger::notice('Image size is too big', ['size' => $filesize, 'max' => $maximagesize]); - return null; - } - } - - return $image; + + return self::resizeToFileSize($image, Strings::getBytesFromShorthand(DI::config()->get('system', 'maximagesize'))); } /** @@ -1237,32 +1243,7 @@ class Photo */ public static function storeWithPreview(Image $image, int $uid, string $resource_id, string $filename, int $filesize, string $album, string $description, string $allow_cid, string $allow_gid, string $deny_cid, string $deny_gid): int { - if ($filesize == 0) { - $filesize = strlen($image->asString()); - } - - $width = $image->getWidth(); - $height = $image->getHeight(); - - $maximagesize = Strings::getBytesFromShorthand(DI::config()->get('system', 'maximagesize')); - - if ($maximagesize && $filesize > $maximagesize) { - // Scale down to multiples of 640 until the maximum size isn't exceeded anymore - foreach ([5120, 2560, 1280, 640, 320] as $pixels) { - if ($filesize > $maximagesize && max($width, $height) > $pixels) { - DI::logger()->info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]); - $image->scaleDown($pixels); - $filesize = strlen($image->asString()); - $width = $image->getWidth(); - $height = $image->getHeight(); - } - } - - if ($filesize > $maximagesize) { - DI::logger()->notice('Image size is too big', ['size' => $filesize, 'max' => $maximagesize]); - return -1; - } - } + $image = self::resizeToFileSize($image, Strings::getBytesFromShorthand(DI::config()->get('system', 'maximagesize'))); $width = $image->getWidth(); $height = $image->getHeight(); diff --git a/src/Model/User.php b/src/Model/User.php index 89d75849fe..18da3e9560 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -880,6 +880,20 @@ class User ]); } + /** + * Returns if the given uid is valid and a moderator + * + * @param int $uid + * + * @return bool + * @throws Exception + */ + public static function isModerator(int $uid): bool + { + // @todo Replace with a moderator check in the future + return self::isSiteAdmin($uid); + } + /** * Checks if a nickname is in the list of the forbidden nicknames * diff --git a/src/Module/Api/Mastodon/Statuses.php b/src/Module/Api/Mastodon/Statuses.php index dad0451fc4..a8f1dc1c66 100644 --- a/src/Module/Api/Mastodon/Statuses.php +++ b/src/Module/Api/Mastodon/Statuses.php @@ -76,16 +76,9 @@ class Statuses extends BaseApi throw new HTTPException\NotFoundException('Item with URI ID ' . $this->parameters['id'] . ' not found for user ' . $uid . '.'); } - // The imput is defined as text. So we can use Markdown for some enhancements - $body = Markdown::toBBCode($request['status']); - - if (DI::pConfig()->get($uid, 'system', 'api_auto_attach', false) && preg_match("/\[url=[^\[\]]*\](.*)\[\/url\]\z/ism", $body, $matches)) { - $body = preg_replace("/\[url=[^\[\]]*\].*\[\/url\]\z/ism", PageInfo::getFooterFromUrl($matches[1]), $body); - } - $item['title'] = ''; $item['uid'] = $post['uid']; - $item['body'] = $body; + $item['body'] = $this->formatStatus($request['status'], $uid); $item['network'] = $post['network']; $item['gravity'] = $post['gravity']; $item['verb'] = $post['verb']; @@ -190,13 +183,6 @@ class Statuses extends BaseApi $owner = User::getOwnerDataById($uid); - // The imput is defined as text. So we can use Markdown for some enhancements - $body = Markdown::toBBCode($request['status']); - - if (DI::pConfig()->get($uid, 'system', 'api_auto_attach', false) && preg_match("/\[url=[^\[\]]*\](.*)\[\/url\]\z/ism", $body, $matches)) { - $body = preg_replace("/\[url=[^\[\]]*\].*\[\/url\]\z/ism", PageInfo::getFooterFromUrl($matches[1]), $body); - } - $item = []; $item['network'] = Protocol::DFRN; $item['uid'] = $uid; @@ -204,7 +190,7 @@ class Statuses extends BaseApi $item['contact-id'] = $owner['id']; $item['author-id'] = $item['owner-id'] = Contact::getPublicIdByUserId($uid); $item['title'] = ''; - $item['body'] = $body; + $item['body'] = $this->formatStatus($request['status'], $uid); $item['app'] = $this->getApp(); switch ($request['visibility']) { @@ -415,4 +401,28 @@ class Statuses extends BaseApi } return $item; } + + /** + * Format the status via Markdown and a link description if enabled for this user + * + * @param string $status + * @param integer $uid + * @return string + */ + private function formatStatus(string $status, int $uid): string + { + // The input is defined as text. So we can use Markdown for some enhancements + $status = Markdown::toBBCode($status); + + if (!DI::pConfig()->get($uid, 'system', 'api_auto_attach', false)) { + return $status; + } + + $status = BBCode::expandVideoLinks($status); + if (preg_match("/\[url=[^\[\]]*\](.*)\[\/url\]\z/ism", $status, $matches)) { + $status = preg_replace("/\[url=[^\[\]]*\].*\[\/url\]\z/ism", PageInfo::getFooterFromUrl($matches[1]), $status); + } + + return $status; + } } diff --git a/src/Module/BaseModeration.php b/src/Module/BaseModeration.php index 3de46b319c..a575e51f79 100644 --- a/src/Module/BaseModeration.php +++ b/src/Module/BaseModeration.php @@ -82,12 +82,12 @@ abstract class BaseModeration extends BaseModule } } - if (!$this->app->isSiteAdmin()) { - throw new HTTPException\ForbiddenException($this->t('You don\'t have access to administration pages.')); + if (!$this->session->isModerator()) { + throw new HTTPException\ForbiddenException($this->t('You don\'t have access to moderation pages.')); } if ($this->session->getSubManagedUserId()) { - throw new HTTPException\ForbiddenException($this->t('Submanaged account can\'t access the administration pages. Please log back in as the main account.')); + throw new HTTPException\ForbiddenException($this->t('Submanaged account can\'t access the moderation pages. Please log back in as the main account.')); } } diff --git a/src/Module/Contact/Profile.php b/src/Module/Contact/Profile.php index 2f8daf28e2..090f7cd86a 100644 --- a/src/Module/Contact/Profile.php +++ b/src/Module/Contact/Profile.php @@ -283,10 +283,10 @@ class Profile extends BaseModule $localRelationship->fetchFurtherInformation, $this->t('Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn\'t contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags.'), [ - '0' => $this->t('Disabled'), - '1' => $this->t('Fetch information'), - '3' => $this->t('Fetch keywords'), - '2' => $this->t('Fetch information and keywords') + Entity\LocalRelationship::FFI_NONE => $this->t('Disabled'), + Entity\LocalRelationship::FFI_INFORMATION => $this->t('Fetch information'), + Entity\LocalRelationship::FFI_KEYWORD => $this->t('Fetch keywords'), + Entity\LocalRelationship::FFI_BOTH => $this->t('Fetch information and keywords') ] ]; } @@ -394,7 +394,7 @@ class Profile extends BaseModule '$remote_self' => [ 'remote_self', $this->t('Mirror postings from this contact'), - $localRelationship->isRemoteSelf, + $localRelationship->remoteSelf, $this->t('Mark this contact as remote_self, this will cause friendica to repost new entries from this contact.'), $remote_self_options ], diff --git a/src/Module/Friendica.php b/src/Module/Friendica.php index c6e2768bd3..fe4c846c92 100644 --- a/src/Module/Friendica.php +++ b/src/Module/Friendica.php @@ -26,7 +26,7 @@ use Friendica\BaseModule; use Friendica\Core\Addon; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Hook; -use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Core\L10n; use Friendica\Core\Renderer; use Friendica\Core\Session\Capability\IHandleUserSessions; @@ -94,8 +94,7 @@ class Friendica extends BaseModule $blockList = $this->config->get('system', 'blocklist') ?? []; - $register_policy_int = $this->config->get('config', 'register_policy'); - if (!empty($blockList) && ($register_policy_int !== Register::CLOSED || $this->session->isAuthenticated())) { + if (!empty($blockList) && ($this->config->get('blocklist', 'public') || $this->session->isAuthenticated())) { $blocked = [ 'title' => $this->t('On this server the following remote servers are blocked.'), 'header' => [ diff --git a/src/Module/NodeInfo110.php b/src/Module/NodeInfo110.php index aee7ade5b3..85785ccca2 100644 --- a/src/Module/NodeInfo110.php +++ b/src/Module/NodeInfo110.php @@ -88,10 +88,6 @@ class NodeInfo110 extends BaseModule $nodeinfo['metadata']['services'] = $nodeinfo['services']; - if (Addon::isEnabled('twitter')) { - $nodeinfo['metadata']['services']['inbound'][] = 'twitter'; - } - $nodeinfo['metadata']['explicitContent'] = $this->config->get('system', 'explicit_content', false) == true; $this->response->setType(ICanCreateResponses::TYPE_JSON); diff --git a/src/Module/NodeInfo120.php b/src/Module/NodeInfo120.php index a5547be3fb..9fc72c528c 100644 --- a/src/Module/NodeInfo120.php +++ b/src/Module/NodeInfo120.php @@ -72,10 +72,6 @@ class NodeInfo120 extends BaseModule $nodeinfo['protocols'][] = 'ostatus'; } - if (Addon::isEnabled('twitter')) { - $nodeinfo['services']['inbound'][] = 'twitter'; - } - $nodeinfo['services']['inbound'][] = 'atom1.0'; $nodeinfo['services']['inbound'][] = 'rss2.0'; $nodeinfo['services']['outbound'][] = 'atom1.0'; diff --git a/src/Module/NodeInfo210.php b/src/Module/NodeInfo210.php index e7112846c6..a1a6e0b199 100644 --- a/src/Module/NodeInfo210.php +++ b/src/Module/NodeInfo210.php @@ -71,10 +71,6 @@ class NodeInfo210 extends BaseModule $nodeinfo['protocols'][] = 'ostatus'; } - if (Addon::isEnabled('twitter')) { - $nodeinfo['services']['inbound'][] = 'twitter'; - } - $nodeinfo['services']['inbound'][] = 'atom1.0'; $nodeinfo['services']['inbound'][] = 'rss2.0'; $nodeinfo['services']['outbound'][] = 'atom1.0'; diff --git a/src/Module/Notifications/Ping.php b/src/Module/Notifications/Ping.php index 120035d557..603d6408c7 100644 --- a/src/Module/Notifications/Ping.php +++ b/src/Module/Notifications/Ping.php @@ -52,6 +52,7 @@ use Friendica\Network\HTTPException; use Friendica\Protocol\Activity; use Friendica\Util\DateTimeFormat; use Friendica\Util\Profiler; +use Friendica\Util\Strings; use GuzzleHttp\Psr7\Uri; use Psr\Log\LoggerInterface; @@ -174,7 +175,7 @@ class Ping extends BaseModule $myurl = $this->session->getMyUrl(); $mail_count = $this->database->count('mail', ["`uid` = ? AND NOT `seen` AND `from-url` != ?", $this->session->getLocalUserId(), $myurl]); - if (intval($this->config->get('config', 'register_policy')) === Register::APPROVE && $this->app->isSiteAdmin()) { + if (intval($this->config->get('config', 'register_policy')) === Register::APPROVE && $this->session->isSiteAdmin()) { $registrations = \Friendica\Model\Register::getPending(); $register_count = count($registrations); } @@ -296,8 +297,8 @@ class Ping extends BaseModule $data['notifications'] = $navNotifications; $data['sysmsgs'] = [ - 'notice' => $this->systemMessages->flushNotices(), - 'info' => $this->systemMessages->flushInfos(), + 'notice' => array_map([Strings::class, 'escapeHtml'], $this->systemMessages->flushNotices()), + 'info' => array_map([Strings::class, 'escapeHtml'], $this->systemMessages->flushInfos()), ]; if (isset($_GET['callback'])) { diff --git a/src/Module/Profile/Conversations.php b/src/Module/Profile/Conversations.php index b53c2d1ab8..cda8f03f9b 100644 --- a/src/Module/Profile/Conversations.php +++ b/src/Module/Profile/Conversations.php @@ -103,10 +103,10 @@ class Conversations extends BaseProfile $this->page['htmlhead'] .= '' . "\n"; } - $this->page['htmlhead'] .= '' . "\n"; - $this->page['htmlhead'] .= '' . "\n"; - $this->page['htmlhead'] .= '' . "\n"; - $this->page['htmlhead'] .= '' . "\n"; + $this->page['htmlhead'] .= '' . "\n"; + $this->page['htmlhead'] .= '' . "\n"; + $this->page['htmlhead'] .= '' . "\n"; + $this->page['htmlhead'] .= '' . "\n"; $category = $datequery = $datequery2 = ''; diff --git a/src/Module/RobotsTxt.php b/src/Module/RobotsTxt.php index 49aab14713..415a8ab472 100644 --- a/src/Module/RobotsTxt.php +++ b/src/Module/RobotsTxt.php @@ -45,6 +45,11 @@ class RobotsTxt extends BaseModule foreach ($allDisallowed as $disallowed) { echo 'Disallow: ' . $disallowed . PHP_EOL; } + + echo PHP_EOL; + echo 'User-agent: ChatGPT-User' . PHP_EOL; + echo 'Disallow: /' . PHP_EOL; + System::exit(); } } diff --git a/src/Module/Search/Index.php b/src/Module/Search/Index.php index 9ec8c9dd6d..f1d99bdf13 100644 --- a/src/Module/Search/Index.php +++ b/src/Module/Search/Index.php @@ -173,7 +173,7 @@ class Index extends BaseSearch $pager = new Pager(DI::l10n(), DI::args()->getQueryString(), $itemsPerPage); if ($tag) { - Logger::info('Start tag search.', ['q' => $search]); + Logger::info('Start tag search.', ['q' => $search, 'start' => $pager->getStart(), 'items' => $pager->getItemsPerPage(), 'last' => $last_uriid]); $uriids = Tag::getURIIdListByTag($search, DI::userSession()->getLocalUserId(), $pager->getStart(), $pager->getItemsPerPage(), $last_uriid); $count = Tag::countByTag($search, DI::userSession()->getLocalUserId()); } else { @@ -185,7 +185,7 @@ class Index extends BaseSearch if (!empty($uriids)) { $condition = ["(`uid` = ? OR (`uid` = ? AND NOT `global`))", 0, DI::userSession()->getLocalUserId()]; $condition = DBA::mergeConditions($condition, ['uri-id' => $uriids]); - $params = ['order' => ['id' => true]]; + $params = ['order' => ['uri-id' => true]]; $items = Post::toArray(Post::selectForUser(DI::userSession()->getLocalUserId(), Item::DISPLAY_FIELDLIST, $condition, $params)); } diff --git a/src/Module/Statistics.php b/src/Module/Statistics.php index 514f10bb73..dc20557822 100644 --- a/src/Module/Statistics.php +++ b/src/Module/Statistics.php @@ -25,7 +25,7 @@ use Friendica\App; use Friendica\BaseModule; use Friendica\Core\Addon; use Friendica\Core\Config\Capability\IManageConfigValues; -use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Core\L10n; use Friendica\Core\System; use Friendica\Network\HTTPException\NotFoundException; @@ -38,7 +38,7 @@ class Statistics extends BaseModule protected $config; /** @var IManageKeyValuePairs */ protected $keyValue; - + public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, IManageConfigValues $config, IManageKeyValuePairs $keyValue, Response $response, array $server, array $parameters = []) { parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); @@ -59,7 +59,7 @@ class Statistics extends BaseModule /// @todo mark the "service" addons and load them dynamically here $services = [ 'appnet' => Addon::isEnabled('appnet'), - 'buffer' => Addon::isEnabled('buffer'), + 'bluesky' => Addon::isEnabled('bluesky'), 'dreamwidth' => Addon::isEnabled('dreamwidth'), 'gnusocial' => Addon::isEnabled('gnusocial'), 'libertree' => Addon::isEnabled('libertree'), diff --git a/src/Module/ToggleMobile.php b/src/Module/ToggleMobile.php index 2408ef7f3d..193f4566c7 100644 --- a/src/Module/ToggleMobile.php +++ b/src/Module/ToggleMobile.php @@ -21,32 +21,43 @@ namespace Friendica\Module; +use Friendica\App; use Friendica\BaseModule; -use Friendica\DI; +use Friendica\Core\L10n; +use Friendica\Core\Session\Capability\IHandleSessions; +use Friendica\Core\System; +use Friendica\Network\HTTPException\BadRequestException; +use Friendica\Util; +use GuzzleHttp\Psr7\Uri; +use Psr\Log\LoggerInterface; /** * Toggles the mobile view (on/off) */ class ToggleMobile extends BaseModule { - protected function content(array $request = []): string + /** @var IHandleSessions */ + private $session; + + public function __construct(IHandleSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Util\Profiler $profiler, Response $response, array $server, array $parameters = []) { - $a = DI::app(); + parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); - if (isset($_GET['off'])) { - $_SESSION['show-mobile'] = false; - } else { - $_SESSION['show-mobile'] = true; + $this->session = $session; + } + + protected function rawContent(array $request = []) + { + $address = $request['address'] ?? '' ?: $this->baseUrl; + + $uri = new Uri($address); + + if (!$this->baseUrl->isLocalUri($uri)) { + throw new BadRequestException(); } - if (isset($_GET['address'])) { - $address = $_GET['address']; - } else { - $address = ''; - } + $this->session->set('show-mobile', !isset($request['off'])); - $a->redirect($address); - - return ''; + System::externalRedirect((string)$uri); } } diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index a76ef6307b..3d020a7472 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1658,7 +1658,7 @@ class Processor $tags = Receiver::processTags(JsonLD::fetchElementArray($activity['as:object'], 'as:tag') ?? []); if (!empty($tags)) { foreach ($tags as $tag) { - if ($tag['type'] != 'Hashtag') { + if (($tag['type'] != 'Hashtag') && !strpos($tag['type'], ':Hashtag')) { continue; } $messageTags[] = ltrim(mb_strtolower($tag['name']), '#'); diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php index fced3526d4..fdfe9be7d5 100644 --- a/src/Protocol/Feed.php +++ b/src/Protocol/Feed.php @@ -25,6 +25,7 @@ use DOMDocument; use DOMElement; use DOMXPath; use Friendica\App; +use Friendica\Contact\LocalRelationship\Entity\LocalRelationship; use Friendica\Content\PageInfo; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; @@ -566,8 +567,10 @@ class Feed continue; } + $fetch_further_information = $contact['fetch_further_information'] ?? LocalRelationship::FFI_NONE; + $preview = ''; - if (!empty($contact['fetch_further_information']) && ($contact['fetch_further_information'] < 3)) { + if (in_array($fetch_further_information, [LocalRelationship::FFI_INFORMATION, LocalRelationship::FFI_BOTH])) { // Handle enclosures and treat them as preview picture foreach ($attachments as $attachment) { if ($attachment['mimetype'] == 'image/jpeg') { @@ -611,7 +614,12 @@ class Feed } } - $data = PageInfo::queryUrl($item['plink'], false, $preview, ($contact['fetch_further_information'] == 2), $contact['ffi_keyword_denylist'] ?? ''); + $data = PageInfo::queryUrl( + $item['plink'], + false, + $fetch_further_information == LocalRelationship::FFI_BOTH, + $contact['ffi_keyword_denylist'] ?? '' + ); if (!empty($data)) { // Take the data that was provided by the feed if the query is empty @@ -630,7 +638,7 @@ class Feed // We always strip the title since it will be added in the page information $item['title'] = ''; $item['body'] = $item['body'] . "\n" . PageInfo::getFooterFromData($data, false); - $taglist = $contact['fetch_further_information'] == 2 ? PageInfo::getTagsFromUrl($item['plink'], $preview, $contact['ffi_keyword_denylist'] ?? '') : []; + $taglist = $fetch_further_information == LocalRelationship::FFI_BOTH ? PageInfo::getTagsFromUrl($item['plink'], $preview, $contact['ffi_keyword_denylist'] ?? '') : []; $item['object-type'] = Activity\ObjectType::BOOKMARK; $attachments = []; @@ -662,7 +670,7 @@ class Feed $item['body'] = '[abstract]' . HTML::toBBCode($summary, $basepath) . "[/abstract]\n" . $item['body']; } - if (!empty($contact['fetch_further_information']) && ($contact['fetch_further_information'] == 3)) { + if ($fetch_further_information == LocalRelationship::FFI_KEYWORD) { if (empty($taglist)) { $taglist = PageInfo::getTagsFromUrl($item['plink'], $preview, $contact['ffi_keyword_denylist'] ?? ''); } diff --git a/src/Protocol/Relay.php b/src/Protocol/Relay.php index c5131fb3fd..2002aa9bb8 100644 --- a/src/Protocol/Relay.php +++ b/src/Protocol/Relay.php @@ -136,16 +136,16 @@ class Relay } if (!self::isWantedLanguage($body)) { - Logger::info('Unwanted or Undetected language found - rejected', ['network' => $network, 'url' => $url, 'causer' => $causer]); + Logger::info('Unwanted or Undetected language found - rejected', ['network' => $network, 'url' => $url, 'causer' => $causer, 'tags' => $tags]); return false; } if ($scope == self::SCOPE_ALL) { - Logger::info('Server accept all posts - accepted', ['network' => $network, 'url' => $url, 'causer' => $causer]); + Logger::info('Server accept all posts - accepted', ['network' => $network, 'url' => $url, 'causer' => $causer, 'tags' => $tags]); return true; } - Logger::info('No matching hashtags found - rejected', ['network' => $network, 'url' => $url, 'causer' => $causer]); + Logger::info('No matching hashtags found - rejected', ['network' => $network, 'url' => $url, 'causer' => $causer, 'tags' => $tags]); return false; } @@ -354,7 +354,7 @@ class Relay public static function getList(array $fields = []): array { return DBA::selectToArray('apcontact', $fields, - ["`type` = ? AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` = ?)", 'Application', 0, Contact::FRIEND]); + ["`type` IN (?, ?) AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` = ?)", 'Application', 'Service', 0, Contact::FRIEND]); } /** diff --git a/src/Util/Network.php b/src/Util/Network.php index f7ceab5433..495510189f 100644 --- a/src/Util/Network.php +++ b/src/Util/Network.php @@ -640,10 +640,11 @@ class Network * @param string $url * * @return bool + * @deprecated since 2023.09, please use BaseUrl->isLocalUrl or BaseUrl->isLocalUri instead. */ public static function isLocalLink(string $url): bool { - return (strpos(Strings::normaliseLink($url), Strings::normaliseLink(DI::baseUrl())) !== false); + return DI::baseUrl()->isLocalUrl($url); } /** diff --git a/src/Worker/PollContacts.php b/src/Worker/PollContacts.php index ba908cb8f3..81ce0f8f0e 100644 --- a/src/Worker/PollContacts.php +++ b/src/Worker/PollContacts.php @@ -45,10 +45,10 @@ class PollContacts if (!empty($abandon_days)) { $condition = DBA::mergeConditions($condition, - ["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed` AND `last-activity` > ?)", 0, DateTimeFormat::utc('now - ' . $abandon_days . ' days')]); + ["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `last-activity` > ?)", 0, DateTimeFormat::utc('now - ' . $abandon_days . ' days')]); } else { $condition = DBA::mergeConditions($condition, - ["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`)", 0]); + ["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `blocked` AND NOT `account_expired` AND NOT `account_removed`)", 0]); } $contacts = DBA::select('contact', ['id', 'nick', 'name', 'network', 'archive', 'last-update', 'priority', 'rating'], $condition); diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 74a65e0eaa..970aeb9ccf 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -56,7 +56,7 @@ use Friendica\Database\DBA; // This file is required several times during the test in DbaDefinition which justifies this condition if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1523); + define('DB_UPDATE_VERSION', 1524); } return [ @@ -1826,8 +1826,8 @@ return [ "rel" => ["type" => "tinyint unsigned", "comment" => "The kind of the relation between the user and the contact"], "info" => ["type" => "mediumtext", "comment" => ""], "notify_new_posts" => ["type" => "boolean", "comment" => ""], - "remote_self" => ["type" => "boolean", "comment" => ""], - "fetch_further_information" => ["type" => "tinyint unsigned", "comment" => ""], + "remote_self" => ["type" => "tinyint unsigned", "comment" => "0 => No mirroring, 1-2 => Mirror as own post, 3 => Mirror as reshare"], + "fetch_further_information" => ["type" => "tinyint unsigned", "comment" => "0 => None, 1 => Fetch information, 3 => Fetch keywords, 2 => Fetch both"], "ffi_keyword_denylist" => ["type" => "text", "comment" => ""], "subhub" => ["type" => "boolean", "comment" => ""], "hub-verify" => ["type" => "varbinary(383)", "comment" => ""], diff --git a/static/defaults.config.php b/static/defaults.config.php index e8f44613ce..4562da8987 100644 --- a/static/defaults.config.php +++ b/static/defaults.config.php @@ -543,11 +543,11 @@ return [ 'pushpoll_frequency' => 3, // redis_host (String) - // Host name of the redis daemon. + // Host name or the path to the Unix domain socket of the Redis daemon. 'redis_host' => '127.0.0.1', - // redis_port (String) - // Port number of the redis daemon. + // redis_port (Integer) + // Port number of the Redis daemon, should be -1 for unix domain socket 'redis_port' => 6379, // redis_db (Integer) @@ -786,4 +786,9 @@ return [ // Banner for Mastodon API 'mastodon_banner' => '/images/friendica-banner.jpg', ], + 'blocklist' => [ + // public (Boolean) + // Wether the blocklist is publicly listed under /about (or in any later API) + 'public' => true, + ], ]; diff --git a/static/dependencies.config.php b/static/dependencies.config.php index 98a9f3077d..3dfde6b5f4 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -37,8 +37,8 @@ use Dice\Dice; use Friendica\App; use Friendica\Core\Cache; use Friendica\Core\Config; -use Friendica\Core\Hooks\Capabilities\ICanCreateInstances; -use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; +use Friendica\Core\Hooks\Capability\ICanCreateInstances; +use Friendica\Core\Hooks\Capability\ICanRegisterStrategies; use Friendica\Core\Hooks\Model\DiceInstanceManager; use Friendica\Core\PConfig; use Friendica\Core\L10n; @@ -63,7 +63,7 @@ return [ // one instance for the whole execution 'shared' => true, ], - \Friendica\Core\Addon\Capabilities\ICanLoadAddons::class => [ + \Friendica\Core\Addon\Capability\ICanLoadAddons::class => [ 'instanceOf' => \Friendica\Core\Addon\Model\AddonLoader::class, 'constructParams' => [ [Dice::INSTANCE => '$basepath'], @@ -178,6 +178,20 @@ return [ $_SERVER, ], ], + '$hostname' => [ + 'instanceOf' => App\BaseURL::class, + 'constructParams' => [ + $_SERVER, + ], + 'call' => [ + ['getHost', [], Dice::CHAIN_CALL], + ], + ], + Cache\Type\AbstractCache::class => [ + 'constructParams' => [ + [Dice::INSTANCE => '$hostname'], + ], + ], App\Page::class => [ 'constructParams' => [ [Dice::INSTANCE => '$basepath'], @@ -201,10 +215,10 @@ return [ ['create', [], Dice::CHAIN_CALL], ], ], - \Friendica\Core\Logger\Capabilities\IHaveCallIntrospections::class => [ + \Friendica\Core\Logger\Capability\IHaveCallIntrospections::class => [ 'instanceOf' => \Friendica\Core\Logger\Util\Introspection::class, 'constructParams' => [ - \Friendica\Core\Logger\Capabilities\IHaveCallIntrospections::IGNORE_CLASS_LIST, + \Friendica\Core\Logger\Capability\IHaveCallIntrospections::IGNORE_CLASS_LIST, ], ], '$devLogger' => [ @@ -276,8 +290,11 @@ return [ ['getBackend', [], Dice::CHAIN_CALL], ], ], - \Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs::class => [ - 'instanceOf' => \Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage::class, + \Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs::class => [ + 'instanceOf' => \Friendica\Core\KeyValueStorage\Factory\KeyValueStorage::class, + 'call' => [ + ['create', [], Dice::CHAIN_CALL], + ], ], Network\HTTPClient\Capability\ICanSendHttpRequests::class => [ 'instanceOf' => Network\HTTPClient\Factory\HttpClient::class, diff --git a/static/strategies.config.php b/static/strategies.config.php index bb3598c369..18872dc1d4 100644 --- a/static/strategies.config.php +++ b/static/strategies.config.php @@ -19,14 +19,31 @@ * */ -use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H; +use Friendica\Core\Cache; +use Friendica\Core\Hooks\Util\StrategiesFileManager; use Friendica\Core\Logger\Type; +use Friendica\Core\KeyValueStorage; +use Friendica\Core\PConfig; use Psr\Log; return [ Log\LoggerInterface::class => [ - Log\NullLogger::class => [''], - Type\SyslogLogger::class => ['syslog'], - Type\StreamLogger::class => ['stream'], + Log\NullLogger::class => [StrategiesFileManager::STRATEGY_DEFAULT_KEY], + Type\SyslogLogger::class => [Type\SyslogLogger::NAME], + Type\StreamLogger::class => [Type\StreamLogger::NAME], + ], + Cache\Capability\ICanCache::class => [ + Cache\Type\DatabaseCache::class => [Cache\Type\DatabaseCache::NAME, StrategiesFileManager::STRATEGY_DEFAULT_KEY], + Cache\Type\APCuCache::class => [Cache\Type\APCuCache::NAME], + Cache\Type\MemcacheCache::class => [Cache\Type\MemcacheCache::NAME], + Cache\Type\MemcachedCache::class => [Cache\Type\MemcachedCache::NAME], + Cache\Type\RedisCache::class => [Cache\Type\RedisCache::NAME], + ], + KeyValueStorage\Capability\IManageKeyValuePairs::class => [ + KeyValueStorage\Type\DBKeyValueStorage::class => [KeyValueStorage\Type\DBKeyValueStorage::NAME, StrategiesFileManager::STRATEGY_DEFAULT_KEY], + ], + PConfig\Capability\IManagePersonalConfigValues::class => [ + PConfig\Type\JitPConfig::class => [PConfig\Type\JitPConfig::NAME], + PConfig\Type\PreloadPConfig::class => [PConfig\Type\PreloadPConfig::NAME, StrategiesFileManager::STRATEGY_DEFAULT_KEY], ], ]; diff --git a/tests/phpunit-addons.xml b/tests/phpunit-addons.xml new file mode 100644 index 0000000000..3793249ab9 --- /dev/null +++ b/tests/phpunit-addons.xml @@ -0,0 +1,24 @@ + + + + ../addon/*/tests/ + + + + + ../addon/ + + + ../addon/*/tests/ + ../addon/*/view/ + ../addon/*/vendor/ + + + diff --git a/tests/src/Core/Addon/Model/AddonLoaderTest.php b/tests/src/Core/Addon/Model/AddonLoaderTest.php index 189110fded..f49333b32d 100644 --- a/tests/src/Core/Addon/Model/AddonLoaderTest.php +++ b/tests/src/Core/Addon/Model/AddonLoaderTest.php @@ -54,7 +54,7 @@ class AddonLoaderTest extends MockedTest [ + \Friendica\Core\Hooks\Capability\BehavioralHookType::STRATEGY => [ \Psr\Log\LoggerInterface::class => [ \Psr\Log\NullLogger::class => [''], ], @@ -79,7 +79,7 @@ EOF; 'addon/testaddon1/static/hooks.config.php' => $this->content, ], 'assertion' => [ - \Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [ + \Friendica\Core\Hooks\Capability\BehavioralHookType::STRATEGY => [ \Psr\Log\LoggerInterface::class => [ \Psr\Log\NullLogger::class => [''], ], @@ -94,7 +94,7 @@ EOF; 'addon/testaddon2/static/hooks.config.php' => $this->content, ], 'assertion' => [ - \Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [ + \Friendica\Core\Hooks\Capability\BehavioralHookType::STRATEGY => [ \Psr\Log\LoggerInterface::class => [ \Psr\Log\NullLogger::class => ['', ''], ], @@ -118,7 +118,7 @@ EOF; 'addon/testaddon2/static/hooks.config.php' => $this->content, ], 'assertion' => [ - \Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [ + \Friendica\Core\Hooks\Capability\BehavioralHookType::STRATEGY => [ \Psr\Log\LoggerInterface::class => [ \Psr\Log\NullLogger::class => [''], ], diff --git a/tests/src/Core/Cache/CacheTest.php b/tests/src/Core/Cache/CacheTest.php index 615a1095d5..775a29374c 100644 --- a/tests/src/Core/Cache/CacheTest.php +++ b/tests/src/Core/Cache/CacheTest.php @@ -23,6 +23,7 @@ namespace Friendica\Test\src\Core\Cache; use Friendica\Core\Cache\Capability\ICanCache; use Friendica\Core\Cache\Capability\ICanCacheInMemory; +use Friendica\Core\Cache\Type\AbstractCache; use Friendica\Test\MockedTest; use Friendica\Util\PidFile; @@ -246,4 +247,13 @@ abstract class CacheTest extends MockedTest self::assertTrue($this->instance->set('key space', 'value')); self::assertEquals('value', $this->instance->get('key space')); } + + public function testGetName() + { + if (defined(get_class($this->instance) . '::NAME')) { + self::assertEquals($this->instance::NAME, $this->instance->getName()); + } else { + self::expectNotToPerformAssertions(); + } + } } diff --git a/tests/src/Core/Cache/DatabaseCacheTest.php b/tests/src/Core/Cache/DatabaseCacheTest.php index 98afa9e248..63cc7e4452 100644 --- a/tests/src/Core/Cache/DatabaseCacheTest.php +++ b/tests/src/Core/Cache/DatabaseCacheTest.php @@ -21,6 +21,7 @@ namespace Friendica\Test\src\Core\Cache; +use Friendica\App\BaseURL; use Friendica\Core\Cache; use Friendica\Test\DatabaseTestTrait; use Friendica\Test\Util\CreateDatabaseTrait; diff --git a/tests/src/Core/Hooks/Model/InstanceManagerTest.php b/tests/src/Core/Hooks/Model/InstanceManagerTest.php index 44459eb2ee..7c5bea8029 100644 --- a/tests/src/Core/Hooks/Model/InstanceManagerTest.php +++ b/tests/src/Core/Hooks/Model/InstanceManagerTest.php @@ -235,4 +235,24 @@ class InstanceManagerTest extends MockedTest self::assertEquals($cBool, $getInstanceA->getCBool()); self::assertEquals($cBool, $getInstanceB->getCBool()); } + + /** + * @see https://github.com/friendica/friendica/issues/13318 + */ + public function testCaseInsensitiveNames() + { + $instance = new DiceInstanceManager(new Dice(), $this->hookFileManager); + + $instance->registerStrategy(IAmADecoratedInterface::class, FakeInstance::class, 'fake'); + + // CamelCase + self::assertInstanceOf(FakeInstance::class, $instance->create(IAmADecoratedInterface::class, 'Fake')); + // UPPER CASE + self::assertInstanceOf(FakeInstance::class, $instance->create(IAmADecoratedInterface::class, 'FAKE')); + // lower case + self::assertInstanceOf(FakeInstance::class, $instance->create(IAmADecoratedInterface::class, 'fake')); + // UnKnOwN + self::assertInstanceOf(FakeInstance::class, $instance->create(IAmADecoratedInterface::class, 'fAkE')); + } + } diff --git a/tests/src/Core/Hooks/Util/StrategiesFileManagerTest.php b/tests/src/Core/Hooks/Util/StrategiesFileManagerTest.php index 592f6f1e06..ebb213fa7b 100644 --- a/tests/src/Core/Hooks/Util/StrategiesFileManagerTest.php +++ b/tests/src/Core/Hooks/Util/StrategiesFileManagerTest.php @@ -21,8 +21,8 @@ namespace Friendica\Test\src\Core\Hooks\Util; -use Friendica\Core\Addon\Capabilities\ICanLoadAddons; -use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; +use Friendica\Core\Addon\Capability\ICanLoadAddons; +use Friendica\Core\Hooks\Capability\ICanRegisterStrategies; use Friendica\Core\Hooks\Exceptions\HookConfigException; use Friendica\Core\Hooks\Util\StrategiesFileManager; use Friendica\Test\MockedTest; diff --git a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php index 80a0f16de0..3a3b255365 100644 --- a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php +++ b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php @@ -21,7 +21,7 @@ namespace Friendica\Test\src\Core\KeyValueStorage; -use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage; use Friendica\Database\Database; use Friendica\Test\Util\CreateDatabaseTrait; diff --git a/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php index 6ccc0f5f4d..ddb0acc4dc 100644 --- a/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php +++ b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php @@ -21,7 +21,7 @@ namespace Friendica\Test\src\Core\KeyValueStorage; -use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs; +use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Test\MockedTest; abstract class KeyValueStorageTest extends MockedTest diff --git a/tests/src/Core/Logger/SyslogLoggerWrapper.php b/tests/src/Core/Logger/SyslogLoggerWrapper.php index 1e0c4535f9..dce28b164c 100644 --- a/tests/src/Core/Logger/SyslogLoggerWrapper.php +++ b/tests/src/Core/Logger/SyslogLoggerWrapper.php @@ -21,7 +21,7 @@ namespace Friendica\Test\src\Core\Logger; -use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections; +use Friendica\Core\Logger\Capability\IHaveCallIntrospections; use Friendica\Core\Logger\Type\SyslogLogger; /** diff --git a/update.php b/update.php index 14219bcdcb..980ec721ab 100644 --- a/update.php +++ b/update.php @@ -1333,3 +1333,19 @@ function update_1520(): int return Update::SUCCESS; } + +/** + * user-contact.remote_self was wrongly declared as boolean, possibly truncating integer values from contact.remote_self + * + * @return int + * @throws Exception + */ +function update_1524(): int +{ + $contacts = DBA::select('contact', ['uid', 'uri-id', 'remote_self'], ["`uid` != ?", 0]); + while ($contact = DBA::fetch($contacts)) { + Contact\User::insertForContactArray($contact); + } + + return Update::SUCCESS; +} diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index a017e59dc8..7a49e009de 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.09-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-16 16:40+0000\n" +"POT-Creation-Date: 2023-08-10 21:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,12 +45,12 @@ msgid "Item not found." msgstr "" #: mod/item.php:451 mod/message.php:67 mod/message.php:113 mod/notes.php:45 -#: mod/photos.php:152 mod/photos.php:670 src/Model/Event.php:522 +#: mod/photos.php:152 mod/photos.php:670 src/Model/Event.php:520 #: src/Module/Attach.php:55 src/Module/BaseApi.php:99 #: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:52 #: src/Module/Calendar/Event/API.php:88 src/Module/Calendar/Event/Form.php:84 #: src/Module/Calendar/Export.php:82 src/Module/Calendar/Show.php:82 -#: src/Module/Circle.php:40 src/Module/Circle.php:83 +#: src/Module/Circle.php:41 src/Module/Circle.php:84 #: src/Module/Contact/Advanced.php:60 src/Module/Contact/Follow.php:87 #: src/Module/Contact/Follow.php:160 src/Module/Contact/MatchInterests.php:86 #: src/Module/Contact/Suggestions.php:54 src/Module/Contact/Unfollow.php:66 @@ -388,7 +388,7 @@ msgid "Save" msgstr "" #: mod/photos.php:67 mod/photos.php:132 mod/photos.php:578 -#: src/Model/Event.php:514 src/Model/Profile.php:234 +#: src/Model/Event.php:512 src/Model/Profile.php:234 #: src/Module/Calendar/Export.php:74 src/Module/Calendar/Show.php:74 #: src/Module/DFRN/Poll.php:43 src/Module/Feed.php:65 src/Module/HCard.php:51 #: src/Module/Profile/Common.php:62 src/Module/Profile/Common.php:71 @@ -943,7 +943,7 @@ msgstr "" msgid "Enter user nickname: " msgstr "" -#: src/Console/User.php:182 src/Model/User.php:681 +#: src/Console/User.php:182 src/Model/User.php:692 #: src/Module/Api/Twitter/ContactEndpoint.php:74 #: src/Module/Moderation/Users/Active.php:71 #: src/Module/Moderation/Users/Blocked.php:71 @@ -1608,7 +1608,7 @@ msgstr "" #: src/Content/GroupManager.php:152 src/Content/Nav.php:276 #: src/Content/Text/HTML.php:880 src/Content/Widget.php:541 -#: src/Model/User.php:1229 +#: src/Model/User.php:1254 msgid "Groups" msgstr "" @@ -1651,31 +1651,31 @@ msgstr "" msgid "Follow Thread" msgstr "" -#: src/Content/Item.php:422 src/Model/Contact.php:1206 +#: src/Content/Item.php:422 src/Model/Contact.php:1205 msgid "View Status" msgstr "" -#: src/Content/Item.php:423 src/Content/Item.php:443 src/Model/Contact.php:1155 -#: src/Model/Contact.php:1198 src/Model/Contact.php:1207 +#: src/Content/Item.php:423 src/Content/Item.php:443 src/Model/Contact.php:1154 +#: src/Model/Contact.php:1197 src/Model/Contact.php:1206 #: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:233 msgid "View Profile" msgstr "" -#: src/Content/Item.php:424 src/Model/Contact.php:1208 +#: src/Content/Item.php:424 src/Model/Contact.php:1207 msgid "View Photos" msgstr "" -#: src/Content/Item.php:425 src/Model/Contact.php:1199 -#: src/Model/Contact.php:1209 +#: src/Content/Item.php:425 src/Model/Contact.php:1198 +#: src/Model/Contact.php:1208 msgid "Network Posts" msgstr "" -#: src/Content/Item.php:426 src/Model/Contact.php:1200 -#: src/Model/Contact.php:1210 +#: src/Content/Item.php:426 src/Model/Contact.php:1199 +#: src/Model/Contact.php:1209 msgid "View Contact" msgstr "" -#: src/Content/Item.php:427 src/Model/Contact.php:1211 +#: src/Content/Item.php:427 src/Model/Contact.php:1210 msgid "Send PM" msgstr "" @@ -1705,7 +1705,7 @@ msgid "Languages" msgstr "" #: src/Content/Item.php:440 src/Content/Widget.php:80 -#: src/Model/Contact.php:1201 src/Model/Contact.php:1212 +#: src/Model/Contact.php:1200 src/Model/Contact.php:1211 #: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195 msgid "Connect/Follow" msgstr "" @@ -1895,7 +1895,7 @@ msgstr "" #: src/Content/Nav.php:299 src/Module/Admin/Tos.php:78 #: src/Module/BaseAdmin.php:95 src/Module/Register.php:176 -#: src/Module/Tos.php:100 +#: src/Module/Tos.php:101 msgid "Terms of Service" msgstr "" @@ -2008,11 +2008,11 @@ msgstr "" msgid "Site map" msgstr "" -#: src/Content/OEmbed.php:317 +#: src/Content/OEmbed.php:316 msgid "Embedding disabled" msgstr "" -#: src/Content/OEmbed.php:441 +#: src/Content/OEmbed.php:440 msgid "Embedded content" msgstr "" @@ -2032,8 +2032,8 @@ msgstr "" msgid "last" msgstr "" -#: src/Content/Text/BBCode.php:696 src/Content/Text/BBCode.php:1602 -#: src/Content/Text/BBCode.php:1603 +#: src/Content/Text/BBCode.php:696 src/Content/Text/BBCode.php:1636 +#: src/Content/Text/BBCode.php:1637 msgid "Image/photo" msgstr "" @@ -2048,23 +2048,23 @@ msgstr "" msgid "Link to source" msgstr "" -#: src/Content/Text/BBCode.php:1509 src/Content/Text/HTML.php:904 +#: src/Content/Text/BBCode.php:1543 src/Content/Text/HTML.php:904 msgid "Click to open/close" msgstr "" -#: src/Content/Text/BBCode.php:1542 +#: src/Content/Text/BBCode.php:1576 msgid "$1 wrote:" msgstr "" -#: src/Content/Text/BBCode.php:1607 src/Content/Text/BBCode.php:1608 +#: src/Content/Text/BBCode.php:1641 src/Content/Text/BBCode.php:1642 msgid "Encrypted content" msgstr "" -#: src/Content/Text/BBCode.php:1872 +#: src/Content/Text/BBCode.php:1901 msgid "Invalid source protocol" msgstr "" -#: src/Content/Text/BBCode.php:1891 +#: src/Content/Text/BBCode.php:1920 msgid "Invalid link protocol" msgstr "" @@ -2147,7 +2147,7 @@ msgstr "" msgid "Local Directory" msgstr "" -#: src/Content/Widget.php:219 src/Model/Circle.php:594 +#: src/Content/Widget.php:219 src/Model/Circle.php:600 #: src/Module/Contact.php:401 src/Module/Welcome.php:76 msgid "Circles" msgstr "" @@ -2164,7 +2164,7 @@ msgstr "" msgid "Relationships" msgstr "" -#: src/Content/Widget.php:253 src/Module/Circle.php:293 +#: src/Content/Widget.php:253 src/Module/Circle.php:292 #: src/Module/Contact.php:345 msgid "All Contacts" msgstr "" @@ -2212,7 +2212,7 @@ msgstr "" msgid "Organisations" msgstr "" -#: src/Content/Widget.php:540 src/Model/Contact.php:1676 +#: src/Content/Widget.php:540 src/Model/Contact.php:1675 msgid "News" msgstr "" @@ -2281,7 +2281,7 @@ msgid "Matrix:" msgstr "" #: src/Content/Widget/VCard.php:111 src/Model/Event.php:82 -#: src/Model/Event.php:109 src/Model/Event.php:473 src/Model/Event.php:965 +#: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963 #: src/Model/Profile.php:373 src/Module/Contact/Profile.php:379 #: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187 #: src/Module/Profile/Profile.php:221 @@ -2293,8 +2293,8 @@ msgstr "" msgid "Network:" msgstr "" -#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1202 -#: src/Model/Contact.php:1213 src/Model/Profile.php:465 +#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1201 +#: src/Model/Contact.php:1212 src/Model/Profile.php:465 #: src/Module/Contact/Profile.php:429 msgid "Unfollow" msgstr "" @@ -2678,142 +2678,142 @@ msgstr "" msgid "Could not connect to database." msgstr "" -#: src/Core/L10n.php:408 src/Model/Event.php:432 +#: src/Core/L10n.php:408 src/Model/Event.php:430 #: src/Module/Settings/Display.php:222 msgid "Monday" msgstr "" -#: src/Core/L10n.php:408 src/Model/Event.php:433 +#: src/Core/L10n.php:408 src/Model/Event.php:431 #: src/Module/Settings/Display.php:223 msgid "Tuesday" msgstr "" -#: src/Core/L10n.php:408 src/Model/Event.php:434 +#: src/Core/L10n.php:408 src/Model/Event.php:432 #: src/Module/Settings/Display.php:224 msgid "Wednesday" msgstr "" -#: src/Core/L10n.php:408 src/Model/Event.php:435 +#: src/Core/L10n.php:408 src/Model/Event.php:433 #: src/Module/Settings/Display.php:225 msgid "Thursday" msgstr "" -#: src/Core/L10n.php:408 src/Model/Event.php:436 +#: src/Core/L10n.php:408 src/Model/Event.php:434 #: src/Module/Settings/Display.php:226 msgid "Friday" msgstr "" -#: src/Core/L10n.php:408 src/Model/Event.php:437 +#: src/Core/L10n.php:408 src/Model/Event.php:435 #: src/Module/Settings/Display.php:227 msgid "Saturday" msgstr "" -#: src/Core/L10n.php:408 src/Model/Event.php:431 +#: src/Core/L10n.php:408 src/Model/Event.php:429 #: src/Module/Settings/Display.php:221 msgid "Sunday" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:452 +#: src/Core/L10n.php:412 src/Model/Event.php:450 msgid "January" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:453 +#: src/Core/L10n.php:412 src/Model/Event.php:451 msgid "February" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:454 +#: src/Core/L10n.php:412 src/Model/Event.php:452 msgid "March" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:455 +#: src/Core/L10n.php:412 src/Model/Event.php:453 msgid "April" msgstr "" -#: src/Core/L10n.php:412 src/Core/L10n.php:431 src/Model/Event.php:443 +#: src/Core/L10n.php:412 src/Core/L10n.php:431 src/Model/Event.php:441 msgid "May" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:456 +#: src/Core/L10n.php:412 src/Model/Event.php:454 msgid "June" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:457 +#: src/Core/L10n.php:412 src/Model/Event.php:455 msgid "July" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:458 +#: src/Core/L10n.php:412 src/Model/Event.php:456 msgid "August" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:459 +#: src/Core/L10n.php:412 src/Model/Event.php:457 msgid "September" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:460 +#: src/Core/L10n.php:412 src/Model/Event.php:458 msgid "October" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:461 +#: src/Core/L10n.php:412 src/Model/Event.php:459 msgid "November" msgstr "" -#: src/Core/L10n.php:412 src/Model/Event.php:462 +#: src/Core/L10n.php:412 src/Model/Event.php:460 msgid "December" msgstr "" -#: src/Core/L10n.php:427 src/Model/Event.php:424 +#: src/Core/L10n.php:427 src/Model/Event.php:422 msgid "Mon" msgstr "" -#: src/Core/L10n.php:427 src/Model/Event.php:425 +#: src/Core/L10n.php:427 src/Model/Event.php:423 msgid "Tue" msgstr "" -#: src/Core/L10n.php:427 src/Model/Event.php:426 +#: src/Core/L10n.php:427 src/Model/Event.php:424 msgid "Wed" msgstr "" -#: src/Core/L10n.php:427 src/Model/Event.php:427 +#: src/Core/L10n.php:427 src/Model/Event.php:425 msgid "Thu" msgstr "" -#: src/Core/L10n.php:427 src/Model/Event.php:428 +#: src/Core/L10n.php:427 src/Model/Event.php:426 msgid "Fri" msgstr "" -#: src/Core/L10n.php:427 src/Model/Event.php:429 +#: src/Core/L10n.php:427 src/Model/Event.php:427 msgid "Sat" msgstr "" -#: src/Core/L10n.php:427 src/Model/Event.php:423 +#: src/Core/L10n.php:427 src/Model/Event.php:421 msgid "Sun" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:439 +#: src/Core/L10n.php:431 src/Model/Event.php:437 msgid "Jan" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:440 +#: src/Core/L10n.php:431 src/Model/Event.php:438 msgid "Feb" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:441 +#: src/Core/L10n.php:431 src/Model/Event.php:439 msgid "Mar" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:442 +#: src/Core/L10n.php:431 src/Model/Event.php:440 msgid "Apr" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:444 +#: src/Core/L10n.php:431 src/Model/Event.php:442 msgid "Jun" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:445 +#: src/Core/L10n.php:431 src/Model/Event.php:443 msgid "Jul" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:446 +#: src/Core/L10n.php:431 src/Model/Event.php:444 msgid "Aug" msgstr "" @@ -2821,15 +2821,15 @@ msgstr "" msgid "Sep" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:448 +#: src/Core/L10n.php:431 src/Model/Event.php:446 msgid "Oct" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:449 +#: src/Core/L10n.php:431 src/Model/Event.php:447 msgid "Nov" msgstr "" -#: src/Core/L10n.php:431 src/Model/Event.php:450 +#: src/Core/L10n.php:431 src/Model/Event.php:448 msgid "Dec" msgstr "" @@ -3007,122 +3007,122 @@ msgstr "" msgid "Legacy module file not found: %s" msgstr "" -#: src/Model/Circle.php:105 +#: src/Model/Circle.php:106 msgid "" "A deleted circle with this name was revived. Existing item permissions " "may apply to this circle and any future members. If this is " "not what you intended, please create another circle with a different name." msgstr "" -#: src/Model/Circle.php:542 +#: src/Model/Circle.php:543 msgid "Everybody" msgstr "" -#: src/Model/Circle.php:561 +#: src/Model/Circle.php:562 msgid "edit" msgstr "" -#: src/Model/Circle.php:593 +#: src/Model/Circle.php:599 msgid "add" msgstr "" -#: src/Model/Circle.php:598 +#: src/Model/Circle.php:604 msgid "Edit circle" msgstr "" -#: src/Model/Circle.php:599 src/Module/Circle.php:194 +#: src/Model/Circle.php:605 src/Module/Circle.php:193 msgid "Contacts not in any circle" msgstr "" -#: src/Model/Circle.php:601 +#: src/Model/Circle.php:607 msgid "Create a new circle" msgstr "" -#: src/Model/Circle.php:602 src/Module/Circle.php:179 src/Module/Circle.php:202 -#: src/Module/Circle.php:277 +#: src/Model/Circle.php:608 src/Module/Circle.php:178 src/Module/Circle.php:201 +#: src/Module/Circle.php:276 msgid "Circle Name: " msgstr "" -#: src/Model/Circle.php:603 +#: src/Model/Circle.php:609 msgid "Edit circles" msgstr "" -#: src/Model/Contact.php:1219 src/Module/Moderation/Users/Pending.php:102 +#: src/Model/Contact.php:1218 src/Module/Moderation/Users/Pending.php:102 #: src/Module/Notifications/Introductions.php:132 #: src/Module/Notifications/Introductions.php:204 msgid "Approve" msgstr "" -#: src/Model/Contact.php:1672 +#: src/Model/Contact.php:1671 msgid "Organisation" msgstr "" -#: src/Model/Contact.php:1680 +#: src/Model/Contact.php:1679 msgid "Group" msgstr "" -#: src/Model/Contact.php:2989 +#: src/Model/Contact.php:2988 msgid "Disallowed profile URL." msgstr "" -#: src/Model/Contact.php:2994 src/Module/Friendica.php:102 +#: src/Model/Contact.php:2993 src/Module/Friendica.php:102 msgid "Blocked domain" msgstr "" -#: src/Model/Contact.php:2999 +#: src/Model/Contact.php:2998 msgid "Connect URL missing." msgstr "" -#: src/Model/Contact.php:3008 +#: src/Model/Contact.php:3007 msgid "" "The contact could not be added. Please check the relevant network " "credentials in your Settings -> Social Networks page." msgstr "" -#: src/Model/Contact.php:3026 +#: src/Model/Contact.php:3025 #, php-format msgid "Expected network %s does not match actual network %s" msgstr "" -#: src/Model/Contact.php:3043 +#: src/Model/Contact.php:3042 msgid "The profile address specified does not provide adequate information." msgstr "" -#: src/Model/Contact.php:3045 +#: src/Model/Contact.php:3044 msgid "No compatible communication protocols or feeds were discovered." msgstr "" -#: src/Model/Contact.php:3048 +#: src/Model/Contact.php:3047 msgid "An author or name was not found." msgstr "" -#: src/Model/Contact.php:3051 +#: src/Model/Contact.php:3050 msgid "No browser URL could be matched to this address." msgstr "" -#: src/Model/Contact.php:3054 +#: src/Model/Contact.php:3053 msgid "" "Unable to match @-style Identity Address with a known protocol or email " "contact." msgstr "" -#: src/Model/Contact.php:3055 +#: src/Model/Contact.php:3054 msgid "Use mailto: in front of address to force email check." msgstr "" -#: src/Model/Contact.php:3061 +#: src/Model/Contact.php:3060 msgid "" "The profile address specified belongs to a network which has been disabled " "on this site." msgstr "" -#: src/Model/Contact.php:3066 +#: src/Model/Contact.php:3065 msgid "" "Limited profile. This person will be unable to receive direct/personal " "notifications from you." msgstr "" -#: src/Model/Contact.php:3132 +#: src/Model/Contact.php:3131 msgid "Unable to retrieve contact information." msgstr "" @@ -3130,99 +3130,99 @@ msgstr "" msgid "l F d, Y \\@ g:i A \\G\\M\\TP (e)" msgstr "" -#: src/Model/Event.php:75 src/Model/Event.php:92 src/Model/Event.php:471 -#: src/Model/Event.php:947 +#: src/Model/Event.php:75 src/Model/Event.php:92 src/Model/Event.php:469 +#: src/Model/Event.php:945 msgid "Starts:" msgstr "" -#: src/Model/Event.php:78 src/Model/Event.php:98 src/Model/Event.php:472 -#: src/Model/Event.php:951 +#: src/Model/Event.php:78 src/Model/Event.php:98 src/Model/Event.php:470 +#: src/Model/Event.php:949 msgid "Finishes:" msgstr "" -#: src/Model/Event.php:421 +#: src/Model/Event.php:419 msgid "all-day" msgstr "" -#: src/Model/Event.php:447 +#: src/Model/Event.php:445 msgid "Sept" msgstr "" -#: src/Model/Event.php:464 src/Module/Calendar/Show.php:128 +#: src/Model/Event.php:462 src/Module/Calendar/Show.php:128 #: src/Util/Temporal.php:343 msgid "today" msgstr "" -#: src/Model/Event.php:465 src/Module/Calendar/Show.php:129 +#: src/Model/Event.php:463 src/Module/Calendar/Show.php:129 #: src/Module/Settings/Display.php:232 src/Util/Temporal.php:353 msgid "month" msgstr "" -#: src/Model/Event.php:466 src/Module/Calendar/Show.php:130 +#: src/Model/Event.php:464 src/Module/Calendar/Show.php:130 #: src/Module/Settings/Display.php:233 src/Util/Temporal.php:354 msgid "week" msgstr "" -#: src/Model/Event.php:467 src/Module/Calendar/Show.php:131 +#: src/Model/Event.php:465 src/Module/Calendar/Show.php:131 #: src/Module/Settings/Display.php:234 src/Util/Temporal.php:355 msgid "day" msgstr "" -#: src/Model/Event.php:469 +#: src/Model/Event.php:467 msgid "No events to display" msgstr "" -#: src/Model/Event.php:518 src/Module/DFRN/Poll.php:47 src/Module/Feed.php:69 +#: src/Model/Event.php:516 src/Module/DFRN/Poll.php:47 src/Module/Feed.php:69 #: src/Module/Update/Profile.php:56 msgid "Access to this profile has been restricted." msgstr "" -#: src/Model/Event.php:560 src/Module/Calendar/Event/Show.php:67 +#: src/Model/Event.php:558 src/Module/Calendar/Event/Show.php:67 msgid "Event not found." msgstr "" -#: src/Model/Event.php:639 +#: src/Model/Event.php:637 msgid "l, F j" msgstr "" -#: src/Model/Event.php:666 +#: src/Model/Event.php:664 msgid "Edit event" msgstr "" -#: src/Model/Event.php:667 +#: src/Model/Event.php:665 msgid "Duplicate event" msgstr "" -#: src/Model/Event.php:668 +#: src/Model/Event.php:666 msgid "Delete event" msgstr "" -#: src/Model/Event.php:898 src/Module/Debug/Localtime.php:38 +#: src/Model/Event.php:896 src/Module/Debug/Localtime.php:38 msgid "l F d, Y \\@ g:i A" msgstr "" -#: src/Model/Event.php:899 +#: src/Model/Event.php:897 msgid "D g:i A" msgstr "" -#: src/Model/Event.php:900 +#: src/Model/Event.php:898 msgid "g:i A" msgstr "" -#: src/Model/Event.php:966 src/Model/Event.php:968 +#: src/Model/Event.php:964 src/Model/Event.php:966 msgid "Show map" msgstr "" -#: src/Model/Event.php:967 +#: src/Model/Event.php:965 msgid "Hide map" msgstr "" -#: src/Model/Event.php:1060 +#: src/Model/Event.php:1058 #, php-format msgid "%s's birthday" msgstr "" -#: src/Model/Event.php:1061 +#: src/Model/Event.php:1059 #, php-format msgid "Happy Birthday %s" msgstr "" @@ -3459,145 +3459,145 @@ msgstr "" msgid "Contact information and Social Networks" msgstr "" -#: src/Model/User.php:214 src/Model/User.php:1142 +#: src/Model/User.php:225 src/Model/User.php:1167 msgid "SERIOUS ERROR: Generation of security keys failed." msgstr "" -#: src/Model/User.php:590 src/Model/User.php:623 +#: src/Model/User.php:601 src/Model/User.php:634 msgid "Login failed" msgstr "" -#: src/Model/User.php:655 +#: src/Model/User.php:666 msgid "Not enough information to authenticate" msgstr "" -#: src/Model/User.php:776 +#: src/Model/User.php:787 msgid "Password can't be empty" msgstr "" -#: src/Model/User.php:818 +#: src/Model/User.php:829 msgid "Empty passwords are not allowed." msgstr "" -#: src/Model/User.php:822 +#: src/Model/User.php:833 msgid "" "The new password has been exposed in a public data dump, please choose " "another." msgstr "" -#: src/Model/User.php:826 +#: src/Model/User.php:837 msgid "The password length is limited to 72 characters." msgstr "" -#: src/Model/User.php:830 +#: src/Model/User.php:841 msgid "The password can't contain white spaces nor accentuated letters" msgstr "" -#: src/Model/User.php:1025 +#: src/Model/User.php:1050 msgid "Passwords do not match. Password unchanged." msgstr "" -#: src/Model/User.php:1032 +#: src/Model/User.php:1057 msgid "An invitation is required." msgstr "" -#: src/Model/User.php:1036 +#: src/Model/User.php:1061 msgid "Invitation could not be verified." msgstr "" -#: src/Model/User.php:1044 +#: src/Model/User.php:1069 msgid "Invalid OpenID url" msgstr "" -#: src/Model/User.php:1057 src/Security/Authentication.php:241 +#: src/Model/User.php:1082 src/Security/Authentication.php:241 msgid "" "We encountered a problem while logging in with the OpenID you provided. " "Please check the correct spelling of the ID." msgstr "" -#: src/Model/User.php:1057 src/Security/Authentication.php:241 +#: src/Model/User.php:1082 src/Security/Authentication.php:241 msgid "The error message was:" msgstr "" -#: src/Model/User.php:1063 +#: src/Model/User.php:1088 msgid "Please enter the required information." msgstr "" -#: src/Model/User.php:1077 +#: src/Model/User.php:1102 #, php-format msgid "" "system.username_min_length (%s) and system.username_max_length (%s) are " "excluding each other, swapping values." msgstr "" -#: src/Model/User.php:1084 +#: src/Model/User.php:1109 #, php-format msgid "Username should be at least %s character." msgid_plural "Username should be at least %s characters." msgstr[0] "" msgstr[1] "" -#: src/Model/User.php:1088 +#: src/Model/User.php:1113 #, php-format msgid "Username should be at most %s character." msgid_plural "Username should be at most %s characters." msgstr[0] "" msgstr[1] "" -#: src/Model/User.php:1096 +#: src/Model/User.php:1121 msgid "That doesn't appear to be your full (First Last) name." msgstr "" -#: src/Model/User.php:1101 +#: src/Model/User.php:1126 msgid "Your email domain is not among those allowed on this site." msgstr "" -#: src/Model/User.php:1105 +#: src/Model/User.php:1130 msgid "Not a valid email address." msgstr "" -#: src/Model/User.php:1108 +#: src/Model/User.php:1133 msgid "The nickname was blocked from registration by the nodes admin." msgstr "" -#: src/Model/User.php:1112 src/Model/User.php:1118 +#: src/Model/User.php:1137 src/Model/User.php:1143 msgid "Cannot use that email." msgstr "" -#: src/Model/User.php:1124 +#: src/Model/User.php:1149 msgid "Your nickname can only contain a-z, 0-9 and _." msgstr "" -#: src/Model/User.php:1132 src/Model/User.php:1189 +#: src/Model/User.php:1157 src/Model/User.php:1214 msgid "Nickname is already registered. Please choose another." msgstr "" -#: src/Model/User.php:1176 src/Model/User.php:1180 +#: src/Model/User.php:1201 src/Model/User.php:1205 msgid "An error occurred during registration. Please try again." msgstr "" -#: src/Model/User.php:1203 +#: src/Model/User.php:1228 msgid "An error occurred creating your default profile. Please try again." msgstr "" -#: src/Model/User.php:1210 +#: src/Model/User.php:1235 msgid "An error occurred creating your self contact. Please try again." msgstr "" -#: src/Model/User.php:1215 +#: src/Model/User.php:1240 msgid "Friends" msgstr "" -#: src/Model/User.php:1219 +#: src/Model/User.php:1244 msgid "" "An error occurred creating your default contact circle. Please try again." msgstr "" -#: src/Model/User.php:1263 +#: src/Model/User.php:1288 msgid "Profile Photos" msgstr "" -#: src/Model/User.php:1458 +#: src/Model/User.php:1483 #, php-format msgid "" "\n" @@ -3605,7 +3605,7 @@ msgid "" "\t\t\tthe administrator of %2$s has set up an account for you." msgstr "" -#: src/Model/User.php:1461 +#: src/Model/User.php:1486 #, php-format msgid "" "\n" @@ -3643,12 +3643,12 @@ msgid "" "\t\tThank you and welcome to %4$s." msgstr "" -#: src/Model/User.php:1494 src/Model/User.php:1601 +#: src/Model/User.php:1519 src/Model/User.php:1626 #, php-format msgid "Registration details for %s" msgstr "" -#: src/Model/User.php:1514 +#: src/Model/User.php:1539 #, php-format msgid "" "\n" @@ -3664,12 +3664,12 @@ msgid "" "\t\t" msgstr "" -#: src/Model/User.php:1533 +#: src/Model/User.php:1558 #, php-format msgid "Registration at %s" msgstr "" -#: src/Model/User.php:1557 +#: src/Model/User.php:1582 #, php-format msgid "" "\n" @@ -3678,7 +3678,7 @@ msgid "" "\t\t\t" msgstr "" -#: src/Model/User.php:1565 +#: src/Model/User.php:1590 #, php-format msgid "" "\n" @@ -3742,7 +3742,7 @@ msgid "Enable" msgstr "" #: src/Module/Admin/Addons/Details.php:111 src/Module/Admin/Addons/Index.php:67 -#: src/Module/Admin/Federation.php:210 src/Module/Admin/Logs/Settings.php:85 +#: src/Module/Admin/Federation.php:214 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:398 src/Module/Admin/Storage.php:138 #: src/Module/Admin/Summary.php:196 src/Module/Admin/Themes/Details.php:90 @@ -3878,71 +3878,71 @@ msgstr "" msgid "Other" msgstr "" -#: src/Module/Admin/Federation.php:150 src/Module/Admin/Federation.php:399 +#: src/Module/Admin/Federation.php:154 src/Module/Admin/Federation.php:403 msgid "unknown" msgstr "" -#: src/Module/Admin/Federation.php:183 +#: src/Module/Admin/Federation.php:187 #, php-format msgid "%2$s total system" msgid_plural "%2$s total systems" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:184 +#: src/Module/Admin/Federation.php:188 #, php-format msgid "%2$s active user last month" msgid_plural "%2$s active users last month" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:185 +#: src/Module/Admin/Federation.php:189 #, php-format msgid "%2$s active user last six months" msgid_plural "%2$s active users last six months" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:186 +#: src/Module/Admin/Federation.php:190 #, php-format msgid "%2$s registered user" msgid_plural "%2$s registered users" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:187 +#: src/Module/Admin/Federation.php:191 #, php-format msgid "%2$s locally created post or comment" msgid_plural "%2$s locally created posts and comments" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:190 +#: src/Module/Admin/Federation.php:194 #, php-format msgid "%2$s post per user" msgid_plural "%2$s posts per user" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:195 +#: src/Module/Admin/Federation.php:199 #, php-format msgid "%2$s user per system" msgid_plural "%2$s users per system" msgstr[0] "" msgstr[1] "" -#: src/Module/Admin/Federation.php:205 +#: src/Module/Admin/Federation.php:209 msgid "" "This page offers you some numbers to the known part of the federated social " "network your Friendica node is part of. These numbers are not complete but " "only reflect the part of the network your node is aware of." msgstr "" -#: src/Module/Admin/Federation.php:211 src/Module/BaseAdmin.php:87 +#: src/Module/Admin/Federation.php:215 src/Module/BaseAdmin.php:87 msgid "Federation Statistics" msgstr "" -#: src/Module/Admin/Federation.php:215 +#: src/Module/Admin/Federation.php:219 #, php-format msgid "" "Currently this node is aware of %2$s node (%3$s active users last month, " @@ -5420,11 +5420,11 @@ msgstr "" msgid "Please login to continue." msgstr "" -#: src/Module/BaseAdmin.php:63 src/Module/BaseModeration.php:86 +#: src/Module/BaseAdmin.php:63 msgid "You don't have access to administration pages." msgstr "" -#: src/Module/BaseAdmin.php:67 src/Module/BaseModeration.php:90 +#: src/Module/BaseAdmin.php:67 msgid "" "Submanaged account can't access the administration pages. Please log back in " "as the main account." @@ -5517,6 +5517,16 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" +#: src/Module/BaseModeration.php:86 +msgid "You don't have access to moderation pages." +msgstr "" + +#: src/Module/BaseModeration.php:90 +msgid "" +"Submanaged account can't access the moderation pages. Please log back in as " +"the main account." +msgstr "" + #: src/Module/BaseModeration.php:112 src/Module/Moderation/Users/Index.php:148 #: src/Module/Moderation/Users/Index.php:158 msgid "Users" @@ -5746,23 +5756,23 @@ msgstr "" msgid "list" msgstr "" -#: src/Module/Circle.php:56 +#: src/Module/Circle.php:57 msgid "Could not create circle." msgstr "" -#: src/Module/Circle.php:67 src/Module/Circle.php:215 src/Module/Circle.php:239 +#: src/Module/Circle.php:68 src/Module/Circle.php:214 src/Module/Circle.php:238 msgid "Circle not found." msgstr "" -#: src/Module/Circle.php:73 +#: src/Module/Circle.php:74 msgid "Circle name was not changed." msgstr "" -#: src/Module/Circle.php:91 +#: src/Module/Circle.php:92 msgid "Unknown circle." msgstr "" -#: src/Module/Circle.php:97 src/Module/Circle.php:106 +#: src/Module/Circle.php:98 src/Module/Circle.php:107 #: src/Module/Contact/Advanced.php:70 src/Module/Contact/Advanced.php:109 #: src/Module/Contact/Contacts.php:71 src/Module/Contact/Conversations.php:84 #: src/Module/Contact/Conversations.php:89 @@ -5775,76 +5785,76 @@ msgstr "" msgid "Contact not found." msgstr "" -#: src/Module/Circle.php:101 src/Module/Contact/Contacts.php:66 +#: src/Module/Circle.php:102 src/Module/Contact/Contacts.php:66 #: src/Module/Conversation/Network.php:189 msgid "Invalid contact." msgstr "" -#: src/Module/Circle.php:110 src/Module/Contact/Revoke.php:73 +#: src/Module/Circle.php:111 src/Module/Contact/Revoke.php:73 msgid "Contact is deleted." msgstr "" -#: src/Module/Circle.php:116 +#: src/Module/Circle.php:117 msgid "Unable to add the contact to the circle." msgstr "" -#: src/Module/Circle.php:119 +#: src/Module/Circle.php:120 msgid "Contact successfully added to circle." msgstr "" -#: src/Module/Circle.php:123 +#: src/Module/Circle.php:124 msgid "Unable to remove the contact from the circle." msgstr "" -#: src/Module/Circle.php:126 +#: src/Module/Circle.php:127 msgid "Contact successfully removed from circle." msgstr "" -#: src/Module/Circle.php:130 +#: src/Module/Circle.php:131 msgid "Bad request." msgstr "" -#: src/Module/Circle.php:171 +#: src/Module/Circle.php:170 msgid "Save Circle" msgstr "" -#: src/Module/Circle.php:172 +#: src/Module/Circle.php:171 msgid "Filter" msgstr "" -#: src/Module/Circle.php:178 +#: src/Module/Circle.php:177 msgid "Create a circle of contacts/friends." msgstr "" -#: src/Module/Circle.php:220 +#: src/Module/Circle.php:219 msgid "Unable to remove circle." msgstr "" -#: src/Module/Circle.php:271 +#: src/Module/Circle.php:270 msgid "Delete Circle" msgstr "" -#: src/Module/Circle.php:281 +#: src/Module/Circle.php:280 msgid "Edit Circle Name" msgstr "" -#: src/Module/Circle.php:291 +#: src/Module/Circle.php:290 msgid "Members" msgstr "" -#: src/Module/Circle.php:294 +#: src/Module/Circle.php:293 msgid "Circle is empty" msgstr "" -#: src/Module/Circle.php:307 +#: src/Module/Circle.php:306 msgid "Remove contact from circle" msgstr "" -#: src/Module/Circle.php:328 +#: src/Module/Circle.php:329 msgid "Click on a contact to add or remove." msgstr "" -#: src/Module/Circle.php:342 +#: src/Module/Circle.php:343 msgid "Add contact to circle" msgstr "" @@ -8347,11 +8357,11 @@ msgstr "" msgid "Show unread" msgstr "" -#: src/Module/Notifications/Ping.php:245 +#: src/Module/Notifications/Ping.php:246 msgid "{0} requested registration" msgstr "" -#: src/Module/Notifications/Ping.php:254 +#: src/Module/Notifications/Ping.php:255 #, php-format msgid "{0} and %d others requested registration" msgstr "" @@ -8370,7 +8380,7 @@ msgstr "" msgid "Unsupported or missing response type" msgstr "" -#: src/Module/OAuth/Authorize.php:59 src/Module/OAuth/Token.php:77 +#: src/Module/OAuth/Authorize.php:59 src/Module/OAuth/Token.php:78 msgid "Incomplete request data" msgstr "" @@ -8381,11 +8391,11 @@ msgid "" "close this window: %s" msgstr "" -#: src/Module/OAuth/Token.php:82 +#: src/Module/OAuth/Token.php:83 msgid "Invalid data or unknown client" msgstr "" -#: src/Module/OAuth/Token.php:104 +#: src/Module/OAuth/Token.php:108 msgid "Unsupported or missing grant type" msgstr "" @@ -10723,7 +10733,7 @@ msgstr "" msgid "Exception thrown in %s:%d" msgstr "" -#: src/Module/Tos.php:57 src/Module/Tos.php:106 +#: src/Module/Tos.php:58 src/Module/Tos.php:107 msgid "" "At the time of registration, and for providing communications between the " "user account and their contacts, the user has to provide a display name (pen " @@ -10736,14 +10746,14 @@ msgid "" "settings, it is not necessary for communication." msgstr "" -#: src/Module/Tos.php:58 src/Module/Tos.php:107 +#: src/Module/Tos.php:59 src/Module/Tos.php:108 msgid "" "This data is required for communication and is passed on to the nodes of the " "communication partners and is stored there. Users can enter additional " "private data that may be transmitted to the communication partners accounts." msgstr "" -#: src/Module/Tos.php:59 src/Module/Tos.php:108 +#: src/Module/Tos.php:60 src/Module/Tos.php:109 #, php-format msgid "" "At any point in time a logged in user can export their account data from the " @@ -10754,11 +10764,11 @@ msgid "" "communication partners." msgstr "" -#: src/Module/Tos.php:62 src/Module/Tos.php:105 +#: src/Module/Tos.php:63 src/Module/Tos.php:106 msgid "Privacy Statement" msgstr "" -#: src/Module/Tos.php:102 +#: src/Module/Tos.php:103 msgid "Rules" msgstr "" diff --git a/view/templates/field_combobox.tpl b/view/templates/field_combobox.tpl index 3e6e06052f..b62bf2dbac 100644 --- a/view/templates/field_combobox.tpl +++ b/view/templates/field_combobox.tpl @@ -1,4 +1,3 @@ - {{$field.1}} {{* html5 don't work on Chrome, Safari and IE9 @@ -6,13 +5,13 @@ {{foreach $field.4 as $opt=>$val}}{{/foreach}} *}} - - + + {{$field.5}} {{foreach $field.4 as $opt=>$val}}{{$val}}{{/foreach}} - + {{if $field.3}} {{$field.3 nofilter}} {{/if}} diff --git a/view/templates/field_openid.tpl b/view/templates/field_openid.tpl index 3c7d02bb8e..033a1f8e50 100644 --- a/view/templates/field_openid.tpl +++ b/view/templates/field_openid.tpl @@ -1,7 +1,6 @@ - {{$field.1}} - + {{if $field.3}} {{$field.3 nofilter}} {{/if}} diff --git a/view/templates/field_password.tpl b/view/templates/field_password.tpl index 07241fb11b..57149fe52d 100644 --- a/view/templates/field_password.tpl +++ b/view/templates/field_password.tpl @@ -1,7 +1,6 @@ - {{$field.1}}{{if $field.4}} *{{/if}} - + {{if $field.3}} {{$field.3 nofilter}} {{/if}} diff --git a/view/theme/frio/php/default.php b/view/theme/frio/php/default.php index a75207a206..74c30f6f7b 100644 --- a/view/theme/frio/php/default.php +++ b/view/theme/frio/php/default.php @@ -137,12 +137,12 @@ $is_singleuser_class = $is_singleuser ? "is-singleuser" : "is-not-singleuser"; '; } else { echo ' - '; + '; if (!empty($page['content'])) { echo $page['content']; } echo ' - + '; } ?> diff --git a/view/theme/frio/templates/field_colorinput.tpl b/view/theme/frio/templates/field_colorinput.tpl index 2c530a2e46..f812ff234b 100644 --- a/view/theme/frio/templates/field_colorinput.tpl +++ b/view/theme/frio/templates/field_colorinput.tpl @@ -1,9 +1,8 @@ - {{$field.1}}{{if $field.4}} *{{/if}} - + {{if $field.3}} {{$field.3 nofilter}} diff --git a/view/theme/frio/templates/field_fileinput.tpl b/view/theme/frio/templates/field_fileinput.tpl index dd6825f2ee..96ae45596e 100644 --- a/view/theme/frio/templates/field_fileinput.tpl +++ b/view/theme/frio/templates/field_fileinput.tpl @@ -1,8 +1,7 @@ - {{$field.1}}{{if $field.4}} *{{/if}} - + {{if $field.3}} diff --git a/view/theme/frio/templates/field_openid.tpl b/view/theme/frio/templates/field_openid.tpl index bae9cb4fc4..c36dbfabca 100644 --- a/view/theme/frio/templates/field_openid.tpl +++ b/view/theme/frio/templates/field_openid.tpl @@ -1,7 +1,6 @@ - {{$field.1}} - + {{if $field.3}} {{$field.3 nofilter}} {{/if}} diff --git a/view/theme/frio/templates/field_password.tpl b/view/theme/frio/templates/field_password.tpl index 25a7d0c4ce..0fb27ca88f 100644 --- a/view/theme/frio/templates/field_password.tpl +++ b/view/theme/frio/templates/field_password.tpl @@ -1,7 +1,6 @@ - {{$field.1}}{{if $field.4}} *{{/if}} - + {{if $field.3}} {{$field.3 nofilter}} {{/if}} diff --git a/view/theme/frio/templates/nav.tpl b/view/theme/frio/templates/nav.tpl index 77077fdd93..e58ab73acf 100644 --- a/view/theme/frio/templates/nav.tpl +++ b/view/theme/frio/templates/nav.tpl @@ -278,7 +278,7 @@ - {{$nav.about.1}} + {{$nav.about.1}} {{if $nav.tos}} @@ -411,7 +411,7 @@ - {{$nav.about.1}} + {{$nav.about.1}} diff --git a/view/theme/frio/templates/search_item.tpl b/view/theme/frio/templates/search_item.tpl index ef02e10641..2d130cab80 100644 --- a/view/theme/frio/templates/search_item.tpl +++ b/view/theme/frio/templates/search_item.tpl @@ -1,4 +1,8 @@ + {{$item.commented}} + {{$item.received}} + {{$item.created_date}} + {{$item.uriid}} {{* Put additional actions in a top-right dropdown menu *}}