Merge remote-tracking branch 'upstream/develop' into move-delivery

This commit is contained in:
Michael 2022-12-30 21:40:09 +00:00
commit 4eceb2d26f
37 changed files with 712 additions and 132 deletions

View File

@ -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);

View File

@ -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
--

View File

@ -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 |

View File

@ -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)

View File

@ -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*:

View File

@ -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.

View File

@ -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');
}

View File

@ -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;
}

View File

@ -0,0 +1,64 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\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;
}

View File

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Core\KeyValueStorage\Exceptions;
class KeyValueStoragePersistenceException extends \RuntimeException
{
public function __construct($message = "", \Throwable $previous = null)
{
parent::__construct($message, 500, $previous);
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\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);
}
}

View File

@ -0,0 +1,117 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\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);
}
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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)) {

View File

@ -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
*/

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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());
}
/**

View File

@ -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

View File

@ -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) . "<br />";
DI::config()->set('database', $func, 'success');
DI::keyValue()->set(sprintf('database_%s', $func), 'success');
}
return $o;

View File

@ -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) {

View File

@ -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
'<strong>' . App::VERSION . '</strong>',
DI::baseUrl()->get(),
'<strong>' . $config->get('system', 'build') . '/' . DB_UPDATE_VERSION . '</strong>',
'<strong>' . $config->get('system', 'post_update_version') . '/' . PostUpdate::VERSION . '</strong>'),
'<strong>' . $keyValue->get('post_update_version') . '/' . PostUpdate::VERSION . '</strong>'),
'friendica' => DI::l10n()->t('Please visit <a href="https://friendi.ca">Friendi.ca</a> to learn more about the Friendica project.'),
'bugs' => DI::l10n()->t('Bug reports and issues: please visit') . ' ' . '<a href="https://github.com/friendica/friendica/issues?state=open">' . DI::l10n()->t('the bugtracker at github') . '</a>',
'info' => DI::l10n()->t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'),

View File

@ -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);

View File

@ -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());
}
/**

View File

@ -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]);
}

View File

@ -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" => [

View File

@ -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' => [

View File

@ -0,0 +1,96 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\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);
}
}

View File

@ -0,0 +1,105 @@
<?php
/**
* @copyright Copyright (C) 2010-2022, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\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]);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""

View File

@ -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"

View File

@ -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'] = 'コンタクトなし';

View File

@ -11,7 +11,15 @@
<div class="media-body">
<div class="text-muted time ago pull-right" title="{{$date}}">{{$ago}}</div>
<h4 class="media-heading">{{$from_name}}</h4>
<h4 class="media-heading">
{{if !$seen}}
<strong>
{{/if}}
<a href="message/{{$id}}">{{$from_name}}</a>
{{if !$seen}}
</strong>
{{/if}}
</h4>
<div class="mail-list-subject">
<a href="message/{{$id}}">
{{if !$seen}}
@ -21,7 +29,8 @@
{{if !$seen}}
</strong>
{{/if}}
</a></div>
</a>
</div>
<a href="message/dropconv/{{$id}}" onclick="return confirmDelete();" title="{{$delete}}" class="pull-right" onmouseover="imgbright(this);" onmouseout="imgdull(this);">
<i class="faded-icon fa fa-trash"></i>
</a>