diff --git a/bin/daemon.php b/bin/daemon.php
index d5ef02a8ec..b7085a490a 100755
--- a/bin/daemon.php
+++ b/bin/daemon.php
@@ -115,7 +115,7 @@ if (is_readable($pidfile)) {
}
if (empty($pid) && in_array($mode, ['stop', 'status'])) {
- DI::config()->set('system', 'worker_daemon_mode', false);
+ DI::keyValue()->set('worker_daemon_mode', false);
die("Pidfile wasn't found. Is the daemon running?\n");
}
@@ -137,7 +137,7 @@ if ($mode == 'stop') {
Logger::notice('Worker daemon process was killed', ['pid' => $pid]);
- DI::config()->set('system', 'worker_daemon_mode', false);
+ DI::keyValue()->set('worker_daemon_mode', false);
die("Worker daemon process $pid was killed.\n");
}
@@ -181,7 +181,7 @@ if (!$foreground) {
DBA::connect();
}
-DI::config()->set('system', 'worker_daemon_mode', true);
+DI::keyValue()->set('worker_daemon_mode', true);
// Just to be sure that this script really runs endlessly
set_time_limit(0);
diff --git a/database.sql b/database.sql
index 7eb756cf2a..2ae33689c1 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2023.03-dev (Giant Rhubarb)
--- DB_UPDATE_VERSION 1504
+-- DB_UPDATE_VERSION 1505
-- ------------------------------------------
@@ -839,6 +839,16 @@ CREATE TABLE IF NOT EXISTS `intro` (
FOREIGN KEY (`suggest-cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
+--
+-- TABLE key-value
+--
+CREATE TABLE IF NOT EXISTS `key-value` (
+ `k` varbinary(50) NOT NULL COMMENT '',
+ `v` mediumtext COMMENT '',
+ `updated_at` int unsigned NOT NULL COMMENT 'timestamp of the last update',
+ PRIMARY KEY(`k`)
+) DEFAULT COLLATE utf8mb4_general_ci COMMENT='A key value storage';
+
--
-- TABLE locks
--
diff --git a/doc/database.md b/doc/database.md
index 9fa438c8d2..5759d29ec7 100644
--- a/doc/database.md
+++ b/doc/database.md
@@ -40,6 +40,7 @@ Database Tables
| [inbox-status](help/database/db_inbox-status) | Status of ActivityPub inboxes |
| [intro](help/database/db_intro) | |
| [item-uri](help/database/db_item-uri) | URI and GUID for items |
+| [key-value](help/database/db_key-value) | A key value storage |
| [locks](help/database/db_locks) | |
| [mail](help/database/db_mail) | private messages |
| [mailacct](help/database/db_mailacct) | Mail account data for fetching mails |
diff --git a/doc/database/db_key-value.md b/doc/database/db_key-value.md
new file mode 100644
index 0000000000..2ed3baa48c
--- /dev/null
+++ b/doc/database/db_key-value.md
@@ -0,0 +1,23 @@
+Table key-value
+===========
+
+A key value storage
+
+Fields
+------
+
+| Field | Description | Type | Null | Key | Default | Extra |
+| ---------- | ---------------------------- | ------------- | ---- | --- | ------- | ----- |
+| k | | varbinary(50) | NO | PRI | NULL | |
+| v | | mediumtext | YES | | NULL | |
+| updated_at | timestamp of the last update | int unsigned | NO | | NULL | |
+
+Indexes
+------------
+
+| Name | Fields |
+| ------- | ------ |
+| PRIMARY | k |
+
+
+Return to [database documentation](help/database)
diff --git a/doc/tools.md b/doc/tools.md
index 1c3b8e119c..fac1f4b392 100644
--- a/doc/tools.md
+++ b/doc/tools.md
@@ -51,7 +51,7 @@ In */etc/fail2ban/jail.local* create a section for Friendica:
bantime = 900
filter = friendica
port = http,https
- logpath = /var/log/friend.log
+ logpath = /var/log/friendica.log
logencoding = utf-8
And create a filter definition in */etc/fail2ban/filter.d/friendica.conf*:
diff --git a/doc/translations.md b/doc/translations.md
index 23ac4a62d7..8b7077b6b1 100644
--- a/doc/translations.md
+++ b/doc/translations.md
@@ -24,6 +24,16 @@ For addons, we add support for a language when if we already support the languag
## Add new translation strings
+### Supported gettext version
+
+We currently support the gettext version 0.19.8.1 and actively check new translation strings with this version.
+
+If you don't use this version, it's possible that our checks fail (f.e. because of tiny differences at linebreaks).
+In case you do have a Docker environment, you can easily update the translations with the following command:
+```shell
+docker run --rm -v $PWD:/data -w /data friendicaci/transifex bin/run_xgettext.sh
+```
+
### Core
Once you have added new translation strings in your code changes, please run `bin/run_xgettext.sh` from the base Friendica directory and commit the updated `view/lang/C/messages.po` to your branch.
diff --git a/src/Console/Contact.php b/src/Console/Contact.php
index 37f3f056e4..d5f3c9923f 100644
--- a/src/Console/Contact.php
+++ b/src/Console/Contact.php
@@ -157,7 +157,7 @@ HELP;
$url = Probe::cleanURI($url);
- $contact = ContactModel::getByURLForUser($url, $user['uid']);
+ $contact = ContactModel::getByURL($url, null, [], $user['uid']);
if (!empty($contact)) {
throw new RuntimeException('Contact already exists');
}
diff --git a/src/Console/PostUpdate.php b/src/Console/PostUpdate.php
index 8bec14e276..702b127109 100644
--- a/src/Console/PostUpdate.php
+++ b/src/Console/PostUpdate.php
@@ -22,7 +22,7 @@
namespace Friendica\Console;
use Friendica\App;
-use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs;
use Friendica\Core\L10n;
use Friendica\Core\Update;
@@ -38,9 +38,9 @@ class PostUpdate extends \Asika\SimpleConsole\Console
*/
private $appMode;
/**
- * @var IManageConfigValues
+ * @var IManageKeyValuePairs
*/
- private $config;
+ private $keyValue;
/**
* @var L10n
*/
@@ -60,13 +60,13 @@ HELP;
return $help;
}
- public function __construct(App\Mode $appMode, IManageConfigValues $config, L10n $l10n, array $argv = null)
+ public function __construct(App\Mode $appMode, IManageKeyValuePairs $keyValue, L10n $l10n, array $argv = null)
{
parent::__construct($argv);
- $this->appMode = $appMode;
- $this->config = $config;
- $this->l10n = $l10n;
+ $this->appMode = $appMode;
+ $this->keyValue = $keyValue;
+ $this->l10n = $l10n;
}
protected function doExecute(): int
@@ -83,7 +83,7 @@ HELP;
$this->out($this->getHelp());
return 0;
} elseif ($reset_version) {
- $this->config->set('system', 'post_update_version', $reset_version);
+ $this->keyValue->set('post_update_version', $reset_version);
echo $this->l10n->t('Post update version number has been set to %s.', $reset_version) . "\n";
return 0;
}
diff --git a/src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php b/src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php
new file mode 100644
index 0000000000..64b317bf1a
--- /dev/null
+++ b/src/Core/KeyValueStorage/Capabilities/IManageKeyValuePairs.php
@@ -0,0 +1,64 @@
+.
+ *
+ */
+
+namespace Friendica\Core\KeyValueStorage\Capabilities;
+
+use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException;
+
+/**
+ * Interface for Friendica specific Key-Value pair storage
+ */
+interface IManageKeyValuePairs extends \ArrayAccess
+{
+ /**
+ * Get a particular value from the KeyValue Storage
+ *
+ * @param string $key The key to query
+ *
+ * @return mixed Stored value or null if it does not exist
+ *
+ * @throws KeyValueStoragePersistenceException In case the persistence layer throws errors
+ *
+ */
+ public function get(string $key);
+
+ /**
+ * Sets a value for a given key
+ *
+ * Note: Please do not store booleans - convert to 0/1 integer values!
+ *
+ * @param string $key The configuration key to set
+ * @param mixed $value The value to store
+ *
+ * @throws KeyValueStoragePersistenceException In case the persistence layer throws errors
+ */
+ public function set(string $key, $value): void;
+
+ /**
+ * Deletes the given key.
+ *
+ * @param string $key The configuration key to delete
+ *
+ * @throws KeyValueStoragePersistenceException In case the persistence layer throws errors
+ *
+ */
+ public function delete(string $key): void;
+}
diff --git a/src/Core/KeyValueStorage/Exceptions/KeyValueStoragePersistenceException.php b/src/Core/KeyValueStorage/Exceptions/KeyValueStoragePersistenceException.php
new file mode 100644
index 0000000000..ad04c33aea
--- /dev/null
+++ b/src/Core/KeyValueStorage/Exceptions/KeyValueStoragePersistenceException.php
@@ -0,0 +1,30 @@
+.
+ *
+ */
+
+namespace Friendica\Core\KeyValueStorage\Exceptions;
+
+class KeyValueStoragePersistenceException extends \RuntimeException
+{
+ public function __construct($message = "", \Throwable $previous = null)
+ {
+ parent::__construct($message, 500, $previous);
+ }
+}
diff --git a/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php
new file mode 100644
index 0000000000..169d27f69b
--- /dev/null
+++ b/src/Core/KeyValueStorage/Type/AbstractKeyValueStorage.php
@@ -0,0 +1,48 @@
+.
+ *
+ */
+
+namespace Friendica\Core\KeyValueStorage\Type;
+
+use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs;
+
+/**
+ * An abstract helper class for Key-Value storage classes
+ */
+abstract class AbstractKeyValueStorage implements IManageKeyValuePairs
+{
+ /** {@inheritDoc} */
+ public function get(string $key)
+ {
+ return $this->offsetGet($key);
+ }
+
+ /** {@inheritDoc} */
+ public function set(string $key, $value): void
+ {
+ $this->offsetSet($key, $value);
+ }
+
+ /** {@inheritDoc} */
+ public function delete(string $key): void
+ {
+ $this->offsetUnset($key);
+ }
+}
diff --git a/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php
new file mode 100644
index 0000000000..de8320c5ef
--- /dev/null
+++ b/src/Core/KeyValueStorage/Type/DBKeyValueStorage.php
@@ -0,0 +1,117 @@
+.
+ *
+ */
+
+namespace Friendica\Core\KeyValueStorage\Type;
+
+use Friendica\Core\Config\Util\ValueConversion;
+use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException;
+use Friendica\Database\Database;
+
+/**
+ * A Key-Value storage provider with DB as persistence layer
+ */
+class DBKeyValueStorage extends AbstractKeyValueStorage
+{
+ const DB_KEY_VALUE_TABLE = 'key-value';
+
+ /** @var Database */
+ protected $database;
+
+ public function __construct(Database $database)
+ {
+ $this->database = $database;
+ }
+
+ /** {@inheritDoc} */
+ public function offsetExists($offset): bool
+ {
+ try {
+ return $this->database->exists(self::DB_KEY_VALUE_TABLE, ['k' => $offset]);
+ } catch (\Exception $exception) {
+ throw new KeyValueStoragePersistenceException(sprintf('Cannot check storage with key %s', $offset), $exception);
+ }
+ }
+
+ /** {@inheritDoc} */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset)
+ {
+ try {
+ $result = $this->database->selectFirst(self::DB_KEY_VALUE_TABLE, ['v'], ['k' => $offset]);
+
+ if ($this->database->isResult($result)) {
+ $value = ValueConversion::toConfigValue($result['v']);
+
+ // just return it in case it is set
+ if (isset($value)) {
+ return $value;
+ }
+ }
+ } catch (\Exception $exception) {
+ throw new KeyValueStoragePersistenceException(sprintf('Cannot get value for key %s', $offset), $exception);
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($offset, $value)
+ {
+ try {
+ // We store our setting values in a string variable.
+ // So we have to do the conversion here so that the compare below works.
+ // The exception are array values.
+ $compare_value = (!is_array($value) ? (string)$value : $value);
+ $stored_value = $this->get($offset);
+
+ if (isset($stored_value) && ($stored_value === $compare_value)) {
+ return;
+ }
+
+ $dbValue = ValueConversion::toDbValue($value);
+
+ $return = $this->database->update(self::DB_KEY_VALUE_TABLE, [
+ 'v' => $dbValue,
+ 'updated_at' => time()
+ ], ['k' => $offset], true);
+
+ if (!$return) {
+ throw new \Exception(sprintf('database update failed: %s', $this->database->errorMessage()));
+ }
+ } catch (\Exception $exception) {
+ throw new KeyValueStoragePersistenceException(sprintf('Cannot set value for %s for key %s', $value, $offset), $exception);
+ }
+ }
+
+ /** {@inheritDoc} */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($offset)
+ {
+ try {
+ if (!$this->database->delete(self::DB_KEY_VALUE_TABLE, ['k' => $offset])) {
+ throw new \Exception(sprintf('database deletion failed: %s', $this->database->errorMessage()));
+ }
+ } catch (\Exception $exception) {
+ throw new KeyValueStoragePersistenceException(sprintf('Cannot delete value with key %s', $offset), $exception);
+ }
+ }
+}
diff --git a/src/Core/Update.php b/src/Core/Update.php
index 8ec96dc989..9e05c1b5bc 100644
--- a/src/Core/Update.php
+++ b/src/Core/Update.php
@@ -76,7 +76,7 @@ class Update
}
// The postupdate has to completed version 1288 for the new post views to take over
- $postupdate = DI::config()->get('system', 'post_update_version', self::NEW_TABLE_STRUCTURE_VERSION);
+ $postupdate = DI::keyValue()->get('post_update_version') ?? self::NEW_TABLE_STRUCTURE_VERSION;
if ($postupdate < self::NEW_TABLE_STRUCTURE_VERSION) {
$error = DI::l10n()->t('Updates from postupdate version %s are not supported. Please update at least to version 2021.01 and wait until the postupdate finished version 1383.', $postupdate);
if (DI::mode()->getExecutor() == Mode::INDEX) {
diff --git a/src/Core/Worker.php b/src/Core/Worker.php
index d6f97eed21..cbe6645294 100644
--- a/src/Core/Worker.php
+++ b/src/Core/Worker.php
@@ -89,9 +89,9 @@ class Worker
self::$process = $process;
// Kill stale processes every 5 minutes
- $last_cleanup = DI::config()->get('system', 'worker_last_cleaned', 0);
+ $last_cleanup = DI::keyValue()->get('worker_last_cleaned') ?? 0;
if (time() > ($last_cleanup + 300)) {
- DI::config()->set('system', 'worker_last_cleaned', time());
+ DI::keyValue()->set( 'worker_last_cleaned', time());
Worker\Cron::killStaleWorkers();
}
@@ -388,7 +388,7 @@ class Worker
$stamp = (float)microtime(true);
$condition = ["`id` = ? AND `next_try` < ?", $queue['id'], DateTimeFormat::utcNow()];
if (DBA::update('workerqueue', ['done' => true], $condition)) {
- DI::config()->set('system', 'last_worker_execution', DateTimeFormat::utcNow());
+ DI::keyValue()->set('last_worker_execution', DateTimeFormat::utcNow());
}
self::$db_duration = (microtime(true) - $stamp);
self::$db_duration_write += (microtime(true) - $stamp);
@@ -429,7 +429,7 @@ class Worker
$stamp = (float)microtime(true);
if (DBA::update('workerqueue', ['done' => true], ['id' => $queue['id']])) {
- DI::config()->set('system', 'last_worker_execution', DateTimeFormat::utcNow());
+ DI::keyValue()->set('last_worker_execution', DateTimeFormat::utcNow());
}
self::$db_duration = (microtime(true) - $stamp);
self::$db_duration_write += (microtime(true) - $stamp);
@@ -1422,7 +1422,7 @@ class Worker
$duration = max($start, $end) - min($start, $end);
// Quit when the last cron execution had been after the previous window
- $last_cron = DI::config()->get('system', 'last_cron_daily');
+ $last_cron = DI::keyValue()->get('last_cron_daily');
if ($last_cron + $duration > time()) {
Logger::info('The Daily cron had been executed recently', ['last' => date(DateTimeFormat::MYSQL, $last_cron), 'start' => date('H:i:s', $start), 'end' => date('H:i:s', $end)]);
return false;
diff --git a/src/Core/Worker/Daemon.php b/src/Core/Worker/Daemon.php
index 6fd64e4f59..7b4c358f1b 100644
--- a/src/Core/Worker/Daemon.php
+++ b/src/Core/Worker/Daemon.php
@@ -47,7 +47,7 @@ class Daemon
return true;
}
- $daemon_mode = DI::config()->get('system', 'worker_daemon_mode', false, true);
+ $daemon_mode = DI::keyValue()->get('worker_daemon_mode') ?? false;
if ($daemon_mode) {
return $daemon_mode;
}
@@ -93,11 +93,11 @@ class Daemon
}
// Check every minute if the daemon is running
- if (DI::config()->get('system', 'last_daemon_check', 0) + 60 > time()) {
+ if ((DI::keyValue()->get('last_daemon_check') ?? 0) + 60 > time()) {
return;
}
- DI::config()->set('system', 'last_daemon_check', time());
+ DI::keyValue()->set('last_daemon_check', time());
$pidfile = DI::config()->get('system', 'pidfile');
if (empty($pidfile)) {
diff --git a/src/DI.php b/src/DI.php
index bf2b5a2371..ecdf92530c 100644
--- a/src/DI.php
+++ b/src/DI.php
@@ -181,6 +181,11 @@ abstract class DI
return self::$dice->create(Core\Config\Capability\IManageConfigValues::class);
}
+ public static function keyValue(): Core\KeyValueStorage\Capabilities\IManageKeyValuePairs
+ {
+ return self::$dice->create(Core\KeyValueStorage\Capabilities\IManageKeyValuePairs::class);
+ }
+
/**
* @return Core\PConfig\Capability\IManagePersonalConfigValues
*/
diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php
index cdb5d4ef98..7de6799cfd 100644
--- a/src/Database/DBStructure.php
+++ b/src/Database/DBStructure.php
@@ -53,7 +53,7 @@ class DBStructure
throw new \Asika\SimpleConsole\CommandArgsException('The version number must be numeric');
}
- DI::config()->set('system', 'build', $version);
+ DI::keyValue()->set('build', $version);
echo DI::l10n()->t('The database version had been set to %s.', $version);
}
@@ -65,7 +65,7 @@ class DBStructure
*/
public static function dropTables(bool $execute)
{
- $postupdate = DI::config()->get('system', 'post_update_version', PostUpdate::VERSION);
+ $postupdate = DI::keyValue()->get('post_update_version') ?? PostUpdate::VERSION;
if ($postupdate < PostUpdate::VERSION) {
echo DI::l10n()->t('The post update is at version %d, it has to be at %d to safely drop the tables.', $postupdate, PostUpdate::VERSION);
return;
diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php
index e57d92ceb7..d54c3f2217 100644
--- a/src/Database/PostUpdate.php
+++ b/src/Database/PostUpdate.php
@@ -129,12 +129,12 @@ class PostUpdate
private static function update1297()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1297) {
+ if (DI::keyValue()->get('post_update_version') >= 1297) {
return true;
}
if (!DBStructure::existsTable('item-delivery-data')) {
- DI::config()->set('system', 'post_update_version', 1297);
+ DI::keyValue()->set('post_update_version', 1297);
return true;
}
@@ -154,7 +154,7 @@ class PostUpdate
Logger::info('Processed rows: ' . DBA::affectedRows());
- DI::config()->set('system', 'post_update_version', 1297);
+ DI::keyValue()->set('post_update_version', 1297);
Logger::info('Done');
@@ -169,7 +169,7 @@ class PostUpdate
private static function update1322()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1322) {
+ if (DI::keyValue()->get('post_update_version') >= 1322) {
return true;
}
@@ -188,7 +188,7 @@ class PostUpdate
}
DBA::close($contact);
- DI::config()->set('system', 'post_update_version', 1322);
+ DI::keyValue()->set('post_update_version', 1322);
Logger::info('Done');
@@ -204,16 +204,16 @@ class PostUpdate
private static function update1329()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1329) {
+ if (DI::keyValue()->get('post_update_version') >= 1329) {
return true;
}
if (!DBStructure::existsTable('item')) {
- DI::config()->set('system', 'post_update_version', 1329);
+ DI::keyValue()->set('post_update_version', 1329);
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1329_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1329_id') ?? 0;
Logger::info('Start', ['item' => $id]);
@@ -237,12 +237,12 @@ class PostUpdate
}
DBA::close($items);
- DI::config()->set('system', 'post_update_version_1329_id', $id);
+ DI::keyValue()->set('post_update_version_1329_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
if ($start_id == $id) {
- DI::config()->set('system', 'post_update_version', 1329);
+ DI::keyValue()->set('post_update_version', 1329);
Logger::info('Done');
return true;
}
@@ -259,16 +259,16 @@ class PostUpdate
private static function update1341()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1341) {
+ if (DI::keyValue()->get('post_update_version') >= 1341) {
return true;
}
if (!DBStructure::existsTable('item-content')) {
- DI::config()->set('system', 'post_update_version', 1342);
+ DI::keyValue()->set('post_update_version', 1342);
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1341_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1341_id') ?? 0;
Logger::info('Start', ['item' => $id]);
@@ -288,19 +288,19 @@ class PostUpdate
$id = $item['uri-id'];
++$rows;
if ($rows % 1000 == 0) {
- DI::config()->set('system', 'post_update_version_1341_id', $id);
+ DI::keyValue()->set('post_update_version_1341_id', $id);
}
}
DBA::close($items);
- DI::config()->set('system', 'post_update_version_1341_id', $id);
+ DI::keyValue()->set('post_update_version_1341_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
// When there are less than 1,000 items processed this means that we reached the end
// The other entries will then be processed with the regular functionality
if ($rows < 1000) {
- DI::config()->set('system', 'post_update_version', 1341);
+ DI::keyValue()->set('post_update_version', 1341);
Logger::info('Done');
return true;
}
@@ -317,16 +317,16 @@ class PostUpdate
private static function update1342()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1342) {
+ if (DI::keyValue()->get('post_update_version') >= 1342) {
return true;
}
if (!DBStructure::existsTable('term') || !DBStructure::existsTable('item-content')) {
- DI::config()->set('system', 'post_update_version', 1342);
+ DI::keyValue()->set('post_update_version', 1342);
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1342_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1342_id') ?? 0;
Logger::info('Start', ['item' => $id]);
@@ -364,19 +364,19 @@ class PostUpdate
$id = $term['tid'];
++$rows;
if ($rows % 1000 == 0) {
- DI::config()->set('system', 'post_update_version_1342_id', $id);
+ DI::keyValue()->set('post_update_version_1342_id', $id);
}
}
DBA::close($terms);
- DI::config()->set('system', 'post_update_version_1342_id', $id);
+ DI::keyValue()->set('post_update_version_1342_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
// When there are less than 1,000 items processed this means that we reached the end
// The other entries will then be processed with the regular functionality
if ($rows < 1000) {
- DI::config()->set('system', 'post_update_version', 1342);
+ DI::keyValue()->set('post_update_version', 1342);
Logger::info('Done');
return true;
}
@@ -393,16 +393,16 @@ class PostUpdate
private static function update1345()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1345) {
+ if (DI::keyValue()->get('post_update_version') >= 1345) {
return true;
}
if (!DBStructure::existsTable('item-delivery-data')) {
- DI::config()->set('system', 'post_update_version', 1345);
+ DI::keyValue()->set('post_update_version', 1345);
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1345_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1345_id') ?? 0;
Logger::info('Start', ['item' => $id]);
@@ -427,14 +427,14 @@ class PostUpdate
}
DBA::close($deliveries);
- DI::config()->set('system', 'post_update_version_1345_id', $id);
+ DI::keyValue()->set('post_update_version_1345_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
// When there are less than 100 items processed this means that we reached the end
// The other entries will then be processed with the regular functionality
if ($rows < 100) {
- DI::config()->set('system', 'post_update_version', 1345);
+ DI::keyValue()->set('post_update_version', 1345);
Logger::info('Done');
return true;
}
@@ -476,16 +476,16 @@ class PostUpdate
private static function update1346()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1346) {
+ if (DI::keyValue()->get('post_update_version') >= 1346) {
return true;
}
if (!DBStructure::existsTable('term')) {
- DI::config()->set('system', 'post_update_version', 1346);
+ DI::keyValue()->set('post_update_version', 1346);
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1346_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1346_id') ?? 0;
Logger::info('Start', ['item' => $id]);
@@ -514,19 +514,19 @@ class PostUpdate
$id = $term['oid'];
++$rows;
if ($rows % 100 == 0) {
- DI::config()->set('system', 'post_update_version_1346_id', $id);
+ DI::keyValue()->set('post_update_version_1346_id', $id);
}
}
DBA::close($terms);
- DI::config()->set('system', 'post_update_version_1346_id', $id);
+ DI::keyValue()->set('post_update_version_1346_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
// When there are less than 10 items processed this means that we reached the end
// The other entries will then be processed with the regular functionality
if ($rows < 10) {
- DI::config()->set('system', 'post_update_version', 1346);
+ DI::keyValue()->set('post_update_version', 1346);
Logger::info('Done');
return true;
}
@@ -544,16 +544,16 @@ class PostUpdate
private static function update1347()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1347) {
+ if (DI::keyValue()->get('post_update_version') >= 1347) {
return true;
}
if (!DBStructure::existsTable('item-activity') || !DBStructure::existsTable('item')) {
- DI::config()->set('system', 'post_update_version', 1347);
+ DI::keyValue()->set('post_update_version', 1347);
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1347_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1347_id') ?? 0;
Logger::info('Start', ['item' => $id]);
@@ -588,12 +588,12 @@ class PostUpdate
}
DBA::close($items);
- DI::config()->set('system', 'post_update_version_1347_id', $id);
+ DI::keyValue()->set('post_update_version_1347_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
if ($start_id == $id) {
- DI::config()->set('system', 'post_update_version', 1347);
+ DI::keyValue()->set('post_update_version', 1347);
Logger::info('Done');
return true;
}
@@ -611,11 +611,11 @@ class PostUpdate
private static function update1348()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1348) {
+ if (DI::keyValue()->get('post_update_version') >= 1348) {
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1348_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1348_id') ?? 0;
Logger::info('Start', ['contact' => $id]);
@@ -641,12 +641,12 @@ class PostUpdate
}
DBA::close($contacts);
- DI::config()->set('system', 'post_update_version_1348_id', $id);
+ DI::keyValue()->set('post_update_version_1348_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
if ($start_id == $id) {
- DI::config()->set('system', 'post_update_version', 1348);
+ DI::keyValue()->set('post_update_version', 1348);
Logger::info('Done');
return true;
}
@@ -664,11 +664,11 @@ class PostUpdate
private static function update1349()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1349) {
+ if (DI::keyValue()->get('post_update_version') >= 1349) {
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1349_id', '');
+ $id = DI::keyValue()->get('post_update_version_1349_id') ?? '';
Logger::info('Start', ['apcontact' => $id]);
@@ -694,12 +694,12 @@ class PostUpdate
}
DBA::close($apcontacts);
- DI::config()->set('system', 'post_update_version_1349_id', $id);
+ DI::keyValue()->set('post_update_version_1349_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
if ($start_id == $id) {
- DI::config()->set('system', 'post_update_version', 1349);
+ DI::keyValue()->set('post_update_version', 1349);
Logger::info('Done');
return true;
}
@@ -717,7 +717,7 @@ class PostUpdate
private static function update1383()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1383) {
+ if (DI::keyValue()->get('post_update_version') >= 1383) {
return true;
}
@@ -743,7 +743,7 @@ class PostUpdate
}
DBA::close($photos);
- DI::config()->set('system', 'post_update_version', 1383);
+ DI::keyValue()->set('post_update_version', 1383);
Logger::info('Done', ['deleted' => $deleted]);
return true;
}
@@ -758,7 +758,7 @@ class PostUpdate
private static function update1384()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1384) {
+ if (DI::keyValue()->get('post_update_version') >= 1384) {
return true;
}
@@ -788,7 +788,7 @@ class PostUpdate
Logger::info('Processed', ['rows' => $rows]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1384);
+ DI::keyValue()->set('post_update_version', 1384);
Logger::info('Done');
return true;
}
@@ -806,12 +806,12 @@ class PostUpdate
private static function update1400()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1400) {
+ if (DI::keyValue()->get('post_update_version') >= 1400) {
return true;
}
if (!DBStructure::existsTable('item')) {
- DI::config()->set('system', 'post_update_version', 1400);
+ DI::keyValue()->set('post_update_version', 1400);
return true;
}
@@ -835,7 +835,7 @@ class PostUpdate
Logger::info('Processed', ['rows' => $rows]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1400);
+ DI::keyValue()->set('post_update_version', 1400);
Logger::info('Done');
return true;
}
@@ -853,7 +853,7 @@ class PostUpdate
private static function update1424()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1424) {
+ if (DI::keyValue()->get('post_update_version') >= 1424) {
return true;
}
@@ -877,7 +877,7 @@ class PostUpdate
Logger::info('Processed', ['rows' => $rows]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1424);
+ DI::keyValue()->set('post_update_version', 1424);
Logger::info('Done');
return true;
}
@@ -895,12 +895,12 @@ class PostUpdate
private static function update1425()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1425) {
+ if (DI::keyValue()->get('post_update_version') >= 1425) {
return true;
}
if (!DBStructure::existsTable('fcontact')) {
- DI::config()->set('system', 'post_update_version', 1425);
+ DI::keyValue()->set('post_update_version', 1425);
return true;
}
@@ -929,7 +929,7 @@ class PostUpdate
Logger::info('Processed', ['rows' => $rows]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1425);
+ DI::keyValue()->set('post_update_version', 1425);
Logger::info('Done');
return true;
}
@@ -947,7 +947,7 @@ class PostUpdate
private static function update1426()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1426) {
+ if (DI::keyValue()->get('post_update_version') >= 1426) {
return true;
}
@@ -976,7 +976,7 @@ class PostUpdate
Logger::info('Processed', ['rows' => $rows]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1426);
+ DI::keyValue()->set('post_update_version', 1426);
Logger::info('Done');
return true;
}
@@ -994,7 +994,7 @@ class PostUpdate
private static function update1427()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1427) {
+ if (DI::keyValue()->get('post_update_version') >= 1427) {
return true;
}
@@ -1023,7 +1023,7 @@ class PostUpdate
Logger::info('Processed', ['rows' => $rows]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1427);
+ DI::keyValue()->set('post_update_version', 1427);
Logger::info('Done');
return true;
}
@@ -1041,16 +1041,16 @@ class PostUpdate
private static function update1452()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1452) {
+ if (DI::keyValue()->get('post_update_version') >= 1452) {
return true;
}
if (!DBStructure::existsTable('conversation')) {
- DI::config()->set('system', 'post_update_version', 1452);
+ DI::keyValue()->set('post_update_version', 1452);
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1452_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1452_id') ?? 0;
Logger::info('Start', ['uri-id' => $id]);
@@ -1089,12 +1089,12 @@ class PostUpdate
DBA::close($conversations);
- DI::config()->set('system', 'post_update_version_1452_id', $id);
+ DI::keyValue()->set('post_update_version_1452_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id, 'last-received' => $received]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1452);
+ DI::keyValue()->set('post_update_version', 1452);
Logger::info('Done');
return true;
}
@@ -1113,7 +1113,7 @@ class PostUpdate
private static function update1483()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1483) {
+ if (DI::keyValue()->get('post_update_version') >= 1483) {
return true;
}
@@ -1129,7 +1129,7 @@ class PostUpdate
}
DBA::close($posts);
- DI::config()->set('system', 'post_update_version', 1483);
+ DI::keyValue()->set('post_update_version', 1483);
Logger::info('Done');
return true;
}
@@ -1144,11 +1144,11 @@ class PostUpdate
private static function update1484()
{
// Was the script completed?
- if (DI::config()->get('system', 'post_update_version') >= 1484) {
+ if (DI::keyValue()->get('post_update_version') >= 1484) {
return true;
}
- $id = DI::config()->get('system', 'post_update_version_1484_id', 0);
+ $id = DI::keyValue()->get('post_update_version_1484_id') ?? 0;
Logger::info('Start', ['id' => $id]);
@@ -1172,12 +1172,12 @@ class PostUpdate
}
DBA::close($contacts);
- DI::config()->set('system', 'post_update_version_1484_id', $id);
+ DI::keyValue()->set('post_update_version_1484_id', $id);
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
if ($rows <= 100) {
- DI::config()->set('system', 'post_update_version', 1484);
+ DI::keyValue()->set('post_update_version', 1484);
Logger::info('Done');
return true;
}
diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index e928df7f63..1bf2f17910 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -624,7 +624,7 @@ class Contact
public static function getPublicAndUserContactID(int $cid, int $uid): array
{
// We have to use the legacy function as long as the post update hasn't finished
- if (DI::config()->get('system', 'post_update_version') < 1427) {
+ if (DI::keyValue()->get('post_update_version') < 1427) {
return self::legacyGetPublicAndUserContactID($cid, $uid);
}
@@ -2953,7 +2953,7 @@ class Contact
}
if (($network != '') && ($ret['network'] != $network)) {
- Logger::notice('Expected network ' . $network . ' does not match actual network ' . $ret['network']);
+ $result['message'] = DI::l10n()->t('Expected network %s does not match actual network %s', $network, $ret['network']);
return $result;
}
diff --git a/src/Model/GServer.php b/src/Model/GServer.php
index b0a9dd5c9a..6945fab3e0 100644
--- a/src/Model/GServer.php
+++ b/src/Model/GServer.php
@@ -2145,7 +2145,7 @@ class GServer
*/
private static function discoverFederation()
{
- $last = DI::config()->get('poco', 'last_federation_discovery');
+ $last = DI::keyValue()->get('poco_last_federation_discovery');
if ($last) {
$next = $last + (24 * 60 * 60);
@@ -2189,7 +2189,7 @@ class GServer
}
}
- DI::config()->set('poco', 'last_federation_discovery', time());
+ DI::keyValue()->set('poco_last_federation_discovery', time());
}
/**
diff --git a/src/Model/Item.php b/src/Model/Item.php
index bb4400a860..753b3d6dac 100644
--- a/src/Model/Item.php
+++ b/src/Model/Item.php
@@ -3016,6 +3016,8 @@ class Item
$item['hashtags'] = $tags['hashtags'];
$item['mentions'] = $tags['mentions'];
+ $item['body'] = preg_replace("#\s*\[attachment .*?].*?\[/attachment]\s*#ism", "\n", $item['body']);
+
if (!$is_preview) {
$item['body'] = Post\Media::removeFromEndOfBody($item['body'] ?? '');
}
@@ -3065,8 +3067,6 @@ class Item
$attachments = Post\Media::splitAttachments($item['uri-id'], $shared_links, $item['has-media'] ?? false);
$item['body'] = self::replaceVisualAttachments($attachments, $item['body'] ?? '');
- $item['body'] = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", "\n", $item['body']);
-
self::putInCache($item);
$item['body'] = $body;
$s = $item["rendered-html"];
@@ -3166,7 +3166,7 @@ class Item
],
]);
}
-
+
/**
* Check if the body contains a link
diff --git a/src/Module/Admin/DBSync.php b/src/Module/Admin/DBSync.php
index bb1fa90330..70d835fcd3 100644
--- a/src/Module/Admin/DBSync.php
+++ b/src/Module/Admin/DBSync.php
@@ -42,7 +42,7 @@ class DBSync extends BaseAdmin
switch ($action) {
case 'mark':
if ($update) {
- DI::config()->set('database', 'update_' . $update, 'success');
+ DI::keyValue()->set('database_update_' . $update, 'success');
$curr = DI::config()->get('system', 'build');
if (intval($curr) == $update) {
DI::config()->set('system', 'build', intval($curr) + 1);
@@ -76,13 +76,13 @@ class DBSync extends BaseAdmin
$o = DI::l10n()->t("Executing %s failed with error: %s", $func, $retval);
} elseif ($retval === Update::SUCCESS) {
$o = DI::l10n()->t('Update %s was successfully applied.', $func);
- DI::config()->set('database', $func, 'success');
+ DI::keyValue()->set(sprintf('database_%s', $func), 'success');
} else {
$o = DI::l10n()->t('Update %s did not return a status. Unknown if it succeeded.', $func);
}
} else {
$o = DI::l10n()->t('There was no additional update function %s that needed to be called.', $func) . "
";
- DI::config()->set('database', $func, 'success');
+ DI::keyValue()->set(sprintf('database_%s', $func), 'success');
}
return $o;
diff --git a/src/Module/Admin/Summary.php b/src/Module/Admin/Summary.php
index d27a9b011b..46f9d440bd 100644
--- a/src/Module/Admin/Summary.php
+++ b/src/Module/Admin/Summary.php
@@ -98,7 +98,7 @@ class Summary extends BaseAdmin
$warningtext[] = DI::l10n()->t('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.)');
}
- $last_worker_call = DI::config()->get('system', 'last_worker_execution', false);
+ $last_worker_call = DI::keyValue()->get('last_worker_execution');
if (!$last_worker_call) {
$warningtext[] = DI::l10n()->t('The worker was never executed. Please check your database structure!');
} elseif ((strtotime(DateTimeFormat::utcNow()) - strtotime($last_worker_call)) > 60 * 60) {
diff --git a/src/Module/Friendica.php b/src/Module/Friendica.php
index 37bd69da49..f21b85fc45 100644
--- a/src/Module/Friendica.php
+++ b/src/Module/Friendica.php
@@ -42,6 +42,7 @@ class Friendica extends BaseModule
protected function content(array $request = []): string
{
$config = DI::config();
+ $keyValue = DI::keyValue();
$visibleAddonList = Addon::getVisibleList();
if (!empty($visibleAddonList)) {
@@ -100,7 +101,7 @@ class Friendica extends BaseModule
'' . App::VERSION . '',
DI::baseUrl()->get(),
'' . $config->get('system', 'build') . '/' . DB_UPDATE_VERSION . '',
- '' . $config->get('system', 'post_update_version') . '/' . PostUpdate::VERSION . ''),
+ '' . $keyValue->get('post_update_version') . '/' . PostUpdate::VERSION . ''),
'friendica' => DI::l10n()->t('Please visit Friendi.ca to learn more about the Friendica project.'),
'bugs' => DI::l10n()->t('Bug reports and issues: please visit') . ' ' . '' . DI::l10n()->t('the bugtracker at github') . '',
'info' => DI::l10n()->t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'),
diff --git a/src/Network/HTTPClient/Client/HttpClient.php b/src/Network/HTTPClient/Client/HttpClient.php
index 32a1a22fc2..76af184975 100644
--- a/src/Network/HTTPClient/Client/HttpClient.php
+++ b/src/Network/HTTPClient/Client/HttpClient.php
@@ -69,7 +69,7 @@ class HttpClient implements ICanSendHttpRequests
$this->logger->debug('Request start.', ['url' => $url, 'method' => $method]);
$host = parse_url($url, PHP_URL_HOST);
- if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A + DNS_AAAA)) {
+ 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();
return CurlResult::createErrorCurl($url);
diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php
index 94f002805b..055a9b4354 100644
--- a/src/Worker/Cron.php
+++ b/src/Worker/Cron.php
@@ -37,7 +37,7 @@ class Cron
{
$a = DI::app();
- $last = DI::config()->get('system', 'last_cron');
+ $last = DI::keyValue()->get('last_cron');
$poll_interval = intval(DI::config()->get('system', 'cron_interval'));
@@ -84,7 +84,7 @@ class Cron
Worker::add(Worker::PRIORITY_LOW, 'PostUpdate');
// Hourly cron calls
- if (DI::config()->get('system', 'last_cron_hourly', 0) + 3600 < time()) {
+ if ((DI::keyValue()->get('last_cron_hourly') ?? 0) + 3600 < time()) {
// Update trending tags cache for the community page
@@ -105,7 +105,7 @@ class Cron
// Clear cache entries
Worker::add(Worker::PRIORITY_LOW, 'ClearCache');
- DI::config()->set('system', 'last_cron_hourly', time());
+ DI::keyValue()->set('last_cron_hourly', time());
}
// Daily maintenance cron calls
@@ -145,12 +145,12 @@ class Cron
// Resubscribe to relay servers
Relay::reSubscribe();
- DI::config()->set('system', 'last_cron_daily', time());
+ DI::keyValue()->set('last_cron_daily', time());
}
Logger::notice('end');
- DI::config()->set('system', 'last_cron', time());
+ DI::keyValue()->set('last_cron', time());
}
/**
diff --git a/src/Worker/PullDirectory.php b/src/Worker/PullDirectory.php
index 8a22e504c0..d174d11f3e 100644
--- a/src/Worker/PullDirectory.php
+++ b/src/Worker/PullDirectory.php
@@ -45,7 +45,7 @@ class PullDirectory
return;
}
- $now = (int)DI::config()->get('system', 'last-directory-sync', 0);
+ $now = (int)(DI::keyValue()->get('last-directory-sync') ?? 0);
Logger::info('Synchronization started.', ['now' => $now, 'directory' => $directory]);
@@ -64,7 +64,7 @@ class PullDirectory
$result = Contact::addByUrls($contacts['results']);
$now = $contacts['now'] ?? 0;
- DI::config()->set('system', 'last-directory-sync', $now);
+ DI::keyValue()->set('last-directory-sync', $now);
Logger::info('Synchronization ended', ['now' => $now, 'count' => $result['count'], 'added' => $result['added'], 'updated' => $result['updated'], 'unchanged' => $result['unchanged'], 'directory' => $directory]);
}
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index 1d573fa87e..25e416d508 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', 1504);
+ define('DB_UPDATE_VERSION', 1505);
}
return [
@@ -889,6 +889,17 @@ return [
"uid" => ["uid"],
]
],
+ "key-value" => [
+ "comment" => "A key value storage",
+ "fields" => [
+ "k" => ["type" => "varbinary(50)", "not null" => "1", "primary" => "1", "comment" => ""],
+ "v" => ["type" => "mediumtext", "comment" => ""],
+ "updated_at" => ["type" => "int unsigned", "not null" => "1", "comment" => "timestamp of the last update"],
+ ],
+ "indexes" => [
+ "PRIMARY" => ["k"],
+ ],
+ ],
"locks" => [
"comment" => "",
"fields" => [
diff --git a/static/dependencies.config.php b/static/dependencies.config.php
index a4c52e0043..116874445b 100644
--- a/static/dependencies.config.php
+++ b/static/dependencies.config.php
@@ -245,6 +245,9 @@ return [
['getBackend', [], Dice::CHAIN_CALL],
],
],
+ \Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs::class => [
+ 'instanceOf' => \Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage::class,
+ ],
Network\HTTPClient\Capability\ICanSendHttpRequests::class => [
'instanceOf' => Network\HTTPClient\Factory\HttpClient::class,
'call' => [
diff --git a/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php
new file mode 100644
index 0000000000..1492c3de51
--- /dev/null
+++ b/tests/src/Core/KeyValueStorage/DBKeyValueStorageTest.php
@@ -0,0 +1,96 @@
+.
+ *
+ */
+
+namespace Friendica\Test\src\Core\KeyValueStorage;
+
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs;
+use Friendica\Core\KeyValueStorage\Type\DBKeyValueStorage;
+use Friendica\Database\Database;
+use Friendica\Database\Definition\DbaDefinition;
+use Friendica\Database\Definition\ViewDefinition;
+use Friendica\Test\DatabaseTestTrait;
+use Friendica\Test\Util\Database\StaticDatabase;
+use Friendica\Util\BasePath;
+use Friendica\Util\Profiler;
+
+class DBKeyValueStorageTest extends KeyValueStorageTest
+{
+ use DatabaseTestTrait;
+
+ /** @var Database */
+ protected $database;
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ $this->setUpDb();
+ }
+
+ protected function tearDown(): void
+ {
+ parent::tearDown();
+
+ $this->tearDownDb();
+ }
+
+ public function getInstance(): IManageKeyValuePairs
+ {
+ $cache = new Cache();
+ $cache->set('database', 'disable_pdo', true);
+
+ $basePath = new BasePath(dirname(__FILE__, 5), $_SERVER);
+
+ $this->database = new StaticDatabase($cache, new Profiler($cache), (new DbaDefinition($basePath->getPath()))->load(), (new ViewDefinition($basePath->getPath()))->load());
+ $this->database->setTestmode(true);
+
+ return new DBKeyValueStorage($this->database);
+ }
+
+ /** @dataProvider dataTests */
+ public function testUpdatedAt($k, $v)
+ {
+ $instance = $this->getInstance();
+
+ $instance->set($k, $v);
+
+ self::assertEquals($v, $instance->get($k));
+ self::assertEquals($v, $instance[$k]);
+
+ $entry = $this->database->selectFirst(DBKeyValueStorage::DB_KEY_VALUE_TABLE, ['updated_at'], ['k' => $k]);
+ self::assertNotEmpty($entry);
+
+ $updateAt = $entry['updated_at'];
+
+ $instance->set($k, 'another_value');
+
+ self::assertEquals('another_value', $instance->get($k));
+ self::assertEquals('another_value', $instance[$k]);
+
+ $entry = $this->database->selectFirst(DBKeyValueStorage::DB_KEY_VALUE_TABLE, ['updated_at'], ['k' => $k]);
+ self::assertNotEmpty($entry);
+
+ $updateAtAfter = $entry['updated_at'];
+
+ self::assertLessThanOrEqual($updateAt, $updateAtAfter);
+ }
+}
diff --git a/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php
new file mode 100644
index 0000000000..b3aee20f59
--- /dev/null
+++ b/tests/src/Core/KeyValueStorage/KeyValueStorageTest.php
@@ -0,0 +1,105 @@
+.
+ *
+ */
+
+namespace Friendica\Test\src\Core\KeyValueStorage;
+
+use Friendica\Core\KeyValueStorage\Capabilities\IManageKeyValuePairs;
+use Friendica\Test\MockedTest;
+
+abstract class KeyValueStorageTest extends MockedTest
+{
+ abstract public function getInstance(): IManageKeyValuePairs;
+
+ public function testInstance()
+ {
+ $instance = $this->getInstance();
+
+ self::assertInstanceOf(IManageKeyValuePairs::class, $instance);
+ }
+
+ public function dataTests(): array
+ {
+ return [
+ 'string' => ['k' => 'data', 'v' => 'it'],
+ 'boolTrue' => ['k' => 'data', 'v' => true],
+ 'boolFalse' => ['k' => 'data', 'v' => false],
+ 'integer' => ['k' => 'data', 'v' => 235],
+ 'decimal' => ['k' => 'data', 'v' => 2.456],
+ 'array' => ['k' => 'data', 'v' => ['1', 2, '3', true, false]],
+ 'boolIntTrue' => ['k' => 'data', 'v' => 1],
+ 'boolIntFalse' => ['k' => 'data', 'v' => 0],
+ ];
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testGetSetDelete($k, $v)
+ {
+ $instance = $this->getInstance();
+
+ $instance->set($k, $v);
+
+ self::assertEquals($v, $instance->get($k));
+ self::assertEquals($v, $instance[$k]);
+
+ $instance->delete($k);
+
+ self::assertNull($instance->get($k));
+ self::assertNull($instance[$k]);
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testSetOverride($k, $v)
+ {
+ $instance = $this->getInstance();
+
+ $instance->set($k, $v);
+
+ self::assertEquals($v, $instance->get($k));
+ self::assertEquals($v, $instance[$k]);
+
+ $instance->set($k, 'another_value');
+
+ self::assertEquals('another_value', $instance->get($k));
+ self::assertEquals('another_value', $instance[$k]);
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testOffsetSetDelete($k, $v)
+ {
+ $instance = $this->getInstance();
+
+ $instance[$k] = $v;
+
+ self::assertEquals($v, $instance->get($k));
+ self::assertEquals($v, $instance[$k]);
+
+ unset($instance[$k]);
+
+ self::assertNull($instance->get($k));
+ self::assertNull($instance[$k]);
+ }
+}
diff --git a/tests/src/Core/Lock/DatabaseLockDriverTest.php b/tests/src/Core/Lock/DatabaseLockDriverTest.php
index bd4cb9cc9b..70c5f37643 100644
--- a/tests/src/Core/Lock/DatabaseLockDriverTest.php
+++ b/tests/src/Core/Lock/DatabaseLockDriverTest.php
@@ -21,15 +21,16 @@
namespace Friendica\Test\src\Core\Lock;
+use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Lock\Type\DatabaseLock;
-use Friendica\Core\Config\Factory\Config;
-use Friendica\DI;
+use Friendica\Database\Database;
+use Friendica\Database\Definition\DbaDefinition;
+use Friendica\Database\Definition\ViewDefinition;
use Friendica\Test\DatabaseTestTrait;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Test\Util\VFSTrait;
+use Friendica\Util\BasePath;
use Friendica\Util\Profiler;
-use Mockery;
-use Psr\Log\NullLogger;
class DatabaseLockDriverTest extends LockTest
{
@@ -38,6 +39,9 @@ class DatabaseLockDriverTest extends LockTest
protected $pid = 123;
+ /** @var Database */
+ protected $database;
+
protected function setUp(): void
{
$this->setUpVfsDir();
@@ -49,7 +53,15 @@ class DatabaseLockDriverTest extends LockTest
protected function getInstance()
{
- return new DatabaseLock(DI::dba(), $this->pid);
+ $cache = new Cache();
+ $cache->set('database', 'disable_pdo', true);
+
+ $basePath = new BasePath(dirname(__FILE__, 5), $_SERVER);
+
+ $this->database = new StaticDatabase($cache, new Profiler($cache), (new DbaDefinition($basePath->getPath()))->load(), (new ViewDefinition($basePath->getPath()))->load());
+ $this->database->setTestmode(true);
+
+ return new DatabaseLock($this->database, $this->pid);
}
protected function tearDown(): void
diff --git a/update.php b/update.php
index d963546e4b..f8697554f5 100644
--- a/update.php
+++ b/update.php
@@ -982,7 +982,7 @@ function update_1429()
return Update::FAILED;
}
- DI::config()->set('system', 'post_update_version', 1423);
+ DI::keyValue()->set('post_update_version', 1423);
return Update::SUCCESS;
}
@@ -1145,3 +1145,33 @@ function update_1502()
DBA::e("UPDATE `pconfig` SET `cat` = 'calendar' WHERE `k` = 'first_day_of_week'");
return Update::SUCCESS;
}
+
+function update_1505()
+{
+ $conditions = [
+ "((`cat` = ?) AND ((`k` LIKE ?) OR (`k` = ?) OR (`k` LIKE ?) OR (`k` = ?))) OR " .
+ "((`cat` != ?) AND (`k` LIKE ?)) OR " .
+ "((`cat` = ?) AND (`k` LIKE ?))",
+ "system",
+ "post_update_%",
+ "worker_last_cleaned",
+ "last%",
+ "worker_daemon_mode",
+ "system",
+ "last_%",
+ "database",
+ "update_%",
+ ];
+
+ $postUpdateEntries = DBA::selectToArray('config', ['cat', 'k', 'v'], $conditions);
+
+ foreach ($postUpdateEntries as $postUpdateEntry) {
+ if ($postUpdateEntry['cat'] === 'system') {
+ DI::keyValue()->set($postUpdateEntry['k'], $postUpdateEntry['v']);
+ } else {
+ DI::keyValue()->set(sprintf('%s_%s', $postUpdateEntry['cat'], $postUpdateEntry['k']), $postUpdateEntry['v']);
+ }
+ }
+
+ return DBA::delete('config', $conditions) ? Update::SUCCESS : Update::FAILED;
+}
diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po
index b8748488f2..1872ad586d 100644
--- a/view/lang/C/messages.po
+++ b/view/lang/C/messages.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2023.03-dev\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-12-30 21:30+0000\n"
+"POT-Creation-Date: 2022-12-29 20:29+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -2898,6 +2898,11 @@ msgid ""
"credentials in your Settings -> Social Networks page."
msgstr ""
+#: src/Model/Contact.php:2956
+#, php-format
+msgid "Expected network %s does not match actual network %s"
+msgstr ""
+
#: src/Model/Contact.php:2973
msgid "The profile address specified does not provide adequate information."
msgstr ""
diff --git a/view/lang/ja/messages.po b/view/lang/ja/messages.po
index 2b3ecfe4ed..d98e4d959e 100644
--- a/view/lang/ja/messages.po
+++ b/view/lang/ja/messages.po
@@ -3030,7 +3030,7 @@ msgstr "フォロワー"
#: src/BaseModule.php:219 src/Content/Widget.php:239
#: src/Module/Contact.php:861
msgid "Following"
-msgstr "以下"
+msgstr "フォロー中"
#: src/BaseModule.php:224 src/Content/Widget.php:240
#: src/Module/Contact.php:862
@@ -3810,7 +3810,7 @@ msgstr ""
#: src/Content/Widget/CalendarExport.php:54
msgid "Export"
-msgstr "輸出する"
+msgstr "エクスポート"
#: src/Content/Widget/CalendarExport.php:55
msgid "Export calendar as ical"
diff --git a/view/lang/ja/strings.php b/view/lang/ja/strings.php
index 454b3bbf5d..a1d2803e12 100644
--- a/view/lang/ja/strings.php
+++ b/view/lang/ja/strings.php
@@ -675,7 +675,7 @@ $a->strings['Page not found.'] = 'ページが見つかりません。';
$a->strings['The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it.'] = 'フォームセキュリティトークンが正しくありませんでした。これは、フォームを送信する前にフォームが長時間(3時間以上)開かれたために発生した可能性があります。';
$a->strings['All contacts'] = 'すべてのコンタクト';
$a->strings['Followers'] = 'フォロワー';
-$a->strings['Following'] = '以下';
+$a->strings['Following'] = 'フォロー中';
$a->strings['Mutual friends'] = '共通の友人';
$a->strings['Could not find any unarchived contact entry for this URL (%s)'] = 'このURL( %s )のアーカイブされていないコンタクトエントリが見つかりませんでした';
$a->strings['The contact entries have been archived'] = 'コンタクトエントリがアーカイブされました';
@@ -837,7 +837,7 @@ $a->strings['%d contact in common'] = [
];
$a->strings['Archives'] = 'アーカイブ';
$a->strings['News'] = 'ニュース';
-$a->strings['Export'] = '輸出する';
+$a->strings['Export'] = 'エクスポート';
$a->strings['Export calendar as ical'] = 'カレンダーをicalとしてエクスポート';
$a->strings['Export calendar as csv'] = 'カレンダーをcsvとしてエクスポート';
$a->strings['No contacts'] = 'コンタクトなし';
diff --git a/view/theme/frio/templates/mail_list.tpl b/view/theme/frio/templates/mail_list.tpl
index bfc21aabaf..264c689c90 100644
--- a/view/theme/frio/templates/mail_list.tpl
+++ b/view/theme/frio/templates/mail_list.tpl
@@ -11,7 +11,15 @@