Merge branch 'phpstan-level-1' into phpstan-level-1-in-addons

This commit is contained in:
Art4 2024-11-29 20:18:25 +00:00
commit b2eee3ffd3
129 changed files with 22490 additions and 21597 deletions

View file

@ -3,7 +3,7 @@
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
parameters: parameters:
level: 0 level: 1
paths: paths:
- addon/ - addon/
@ -16,5 +16,9 @@ parameters:
scanDirectories: scanDirectories:
- mod - mod
- static
- vendor - vendor
- view - view
dynamicConstantNames:
- DB_UPDATE_VERSION

View file

@ -74,6 +74,7 @@
"psr/log": "^1.1", "psr/log": "^1.1",
"seld/cli-prompt": "^1.0", "seld/cli-prompt": "^1.0",
"smarty/smarty": "^4", "smarty/smarty": "^4",
"textalk/websocket": "^1.6",
"ua-parser/uap-php": "^3.9", "ua-parser/uap-php": "^3.9",
"xemlock/htmlpurifier-html5": "^0.1.11" "xemlock/htmlpurifier-html5": "^0.1.11"
}, },

169
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "3e31a2243fb69e47e1b7000cca946fa2", "content-hash": "64436f375561718bb857e3e1b0e503c9",
"packages": [ "packages": [
{ {
"name": "asika/simple-console", "name": "asika/simple-console",
@ -1365,6 +1365,24 @@
"html", "html",
"markdown" "markdown"
], ],
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
},
{
"url": "https://www.patreon.com/colinodell",
"type": "patreon"
}
],
"time": "2020-07-01T00:34:03+00:00" "time": "2020-07-01T00:34:03+00:00"
}, },
{ {
@ -2796,6 +2814,104 @@
], ],
"time": "2024-03-03T02:14:58+00:00" "time": "2024-03-03T02:14:58+00:00"
}, },
{
"name": "phrity/net-uri",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/sirn-se/phrity-net-uri.git",
"reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sirn-se/phrity-net-uri/zipball/3f458e0c4d1ddc0e218d7a5b9420127c63925f43",
"reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43",
"shasum": ""
},
"require": {
"php": "^7.4 | ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0 | ^2.0"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.0",
"phpunit/phpunit": "^9.0 | ^10.0",
"squizlabs/php_codesniffer": "^3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Phrity\\Net\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Sören Jensen",
"email": "sirn@sirn.se",
"homepage": "https://phrity.sirn.se"
}
],
"description": "PSR-7 Uri and PSR-17 UriFactory implementation",
"homepage": "https://phrity.sirn.se/net-uri",
"keywords": [
"psr-17",
"psr-7",
"uri",
"uri factory"
],
"time": "2023-08-21T10:33:06+00:00"
},
{
"name": "phrity/util-errorhandler",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/sirn-se/phrity-util-errorhandler.git",
"reference": "483228156e06673963902b1cc1e6bd9541ab4d5e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sirn-se/phrity-util-errorhandler/zipball/483228156e06673963902b1cc1e6bd9541ab4d5e",
"reference": "483228156e06673963902b1cc1e6bd9541ab4d5e",
"shasum": ""
},
"require": {
"php": "^7.4 | ^8.0"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.0",
"phpunit/phpunit": "^9.0 | ^10.0 | ^11.0",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Phrity\\Util\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Sören Jensen",
"email": "sirn@sirn.se",
"homepage": "https://phrity.sirn.se"
}
],
"description": "Inline error handler; catch and resolve errors for code block.",
"homepage": "https://phrity.sirn.se/util-errorhandler",
"keywords": [
"error",
"warning"
],
"time": "2024-09-12T06:49:16+00:00"
},
{ {
"name": "pragmarx/google2fa", "name": "pragmarx/google2fa",
"version": "v5.0.0", "version": "v5.0.0",
@ -3658,6 +3774,57 @@
], ],
"time": "2020-10-23T14:02:19+00:00" "time": "2020-10-23T14:02:19+00:00"
}, },
{
"name": "textalk/websocket",
"version": "1.6.3",
"source": {
"type": "git",
"url": "https://github.com/Textalk/websocket-php.git",
"reference": "67de79745b1a357caf812bfc44e0abf481cee012"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Textalk/websocket-php/zipball/67de79745b1a357caf812bfc44e0abf481cee012",
"reference": "67de79745b1a357caf812bfc44e0abf481cee012",
"shasum": ""
},
"require": {
"php": "^7.4 | ^8.0",
"phrity/net-uri": "^1.0",
"phrity/util-errorhandler": "^1.0",
"psr/http-message": "^1.0",
"psr/log": "^1.0 | ^2.0 | ^3.0"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.0",
"phpunit/phpunit": "^9.0",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"autoload": {
"psr-4": {
"WebSocket\\": "lib"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"ISC"
],
"authors": [
{
"name": "Fredrik Liljegren"
},
{
"name": "Sören Jensen"
}
],
"description": "WebSocket client and server",
"support": {
"issues": "https://github.com/Textalk/websocket-php/issues",
"source": "https://github.com/Textalk/websocket-php/tree/1.6.3"
},
"time": "2022-11-07T18:59:33+00:00"
},
{ {
"name": "ua-parser/uap-php", "name": "ua-parser/uap-php",
"version": "v3.9.14", "version": "v3.9.14",

View file

@ -341,13 +341,13 @@ function samplestorage_storage_uninstall()
DI::storageManager()->unregister(SampleStorageBackend::class); DI::storageManager()->unregister(SampleStorageBackend::class);
} }
function samplestorage_storage_instance(App $a, array &$data) function samplestorage_storage_instance(AppHelper $appHelper, array &$data)
{ {
$config = new SampleStorageBackendConfig(DI::l10n(), DI::config()); $config = new SampleStorageBackendConfig(DI::l10n(), DI::config());
$data['storage'] = new SampleStorageBackendConfig($config->getFileName()); $data['storage'] = new SampleStorageBackendConfig($config->getFileName());
} }
function samplestorage_storage_config(App $a, array &$data) function samplestorage_storage_config(AppHelper $appHelper, array &$data)
{ {
$data['storage_config'] = new SampleStorageBackendConfig(DI::l10n(), DI::config()); $data['storage_config'] = new SampleStorageBackendConfig(DI::l10n(), DI::config());
} }

View file

@ -46,9 +46,9 @@ The code will be something like:
// mod/network.php // mod/network.php
<?php <?php
use Friendica\App; use Friendica\AppHelper;
function network_content(App $a) { function network_content(AppHelper $appHelper) {
$itemsmanager = new \Friendica\ItemsManager(); $itemsmanager = new \Friendica\ItemsManager();
$items = $itemsmanager->getAll(); $items = $itemsmanager->getAll();

View file

@ -447,6 +447,7 @@ class App implements AppHelper
$requeststring = ($server['REQUEST_METHOD'] ?? '') . ' ' . ($server['REQUEST_URI'] ?? '') . ' ' . ($server['SERVER_PROTOCOL'] ?? ''); $requeststring = ($server['REQUEST_METHOD'] ?? '') . ' ' . ($server['REQUEST_URI'] ?? '') . ' ' . ($server['SERVER_PROTOCOL'] ?? '');
$this->logger->debug('Request received', ['address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '']); $this->logger->debug('Request received', ['address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '']);
$request_start = microtime(true); $request_start = microtime(true);
$request = $_REQUEST;
$this->profiler->set($start_time, 'start'); $this->profiler->set($start_time, 'start');
$this->profiler->set(microtime(true), 'classinit'); $this->profiler->set(microtime(true), 'classinit');
@ -581,7 +582,7 @@ class App implements AppHelper
// Processes data from GET requests // Processes data from GET requests
$httpinput = $httpInput->process(); $httpinput = $httpInput->process();
$input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST); $input = array_merge($httpinput['variables'], $httpinput['files'], $request);
// Let the module run its internal process (init, get, post, ...) // Let the module run its internal process (init, get, post, ...)
$timestamp = microtime(true); $timestamp = microtime(true);

View file

@ -103,6 +103,8 @@ class BaseURL extends Uri implements UriInterface
* @throws HTTPException\TemporaryRedirectException * @throws HTTPException\TemporaryRedirectException
* *
* @throws HTTPException\InternalServerErrorException In Case the given URL is not relative to the Friendica node * @throws HTTPException\InternalServerErrorException In Case the given URL is not relative to the Friendica node
*
* @return never
*/ */
public function redirect(string $toUrl = '', bool $ssl = false) public function redirect(string $toUrl = '', bool $ssl = false)
{ {

View file

@ -334,17 +334,17 @@ class Router
$stamp = microtime(true); $stamp = microtime(true);
try {
/** @var ICanHandleRequests $module */ /** @var ICanHandleRequests $module */
return $this->dice->create($moduleClass, $this->parameters); $module = $this->dice->create($moduleClass, $this->parameters);
} finally {
if ($this->dice_profiler_threshold > 0) { if ($this->dice_profiler_threshold > 0) {
$dur = floatval(microtime(true) - $stamp); $dur = floatval(microtime(true) - $stamp);
if ($dur >= $this->dice_profiler_threshold) { if ($dur >= $this->dice_profiler_threshold) {
$this->logger->notice('Dice module creation lasts too long.', ['duration' => round($dur, 3), 'module' => $moduleClass, 'parameters' => $this->parameters]); $this->logger->notice('Dice module creation lasts too long.', ['duration' => round($dur, 3), 'module' => $moduleClass, 'parameters' => $this->parameters]);
} }
} }
}
return $module;
} }
/** /**

View file

@ -245,10 +245,10 @@ abstract class BaseModule implements ICanHandleRequests
$this->response->setStatus($e->getCode(), $e->getMessage()); $this->response->setStatus($e->getCode(), $e->getMessage());
$this->response->addContent($httpException->content($e)); $this->response->addContent($httpException->content($e));
} finally {
$this->profiler->set(microtime(true) - $timestamp, 'content');
} }
$this->profiler->set(microtime(true) - $timestamp, 'content');
return $this->response->generate(); return $this->response->generate();
} }
@ -269,7 +269,7 @@ abstract class BaseModule implements ICanHandleRequests
$request[$parameter] = $this->getRequestValue($input, $parameter, $defaultvalue); $request[$parameter] = $this->getRequestValue($input, $parameter, $defaultvalue);
} }
foreach ($input ?? [] as $parameter => $value) { foreach ($input as $parameter => $value) {
if ($parameter == 'pagename') { if ($parameter == 'pagename') {
continue; continue;
} }
@ -456,7 +456,7 @@ abstract class BaseModule implements ICanHandleRequests
* @param string $content * @param string $content
* @param string $type * @param string $type
* @param string|null $content_type * @param string|null $content_type
* @return void * @return never
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public function httpExit(string $content, string $type = Response::TYPE_HTML, ?string $content_type = null) public function httpExit(string $content, string $type = Response::TYPE_HTML, ?string $content_type = null)
@ -493,7 +493,7 @@ abstract class BaseModule implements ICanHandleRequests
* @param mixed $content * @param mixed $content
* @param string $content_type * @param string $content_type
* @param int $options A combination of json_encode() binary flags * @param int $options A combination of json_encode() binary flags
* @return void * @return never
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @see json_encode() * @see json_encode()
*/ */
@ -508,7 +508,7 @@ abstract class BaseModule implements ICanHandleRequests
* @param int $httpCode * @param int $httpCode
* @param mixed $content * @param mixed $content
* @param string $content_type * @param string $content_type
* @return void * @return never
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
public function jsonError(int $httpCode, $content, string $content_type = 'application/json') public function jsonError(int $httpCode, $content, string $content_type = 'application/json')

View file

@ -12,7 +12,6 @@ use Friendica\Contact\Avatar;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Photo; use Friendica\Model\Photo;
use Friendica\Util\Images;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
@ -115,6 +114,10 @@ HELP;
private function storeAvatar(string $resourceid, array $contact, bool $quit_on_invalid) private function storeAvatar(string $resourceid, array $contact, bool $quit_on_invalid)
{ {
$photo = false;
$imgdata = false;
$image = null;
$valid = !empty($resourceid); $valid = !empty($resourceid);
if ($valid) { if ($valid) {
$this->out('1', false); $this->out('1', false);
@ -143,7 +146,7 @@ HELP;
} }
} }
if ($valid) { if ($valid && $image instanceof Image) {
$this->out('4', false); $this->out('4', false);
$fields = Avatar::storeAvatarByImage($contact, $image); $fields = Avatar::storeAvatarByImage($contact, $image);
} else { } else {

View file

@ -142,17 +142,18 @@ class ContactSelector
$replace = array_values($nets); $replace = array_values($nets);
$networkname = str_replace($search, $replace, $network); $networkname = str_replace($search, $replace, $network);
$platform = '';
if (in_array($network, Protocol::FEDERATED) && !empty($gsid)) { if (in_array($network, Protocol::FEDERATED) && !empty($gsid)) {
$gserver = self::getServerForId($gsid); $gserver = self::getServerForId($gsid);
if (!empty($gserver['platform'])) { if (!empty($gserver['platform'])) {
$platform = $gserver['platform']; $platform = (string) $gserver['platform'];
} elseif (!empty($gserver['network']) && ($gserver['network'] != Protocol::ACTIVITYPUB)) { } elseif (!empty($gserver['network']) && ($gserver['network'] != Protocol::ACTIVITYPUB)) {
$platform = self::networkToName($gserver['network']); $platform = self::networkToName($gserver['network']);
} }
if (!empty($platform)) { if ($platform !== '') {
$networkname = $platform; $networkname = $platform;
} }
} }
@ -161,7 +162,7 @@ class ContactSelector
$networkname = DI::l10n()->t('%s (via %s)', $networkname, self::networkToName($protocol)); $networkname = DI::l10n()->t('%s (via %s)', $networkname, self::networkToName($protocol));
} elseif (in_array($network, ['', $protocol]) && ($network == Protocol::DFRN)) { } elseif (in_array($network, ['', $protocol]) && ($network == Protocol::DFRN)) {
$networkname .= ' (DFRN)'; $networkname .= ' (DFRN)';
} elseif (in_array($network, ['', $protocol]) && ($network == Protocol::DIASPORA) && ($platform != 'diaspora')) { } elseif (in_array($network, ['', $protocol]) && ($network == Protocol::DIASPORA) && ($platform !== 'diaspora')) {
$networkname .= ' (Diaspora)'; $networkname .= ' (Diaspora)';
} }

View file

@ -180,6 +180,7 @@ class Item
public static function replaceTag(string &$body, int $profile_uid, string $tag, string $network = '') public static function replaceTag(string &$body, int $profile_uid, string $tag, string $network = '')
{ {
$replaced = false; $replaced = false;
$contact = [];
//is it a person tag? //is it a person tag?
if (Tag::isType($tag, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION)) { if (Tag::isType($tag, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION)) {
@ -247,6 +248,8 @@ class Item
} }
} }
$newname = '';
// Check if $contact has been successfully loaded // Check if $contact has been successfully loaded
if (DBA::isResult($contact)) { if (DBA::isResult($contact)) {
$profile = $contact['url']; $profile = $contact['url'];

View file

@ -178,7 +178,7 @@ class OEmbed
$oembed->thumbnail_height = $data['images'][0]['height']; $oembed->thumbnail_height = $data['images'][0]['height'];
} }
Hook::callAll('oembed_fetch_url', $embedurl, $oembed); Hook::callAll('oembed_fetch_url', $embedurl);
return $oembed; return $oembed;
} }

View file

@ -119,6 +119,7 @@ class PostMedia extends BaseRepository
$heights = []; $heights = [];
$selected = ''; $selected = '';
$previews = []; $previews = [];
$video = [];
foreach ($PostMedias as $PostMedia) { foreach ($PostMedias as $PostMedia) {
foreach ($links as $link) { foreach ($links as $link) {

View file

@ -543,6 +543,8 @@ class NPF
return $npf; return $npf;
} }
$block = [];
$media = Post\Media::getByURL($uri_id, $attributes['src'], [Post\Media::AUDIO, Post\Media::VIDEO]); $media = Post\Media::getByURL($uri_id, $attributes['src'], [Post\Media::AUDIO, Post\Media::VIDEO]);
if (!empty($media)) { if (!empty($media)) {
switch ($media['type']) { switch ($media['type']) {

View file

@ -114,6 +114,8 @@ class Plaintext
$post['text'] = trim($item['title']); $post['text'] = trim($item['title']);
} }
$abstract = '';
// Fetch the abstract from the given target network // Fetch the abstract from the given target network
switch ($htmlmode) { switch ($htmlmode) {
case BBCode::TWITTER: case BBCode::TWITTER:
@ -242,6 +244,8 @@ class Plaintext
$part = ''; $part = '';
$break_pos = 0; $break_pos = 0;
$comma_pos = 0; $comma_pos = 0;
$pos = 0;
$word = '';
$limit = $baselimit; $limit = $baselimit;

View file

@ -402,7 +402,7 @@ class Widget
return ''; return '';
} }
$commonContacts = Contact\Relation::listCommon($localPCid, $visitorPCid, $condition, 0, 5, true); $commonContacts = Contact\Relation::listCommon($localPCid, $visitorPCid, $condition, 0, 5);
if (!DBA::isResult($commonContacts)) { if (!DBA::isResult($commonContacts)) {
return ''; return '';
} }
@ -479,6 +479,10 @@ class Widget
DI::cache()->set($cachekey, $dthen, Duration::HOUR); DI::cache()->set($cachekey, $dthen, Duration::HOUR);
} }
$cutoffday = '';
$thisday = '';
$nextday = '';
if ($dthen) { if ($dthen) {
// Set the start and end date to the beginning of the month // Set the start and end date to the beginning of the month
$cutoffday = $dthen; $cutoffday = $dthen;
@ -513,7 +517,6 @@ class Widget
return $o; return $o;
} }
$cutoff_year = intval(DateTimeFormat::localNow('Y')) - $visible_years; $cutoff_year = intval(DateTimeFormat::localNow('Y')) - $visible_years;
$cutoff = array_key_exists($cutoff_year, $ret); $cutoff = array_key_exists($cutoff_year, $ret);

View file

@ -34,7 +34,7 @@ class VCard
public static function getHTML(array $contact, bool $hide_mention = false, bool $hide_follow = false): string public static function getHTML(array $contact, bool $hide_mention = false, bool $hide_follow = false): string
{ {
if (!isset($contact['network']) || !isset($contact['id'])) { if (!isset($contact['network']) || !isset($contact['id'])) {
Logger::warning('Incomplete contact', ['contact' => $contact ?? []]); Logger::warning('Incomplete contact', ['contact' => $contact]);
} }
$contact_url = Contact::getProfileLink($contact); $contact_url = Contact::getProfileLink($contact);

View file

@ -14,8 +14,8 @@ use Throwable;
*/ */
class AddonInvalidConfigFileException extends \RuntimeException class AddonInvalidConfigFileException extends \RuntimeException
{ {
public function __construct($message = '', $code = 0, Throwable $previous = null) public function __construct($message = '')
{ {
parent::__construct($message, 500, $previous); parent::__construct($message, 500);
} }
} }

View file

@ -47,17 +47,21 @@ class DatabaseCache extends AbstractCache implements ICanCache
} }
$stmt = $this->dba->select('cache', ['k'], $where); $stmt = $this->dba->select('cache', ['k'], $where);
} catch (\Exception $exception) {
throw new CachePersistenceException(sprintf('Cannot fetch all keys with prefix %s', $prefix), $exception);
}
try {
$keys = []; $keys = [];
while ($key = $this->dba->fetch($stmt)) { while ($key = $this->dba->fetch($stmt)) {
array_push($keys, $key['k']); array_push($keys, $key['k']);
} }
} catch (\Exception $exception) { } catch (\Exception $exception) {
throw new CachePersistenceException(sprintf('Cannot fetch all keys with prefix %s', $prefix), $exception);
} finally {
$this->dba->close($stmt); $this->dba->close($stmt);
throw new CachePersistenceException(sprintf('Cannot fetch all keys with prefix %s', $prefix), $exception);
} }
$this->dba->close($stmt);
return $keys; return $keys;
} }

View file

