diff --git a/bin/worker.php b/bin/worker.php
index de207ae98f..a742132480 100755
--- a/bin/worker.php
+++ b/bin/worker.php
@@ -69,8 +69,6 @@ if (!DI::mode()->has(App\Mode::MAINTENANCEDISABLED)) {
return;
}
-DI::baseUrl()->saveByURL(DI::config()->get('system', 'url'));
-
$spawn = array_key_exists('s', $options) || array_key_exists('spawn', $options);
if ($spawn) {
diff --git a/composer.lock b/composer.lock
index 63f8a0d5b0..0034780263 100644
--- a/composer.lock
+++ b/composer.lock
@@ -666,6 +666,7 @@
"x509",
"x690"
],
+ "abandoned": true,
"time": "2021-12-11T12:41:06+00:00"
},
{
@@ -1244,16 +1245,16 @@
},
{
"name": "level-2/dice",
- "version": "4.0.3",
+ "version": "4.0.4",
"source": {
"type": "git",
"url": "https://github.com/Level-2/Dice.git",
- "reference": "3e9a8548398c01e2527110c916a93f6efa17ac9c"
+ "reference": "e04c98d96bcc932a917b2b7e7944887e4839056a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Level-2/Dice/zipball/3e9a8548398c01e2527110c916a93f6efa17ac9c",
- "reference": "3e9a8548398c01e2527110c916a93f6efa17ac9c",
+ "url": "https://api.github.com/repos/Level-2/Dice/zipball/e04c98d96bcc932a917b2b7e7944887e4839056a",
+ "reference": "e04c98d96bcc932a917b2b7e7944887e4839056a",
"shasum": ""
},
"require": {
@@ -1263,6 +1264,9 @@
"phpunit/phpunit": "^6.5"
},
"type": "library",
+ "extra": {
+ "patches_applied": []
+ },
"autoload": {
"psr-4": {
"Dice\\": "./"
@@ -1286,7 +1290,7 @@
"di",
"ioc"
],
- "time": "2021-04-20T14:06:06+00:00"
+ "time": "2022-03-28T21:20:23+00:00"
},
{
"name": "lightopenid/lightopenid",
diff --git a/config/local-sample.config.php b/config/local-sample.config.php
index 9bf073df1d..2e9c02b421 100644
--- a/config/local-sample.config.php
+++ b/config/local-sample.config.php
@@ -36,9 +36,11 @@ return [
'sitename' => 'Friendica Social Network',
'register_policy' => \Friendica\Module\Register::OPEN,
'register_text' => '',
+ 'hostname' => 'friendica.local',
],
'system' => [
'default_timezone' => 'UTC',
'language' => 'en',
+ 'url' => 'https://friendica.local',
],
];
diff --git a/database.sql b/database.sql
index 48e0930e67..0b91aedc06 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2023.03-dev (Giant Rhubarb)
--- DB_UPDATE_VERSION 1511
+-- DB_UPDATE_VERSION 1512
-- ------------------------------------------
diff --git a/mods/local.config.vagrant.php b/mods/local.config.vagrant.php
index da873116d8..379ddf185d 100644
--- a/mods/local.config.vagrant.php
+++ b/mods/local.config.vagrant.php
@@ -40,5 +40,7 @@ return [
'language' => 'en',
'basepath' => '/vagrant',
'ssl_policy' => \Friendica\App\BaseURL::SSL_POLICY_SELFSIGN,
+ 'url' => 'https://192.168.56.10',
+ 'urlpath' => '',
],
];
diff --git a/src/App.php b/src/App.php
index a5ef7970d5..9df62a4e77 100644
--- a/src/App.php
+++ b/src/App.php
@@ -540,25 +540,6 @@ class App
return Core\Theme::getStylesheetPath($this->getCurrentTheme());
}
- /**
- * Sets the base url for use in cmdline programs which don't have
- * $_SERVER variables
- */
- public function checkURL()
- {
- $url = $this->config->get('system', 'url');
-
- // if the url isn't set or the stored url is radically different
- // than the currently visited url, store the current value accordingly.
- // "Radically different" ignores common variations such as http vs https
- // and www.example.com vs example.com.
- // We will only change the url to an ip address if there is no existing setting
-
- if (empty($url) || (!Util\Strings::compareLink($url, $this->baseURL->get())) && (!preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $this->baseURL->getHostname()))) {
- $this->config->set('system', 'url', $this->baseURL->get());
- }
- }
-
/**
* Frontend App script
*
@@ -657,7 +638,6 @@ class App
if ($this->mode->isInstall() && $moduleName !== 'install') {
$this->baseURL->redirect('install');
} else {
- $this->checkURL();
Core\Update::check($this->getBasePath(), false);
Core\Addon::loadAddons();
Core\Hook::loadHooks();
diff --git a/src/App/BaseURL.php b/src/App/BaseURL.php
index ab3d03a5be..f02cb9ef99 100644
--- a/src/App/BaseURL.php
+++ b/src/App/BaseURL.php
@@ -257,109 +257,18 @@ class BaseURL
*/
public function __construct(IManageConfigValues $config, array $server)
{
- $this->config = $config;
- $this->server = $server;
-
- $this->determineSchema();
- $this->checkConfig();
- }
-
- /**
- * Check the current config during loading
- */
- public function checkConfig()
- {
+ $this->config = $config;
+ $this->server = $server;
$this->hostname = $this->config->get('config', 'hostname');
- $this->urlPath = $this->config->get('system', 'urlpath');
- $this->sslPolicy = $this->config->get('system', 'ssl_policy');
+ $this->urlPath = $this->config->get('system', 'urlpath') ?? '';
+ $this->sslPolicy = $this->config->get('system', 'ssl_policy') ?? static::DEFAULT_SSL_SCHEME;
$this->url = $this->config->get('system', 'url');
- if (empty($this->hostname)) {
- $this->determineHostname();
-
- if (!empty($this->hostname)) {
- $this->config->set('config', 'hostname', $this->hostname);
- }
+ if (empty($this->hostname) || empty($this->url)) {
+ throw new \Exception('Invalid config - Missing system.url or config.hostname');
}
- if (!isset($this->urlPath)) {
- $this->determineURLPath();
- $this->config->set('system', 'urlpath', $this->urlPath);
- }
-
- if (!isset($this->sslPolicy)) {
- if ($this->scheme == 'https') {
- $this->sslPolicy = self::SSL_POLICY_FULL;
- } else {
- $this->sslPolicy = self::DEFAULT_SSL_SCHEME;
- }
- $this->config->set('system', 'ssl_policy', $this->sslPolicy);
- }
-
- if (empty($this->url)) {
- $this->determineBaseUrl();
-
- if (!empty($this->url)) {
- $this->config->set('system', 'url', $this->url);
- }
- }
- }
-
- /**
- * Determines the hostname of this node if not set already
- */
- private function determineHostname()
- {
- $this->hostname = '';
-
- if (!empty($this->server['SERVER_NAME'])) {
- $this->hostname = $this->server['SERVER_NAME'];
-
- if (!empty($this->server['SERVER_PORT']) && $this->server['SERVER_PORT'] != 80 && $this->server['SERVER_PORT'] != 443) {
- $this->hostname .= ':' . $this->server['SERVER_PORT'];
- }
- }
- }
-
- /**
- * Figure out if we are running at the top of a domain or in a sub-directory
- */
- private function determineURLPath()
- {
- $this->urlPath = '';
-
- /*
- * The automatic path detection in this function is currently deactivated,
- * see issue https://github.com/friendica/friendica/issues/6679
- *
- * The problem is that the function seems to be confused with some url.
- * These then confuses the detection which changes the url path.
- */
-
- /* Relative script path to the web server root
- * Not all of those $_SERVER properties can be present, so we do by inverse priority order
- */
- $relative_script_path =
- ($this->server['REDIRECT_URL'] ?? '') ?:
- ($this->server['REDIRECT_URI'] ?? '') ?:
- ($this->server['REDIRECT_SCRIPT_URL'] ?? '') ?:
- ($this->server['SCRIPT_URL'] ?? '') ?:
- $this->server['REQUEST_URI'] ?? '';
-
- /* $relative_script_path gives /relative/path/to/friendica/module/parameter
- * QUERY_STRING gives pagename=module/parameter
- *
- * To get /relative/path/to/friendica we perform dirname() for as many levels as there are slashes in the QUERY_STRING
- */
- if (!empty($relative_script_path)) {
- // Module
- if (!empty($this->server['QUERY_STRING'])) {
- $this->urlPath = trim(dirname($relative_script_path, substr_count(trim($this->server['QUERY_STRING'], '/'), '/') + 1), '/');
- } else {
- // Root page
- $this->urlPath = trim($relative_script_path, '/');
- }
- }
+ $this->determineSchema();
}
/**
diff --git a/src/App/Request.php b/src/App/Request.php
index 675841ae76..d61303d5d7 100644
--- a/src/App/Request.php
+++ b/src/App/Request.php
@@ -74,7 +74,7 @@ class Request
public function __construct(IManageConfigValues $config, array $server = [])
{
$this->remoteAddress = $this->determineRemoteAddress($config, $server);
- $this->requestId = $server[static::DEFAULT_REQUEST_ID_HEADER] ?? System::createGUID(8);
+ $this->requestId = $server[static::DEFAULT_REQUEST_ID_HEADER] ?? System::createGUID(8, false);
}
/**
diff --git a/src/Content/OEmbed.php b/src/Content/OEmbed.php
index 7553cd9f81..562febdaf9 100644
--- a/src/Content/OEmbed.php
+++ b/src/Content/OEmbed.php
@@ -316,7 +316,7 @@ class OEmbed
if ($stopoembed == true) {
return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "" . DI::l10n()->t('Embedding disabled') . " : $1", $text);
}
- return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", ['self', 'replaceCallback'], $text);
+ return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", [self::class, 'replaceCallback'], $text);
}
/**
diff --git a/src/Content/Smilies.php b/src/Content/Smilies.php
index 5ebb5b64e8..c51d9b3305 100644
--- a/src/Content/Smilies.php
+++ b/src/Content/Smilies.php
@@ -218,8 +218,8 @@ class Smilies
return $text;
}
- $text = preg_replace_callback('/<(pre)>(.*?)<\/pre>/ism', 'self::encode', $text);
- $text = preg_replace_callback('/<(code)>(.*?)<\/code>/ism', 'self::encode', $text);
+ $text = preg_replace_callback('/<(pre)>(.*?)<\/pre>/ism', [self::class, 'encode'], $text);
+ $text = preg_replace_callback('/<(code)>(.*?)<\/code>/ism', [self::class, 'encode'], $text);
if ($no_images) {
$cleaned = ['texts' => [], 'icons' => []];
@@ -233,11 +233,11 @@ class Smilies
$smilies = $cleaned;
}
- $text = preg_replace_callback('/<(3+)/', 'self::heartReplaceCallback', $text);
+ $text = preg_replace_callback('/<(3+)/', [self::class, 'heartReplaceCallback'], $text);
$text = self::strOrigReplace($smilies['texts'], $smilies['icons'], $text);
- $text = preg_replace_callback('/<(code)>(.*?)<\/code>/ism', 'self::decode', $text);
- $text = preg_replace_callback('/<(pre)>(.*?)<\/pre>/ism', 'self::decode', $text);
+ $text = preg_replace_callback('/<(code)>(.*?)<\/code>/ism', [self::class, 'decode'], $text);
+ $text = preg_replace_callback('/<(pre)>(.*?)<\/pre>/ism', [self::class, 'decode'], $text);
return $text;
}
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index f65eeeee2c..e95ed06759 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -1415,8 +1415,8 @@ class BBCode
public static function cleanPictureLinks(string $text): string
{
DI::profiler()->startRecording('rendering');
- $return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $text);
- $return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $return);
+ $return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", [self::class, 'cleanPictureLinksCallback'], $text);
+ $return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", [self::class, 'cleanPictureLinksCallback'], $return);
DI::profiler()->stopRecording();
return $return;
}
@@ -1450,7 +1450,7 @@ class BBCode
{
DI::profiler()->startRecording('rendering');
$regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
- $body = preg_replace_callback($regexp, ['self', 'mentionCallback'], $body);
+ $body = preg_replace_callback($regexp, [self::class, 'mentionCallback'], $body);
DI::profiler()->stopRecording();
return $body;
}
@@ -2002,12 +2002,12 @@ class BBCode
if (!$for_plaintext) {
if (in_array($simple_html, [self::OSTATUS, self::MASTODON_API, self::TWITTER_API, self::ACTIVITYPUB])) {
- $text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text);
- $text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text);
+ $text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", [self::class, 'convertUrlForActivityPubCallback'], $text);
+ $text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", [self::class, 'convertUrlForActivityPubCallback'], $text);
}
} else {
$text = preg_replace("(\[url\](.*?)\[\/url\])ism", " $1 ", $text);
- $text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'self::removePictureLinksCallback', $text);
+ $text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", [self::class, 'removePictureLinksCallback'], $text);
}
// Bookmarks in red - will be converted to bookmarks in friendica
@@ -2017,7 +2017,7 @@ class BBCode
"[bookmark=$1]$2[/bookmark]", $text);
if (in_array($simple_html, [self::OSTATUS, self::TWITTER])) {
- $text = preg_replace_callback("/([^#@!])\[url\=([^\]]*)\](.*?)\[\/url\]/ism", "self::expandLinksCallback", $text);
+ $text = preg_replace_callback("/([^#@!])\[url\=([^\]]*)\](.*?)\[\/url\]/ism", [self::class, 'expandLinksCallback'], $text);
//$text = preg_replace("/[^#@!]\[url\=([^\]]*)\](.*?)\[\/url\]/ism", ' $2 [url]$1[/url]', $text);
$text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", ' $2 [url]$1[/url]', $text);
}
@@ -2327,7 +2327,7 @@ class BBCode
$url_search_string = "^\[\]";
$text = preg_replace_callback(
"/([@!])\[(.*?)\]\(([$url_search_string]*?)\)/ism",
- ['self', 'bbCodeMention2DiasporaCallback'],
+ [self::class, 'bbCodeMention2DiasporaCallback'],
$text
);
}
diff --git a/src/Content/Text/HTML.php b/src/Content/Text/HTML.php
index c65e1d9820..f9f340135c 100644
--- a/src/Content/Text/HTML.php
+++ b/src/Content/Text/HTML.php
@@ -1032,7 +1032,7 @@ class HTML
// the quotes, e.g.:
//
// concat("'foo'", '"', "bar")
- return 'concat(' . implode(', \'"\', ', array_map(['self', 'xpathQuote'], explode('"', $value))) . ')';
+ return 'concat(' . implode(', \'"\', ', array_map([self::class, 'xpathQuote'], explode('"', $value))) . ')';
}
/**
diff --git a/src/Content/Widget/TagCloud.php b/src/Content/Widget/TagCloud.php
index 6f146f4ac1..53d332f0a8 100644
--- a/src/Content/Widget/TagCloud.php
+++ b/src/Content/Widget/TagCloud.php
@@ -144,7 +144,7 @@ class TagCloud
$x ++;
}
- usort($tags, 'self::tagsSort');
+ usort($tags, [self::class, 'tagsSort']);
$range = max(0.01, $max - $min) * 1.0001;
for ($x = 0; $x < count($tags); $x ++) {
diff --git a/src/Core/Config/Util/ConfigFileTransformer.php b/src/Core/Config/Util/ConfigFileTransformer.php
index 45e7a5522b..f159721644 100644
--- a/src/Core/Config/Util/ConfigFileTransformer.php
+++ b/src/Core/Config/Util/ConfigFileTransformer.php
@@ -214,6 +214,17 @@ class ConfigFileTransformer
case "NULL":
return "null";
case "object":
+ if (method_exists($value, '__toString')) {
+ return sprintf('\'%s\'', $value);
+ } elseif ($value instanceof \Serializable) {
+ try {
+ return $value->serialize();
+ } catch (\Exception $e) {
+ throw new \InvalidArgumentException(sprintf('Cannot serialize %s.', gettype($value)), $e);
+ }
+ } else {
+ throw new \InvalidArgumentException(sprintf('%s is an object without stringify.', gettype($value)));
+ }
case "resource":
case "resource (closed)":
throw new \InvalidArgumentException(sprintf('%s in configs are not supported yet.', gettype($value)));
diff --git a/src/Core/Hooks/Capabilities/IAmAStrategy.php b/src/Core/Hooks/Capabilities/IAmAStrategy.php
new file mode 100644
index 0000000000..017cb56c4e
--- /dev/null
+++ b/src/Core/Hooks/Capabilities/IAmAStrategy.php
@@ -0,0 +1,29 @@
+.
+ *
+ */
+
+namespace Friendica\Core\Hooks\Capabilities;
+
+/**
+ * All classes, implementing this interface are valid Strategies for Hook calls
+ */
+interface IAmAStrategy
+{
+}
diff --git a/src/Core/Hooks/Capabilities/ICanManageInstances.php b/src/Core/Hooks/Capabilities/ICanManageInstances.php
new file mode 100644
index 0000000000..bdad1b9235
--- /dev/null
+++ b/src/Core/Hooks/Capabilities/ICanManageInstances.php
@@ -0,0 +1,81 @@
+.
+ *
+ */
+
+namespace Friendica\Core\Hooks\Capabilities;
+
+use Friendica\Core\Hooks\Exceptions\HookInstanceException;
+use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException;
+
+/**
+ * Managing special instance and decorator treatments for classes
+ */
+interface ICanManageInstances
+{
+ /**
+ * Register a class(strategy) for a given interface with a unique name.
+ *
+ * @see https://refactoring.guru/design-patterns/strategy
+ *
+ * @param string $interface The interface, which the given class implements
+ * @param string $name An arbitrary identifier for the given class, which will be used for factories, dependency injections etc.
+ * @param string $class The fully-qualified given class name
+ * @param ?array $arguments Additional arguments, which can be passed to the constructor
+ *
+ * @return $this This interface for chain-calls
+ *
+ * @throws HookRegisterArgumentException in case the given class for the interface isn't valid or already set
+ */
+ public function registerStrategy(string $interface, string $name, string $class, array $arguments = null): self;
+
+ /**
+ * Register a new decorator for a given class or interface
+ * @see https://refactoring.guru/design-patterns/decorator
+ *
+ * @note Decorator attach new behaviors to classes without changing them or without letting them know about it.
+ *
+ * @param string $class The fully-qualified class or interface name, which gets decorated by a class
+ * @param string $decoratorClass The fully-qualified name of the class which mimics the given class or interface and adds new functionality
+ * @param array $arguments Additional arguments, which can be passed to the constructor of "decoratorClass"
+ *
+ * @return $this This interface for chain-calls
+ *
+ * @throws HookRegisterArgumentException in case the given class for the class or interface isn't valid
+ */
+ public function registerDecorator(string $class, string $decoratorClass, array $arguments = []): self;
+
+ /**
+ * Returns a new instance of a given class for the corresponding name
+ *
+ * The instance will be build based on the registered strategy and the (unique) name
+ *
+ * In case, there are registered decorators for this class as well, all decorators of the list will be wrapped
+ * around the instance before returning it
+ *
+ * @param string $class The fully-qualified name of the given class or interface which will get returned
+ * @param string $name An arbitrary identifier to find a concrete instance strategy.
+ * @param array $arguments Additional arguments, which can be passed to the constructor of "$class" at runtime
+ *
+ * @return object The concrete instance of the type "$class"
+ *
+ * @throws HookInstanceException In case the class cannot get created
+ */
+ public function getInstance(string $class, string $name, array $arguments = []): object;
+}
diff --git a/src/Core/Hooks/Exceptions/HookInstanceException.php b/src/Core/Hooks/Exceptions/HookInstanceException.php
new file mode 100644
index 0000000000..bda8e7c8fb
--- /dev/null
+++ b/src/Core/Hooks/Exceptions/HookInstanceException.php
@@ -0,0 +1,30 @@
+.
+ *
+ */
+
+namespace Friendica\Core\Hooks\Exceptions;
+
+class HookInstanceException extends \RuntimeException
+{
+ public function __construct($message = "", \Throwable $previous = null)
+ {
+ parent::__construct($message, 500, $previous);
+ }
+}
diff --git a/src/Core/Hooks/Exceptions/HookRegisterArgumentException.php b/src/Core/Hooks/Exceptions/HookRegisterArgumentException.php
new file mode 100644
index 0000000000..799c4294be
--- /dev/null
+++ b/src/Core/Hooks/Exceptions/HookRegisterArgumentException.php
@@ -0,0 +1,30 @@
+.
+ *
+ */
+
+namespace Friendica\Core\Hooks\Exceptions;
+
+class HookRegisterArgumentException extends \RuntimeException
+{
+ public function __construct($message = "", \Throwable $previous = null)
+ {
+ parent::__construct($message, 500, $previous);
+ }
+}
diff --git a/src/Core/Hooks/Model/InstanceManager.php b/src/Core/Hooks/Model/InstanceManager.php
new file mode 100644
index 0000000000..7bfcfa420d
--- /dev/null
+++ b/src/Core/Hooks/Model/InstanceManager.php
@@ -0,0 +1,104 @@
+.
+ *
+ */
+
+namespace Friendica\Core\Hooks\Model;
+
+use Dice\Dice;
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
+use Friendica\Core\Hooks\Capabilities\ICanManageInstances;
+use Friendica\Core\Hooks\Exceptions\HookInstanceException;
+use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException;
+
+/** {@inheritDoc} */
+class InstanceManager implements ICanManageInstances
+{
+ protected $instance = [];
+ protected $instanceArguments = [];
+ protected $decorator = [];
+
+ /** @var Dice */
+ protected $dice;
+
+ public function __construct(Dice $dice)
+ {
+ $this->dice = $dice;
+ }
+
+ /** {@inheritDoc} */
+ public function registerStrategy(string $interface, string $name, string $class, array $arguments = null): ICanManageInstances
+ {
+ if (!is_a($class, $interface, true)) {
+ throw new HookRegisterArgumentException(sprintf('%s is not a valid class for the interface %s', $class, $interface));
+ }
+
+ if (!is_a($class, IAmAStrategy::class, true)) {
+ throw new HookRegisterArgumentException(sprintf('%s does not inherit from the marker interface %s', $class, IAmAStrategy::class));
+ }
+
+ if (!empty($this->instance[$interface][$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->instanceArguments[$interface][$name] = $arguments;
+
+ return $this;
+ }
+
+ /** {@inheritDoc} */
+ public function registerDecorator(string $class, string $decoratorClass, array $arguments = []): ICanManageInstances
+ {
+ if (!is_a($decoratorClass, $class, true)) {
+ throw new HookRegisterArgumentException(sprintf('%s is not a valid substitution for the given class or interface %s', $decoratorClass, $class));
+ }
+
+ $this->decorator[$class][] = [
+ 'class' => $decoratorClass,
+ 'arguments' => $arguments,
+ ];
+
+ return $this;
+ }
+
+ /** {@inheritDoc} */
+ public function getInstance(string $class, string $name, array $arguments = []): object
+ {
+ if (empty($this->instance[$class][$name])) {
+ throw new HookInstanceException(sprintf('The class with the name %s isn\'t registered for the class or interface %s', $name, $class));
+ }
+
+ $instance = $this->dice->create($this->instance[$class][$name], array_merge($this->instanceArguments[$class][$name] ?? [], $arguments));
+
+ foreach ($this->decorator[$class] ?? [] as $decorator) {
+ $this->dice = $this->dice->addRule($class, [
+ 'instanceOf' => $decorator['class'],
+ 'constructParams' => empty($decorator['arguments']) ? null : $decorator['arguments'],
+ /// @todo maybe support call structures for hooks as well in a later stage - could make factory calls easier
+ 'call' => null,
+ 'substitutions' => [$class => $instance],
+ ]);
+
+ $instance = $this->dice->create($class);
+ }
+
+ return $instance;
+ }
+}
diff --git a/src/Core/Logger/Exception/LoggerInvalidException.php b/src/Core/Logger/Exception/LoggerInvalidException.php
new file mode 100644
index 0000000000..db6ecb78c5
--- /dev/null
+++ b/src/Core/Logger/Exception/LoggerInvalidException.php
@@ -0,0 +1,32 @@
+.
+ *
+ */
+
+namespace Friendica\Core\Logger\Exception;
+
+use Throwable;
+
+class LoggerInvalidException extends \RuntimeException
+{
+ public function __construct($message = "", Throwable $previous = null)
+ {
+ parent::__construct($message, 500, $previous);
+ }
+}
diff --git a/src/Core/Logger/Factory/Logger.php b/src/Core/Logger/Factory/Logger.php
index 3dd2a81dc2..2821a813c2 100644
--- a/src/Core/Logger/Factory/Logger.php
+++ b/src/Core/Logger/Factory/Logger.php
@@ -22,16 +22,11 @@
namespace Friendica\Core\Logger\Factory;
use Friendica\Core\Config\Capability\IManageConfigValues;
-use Friendica\Core;
-use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections;
+use Friendica\Core\Hooks\Capabilities\ICanManageInstances;
use Friendica\Core\Logger\Exception\LogLevelException;
-use Friendica\Database\Database;
-use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Util\FileSystem;
use Friendica\Core\Logger\Type\ProfilerLogger;
use Friendica\Core\Logger\Type\StreamLogger;
use Friendica\Core\Logger\Type\SyslogLogger;
-use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
@@ -44,115 +39,55 @@ class Logger
const DEV_CHANNEL = 'dev';
/** @var string The log-channel (app, worker, ...) */
- private $channel;
+ protected $channel;
+ /** @var ICanManageInstances */
+ protected $instanceManager;
+ /** @var IManageConfigValues */
+ protected $config;
- public function __construct(string $channel, bool $includeAddon = true)
+ public function __construct(string $channel, ICanManageInstances $instanceManager, IManageConfigValues $config, string $logfile = null)
{
- $this->channel = $channel;
+ $this->channel = $channel;
+ $this->instanceManager = $instanceManager;
+ $this->config = $config;
- /// @fixme clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore
- if ($includeAddon) {
- Core\Addon::loadAddons();
- Core\Hook::loadHooks();
+ $this->instanceManager
+ ->registerStrategy(LoggerInterface::class, 'syslog', SyslogLogger::class)
+ ->registerStrategy(LoggerInterface::class, 'stream', StreamLogger::class, isset($logfile) ? [$logfile] : null);
+
+ if ($this->config->get('system', 'profiling') ?? false) {
+ $this->instanceManager->registerDecorator(LoggerInterface::class, ProfilerLogger::class);
}
}
/**
* Creates a new PSR-3 compliant logger instances
*
- * @param Database $database The Friendica Database instance
- * @param IManageConfigValues $config The config
- * @param Profiler $profiler The profiler of the app
- * @param FileSystem $fileSystem FileSystem utils
- * @param string|null $minLevel (optional) Override minimum Loglevel to log
+ * @param string|null $loglevel (optional) A given loglevel in case the loglevel in the config isn't applicable
*
* @return LoggerInterface The PSR-3 compliant logger instance
*/
- public function create(Database $database, IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem, IHaveCallIntrospections $introspection, ?string $minLevel = null): LoggerInterface
+ public function create(string $loglevel = null): LoggerInterface
{
- if (empty($config->get('system', 'debugging', false))) {
- $logger = new NullLogger();
- $database->setLogger($logger);
+ if (empty($this->config->get('system', 'debugging') ?? false)) {
+ return new NullLogger();
+ }
+
+ $loglevel = $loglevel ?? static::mapLegacyConfigDebugLevel($this->config->get('system', 'loglevel'));
+ $name = $this->config->get('system', 'logger_config') ?? 'stream';
+
+ try {
+ /** @var LoggerInterface */
+ return $this->instanceManager->getInstance(LoggerInterface::class, $name, [$this->channel, $loglevel]);
+ } catch (LogLevelException $exception) {
+ // If there's a wrong config value for loglevel, try again with standard
+ $logger = $this->create(LogLevel::NOTICE);
+ $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
return $logger;
+ } catch (\Throwable $e) {
+ // No logger ...
+ return new NullLogger();
}
-
- $minLevel = $minLevel ?? $config->get('system', 'loglevel');
- $loglevel = self::mapLegacyConfigDebugLevel((string)$minLevel);
-
- $name = $config->get('system', 'logger_config', 'stream');
-
- switch ($name) {
- case 'syslog':
- try {
- $logger = new SyslogLogger($this->channel, $introspection, $loglevel, $config->get('system', 'syslog_flags', SyslogLogger::DEFAULT_FLAGS), $config->get('system', 'syslog_facility', SyslogLogger::DEFAULT_FACILITY));
- } catch (LogLevelException $exception) {
- // If there's a wrong config value for loglevel, try again with standard
- $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE);
- $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
- } catch (\Throwable $e) {
- // No logger ...
- $logger = new NullLogger();
- }
- break;
-
- case 'stream':
- default:
- $data = [
- 'name' => $name,
- 'channel' => $this->channel,
- 'introspection' => $introspection,
- 'loglevel' => $loglevel,
- 'logger' => null,
- ];
- try {
- Core\Hook::callAll('logger_instance', $data);
- } catch (InternalServerErrorException $exception) {
- $data['logger'] = null;
- }
-
- if (($data['logger'] ?? null) instanceof LoggerInterface) {
- $logger = $data['logger'];
- }
-
- if (empty($logger)) {
- $stream = $config->get('system', 'logfile');
- // just add a stream in case it's either writable or not file
- if (!is_file($stream) || is_writable($stream)) {
- try {
- $logger = new StreamLogger($this->channel, $stream, $introspection, $fileSystem, $loglevel);
- } catch (LogLevelException $exception) {
- // If there's a wrong config value for loglevel, try again with standard
- $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE);
- $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
- } catch (\Throwable $t) {
- // No logger ...
- $logger = new NullLogger();
- }
- } else {
- try {
- $logger = new SyslogLogger($this->channel, $introspection, $loglevel);
- } catch (LogLevelException $exception) {
- // If there's a wrong config value for loglevel, try again with standard
- $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE);
- $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
- } catch (\Throwable $e) {
- // No logger ...
- $logger = new NullLogger();
- }
- }
- }
- break;
- }
-
- $profiling = $config->get('system', 'profiling', false);
-
- // In case profiling is enabled, wrap the ProfilerLogger around the current logger
- if (isset($profiling) && $profiling !== false) {
- $logger = new ProfilerLogger($logger, $profiler);
- }
-
- $database->setLogger($logger);
- return $logger;
}
/**
@@ -163,63 +98,24 @@ class Logger
*
* It should never get filled during normal usage of Friendica
*
- * @param IManageConfigValues $config The config
- * @param Profiler $profiler The profiler of the app
- * @param FileSystem $fileSystem FileSystem utils
- *
* @return LoggerInterface The PSR-3 compliant logger instance
* @throws \Exception
*/
- public static function createDev(IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem, IHaveCallIntrospections $introspection)
+ public function createDev()
{
- $debugging = $config->get('system', 'debugging');
- $stream = $config->get('system', 'dlogfile');
- $developerIp = $config->get('system', 'dlogip');
+ $debugging = $this->config->get('system', 'debugging');
+ $stream = $this->config->get('system', 'dlogfile');
+ $developerIp = $this->config->get('system', 'dlogip');
if ((!isset($developerIp) || !$debugging) &&
(!is_file($stream) || is_writable($stream))) {
return new NullLogger();
}
- $name = $config->get('system', 'logger_config', 'stream');
+ $name = $this->config->get('system', 'logger_config') ?? 'stream';
- switch ($name) {
-
- case 'syslog':
- $logger = new SyslogLogger(self::DEV_CHANNEL, $introspection, LogLevel::DEBUG);
- break;
-
- case 'stream':
- default:
- $data = [
- 'name' => $name,
- 'channel' => self::DEV_CHANNEL,
- 'introspection' => $introspection,
- 'loglevel' => LogLevel::DEBUG,
- 'logger' => null,
- ];
- try {
- Core\Hook::callAll('logger_instance', $data);
- } catch (InternalServerErrorException $exception) {
- $data['logger'] = null;
- }
-
- if (($data['logger'] ?? null) instanceof LoggerInterface) {
- return $data['logger'];
- }
-
- $logger = new StreamLogger(self::DEV_CHANNEL, $stream, $introspection, $fileSystem, LogLevel::DEBUG);
- break;
- }
-
- $profiling = $config->get('system', 'profiling', false);
-
- // In case profiling is enabled, wrap the ProfilerLogger around the current logger
- if (isset($profiling) && $profiling !== false) {
- $logger = new ProfilerLogger($logger, $profiler);
- }
-
- return $logger;
+ /** @var LoggerInterface */
+ return $this->instanceManager->getInstance(LoggerInterface::class, $name, [self::DEV_CHANNEL, LogLevel::DEBUG, $stream]);
}
/**
diff --git a/src/Core/Logger/Type/AbstractLogger.php b/src/Core/Logger/Type/AbstractLogger.php
index bc4b00ecea..77a61e9206 100644
--- a/src/Core/Logger/Type/AbstractLogger.php
+++ b/src/Core/Logger/Type/AbstractLogger.php
@@ -21,8 +21,8 @@
namespace Friendica\Core\Logger\Type;
+use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections;
use Friendica\Core\Logger\Exception\LoggerException;
-use Friendica\Core\Logger\Util\Introspection;
use Friendica\Util\Strings;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
@@ -46,7 +46,7 @@ abstract class AbstractLogger implements LoggerInterface
/**
* The Introspection for the current call
- * @var Introspection
+ * @var IHaveCallIntrospections
*/
protected $introspection;
@@ -69,11 +69,11 @@ abstract class AbstractLogger implements LoggerInterface
/**
* @param string $channel The output channel
- * @param Introspection $introspection The introspection of the current call
+ * @param IHaveCallIntrospections $introspection The introspection of the current call
*
* @throws LoggerException
*/
- public function __construct(string $channel, Introspection $introspection)
+ public function __construct(string $channel, IHaveCallIntrospections $introspection)
{
$this->channel = $channel;
$this->introspection = $introspection;
diff --git a/src/Core/Logger/Type/StreamLogger.php b/src/Core/Logger/Type/StreamLogger.php
index a444faaaba..6e0f657978 100644
--- a/src/Core/Logger/Type/StreamLogger.php
+++ b/src/Core/Logger/Type/StreamLogger.php
@@ -21,18 +21,20 @@
namespace Friendica\Core\Logger\Type;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
+use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections;
use Friendica\Core\Logger\Exception\LoggerArgumentException;
use Friendica\Core\Logger\Exception\LoggerException;
use Friendica\Core\Logger\Exception\LogLevelException;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\FileSystem;
-use Friendica\Core\Logger\Util\Introspection;
use Psr\Log\LogLevel;
/**
* A Logger instance for logging into a stream (file, stdout, stderr)
*/
-class StreamLogger extends AbstractLogger
+class StreamLogger extends AbstractLogger implements IAmAStrategy
{
/**
* The minimum loglevel at which this logger will be triggered
@@ -80,16 +82,20 @@ class StreamLogger extends AbstractLogger
/**
* {@inheritdoc}
- * @param string|resource $stream The stream to write with this logger (either a file or a stream, i.e. stdout)
* @param string $level The minimum loglevel at which this logger will be triggered
*
* @throws LoggerArgumentException
* @throws LogLevelException
*/
- public function __construct($channel, $stream, Introspection $introspection, FileSystem $fileSystem, string $level = LogLevel::DEBUG)
+ public function __construct(string $channel, IManageConfigValues $config, IHaveCallIntrospections $introspection, FileSystem $fileSystem, string $level = LogLevel::DEBUG)
{
$this->fileSystem = $fileSystem;
+ $stream = $this->logfile ?? $config->get('system', 'logfile');
+ if ((file_exists($stream) && !is_writable($stream)) || is_writable(basename($stream))) {
+ throw new LoggerArgumentException(sprintf('%s is not a valid logfile', $stream));
+ }
+
parent::__construct($channel, $introspection);
if (is_resource($stream)) {
diff --git a/src/Core/Logger/Type/SyslogLogger.php b/src/Core/Logger/Type/SyslogLogger.php
index b38cb01855..3c9ab581a0 100644
--- a/src/Core/Logger/Type/SyslogLogger.php
+++ b/src/Core/Logger/Type/SyslogLogger.php
@@ -21,16 +21,18 @@
namespace Friendica\Core\Logger\Type;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
+use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections;
use Friendica\Core\Logger\Exception\LoggerException;
use Friendica\Core\Logger\Exception\LogLevelException;
-use Friendica\Core\Logger\Util\Introspection;
use Psr\Log\LogLevel;
/**
* A Logger instance for syslogging (fast, but simple)
* @see http://php.net/manual/en/function.syslog.php
*/
-class SyslogLogger extends AbstractLogger
+class SyslogLogger extends AbstractLogger implements IAmAStrategy
{
const IDENT = 'Friendica';
@@ -100,17 +102,16 @@ class SyslogLogger extends AbstractLogger
/**
* {@inheritdoc}
* @param string $level The minimum loglevel at which this logger will be triggered
- * @param int $logOpts Indicates what logging options will be used when generating a log message
- * @param int $logFacility Used to specify what type of program is logging the message
*
* @throws LogLevelException
* @throws LoggerException
*/
- public function __construct($channel, Introspection $introspection, string $level = LogLevel::NOTICE, int $logOpts = self::DEFAULT_FLAGS, int $logFacility = self::DEFAULT_FACILITY )
+ public function __construct(string $channel, IManageConfigValues $config, IHaveCallIntrospections $introspection, string $level = LogLevel::NOTICE)
{
parent::__construct($channel, $introspection);
- $this->logOpts = $logOpts;
- $this->logFacility = $logFacility;
+
+ $this->logOpts = $config->get('system', 'syslog_flags') ?? static::DEFAULT_FLAGS;
+ $this->logFacility = $config->get('system', 'syslog_facility') ?? static::DEFAULT_FACILITY;
$this->logLevel = $this->mapLevelToPriority($level);
$this->introspection->addClasses([self::class]);
}
diff --git a/src/Database/DBA.php b/src/Database/DBA.php
index ffeecfaa71..e29cd30386 100644
--- a/src/Database/DBA.php
+++ b/src/Database/DBA.php
@@ -527,7 +527,7 @@ class DBA
public static function buildTableString(array $tables): string
{
// Quote each entry
- return implode(',', array_map(['self', 'quoteIdentifier'], $tables));
+ return implode(',', array_map([self::class, 'quoteIdentifier'], $tables));
}
/**
@@ -717,7 +717,7 @@ class DBA
{
$groupby_string = '';
if (!empty($params['group_by'])) {
- $groupby_string = " GROUP BY " . implode(', ', array_map(['self', 'quoteIdentifier'], $params['group_by']));
+ $groupby_string = " GROUP BY " . implode(', ', array_map([self::class, 'quoteIdentifier'], $params['group_by']));
}
$order_string = '';
diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php
index c0bd005d1e..579b9cdc11 100644
--- a/src/Database/DBStructure.php
+++ b/src/Database/DBStructure.php
@@ -783,7 +783,7 @@ class DBStructure
}
if (!DBA::exists('verb', ['id' => 0])) {
- DBA::insert('verb', ['name' => '']);
+ DBA::insert('verb', ['name' => ''], Database::INSERT_IGNORE);
$lastid = DBA::lastInsertId();
if ($lastid != 0) {
DBA::update('verb', ['id' => 0], ['id' => $lastid]);
@@ -819,7 +819,7 @@ class DBStructure
}
if (self::existsTable('contact') && !DBA::exists('contact', ['id' => 0])) {
- DBA::insert('contact', ['nurl' => '']);
+ DBA::insert('contact', ['nurl' => ''], Database::INSERT_IGNORE);
$lastid = DBA::lastInsertId();
if ($lastid != 0) {
DBA::update('contact', ['id' => 0], ['id' => $lastid]);
@@ -834,7 +834,7 @@ class DBStructure
}
if (self::existsTable('tag') && !DBA::exists('tag', ['id' => 0])) {
- DBA::insert('tag', ['name' => '']);
+ DBA::insert('tag', ['name' => ''], Database::INSERT_IGNORE);
$lastid = DBA::lastInsertId();
if ($lastid != 0) {
DBA::update('tag', ['id' => 0], ['id' => $lastid]);
@@ -850,7 +850,7 @@ class DBStructure
if (self::existsTable('permissionset')) {
if (!DBA::exists('permissionset', ['id' => 0])) {
- DBA::insert('permissionset', ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '']);
+ DBA::insert('permissionset', ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''], Database::INSERT_IGNORE);
$lastid = DBA::lastInsertId();
if ($lastid != 0) {
DBA::update('permissionset', ['id' => 0], ['id' => $lastid]);
@@ -878,7 +878,7 @@ class DBStructure
}
$fields = ['id' => $set['psid'], 'uid' => $set['uid'], 'allow_cid' => $permission,
'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''];
- DBA::insert('permissionset', $fields);
+ DBA::insert('permissionset', $fields, Database::INSERT_IGNORE);
}
DBA::close($sets);
}
diff --git a/src/Database/Database.php b/src/Database/Database.php
index 032a282030..a5fe7f978a 100644
--- a/src/Database/Database.php
+++ b/src/Database/Database.php
@@ -36,7 +36,6 @@ use PDO;
use PDOException;
use PDOStatement;
use Psr\Log\LoggerInterface;
-use Psr\Log\NullLogger;
/**
* This class is for the low level database stuff that does driver specific things.
@@ -81,16 +80,14 @@ class Database
/** @var ViewDefinition */
protected $viewDefinition;
- public function __construct(IManageConfigValues $config, Profiler $profiler, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition)
+ public function __construct(IManageConfigValues $config, Profiler $profiler, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition, LoggerInterface $logger)
{
// We are storing these values for being able to perform a reconnect
- $this->config = $config;
- $this->profiler = $profiler;
+ $this->config = $config;
+ $this->profiler = $profiler;
$this->dbaDefinition = $dbaDefinition;
$this->viewDefinition = $viewDefinition;
-
- // Temporary NullLogger until we can fetch the logger class from the config
- $this->logger = new NullLogger();
+ $this->logger = $logger;
$this->connect();
}
@@ -196,21 +193,6 @@ class Database
$this->testmode = $test;
}
- /**
- * Sets the logger for DBA
- *
- * @note this is necessary because if we want to load the logger configuration
- * from the DB, but there's an error, we would print out an exception.
- * So the logger gets updated after the logger configuration can be retrieved
- * from the database
- *
- * @param LoggerInterface $logger
- */
- public function setLogger(LoggerInterface $logger)
- {
- $this->logger = $logger;
- }
-
/**
* Sets the profiler for DBA
*
diff --git a/src/Database/Definition/DbaDefinition.php b/src/Database/Definition/DbaDefinition.php
index b65a7d30ed..1e597bd64b 100644
--- a/src/Database/Definition/DbaDefinition.php
+++ b/src/Database/Definition/DbaDefinition.php
@@ -87,6 +87,10 @@ class DbaDefinition
$data[$field] = mb_substr($data[$field], 0, $result[1]);
} elseif (is_string($data[$field]) && preg_match("/binary\((\d*)\)/", $definition[$table]['fields'][$field]['type'], $result)) {
$data[$field] = substr($data[$field], 0, $result[1]);
+ } elseif (is_numeric($data[$field]) && $definition[$table]['fields'][$field]['type'] === 'int') {
+ $data[$field] = min(max((int)$data[$field], -2147483648), 2147483647);
+ } elseif (is_numeric($data[$field]) && $definition[$table]['fields'][$field]['type'] === 'int unsigned') {
+ $data[$field] = min(max((int)$data[$field], 0), 4294967295);
}
$fields[$field] = $data[$field];
}
diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index e847ce0346..7b5a1e428a 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -243,15 +243,13 @@ class Contact
* @throws \Exception
* @todo Let's get rid of boolean type of $old_fields
*/
- public static function update(array $fields, array $condition, $old_fields = [])
+ public static function update(array $fields, array $condition, $old_fields = []): bool
{
- $fields = DI::dbaDefinition()->truncateFieldsForTable('contact', $fields);
- $ret = DBA::update('contact', $fields, $condition, $old_fields);
-
// Apply changes to the "user-contact" table on dedicated fields
Contact\User::updateByContactUpdate($fields, $condition);
- return $ret;
+ $fields = DI::dbaDefinition()->truncateFieldsForTable('contact', $fields);
+ return DBA::update('contact', $fields, $condition, $old_fields);
}
/**
@@ -2970,7 +2968,7 @@ class Contact
}
// check if we already have a contact
- $condition = ['uid' => $uid, 'nurl' => Strings::normaliseLink($ret['url'])];
+ $condition = ['uid' => $uid, 'nurl' => Strings::normaliseLink($ret['url']), 'deleted' => false];
$contact = DBA::selectFirst('contact', ['id', 'rel', 'url', 'pending', 'hub-verify'], $condition);
$protocol = self::getProtocol($ret['url'], $ret['network']);
@@ -3293,7 +3291,7 @@ class Contact
if ($contact['rel'] == self::SHARING || in_array($contact['network'], [Protocol::FEED, Protocol::MAIL])) {
self::remove($contact['id']);
} else {
- self::update(['rel' => self::FOLLOWER], ['id' => $contact['id']]);
+ self::update(['rel' => self::FOLLOWER, 'pending' => false], ['id' => $contact['id']]);
}
Worker::add(Worker::PRIORITY_LOW, 'ContactDiscoveryForUser', $contact['uid']);
diff --git a/src/Model/Event.php b/src/Model/Event.php
index ca22c32ac6..e39ee5fd56 100644
--- a/src/Model/Event.php
+++ b/src/Model/Event.php
@@ -198,7 +198,7 @@ class Event
public static function sortByDate(array $event_list): array
{
- usort($event_list, ['self', 'compareDatesCallback']);
+ usort($event_list, [self::class, 'compareDatesCallback']);
return $event_list;
}
diff --git a/src/Model/GServer.php b/src/Model/GServer.php
index 54e4d7220e..7e3f0f4802 100644
--- a/src/Model/GServer.php
+++ b/src/Model/GServer.php
@@ -455,22 +455,26 @@ class GServer
* Set failed server status
*
* @param string $url
+ * @return void
*/
public static function setFailureByUrl(string $url)
{
- $gserver = DBA::selectFirst('gserver', [], ['nurl' => Strings::normaliseLink($url)]);
+ $nurl = Strings::normaliseLink($url);
+
+ $gserver = DBA::selectFirst('gserver', [], ['nurl' => $nurl]);
if (DBA::isResult($gserver)) {
$next_update = self::getNextUpdateDate(false, $gserver['created'], $gserver['last_contact']);
self::update(['url' => $url, 'failed' => true, 'blocked' => Network::isUrlBlocked($url), 'last_failure' => DateTimeFormat::utcNow(),
'next_contact' => $next_update, 'network' => Protocol::PHANTOM, 'detection-method' => null],
- ['nurl' => Strings::normaliseLink($url)]);
+ ['nurl' => $nurl]);
Logger::info('Set failed status for existing server', ['url' => $url]);
if (self::isDefunct($gserver)) {
self::archiveContacts($gserver['id']);
}
return;
}
- self::insert(['url' => $url, 'nurl' => Strings::normaliseLink($url),
+
+ self::insert(['url' => $url, 'nurl' => $nurl,
'network' => Protocol::PHANTOM, 'created' => DateTimeFormat::utcNow(),
'failed' => true, 'last_failure' => DateTimeFormat::utcNow()]);
Logger::info('Set failed status for new server', ['url' => $url]);
@@ -556,7 +560,7 @@ class GServer
// If the URL missmatches, then we mark the old entry as failure
if (!Strings::compareLink($url, $original_url)) {
self::setFailureByUrl($original_url);
- if (!self::getID($url, true)) {
+ if (!self::getID($url, true) && !Network::isUrlBlocked($url)) {
self::detect($url, $network, $only_nodeinfo);
}
return false;
@@ -577,7 +581,7 @@ class GServer
(((parse_url($url, PHP_URL_HOST) != parse_url($valid_url, PHP_URL_HOST)) || (parse_url($url, PHP_URL_PATH) != parse_url($valid_url, PHP_URL_PATH))) && empty(parse_url($valid_url, PHP_URL_PATH)))) {
Logger::debug('Found redirect. Mark old entry as failure', ['old' => $url, 'new' => $valid_url]);
self::setFailureByUrl($url);
- if (!self::getID($valid_url, true)) {
+ if (!self::getID($valid_url, true) && !Network::isUrlBlocked($valid_url)) {
self::detect($valid_url, $network, $only_nodeinfo);
}
return false;
@@ -591,7 +595,7 @@ class GServer
$valid_url = (string)Uri::fromParts($parts);
self::setFailureByUrl($url);
- if (!self::getID($valid_url, true)) {
+ if (!self::getID($valid_url, true) && !Network::isUrlBlocked($valid_url)) {
self::detect($valid_url, $network, $only_nodeinfo);
}
return false;
diff --git a/src/Model/Nodeinfo.php b/src/Model/Nodeinfo.php
index 0fbaf93c7e..07f56dd7bb 100644
--- a/src/Model/Nodeinfo.php
+++ b/src/Model/Nodeinfo.php
@@ -55,17 +55,17 @@ class Nodeinfo
$userStats = User::getStatistics();
- $config->set('nodeinfo', 'total_users', $userStats['total_users']);
- $config->set('nodeinfo', 'active_users_halfyear', $userStats['active_users_halfyear']);
- $config->set('nodeinfo', 'active_users_monthly', $userStats['active_users_monthly']);
- $config->set('nodeinfo', 'active_users_weekly', $userStats['active_users_weekly']);
+ DI::keyValue()->set('nodeinfo_total_users', $userStats['total_users']);
+ DI::keyValue()->set('nodeinfo_active_users_halfyear', $userStats['active_users_halfyear']);
+ DI::keyValue()->set('nodeinfo_active_users_monthly', $userStats['active_users_monthly']);
+ DI::keyValue()->set('nodeinfo_active_users_weekly', $userStats['active_users_weekly']);
$logger->info('user statistics', $userStats);
$posts = DBA::count('post-thread', ["`uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE NOT `deleted` AND `origin`)"]);
$comments = DBA::count('post', ["NOT `deleted` AND `gravity` = ? AND `uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `origin`)", Item::GRAVITY_COMMENT]);
- $config->set('nodeinfo', 'local_posts', $posts);
- $config->set('nodeinfo', 'local_comments', $comments);
+ DI::keyValue()->set('nodeinfo_local_posts', $posts);
+ DI::keyValue()->set('nodeinfo_local_comments', $comments);
$logger->info('User actitivy', ['posts' => $posts, 'comments' => $comments]);
}
@@ -83,14 +83,14 @@ class Nodeinfo
$usage->users = new \stdClass;
if (!empty($config->get('system', 'nodeinfo'))) {
- $usage->users->total = intval($config->get('nodeinfo', 'total_users'));
- $usage->users->activeHalfyear = intval($config->get('nodeinfo', 'active_users_halfyear'));
- $usage->users->activeMonth = intval($config->get('nodeinfo', 'active_users_monthly'));
- $usage->localPosts = intval($config->get('nodeinfo', 'local_posts'));
- $usage->localComments = intval($config->get('nodeinfo', 'local_comments'));
+ $usage->users->total = intval(DI::keyValue()->get('nodeinfo_total_users'));
+ $usage->users->activeHalfyear = intval(DI::keyValue()->get('nodeinfo_active_users_halfyear'));
+ $usage->users->activeMonth = intval(DI::keyValue()->get('nodeinfo_active_users_monthly'));
+ $usage->localPosts = intval(DI::keyValue()->get('nodeinfo_local_posts'));
+ $usage->localComments = intval(DI::keyValue()->get('nodeinfo_local_comments'));
if ($version2) {
- $usage->users->activeWeek = intval($config->get('nodeinfo', 'active_users_weekly'));
+ $usage->users->activeWeek = intval(DI::keyValue()->get('nodeinfo_active_users_weekly'));
}
}
diff --git a/src/Model/User.php b/src/Model/User.php
index bd7351f072..75b913250c 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -757,7 +757,7 @@ class User
}
/**
- * Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces, accentuated letters and colon (:).
+ * Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces and accentuated letters.
*
* Password length is limited to 72 characters if the current default password hashing algorithm is Blowfish.
* From the manual: "Using the PASSWORD_BCRYPT as the algorithm, will result in the password parameter being
@@ -770,13 +770,13 @@ class User
*/
public static function getPasswordRegExp(string $delimiter = null): string
{
- $allowed_characters = '!"#$%&\'()*+,-./;<=>?@[\]^_`{|}~';
+ $allowed_characters = ':!"#$%&\'()*+,-./;<=>?@[\]^_`{|}~';
if ($delimiter) {
$allowed_characters = preg_quote($allowed_characters, $delimiter);
}
- return '^[a-zA-Z0-9' . $allowed_characters . ']' . (PASSWORD_DEFAULT !== PASSWORD_BCRYPT ? '{1,72}' : '+') . '$';
+ return '^[a-zA-Z0-9' . $allowed_characters . ']' . (PASSWORD_DEFAULT === PASSWORD_BCRYPT ? '{1,72}' : '+') . '$';
}
/**
@@ -804,7 +804,7 @@ class User
}
if (!preg_match('/' . self::getPasswordRegExp('/') . '/', $password)) {
- throw new Exception(DI::l10n()->t('The password can\'t contain accentuated letters, white spaces or colons (:)'));
+ throw new Exception(DI::l10n()->t("The password can't contain white spaces nor accentuated letters"));
}
return self::updatePasswordHashed($uid, self::hashPassword($password));
diff --git a/src/Module/Contact/Profile.php b/src/Module/Contact/Profile.php
index 15eebd3603..e13fbd584c 100644
--- a/src/Module/Contact/Profile.php
+++ b/src/Module/Contact/Profile.php
@@ -197,7 +197,7 @@ class Profile extends BaseModule
Contact\User::setIgnored($contact['id'], DI::userSession()->getLocalUserId(), true);
$message = $this->t('Contact has been ignored');
}
-
+
// @TODO: add $this->localRelationship->save($localRelationship);
DI::sysmsg()->addInfo($message);
}
@@ -213,7 +213,7 @@ class Profile extends BaseModule
Contact\User::setCollapsed($contact['id'], DI::userSession()->getLocalUserId(), true);
$message = $this->t('Contact has been collapsed');
}
-
+
// @TODO: add $this->localRelationship->save($localRelationship);
DI::sysmsg()->addInfo($message);
}
@@ -239,9 +239,6 @@ class Profile extends BaseModule
'$baseurl' => $this->baseUrl->get(true),
]);
- $contact['blocked'] = Contact\User::isBlocked($contact['id'], DI::userSession()->getLocalUserId());
- $contact['readonly'] = Contact\User::isIgnored($contact['id'], DI::userSession()->getLocalUserId());
-
switch ($localRelationship->rel) {
case Contact::FRIEND: $relation_text = $this->t('You are mutual friends with %s', $contact['name']); break;
case Contact::FOLLOWER: $relation_text = $this->t('You are sharing with %s', $contact['name']); break;
@@ -361,16 +358,13 @@ class Profile extends BaseModule
'$last_update' => $last_update,
'$udnow' => $this->t('Update now'),
'$contact_id' => $contact['id'],
- '$block_text' => ($contact['blocked'] ? $this->t('Unblock') : $this->t('Block')),
- '$ignore_text' => ($contact['readonly'] ? $this->t('Unignore') : $this->t('Ignore')),
- '$insecure' => (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::MAIL, Protocol::DIASPORA]) ? '' : $insecure),
- '$info' => $localRelationship->info,
- '$cinfo' => ['info', '', $localRelationship->info, ''],
- '$blocked' => ($contact['blocked'] ? $this->t('Currently blocked') : ''),
- '$ignored' => ($contact['readonly'] ? $this->t('Currently ignored') : ''),
- '$collapsed' => (Contact\User::isCollapsed($contact['id'], DI::userSession()->getLocalUserId()) ? $this->t('Currently collapsed') : ''),
+ '$pending' => $localRelationship->pending ? $this->t('Awaiting connection acknowledge') : '',
+ '$blocked' => $localRelationship->blocked ? $this->t('Currently blocked') : '',
+ '$ignored' => $localRelationship->ignored ? $this->t('Currently ignored') : '',
+ '$collapsed' => $localRelationship->collapsed ? $this->t('Currently collapsed') : '',
'$archived' => ($contact['archive'] ? $this->t('Currently archived') : ''),
- '$pending' => ($contact['pending'] ? $this->t('Awaiting connection acknowledge') : ''),
+ '$insecure' => (in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::MAIL, Protocol::DIASPORA]) ? '' : $insecure),
+ '$cinfo' => ['info', '', $localRelationship->info, ''],
'$hidden' => ['hidden', $this->t('Hide this contact from others'), $localRelationship->hidden, $this->t('Replies/likes to your public posts may still be visible')],
'$notify_new_posts' => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')],
'$fetch_further_information' => $fetch_further_information,
diff --git a/src/Module/Maintenance.php b/src/Module/Maintenance.php
index 412723db31..67f65b8e39 100644
--- a/src/Module/Maintenance.php
+++ b/src/Module/Maintenance.php
@@ -36,7 +36,7 @@ class Maintenance extends BaseModule
{
protected function content(array $request = []): string
{
- $reason = DI::config()->get('system', 'maintenance_reason');
+ $reason = DI::config()->get('system', 'maintenance_reason') ?? '';
if ((substr(Strings::normaliseLink($reason), 0, 7) === 'http://') ||
(substr(Strings::normaliseLink($reason), 0, 8) === 'https://')) {
diff --git a/src/Module/OAuth/Token.php b/src/Module/OAuth/Token.php
index 2752c69a6d..21c18d47c6 100644
--- a/src/Module/OAuth/Token.php
+++ b/src/Module/OAuth/Token.php
@@ -61,7 +61,10 @@ class Token extends BaseApi
}
if (empty($request['client_id']) && substr($authorization, 0, 6) == 'Basic ') {
- $datapair = explode(':', base64_decode(trim(substr($authorization, 6))));
+ // Per RFC2617, usernames can't contain a colon but password can,
+ // so we cut on the first colon to obtain the username and the password
+ // @see https://www.rfc-editor.org/rfc/rfc2617#section-2
+ $datapair = explode(':', base64_decode(trim(substr($authorization, 6))), 2);
if (count($datapair) == 2) {
$request['client_id'] = $datapair[0];
$request['client_secret'] = $datapair[1];
diff --git a/src/Module/Security/PasswordTooLong.php b/src/Module/Security/PasswordTooLong.php
index 1934556b3f..53fafea41e 100644
--- a/src/Module/Security/PasswordTooLong.php
+++ b/src/Module/Security/PasswordTooLong.php
@@ -98,7 +98,7 @@ class PasswordTooLong extends \Friendica\BaseModule
'$return_url' => $request['return_url'] ?? '',
'$password_current' => ['password_current', $this->l10n->t('Current Password:'), '', $this->l10n->t('Your current password to confirm the changes'), 'required', 'autocomplete="off"'],
- '$password' => ['password', $this->l10n->t('New Password:'), '', $this->l10n->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces, accentuated letters and colon (:).') . ' ' . $this->l10n->t('Password length is limited to 72 characters.'), 'required', 'autocomplete="off"', User::getPasswordRegExp()],
+ '$password' => ['password', $this->l10n->t('New Password:'), '', $this->l10n->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces and accentuated letters.') . ' ' . $this->l10n->t('Password length is limited to 72 characters.'), 'required', 'autocomplete="off"', User::getPasswordRegExp()],
'$password_confirm' => ['password_confirm', $this->l10n->t('Confirm:'), '', '', 'required', 'autocomplete="off"'],
]);
diff --git a/src/Module/Settings/Account.php b/src/Module/Settings/Account.php
index df8d41519c..f8f65e7206 100644
--- a/src/Module/Settings/Account.php
+++ b/src/Module/Settings/Account.php
@@ -549,7 +549,7 @@ class Account extends BaseSettings
$notify_type = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'notify_type');
- $passwordRules = DI::l10n()->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces, accentuated letters and colon (:).')
+ $passwordRules = DI::l10n()->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces and accentuated letters.')
. (PASSWORD_DEFAULT === PASSWORD_BCRYPT ? ' ' . DI::l10n()->t('Password length is limited to 72 characters.') : '');
$tpl = Renderer::getMarkupTemplate('settings/account.tpl');
diff --git a/src/Module/Statistics.php b/src/Module/Statistics.php
index 75d3e6432b..514f10bb73 100644
--- a/src/Module/Statistics.php
+++ b/src/Module/Statistics.php
@@ -25,6 +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\L10n;
use Friendica\Core\System;
use Friendica\Network\HTTPException\NotFoundException;
@@ -35,13 +36,15 @@ class Statistics extends BaseModule
{
/** @var IManageConfigValues */
protected $config;
-
- public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, IManageConfigValues $config, Response $response, array $server, array $parameters = [])
+ /** @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);
- $this->config = $config;
-
+ $this->config = $config;
+ $this->keyValue = $keyValue;
if (!$this->config->get("system", "nodeinfo")) {
throw new NotFoundException();
}
@@ -72,10 +75,10 @@ class Statistics extends BaseModule
'network' => App::PLATFORM,
'version' => App::VERSION . '-' . DB_UPDATE_VERSION,
'registrations_open' => $registration_open,
- 'total_users' => $this->config->get('nodeinfo', 'total_users'),
- 'active_users_halfyear' => $this->config->get('nodeinfo', 'active_users_halfyear'),
- 'active_users_monthly' => $this->config->get('nodeinfo', 'active_users_monthly'),
- 'local_posts' => $this->config->get('nodeinfo', 'local_posts'),
+ 'total_users' => $this->keyValue->get('nodeinfo_total_users'),
+ 'active_users_halfyear' => $this->keyValue->get('nodeinfo_active_users_halfyear'),
+ 'active_users_monthly' => $this->keyValue->get('nodeinfo_active_users_monthly'),
+ 'local_posts' => $this->keyValue->get('nodeinfo_local_posts'),
'services' => $services,
], $services);
diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php
index 87671f7e6a..2d15dd85c1 100644
--- a/src/Navigation/Notifications/Repository/Notify.php
+++ b/src/Navigation/Notifications/Repository/Notify.php
@@ -614,7 +614,7 @@ class Notify extends BaseRepository
$emailBuilder->setHeader('Message-ID', $message_id);
$log_msg = "No previous notification found for this parent:\n" .
- " parent: ${params['parent']}\n" . " uid : ${params['uid']}\n";
+ " parent: {$params['parent']}\n" . " uid : {$params['uid']}\n";
$this->logger->info($log_msg);
} else {
// If not, just "follow" the thread.
diff --git a/src/Network/HTTPClient/Client/HttpClient.php b/src/Network/HTTPClient/Client/HttpClient.php
index 2ef704df1f..4ee0842150 100644
--- a/src/Network/HTTPClient/Client/HttpClient.php
+++ b/src/Network/HTTPClient/Client/HttpClient.php
@@ -69,6 +69,10 @@ class HttpClient implements ICanSendHttpRequests
$this->logger->debug('Request start.', ['url' => $url, 'method' => $method]);
$host = parse_url($url, PHP_URL_HOST);
+ if (empty($host)) {
+ throw new \InvalidArgumentException('Unable to retrieve the host in URL: ' . $url);
+ }
+
if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A + DNS_AAAA) && !gethostbyname($host)) {
$this->logger->debug('URL cannot be resolved.', ['url' => $url, 'callstack' => System::callstack(20)]);
$this->profiler->stopRecording();
diff --git a/src/Object/Api/Mastodon/Card.php b/src/Object/Api/Mastodon/Card.php
index d9b7344561..c4d21f66a3 100644
--- a/src/Object/Api/Mastodon/Card.php
+++ b/src/Object/Api/Mastodon/Card.php
@@ -54,6 +54,8 @@ class Card extends BaseDataTransferObject
protected $image;
/** @var string */
protected $blurhash;
+ /** @var array */
+ protected $history;
/**
* Creates a card record from an attachment array.
diff --git a/src/Object/Api/Mastodon/Stats.php b/src/Object/Api/Mastodon/Stats.php
index 1f08ab2ed7..335c82d431 100644
--- a/src/Object/Api/Mastodon/Stats.php
+++ b/src/Object/Api/Mastodon/Stats.php
@@ -25,7 +25,6 @@ use Friendica\BaseDataTransferObject;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Protocol;
use Friendica\Database\Database;
-use Friendica\Database\DBA;
use Friendica\DI;
/**
@@ -45,9 +44,9 @@ class Stats extends BaseDataTransferObject
public function __construct(IManageConfigValues $config, Database $database)
{
if (!empty($config->get('system', 'nodeinfo'))) {
- $this->user_count = intval($config->get('nodeinfo', 'total_users'));
- $this->status_count = $config->get('nodeinfo', 'local_posts') + $config->get('nodeinfo', 'local_comments');
- $this->domain_count = $database->count('gserver', ["`network` in (?, ?) AND NOT `failed`", Protocol::DFRN, Protocol::ACTIVITYPUB]);
+ $this->user_count = intval(DI::keyValue()->get('nodeinfo_total_users'));
+ $this->status_count = DI::keyValue()->get('nodeinfo_local_posts') + DI::keyValue()->get('nodeinfo_local_comments');
+ $this->domain_count = $database->count('gserver', ["`network` in (?, ?) AND NOT `failed` AND NOT `blocked`", Protocol::DFRN, Protocol::ACTIVITYPUB]);
}
}
}
diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php
index 6e1180bca8..bcff0b53b1 100644
--- a/src/Protocol/ActivityPub/Transmitter.php
+++ b/src/Protocol/ActivityPub/Transmitter.php
@@ -1661,7 +1661,7 @@ class Transmitter
*
* } elseif (($type == 'Article') && empty($data['summary'])) {
* $regexp = "/[@!]\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
- * $summary = preg_replace_callback($regexp, ['self', 'mentionAddrCallback'], $body);
+ * $summary = preg_replace_callback($regexp, [self::class, 'mentionAddrCallback'], $body);
* $data['summary'] = BBCode::toPlaintext(Plaintext::shorten(self::removePictures($summary), 1000));
* }
*/
diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php
index 9d19a4ebac..f1e96dedc3 100644
--- a/src/Util/ParseUrl.php
+++ b/src/Util/ParseUrl.php
@@ -646,7 +646,7 @@ class ParseUrl
$arr_tags = str_getcsv($string);
if (count($arr_tags)) {
// add the # sign to every tag
- array_walk($arr_tags, ['self', 'arrAddHashes']);
+ array_walk($arr_tags, [self::class, 'arrAddHashes']);
return $arr_tags;
}
diff --git a/src/Util/Proxy.php b/src/Util/Proxy.php
index 67a0becb04..7f3c946722 100644
--- a/src/Util/Proxy.php
+++ b/src/Util/Proxy.php
@@ -141,7 +141,7 @@ class Proxy
{
$html = str_replace(Strings::normaliseLink(DI::baseUrl()) . '/', DI::baseUrl() . '/', $html);
- return preg_replace_callback('/(]*src *= *["\'])([^"\']+)(["\'][^>]*>)/siU', 'self::replaceUrl', $html);
+ return preg_replace_callback('/(]*src *= *["\'])([^"\']+)(["\'][^>]*>)/siU', [self::class, 'replaceUrl'], $html);
}
/**
diff --git a/src/Worker/UpdateServerPeers.php b/src/Worker/UpdateServerPeers.php
index 85a1b61bf6..4829b538cf 100644
--- a/src/Worker/UpdateServerPeers.php
+++ b/src/Worker/UpdateServerPeers.php
@@ -57,7 +57,7 @@ class UpdateServerPeers
$total = 0;
$added = 0;
foreach ($peers as $peer) {
- if (Network::isUrlBlocked('http://' . $peer)) {
+ if (Network::isUrlBlocked('https://' . $peer)) {
// Ignore blocked systems as soon as possible in the loop to avoid being slowed down by tar pits
continue;
}
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index a6459f16ba..4329410b4a 100644
--- a/static/dbstructure.config.php
+++ b/static/dbstructure.config.php
@@ -55,7 +55,7 @@
use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1511);
+ define('DB_UPDATE_VERSION', 1512);
}
return [
diff --git a/static/dependencies.config.php b/static/dependencies.config.php
index 1836a44dd5..5b7a345685 100644
--- a/static/dependencies.config.php
+++ b/static/dependencies.config.php
@@ -37,6 +37,8 @@ use Dice\Dice;
use Friendica\App;
use Friendica\Core\Cache;
use Friendica\Core\Config;
+use Friendica\Core\Hooks\Capabilities\ICanManageInstances;
+use Friendica\Core\Hooks\Model\InstanceManager;
use Friendica\Core\PConfig;
use Friendica\Core\L10n;
use Friendica\Core\Lock;
@@ -76,6 +78,12 @@ return [
$_SERVER
]
],
+ ICanManageInstances::class => [
+ 'instanceOf' => InstanceManager::class,
+ 'constructParams' => [
+ [Dice::INSTANCE => Dice::SELF],
+ ],
+ ],
Config\Util\ConfigFileManager::class => [
'instanceOf' => Config\Factory\Config::class,
'call' => [
diff --git a/tests/Util/CreateDatabaseTrait.php b/tests/Util/CreateDatabaseTrait.php
index 51f74c7a52..127d8da2f1 100644
--- a/tests/Util/CreateDatabaseTrait.php
+++ b/tests/Util/CreateDatabaseTrait.php
@@ -30,6 +30,7 @@ use Friendica\Database\Definition\ViewDefinition;
use Friendica\Test\DatabaseTestTrait;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Util\Profiler;
+use Psr\Log\NullLogger;
trait CreateDatabaseTrait
{
@@ -45,7 +46,7 @@ trait CreateDatabaseTrait
],
]));
- $database = new StaticDatabase($config, new Profiler($config), (new DbaDefinition($this->root->url()))->load(), (new ViewDefinition($this->root->url()))->load());
+ $database = new StaticDatabase($config, new Profiler($config), (new DbaDefinition($this->root->url()))->load(), (new ViewDefinition($this->root->url()))->load(), new NullLogger());
$database->setTestmode(true);
return $database;
diff --git a/tests/Util/Hooks/InstanceMocks/FakeInstance.php b/tests/Util/Hooks/InstanceMocks/FakeInstance.php
new file mode 100644
index 0000000000..ff99002f7c
--- /dev/null
+++ b/tests/Util/Hooks/InstanceMocks/FakeInstance.php
@@ -0,0 +1,60 @@
+.
+ *
+ */
+
+namespace Friendica\Test\Util\Hooks\InstanceMocks;
+
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
+
+class FakeInstance implements IAmADecoratedInterface, IAmAStrategy
+{
+ protected $aText = null;
+ protected $cBool = null;
+ protected $bText = null;
+
+ public function __construct(string $aText = null, bool $cBool = null, string $bText = null)
+ {
+ $this->aText = $aText;
+ $this->cBool = $cBool;
+ $this->bText = $bText;
+ }
+
+ public function createSomething(string $aText, bool $cBool, string $bText): string
+ {
+ $this->aText = $aText;
+ $this->cBool = $cBool;
+ $this->bText = $bText;
+ }
+
+ public function getAText(): ?string
+ {
+ return $this->aText;
+ }
+
+ public function getBText(): ?string
+ {
+ return $this->bText;
+ }
+
+ public function getCBool(): ?bool
+ {
+ return $this->cBool;
+ }
+}
diff --git a/tests/Util/Hooks/InstanceMocks/FakeInstanceDecorator.php b/tests/Util/Hooks/InstanceMocks/FakeInstanceDecorator.php
new file mode 100644
index 0000000000..af4db96c44
--- /dev/null
+++ b/tests/Util/Hooks/InstanceMocks/FakeInstanceDecorator.php
@@ -0,0 +1,59 @@
+.
+ *
+ */
+
+namespace Friendica\Test\Util\Hooks\InstanceMocks;
+
+class FakeInstanceDecorator implements IAmADecoratedInterface
+{
+ public static $countInstance = 0;
+
+ /** @var IAmADecoratedInterface */
+ protected $orig;
+ protected $prefix = '';
+
+ public function __construct(IAmADecoratedInterface $orig, string $prefix = '')
+ {
+ $this->orig = $orig;
+ $this->prefix = $prefix;
+
+ self::$countInstance++;
+ }
+
+ public function createSomething(string $aText, bool $cBool, string $bText): string
+ {
+ return $this->orig->createSomething($aText, $cBool, $bText);
+ }
+
+ public function getAText(): ?string
+ {
+ return $this->prefix . $this->orig->getAText();
+ }
+
+ public function getBText(): ?string
+ {
+ return $this->prefix . $this->orig->getBText();
+ }
+
+ public function getCBool(): ?bool
+ {
+ return $this->prefix . $this->orig->getCBool();
+ }
+}
diff --git a/tests/Util/Hooks/InstanceMocks/IAmADecoratedInterface.php b/tests/Util/Hooks/InstanceMocks/IAmADecoratedInterface.php
new file mode 100644
index 0000000000..fe93aa998d
--- /dev/null
+++ b/tests/Util/Hooks/InstanceMocks/IAmADecoratedInterface.php
@@ -0,0 +1,33 @@
+.
+ *
+ */
+
+namespace Friendica\Test\Util\Hooks\InstanceMocks;
+
+interface IAmADecoratedInterface
+{
+ public function createSomething(string $aText, bool $cBool, string $bText): string;
+
+ public function getAText(): ?string;
+
+ public function getBText(): ?string;
+
+ public function getCBool(): ?bool;
+}
diff --git a/tests/Util/SerializableObjectDouble.php b/tests/Util/SerializableObjectDouble.php
new file mode 100644
index 0000000000..e159655012
--- /dev/null
+++ b/tests/Util/SerializableObjectDouble.php
@@ -0,0 +1,35 @@
+.
+ *
+ */
+
+namespace Friendica\Test\Util;
+
+class SerializableObjectDouble implements \Serializable
+{
+ public function serialize()
+ {
+ return '\'serialized\'';
+ }
+
+ public function unserialize($data)
+ {
+ return '\'unserialized\'';
+ }
+}
diff --git a/tests/datasets/config/transformer/object_valid.node.config.php b/tests/datasets/config/transformer/object_valid.node.config.php
new file mode 100644
index 0000000000..bfe61f3c8d
--- /dev/null
+++ b/tests/datasets/config/transformer/object_valid.node.config.php
@@ -0,0 +1,11 @@
+ [
+ 'toString' => new HiddenString('test'),
+ 'serializable' => new SerializableObjectDouble(),
+ ],
+];
diff --git a/tests/functional/DependencyCheckTest.php b/tests/functional/DependencyCheckTest.php
index 86724bf437..27e693295e 100644
--- a/tests/functional/DependencyCheckTest.php
+++ b/tests/functional/DependencyCheckTest.php
@@ -25,7 +25,6 @@ use Dice\Dice;
use Friendica\App;
use Friendica\Core\Cache\Capability\ICanCache;
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Config\Model\Config;
use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Lock\Capability\ICanLock;
@@ -33,7 +32,6 @@ use Friendica\Database\Database;
use Friendica\Test\Util\VFSTrait;
use Friendica\Util\BasePath;
use Friendica\Core\Config\Util\ConfigFileManager;
-use Friendica\Util\Profiler;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
@@ -53,7 +51,18 @@ class DependencyCheckTest extends TestCase
$this->setUpVfsDir();
$this->dice = (new Dice())
- ->addRules(include __DIR__ . '/../../static/dependencies.config.php');
+ ->addRules(include __DIR__ . '/../../static/dependencies.config.php')
+ ->addRule(BasePath::class, [
+ 'constructParams' => [
+ $this->root->url(),
+ [],
+ ],
+ ])
+ ->addRule(LoggerInterface::class, ['constructParams' => ['test']]);
+
+ /** @var IManageConfigValues $config */
+ $config = $this->dice->create(IManageConfigValues::class);
+ $config->set('system', 'logfile', $this->root->url() . '/logs/friendica.log');
}
/**
@@ -142,7 +151,7 @@ class DependencyCheckTest extends TestCase
public function testLogger()
{
/** @var LoggerInterface $logger */
- $logger = $this->dice->create(LoggerInterface::class, ['test']);
+ $logger = $this->dice->create(LoggerInterface::class, [['$channel' => 'test']]);
self::assertInstanceOf(LoggerInterface::class, $logger);
}
@@ -154,7 +163,7 @@ class DependencyCheckTest extends TestCase
$config->set('system', 'dlogfile', $this->root->url() . '/friendica.log');
/** @var LoggerInterface $logger */
- $logger = $this->dice->create('$devLogger', ['dev']);
+ $logger = $this->dice->create('$devLogger', [['$channel' => 'dev']]);
self::assertInstanceOf(LoggerInterface::class, $logger);
}
@@ -164,6 +173,7 @@ class DependencyCheckTest extends TestCase
/** @var ICanCache $cache */
$cache = $this->dice->create(ICanCache::class);
+
self::assertInstanceOf(ICanCache::class, $cache);
}
diff --git a/tests/src/Core/Cache/DatabaseCacheTest.php b/tests/src/Core/Cache/DatabaseCacheTest.php
index e5f3359580..81804a806e 100644
--- a/tests/src/Core/Cache/DatabaseCacheTest.php
+++ b/tests/src/Core/Cache/DatabaseCacheTest.php
@@ -62,7 +62,7 @@ class DatabaseCacheTest extends CacheTest
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
- $dba = new StaticDatabase($config, $profiler, $dbaDefinition, $viewDefinition);
+ $dba = new StaticDatabase($config, $profiler, $dbaDefinition, $viewDefinition, new NullLogger());
$this->cache = new Cache\Type\DatabaseCache('database', $dba);
return $this->cache;
diff --git a/tests/src/Core/Config/Util/ConfigFileTransformerTest.php b/tests/src/Core/Config/Util/ConfigFileTransformerTest.php
index bb156cf282..c11a770ad8 100644
--- a/tests/src/Core/Config/Util/ConfigFileTransformerTest.php
+++ b/tests/src/Core/Config/Util/ConfigFileTransformerTest.php
@@ -23,6 +23,9 @@ namespace Friendica\Test\src\Core\Config\Util;
use Friendica\Core\Config\Util\ConfigFileTransformer;
use Friendica\Test\MockedTest;
+use Friendica\Test\Util\SerializableObjectDouble;
+use ParagonIE\HiddenString\HiddenString;
+use function PHPUnit\Framework\assertEquals;
class ConfigFileTransformerTest extends MockedTest
{
@@ -45,9 +48,34 @@ class ConfigFileTransformerTest extends MockedTest
'configFile' => (dirname(__DIR__, 4) . '/datasets/config/transformer/object.node.config.php'),
'assertException' => true,
],
- 'ressource_invalid' => [
+ 'resource' => [
'configFile' => (dirname(__DIR__, 4) . '/datasets/config/transformer/ressource.node.config.php'),
- 'assertException' => true,
+ 'assertException' => false,
+ 'assertion' => << The server domain pattern syntax is case-insensitive shell wildcard, "
"comprising the following special characters: This file can be downloaded from the {{$reason}}
"
msgstr ""
-#: src/Module/Admin/Summary.php:66
+#: src/Module/Admin/Summary.php:64
#, php-format
msgid ""
"Your DB still runs with InnoDB tables in the Antelope file format. You "
@@ -5034,7 +5033,7 @@ msgid ""
"installation for an automatic conversion.
"
msgstr ""
-#: src/Module/Admin/Summary.php:76
+#: src/Module/Admin/Summary.php:74
#, php-format
msgid ""
"Your table_definition_cache is too low (%d). This can lead to the database "
@@ -5042,39 +5041,39 @@ msgid ""
"to %d. See here for more information.
"
msgstr ""
-#: src/Module/Admin/Summary.php:86
+#: src/Module/Admin/Summary.php:84
#, php-format
msgid ""
"There is a new version of Friendica available for download. Your current "
"version is %1$s, upstream version is %2$s"
msgstr ""
-#: src/Module/Admin/Summary.php:95
+#: src/Module/Admin/Summary.php:93
msgid ""
"The database update failed. Please run \"php bin/console.php dbstructure "
"update\" from the command line and have a look at the errors that might "
"appear."
msgstr ""
-#: src/Module/Admin/Summary.php:99
+#: src/Module/Admin/Summary.php:97
msgid ""
"The last update failed. Please run \"php bin/console.php dbstructure update"
"\" from the command line and have a look at the errors that might appear. "
"(Some of the errors are possibly inside the logfile.)"
msgstr ""
-#: src/Module/Admin/Summary.php:104
+#: src/Module/Admin/Summary.php:102
msgid "The worker was never executed. Please check your database structure!"
msgstr ""
-#: src/Module/Admin/Summary.php:106
+#: src/Module/Admin/Summary.php:104
#, php-format
msgid ""
"The last worker execution was on %s UTC. This is older than one hour. Please "
"check your crontab settings."
msgstr ""
-#: src/Module/Admin/Summary.php:111
+#: src/Module/Admin/Summary.php:109
#, php-format
msgid ""
"Friendica's configuration now is stored in config/local.config.php, please "
@@ -5083,7 +5082,7 @@ msgid ""
"with the transition."
msgstr ""
-#: src/Module/Admin/Summary.php:115
+#: src/Module/Admin/Summary.php:113
#, php-format
msgid ""
"Friendica's configuration now is stored in config/local.config.php, please "
@@ -5092,7 +5091,7 @@ msgid ""
"with the transition."
msgstr ""
-#: src/Module/Admin/Summary.php:119
+#: src/Module/Admin/Summary.php:117
#, php-format
msgid ""
"Friendica's configuration store \"%s\" isn't writable. Until then database "
@@ -5100,7 +5099,7 @@ msgid ""
"configuration changes won't be saved."
msgstr ""
-#: src/Module/Admin/Summary.php:125
+#: src/Module/Admin/Summary.php:123
#, php-format
msgid ""
"%s is not reachable on your system. This is a severe "
@@ -5108,50 +5107,50 @@ msgid ""
"href=\"%s\">the installation page for help."
msgstr ""
-#: src/Module/Admin/Summary.php:143
+#: src/Module/Admin/Summary.php:141
#, php-format
msgid "The logfile '%s' is not usable. No logging possible (error: '%s')"
msgstr ""
-#: src/Module/Admin/Summary.php:157
+#: src/Module/Admin/Summary.php:155
#, php-format
msgid "The debug logfile '%s' is not usable. No logging possible (error: '%s')"
msgstr ""
-#: src/Module/Admin/Summary.php:173
+#: src/Module/Admin/Summary.php:171
#, php-format
msgid ""
"Friendica's system.basepath was updated from '%s' to '%s'. Please remove the "
"system.basepath from your db to avoid differences."
msgstr ""
-#: src/Module/Admin/Summary.php:181
+#: src/Module/Admin/Summary.php:179
#, php-format
msgid ""
"Friendica's current system.basepath '%s' is wrong and the config file '%s' "
"isn't used."
msgstr ""
-#: src/Module/Admin/Summary.php:189
+#: src/Module/Admin/Summary.php:187
#, php-format
msgid ""
"Friendica's current system.basepath '%s' is not equal to the config file "
"'%s'. Please fix your configuration."
msgstr ""
-#: src/Module/Admin/Summary.php:200
+#: src/Module/Admin/Summary.php:198
msgid "Message queues"
msgstr ""
-#: src/Module/Admin/Summary.php:206
+#: src/Module/Admin/Summary.php:204
msgid "Server Settings"
msgstr ""
-#: src/Module/Admin/Summary.php:224
+#: src/Module/Admin/Summary.php:222
msgid "Version"
msgstr ""
-#: src/Module/Admin/Summary.php:228
+#: src/Module/Admin/Summary.php:226
msgid "Active addons"
msgstr ""
@@ -5543,13 +5542,13 @@ msgstr ""
#: src/Module/Install.php:286 src/Module/Install.php:291
#: src/Module/Install.php:305 src/Module/Install.php:320
#: src/Module/Install.php:347
-#: src/Module/Moderation/Blocklist/Server/Add.php:134
#: src/Module/Moderation/Blocklist/Server/Add.php:136
-#: src/Module/Moderation/Blocklist/Server/Import.php:126
-#: src/Module/Moderation/Blocklist/Server/Index.php:83
-#: src/Module/Moderation/Blocklist/Server/Index.php:84
-#: src/Module/Moderation/Blocklist/Server/Index.php:112
-#: src/Module/Moderation/Blocklist/Server/Index.php:113
+#: src/Module/Moderation/Blocklist/Server/Add.php:138
+#: src/Module/Moderation/Blocklist/Server/Import.php:129
+#: src/Module/Moderation/Blocklist/Server/Index.php:86
+#: src/Module/Moderation/Blocklist/Server/Index.php:87
+#: src/Module/Moderation/Blocklist/Server/Index.php:115
+#: src/Module/Moderation/Blocklist/Server/Index.php:116
#: src/Module/Moderation/Item/Delete.php:67 src/Module/Register.php:148
#: src/Module/Security/TwoFactor/Verify.php:101
#: src/Module/Settings/TwoFactor/Index.php:140
@@ -5589,15 +5588,15 @@ msgstr ""
msgid "Basic"
msgstr ""
-#: src/Module/Calendar/Export.php:77
+#: src/Module/Calendar/Export.php:94
msgid "This calendar format is not supported"
msgstr ""
-#: src/Module/Calendar/Export.php:79
+#: src/Module/Calendar/Export.php:96
msgid "No exportable data found"
msgstr ""
-#: src/Module/Calendar/Export.php:96
+#: src/Module/Calendar/Export.php:113
msgid "calendar"
msgstr ""
@@ -5696,20 +5695,18 @@ msgstr ""
msgid "Update"
msgstr ""
-#: src/Module/Contact.php:440 src/Module/Contact/Profile.php:364
-#: src/Module/Contact/Profile.php:484
+#: src/Module/Contact.php:440 src/Module/Contact/Profile.php:478
#: src/Module/Moderation/Blocklist/Contact.php:117
#: src/Module/Moderation/Users/Blocked.php:138
#: src/Module/Moderation/Users/Index.php:154
msgid "Unblock"
msgstr ""
-#: src/Module/Contact.php:441 src/Module/Contact/Profile.php:365
-#: src/Module/Contact/Profile.php:492
+#: src/Module/Contact.php:441 src/Module/Contact/Profile.php:486
msgid "Unignore"
msgstr ""
-#: src/Module/Contact.php:442 src/Module/Contact/Profile.php:500
+#: src/Module/Contact.php:442 src/Module/Contact/Profile.php:494
msgid "Uncollapse"
msgstr ""
@@ -5761,7 +5758,7 @@ msgstr ""
msgid "Pending incoming contact request"
msgstr ""
-#: src/Module/Contact.php:597 src/Module/Contact/Profile.php:350
+#: src/Module/Contact.php:597 src/Module/Contact/Profile.php:347
#, php-format
msgid "Visit %s's profile [%s]"
msgstr ""
@@ -5914,7 +5911,7 @@ msgstr ""
msgid "Your Identity Address:"
msgstr ""
-#: src/Module/Contact/Follow.php:169 src/Module/Contact/Profile.php:382
+#: src/Module/Contact/Follow.php:169 src/Module/Contact/Profile.php:376
#: src/Module/Contact/Unfollow.php:129
#: src/Module/Moderation/Blocklist/Contact.php:133
#: src/Module/Notifications/Introductions.php:129
@@ -5922,7 +5919,7 @@ msgstr ""
msgid "Profile URL"
msgstr ""
-#: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:394
+#: src/Module/Contact/Follow.php:170 src/Module/Contact/Profile.php:388
#: src/Module/Notifications/Introductions.php:191
#: src/Module/Profile/Profile.php:234
msgid "Tags:"
@@ -5989,220 +5986,220 @@ msgstr ""
msgid "Contact has been collapsed"
msgstr ""
-#: src/Module/Contact/Profile.php:246
+#: src/Module/Contact/Profile.php:243
#, php-format
msgid "You are mutual friends with %s"
msgstr ""
-#: src/Module/Contact/Profile.php:247
+#: src/Module/Contact/Profile.php:244
#, php-format
msgid "You are sharing with %s"
msgstr ""
-#: src/Module/Contact/Profile.php:248
+#: src/Module/Contact/Profile.php:245
#, php-format
msgid "%s is sharing with you"
msgstr ""
-#: src/Module/Contact/Profile.php:264
+#: src/Module/Contact/Profile.php:261
msgid "Private communications are not available for this contact."
msgstr ""
-#: src/Module/Contact/Profile.php:266
+#: src/Module/Contact/Profile.php:263
msgid "Never"
msgstr ""
-#: src/Module/Contact/Profile.php:269
+#: src/Module/Contact/Profile.php:266
msgid "(Update was not successful)"
msgstr ""
-#: src/Module/Contact/Profile.php:269
+#: src/Module/Contact/Profile.php:266
msgid "(Update was successful)"
msgstr ""
-#: src/Module/Contact/Profile.php:271 src/Module/Contact/Profile.php:455
+#: src/Module/Contact/Profile.php:268 src/Module/Contact/Profile.php:449
msgid "Suggest friends"
msgstr ""
-#: src/Module/Contact/Profile.php:275
+#: src/Module/Contact/Profile.php:272
#, php-format
msgid "Network type: %s"
msgstr ""
-#: src/Module/Contact/Profile.php:280
+#: src/Module/Contact/Profile.php:277
msgid "Communications lost with this contact!"
msgstr ""
-#: src/Module/Contact/Profile.php:286
+#: src/Module/Contact/Profile.php:283
msgid "Fetch further information for feeds"
msgstr ""
-#: src/Module/Contact/Profile.php:288
+#: src/Module/Contact/Profile.php:285
msgid ""
"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."
msgstr ""
-#: src/Module/Contact/Profile.php:291
+#: src/Module/Contact/Profile.php:288
msgid "Fetch information"
msgstr ""
-#: src/Module/Contact/Profile.php:292
+#: src/Module/Contact/Profile.php:289
msgid "Fetch keywords"
msgstr ""
-#: src/Module/Contact/Profile.php:293
+#: src/Module/Contact/Profile.php:290
msgid "Fetch information and keywords"
msgstr ""
-#: src/Module/Contact/Profile.php:303 src/Module/Contact/Profile.php:308
-#: src/Module/Contact/Profile.php:313 src/Module/Contact/Profile.php:319
+#: src/Module/Contact/Profile.php:300 src/Module/Contact/Profile.php:305
+#: src/Module/Contact/Profile.php:310 src/Module/Contact/Profile.php:316
msgid "No mirroring"
msgstr ""
-#: src/Module/Contact/Profile.php:304 src/Module/Contact/Profile.php:314
-#: src/Module/Contact/Profile.php:320
+#: src/Module/Contact/Profile.php:301 src/Module/Contact/Profile.php:311
+#: src/Module/Contact/Profile.php:317
msgid "Mirror as my own posting"
msgstr ""
-#: src/Module/Contact/Profile.php:309 src/Module/Contact/Profile.php:315
+#: src/Module/Contact/Profile.php:306 src/Module/Contact/Profile.php:312
msgid "Native reshare"
msgstr ""
-#: src/Module/Contact/Profile.php:332
+#: src/Module/Contact/Profile.php:329
msgid "Contact Information / Notes"
msgstr ""
-#: src/Module/Contact/Profile.php:333
+#: src/Module/Contact/Profile.php:330
msgid "Contact Settings"
msgstr ""
-#: src/Module/Contact/Profile.php:341
+#: src/Module/Contact/Profile.php:338
msgid "Contact"
msgstr ""
-#: src/Module/Contact/Profile.php:345
+#: src/Module/Contact/Profile.php:342
msgid "Their personal note"
msgstr ""
-#: src/Module/Contact/Profile.php:347
+#: src/Module/Contact/Profile.php:344
msgid "Edit contact notes"
msgstr ""
-#: src/Module/Contact/Profile.php:351
+#: src/Module/Contact/Profile.php:348
msgid "Block/Unblock contact"
msgstr ""
-#: src/Module/Contact/Profile.php:352
+#: src/Module/Contact/Profile.php:349
msgid "Ignore contact"
msgstr ""
-#: src/Module/Contact/Profile.php:353
+#: src/Module/Contact/Profile.php:350
msgid "View conversations"
msgstr ""
-#: src/Module/Contact/Profile.php:358
+#: src/Module/Contact/Profile.php:355
msgid "Last update:"
msgstr ""
-#: src/Module/Contact/Profile.php:360
+#: src/Module/Contact/Profile.php:357
msgid "Update public posts"
msgstr ""
-#: src/Module/Contact/Profile.php:362 src/Module/Contact/Profile.php:465
+#: src/Module/Contact/Profile.php:359 src/Module/Contact/Profile.php:459
msgid "Update now"
msgstr ""
-#: src/Module/Contact/Profile.php:369
-msgid "Currently blocked"
-msgstr ""
-
-#: src/Module/Contact/Profile.php:370
-msgid "Currently ignored"
-msgstr ""
-
-#: src/Module/Contact/Profile.php:371
-msgid "Currently collapsed"
-msgstr ""
-
-#: src/Module/Contact/Profile.php:372
-msgid "Currently archived"
-msgstr ""
-
-#: src/Module/Contact/Profile.php:373
+#: src/Module/Contact/Profile.php:361
msgid "Awaiting connection acknowledge"
msgstr ""
-#: src/Module/Contact/Profile.php:374
+#: src/Module/Contact/Profile.php:362
+msgid "Currently blocked"
+msgstr ""
+
+#: src/Module/Contact/Profile.php:363
+msgid "Currently ignored"
+msgstr ""
+
+#: src/Module/Contact/Profile.php:364
+msgid "Currently collapsed"
+msgstr ""
+
+#: src/Module/Contact/Profile.php:365
+msgid "Currently archived"
+msgstr ""
+
+#: src/Module/Contact/Profile.php:368
#: src/Module/Notifications/Introductions.php:192
msgid "Hide this contact from others"
msgstr ""
-#: src/Module/Contact/Profile.php:374
+#: src/Module/Contact/Profile.php:368
msgid ""
"Replies/likes to your public posts may still be visible"
msgstr ""
-#: src/Module/Contact/Profile.php:375
+#: src/Module/Contact/Profile.php:369
msgid "Notification for new posts"
msgstr ""
-#: src/Module/Contact/Profile.php:375
+#: src/Module/Contact/Profile.php:369
msgid "Send a notification of every new post of this contact"
msgstr ""
-#: src/Module/Contact/Profile.php:377
+#: src/Module/Contact/Profile.php:371
msgid "Keyword Deny List"
msgstr ""
-#: src/Module/Contact/Profile.php:377
+#: src/Module/Contact/Profile.php:371
msgid ""
"Comma separated list of keywords that should not be converted to hashtags, "
"when \"Fetch information and keywords\" is selected"
msgstr ""
-#: src/Module/Contact/Profile.php:395
+#: src/Module/Contact/Profile.php:389
#: src/Module/Settings/TwoFactor/Index.php:139
msgid "Actions"
msgstr ""
-#: src/Module/Contact/Profile.php:397
+#: src/Module/Contact/Profile.php:391
#: src/Module/Settings/TwoFactor/Index.php:119 view/theme/frio/theme.php:229
msgid "Status"
msgstr ""
-#: src/Module/Contact/Profile.php:403
+#: src/Module/Contact/Profile.php:397
msgid "Mirror postings from this contact"
msgstr ""
-#: src/Module/Contact/Profile.php:405
+#: src/Module/Contact/Profile.php:399
msgid ""
"Mark this contact as remote_self, this will cause friendica to repost new "
"entries from this contact."
msgstr ""
-#: src/Module/Contact/Profile.php:475
+#: src/Module/Contact/Profile.php:469
msgid "Refetch contact data"
msgstr ""
-#: src/Module/Contact/Profile.php:486
+#: src/Module/Contact/Profile.php:480
msgid "Toggle Blocked status"
msgstr ""
-#: src/Module/Contact/Profile.php:494
+#: src/Module/Contact/Profile.php:488
msgid "Toggle Ignored status"
msgstr ""
-#: src/Module/Contact/Profile.php:502
+#: src/Module/Contact/Profile.php:496
msgid "Toggle Collapsed status"
msgstr ""
-#: src/Module/Contact/Profile.php:509 src/Module/Contact/Revoke.php:106
+#: src/Module/Contact/Profile.php:503 src/Module/Contact/Revoke.php:106
msgid "Revoke Follow"
msgstr ""
-#: src/Module/Contact/Profile.php:511
+#: src/Module/Contact/Profile.php:505
msgid "Revoke the follow from this contact"
msgstr ""
@@ -6725,8 +6722,8 @@ msgid "On this server the following remote servers are blocked."
msgstr ""
#: src/Module/Friendica.php:84
-#: src/Module/Moderation/Blocklist/Server/Index.php:84
-#: src/Module/Moderation/Blocklist/Server/Index.php:108
+#: src/Module/Moderation/Blocklist/Server/Index.php:87
+#: src/Module/Moderation/Blocklist/Server/Index.php:111
msgid "Reason for the block"
msgstr ""
@@ -7399,32 +7396,32 @@ msgid ""
msgstr ""
#: src/Module/Moderation/Blocklist/Contact.php:135
-#: src/Module/Moderation/Blocklist/Server/Import.php:121
+#: src/Module/Moderation/Blocklist/Server/Import.php:124
msgid "Block Reason"
msgstr ""
-#: src/Module/Moderation/Blocklist/Server/Add.php:78
+#: src/Module/Moderation/Blocklist/Server/Add.php:80
msgid "Server domain pattern added to the blocklist."
msgstr ""
-#: src/Module/Moderation/Blocklist/Server/Add.php:86
+#: src/Module/Moderation/Blocklist/Server/Add.php:88
#, php-format
msgid "%s server scheduled to be purged."
msgid_plural "%s servers scheduled to be purged."
msgstr[0] ""
msgstr[1] ""
-#: src/Module/Moderation/Blocklist/Server/Add.php:118
-#: src/Module/Moderation/Blocklist/Server/Import.php:114
+#: src/Module/Moderation/Blocklist/Server/Add.php:120
+#: src/Module/Moderation/Blocklist/Server/Import.php:117
msgid "← Return to the list"
msgstr ""
-#: src/Module/Moderation/Blocklist/Server/Add.php:120
+#: src/Module/Moderation/Blocklist/Server/Add.php:122
msgid "Block A New Server Domain Pattern"
msgstr ""
-#: src/Module/Moderation/Blocklist/Server/Add.php:121
-#: src/Module/Moderation/Blocklist/Server/Index.php:96
+#: src/Module/Moderation/Blocklist/Server/Add.php:123
+#: src/Module/Moderation/Blocklist/Server/Index.php:99
msgid ""
"/friendica
path of any "
"Friendica server.
+
{{if $location}}
{{/if}}
{{if $xmpp}}
{{/if}}
{{if $matrix}}
{{/if}}
@@ -63,40 +62,39 @@
- {{if $contact_settings_label}}
+ {{if $contact_settings_label}}
{{$contact_settings_label}}
{{$lbl_info1}}
-
- {{$lbl_info2}}