@ -11,8 +11,8 @@ use Throwable;
class ConfigFileException extends \RuntimeException class ConfigFileException extends \RuntimeException
{ {
public function __construct($message = "", $code = 0, Throwable $previous = null) public function __construct($message = "")
{ {
parent::__construct($message, 500, $previous); parent::__construct($message, 500);
} }
} }

View file

@ -245,7 +245,10 @@ class ConfigFileManager
$fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php'; $fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php';
$config = []; $config = [];
if (file_exists($fullName)) { if (!file_exists($fullName)) {
return $config;
}
$a = new \stdClass(); $a = new \stdClass();
$a->config = []; $a->config = [];
include $fullName; include $fullName;
@ -283,7 +286,7 @@ class ConfigFileManager
$config['database']['database'] = $db_data; $config['database']['database'] = $db_data;
unset($db_data); unset($db_data);
} }
if (isset($config['system']['db_charset'])) { if (isset($config['system']) && isset($config['system']['db_charset'])) {
$config['database']['charset'] = $config['system']['db_charset']; $config['database']['charset'] = $config['system']['db_charset'];
} }
if (isset($pidfile)) { if (isset($pidfile)) {
@ -298,7 +301,6 @@ class ConfigFileManager
$config['system']['language'] = $lang; $config['system']['language'] = $lang;
unset($lang); unset($lang);
} }
}
return $config; return $config;
} }

View file

@ -182,17 +182,22 @@ class DatabaseLock extends AbstractLock
} }
$stmt = $this->dba->select('locks', ['name'], $where); $stmt = $this->dba->select('locks', ['name'], $where);
} catch (\Exception $exception) {
throw new LockPersistenceException(sprintf('Cannot get lock with prefix %s', $prefix), $exception);
}
try {
$keys = []; $keys = [];
while ($key = $this->dba->fetch($stmt)) { while ($key = $this->dba->fetch($stmt)) {
array_push($keys, $key['name']); array_push($keys, $key['name']);
} }
} catch (\Exception $exception) { } catch (\Exception $exception) {
throw new LockPersistenceException(sprintf('Cannot get lock with prefix %s', $prefix), $exception);
} finally {
$this->dba->close($stmt); $this->dba->close($stmt);
throw new LockPersistenceException(sprintf('Cannot get lock with prefix %s', $prefix), $exception);
} }
$this->dba->close($stmt);
return $keys; return $keys;
} }
} }

View file

@ -60,7 +60,11 @@ class PConfig
} else { } else {
$configs = $this->db->select(static::$table_name, ['cat', 'v', 'k'], ['cat' => $cat, 'uid' => $uid]); $configs = $this->db->select(static::$table_name, ['cat', 'v', 'k'], ['cat' => $cat, 'uid' => $uid]);
} }
} catch (\Exception $exception) {
throw new PConfigPersistenceException(sprintf('Cannot load config category "%s" for user %d', $cat, $uid), $exception);
}
try {
while ($config = $this->db->fetch($configs)) { while ($config = $this->db->fetch($configs)) {
$key = $config['k']; $key = $config['k'];
$value = ValueConversion::toConfigValue($config['v']); $value = ValueConversion::toConfigValue($config['v']);
@ -71,11 +75,12 @@ class PConfig
} }
} }
} catch (\Exception $exception) { } catch (\Exception $exception) {
throw new PConfigPersistenceException(sprintf('Cannot load config category %s for user %d', $cat, $uid), $exception);
} finally {
$this->db->close($configs); $this->db->close($configs);
throw new PConfigPersistenceException(sprintf('Cannot load config category "%s" for user %d', $cat, $uid), $exception);
} }
$this->db->close($configs);
return $return; return $return;
} }

View file

@ -13,11 +13,14 @@ use Friendica\Core\Cache\Factory\Cache;
use Friendica\Core\Cache\Type\DatabaseCache; use Friendica\Core\Cache\Type\DatabaseCache;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Session\Capability\IHandleSessions; use Friendica\Core\Session\Capability\IHandleSessions;
use Friendica\Core\Session\Type; use Friendica\Core\Session\Handler\Cache as CacheHandler;
use Friendica\Core\Session\Handler; use Friendica\Core\Session\Handler\Database as DatabaseHandler;
use Friendica\Core\Session\Type\Memory;
use Friendica\Core\Session\Type\Native;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Throwable;
/** /**
* Factory for creating a valid Session for this run * Factory for creating a valid Session for this run
@ -49,36 +52,45 @@ class Session
$profiler->startRecording('session'); $profiler->startRecording('session');
$session_handler = $config->get('system', 'session_handler', self::HANDLER_DEFAULT); $session_handler = $config->get('system', 'session_handler', self::HANDLER_DEFAULT);
try {
if ($mode->isInstall() || $mode->isBackend()) { if ($mode->isInstall() || $mode->isBackend()) {
$session = new Type\Memory(); $session = new Memory();
} else { $profiler->stopRecording();
return $session;
}
try {
switch ($session_handler) { switch ($session_handler) {
case self::HANDLER_DATABASE: case self::HANDLER_DATABASE:
$handler = new Handler\Database($dba, $logger, $server); $handler = new DatabaseHandler($dba, $logger, $server);
break; break;
case self::HANDLER_CACHE: case self::HANDLER_CACHE:
$cache = $cacheFactory->createDistributed(); $cache = $cacheFactory->createDistributed();
// In case we're using the db as cache driver, use the native db session, not the cache // In case we're using the db as cache driver, use the native db session, not the cache
if ($config->get('system', 'cache_driver') === DatabaseCache::NAME) { if ($config->get('system', 'cache_driver') === DatabaseCache::NAME) {
$handler = new Handler\Database($dba, $logger, $server); $handler = new DatabaseHandler($dba, $logger, $server);
} else { } else {
$handler = new Handler\Cache($cache, $logger); $handler = new CacheHandler($cache, $logger);
} }
break; break;
default: default:
$handler = null; $handler = null;
} }
} catch (Throwable $e) {
$session = new Type\Native($baseURL, $handler);
}
} catch (\Throwable $e) {
$logger->notice('Unable to create session', ['mode' => $mode, 'session_handler' => $session_handler, 'exception' => $e]); $logger->notice('Unable to create session', ['mode' => $mode, 'session_handler' => $session_handler, 'exception' => $e]);
$session = new Type\Memory(); $session = new Memory();
} finally {
$profiler->stopRecording(); $profiler->stopRecording();
return $session; return $session;
} }
try {
$session = new Native($baseURL, $handler);
} catch (Throwable $e) {
$logger->notice('Unable to create session', ['mode' => $mode, 'session_handler' => $session_handler, 'exception' => $e]);
$session = new Memory();
}
$profiler->stopRecording();
return $session;
} }
} }

View file

@ -54,16 +54,13 @@ class ExternalResource implements ICanReadFromStorage
$this->logger->notice('URL is invalid', ['url' => $data->url, 'error' => $exception]); $this->logger->notice('URL is invalid', ['url' => $data->url, 'error' => $exception]);
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $exception->getCode(), $exception); throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $exception->getCode(), $exception);
} }
if (!empty($fetchResult) && $fetchResult->isSuccess()) {
$this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]); if (!$fetchResult->isSuccess()) {
return $fetchResult->getBodyString();
} else {
if (empty($fetchResult)) {
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference));
} else {
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBodyString())); throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBodyString()));
} }
}
$this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]);
return $fetchResult->getBodyString();
} }
/** /**

View file

@ -393,6 +393,8 @@ class System
/** /**
* Exit the program execution. * Exit the program execution.
*
* @return never
*/ */
public static function exit() public static function exit()
{ {
@ -506,6 +508,8 @@ class System
* @throws TemporaryRedirectException * @throws TemporaryRedirectException
* *
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*
* @return never
*/ */
public static function externalRedirect($url, $code = 302) public static function externalRedirect($url, $code = 302)
{ {

View file

@ -275,7 +275,7 @@ class DBStructure
$is_new_table = false; $is_new_table = false;
$sql3 = ""; $sql3 = "";
if (!isset($database[$name])) { if (!isset($database[$name])) {
$sql = DbaDefinitionSqlWriter::createTable($name, $structure, $verbose, $action); $sql = DbaDefinitionSqlWriter::createTable($name, $structure);
if ($verbose) { if ($verbose) {
echo $sql; echo $sql;
} }

View file

@ -534,6 +534,8 @@ class Database
throw new ServiceUnavailableException('The Connection is empty, although connected is set true.'); throw new ServiceUnavailableException('The Connection is empty, although connected is set true.');
} }
$retval = false;
switch ($this->driver) { switch ($this->driver) {
case self::PDO: case self::PDO:
// If there are no arguments we use "query" // If there are no arguments we use "query"
@ -1074,6 +1076,8 @@ class Database
*/ */
public function lastInsertId(): int public function lastInsertId(): int
{ {
$id = 0;
switch ($this->driver) { switch ($this->driver) {
case self::PDO: case self::PDO:
$id = $this->connection->lastInsertId(); $id = $this->connection->lastInsertId();
@ -1681,6 +1685,8 @@ class Database
return false; return false;
} }
$ret = false;
switch ($this->driver) { switch ($this->driver) {
case self::PDO: case self::PDO:
$ret = $stmt->closeCursor(); $ret = $stmt->closeCursor();
@ -1695,8 +1701,6 @@ class Database
} elseif ($stmt instanceof mysqli_result) { } elseif ($stmt instanceof mysqli_result) {
$stmt->free(); $stmt->free();
$ret = true; $ret = true;
} else {
$ret = false;
} }
break; break;
} }

View file

@ -284,7 +284,7 @@ class PostUpdate
} }
while ($item = DBA::fetch($items)) { while ($item = DBA::fetch($items)) {
Tag::storeFromBody($item['uri-id'], $item['body'], '#!@', false); Tag::storeFromBody($item['uri-id'], $item['body'], '#!@');
$id = $item['uri-id']; $id = $item['uri-id'];
++$rows; ++$rows;
if ($rows % 1000 == 0) { if ($rows % 1000 == 0) {
@ -775,11 +775,8 @@ class PostUpdate
while ($photo = DBA::fetch($photos)) { while ($photo = DBA::fetch($photos)) {
$img = Photo::getImageForPhoto($photo); $img = Photo::getImageForPhoto($photo);
if (!empty($img)) {
$md5 = md5($img->asString()); $md5 = md5($img->asString());
} else {
$md5 = '';
}
DBA::update('photo', ['hash' => $md5], ['id' => $photo['id']]); DBA::update('photo', ['hash' => $md5], ['id' => $photo['id']]);
++$rows; ++$rows;
} }

View file

@ -25,11 +25,11 @@ class View
foreach (['post-view', 'post-thread-view'] as $view) { foreach (['post-view', 'post-thread-view'] as $view) {
if (self::isView($view)) { if (self::isView($view)) {
$sql = sprintf("DROP VIEW IF EXISTS `%s`", DBA::escape($view)); $sql = sprintf("DROP VIEW IF EXISTS `%s`", DBA::escape($view));
if (!empty($sql) && $verbose) { if ($verbose) {
echo $sql . ";\n"; echo $sql . ";\n";
} }
if (!empty($sql) && $action) { if ($action) {
DBA::e($sql); DBA::e($sql);
} }
} }

View file

@ -48,6 +48,9 @@ class DirectMessage extends BaseFactory
throw new HTTPException\NotFoundException('Direct message with ID ' . $mail . ' not found.'); throw new HTTPException\NotFoundException('Direct message with ID ' . $mail . ' not found.');
} }
$title = '';
$text = '';
if (!empty($text_mode)) { if (!empty($text_mode)) {
$title = $mail['title']; $title = $mail['title'];
if ($text_mode == 'html') { if ($text_mode == 'html') {
@ -56,7 +59,6 @@ class DirectMessage extends BaseFactory
$text = HTML::toPlaintext(BBCode::convertForUriId($mail['uri-id'], $mail['body'], BBCode::TWITTER_API), 0); $text = HTML::toPlaintext(BBCode::convertForUriId($mail['uri-id'], $mail['body'], BBCode::TWITTER_API), 0);
} }
} else { } else {
$title = '';
$text = $mail['title'] . "\n" . HTML::toPlaintext(BBCode::convertForUriId($mail['uri-id'], $mail['body'], BBCode::TWITTER_API), 0); $text = $mail['title'] . "\n" . HTML::toPlaintext(BBCode::convertForUriId($mail['uri-id'], $mail['body'], BBCode::TWITTER_API), 0);
} }

View file

@ -57,7 +57,7 @@ class User extends BaseFactory
['author-id' => $publicContact['id'], 'gravity' => [Item::GRAVITY_COMMENT, Item::GRAVITY_PARENT], 'private' => [Item::PUBLIC, Item::UNLISTED]], ['author-id' => $publicContact['id'], 'gravity' => [Item::GRAVITY_COMMENT, Item::GRAVITY_PARENT], 'private' => [Item::PUBLIC, Item::UNLISTED]],
['order' => ['uri-id' => true]]); ['order' => ['uri-id' => true]]);
if (!empty($post['uri-id'])) { if (!empty($post['uri-id'])) {
$status = $this->status->createFromUriId($post['uri-id'], $uid)->toArray(); $status = $this->status->createFromUriId($post['uri-id'], $uid);
} }
} }

View file

@ -178,7 +178,7 @@ class APContact
try { try {
$curlResult = HTTPSignature::fetchRaw($url); $curlResult = HTTPSignature::fetchRaw($url);
$failed = empty($curlResult) || empty($curlResult->getBodyString()) || $failed = empty($curlResult->getBodyString()) ||
(!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410)); (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410));
if (!$failed) { if (!$failed) {

View file

@ -2364,6 +2364,8 @@ class Contact
$cache_avatar = !DBA::exists('contact', ['nurl' => $contact['nurl'], 'self' => true]); $cache_avatar = !DBA::exists('contact', ['nurl' => $contact['nurl'], 'self' => true]);
} }
$fields = [];
if (in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) || $cache_avatar) { if (in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) || $cache_avatar) {
if (Avatar::deleteCache($contact)) { if (Avatar::deleteCache($contact)) {
$force = true; $force = true;
@ -2380,6 +2382,8 @@ class Contact
Logger::debug('Use default avatar', ['id' => $cid, 'uid' => $uid]); Logger::debug('Use default avatar', ['id' => $cid, 'uid' => $uid]);
} }
$local_uid = 0;
// Use the data from the self account // Use the data from the self account
if (empty($fields)) { if (empty($fields)) {
$local_uid = User::getIdForURL($contact['url']); $local_uid = User::getIdForURL($contact['url']);
@ -2411,8 +2415,15 @@ class Contact
if ($update) { if ($update) {
$photos = Photo::importProfilePhoto($avatar, $uid, $cid, true); $photos = Photo::importProfilePhoto($avatar, $uid, $cid, true);
if ($photos) { if ($photos) {
$fields = ['avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'blurhash' => $photos[3], 'avatar-date' => DateTimeFormat::utcNow()]; $fields = [
$update = !empty($fields); 'avatar' => $avatar,
'photo' => $photos[0],
'thumb' => $photos[1],
'micro' => $photos[2],
'blurhash' => $photos[3],
'avatar-date' => DateTimeFormat::utcNow(),
];
$update = true;
Logger::debug('Created new cached avatars', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]); Logger::debug('Created new cached avatars', ['id' => $cid, 'uid' => $uid, 'owner-uid' => $local_uid]);
} else { } else {
$update = false; $update = false;

View file

@ -128,10 +128,11 @@ class User
* @param int $cid Either public contact id or user's contact id * @param int $cid Either public contact id or user's contact id
* @param int $uid User ID * @param int $uid User ID
* @param boolean $blocked Is the contact blocked or unblocked? * @param boolean $blocked Is the contact blocked or unblocked?
* @param boolean $only_set Only set the block flag, don't execute any block transmission
* @return void * @return void
* @throws \Exception * @throws \Exception
*/ */
public static function setBlocked(int $cid, int $uid, bool $blocked) public static function setBlocked(int $cid, int $uid, bool $blocked, bool $only_set = false)
{ {
$cdata = Contact::getPublicAndUserContactID($cid, $uid); $cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) { if (empty($cdata)) {
@ -139,11 +140,14 @@ class User
} }
$contact = Contact::getById($cdata['public']); $contact = Contact::getById($cdata['public']);
if (!$only_set) {
if ($blocked) { if ($blocked) {
Worker::add(Worker::PRIORITY_HIGH, 'Contact\Block', $cid, $uid); Worker::add(Worker::PRIORITY_HIGH, 'Contact\Block', $cid, $uid);
} else { } else {
Worker::add(Worker::PRIORITY_HIGH, 'Contact\Unblock', $cid, $uid); Worker::add(Worker::PRIORITY_HIGH, 'Contact\Unblock', $cid, $uid);
} }
}
if ($cdata['user'] != 0) { if ($cdata['user'] != 0) {
DBA::update('contact', ['blocked' => $blocked], ['id' => $cdata['user'], 'pending' => false]); DBA::update('contact', ['blocked' => $blocked], ['id' => $cdata['user'], 'pending' => false]);

View file

@ -29,6 +29,7 @@ class Conversation
const PARCEL_ATOM = 14; const PARCEL_ATOM = 14;
const PARCEL_ATOM03 = 15; const PARCEL_ATOM03 = 15;
const PARCEL_OPML = 16; const PARCEL_OPML = 16;
const PARCEL_JETSTREAM = 17; // @see https://github.com/bluesky-social/jetstream
const PARCEL_TWITTER = 67; const PARCEL_TWITTER = 67;
const PARCEL_CONNECTOR = 68; const PARCEL_CONNECTOR = 68;
const PARCEL_UNKNOWN = 255; const PARCEL_UNKNOWN = 255;

View file

@ -333,7 +333,7 @@ class Event
$item['uri'] = $event['uri']; $item['uri'] = $event['uri'];
$item['uri-id'] = ItemURI::getIdByURI($event['uri']); $item['uri-id'] = ItemURI::getIdByURI($event['uri']);
$item['guid'] = $event['guid']; $item['guid'] = $event['guid'];
$item['plink'] = $arr['plink'] ?? ''; $item['plink'] = '';
$item['post-type'] = Item::PT_EVENT; $item['post-type'] = Item::PT_EVENT;
$item['wall'] = $event['cid'] ? 0 : 1; $item['wall'] = $event['cid'] ? 0 : 1;
$item['contact-id'] = $contact['id']; $item['contact-id'] = $contact['id'];

View file

@ -224,6 +224,8 @@ class GServer
*/ */
public static function reachable(array $contact): bool public static function reachable(array $contact): bool
{ {
$server = '';
if (!empty($contact['gsid'])) { if (!empty($contact['gsid'])) {
$gsid = $contact['gsid']; $gsid = $contact['gsid'];
} elseif (!empty($contact['baseurl'])) { } elseif (!empty($contact['baseurl'])) {
@ -800,6 +802,8 @@ class GServer
$serverdata['failed'] = false; $serverdata['failed'] = false;
$serverdata['blocked'] = false; $serverdata['blocked'] = false;
$id = 0;
$gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => Strings::normaliseLink($url)]); $gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => Strings::normaliseLink($url)]);
if (!DBA::isResult($gserver)) { if (!DBA::isResult($gserver)) {
$serverdata['created'] = DateTimeFormat::utcNow(); $serverdata['created'] = DateTimeFormat::utcNow();
@ -1197,10 +1201,6 @@ class GServer
} }
} }
if (empty($server)) {
return [];
}
if (empty($server['network'])) { if (empty($server['network'])) {
$server['network'] = Protocol::PHANTOM; $server['network'] = Protocol::PHANTOM;
} }
@ -1337,10 +1337,6 @@ class GServer
} }
} }
if (empty($server)) {
return [];
}
if (empty($server['network'])) { if (empty($server['network'])) {
$server['network'] = Protocol::PHANTOM; $server['network'] = Protocol::PHANTOM;
} }
@ -1444,7 +1440,7 @@ class GServer
} }
} }
if (empty($server) || empty($server['platform'])) { if (empty($server['platform'])) {
return []; return [];
} }
@ -1652,10 +1648,11 @@ class GServer
} }
$data = json_decode($curlResult->getBodyString(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (!is_string($data)) {
return ''; return '';
} }
return $data ?? '';
return $data;
} }
private static function getZotData(string $url, array $serverdata): array private static function getZotData(string $url, array $serverdata): array
@ -2310,13 +2307,19 @@ class GServer
return $serverdata; return $serverdata;
} }
if (file_exists(__DIR__ . '/../../static/platforms.config.php')) { if (!file_exists(__DIR__ . '/../../static/platforms.config.php')) {
require __DIR__ . '/../../static/platforms.config.php';
} else {
throw new HTTPException\InternalServerErrorException('Invalid platform file'); throw new HTTPException\InternalServerErrorException('Invalid platform file');
} }
$platforms = array_merge($ap_platforms, $dfrn_platforms, $zap_platforms, $platforms); /** @var array $grouped_platforms */
$grouped_platforms = require __DIR__ . '/../../static/platforms.config.php';
$platforms = array_merge(
$grouped_platforms['ap_platforms'],
$grouped_platforms['dfrn_platforms'],
$grouped_platforms['zap_platforms'],
$grouped_platforms['platforms'],
);
$doc = new DOMDocument(); $doc = new DOMDocument();
@$doc->loadHTML($curlResult->getBodyString()); @$doc->loadHTML($curlResult->getBodyString());
@ -2367,11 +2370,11 @@ class GServer
$platform = $platform_parts[0]; $platform = $platform_parts[0];
$serverdata['version'] = $platform_parts[1]; $serverdata['version'] = $platform_parts[1];
} }
if (in_array($platform, array_values($dfrn_platforms))) { if (in_array($platform, array_values($grouped_platforms['dfrn_platforms']))) {
$serverdata['network'] = Protocol::DFRN; $serverdata['network'] = Protocol::DFRN;
} elseif (in_array($platform, array_values($ap_platforms))) { } elseif (in_array($platform, array_values($grouped_platforms['ap_platforms']))) {
$serverdata['network'] = Protocol::ACTIVITYPUB; $serverdata['network'] = Protocol::ACTIVITYPUB;
} elseif (in_array($platform, array_values($zap_platforms))) { } elseif (in_array($platform, array_values($grouped_platforms['zap_platforms']))) {
$serverdata['network'] = Protocol::ZOT; $serverdata['network'] = Protocol::ZOT;
} }
if (in_array($platform, array_values($platforms))) { if (in_array($platform, array_values($platforms))) {
@ -2414,9 +2417,9 @@ class GServer
$assigned = true; $assigned = true;
} }
if (in_array($attr['content'], array_keys($ap_platforms))) { if (in_array($attr['content'], array_keys($grouped_platforms['ap_platforms']))) {
$serverdata['network'] = Protocol::ACTIVITYPUB; $serverdata['network'] = Protocol::ACTIVITYPUB;
} elseif (in_array($attr['content'], array_values($zap_platforms))) { } elseif (in_array($attr['content'], array_values($grouped_platforms['zap_platforms']))) {
$serverdata['network'] = Protocol::ZOT; $serverdata['network'] = Protocol::ZOT;
} }
} }
@ -2492,7 +2495,7 @@ class GServer
*/ */
public static function discover() public static function discover()
{ {
if (!DI::config('system', 'discover_servers')) { if (!DI::config()->get('system', 'discover_servers')) {
return; return;
} }

View file

@ -193,6 +193,7 @@ class Item
$fields['vid'] = Verb::getID($fields['verb']); $fields['vid'] = Verb::getID($fields['verb']);
} }
$previous = [];
if (!empty($fields['edited'])) { if (!empty($fields['edited'])) {
$previous = Post::selectFirst(['edited'], $condition); $previous = Post::selectFirst(['edited'], $condition);
} }
@ -856,6 +857,8 @@ class Item
$priority = Worker::PRIORITY_HIGH; $priority = Worker::PRIORITY_HIGH;
$copy_permissions = false;
// If it is a posting where users should get notifications, then define it as wall posting // If it is a posting where users should get notifications, then define it as wall posting
if ($notify) { if ($notify) {
$item = self::prepareOriginPost($item); $item = self::prepareOriginPost($item);
@ -1472,6 +1475,12 @@ class Item
return false; return false;
} }
// We only have to apply restrictions if the post originates from our server or is federated.
// Every other time we can trust the remote system.
if (!in_array($item['network'], Protocol::FEDERATED) && !$item['origin']) {
return false;
}
if (($restrictions & self::CANT_REPLY) && ($item['verb'] == Activity::POST)) { if (($restrictions & self::CANT_REPLY) && ($item['verb'] == Activity::POST)) {
return true; return true;
} }
@ -1796,7 +1805,7 @@ class Item
} }
} }
if (($source_uid == 0) && (($item['private'] == self::PRIVATE) || !in_array($item['network'], Protocol::FEDERATED))) { if (($source_uid == 0) && (($item['private'] == self::PRIVATE) || !in_array($item['network'], array_merge(Protocol::FEDERATED, [Protocol::BLUESKY])))) {
Logger::notice('Item is private or not from a federated network. It will not be stored for the user.', ['uri-id' => $uri_id, 'uid' => $uid, 'private' => $item['private'], 'network' => $item['network']]); Logger::notice('Item is private or not from a federated network. It will not be stored for the user.', ['uri-id' => $uri_id, 'uid' => $uid, 'private' => $item['private'], 'network' => $item['network']]);
return 0; return 0;
} }
@ -3199,7 +3208,7 @@ class Item
} elseif ($remote_user) { } elseif ($remote_user) {
// Authenticated visitor - fetch the matching permissionsets // Authenticated visitor - fetch the matching permissionsets
$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id); $permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id);
if (!empty($permissionSets)) { if (count($permissionSets) > 0) {
$condition = [ $condition = [
"(`private` != ? OR (`private` = ? AND `wall` "(`private` != ? OR (`private` = ? AND `wall`
AND `psid` IN (" . implode(', ', array_fill(0, count($permissionSets), '?')) . ")))", AND `psid` IN (" . implode(', ', array_fill(0, count($permissionSets), '?')) . ")))",
@ -3228,17 +3237,12 @@ class Item
$table = DBA::quoteIdentifier($table) . '.'; $table = DBA::quoteIdentifier($table) . '.';
} }
/*
* Construct permissions
*
* default permissions - anonymous user
*/
$sql = sprintf(" AND " . $table . "`private` != %d", self::PRIVATE);
// Profile owner - everything is visible // Profile owner - everything is visible
if ($local_user && ($local_user == $owner_id)) { if ($local_user && ($local_user == $owner_id)) {
$sql = ''; return '';
} elseif ($remote_user) { }
if ($remote_user) {
/* /*
* Authenticated visitor. Unless pre-verified, * Authenticated visitor. Unless pre-verified,
* check that the contact belongs to this $owner_id * check that the contact belongs to this $owner_id
@ -3248,16 +3252,21 @@ class Item
*/ */
$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id); $permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id);
if (!empty($permissionSets)) {
$sql_set = sprintf(" OR (" . $table . "`private` = %d AND " . $table . "`wall` AND " . $table . "`psid` IN (", self::PRIVATE) . implode(',', $permissionSets->column('id')) . "))";
} else {
$sql_set = ''; $sql_set = '';
if (count($permissionSets) > 0) {
$sql_set = sprintf(" OR (" . $table . "`private` = %d AND " . $table . "`wall` AND " . $table . "`psid` IN (", self::PRIVATE) . implode(',', $permissionSets->column('id')) . "))";
} }
$sql = sprintf(" AND (" . $table . "`private` != %d", self::PRIVATE) . $sql_set . ")"; return sprintf(" AND (" . $table . "`private` != %d", self::PRIVATE) . $sql_set . ")";
} }
return $sql; /*
* Construct permissions
*
* default permissions - anonymous user
*/
return sprintf(" AND " . $table . "`private` != %d", self::PRIVATE);
} }
/** /**
@ -3381,6 +3390,7 @@ class Item
$shared_uri_id = 0; $shared_uri_id = 0;
$shared_links = []; $shared_links = [];
$quote_shared_links = []; $quote_shared_links = [];
$shared_item = [];
$shared = DI::contentItem()->getSharedPost($item, $fields); $shared = DI::contentItem()->getSharedPost($item, $fields);
if (!empty($shared['post'])) { if (!empty($shared['post'])) {
@ -3424,6 +3434,8 @@ class Item
} }
} }
$sharedSplitAttachments = [];
if (!empty($shared_item['uri-id'])) { if (!empty($shared_item['uri-id'])) {
$shared_uri_id = $shared_item['uri-id']; $shared_uri_id = $shared_item['uri-id'];
$shared_links[] = strtolower($shared_item['plink']); $shared_links[] = strtolower($shared_item['plink']);
@ -3497,7 +3509,7 @@ class Item
$s = self::addGallery($s, $sharedSplitAttachments['visual']); $s = self::addGallery($s, $sharedSplitAttachments['visual']);
$s = self::addVisualAttachments($sharedSplitAttachments['visual'], $shared_item, $s, true); $s = self::addVisualAttachments($sharedSplitAttachments['visual'], $shared_item, $s, true);
$s = self::addLinkAttachment($shared_uri_id ?: $item['uri-id'], $sharedSplitAttachments, $body, $s, true, $quote_shared_links); $s = self::addLinkAttachment($shared_uri_id ?: $item['uri-id'], $sharedSplitAttachments, $body, $s, true, $quote_shared_links);
$s = self::addNonVisualAttachments($sharedSplitAttachments['additional'], $item, $s, true); $s = self::addNonVisualAttachments($sharedSplitAttachments['additional'], $item, $s);
$body = BBCode::removeSharedData($body); $body = BBCode::removeSharedData($body);
} }
@ -3510,7 +3522,7 @@ class Item
$s = self::addGallery($s, $itemSplitAttachments['visual']); $s = self::addGallery($s, $itemSplitAttachments['visual']);
$s = self::addVisualAttachments($itemSplitAttachments['visual'], $item, $s, false); $s = self::addVisualAttachments($itemSplitAttachments['visual'], $item, $s, false);
$s = self::addLinkAttachment($item['uri-id'], $itemSplitAttachments, $body, $s, false, $shared_links); $s = self::addLinkAttachment($item['uri-id'], $itemSplitAttachments, $body, $s, false, $shared_links);
$s = self::addNonVisualAttachments($itemSplitAttachments['additional'], $item, $s, false); $s = self::addNonVisualAttachments($itemSplitAttachments['additional'], $item, $s);
$s = self::addQuestions($item, $s); $s = self::addQuestions($item, $s);
// Map. // Map.

View file

@ -318,6 +318,8 @@ class Engagement
$result = Post::selectPosts(['author-addr', 'author-nick', 'author-contact-type'], $result = Post::selectPosts(['author-addr', 'author-nick', 'author-contact-type'],
['thr-parent-id' => $uri_id, 'gravity' => Item::GRAVITY_ACTIVITY, 'verb' => Activity::ANNOUNCE, 'author-contact-type' => [Contact::TYPE_RELAY, Contact::TYPE_COMMUNITY]]); ['thr-parent-id' => $uri_id, 'gravity' => Item::GRAVITY_ACTIVITY, 'verb' => Activity::ANNOUNCE, 'author-contact-type' => [Contact::TYPE_RELAY, Contact::TYPE_COMMUNITY]]);
while ($reshare = Post::fetch($result)) { while ($reshare = Post::fetch($result)) {
$prefix = '';
switch ($reshare['author-contact-type']) { switch ($reshare['author-contact-type']) {
case Contact::TYPE_RELAY: case Contact::TYPE_RELAY:
$prefix = ' application_'; $prefix = ' application_';

View file

@ -113,9 +113,6 @@ class Link
try { try {
$curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]); $curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]);
if (empty($curlResult) || !$curlResult->isSuccess()) {
return [];
}
} catch (\Exception $exception) { } catch (\Exception $exception) {
Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]); Logger::notice('Error fetching url', ['url' => $url, 'exception' => $exception]);
return []; return [];

View file

@ -699,7 +699,7 @@ class Media
if (preg_match_all("/\[url\](https?:.*?)\[\/url\]/ism", $body, $matches)) { if (preg_match_all("/\[url\](https?:.*?)\[\/url\]/ism", $body, $matches)) {
foreach ($matches[1] as $url) { foreach ($matches[1] as $url) {
Logger::info('Got page url (link without description)', ['uri-id' => $uriid, 'url' => $url]); Logger::info('Got page url (link without description)', ['uri-id' => $uriid, 'url' => $url]);
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false, $network); $result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false);
if ($result && !in_array($network, [Protocol::ACTIVITYPUB, Protocol::DIASPORA])) { if ($result && !in_array($network, [Protocol::ACTIVITYPUB, Protocol::DIASPORA])) {
self::revertHTMLType($uriid, $url, $fullbody); self::revertHTMLType($uriid, $url, $fullbody);
Logger::debug('Revert HTML type', ['uri-id' => $uriid, 'url' => $url]); Logger::debug('Revert HTML type', ['uri-id' => $uriid, 'url' => $url]);
@ -715,7 +715,7 @@ class Media
if (preg_match_all("/\[url\=(https?:.*?)\].*?\[\/url\]/ism", $body, $matches)) { if (preg_match_all("/\[url\=(https?:.*?)\].*?\[\/url\]/ism", $body, $matches)) {
foreach ($matches[1] as $url) { foreach ($matches[1] as $url) {
Logger::info('Got page url (link with description)', ['uri-id' => $uriid, 'url' => $url]); Logger::info('Got page url (link with description)', ['uri-id' => $uriid, 'url' => $url]);
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false, $network); $result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false);
if ($result && !in_array($network, [Protocol::ACTIVITYPUB, Protocol::DIASPORA])) { if ($result && !in_array($network, [Protocol::ACTIVITYPUB, Protocol::DIASPORA])) {
self::revertHTMLType($uriid, $url, $fullbody); self::revertHTMLType($uriid, $url, $fullbody);
Logger::debug('Revert HTML type', ['uri-id' => $uriid, 'url' => $url]); Logger::debug('Revert HTML type', ['uri-id' => $uriid, 'url' => $url]);
@ -846,7 +846,7 @@ class Media
} }
/** /**
* Update post-media entries * Update post-media entries by id
* *
* @param array $fields * @param array $fields
* @param int $id * @param int $id
@ -857,6 +857,18 @@ class Media
return DBA::update('post-media', $fields, ['id' => $id]); return DBA::update('post-media', $fields, ['id' => $id]);
} }
/**
* Update post-media entries
*
* @param array $fields
* @param array $condition
* @return boolean
*/
public static function update(array $fields, array $condition): bool
{
return DBA::update('post-media', $fields, $condition);
}
/** /**
* Checks if media attachments are associated with the provided item ID. * Checks if media attachments are associated with the provided item ID.
* *

View file

@ -49,7 +49,7 @@ class Embed extends BaseAdmin
require_once "view/theme/$theme/config.php"; require_once "view/theme/$theme/config.php";
if (function_exists('theme_admin_post')) { if (function_exists('theme_admin_post')) {
self::checkFormSecurityTokenRedirectOnError('/admin/themes/' . $theme . '/embed?mode=minimal', 'admin_theme_settings'); self::checkFormSecurityTokenRedirectOnError('/admin/themes/' . $theme . '/embed?mode=minimal', 'admin_theme_settings');
theme_admin_post($this->appHelper); theme_admin_post();
} }
} }

View file

@ -31,7 +31,7 @@ class Markers extends BaseApi
} }
} }
if (empty($timeline) || empty($last_read_id) || empty($application['id'])) { if ($timeline === '' || $last_read_id === '' || empty($application['id'])) {
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity()); $this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity());
} }

View file

@ -28,12 +28,12 @@ class Show extends ContactEndpoint
$target_cid = BaseApi::getContactIDForSearchterm($this->getRequestValue($request, 'target_screen_name', ''), '', $this->getRequestValue($request, 'target_id', 0), $uid); $target_cid = BaseApi::getContactIDForSearchterm($this->getRequestValue($request, 'target_screen_name', ''), '', $this->getRequestValue($request, 'target_id', 0), $uid);
$source = Contact::getById($source_cid); $source = Contact::getById($source_cid);
if (empty($source)) { if ($source === false) {
throw new NotFoundException('Source not found'); throw new NotFoundException('Source not found');
} }
$target = Contact::getById($target_cid); $target = Contact::getById($target_cid);
if (empty($source)) { if ($target === false) {
throw new NotFoundException('Target not found'); throw new NotFoundException('Target not found');
} }

View file

@ -511,7 +511,7 @@ class BaseApi extends BaseModule
/** /**
* @param int $errorno * @param int $errorno
* @param Error $error * @param Error $error
* @return void * @return never
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
*/ */
protected function logAndJsonError(int $errorno, Error $error) protected function logAndJsonError(int $errorno, Error $error)

View file

@ -131,7 +131,7 @@ abstract class BaseNotifications extends BaseModule
$notif_tpl = Renderer::getMarkupTemplate('notifications/notifications.tpl'); $notif_tpl = Renderer::getMarkupTemplate('notifications/notifications.tpl');
return Renderer::replaceMacros($notif_tpl, [ return Renderer::replaceMacros($notif_tpl, [
'$header' => $header ?? $this->t('Notifications'), '$header' => $header ?: $this->t('Notifications'),
'$tabs' => $tabs, '$tabs' => $tabs,
'$notifications' => $notifications, '$notifications' => $notifications,
'$noContent' => $noContent, '$noContent' => $noContent,

View file

@ -140,9 +140,9 @@ class API extends BaseModule
$share = intval($request['share'] ?? 0); $share = intval($request['share'] ?? 0);
$isPreview = intval($request['preview'] ?? 0); $isPreview = intval($request['preview'] ?? 0);
$start = DateTimeFormat::convert($strStartDateTime ?? DBA::NULL_DATETIME, 'UTC', $this->timezone); $start = DateTimeFormat::convert($strStartDateTime, 'UTC', $this->timezone);
if (!$noFinish) { if (!$noFinish) {
$finish = DateTimeFormat::convert($strFinishDateTime ?? DBA::NULL_DATETIME, 'UTC', $this->timezone); $finish = DateTimeFormat::convert($strFinishDateTime, 'UTC', $this->timezone);
} else { } else {
$finish = DBA::NULL_DATETIME; $finish = DBA::NULL_DATETIME;
} }

View file

@ -70,6 +70,8 @@ class Circle extends BaseModule
throw new \Exception(DI::l10n()->t('Permission denied.'), 403); throw new \Exception(DI::l10n()->t('Permission denied.'), 403);
} }
$message = '';
if (isset($this->parameters['command'])) { if (isset($this->parameters['command'])) {
$circle_id = $this->parameters['circle']; $circle_id = $this->parameters['circle'];
$contact_id = $this->parameters['contact']; $contact_id = $this->parameters['contact'];
@ -170,6 +172,8 @@ class Circle extends BaseModule
} }
$nocircle = false; $nocircle = false;
$members = [];
$preselected = [];
// @TODO: Replace with parameter from router // @TODO: Replace with parameter from router
if ((DI::args()->getArgc() == 2) && (DI::args()->getArgv()[1] === 'none') || if ((DI::args()->getArgc() == 2) && (DI::args()->getArgv()[1] === 'none') ||
@ -181,9 +185,6 @@ class Circle extends BaseModule
'name' => DI::l10n()->t('Contacts not in any circle'), 'name' => DI::l10n()->t('Contacts not in any circle'),
]; ];
$members = [];
$preselected = [];
$context = $context + [ $context = $context + [
'$title' => $circle['name'], '$title' => $circle['name'],
'$gname' => ['circle_name', DI::l10n()->t('Circle Name: '), $circle['name'], ''], '$gname' => ['circle_name', DI::l10n()->t('Circle Name: '), $circle['name'], ''],

View file

@ -7,18 +7,19 @@
namespace Friendica\Module\Contact; namespace Friendica\Module\Contact;
use Friendica\App; use Friendica\App\Arguments;
use Friendica\App\BaseURL;
use Friendica\App\Page;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Contact\LocalRelationship\Repository\LocalRelationship; use Friendica\Contact\LocalRelationship\Repository\LocalRelationship;
use Friendica\Content\Conversation; use Friendica\Content\Conversation;
use Friendica\Content\Nav; use Friendica\Content\Nav;
use Friendica\Content\Widget; use Friendica\Content\Widget\VCard;
use Friendica\Core\ACL; use Friendica\Core\ACL;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\Theme; use Friendica\Core\Theme;
use Friendica\Model;
use Friendica\Model\Contact as ModelContact; use Friendica\Model\Contact as ModelContact;
use Friendica\Module\Contact; use Friendica\Module\Contact;
use Friendica\Module\Response; use Friendica\Module\Response;
@ -33,7 +34,7 @@ use Psr\Log\LoggerInterface;
class Conversations extends BaseModule class Conversations extends BaseModule
{ {
/** /**
* @var App\Page * @var Page
*/ */
private $page; private $page;
/** /**
@ -49,7 +50,7 @@ class Conversations extends BaseModule
*/ */
private $userSession; private $userSession;
public function __construct(L10n $l10n, LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, Conversation $conversation, IHandleUserSessions $userSession, $server, array $parameters = []) public function __construct(L10n $l10n, LocalRelationship $localRelationship, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, Page $page, Conversation $conversation, IHandleUserSessions $userSession, $server, array $parameters = [])
{ {
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
@ -67,12 +68,12 @@ class Conversations extends BaseModule
// Backward compatibility: Ensure to use the public contact when the user contact is provided // Backward compatibility: Ensure to use the public contact when the user contact is provided
// Remove by version 2022.03 // Remove by version 2022.03
$pcid = Model\Contact::getPublicContactId(intval($this->parameters['id']), $this->userSession->getLocalUserId()); $pcid = ModelContact::getPublicContactId(intval($this->parameters['id']), $this->userSession->getLocalUserId());
if (!$pcid) { if (!$pcid) {
throw new NotFoundException($this->t('Contact not found.')); throw new NotFoundException($this->t('Contact not found.'));
} }
$contact = Model\Contact::getAccountById($pcid); $contact = ModelContact::getAccountById($pcid);
if (empty($contact)) { if (empty($contact)) {
throw new NotFoundException($this->t('Contact not found.')); throw new NotFoundException($this->t('Contact not found.'));
} }
@ -83,7 +84,7 @@ class Conversations extends BaseModule
} }
$localRelationship = $this->localRelationship->getForUserContact($this->userSession->getLocalUserId(), $contact['id']); $localRelationship = $this->localRelationship->getForUserContact($this->userSession->getLocalUserId(), $contact['id']);
if ($localRelationship->rel === Model\Contact::SELF) { if ($localRelationship->rel === ModelContact::SELF) {
$this->baseUrl->redirect('profile/' . $contact['nick']); $this->baseUrl->redirect('profile/' . $contact['nick']);
} }
@ -93,10 +94,12 @@ class Conversations extends BaseModule
$this->page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.css')); $this->page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput.css'));
$this->page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput-typeahead.css')); $this->page->registerStylesheet(Theme::getPathForFile('js/friendica-tagsinput/friendica-tagsinput-typeahead.css'));
$this->page['aside'] .= Widget\VCard::getHTML($contact, true); $this->page['aside'] .= VCard::getHTML($contact, true);
Nav::setSelected('contact'); Nav::setSelected('contact');
$output = '';
if (!$contact['ap-posting-restricted']) { if (!$contact['ap-posting-restricted']) {
$options = [ $options = [
'lockstate' => ACL::getLockstateForUserId($this->userSession->getLocalUserId()) ? 'lock' : 'unlock', 'lockstate' => ACL::getLockstateForUserId($this->userSession->getLocalUserId()) ? 'lock' : 'unlock',
@ -104,12 +107,12 @@ class Conversations extends BaseModule
'bang' => '', 'bang' => '',
'content' => ($contact['contact-type'] == ModelContact::TYPE_COMMUNITY ? '!' : '@') . ($contact['addr'] ?: $contact['url']), 'content' => ($contact['contact-type'] == ModelContact::TYPE_COMMUNITY ? '!' : '@') . ($contact['addr'] ?: $contact['url']),
]; ];
$o = $this->conversation->statusEditor($options); $output = $this->conversation->statusEditor($options);
} }
$o .= Contact::getTabsHTML($contact, Contact::TAB_CONVERSATIONS); $output .= Contact::getTabsHTML($contact, Contact::TAB_CONVERSATIONS);
$o .= Model\Contact::getThreadsFromId($contact['id'], $this->userSession->getLocalUserId(), 0, 0, $request['last_created'] ?? ''); $output .= ModelContact::getThreadsFromId($contact['id'], $this->userSession->getLocalUserId(), 0, 0, $request['last_created'] ?? '');
return $o; return $output;
} }
} }

View file

@ -7,7 +7,8 @@
namespace Friendica\Module\Conversation; namespace Friendica\Module\Conversation;
use Friendica\App; use Friendica\App\Arguments;
use Friendica\App\BaseURL;
use Friendica\App\Mode; use Friendica\App\Mode;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Content\Conversation\Collection\Timelines; use Friendica\Content\Conversation\Collection\Timelines;
@ -31,6 +32,8 @@ use Friendica\Model\Post;
use Friendica\Model\Post\Engagement; use Friendica\Model\Post\Engagement;
use Friendica\Model\Post\SearchIndex; use Friendica\Model\Post\SearchIndex;
use Friendica\Module\Response; use Friendica\Module\Response;
use Friendica\Network\HTTPException\BadRequestException;
use Friendica\Network\HTTPException\ForbiddenException;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
@ -67,7 +70,7 @@ class Timeline extends BaseModule
/** @var string */ /** @var string */
protected $network; protected $network;
/** @var App\Mode $mode */ /** @var Mode $mode */
protected $mode; protected $mode;
/** @var IHandleUserSessions */ /** @var IHandleUserSessions */
protected $session; protected $session;
@ -82,7 +85,7 @@ class Timeline extends BaseModule
/** @var UserDefinedChannel */ /** @var UserDefinedChannel */
protected $channelRepository; protected $channelRepository;
public function __construct(UserDefinedChannel $channel, Mode $mode, IHandleUserSessions $session, Database $database, IManagePersonalConfigValues $pConfig, IManageConfigValues $config, ICanCache $cache, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server = [], array $parameters = []) public function __construct(UserDefinedChannel $channel, Mode $mode, IHandleUserSessions $session, Database $database, IManagePersonalConfigValues $pConfig, IManageConfigValues $config, ICanCache $cache, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server = [], array $parameters = [])
{ {
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
@ -98,8 +101,8 @@ class Timeline extends BaseModule
/** /**
* Computes module parameters from the request and local configuration * Computes module parameters from the request and local configuration
* *
* @throws HTTPException\BadRequestException * @throws BadRequestException
* @throws HTTPException\ForbiddenException * @throws ForbiddenException
*/ */
protected function parseRequest(array $request) protected function parseRequest(array $request)
{ {
@ -308,6 +311,8 @@ class Timeline extends BaseModule
{ {
$table = 'post-engagement'; $table = 'post-engagement';
$condition = [];
if ($this->selectedTab == ChannelEntity::WHATSHOT) { if ($this->selectedTab == ChannelEntity::WHATSHOT) {
if (!is_null($this->accountType)) { if (!is_null($this->accountType)) {
$condition = ["(`comments` > ? OR `activities` > ?) AND `contact-type` = ?", $this->getMedianComments($uid, 4), $this->getMedianActivities($uid, 4), $this->accountType]; $condition = ["(`comments` > ? OR `activities` > ?) AND `contact-type` = ?", $this->getMedianComments($uid, 4), $this->getMedianActivities($uid, 4), $this->accountType];
@ -684,6 +689,7 @@ class Timeline extends BaseModule
protected function getCommunityItems() protected function getCommunityItems()
{ {
$items = $this->selectItems(); $items = $this->selectItems();
$key = '';
if ($this->selectedTab == Community::LOCAL) { if ($this->selectedTab == Community::LOCAL) {
$maxpostperauthor = (int)$this->config->get('system', 'max_author_posts_community_page'); $maxpostperauthor = (int)$this->config->get('system', 'max_author_posts_community_page');
@ -692,9 +698,15 @@ class Timeline extends BaseModule
$maxpostperauthor = (int)$this->config->get('system', 'max_server_posts_community_page'); $maxpostperauthor = (int)$this->config->get('system', 'max_server_posts_community_page');
$key = 'author-gsid'; $key = 'author-gsid';
} else { } else {
$maxpostperauthor = 0; $this->setItemsSeenByCondition([
'unseen' => true,
'uid' => $this->session->getLocalUserId(),
'parent-uri-id' => array_column($items, 'uri-id')
]);
return $items;
} }
if ($maxpostperauthor != 0) {
$count = 1; $count = 1;
$author_posts = []; $author_posts = [];
$selected_items = []; $selected_items = [];
@ -733,9 +745,6 @@ class Timeline extends BaseModule
$items = $this->selectItems(); $items = $this->selectItems();
} }
} }
} else {
$selected_items = $items;
}
$condition = ['unseen' => true, 'uid' => $this->session->getLocalUserId(), 'parent-uri-id' => array_column($selected_items, 'uri-id')]; $condition = ['unseen' => true, 'uid' => $this->session->getLocalUserId(), 'parent-uri-id' => array_column($selected_items, 'uri-id')];
$this->setItemsSeenByCondition($condition); $this->setItemsSeenByCondition($condition);

View file

@ -37,26 +37,13 @@ class PageNotFound extends BaseModule
public function run(ModuleHTTPException $httpException, array $request = []): ResponseInterface public function run(ModuleHTTPException $httpException, array $request = []): ResponseInterface
{ {
/* The URL provided does not resolve to a valid module. // The URL provided does not resolve to a valid module.
*
* On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
* We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
* we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page
* this will often succeed and eventually do the right thing.
*
* Otherwise we are going to emit a 404 not found.
*/
$queryString = $this->server['QUERY_STRING']; $queryString = $this->server['QUERY_STRING'];
// Stupid browser tried to pre-fetch our JavaScript img template. Don't log the event or return anything - just quietly exit. // Stupid browser tried to pre-fetch our JavaScript img template. Don't log the event or return anything - just quietly exit.
if (!empty($queryString) && preg_match('/{[0-9]}/', $queryString) !== 0) { if (!empty($queryString) && preg_match('/{[0-9]}/', $queryString) !== 0) {
System::exit(); System::exit();
} }
if (!empty($queryString) && ($queryString === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
$this->logger->info('index.php: dreamhost_error_hack invoked.', ['Original URI' => $this->server['REQUEST_URI']]);
$this->baseUrl->redirect($this->server['REQUEST_URI']);
}
$this->logger->debug('index.php: page not found.', [ $this->logger->debug('index.php: page not found.', [
'request_uri' => $this->server['REQUEST_URI'], 'request_uri' => $this->server['REQUEST_URI'],
'address' => $this->remoteAddress, 'address' => $this->remoteAddress,

View file

@ -166,12 +166,13 @@ class Display extends BaseModule
*/ */
protected function displaySidebar(array $item) protected function displaySidebar(array $item)
{ {
$author = [];
$shared = $this->contentItem->getSharedPost($item, ['author-link']); $shared = $this->contentItem->getSharedPost($item, ['author-link']);
if (!empty($shared) && empty($shared['comment'])) { if (array_key_exists('comment', $shared) && strval($shared['comment']) === '') {
$author = Contact::getByURLForUser($shared['post']['author-link'], $this->session->getLocalUserId()); $author = Contact::getByURLForUser($shared['post']['author-link'], $this->session->getLocalUserId());
} }
if (empty($contact)) { if ($author === []) {
$author = Contact::getById($item['author-id']); $author = Contact::getById($item['author-id']);
} }

View file

@ -65,31 +65,26 @@ class Magic extends BaseModule
$this->logger->debug('Invoked', ['request' => $request]); $this->logger->debug('Invoked', ['request' => $request]);
$addr = $request['addr'] ?? ''; $addr = (string) $request['addr'] ?? '';
$bdest = $request['bdest'] ?? ''; $bdest = (string) $request['bdest'] ?? '';
$dest = $request['dest'] ?? ''; $dest = (string) $request['dest'] ?? '';
$rev = intval($request['rev'] ?? 0);
$owa = intval($request['owa'] ?? 0); $owa = intval($request['owa'] ?? 0);
$delegate = $request['delegate'] ?? '';
// bdest is preferred as it is hex-encoded and can survive url rewrite and argument parsing // bdest is preferred as it is hex-encoded and can survive url rewrite and argument parsing
if (!empty($bdest)) { if ($bdest !== '') {
$dest = hex2bin($bdest); $dest = hex2bin($bdest);
$this->logger->debug('bdest detected', ['dest' => $dest]); $this->logger->debug('bdest detected', ['dest' => $dest]);
} }
$target = $dest ?: $addr; $target = $dest ?: $addr;
if ($addr ?: $dest) {
$contact = Contact::getByURL($addr ?: $dest); $contact = Contact::getByURL($addr ?: $dest);
} if ($contact === [] && $owa === 0) {
if (empty($contact)) {
if (!$owa) {
$this->logger->info('No contact record found, no oWA, redirecting to destination.', ['request' => $request, 'server' => $_SERVER, 'dest' => $dest]); $this->logger->info('No contact record found, no oWA, redirecting to destination.', ['request' => $request, 'server' => $_SERVER, 'dest' => $dest]);
$this->appHelper->redirect($dest); $this->appHelper->redirect($dest);
} }
} else {
if ($contact !== []) {
// Redirect if the contact is already authenticated on this site. // Redirect if the contact is already authenticated on this site.
if ($this->appHelper->getContactId() && strpos($contact['nurl'], Strings::normaliseLink($this->baseUrl)) !== false) { if ($this->appHelper->getContactId() && strpos($contact['nurl'], Strings::normaliseLink($this->baseUrl)) !== false) {
$this->logger->info('Contact is already authenticated, redirecting to destination.', ['dest' => $dest]); $this->logger->info('Contact is already authenticated, redirecting to destination.', ['dest' => $dest]);
@ -99,7 +94,7 @@ class Magic extends BaseModule
$this->logger->debug('Contact found', ['url' => $contact['url']]); $this->logger->debug('Contact found', ['url' => $contact['url']]);
} }
if (!$this->userSession->getLocalUserId() || !$owa) { if (!$this->userSession->getLocalUserId() || $owa === 0) {
$this->logger->notice('Not logged in or not OWA, redirecting to destination.', ['uid' => $this->userSession->getLocalUserId(), 'owa' => $owa, 'dest' => $dest]); $this->logger->notice('Not logged in or not OWA, redirecting to destination.', ['uid' => $this->userSession->getLocalUserId(), 'owa' => $owa, 'dest' => $dest]);
$this->appHelper->redirect($dest); $this->appHelper->redirect($dest);
} }

View file

@ -48,15 +48,18 @@ class Active extends BaseUsers
{ {
parent::content(); parent::content();
$action = $this->parameters['action'] ?? ''; $action = (string) $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0; $uid = (int) $this->parameters['uid'] ?? 0;
if ($uid) { if ($uid === 0) {
$user = User::getById($uid, ['username', 'blocked']);
if (!$user) {
$this->systemMessages->addNotice($this->t('User not found')); $this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users'); $this->baseUrl->redirect('moderation/users');
} }
$user = User::getById($uid, ['username', 'blocked']);
if (!is_array($user)) {
$this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users');
} }
switch ($action) { switch ($action) {

View file

@ -48,15 +48,18 @@ class Blocked extends BaseUsers
{ {
parent::content(); parent::content();
$action = $this->parameters['action'] ?? ''; $action = (string) $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0; $uid = (int) $this->parameters['uid'] ?? 0;
if ($uid) { if ($uid === 0) {
$user = User::getById($uid, ['username', 'blocked']);
if (!$user) {
$this->systemMessages->addNotice($this->t('User not found')); $this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users'); $this->baseUrl->redirect('moderation/users');
} }
$user = User::getById($uid, ['username', 'blocked']);
if (!is_array($user)) {
$this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users');
} }
switch ($action) { switch ($action) {

View file

@ -55,15 +55,18 @@ class Index extends BaseUsers
{ {
parent::content(); parent::content();
$action = $this->parameters['action'] ?? ''; $action = (string) $this->parameters['action'] ?? '';
$uid = $this->parameters['uid'] ?? 0; $uid = (int) $this->parameters['uid'] ?? 0;
if ($uid) { if ($uid === 0) {
$user = User::getById($uid, ['username', 'blocked']);
if (!$user) {
$this->systemMessages->addNotice($this->t('User not found')); $this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users'); $this->baseUrl->redirect('moderation/users');
} }
$user = User::getById($uid, ['username', 'blocked']);
if (!is_array($user)) {
$this->systemMessages->addNotice($this->t('User not found'));
$this->baseUrl->redirect('moderation/users');
} }
switch ($action) { switch ($action) {

View file

@ -66,12 +66,30 @@ class Token extends BaseApi
$this->logAndJsonError(401, $this->errorFactory->Unauthorized('invalid_client', $this->t('Invalid data or unknown client'))); $this->logAndJsonError(401, $this->errorFactory->Unauthorized('invalid_client', $this->t('Invalid data or unknown client')));
} }
if ($request['grant_type'] == 'client_credentials') { $grant_type = (string) $request['grant_type'];
if (!in_array($grant_type, ['client_credentials', 'authorization_code'])) {
Logger::warning('Unsupported or missing grant type', ['request' => $_REQUEST]);
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity($this->t('Unsupported or missing grant type')));
}
if ($grant_type === 'client_credentials') {
// the "client_credentials" are used as a token for the application itself. // the "client_credentials" are used as a token for the application itself.
// see https://aaronparecki.com/oauth-2-simplified/#client-credentials // see https://aaronparecki.com/oauth-2-simplified/#client-credentials
$token = OAuth::createTokenForUser($application, 0, ''); $token = OAuth::createTokenForUser($application, 0, '');
$me = null;
} elseif ($request['grant_type'] == 'authorization_code') { $object = new \Friendica\Object\Api\Mastodon\Token(
$token['access_token'],
'Bearer',
$application['scopes'],
$token['created_at'],
null
);
$this->jsonExit($object->toArray());
}
// now check for $grant_type === 'authorization_code'
// For security reasons only allow freshly created tokens // For security reasons only allow freshly created tokens
$redirect_uri = strtok($request['redirect_uri'],'?'); $redirect_uri = strtok($request['redirect_uri'],'?');
$condition = [ $condition = [
@ -84,14 +102,16 @@ class Token extends BaseApi
$this->logger->notice('Token not found or outdated', $condition); $this->logger->notice('Token not found or outdated', $condition);
$this->logAndJsonError(401, $this->errorFactory->Unauthorized()); $this->logAndJsonError(401, $this->errorFactory->Unauthorized());
} }
$owner = User::getOwnerDataById($token['uid']);
$me = $owner['url'];
} else {
Logger::warning('Unsupported or missing grant type', ['request' => $_REQUEST]);
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity($this->t('Unsupported or missing grant type')));
}
$object = new \Friendica\Object\Api\Mastodon\Token($token['access_token'], 'Bearer', $application['scopes'], $token['created_at'], $me); $owner = User::getOwnerDataById($token['uid']);
$object = new \Friendica\Object\Api\Mastodon\Token(
$token['access_token'],
'Bearer',
$application['scopes'],
$token['created_at'],
$owner['url']
);
$this->jsonExit($object->toArray()); $this->jsonExit($object->toArray());
} }

View file

@ -27,9 +27,6 @@ class OpenSearch extends BaseModule
/** @var IManageConfigValues */ /** @var IManageConfigValues */
private $config; private $config;
/** @var App\baseUrl */
protected $baseUrl;
/** @var string */ /** @var string */
private $basePath; private $basePath;
@ -39,7 +36,6 @@ class OpenSearch extends BaseModule
$this->config = $config; $this->config = $config;
$this->basePath = $basePath->getPath(); $this->basePath = $basePath->getPath();
$this->baseUrl = $baseUrl;
} }
/** /**

View file

@ -143,6 +143,8 @@ class Photo extends BaseApi
$cacheable = ($photo['allow_cid'] . $photo['allow_gid'] . $photo['deny_cid'] . $photo['deny_gid'] === '') && (isset($photo['cacheable']) ? $photo['cacheable'] : true); $cacheable = ($photo['allow_cid'] . $photo['allow_gid'] . $photo['deny_cid'] . $photo['deny_gid'] === '') && (isset($photo['cacheable']) ? $photo['cacheable'] : true);
$stamp = microtime(true); $stamp = microtime(true);
$imgdata = '';
$mimetype = false;
if (empty($request['blur']) || empty($photo['blurhash'])) { if (empty($request['blur']) || empty($photo['blurhash'])) {
$imgdata = MPhoto::getImageDataForPhoto($photo); $imgdata = MPhoto::getImageDataForPhoto($photo);
@ -150,7 +152,9 @@ class Photo extends BaseApi
} }
if (empty($imgdata) && empty($photo['blurhash'])) { if (empty($imgdata) && empty($photo['blurhash'])) {
throw new HTTPException\NotFoundException(); throw new HTTPException\NotFoundException();
} elseif (empty($imgdata) && !empty($photo['blurhash'])) { }
if (empty($imgdata) && !empty($photo['blurhash'])) {
$image = new Image('', image_type_to_mime_type(IMAGETYPE_WEBP)); $image = new Image('', image_type_to_mime_type(IMAGETYPE_WEBP));
$image->getFromBlurHash($photo['blurhash'], $photo['width'], $photo['height']); $image->getFromBlurHash($photo['blurhash'], $photo['width'], $photo['height']);
$imgdata = $image->asString(); $imgdata = $image->asString();
@ -376,6 +380,9 @@ class Photo extends BaseApi
Logger::debug('Expected Content-Type', ['mime' => $mimetext, 'url' => $url]); Logger::debug('Expected Content-Type', ['mime' => $mimetext, 'url' => $url]);
} }
} }
$url = '';
if (empty($mimetext) && !empty($contact['blurhash'])) { if (empty($mimetext) && !empty($contact['blurhash'])) {
$image = new Image('', image_type_to_mime_type(IMAGETYPE_WEBP)); $image = new Image('', image_type_to_mime_type(IMAGETYPE_WEBP));
$image->getFromBlurHash($contact['blurhash'], $customsize, $customsize); $image->getFromBlurHash($contact['blurhash'], $customsize, $customsize);

View file

@ -77,11 +77,12 @@ class Remove extends \Friendica\BaseModule
$tag_text = Tag::getCSVByURIId($item['uri-id']); $tag_text = Tag::getCSVByURIId($item['uri-id']);
$tags = explode(',', $tag_text); if ($tag_text === '') {
if (empty($tags)) {
$this->baseUrl->redirect($returnUrl); $this->baseUrl->redirect($returnUrl);
} }
$tags = explode(',', $tag_text);
$tag_checkboxes = array_map(function ($tag_text) { $tag_checkboxes = array_map(function ($tag_text) {
return ['tag[' . bin2hex($tag_text) . ']', BBCode::toPlaintext($tag_text)]; return ['tag[' . bin2hex($tag_text) . ']', BBCode::toPlaintext($tag_text)];
}, $tags); }, $tags);

View file

@ -128,6 +128,10 @@ class Photos extends \Friendica\Module\BaseProfile
} }
$ret = ['src' => '', 'filename' => '', 'filesize' => 0, 'type' => '']; $ret = ['src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''];
$src = null;
$filename = '';
$filesize = 0;
$type = '';
Hook::callAll('photo_post_file', $ret); Hook::callAll('photo_post_file', $ret);
@ -167,7 +171,11 @@ class Photos extends \Friendica\Module\BaseProfile
$this->systemMessages->addNotice($this->t('Server can\'t accept new file upload at this time, please contact your administrator')); $this->systemMessages->addNotice($this->t('Server can\'t accept new file upload at this time, please contact your administrator'));
break; break;
} }
if ($src !== null) {
@unlink($src); @unlink($src);
}
$foo = 0; $foo = 0;
Hook::callAll('photo_post_end', $foo); Hook::callAll('photo_post_end', $foo);
return; return;

View file

@ -96,7 +96,7 @@ class Trust extends BaseModule
// exception wanted! // exception wanted!
throw $e; throw $e;
} catch (\Exception $e) { } catch (\Exception $e) {
$this->logger->warning('Unexpected error during authentication.', ['user' => $this->session->getLocalUserId(), 'exception' => $exception]); $this->logger->warning('Unexpected error during authentication.', ['user' => $this->session->getLocalUserId(), 'exception' => $e]);
} }
} }
} }

View file

@ -46,9 +46,6 @@ class Crop extends BaseSettings
$base_image = Photo::selectFirst([], ['resource-id' => $resource_id, 'uid' => DI::userSession()->getLocalUserId(), 'scale' => $scale]); $base_image = Photo::selectFirst([], ['resource-id' => $resource_id, 'uid' => DI::userSession()->getLocalUserId(), 'scale' => $scale]);
if (DBA::isResult($base_image)) { if (DBA::isResult($base_image)) {
$Image = Photo::getImageForPhoto($base_image); $Image = Photo::getImageForPhoto($base_image);
if (empty($Image)) {
throw new HTTPException\InternalServerErrorException();
}
if ($Image->isValid()) { if ($Image->isValid()) {
// If setting for the default profile, unset the profile photo flag from any other photos I own // If setting for the default profile, unset the profile photo flag from any other photos I own
@ -185,7 +182,7 @@ class Crop extends BaseSettings
} }
$Image = Photo::getImageForPhoto($photos[0]); $Image = Photo::getImageForPhoto($photos[0]);
if (empty($Image)) { if (!$Image->isValid()) {
throw new HTTPException\InternalServerErrorException(); throw new HTTPException\InternalServerErrorException();
} }

View file

@ -92,8 +92,6 @@ class RemoveMe extends BaseSettings
$this->baseUrl->redirect(); $this->baseUrl->redirect();
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
$this->systemMessages->addNotice($e->getMessage()); $this->systemMessages->addNotice($e->getMessage());
} finally {
return;
} }
} }

View file

@ -64,6 +64,8 @@ class Xrd extends BaseModule
header('Vary: Accept', false); header('Vary: Accept', false);
$alias = '';
if ($name == User::getActorName()) { if ($name == User::getActorName()) {
$owner = User::getSystemAccount(); $owner = User::getSystemAccount();
if (empty($owner)) { if (empty($owner)) {
@ -108,7 +110,7 @@ class Xrd extends BaseModule
$parts[] = current(explode(';', $part)); $parts[] = current(explode(';', $part));
} }
if (empty($parts)) { if ($parts === []) {
return $default; return $default;
} elseif (in_array('application/jrd+json', $parts) && !in_array('application/xrd+xml', $parts)) { } elseif (in_array('application/jrd+json', $parts) && !in_array('application/xrd+xml', $parts)) {
return Response::TYPE_JSON; return Response::TYPE_JSON;

View file

@ -41,13 +41,13 @@ class FormattedNotify extends BaseDataTransferObject
public function __construct(string $label, string $link, string $image, string $url, string $text, string $when, string $ago, bool $seen) public function __construct(string $label, string $link, string $image, string $url, string $text, string $when, string $ago, bool $seen)
{ {
$this->label = $label ?? ''; $this->label = $label;
$this->link = $link ?? ''; $this->link = $link;
$this->image = $image ?? ''; $this->image = $image;
$this->url = $url ?? ''; $this->url = $url;
$this->text = $text ?? ''; $this->text = $text;
$this->when = $when ?? ''; $this->when = $when;
$this->ago = $ago ?? ''; $this->ago = $ago;
$this->seen = $seen ?? false; $this->seen = $seen;
} }
} }

View file

@ -220,14 +220,16 @@ class Probe
Logger::notice('Got exception', ['code' => $th->getCode(), 'message' => $th->getMessage()]); Logger::notice('Got exception', ['code' => $th->getCode(), 'message' => $th->getMessage()]);
return []; return [];
} }
$ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0); $ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0);
$host_url = $host;
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
$xml = $curlResult->getBodyString(); $xml = $curlResult->getBodyString();
$xrd = XML::parseString($xml, true); $xrd = XML::parseString($xml, true);
if (!empty($url)) { if (!empty($url)) {
$host_url = 'https://' . $host; $host_url = 'https://' . $host;
} else {
$host_url = $host;
} }
} elseif ($curlResult->isTimeout()) { } elseif ($curlResult->isTimeout()) {
Logger::info('Probing timeout', ['url' => $ssl_url]); Logger::info('Probing timeout', ['url' => $ssl_url]);
@ -550,6 +552,7 @@ class Probe
public static function getWebfingerArray(string $uri): array public static function getWebfingerArray(string $uri): array
{ {
$parts = parse_url($uri); $parts = parse_url($uri);
$lrdd = [];
if (!empty($parts['scheme']) && !empty($parts['host'])) { if (!empty($parts['scheme']) && !empty($parts['host'])) {
$host = $parts['host']; $host = $parts['host'];
@ -562,8 +565,11 @@ class Probe
$nick = ''; $nick = '';
$addr = ''; $addr = '';
$path_parts = explode('/', trim($parts['path'] ?? '', '/')); $path_parts = [];
if (!empty($path_parts)) {
if (array_key_exists('path', $parts) && trim(strval($parts['path']), '/') !== '') {
$path_parts = explode('/', trim($parts['path'], '/'));
$nick = ltrim(end($path_parts), '@'); $nick = ltrim(end($path_parts), '@');
$addr = $nick . '@' . $host; $addr = $nick . '@' . $host;
} }
@ -574,7 +580,7 @@ class Probe
} }
if (empty($webfinger) && empty($lrdd)) { if (empty($webfinger) && empty($lrdd)) {
while (empty($lrdd) && empty($webfinger) && (sizeof($path_parts) > 1)) { while (empty($lrdd) && empty($webfinger) && (count($path_parts) > 1)) {
$host .= '/' . array_shift($path_parts); $host .= '/' . array_shift($path_parts);
$baseurl = $parts['scheme'] . '://' . $host; $baseurl = $parts['scheme'] . '://' . $host;
@ -668,8 +674,10 @@ class Probe
return null; return null;
} }
$detected = '';
// First try the address because this is the primary purpose of webfinger // First try the address because this is the primary purpose of webfinger
if (!empty($addr)) { if ($addr !== '') {
$detected = $addr; $detected = $addr;
$path = str_replace('{uri}', urlencode('acct:' . $addr), $template); $path = str_replace('{uri}', urlencode('acct:' . $addr), $template);
$webfinger = self::webfinger($path, $type); $webfinger = self::webfinger($path, $type);
@ -823,13 +831,15 @@ class Probe
*/ */
private static function zot(array $webfinger, array $data): array private static function zot(array $webfinger, array $data): array
{ {
$zot_url = '';
foreach ($webfinger['links'] as $link) { foreach ($webfinger['links'] as $link) {
if (($link['rel'] == 'http://purl.org/zot/protocol/6.0') && !empty($link['href'])) { if (($link['rel'] == 'http://purl.org/zot/protocol/6.0') && !empty($link['href'])) {
$zot_url = $link['href']; $zot_url = $link['href'];
} }
} }
if (empty($zot_url)) { if ($zot_url === '') {
return $data; return $data;
} }
@ -1429,7 +1439,7 @@ class Probe
&& !empty($data['guid']) && !empty($data['guid'])
&& !empty($data['baseurl']) && !empty($data['baseurl'])
&& !empty($data['pubkey']) && !empty($data['pubkey'])
&& !empty($hcard_url) && $hcard_url !== ''
) { ) {
$data['network'] = Protocol::DIASPORA; $data['network'] = Protocol::DIASPORA;
$data['manually-approve'] = false; $data['manually-approve'] = false;
@ -1776,7 +1786,7 @@ class Probe
$password = ''; $password = '';
openssl_private_decrypt(hex2bin($mailacct['pass']), $password, $user['prvkey']); openssl_private_decrypt(hex2bin($mailacct['pass']), $password, $user['prvkey']);
$mbox = Email::connect($mailbox, $mailacct['user'], $password); $mbox = Email::connect($mailbox, $mailacct['user'], $password);
if (!$mbox) { if ($mbox === false) {
return []; return [];
} }
@ -1828,7 +1838,7 @@ class Probe
} }
} }
if (!empty($mbox)) { if ($mbox !== false) {
imap_close($mbox); imap_close($mbox);
} }

View file

@ -62,7 +62,7 @@ class User extends BaseDataTransferObject
protected $default_profile; protected $default_profile;
/** @var bool */ /** @var bool */
protected $default_profile_image; protected $default_profile_image;
/** @var Status */ /** @var array */
protected $status; protected $status;
/** @var array */ /** @var array */
protected $withheld_in_countries; protected $withheld_in_countries;
@ -117,12 +117,11 @@ class User extends BaseDataTransferObject
* @param array $publicContact Full contact table record with uid = 0 * @param array $publicContact Full contact table record with uid = 0
* @param array $apcontact Optional full apcontact table record * @param array $apcontact Optional full apcontact table record
* @param array $userContact Optional full contact table record with uid != 0 * @param array $userContact Optional full contact table record with uid != 0
* @param null $status
* @param bool $include_user_entities Whether to add the entities property * @param bool $include_user_entities Whether to add the entities property
* *
* @throws InternalServerErrorException * @throws InternalServerErrorException
*/ */
public function __construct(array $publicContact, array $apcontact = [], array $userContact = [], $status = null, bool $include_user_entities = true) public function __construct(array $publicContact, array $apcontact = [], array $userContact = [], ?Status $status = null, bool $include_user_entities = true)
{ {
$uid = $userContact['uid'] ?? 0; $uid = $userContact['uid'] ?? 0;
@ -156,10 +155,10 @@ class User extends BaseDataTransferObject
$this->default_profile = false; $this->default_profile = false;
$this->default_profile_image = false; $this->default_profile_image = false;
if (!empty($status)) { if ($status === null) {
$this->status = $status;
} else {
unset($this->status); unset($this->status);
} else {
$this->status = $status;
} }
// Unused optional fields // Unused optional fields

View file

@ -771,7 +771,7 @@ class Image
public function getBlurHash(): string public function getBlurHash(): string
{ {
$image = New Image($this->asString(), $this->getType(), $this->filename, false); $image = New Image($this->asString(), $this->getType(), $this->filename, false);
if (empty($image) || !$this->isValid()) { if (!$this->isValid()) {
return ''; return '';
} }
@ -827,6 +827,7 @@ class Image
{ {
$scaled = Images::getScalingDimensions($width, $height, 90); $scaled = Images::getScalingDimensions($width, $height, 90);
$pixels = Blurhash::decode($blurhash, $scaled['width'], $scaled['height']); $pixels = Blurhash::decode($blurhash, $scaled['width'], $scaled['height']);
$draw = null;
if ($this->isImagick()) { if ($this->isImagick()) {
$this->image = new Imagick(); $this->image = new Imagick();
@ -839,7 +840,7 @@ class Image
for ($y = 0; $y < $scaled['height']; ++$y) { for ($y = 0; $y < $scaled['height']; ++$y) {
for ($x = 0; $x < $scaled['width']; ++$x) { for ($x = 0; $x < $scaled['width']; ++$x) {
[$r, $g, $b] = $pixels[$y][$x]; [$r, $g, $b] = $pixels[$y][$x];
if ($this->isImagick()) { if ($draw !== null) {
$draw->setFillColor("rgb($r, $g, $b)"); $draw->setFillColor("rgb($r, $g, $b)");
$draw->point($x, $y); $draw->point($x, $y);
} else { } else {
@ -848,7 +849,7 @@ class Image
} }
} }
if ($this->isImagick()) { if ($draw !== null) {
$this->image->drawImage($draw); $this->image->drawImage($draw);
$this->width = $this->image->getImageWidth(); $this->width = $this->image->getImageWidth();
$this->height = $this->image->getImageHeight(); $this->height = $this->image->getImageHeight();

View file

@ -323,7 +323,7 @@ class ClientToServer
$requester_id = Contact::getIdForURL($requester, $owner['uid']); $requester_id = Contact::getIdForURL($requester, $owner['uid']);
if (!empty($requester_id)) { if (!empty($requester_id)) {
$permissionSets = DI::permissionSet()->selectByContactId($requester_id, $owner['uid']); $permissionSets = DI::permissionSet()->selectByContactId($requester_id, $owner['uid']);
if (!empty($permissionSets)) { if (count($permissionSets) > 0) {
$condition = ['psid' => array_merge($permissionSets->column('id'), $condition = ['psid' => array_merge($permissionSets->column('id'),
[DI::permissionSet()->selectPublicForUser($owner['uid'])])]; [DI::permissionSet()->selectPublicForUser($owner['uid'])])];
} }

View file

@ -42,6 +42,8 @@ class Delivery
continue; continue;
} }
$result = [];
if (!$serverfail) { if (!$serverfail) {
$result = self::deliverToInbox($post['command'], 0, $inbox, $owner, $post['receivers'], $post['uri-id']); $result = self::deliverToInbox($post['command'], 0, $inbox, $owner, $post['receivers'], $post['uri-id']);
@ -121,11 +123,12 @@ class Delivery
$serverfail = $response->isTimeout(); $serverfail = $response->isTimeout();
} catch (\Throwable $th) { } catch (\Throwable $th) {
Logger::notice('Got exception', ['code' => $th->getCode(), 'message' => $th->getMessage()]); Logger::notice('Got exception', ['code' => $th->getCode(), 'message' => $th->getMessage()]);
$response = null;
$success = false; $success = false;
$serverfail = true; $serverfail = true;
} }
$runtime = microtime(true) - $timestamp; $runtime = microtime(true) - $timestamp;
if (!$success) { if ($success === false) {
// 5xx errors are problems on the server. We don't need to continue delivery then. // 5xx errors are problems on the server. We don't need to continue delivery then.
if (!$serverfail && ($response->getReturnCode() >= 500) && ($response->getReturnCode() <= 599)) { if (!$serverfail && ($response->getReturnCode() >= 500) && ($response->getReturnCode() <= 599)) {
$serverfail = true; $serverfail = true;

View file

@ -1361,6 +1361,7 @@ class Processor
} }
$hash = substr($tag['name'], 0, 1); $hash = substr($tag['name'], 0, 1);
$type = 0;
if ($tag['type'] == 'Mention') { if ($tag['type'] == 'Mention') {
if (in_array($hash, [Tag::TAG_CHARACTER[Tag::MENTION], if (in_array($hash, [Tag::TAG_CHARACTER[Tag::MENTION],
@ -1616,7 +1617,7 @@ class Processor
return []; return [];
} }
if (!self::isValidObject($object, $url)) { if (!self::isValidObject($object)) {
return []; return [];
} }
@ -1657,10 +1658,6 @@ class Processor
return ''; return '';
} }
if (empty($curlResult)) {
return '';
}
$body = $curlResult->getBodyString(); $body = $curlResult->getBodyString();
if (!$curlResult->isSuccess() || empty($body)) { if (!$curlResult->isSuccess() || empty($body)) {
if (in_array($curlResult->getReturnCode(), [403, 404, 406, 410])) { if (in_array($curlResult->getReturnCode(), [403, 404, 406, 410])) {
@ -1680,7 +1677,7 @@ class Processor
return null; return null;
} }
if (!self::isValidObject($object, $url)) { if (!self::isValidObject($object)) {
return null; return null;
} }
@ -1829,6 +1826,8 @@ class Processor
Logger::notice('Fetch replies - start', ['replies' => $url, 'callstack' => $child['callstack'], 'system' => $callstack]); Logger::notice('Fetch replies - start', ['replies' => $url, 'callstack' => $child['callstack'], 'system' => $callstack]);
$fetched = 0; $fetched = 0;
foreach ($replies as $reply) { foreach ($replies as $reply) {
$id = '';
if (is_array($reply)) { if (is_array($reply)) {
$ldobject = JsonLD::compact($reply); $ldobject = JsonLD::compact($reply);
$id = JsonLD::fetchElement($ldobject, '@id'); $id = JsonLD::fetchElement($ldobject, '@id');
@ -2120,9 +2119,8 @@ class Processor
self::transmitPendingEvents($cid, $owner['uid']); self::transmitPendingEvents($cid, $owner['uid']);
} }
if (empty($contact)) {
Contact::update(['hub-verify' => $activity['id'], 'protocol' => Protocol::ACTIVITYPUB], ['id' => $cid]); Contact::update(['hub-verify' => $activity['id'], 'protocol' => Protocol::ACTIVITYPUB], ['id' => $cid]);
}
Logger::notice('Follow user ' . $uid . ' from contact ' . $cid . ' with id ' . $activity['id']); Logger::notice('Follow user ' . $uid . ' from contact ' . $cid . ' with id ' . $activity['id']);
Queue::remove($activity); Queue::remove($activity);
} }
@ -2334,9 +2332,10 @@ class Processor
*/ */
public static function acceptFollowUser(array $activity) public static function acceptFollowUser(array $activity)
{ {
$check_id = false;
if (!empty($activity['object_actor'])) { if (!empty($activity['object_actor'])) {
$uid = User::getIdForURL($activity['object_actor']); $uid = User::getIdForURL($activity['object_actor']);
$check_id = false;
} elseif (!empty($activity['receiver']) && (count($activity['receiver']) == 1)) { } elseif (!empty($activity['receiver']) && (count($activity['receiver']) == 1)) {
$uid = array_shift($activity['receiver']); $uid = array_shift($activity['receiver']);
$check_id = true; $check_id = true;

View file

@ -414,7 +414,7 @@ class Queue
{ {
$entries = DBA::select('inbox-entry', ['id'], ["NOT `trust` AND `wid` IS NULL"], ['order' => ['id' => true]]); $entries = DBA::select('inbox-entry', ['id'], ["NOT `trust` AND `wid` IS NULL"], ['order' => ['id' => true]]);
while ($entry = DBA::fetch($entries)) { while ($entry = DBA::fetch($entries)) {
$data = self::reprepareActivityById($entry['id'], false); $data = self::reprepareActivityById($entry['id']);
if ($data['trust']) { if ($data['trust']) {
DBA::update('inbox-entry', ['trust' => true], ['id' => $entry['id']]); DBA::update('inbox-entry', ['trust' => true], ['id' => $entry['id']]);
} }

View file

@ -307,6 +307,7 @@ class Receiver
$id = JsonLD::fetchElement($activity, '@id'); $id = JsonLD::fetchElement($activity, '@id');
$type = JsonLD::fetchElement($activity, '@type'); $type = JsonLD::fetchElement($activity, '@type');
$object_id = JsonLD::fetchElement($activity, 'as:object', '@id'); $object_id = JsonLD::fetchElement($activity, 'as:object', '@id');
$object_type = '';
if (!empty($object_id) && in_array($type, ['as:Create', 'as:Update'])) { if (!empty($object_id) && in_array($type, ['as:Create', 'as:Update'])) {
$fetch_id = $object_id; $fetch_id = $object_id;
@ -618,7 +619,7 @@ class Receiver
} }
$actor = JsonLD::fetchElement($activity, 'as:actor', '@id'); $actor = JsonLD::fetchElement($activity, 'as:actor', '@id');
if (empty($actor)) { if ($actor === null || $actor === '') {
Logger::info('Empty actor', ['activity' => $activity]); Logger::info('Empty actor', ['activity' => $activity]);
return true; return true;
} }
@ -630,7 +631,7 @@ class Receiver
$id = JsonLD::fetchElement($activity, '@id'); $id = JsonLD::fetchElement($activity, '@id');
$object_id = JsonLD::fetchElement($activity, 'as:object', '@id'); $object_id = JsonLD::fetchElement($activity, 'as:object', '@id');
if (!empty($published) && !empty($object_id) && in_array($type, ['as:Create', 'as:Update']) && in_array($object_type, self::CONTENT_TYPES) if (!empty($published) && $object_id !== null && in_array($type, ['as:Create', 'as:Update']) && in_array($object_type, self::CONTENT_TYPES)
&& ($push || ($completion != self::COMPLETION_MANUAL)) && DI::contentItem()->isTooOld($published) && !Post::exists(['uri' => $object_id])) { && ($push || ($completion != self::COMPLETION_MANUAL)) && DI::contentItem()->isTooOld($published) && !Post::exists(['uri' => $object_id])) {
Logger::debug('Activity is too old. It will not be processed', ['push' => $push, 'completion' => $completion, 'type' => $type, 'object-type' => $object_type, 'published' => $published, 'id' => $id, 'object-id' => $object_id]); Logger::debug('Activity is too old. It will not be processed', ['push' => $push, 'completion' => $completion, 'type' => $type, 'object-type' => $object_type, 'published' => $published, 'id' => $id, 'object-id' => $object_id]);
return true; return true;
@ -641,7 +642,7 @@ class Receiver
// Test the provided signatures against the actor and "attributedTo" // Test the provided signatures against the actor and "attributedTo"
if ($trust_source) { if ($trust_source) {
if (!empty($attributed_to) && !empty($actor)) { if ($attributed_to !== false && $attributed_to !== '') {
$trust_source = (in_array($actor, $signer) && in_array($attributed_to, $signer)); $trust_source = (in_array($actor, $signer) && in_array($attributed_to, $signer));
} else { } else {
$trust_source = in_array($actor, $signer); $trust_source = in_array($actor, $signer);
@ -1185,6 +1186,8 @@ class Receiver
} }
$parent_followers = ''; $parent_followers = '';
$parent_profile = [];
$parent = Post::selectFirstPost(['parent-author-link'], ['uri' => $reply]); $parent = Post::selectFirstPost(['parent-author-link'], ['uri' => $reply]);
if (!empty($parent['parent-author-link'])) { if (!empty($parent['parent-author-link'])) {
$parent_profile = APContact::getByURL($parent['parent-author-link']); $parent_profile = APContact::getByURL($parent['parent-author-link']);

View file

@ -573,11 +573,12 @@ class Transmitter
$exclusive = false; $exclusive = false;
$mention = false; $mention = false;
$audience = []; $audience = [];
$owner = false;
// Check if we should always deliver our stuff via BCC // Check if we should always deliver our stuff via BCC
if (!empty($item['uid'])) { if (!empty($item['uid'])) {
$owner = User::getOwnerDataById($item['uid']); $owner = User::getOwnerDataById($item['uid']);
if (!empty($owner)) { if (is_array($owner)) {
$always_bcc = $owner['hide-friends']; $always_bcc = $owner['hide-friends'];
$is_group = ($owner['account-type'] == User::ACCOUNT_TYPE_COMMUNITY); $is_group = ($owner['account-type'] == User::ACCOUNT_TYPE_COMMUNITY);
@ -1399,7 +1400,7 @@ class Transmitter
$type = self::getTypeOfItem($item); $type = self::getTypeOfItem($item);
if (!$object_mode) { if (!$object_mode) {
$data = ['@context' => $context ?? ActivityPub::CONTEXT]; $data = ['@context' => ActivityPub::CONTEXT];
if ($item['deleted'] && ($item['gravity'] == Item::GRAVITY_ACTIVITY)) { if ($item['deleted'] && ($item['gravity'] == Item::GRAVITY_ACTIVITY)) {
$type = 'Undo'; $type = 'Undo';
@ -1750,6 +1751,7 @@ class Transmitter
$title = $item['title']; $title = $item['title'];
$summary = $item['content-warning'] ?: BBCode::toPlaintext(BBCode::getAbstract($item['body'], Protocol::ACTIVITYPUB)); $summary = $item['content-warning'] ?: BBCode::toPlaintext(BBCode::getAbstract($item['body'], Protocol::ACTIVITYPUB));
$type = '';
if ($item['event-type'] == 'event') { if ($item['event-type'] == 'event') {
$type = 'Event'; $type = 'Event';

View file

@ -12,7 +12,6 @@ use Friendica\Contact\FriendSuggest\Exception\FriendSuggestNotFoundException;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Contact; use Friendica\Model\Contact;
@ -48,6 +47,8 @@ class Delivery
$top_level = false; $top_level = false;
$followup = false; $followup = false;
$public_message = false; $public_message = false;
$parent = false;
$thr_parent = false;
$items = []; $items = [];
if ($cmd == self::MAIL) { if ($cmd == self::MAIL) {

View file

@ -623,22 +623,21 @@ class Diaspora
*/ */
private static function validPosting(array $msg) private static function validPosting(array $msg)
{ {
$data = XML::parseString($msg['message']); $element = XML::parseString($msg['message']);
if (!is_object($data)) { if (!is_object($element)) {
Logger::info('No valid XML', ['message' => $msg['message']]); Logger::info('No valid XML', ['message' => $msg['message']]);
return false; return false;
} }
$oldXML = false;
// Is this the new or the old version? // Is this the new or the old version?
if ($data->getName() == 'XML') { if ($element->getName() === 'XML') {
$oldXML = true; $oldXML = true;
foreach ($data->post->children() as $child) { foreach ($element->post->children() as $child) {
$element = $child; $element = $child;
} }
} else {
$oldXML = false;
$element = $data;
} }
$type = $element->getName(); $type = $element->getName();
@ -1460,7 +1459,7 @@ class Diaspora
*/ */
foreach ($matches as $match) { foreach ($matches as $match) {
if (empty($match)) { if ($match === '') {
continue; continue;
} }
@ -3030,7 +3029,7 @@ class Diaspora
// The "addr" field should always be filled. // The "addr" field should always be filled.
// If this isn't the case, it will raise a notice some lines later. // If this isn't the case, it will raise a notice some lines later.
// And in the log we will see where it came from, and we can handle it there. // And in the log we will see where it came from, and we can handle it there.
Logger::notice('Empty addr', ['contact' => $contact ?? []]); Logger::notice('Empty addr', ['contact' => $contact]);
} }
$envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey ?? '', $public_batch); $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey ?? '', $public_batch);
@ -3655,6 +3654,8 @@ class Diaspora
*/ */
public static function sendFollowup(array $item, array $owner, array $contact, bool $public_batch = false): int public static function sendFollowup(array $item, array $owner, array $contact, bool $public_batch = false): int
{ {
$type = '';
if (in_array($item['verb'], [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE])) { if (in_array($item['verb'], [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE])) {
$message = self::constructAttend($item, $owner); $message = self::constructAttend($item, $owner);
$type = 'event_participation'; $type = 'event_participation';

View file

@ -25,7 +25,7 @@ class Email
* @param string $mailbox The mailbox name * @param string $mailbox The mailbox name
* @param string $username The username * @param string $username The username
* @param string $password The password * @param string $password The password
* @return Connection|resource|bool * @return Connection|false
* @throws \Exception * @throws \Exception
*/ */
public static function connect(string $mailbox, string $username, string $password) public static function connect(string $mailbox, string $username, string $password)

View file

@ -736,7 +736,7 @@ class Feed
$publish_at = date(DateTimeFormat::MYSQL, $publish_time); $publish_at = date(DateTimeFormat::MYSQL, $publish_time);
if (Post\Delayed::add($posting['item']['uri'], $posting['item'], $posting['notify'], Post\Delayed::PREPARED, $publish_at, $posting['taglist'], $posting['attachments'])) { if (Post\Delayed::add($posting['item']['uri'], $posting['item'], $posting['notify'], Post\Delayed::PREPARED, $publish_at, $posting['taglist'], $posting['attachments'])) {
DI::pConfig()->set($item['uid'], 'system', 'last_publish', $publish_time); DI::pConfig()->set($posting['item']['uid'], 'system', 'last_publish', $publish_time);
} }
} }
} }
@ -1407,7 +1407,7 @@ class Feed
$contact = Contact::getByURL($item['author-link']) ?: $owner; $contact = Contact::getByURL($item['author-link']) ?: $owner;
$contact['nickname'] = $contact['nickname'] ?? $contact['nick']; $contact['nickname'] = $contact['nickname'] ?? $contact['nick'];
$author = self::addAuthor($doc, $contact, false); $author = self::addAuthor($doc, $contact);
$entry->appendChild($author); $entry->appendChild($author);
} }
} else { } else {

View file

@ -109,9 +109,9 @@ class NotifyMailBuilder extends MailBuilder
public function withPhoto(string $image, string $link, string $name) public function withPhoto(string $image, string $link, string $name)
{ {
$this->photo = [ $this->photo = [
'image' => $image ?? '', 'image' => $image,
'link' => $link ?? '', 'link' => $link,
'name' => $name ?? '', 'name' => $name,
]; ];
return $this; return $this;

View file

@ -480,10 +480,6 @@ class HTTPSignature
return []; return [];
} }
if (empty($curlResult)) {
return [];
}
if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) { if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) {
Logger::debug('Fetching was unsuccessful', ['url' => $request, 'return-code' => $curlResult->getReturnCode(), 'error-number' => $curlResult->getErrorNumber(), 'error' => $curlResult->getError()]); Logger::debug('Fetching was unsuccessful', ['url' => $request, 'return-code' => $curlResult->getReturnCode(), 'error-number' => $curlResult->getErrorNumber(), 'error' => $curlResult->getError()]);
return []; return [];

View file

@ -308,13 +308,13 @@ class Images
$data = DI::cache()->get($cacheKey); $data = DI::cache()->get($cacheKey);
if (empty($data) || !is_array($data)) { if (!is_array($data)) {
$data = self::getInfoFromURL($url, $ocr); $data = self::getInfoFromURL($url, $ocr);
DI::cache()->set($cacheKey, $data); DI::cache()->set($cacheKey, $data);
} }
return $data ?? []; return $data;
} }
/** /**

View file

@ -286,7 +286,7 @@ class JsonLD
* @param $type * @param $type
* @param $type_value * @param $type_value
* *
* @return string fetched element * @return string|null fetched element
*/ */
public static function fetchElement($array, $element, $key = '@id', $type = null, $type_value = null) public static function fetchElement($array, $element, $key = '@id', $type = null, $type_value = null)
{ {

View file

@ -1087,7 +1087,7 @@ class ParseUrl
$content = JsonLD::fetchElement($jsonld, 'logo', 'url', '@type', 'ImageObject'); $content = JsonLD::fetchElement($jsonld, 'logo', 'url', '@type', 'ImageObject');
if (!empty($content) && is_string($content)) { if (!empty($content) && is_string($content)) {
$jsonldinfo['publisher_img'] = trim($content); $jsonldinfo['publisher_img'] = trim($content);
} elseif (!empty($content) && is_array($content)) { } elseif (is_array($content) && array_key_exists(0, $content)) {
$jsonldinfo['publisher_img'] = trim($content[0]); $jsonldinfo['publisher_img'] = trim($content[0]);
} }

View file

@ -220,7 +220,7 @@ class OnePoll
Logger::info('Mail is enabled'); Logger::info('Mail is enabled');
$mbox = null; $mbox = false;
$user = DBA::selectFirst('user', ['prvkey'], ['uid' => $importer_uid]); $user = DBA::selectFirst('user', ['prvkey'], ['uid' => $importer_uid]);
$condition = ["`server` != ? AND `user` != ? AND `port` != ? AND `uid` = ?", '', '', 0, $importer_uid]; $condition = ["`server` != ? AND `user` != ? AND `port` != ? AND `uid` = ?", '', '', 0, $importer_uid];
@ -232,17 +232,18 @@ class OnePoll
$mbox = Email::connect($mailbox, $mailconf['user'], $password); $mbox = Email::connect($mailbox, $mailconf['user'], $password);
unset($password); unset($password);
Logger::notice('Connect', ['user' => $mailconf['user']]); Logger::notice('Connect', ['user' => $mailconf['user']]);
if ($mbox) {
$fields = ['last_check' => $updated]; if ($mbox === false) {
DBA::update('mailacct', $fields, ['id' => $mailconf['id']]);
Logger::notice('Connected', ['user' => $mailconf['user']]);
} else {
Logger::notice('Connection error', ['user' => $mailconf['user'], 'error' => imap_errors()]); Logger::notice('Connection error', ['user' => $mailconf['user'], 'error' => imap_errors()]);
return false; return false;
} }
$fields = ['last_check' => $updated];
DBA::update('mailacct', $fields, ['id' => $mailconf['id']]);
Logger::notice('Connected', ['user' => $mailconf['user']]);
} }
if (empty($mbox)) { if ($mbox === false) {
return false; return false;
} }

View file

@ -129,3 +129,10 @@ $zap_platforms = [
'hubzilla' => 'hubzilla', 'hubzilla' => 'hubzilla',
'osada' => 'osada', 'osada' => 'osada',
]; ];
return [
'ap_platforms' => $ap_platforms,
'dfrn_platforms' => $dfrn_platforms,
'zap_platforms' => $zap_platforms,
'platforms' => $platforms,
];

View file

@ -5,7 +5,7 @@
// //
// SPDX-License-Identifier: AGPL-3.0-or-later // SPDX-License-Identifier: AGPL-3.0-or-later
namespace Friendica\Test\src\Content; namespace Friendica\Test\src\Content\Text;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\Plaintext; use Friendica\Content\Text\Plaintext;
@ -32,6 +32,7 @@ class PlaintextTest extends FixtureTest
'Ich ignoriere auch Anfragen, wenn sie von Accounts kommen, die ggf. tausenden von anderen Accounts folgen, da ich davon ausgehe, (5/6)', 'Ich ignoriere auch Anfragen, wenn sie von Accounts kommen, die ggf. tausenden von anderen Accounts folgen, da ich davon ausgehe, (5/6)',
'dass da niemand ernsthaft so vielen Accounts folgen kann. (6/6)' 'dass da niemand ernsthaft so vielen Accounts folgen kann. (6/6)'
], ],
],
'test-2' => [ 'test-2' => [
'data' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', 'data' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
'expected' => [ 'expected' => [
@ -42,7 +43,6 @@ class PlaintextTest extends FixtureTest
'sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. (5/6)', 'sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. (5/6)',
'Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. (6/6)' 'Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. (6/6)'
], ],
]
], ],
]; ];
} }

File diff suppressed because it is too large Load diff

View file

@ -198,7 +198,6 @@ $a->strings['I like this (toggle)'] = 'أعجبني (بدِّل)';
$a->strings['Dislike'] = 'لم يعجبني'; $a->strings['Dislike'] = 'لم يعجبني';
$a->strings['I don\'t like this (toggle)'] = 'لم يعجبني (بدِّل)'; $a->strings['I don\'t like this (toggle)'] = 'لم يعجبني (بدِّل)';
$a->strings['Map'] = 'خريطة'; $a->strings['Map'] = 'خريطة';
$a->strings['No system theme config value set.'] = 'لم تُضبط سمة النظام.';
$a->strings['Apologies but the website is unavailable at the moment.'] = 'نعتذر هذا الموقع غير متاح حاليا.'; $a->strings['Apologies but the website is unavailable at the moment.'] = 'نعتذر هذا الموقع غير متاح حاليا.';
$a->strings['Delete this item?'] = 'أتريد حذف العنصر؟'; $a->strings['Delete this item?'] = 'أتريد حذف العنصر؟';
$a->strings['Block this author? They won\'t be able to follow you nor see your public posts, and you won\'t be able to see their posts and their notifications.'] = 'أتريد حظر هذا المتراسل؟ لن يتمكن من متابعتك أو رؤية مشاركاتك العلنية، ولن تكون قادراً على رؤية مشاركاتهم واستلام تنبيهات منهم.'; $a->strings['Block this author? They won\'t be able to follow you nor see your public posts, and you won\'t be able to see their posts and their notifications.'] = 'أتريد حظر هذا المتراسل؟ لن يتمكن من متابعتك أو رؤية مشاركاتك العلنية، ولن تكون قادراً على رؤية مشاركاتهم واستلام تنبيهات منهم.';
@ -206,6 +205,7 @@ $a->strings['toggle mobile'] = 'بدّل واجهة الهاتف';
$a->strings['Method not allowed for this module. Allowed method(s): %s'] = 'هذه الطريقة غير مسموح بها لهذه الوحدة. الطرق المسموح بها: %s'; $a->strings['Method not allowed for this module. Allowed method(s): %s'] = 'هذه الطريقة غير مسموح بها لهذه الوحدة. الطرق المسموح بها: %s';
$a->strings['Page not found.'] = 'لم يُعثر على الصفحة.'; $a->strings['Page not found.'] = 'لم يُعثر على الصفحة.';
$a->strings['You must be logged in to use addons. '] = 'يجب عليك الولوج لاستخدام الإضافات. '; $a->strings['You must be logged in to use addons. '] = 'يجب عليك الولوج لاستخدام الإضافات. ';
$a->strings['No system theme config value set.'] = 'لم تُضبط سمة النظام.';
$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['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['All contacts'] = 'كل المتراسلين';
$a->strings['Followers'] = 'متابِعون'; $a->strings['Followers'] = 'متابِعون';
@ -434,7 +434,6 @@ $a->strings['first'] = 'الأول';
$a->strings['prev'] = 'السابق'; $a->strings['prev'] = 'السابق';
$a->strings['next'] = 'التالي'; $a->strings['next'] = 'التالي';
$a->strings['last'] = 'الأخير'; $a->strings['last'] = 'الأخير';
$a->strings['Image/photo'] = 'صورة';
$a->strings['<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a> %3$s'] = '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a> %3$s'; $a->strings['<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a> %3$s'] = '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a> %3$s';
$a->strings['Link to source'] = 'رابط المصدر'; $a->strings['Link to source'] = 'رابط المصدر';
$a->strings['Click to open/close'] = 'أنقر للفتح/للإغلاق'; $a->strings['Click to open/close'] = 'أنقر للفتح/للإغلاق';
@ -811,7 +810,6 @@ $a->strings['Addons reloaded'] = 'أُعيد تحميل الإضافة';
$a->strings['Addon %s failed to install.'] = 'فشل تثبيت إضافة %s.'; $a->strings['Addon %s failed to install.'] = 'فشل تثبيت إضافة %s.';
$a->strings['Save Settings'] = 'احفظ الإعدادات'; $a->strings['Save Settings'] = 'احفظ الإعدادات';
$a->strings['Reload active addons'] = 'أعد تحميل الإضافات النشطة'; $a->strings['Reload active addons'] = 'أعد تحميل الإضافات النشطة';
$a->strings['There are currently no addons available on your node. You can find the official addon repository at %1$s and might find other interesting addons in the open addon registry at %2$s'] = 'لا توجد حاليا أي إضافات متاحة في عقدتك. يمكنك العثور على مستودع الإضافات الرسمي في %1$s وقد تجد إضافات أخرى مثيرة للاهتمام في سجل الإضافات المفتوحة في %2$s';
$a->strings['Update has been marked successful'] = 'تُحقق من صحة التحديث وعلّم كـ"ناجح"'; $a->strings['Update has been marked successful'] = 'تُحقق من صحة التحديث وعلّم كـ"ناجح"';
$a->strings['Database structure update %s was successfully applied.'] = 'نجح تطبيق التحديث بنية قاعدة البيانات %s.'; $a->strings['Database structure update %s was successfully applied.'] = 'نجح تطبيق التحديث بنية قاعدة البيانات %s.';
$a->strings['Executing of database structure update %s failed with error: %s'] = 'فشل تنفيذ تحديث بنية قاعدة البيانات %s مع رمز الخطأ: %s'; $a->strings['Executing of database structure update %s failed with error: %s'] = 'فشل تنفيذ تحديث بنية قاعدة البيانات %s مع رمز الخطأ: %s';
@ -1345,8 +1343,6 @@ $a->strings['HTML::toMarkdown'] = 'HTML::toMarkdown';
$a->strings['HTML::toPlaintext'] = 'HTML::toPlaintext'; $a->strings['HTML::toPlaintext'] = 'HTML::toPlaintext';
$a->strings['HTML::toPlaintext (compact)'] = 'HTML::toPlaintext (compact)'; $a->strings['HTML::toPlaintext (compact)'] = 'HTML::toPlaintext (compact)';
$a->strings['Decoded post'] = 'مشاركة مفكوكة الترميز'; $a->strings['Decoded post'] = 'مشاركة مفكوكة الترميز';
$a->strings['Post converted'] = 'حُولت المشاركة';
$a->strings['Twitter addon is absent from the addon/ folder.'] = 'إضافة تويتر غير موجودة في مجلد addon.';
$a->strings['Source text'] = 'النص المصدري'; $a->strings['Source text'] = 'النص المصدري';
$a->strings['BBCode'] = 'BBCode'; $a->strings['BBCode'] = 'BBCode';
$a->strings['Markdown'] = 'ماركداون'; $a->strings['Markdown'] = 'ماركداون';
@ -1987,7 +1983,6 @@ $a->strings['Remove My Account'] = 'أزل حسابي';
$a->strings['This will completely remove your account. Once this has been done it is not recoverable.'] = 'سيزال حسابك نهائيًا. لا مجال لتراجع عند انتهائه.'; $a->strings['This will completely remove your account. Once this has been done it is not recoverable.'] = 'سيزال حسابك نهائيًا. لا مجال لتراجع عند انتهائه.';
$a->strings['Please enter your password for verification:'] = 'يرجى إدخال كلمة المرور للتأكيد:'; $a->strings['Please enter your password for verification:'] = 'يرجى إدخال كلمة المرور للتأكيد:';
$a->strings['Please enter your password to access this page.'] = 'يرجى إدخال كلمة المرور للوصول إلى هذه الصفحة.'; $a->strings['Please enter your password to access this page.'] = 'يرجى إدخال كلمة المرور للوصول إلى هذه الصفحة.';
$a->strings['New app-specific password generated.'] = 'أُنشئت كلمة مرور جديدة خاصة بالتطبيق بنجاح.';
$a->strings['Last Used'] = 'آخر استخدام'; $a->strings['Last Used'] = 'آخر استخدام';
$a->strings['Revoke'] = 'أبطل'; $a->strings['Revoke'] = 'أبطل';
$a->strings['Revoke All'] = 'أبطل الكل'; $a->strings['Revoke All'] = 'أبطل الكل';

File diff suppressed because it is too large Load diff

View file

@ -200,7 +200,6 @@ $a->strings['first'] = 'Първа';
$a->strings['prev'] = 'Пред.'; $a->strings['prev'] = 'Пред.';
$a->strings['next'] = 'следващ'; $a->strings['next'] = 'следващ';
$a->strings['last'] = 'Дата на последния одит. '; $a->strings['last'] = 'Дата на последния одит. ';
$a->strings['Image/photo'] = 'Изображение / снимка';
$a->strings['Click to open/close'] = 'Кликнете за отваряне / затваряне'; $a->strings['Click to open/close'] = 'Кликнете за отваряне / затваряне';
$a->strings['$1 wrote:'] = '$ 1 пише:'; $a->strings['$1 wrote:'] = '$ 1 пише:';
$a->strings['Encrypted content'] = 'Шифрирано съдържание'; $a->strings['Encrypted content'] = 'Шифрирано съдържание';

File diff suppressed because it is too large Load diff

View file

@ -300,7 +300,6 @@ $a->strings['first'] = 'Primer';
$a->strings['prev'] = 'Prev'; $a->strings['prev'] = 'Prev';
$a->strings['next'] = 'següent'; $a->strings['next'] = 'següent';
$a->strings['last'] = 'Últim'; $a->strings['last'] = 'Últim';
$a->strings['Image/photo'] = 'Imatge/foto';
$a->strings['Click to open/close'] = 'Clicar per a obrir/tancar'; $a->strings['Click to open/close'] = 'Clicar per a obrir/tancar';
$a->strings['$1 wrote:'] = '$1 va escriure:'; $a->strings['$1 wrote:'] = '$1 va escriure:';
$a->strings['Encrypted content'] = 'Encriptar contingut'; $a->strings['Encrypted content'] = 'Encriptar contingut';
@ -1008,7 +1007,6 @@ $a->strings['Please enter your password for verification:'] = 'Si us plau, intro
$a->strings['Please enter your password to access this page.'] = 'Introduïu la vostra contrasenya per accedir a aquesta pàgina.'; $a->strings['Please enter your password to access this page.'] = 'Introduïu la vostra contrasenya per accedir a aquesta pàgina.';
$a->strings['App-specific password generation failed: The description is empty.'] = 'Ha fallat la generació de contrasenya específica per a laplicació: la descripció està buida.'; $a->strings['App-specific password generation failed: The description is empty.'] = 'Ha fallat la generació de contrasenya específica per a laplicació: la descripció està buida.';
$a->strings['App-specific password generation failed: This description already exists.'] = 'Ha fallat la generació de contrasenya específica per a l\'aplicació: aquesta descripció ja existeix'; $a->strings['App-specific password generation failed: This description already exists.'] = 'Ha fallat la generació de contrasenya específica per a l\'aplicació: aquesta descripció ja existeix';
$a->strings['New app-specific password generated.'] = 'S\'ha generat una contrasenya nova específica per a l\'aplicació.';
$a->strings['App-specific passwords successfully revoked.'] = 'Les contrasenyes específiques de l\'aplicació s\'han revocat correctament.'; $a->strings['App-specific passwords successfully revoked.'] = 'Les contrasenyes específiques de l\'aplicació s\'han revocat correctament.';
$a->strings['App-specific password successfully revoked.'] = 'La contrasenya específica de l\'aplicació s\'ha revocat correctament.'; $a->strings['App-specific password successfully revoked.'] = 'La contrasenya específica de l\'aplicació s\'ha revocat correctament.';
$a->strings['Two-factor app-specific passwords'] = 'Contrasenyes específiques per a l\'aplicació de dos factors'; $a->strings['Two-factor app-specific passwords'] = 'Contrasenyes específiques per a l\'aplicació de dos factors';

File diff suppressed because it is too large Load diff

View file

@ -185,11 +185,11 @@ $a->strings['Delete'] = 'Odstranit';
$a->strings['I like this (toggle)'] = 'To se mi líbí (přepínat)'; $a->strings['I like this (toggle)'] = 'To se mi líbí (přepínat)';
$a->strings['I don\'t like this (toggle)'] = 'To se mi nelíbí (přepínat)'; $a->strings['I don\'t like this (toggle)'] = 'To se mi nelíbí (přepínat)';
$a->strings['Map'] = 'Mapa'; $a->strings['Map'] = 'Mapa';
$a->strings['No system theme config value set.'] = 'Není nastavena konfigurační hodnota systémového motivu.';
$a->strings['Delete this item?'] = 'Odstranit tuto položku?'; $a->strings['Delete this item?'] = 'Odstranit tuto položku?';
$a->strings['toggle mobile'] = 'přepínat mobilní zobrazení'; $a->strings['toggle mobile'] = 'přepínat mobilní zobrazení';
$a->strings['Page not found.'] = 'Stránka nenalezena'; $a->strings['Page not found.'] = 'Stránka nenalezena';
$a->strings['You must be logged in to use addons. '] = 'Pro použití doplňků musíte být přihlášen/a.'; $a->strings['You must be logged in to use addons. '] = 'Pro použití doplňků musíte být přihlášen/a.';
$a->strings['No system theme config value set.'] = 'Není nastavena konfigurační hodnota systémového motivu.';
$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.'] = 'Formulářový bezpečnostní token nebyl správný. To pravděpodobně nastalo kvůli tom, že formulář byl otevřen příliš dlouho (>3 hodiny) před jeho odesláním.'; $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.'] = 'Formulářový bezpečnostní token nebyl správný. To pravděpodobně nastalo kvůli tom, že formulář byl otevřen příliš dlouho (>3 hodiny) před jeho odesláním.';
$a->strings['All contacts'] = 'Všechny kontakty'; $a->strings['All contacts'] = 'Všechny kontakty';
$a->strings['Followers'] = 'Sledující'; $a->strings['Followers'] = 'Sledující';
@ -371,7 +371,6 @@ $a->strings['first'] = 'první';
$a->strings['prev'] = 'předchozí'; $a->strings['prev'] = 'předchozí';
$a->strings['next'] = 'další'; $a->strings['next'] = 'další';
$a->strings['last'] = 'poslední'; $a->strings['last'] = 'poslední';
$a->strings['Image/photo'] = 'Obrázek/fotka';
$a->strings['Click to open/close'] = 'Kliknutím otevřete/zavřete'; $a->strings['Click to open/close'] = 'Kliknutím otevřete/zavřete';
$a->strings['$1 wrote:'] = '$1 napsal/a:'; $a->strings['$1 wrote:'] = '$1 napsal/a:';
$a->strings['Encrypted content'] = 'Šifrovaný obsah'; $a->strings['Encrypted content'] = 'Šifrovaný obsah';
@ -704,7 +703,6 @@ $a->strings['Maintainer: '] = 'Správce: ';
$a->strings['Addon %s failed to install.'] = 'Instalace doplňku %s selhala.'; $a->strings['Addon %s failed to install.'] = 'Instalace doplňku %s selhala.';
$a->strings['Save Settings'] = 'Uložit nastavení'; $a->strings['Save Settings'] = 'Uložit nastavení';
$a->strings['Reload active addons'] = 'Znovu načíst aktivní doplňky'; $a->strings['Reload active addons'] = 'Znovu načíst aktivní doplňky';
$a->strings['There are currently no addons available on your node. You can find the official addon repository at %1$s and might find other interesting addons in the open addon registry at %2$s'] = 'Aktuálně nejsou na Vašem serveru k dispozici žádné doplňky. Oficiální repozitář doplňků najdete na %1$s a další zajímavé doplňky můžete najít v otevřeném registru doplňků na %2$s';
$a->strings['Update has been marked successful'] = 'Aktualizace byla označena jako úspěšná.'; $a->strings['Update has been marked successful'] = 'Aktualizace byla označena jako úspěšná.';
$a->strings['Database structure update %s was successfully applied.'] = 'Aktualizace struktury databáze %s byla úspěšně aplikována.'; $a->strings['Database structure update %s was successfully applied.'] = 'Aktualizace struktury databáze %s byla úspěšně aplikována.';
$a->strings['Executing of database structure update %s failed with error: %s'] = 'Provádění aktualizace databáze %s selhalo s chybou: %s'; $a->strings['Executing of database structure update %s failed with error: %s'] = 'Provádění aktualizace databáze %s selhalo s chybou: %s';

File diff suppressed because it is too large Load diff

View file

@ -193,7 +193,6 @@ $a->strings['I like this (toggle)'] = 'Ich mag das (toggle)';
$a->strings['Dislike'] = 'Mag ich nicht'; $a->strings['Dislike'] = 'Mag ich nicht';
$a->strings['I don\'t like this (toggle)'] = 'Ich mag das nicht (toggle)'; $a->strings['I don\'t like this (toggle)'] = 'Ich mag das nicht (toggle)';
$a->strings['Map'] = 'Karte'; $a->strings['Map'] = 'Karte';
$a->strings['No system theme config value set.'] = 'Es wurde kein Konfigurationswert für das systemweite Theme gesetzt.';
$a->strings['Apologies but the website is unavailable at the moment.'] = 'Entschuldigung, aber die Webseite ist derzeit nicht erreichbar.'; $a->strings['Apologies but the website is unavailable at the moment.'] = 'Entschuldigung, aber die Webseite ist derzeit nicht erreichbar.';
$a->strings['Delete this item?'] = 'Diesen Beitrag löschen?'; $a->strings['Delete this item?'] = 'Diesen Beitrag löschen?';
$a->strings['Block this author? They won\'t be able to follow you nor see your public posts, and you won\'t be able to see their posts and their notifications.'] = 'Soll dieser Autor geblockt werden? Sie werden nicht in der Lage sein, dir zu folgen oder deine öffentlichen Beiträge zu sehen. Außerdem wirst du nicht in der Lage sein ihre Beiträge und Benachrichtigungen zu lesen.'; $a->strings['Block this author? They won\'t be able to follow you nor see your public posts, and you won\'t be able to see their posts and their notifications.'] = 'Soll dieser Autor geblockt werden? Sie werden nicht in der Lage sein, dir zu folgen oder deine öffentlichen Beiträge zu sehen. Außerdem wirst du nicht in der Lage sein ihre Beiträge und Benachrichtigungen zu lesen.';
@ -222,6 +221,7 @@ $a->strings['toggle mobile'] = 'mobile Ansicht umschalten';
$a->strings['Method not allowed for this module. Allowed method(s): %s'] = 'Diese Methode ist in diesem Modul nicht erlaubt. Erlaubte Methoden sind: %s'; $a->strings['Method not allowed for this module. Allowed method(s): %s'] = 'Diese Methode ist in diesem Modul nicht erlaubt. Erlaubte Methoden sind: %s';
$a->strings['Page not found.'] = 'Seite nicht gefunden.'; $a->strings['Page not found.'] = 'Seite nicht gefunden.';
$a->strings['You must be logged in to use addons. '] = 'Du musst angemeldet sein, um Addons benutzen zu können.'; $a->strings['You must be logged in to use addons. '] = 'Du musst angemeldet sein, um Addons benutzen zu können.';
$a->strings['No system theme config value set.'] = 'Es wurde kein Konfigurationswert für das systemweite Theme gesetzt.';
$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.'] = 'Das Sicherheitsmerkmal war nicht korrekt. Das passiert meistens, wenn das Formular vor dem Absenden zu lange geöffnet war (länger als 3 Stunden).'; $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.'] = 'Das Sicherheitsmerkmal war nicht korrekt. Das passiert meistens, wenn das Formular vor dem Absenden zu lange geöffnet war (länger als 3 Stunden).';
$a->strings['All contacts'] = 'Alle Kontakte'; $a->strings['All contacts'] = 'Alle Kontakte';
$a->strings['Followers'] = 'Folgende'; $a->strings['Followers'] = 'Folgende';
@ -233,6 +233,7 @@ $a->strings['Addon already enabled'] = 'Addon bereits aktiviert';
$a->strings['Addon already disabled'] = 'Addon bereits deaktiviert'; $a->strings['Addon already disabled'] = 'Addon bereits deaktiviert';
$a->strings['Could not find any unarchived contact entry for this URL (%s)'] = 'Für die URL (%s) konnte kein nicht-archivierter Kontakt gefunden werden'; $a->strings['Could not find any unarchived contact entry for this URL (%s)'] = 'Für die URL (%s) konnte kein nicht-archivierter Kontakt gefunden werden';
$a->strings['The contact entries have been archived'] = 'Die Kontakteinträge wurden archiviert.'; $a->strings['The contact entries have been archived'] = 'Die Kontakteinträge wurden archiviert.';
$a->strings['The avatar cache needs to be disabled in local.config.php to use this command.'] = 'Der Zwischenspeicher für Kontaktprofilbilder muss in der local.config.php deaktiviert sein, um diesen Befehl nutzen zu können.';
$a->strings['Could not find any contact entry for this URL (%s)'] = 'Für die URL (%s) konnte kein Kontakt gefunden werden'; $a->strings['Could not find any contact entry for this URL (%s)'] = 'Für die URL (%s) konnte kein Kontakt gefunden werden';
$a->strings['The contact has been blocked from the node'] = 'Der Kontakt wurde von diesem Knoten geblockt'; $a->strings['The contact has been blocked from the node'] = 'Der Kontakt wurde von diesem Knoten geblockt';
$a->strings['%d %s, %d duplicates.'] = '%d %s, Duplikat %d.'; $a->strings['%d %s, %d duplicates.'] = '%d %s, Duplikat %d.';
@ -580,7 +581,6 @@ $a->strings['first'] = 'erste';
$a->strings['prev'] = 'vorige'; $a->strings['prev'] = 'vorige';
$a->strings['next'] = 'nächste'; $a->strings['next'] = 'nächste';
$a->strings['last'] = 'letzte'; $a->strings['last'] = 'letzte';
$a->strings['Image/photo'] = 'Bild/Foto';
$a->strings['<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a> %3$s'] = '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>%3$s'; $a->strings['<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a> %3$s'] = '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>%3$s';
$a->strings['Link to source'] = 'Link zum Originalbeitrag'; $a->strings['Link to source'] = 'Link zum Originalbeitrag';
$a->strings['Click to open/close'] = 'Zum Öffnen/Schließen klicken'; $a->strings['Click to open/close'] = 'Zum Öffnen/Schließen klicken';
@ -830,6 +830,7 @@ $a->strings['Create a new circle'] = 'Erstelle neuen Circle';
$a->strings['Circle Name: '] = 'Circle Name: '; $a->strings['Circle Name: '] = 'Circle Name: ';
$a->strings['Edit circles'] = 'Circles bearbeiten'; $a->strings['Edit circles'] = 'Circles bearbeiten';
$a->strings['Approve'] = 'Genehmigen'; $a->strings['Approve'] = 'Genehmigen';
$a->strings['%s has blocked you'] = '%s hat dich blockiert';
$a->strings['Organisation'] = 'Organisation'; $a->strings['Organisation'] = 'Organisation';
$a->strings['Group'] = 'Gruppe'; $a->strings['Group'] = 'Gruppe';
$a->strings['Relay'] = 'Relais'; $a->strings['Relay'] = 'Relais';
@ -872,6 +873,9 @@ $a->strings['%s\'s birthday'] = '%ss Geburtstag';
$a->strings['Happy Birthday %s'] = 'Herzlichen Glückwunsch, %s'; $a->strings['Happy Birthday %s'] = 'Herzlichen Glückwunsch, %s';
$a->strings['%s (%s - %s): %s'] = '%s (%s - %s): %s'; $a->strings['%s (%s - %s): %s'] = '%s (%s - %s): %s';
$a->strings['%s (%s): %s'] = '%s (%s): %s'; $a->strings['%s (%s): %s'] = '%s (%s): %s';
$a->strings['Detected languages in this post:
%s'] = 'Erkannte Sprachen in diesem Beitrag:
%s';
$a->strings['activity'] = 'Aktivität'; $a->strings['activity'] = 'Aktivität';
$a->strings['comment'] = 'Kommentar'; $a->strings['comment'] = 'Kommentar';
$a->strings['post'] = 'Beitrag'; $a->strings['post'] = 'Beitrag';
@ -1123,7 +1127,7 @@ $a->strings['Addons reloaded'] = 'Addons neu geladen';
$a->strings['Addon %s failed to install.'] = 'Addon %s konnte nicht installiert werden'; $a->strings['Addon %s failed to install.'] = 'Addon %s konnte nicht installiert werden';
$a->strings['Save Settings'] = 'Einstellungen speichern'; $a->strings['Save Settings'] = 'Einstellungen speichern';
$a->strings['Reload active addons'] = 'Aktivierte Addons neu laden'; $a->strings['Reload active addons'] = 'Aktivierte Addons neu laden';
$a->strings['There are currently no addons available on your node. You can find the official addon repository at %1$s and might find other interesting addons in the open addon registry at %2$s'] = 'Es sind derzeit keine Addons auf diesem Knoten verfügbar. Du findest das offizielle Addon-Repository unter %1$s und weitere eventuell interessante Addons im offenen Addon-Verzeichnis auf %2$s.'; $a->strings['There are currently no addons available on your node. You can find the official addon repository at %1$s.'] = 'Es sind derzeit keine Addons auf diesem Knoten verfügbar. Du findest das offizielle Addon-Repository unter %1$s.';
$a->strings['Update has been marked successful'] = 'Update wurde als erfolgreich markiert'; $a->strings['Update has been marked successful'] = 'Update wurde als erfolgreich markiert';
$a->strings['Database structure update %s was successfully applied.'] = 'Das Update %s der Struktur der Datenbank wurde erfolgreich angewandt.'; $a->strings['Database structure update %s was successfully applied.'] = 'Das Update %s der Struktur der Datenbank wurde erfolgreich angewandt.';
$a->strings['Executing of database structure update %s failed with error: %s'] = 'Das Update %s der Struktur der Datenbank schlug mit folgender Fehlermeldung fehl: %s'; $a->strings['Executing of database structure update %s failed with error: %s'] = 'Das Update %s der Struktur der Datenbank schlug mit folgender Fehlermeldung fehl: %s';
@ -1219,6 +1223,7 @@ $a->strings['Job Parameters'] = 'Parameter der Aufgabe';
$a->strings['Created'] = 'Erstellt'; $a->strings['Created'] = 'Erstellt';
$a->strings['Next Try'] = 'Nächster Versuch'; $a->strings['Next Try'] = 'Nächster Versuch';
$a->strings['Priority'] = 'Priorität'; $a->strings['Priority'] = 'Priorität';
$a->strings['%s is no valid input for maximum media size'] = '%s ist keine gültige Angabe der maximalen Größe von Medien';
$a->strings['%s is no valid input for maximum image size'] = '%s ist keine gültige Angabe der maximalen Größe von Bildern'; $a->strings['%s is no valid input for maximum image size'] = '%s ist keine gültige Angabe der maximalen Größe von Bildern';
$a->strings['No special theme for mobile devices'] = 'Kein spezielles Theme für mobile Geräte verwenden.'; $a->strings['No special theme for mobile devices'] = 'Kein spezielles Theme für mobile Geräte verwenden.';
$a->strings['%s - (Experimental)'] = '%s - (Experimentell)'; $a->strings['%s - (Experimental)'] = '%s - (Experimentell)';
@ -1288,6 +1293,12 @@ $a->strings['Maximum image length'] = 'Maximale Bildlänge';
$a->strings['Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.'] = 'Maximale Länge in Pixeln der längsten Seite eines hochgeladenen Bildes. Grundeinstellung ist -1, was keine Einschränkung bedeutet.'; $a->strings['Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.'] = 'Maximale Länge in Pixeln der längsten Seite eines hochgeladenen Bildes. Grundeinstellung ist -1, was keine Einschränkung bedeutet.';
$a->strings['JPEG image quality'] = 'Qualität des JPEG Bildes'; $a->strings['JPEG image quality'] = 'Qualität des JPEG Bildes';
$a->strings['Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.'] = 'Hochgeladene JPEG-Bilder werden mit dieser Qualität [0-100] gespeichert. Grundeinstellung ist 100, kein Qualitätsverlust.'; $a->strings['Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.'] = 'Hochgeladene JPEG-Bilder werden mit dieser Qualität [0-100] gespeichert. Grundeinstellung ist 100, kein Qualitätsverlust.';
$a->strings['Maximum media file size'] = 'Maximale Medien-Dateigröße';
$a->strings['Maximum size in bytes of uploaded media files. Default is 0, which means no limits. You can put k, m, or g behind the desired value for KiB, MiB, GiB, respectively.
The value of <code>upload_max_filesize</code> in your <code>PHP.ini</code> needs be set to at least the desired limit.
Currently <code>upload_max_filesize</code> is set to %s (%s byte)'] = 'Die maximale Größe von Multimedia Dateien in Bytes. Grundeinstellung ist 0, welches keine Limitierung durch die Bildgröße bedeutet. Du kannst k, m oder g als Abkürzung hinter der Zahl angeben um KiB, MIB oder GiB zu definieren.
Der Wert der <code>1upload_max_filesize1</code> Variable in der <code>php.ini</code> Datei muss diesem Limit mindestens entsprechen.
Derzeit ist <code>3upload_max_filesize3</code> auf %s (%sByte) gesetzt.';
$a->strings['Register policy'] = 'Registrierungsmethode'; $a->strings['Register policy'] = 'Registrierungsmethode';
$a->strings['Maximum Users'] = 'Maximale Benutzeranzahl'; $a->strings['Maximum Users'] = 'Maximale Benutzeranzahl';
$a->strings['If defined, the register policy is automatically closed when the given number of users is reached and reopens the registry when the number drops below the limit. It only works when the policy is set to open or close, but not when the policy is set to approval.'] = 'Falls definiert, wird die Registrierungsrichtlinie automatisch geschlossen, wenn die angegebene Anzahl von Benutzern erreicht ist, und die Registrierung wieder geöffnet, wenn die Anzahl unter den Grenzwert fällt. Dies funktioniert nur, wenn die Richtlinie auf "Öffnen" oder "Schließen" eingestellt ist, nicht aber, wenn die Richtlinie auf "Genehmigung" eingestellt ist.'; $a->strings['If defined, the register policy is automatically closed when the given number of users is reached and reopens the registry when the number drops below the limit. It only works when the policy is set to open or close, but not when the policy is set to approval.'] = 'Falls definiert, wird die Registrierungsrichtlinie automatisch geschlossen, wenn die angegebene Anzahl von Benutzern erreicht ist, und die Registrierung wieder geöffnet, wenn die Anzahl unter den Grenzwert fällt. Dies funktioniert nur, wenn die Richtlinie auf "Öffnen" oder "Schließen" eingestellt ist, nicht aber, wenn die Richtlinie auf "Genehmigung" eingestellt ist.';
@ -1402,6 +1413,7 @@ $a->strings['When the database cleanup is enabled, this defines the days after w
$a->strings['Lifespan of unclaimed items'] = 'Lebensdauer nicht angeforderter Beiträge'; $a->strings['Lifespan of unclaimed items'] = 'Lebensdauer nicht angeforderter Beiträge';
$a->strings['When the database cleanup is enabled, this defines the days after which unclaimed remote items (mostly content from the relay) will be deleted. Default value is 90 days. Defaults to the general lifespan value of remote items if set to 0.'] = 'Wenn das Aufräumen der Datenbank aktiviert ist, definiert dies die Anzahl von Tagen, nach denen nicht angeforderte Beiträge (hauptsächlich solche, die über das Relais eintreffen) gelöscht werden. Der Standardwert beträgt 90 Tage. Wird dieser Wert auf 0 gesetzt, wird die Lebensdauer von Beiträgen anderer Knoten verwendet.'; $a->strings['When the database cleanup is enabled, this defines the days after which unclaimed remote items (mostly content from the relay) will be deleted. Default value is 90 days. Defaults to the general lifespan value of remote items if set to 0.'] = 'Wenn das Aufräumen der Datenbank aktiviert ist, definiert dies die Anzahl von Tagen, nach denen nicht angeforderte Beiträge (hauptsächlich solche, die über das Relais eintreffen) gelöscht werden. Der Standardwert beträgt 90 Tage. Wird dieser Wert auf 0 gesetzt, wird die Lebensdauer von Beiträgen anderer Knoten verwendet.';
$a->strings['Lifespan of raw conversation data'] = 'Lebensdauer der Beiträge'; $a->strings['Lifespan of raw conversation data'] = 'Lebensdauer der Beiträge';
$a->strings['The conversation data is used for ActivityPub, as well as for debug purposes. It should be safe to remove it after 14 days, default is 90 days.'] = 'Die Konversationsdaten werden für ActivityPub sowie für Debug-Zwecke verwendet. Sie sollten gefahrlos nach 14 Tagen entfernt werden können, der Standardwert beträgt 90 Tage.';
$a->strings['Maximum numbers of comments per post'] = 'Maximale Anzahl von Kommentaren pro Beitrag'; $a->strings['Maximum numbers of comments per post'] = 'Maximale Anzahl von Kommentaren pro Beitrag';
$a->strings['How much comments should be shown for each post? Default value is 100.'] = 'Wie viele Kommentare sollen pro Beitrag angezeigt werden? Standardwert sind 100.'; $a->strings['How much comments should be shown for each post? Default value is 100.'] = 'Wie viele Kommentare sollen pro Beitrag angezeigt werden? Standardwert sind 100.';
$a->strings['Maximum numbers of comments per post on the display page'] = 'Maximale Anzahl von Kommentaren in der Einzelansicht'; $a->strings['Maximum numbers of comments per post on the display page'] = 'Maximale Anzahl von Kommentaren in der Einzelansicht';
@ -1866,9 +1878,6 @@ $a->strings['HTML::toPlaintext'] = 'HTML::toPlaintext';
$a->strings['HTML::toPlaintext (compact)'] = 'HTML::toPlaintext (kompakt)'; $a->strings['HTML::toPlaintext (compact)'] = 'HTML::toPlaintext (kompakt)';
$a->strings['Decoded post'] = 'Dekodierter Beitrag'; $a->strings['Decoded post'] = 'Dekodierter Beitrag';
$a->strings['Post array before expand entities'] = 'Beiträgs Array bevor die Entitäten erweitert wurden.'; $a->strings['Post array before expand entities'] = 'Beiträgs Array bevor die Entitäten erweitert wurden.';
$a->strings['Post converted'] = 'Konvertierter Beitrag';
$a->strings['Converted body'] = 'Konvertierter Beitragskörper';
$a->strings['Twitter addon is absent from the addon/ folder.'] = 'Das Twitter-Addon konnte nicht im addpn/ Verzeichnis gefunden werden.';
$a->strings['Babel Diagnostic'] = 'Babel Diagnostik'; $a->strings['Babel Diagnostic'] = 'Babel Diagnostik';
$a->strings['Source text'] = 'Quelltext'; $a->strings['Source text'] = 'Quelltext';
$a->strings['BBCode'] = 'BBCode'; $a->strings['BBCode'] = 'BBCode';
@ -2263,6 +2272,7 @@ $a->strings['success'] = 'Erfolg';
$a->strings['failed'] = 'Fehlgeschlagen'; $a->strings['failed'] = 'Fehlgeschlagen';
$a->strings['ignored'] = 'Ignoriert'; $a->strings['ignored'] = 'Ignoriert';
$a->strings['Keep this window open until done.'] = 'Lasse dieses Fenster offen, bis der Vorgang abgeschlossen ist.'; $a->strings['Keep this window open until done.'] = 'Lasse dieses Fenster offen, bis der Vorgang abgeschlossen ist.';
$a->strings['Search in Friendica %s'] = 'Friendica durchsuchen %s';
$a->strings['The Photo is not available.'] = 'Das Foto ist nicht verfügbar.'; $a->strings['The Photo is not available.'] = 'Das Foto ist nicht verfügbar.';
$a->strings['The Photo with id %s is not available.'] = 'Das Bild mit ID %s ist nicht verfügbar.'; $a->strings['The Photo with id %s is not available.'] = 'Das Bild mit ID %s ist nicht verfügbar.';
$a->strings['Invalid external resource with url %s.'] = 'Ungültige externe Ressource mit der URL %s'; $a->strings['Invalid external resource with url %s.'] = 'Ungültige externe Ressource mit der URL %s';
@ -2629,6 +2639,10 @@ $a->strings['Potential Delegates'] = 'Potentielle Bevollmächtigte';
$a->strings['No entries.'] = 'Keine Einträge.'; $a->strings['No entries.'] = 'Keine Einträge.';
$a->strings['The theme you chose isn\'t available.'] = 'Das gewählte Theme ist nicht verfügbar'; $a->strings['The theme you chose isn\'t available.'] = 'Das gewählte Theme ist nicht verfügbar';
$a->strings['%s - (Unsupported)'] = '%s - (Nicht unterstützt)'; $a->strings['%s - (Unsupported)'] = '%s - (Nicht unterstützt)';
$a->strings['Color/Black'] = 'Farbe/Schwarz';
$a->strings['Black'] = 'Schwarz';
$a->strings['Color/White'] = 'Farbe/Weiß';
$a->strings['White'] = 'Weiß';
$a->strings['No preview'] = 'Keine Vorschau'; $a->strings['No preview'] = 'Keine Vorschau';
$a->strings['No image'] = 'Kein Bild'; $a->strings['No image'] = 'Kein Bild';
$a->strings['Small Image'] = 'Kleines Bild'; $a->strings['Small Image'] = 'Kleines Bild';
@ -2664,6 +2678,12 @@ $a->strings['DIsplay the event list'] = 'Anzeige der der anstehenden Ereignisse'
$a->strings['Display the birthday reminder and event list on the network page.'] = 'Zeigt die Geburtstagserinnerungen und die anstehenden Veranstaltungen auf der Netzwerkseite an.'; $a->strings['Display the birthday reminder and event list on the network page.'] = 'Zeigt die Geburtstagserinnerungen und die anstehenden Veranstaltungen auf der Netzwerkseite an.';
$a->strings['Link preview mode'] = 'Vorschau Modus für Links'; $a->strings['Link preview mode'] = 'Vorschau Modus für Links';
$a->strings['Appearance of the link preview that is added to each post with a link.'] = 'Aussehen der Linkvorschau, die zu jedem Beitrag mit einem Link hinzugefügt wird.'; $a->strings['Appearance of the link preview that is added to each post with a link.'] = 'Aussehen der Linkvorschau, die zu jedem Beitrag mit einem Link hinzugefügt wird.';
$a->strings['Hide pictures with empty alternative text'] = 'Bilder ohne Alternativtext verbergen';
$a->strings['Don\'t display pictures that are missing the alternative text.'] = 'Bilder die keinen beschreibenden Alternativtext besitzen werden nicht angezeigt.';
$a->strings['Hide custom emojis'] = 'Benutzerdefinierte Emojis ausblenden';
$a->strings['Don\'t display custom emojis.'] = 'Benutzerdefinierte Emojis werden nicht angezeigt.';
$a->strings['Platform icons style'] = 'Stiel der Platformicons';
$a->strings['Style of the platform icons'] = 'Stiel der verwendeten Platformicons';
$a->strings['Bookmark'] = 'Lesezeichen'; $a->strings['Bookmark'] = 'Lesezeichen';
$a->strings['Enable timelines that you want to see in the channels widget. Bookmark timelines that you want to see in the top menu.'] = 'Aktiviere die Timelines, die Sie im Kanäle-Widget sehen möchten. Setze ein Lesezeichen für Timelines, die du im oberen Menü sehen willst.'; $a->strings['Enable timelines that you want to see in the channels widget. Bookmark timelines that you want to see in the top menu.'] = 'Aktiviere die Timelines, die Sie im Kanäle-Widget sehen möchten. Setze ein Lesezeichen für Timelines, die du im oberen Menü sehen willst.';
$a->strings['Channel languages:'] = 'Channel Sprachen:'; $a->strings['Channel languages:'] = 'Channel Sprachen:';
@ -2751,7 +2771,7 @@ $a->strings['Save changes'] = 'Einstellungen speichern';
$a->strings['Please enter your password to access this page.'] = 'Bitte gib dein Passwort ein, um auf diese Seite zuzugreifen.'; $a->strings['Please enter your password to access this page.'] = 'Bitte gib dein Passwort ein, um auf diese Seite zuzugreifen.';
$a->strings['App-specific password generation failed: The description is empty.'] = 'Die Erzeugung des App spezifischen Passworts ist fehlgeschlagen. Die Beschreibung ist leer.'; $a->strings['App-specific password generation failed: The description is empty.'] = 'Die Erzeugung des App spezifischen Passworts ist fehlgeschlagen. Die Beschreibung ist leer.';
$a->strings['App-specific password generation failed: This description already exists.'] = 'Die Erzeugung des App spezifischen Passworts ist fehlgeschlagen. Die Beschreibung existiert bereits.'; $a->strings['App-specific password generation failed: This description already exists.'] = 'Die Erzeugung des App spezifischen Passworts ist fehlgeschlagen. Die Beschreibung existiert bereits.';
$a->strings['New app-specific password generated.'] = 'Neues App spezifisches Passwort erzeugt.'; $a->strings['New app-specific password generated: %s'] = 'Neues App spezifisches Passwort erzeugt: %s';
$a->strings['App-specific passwords successfully revoked.'] = 'App spezifische Passwörter erfolgreich widerrufen.'; $a->strings['App-specific passwords successfully revoked.'] = 'App spezifische Passwörter erfolgreich widerrufen.';
$a->strings['App-specific password successfully revoked.'] = 'App spezifisches Passwort erfolgreich widerrufen.'; $a->strings['App-specific password successfully revoked.'] = 'App spezifisches Passwort erfolgreich widerrufen.';
$a->strings['Two-factor app-specific passwords'] = 'Zwei-Faktor App spezifische Passwörter.'; $a->strings['Two-factor app-specific passwords'] = 'Zwei-Faktor App spezifische Passwörter.';
@ -3150,7 +3170,6 @@ $a->strings['Skip to main content'] = 'Zum Inhalt der Seite gehen';
$a->strings['Back to top'] = 'Zurück nach Oben'; $a->strings['Back to top'] = 'Zurück nach Oben';
$a->strings['Light'] = 'Hell'; $a->strings['Light'] = 'Hell';
$a->strings['Dark'] = 'Dunkel'; $a->strings['Dark'] = 'Dunkel';
$a->strings['Black'] = 'Schwarz';
$a->strings['Custom'] = 'Benutzerdefiniert'; $a->strings['Custom'] = 'Benutzerdefiniert';
$a->strings['Guest'] = 'Gast'; $a->strings['Guest'] = 'Gast';
$a->strings['Visitor'] = 'Besucher'; $a->strings['Visitor'] = 'Besucher';

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more