Merge branch 'develop' into merge-2024.09-rc-branch

This commit is contained in:
Art4 2024-11-16 08:32:25 +00:00
commit eb04f3b079
25 changed files with 340 additions and 205 deletions

14
.phpstan.neon Normal file
View file

@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: 2010 - 2024 the Friendica project
#
# SPDX-License-Identifier: CC0-1.0
parameters:
level: 0
paths:
- src/
scanDirectories:
- mod
- vendor
- view

View file

@ -152,13 +152,16 @@
"mikey179/vfsstream": "^1.6",
"mockery/mockery": "^1.3",
"php-mock/php-mock-phpunit": "^2.10",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^9"
},
"scripts": {
"test": "phpunit",
"test:unit": "phpunit -c tests/phpunit.xml --testsuite unit",
"phpstan": "phpstan analyze --memory-limit 1024M --configuration .phpstan.neon",
"lint": "find . -name \\*.php -not -path './vendor/*' -not -path './view/asset/*' -print0 | xargs -0 -n1 php -l",
"docker:translate": "docker run --rm -v $PWD:/data -w /data friendicaci/transifex bin/run_xgettext.sh",
"lang:recreate": "bin/run_xgettext.sh",
"cs:install": "@composer install --working-dir=bin/dev/php-cs-fixer",
"cs:check": [
"@cs:install",

60
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d51158b9593011921144e90af146a86a",
"content-hash": "3e31a2243fb69e47e1b7000cca946fa2",
"packages": [
{
"name": "asika/simple-console",
@ -4832,6 +4832,64 @@
],
"time": "2024-02-11T07:24:16+00:00"
},
{
"name": "phpstan/phpstan",
"version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "ab4e9b4415a5fc9e4d27f7fe16c8bc9d067dcd6d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/ab4e9b4415a5fc9e4d27f7fe16c8bc9d067dcd6d",
"reference": "ab4e9b4415a5fc9e4d27f7fe16c8bc9d067dcd6d",
"shasum": ""
},
"require": {
"php": "^7.4|^8.0"
},
"conflict": {
"phpstan/phpstan-shim": "*"
},
"bin": [
"phpstan",
"phpstan.phar"
],
"type": "library",
"autoload": {
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPStan - PHP Static Analysis Tool",
"keywords": [
"dev",
"static analysis"
],
"support": {
"docs": "https://phpstan.org/user-guide/getting-started",
"forum": "https://github.com/phpstan/phpstan/discussions",
"issues": "https://github.com/phpstan/phpstan/issues",
"security": "https://github.com/phpstan/phpstan/security/policy",
"source": "https://github.com/phpstan/phpstan-src"
},
"funding": [
{
"url": "https://github.com/ondrejmirtes",
"type": "github"
},
{
"url": "https://github.com/phpstan",
"type": "github"
}
],
"time": "2024-11-11T15:43:04+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.31",

View file

@ -210,7 +210,7 @@ class Mode
public function isInstall(): bool
{
return !$this->has(Mode::LOCALCONFIGPRESENT) ||
!$this->has(MODE::DBAVAILABLE);
!$this->has(Mode::DBAVAILABLE);
}
/**

View file

@ -89,7 +89,9 @@ class BaseCollection extends \ArrayIterator
*/
public function map(callable $callback): BaseCollection
{
return new static(array_map($callback, $this->getArrayCopy()), $this->getTotalCount());
$class = get_class($this);
return new $class(array_map($callback, $this->getArrayCopy()), $this->getTotalCount());
}
/**
@ -102,7 +104,9 @@ class BaseCollection extends \ArrayIterator
*/
public function filter(callable $callback = null, int $flag = 0): BaseCollection
{
return new static(array_filter($this->getArrayCopy(), $callback, $flag));
$class = get_class($this);
return new $class(array_filter($this->getArrayCopy(), $callback, $flag));
}
/**
@ -112,7 +116,9 @@ class BaseCollection extends \ArrayIterator
*/
public function reverse(): BaseCollection
{
return new static(array_reverse($this->getArrayCopy()), $this->getTotalCount());
$class = get_class($this);
return new $class(array_reverse($this->getArrayCopy()), $this->getTotalCount());
}
/**
@ -128,7 +134,9 @@ class BaseCollection extends \ArrayIterator
}
return array_map(function ($array) {
return new static($array);
$class = get_class($this);
return new $class($array);
}, array_chunk($this->getArrayCopy(), $length));
}

View file

@ -144,6 +144,8 @@ HELP;
}
$this->out($table->getTable());
return 0;
}
/**

View file

@ -8,6 +8,7 @@
namespace Friendica\Console;
use Asika\SimpleConsole\Console;
use Exception;
use Friendica\App;
use Friendica\App\BaseURL;
use Friendica\Core\Config\Capability\IManageConfigValues;

View file

@ -158,9 +158,10 @@ HELP;
if ($result['success']) {
$this->out('User ' . $user['nickname'] . ' now connected to ' . $url . ', contact ID ' . $result['cid']);
} else {
throw new RuntimeException($result['message']);
return true;
}
throw new RuntimeException($result['message']);
}
/**

View file

@ -7,12 +7,11 @@
namespace Friendica\Console;
use Friendica\App;
use Asika\SimpleConsole\CommandArgsException;
use Friendica\App\Mode;
use Friendica\Core\L10n;
use Friendica\Database\Database;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Util\Strings;
use RuntimeException;
/**
@ -23,13 +22,17 @@ class FixAPDeliveryWorkerTaskParameters extends \Asika\SimpleConsole\Console
protected $helpOptions = ['h', 'help', '?'];
/**
* @var App\Mode
* @var Mode
*/
private $appMode;
/**
* @var Database
*/
private $dba;
/**
* @var L10n
*/
private $l10n;
/**
* @var int
*/
@ -62,7 +65,7 @@ HELP;
return $help;
}
public function __construct(App\Mode $appMode, Database $dba, \Friendica\Core\L10n $l10n, array $argv = null)
public function __construct(Mode $appMode, Database $dba, L10n $l10n, array $argv = null)
{
parent::__construct($argv);
@ -80,7 +83,7 @@ HELP;
}
if (count($this->args) > 0) {
throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
throw new CommandArgsException('Too many arguments');
}
if ($this->appMode->isInstall()) {

View file

@ -122,7 +122,7 @@ HELP;
case 'search':
return $this->searchUser();
case 'config':
return $this->configUser();
return ($this->configUser()) ? 0 : 1;
default:
throw new \Asika\SimpleConsole\CommandArgsException('Wrong command.');
}
@ -512,5 +512,7 @@ HELP;
$this->out($this->getHelp());
return false;
}
return true;
}
}

View file

@ -228,7 +228,7 @@ class PostMedia extends BaseEntity
$newHeight = $dimensionts['height'];
}
return new static(
return new self(
$this->uriId,
$this->url,
$this->type,
@ -255,7 +255,7 @@ class PostMedia extends BaseEntity
public function withUrl(\GuzzleHttp\Psr7\Uri $url): self
{
return new static(
return new self(
$this->uriId,
$url,
$this->type,

View file

@ -26,7 +26,6 @@ class ContactBlock
/**
* Get HTML for contact block
*
* @template widget/contacts.tpl
* @hook contact_block_end (contacts=>array, output=>string)
* @return string Formatted HTML code or empty string
*/

View file

@ -26,7 +26,6 @@ class VCard
/**
* Get HTML for vcard block
*
* @template widget/vcard.tpl
* @param array $contact
* @param bool $hide_mention
* @param bool $hide_follow

View file

@ -41,11 +41,8 @@ class APCuCache extends AbstractCache implements ICanCacheInMemory
$ns = $this->getCacheKey($prefix ?? '');
$ns = preg_quote($ns, '/');
if (class_exists('\APCIterator')) {
$iterator = new \APCIterator('user', '/^' . $ns. '/', APC_ITER_KEY);
} else {
$iterator = new \APCUIterator('/^' . $ns . '/', APC_ITER_KEY);
}
/** @phpstan-ignore-next-line see https://github.com/friendica/friendica-addons/pull/1363 */
$iterator = new \APCUIterator('/^' . $ns . '/', APC_ITER_KEY);
$keys = [];
foreach ($iterator as $item) {
@ -122,11 +119,8 @@ class APCuCache extends AbstractCache implements ICanCacheInMemory
$prefix = $this->getPrefix();
$prefix = preg_quote($prefix, '/');
if (class_exists('\APCIterator')) {
$iterator = new \APCIterator('user', '/^' . $prefix . '/', APC_ITER_KEY);
} else {
$iterator = new \APCUIterator('/^' . $prefix . '/', APC_ITER_KEY);
}
/** @phpstan-ignore-next-line see https://github.com/friendica/friendica-addons/pull/1363 */
$iterator = new \APCUIterator('/^' . $prefix . '/', APC_ITER_KEY);
return apcu_delete($iterator);
}
@ -149,10 +143,7 @@ class APCuCache extends AbstractCache implements ICanCacheInMemory
return false;
} elseif (!ini_get('apc.enabled') && !ini_get('apc.enable_cli')) {
return false;
} elseif (
version_compare(phpversion('apc') ?: '0.0.0', '4.0.6') === -1 &&
version_compare(phpversion('apcu') ?: '0.0.0', '5.1.0') === -1
) {
} elseif (version_compare(phpversion('apcu') ?: '0.0.0', '5.1.0', '<')) {
return false;
}

View file

@ -2709,8 +2709,6 @@ class Contact
*
* @param int $id
* @param array $contact
*
* @return boolean
*/
private static function hasLocalData(int $id, array $contact): bool
{
@ -2770,6 +2768,8 @@ class Contact
'network', 'alias', 'baseurl', 'gsid', 'forum', 'prv', 'contact-type', 'pubkey', 'last-item', 'xmpp', 'matrix',
'created', 'last-update'
];
/** @var array<string,mixed> */
$contact = DBA::selectFirst('contact', $fields, ['id' => $id]);
if (!DBA::isResult($contact)) {
return false;
@ -2795,22 +2795,22 @@ class Contact
$has_local_data = self::hasLocalData($id, $contact);
$uid = $contact['uid'];
$uid = $contact['uid'] ?? null;
unset($contact['uid']);
$uriid = $contact['uri-id'];
$uriid = $contact['uri-id'] ?? null;
unset($contact['uri-id']);
$pubkey = $contact['pubkey'];
$pubkey = $contact['pubkey'] ?? null;
unset($contact['pubkey']);
$created = $contact['created'];
$created = $contact['created'] ?? '';
unset($contact['created']);
$last_update = $contact['last-update'];
$last_update = $contact['last-update'] ?? '';
unset($contact['last-update']);
$contact['photo'] = $contact['avatar'];
$contact['photo'] = $contact['avatar'] ?? null;
unset($contact['avatar']);
$updated = DateTimeFormat::utcNow();

View file

@ -3199,10 +3199,10 @@ class Item
} elseif ($remote_user) {
// Authenticated visitor - fetch the matching permissionsets
$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id);
if (!empty($set)) {
if (!empty($permissionSets)) {
$condition = [
"(`private` != ? OR (`private` = ? AND `wall`
AND `psid` IN (" . implode(', ', array_fill(0, count($set), '?')) . ")))",
AND `psid` IN (" . implode(', ', array_fill(0, count($permissionSets), '?')) . ")))",
self::PRIVATE, self::PRIVATE
];
$condition = array_merge($condition, $permissionSets->column('id'));
@ -3248,7 +3248,7 @@ class Item
*/
$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id);
if (!empty($set)) {
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 = '';

View file

@ -157,10 +157,6 @@ class Search extends BaseApi
$condition = DBA::mergeConditions($condition, ["`uri-id` < ?", $max_id]);
}
if (!empty($since_id)) {
$condition = DBA::mergeConditions($condition, ["`uri-id` > ?", $since_id]);
}
if (!empty($min_id)) {
$condition = DBA::mergeConditions($condition, ["`uri-id` > ?", $min_id]);

View file

@ -23,12 +23,12 @@ class ActivityPubConversion extends BaseModule
protected function content(array $request = []): string
{
function visible_whitespace($s)
{
return '<pre>' . htmlspecialchars($s) . '</pre>';
}
$results = [];
$visible_whitespace = function (string $s): string {
return '<pre>' . htmlspecialchars($s) . '</pre>';
};
if (!empty($_REQUEST['source'])) {
try {
$source = json_decode($_REQUEST['source'], true);
@ -43,11 +43,11 @@ class ActivityPubConversion extends BaseModule
$formatted = json_encode($source, JSON_PRETTY_PRINT);
$results[] = [
'title' => DI::l10n()->t('Formatted'),
'content' => visible_whitespace(trim(var_export($formatted, true), "'")),
'content' => $visible_whitespace(trim(var_export($formatted, true), "'")),
];
$results[] = [
'title' => DI::l10n()->t('Source'),
'content' => visible_whitespace(var_export($source, true))
'content' => $visible_whitespace(var_export($source, true))
];
$activity = JsonLD::compact($source);
if (!$activity) {
@ -55,7 +55,7 @@ class ActivityPubConversion extends BaseModule
}
$results[] = [
'title' => DI::l10n()->t('Activity'),
'content' => visible_whitespace(var_export($activity, true))
'content' => $visible_whitespace(var_export($activity, true))
];
$type = JsonLD::fetchElement($activity, '@type');
@ -92,10 +92,6 @@ class ActivityPubConversion extends BaseModule
throw new \Exception('No trust for activity type "' . $type . '", so we quit now.');
}
if (!empty($body) && empty($object_data['raw'])) {
$object_data['raw'] = $body;
}
// Internal flag for thread completion. See Processor.php
if (!empty($activity['thread-completion'])) {
$object_data['thread-completion'] = $activity['thread-completion'];
@ -107,14 +103,14 @@ class ActivityPubConversion extends BaseModule
$results[] = [
'title' => DI::l10n()->t('Object data'),
'content' => visible_whitespace(var_export($object_data, true))
'content' => $visible_whitespace(var_export($object_data, true))
];
$item = ActivityPub\Processor::createItem($object_data, true);
$results[] = [
'title' => DI::l10n()->t('Result Item'),
'content' => visible_whitespace(var_export($item, true))
'content' => $visible_whitespace(var_export($item, true))
];
} catch (\Throwable $e) {
$results[] = [

View file

@ -29,12 +29,12 @@ class Babel extends BaseModule
protected function content(array $request = []): string
{
function visible_whitespace($s)
{
return '<pre>' . htmlspecialchars($s) . '</pre>';
}
$results = [];
$visible_whitespace = function (string $s): string {
return '<pre>' . htmlspecialchars($s) . '</pre>';
};
if (!empty($request['text'])) {
self::checkFormSecurityTokenForbiddenOnError('babel');
switch (($request['type'] ?? '') ?: 'bbcode') {
@ -42,24 +42,24 @@ class Babel extends BaseModule
$bbcode = $request['text'];
$results[] = [
'title' => DI::l10n()->t('Source input'),
'content' => visible_whitespace($bbcode)
'content' => $visible_whitespace($bbcode)
];
$plain = Text\BBCode::toPlaintext($bbcode, false);
$results[] = [
'title' => DI::l10n()->t('BBCode::toPlaintext'),
'content' => visible_whitespace($plain)
'content' => $visible_whitespace($plain)
];
$html = Text\BBCode::convertForUriId(0, $bbcode);
$results[] = [
'title' => DI::l10n()->t('BBCode::convert (raw HTML)'),
'content' => visible_whitespace($html)
'content' => $visible_whitespace($html)
];
$results[] = [
'title' => DI::l10n()->t('BBCode::convert (hex)'),
'content' => visible_whitespace(bin2hex($html)),
'content' => $visible_whitespace(bin2hex($html)),
];
$results[] = [
@ -70,19 +70,19 @@ class Babel extends BaseModule
$bbcode2 = Text\HTML::toBBCode($html);
$results[] = [
'title' => DI::l10n()->t('BBCode::convert => HTML::toBBCode'),
'content' => visible_whitespace($bbcode2)
'content' => $visible_whitespace($bbcode2)
];
$markdown = Text\BBCode::toMarkdown($bbcode);
$results[] = [
'title' => DI::l10n()->t('BBCode::toMarkdown'),
'content' => visible_whitespace($markdown)
'content' => $visible_whitespace($markdown)
];
$html2 = Text\Markdown::convert($markdown);
$results[] = [
'title' => DI::l10n()->t('BBCode::toMarkdown => Markdown::convert (raw HTML)'),
'content' => visible_whitespace($html2)
'content' => $visible_whitespace($html2)
];
$results[] = [
'title' => DI::l10n()->t('BBCode::toMarkdown => Markdown::convert'),
@ -92,13 +92,13 @@ class Babel extends BaseModule
$bbcode3 = Text\Markdown::toBBCode($markdown);
$results[] = [
'title' => DI::l10n()->t('BBCode::toMarkdown => Markdown::toBBCode'),
'content' => visible_whitespace($bbcode3)
'content' => $visible_whitespace($bbcode3)
];
$bbcode4 = Text\HTML::toBBCode($html2);
$results[] = [
'title' => DI::l10n()->t('BBCode::toMarkdown => Markdown::convert => HTML::toBBCode'),
'content' => visible_whitespace($bbcode4)
'content' => $visible_whitespace($bbcode4)
];
$tags = Text\BBCode::getTags($bbcode);
@ -106,22 +106,22 @@ class Babel extends BaseModule
$body = Item::setHashtags($bbcode);
$results[] = [
'title' => DI::l10n()->t('Item Body'),
'content' => visible_whitespace($body)
'content' => $visible_whitespace($body)
];
$results[] = [
'title' => DI::l10n()->t('Item Tags'),
'content' => visible_whitespace(var_export($tags, true)),
'content' => $visible_whitespace(var_export($tags, true)),
];
$body2 = PageInfo::searchAndAppendToBody($bbcode, true);
$results[] = [
'title' => DI::l10n()->t('PageInfo::appendToBody'),
'content' => visible_whitespace($body2)
'content' => $visible_whitespace($body2)
];
$html3 = Text\BBCode::convertForUriId(0, $body2);
$results[] = [
'title' => DI::l10n()->t('PageInfo::appendToBody => BBCode::convert (raw HTML)'),
'content' => visible_whitespace($html3)
'content' => $visible_whitespace($html3)
];
$results[] = [
'title' => DI::l10n()->t('PageInfo::appendToBody => BBCode::convert'),
@ -132,7 +132,7 @@ class Babel extends BaseModule
$diaspora = trim($request['text']);
$results[] = [
'title' => DI::l10n()->t('Source input (Diaspora format)'),
'content' => visible_whitespace($diaspora),
'content' => $visible_whitespace($diaspora),
];
$markdown = XML::unescape($diaspora);
@ -141,13 +141,13 @@ class Babel extends BaseModule
$results[] = [
'title' => DI::l10n()->t('Source input (Markdown)'),
'content' => visible_whitespace($markdown),
'content' => $visible_whitespace($markdown),
];
$html = Text\Markdown::convert($markdown);
$results[] = [
'title' => DI::l10n()->t('Markdown::convert (raw HTML)'),
'content' => visible_whitespace($html),
'content' => $visible_whitespace($html),
];
$results[] = [
@ -158,14 +158,14 @@ class Babel extends BaseModule
$bbcode = Text\Markdown::toBBCode($markdown);
$results[] = [
'title' => DI::l10n()->t('Markdown::toBBCode'),
'content' => visible_whitespace($bbcode),
'content' => $visible_whitespace($bbcode),
];
break;
case 'html' :
$html = trim($request['text']);
$results[] = [
'title' => DI::l10n()->t('Raw HTML input'),
'content' => visible_whitespace($html),
'content' => $visible_whitespace($html),
];
$results[] = [
@ -177,12 +177,12 @@ class Babel extends BaseModule
$results[] = [
'title' => DI::l10n()->t('HTML Purified (raw)'),
'content' => visible_whitespace($purified),
'content' => $visible_whitespace($purified),
];
$results[] = [
'title' => DI::l10n()->t('HTML Purified (hex)'),
'content' => visible_whitespace(bin2hex($purified)),
'content' => $visible_whitespace(bin2hex($purified)),
];
$results[] = [
@ -193,7 +193,7 @@ class Babel extends BaseModule
$bbcode = Text\HTML::toBBCode($html);
$results[] = [
'title' => DI::l10n()->t('HTML::toBBCode'),
'content' => visible_whitespace($bbcode)
'content' => $visible_whitespace($bbcode)
];
$html2 = Text\BBCode::convertForUriId(0, $bbcode);
@ -210,25 +210,25 @@ class Babel extends BaseModule
$bbcode2plain = Text\BBCode::toPlaintext($bbcode);
$results[] = [
'title' => DI::l10n()->t('HTML::toBBCode => BBCode::toPlaintext'),
'content' => visible_whitespace($bbcode2plain),
'content' => $visible_whitespace($bbcode2plain),
];
$markdown = Text\HTML::toMarkdown($html);
$results[] = [
'title' => DI::l10n()->t('HTML::toMarkdown'),
'content' => visible_whitespace($markdown)
'content' => $visible_whitespace($markdown)
];
$text = Text\HTML::toPlaintext($html, 0);
$results[] = [
'title' => DI::l10n()->t('HTML::toPlaintext'),
'content' => visible_whitespace($text),
'content' => $visible_whitespace($text),
];
$text = Text\HTML::toPlaintext($html, 0, true);
$results[] = [
'title' => DI::l10n()->t('HTML::toPlaintext (compact)'),
'content' => visible_whitespace($text),
'content' => $visible_whitespace($text),
];
break;
case 'twitter':
@ -237,16 +237,11 @@ class Babel extends BaseModule
if (file_exists('addon/twitter/twitter.php')) {
require_once 'addon/twitter/twitter.php';
if (parse_url($json) !== false) {
preg_match('#^https?://(?:mobile\.|www\.)?twitter.com/[^/]+/status/(\d+).*#', $json, $matches);
$status = twitter_statuses_show($matches[1]);
} else {
$status = json_decode($json);
}
$status = json_decode($json);
$results[] = [
'title' => DI::l10n()->t('Decoded post'),
'content' => visible_whitespace(var_export($status, true)),
'content' => $visible_whitespace(var_export($status, true)),
];
$postarray = [];
@ -263,23 +258,9 @@ class Babel extends BaseModule
$postarray['object-type'] = Activity\ObjectType::BOOKMARK;
}
$picture = \twitter_media_entities($status, $postarray);
$results[] = [
'title' => DI::l10n()->t('Post array before expand entities'),
'content' => visible_whitespace(var_export($postarray, true)),
];
$converted = \twitter_expand_entities($postarray['body'], $status, $picture);
$results[] = [
'title' => DI::l10n()->t('Post converted'),
'content' => visible_whitespace(var_export($converted, true)),
];
$results[] = [
'title' => DI::l10n()->t('Converted body'),
'content' => visible_whitespace($converted['body']),
'content' => $visible_whitespace(var_export($postarray, true)),
];
} else {
$results[] = [

View file

@ -11,36 +11,43 @@ use Friendica\BaseModule;
use Friendica\Core\System;
use Friendica\DI;
use Friendica\Model\Post;
use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\Network\HTTPException\UnauthorizedException;
/**
* Print the body of an Item
*/
class ItemBody extends BaseModule
{
/**
* @throws NotFoundException|UnauthorizedException
*
* @return string|never
*/
protected function content(array $request = []): string
{
if (!DI::userSession()->getLocalUserId()) {
throw new HTTPException\UnauthorizedException(DI::l10n()->t('Access denied.'));
throw new UnauthorizedException(DI::l10n()->t('Access denied.'));
}
if (empty($this->parameters['item'])) {
throw new HTTPException\NotFoundException(DI::l10n()->t('Item not found.'));
throw new NotFoundException(DI::l10n()->t('Item not found.'));
}
$itemId = intval($this->parameters['item']);
$item = Post::selectFirst(['body'], ['uid' => [0, DI::userSession()->getLocalUserId()], 'uri-id' => $itemId]);
if (!empty($item)) {
if (DI::mode()->isAjax()) {
echo str_replace("\n", '<br />', $item['body']);
System::exit();
} else {
return str_replace("\n", '<br />', $item['body']);
}
} else {
throw new HTTPException\NotFoundException(DI::l10n()->t('Item not found.'));
if (empty($item)) {
throw new NotFoundException(DI::l10n()->t('Item not found.'));
}
// TODO: Extract this code into controller
if (DI::mode()->isAjax()) {
echo str_replace("\n", '<br />', $item['body']);
System::exit();
}
return str_replace("\n", '<br />', $item['body']);
}
}

View file

@ -17,16 +17,30 @@ use Friendica\BaseDataTransferObject;
*/
class Preferences extends BaseDataTransferObject
{
// /** @var string (Enumerable, oneOf) */
// protected $posting_default_visibility;
// /** @var bool */
// protected $posting_default_sensitive;
// /** @var string (ISO 639-1 language two-letter code), or null*/
// protected $posting_default_language;
// /** @var string (Enumerable, oneOf) */
// protected $reading_expand_media;
// /** @var bool */
// protected $reading_expand_spoilers;
/**
* @var string (Enumerable, oneOf)
*/
private $visibility;
/**
* @var bool
*/
private $sensitive;
/**
* @var string (ISO 639-1 language two-letter code), or null
*/
private $language;
/**
* @var string (Enumerable, oneOf)
*/
private $media;
/**
* @var bool
*/
private $spoilers;
/**
* Creates a preferences record.
@ -39,10 +53,26 @@ class Preferences extends BaseDataTransferObject
*/
public function __construct(string $visibility, bool $sensitive, string $language, string $media, bool $spoilers)
{
$this->{'posting:default:visibility'} = $visibility;
$this->{'posting:default:sensitive'} = $sensitive;
$this->{'posting:default:language'} = $language;
$this->{'reading:expand:media'} = $media;
$this->{'reading:expand:spoilers'} = $spoilers;
$this->visibility = $visibility;
$this->sensitive = $sensitive;
$this->language = $language;
$this->media = $media;
$this->spoilers = $spoilers;
}
/**
* Returns the current entity as an array
*
* @return array
*/
public function toArray(): array
{
return [
'posting:default:visibility' => $this->visibility,
'posting:default:sensitive' => $this->sensitive,
'posting:default:language' => $this->language,
'reading:expand:media' => $this->media,
'reading:expand:spoilers' => $this->spoilers,
];
}
}

View file

@ -1880,25 +1880,29 @@ class Receiver
$object_data = self::getObjectDataFromActivity($object);
$receiverdata = self::getReceivers($object, $actor ?: $object_data['actor'] ?? '', $object_data['tags'], true, false);
$receivers = $reception_types = [];
foreach ($receiverdata as $key => $data) {
$receivers[$key] = $data['uid'];
$reception_types[$data['uid']] = $data['type'] ?? 0;
}
$object_data['receiver_urls'] = self::getReceiverURL($object);
$object_data['receiver'] = $receivers;
$object_data['reception_type'] = $reception_types;
$object_data['receiver'] = [];
$object_data['reception_type'] = [];
$object_data['unlisted'] = false;
$receiverdata = self::getReceivers($object, $actor ?: $object_data['actor'] ?? '', $object_data['tags'], true, false);
foreach ($receiverdata as $key => $data) {
if ($data['uid'] !== -1) {
$object_data['reception_type'][$data['uid']] = $data['type'] ?? 0;
}
if ($key !== -1) {
$object_data['receiver'][$key] = $data['uid'];
} else {
$object_data['unlisted'] = true;
}
}
if (!empty($object['pixelfed:capabilities'])) {
$object_data['capabilities'] = self::getCapabilities($object);
}
$object_data['unlisted'] = in_array(-1, $object_data['receiver']);
unset($object_data['receiver'][-1]);
unset($object_data['reception_type'][-1]);
return $object_data;
}

View file

@ -359,6 +359,8 @@ class Temporal
return sprintf($format, $r, (($r == 1) ? $str[0] : $str[1]));
}
}
return '';
}
/**

View file

@ -0,0 +1,46 @@
<?php
// Copyright (C) 2010-2024, the Friendica project
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
//
// SPDX-License-Identifier: AGPL-3.0-or-later
namespace Friendica\Test\Unit\Object\Api\Mastodon;
use Friendica\Object\Api\Mastodon\Preferences;
use PHPUnit\Framework\TestCase;
class PreferencesTest extends TestCase
{
public function testToArrayReturnsArray(): void
{
$preferences = new Preferences('visibility', true, 'language', 'media', false);
self::assertSame(
[
'posting:default:visibility' => 'visibility',
'posting:default:sensitive' => true,
'posting:default:language' => 'language',
'reading:expand:media' => 'media',
'reading:expand:spoilers' => false,
],
$preferences->toArray(),
);
}
public function testJsonSerializeReturnsArray(): void
{
$preferences = new Preferences('visibility', true, 'language', 'media', false);
self::assertSame(
[
'posting:default:visibility' => 'visibility',
'posting:default:sensitive' => true,
'posting:default:language' => 'language',
'reading:expand:media' => 'media',
'reading:expand:spoilers' => false,
],
$preferences->jsonSerialize(),
);
}
}

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2024.09-rc\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-15 06:54+0000\n"
"POT-Creation-Date: 2024-11-16 08:31+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -39,8 +39,8 @@ msgid "Empty post discarded."
msgstr ""
#: mod/item.php:425 src/Module/Admin/Themes/Details.php:31
#: src/Module/Admin/Themes/Index.php:51 src/Module/Debug/ItemBody.php:28
#: src/Module/Debug/ItemBody.php:43 src/Module/Item/Feed.php:66
#: src/Module/Admin/Themes/Index.php:51 src/Module/Debug/ItemBody.php:34
#: src/Module/Debug/ItemBody.php:42 src/Module/Item/Feed.php:66
msgid "Item not found."
msgstr ""
@ -292,8 +292,8 @@ msgstr ""
#: mod/photos.php:1152 mod/photos.php:1232
#: src/Module/Calendar/Event/Form.php:236 src/Module/Contact/Advanced.php:118
#: src/Module/Contact/Profile.php:376
#: src/Module/Debug/ActivityPubConversion.php:132
#: src/Module/Debug/Babel.php:307 src/Module/Debug/Localtime.php:50
#: src/Module/Debug/ActivityPubConversion.php:128
#: src/Module/Debug/Babel.php:288 src/Module/Debug/Localtime.php:50
#: src/Module/Debug/Probe.php:40 src/Module/Debug/WebFinger.php:37
#: src/Module/FriendSuggest.php:131 src/Module/Install.php:221
#: src/Module/Install.php:261 src/Module/Install.php:296
@ -792,15 +792,15 @@ msgstr ""
msgid "Common"
msgstr ""
#: src/Console/Addon.php:161 src/Console/Addon.php:185
#: src/Console/Addon.php:163 src/Console/Addon.php:187
msgid "Addon not found"
msgstr ""
#: src/Console/Addon.php:165
#: src/Console/Addon.php:167
msgid "Addon already enabled"
msgstr ""
#: src/Console/Addon.php:189
#: src/Console/Addon.php:191
msgid "Addon already disabled"
msgstr ""
@ -1065,7 +1065,7 @@ msgstr ""
msgid "Email"
msgstr ""
#: src/Content/ContactSelector.php:122 src/Module/Debug/Babel.php:301
#: src/Content/ContactSelector.php:122 src/Module/Debug/Babel.php:282
msgid "Diaspora"
msgstr ""
@ -1365,7 +1365,7 @@ msgstr ""
msgid "Public post"
msgstr ""
#: src/Content/Conversation.php:410 src/Content/Widget/VCard.php:122
#: src/Content/Conversation.php:410 src/Content/Widget/VCard.php:121
#: src/Model/Profile.php:462 src/Module/Admin/Logs/View.php:80
#: src/Module/Post/Edit.php:167
msgid "Message"
@ -2273,7 +2273,7 @@ msgstr ""
msgid "The end"
msgstr ""
#: src/Content/Text/HTML.php:847 src/Content/Widget/VCard.php:118
#: src/Content/Text/HTML.php:847 src/Content/Widget/VCard.php:117
#: src/Model/Profile.php:456 src/Module/Contact/Profile.php:484
msgid "Follow"
msgstr ""
@ -2416,18 +2416,18 @@ msgstr ""
msgid "Export calendar as csv"
msgstr ""
#: src/Content/Widget/ContactBlock.php:65
#: src/Content/Widget/ContactBlock.php:64
msgid "No contacts"
msgstr ""
#: src/Content/Widget/ContactBlock.php:96
#: src/Content/Widget/ContactBlock.php:95
#, php-format
msgid "%d Contact"
msgid_plural "%d Contacts"
msgstr[0] ""
msgstr[1] ""
#: src/Content/Widget/ContactBlock.php:113
#: src/Content/Widget/ContactBlock.php:112
msgid "View Contacts"
msgstr ""
@ -2446,27 +2446,27 @@ msgstr[1] ""
msgid "More Trending Tags"
msgstr ""
#: src/Content/Widget/VCard.php:96 src/Model/Contact.php:1207
#: src/Content/Widget/VCard.php:95 src/Model/Contact.php:1207
#: src/Model/Profile.php:441
msgid "Post to group"
msgstr ""
#: src/Content/Widget/VCard.php:101 src/Model/Contact.php:1211
#: src/Content/Widget/VCard.php:100 src/Model/Contact.php:1211
#: src/Model/Profile.php:445 src/Module/Moderation/Item/Source.php:77
msgid "Mention"
msgstr ""
#: src/Content/Widget/VCard.php:111 src/Model/Profile.php:360
#: src/Content/Widget/VCard.php:110 src/Model/Profile.php:360
#: src/Module/Contact/Profile.php:420 src/Module/Profile/Profile.php:187
msgid "XMPP:"
msgstr ""
#: src/Content/Widget/VCard.php:112 src/Model/Profile.php:361
#: src/Content/Widget/VCard.php:111 src/Model/Profile.php:361
#: src/Module/Contact/Profile.php:422 src/Module/Profile/Profile.php:191
msgid "Matrix:"
msgstr ""
#: src/Content/Widget/VCard.php:113 src/Model/Event.php:68
#: src/Content/Widget/VCard.php:112 src/Model/Event.php:68
#: src/Model/Event.php:95 src/Model/Event.php:457 src/Model/Event.php:946
#: src/Model/Profile.php:355 src/Module/Contact/Profile.php:418
#: src/Module/Directory.php:134 src/Module/Notifications/Introductions.php:180
@ -2474,18 +2474,18 @@ msgstr ""
msgid "Location:"
msgstr ""
#: src/Content/Widget/VCard.php:116 src/Model/Profile.php:469
#: src/Content/Widget/VCard.php:115 src/Model/Profile.php:469
#: src/Module/Notifications/Introductions.php:194
msgid "Network:"
msgstr ""
#: src/Content/Widget/VCard.php:120 src/Model/Contact.php:1239
#: src/Content/Widget/VCard.php:119 src/Model/Contact.php:1239
#: src/Model/Contact.php:1251 src/Model/Profile.php:458
#: src/Module/Contact/Profile.php:476
msgid "Unfollow"
msgstr ""
#: src/Content/Widget/VCard.php:126 src/Model/Contact.php:1209
#: src/Content/Widget/VCard.php:125 src/Model/Contact.php:1209
#: src/Model/Profile.php:443
msgid "View group"
msgstr ""
@ -5630,7 +5630,7 @@ msgstr ""
msgid "Babel"
msgstr ""
#: src/Module/BaseAdmin.php:97 src/Module/Debug/ActivityPubConversion.php:129
#: src/Module/BaseAdmin.php:97 src/Module/Debug/ActivityPubConversion.php:125
msgid "ActivityPub Conversion"
msgstr ""
@ -6248,7 +6248,7 @@ msgstr[1] ""
#: src/Module/Contact/Follow.php:56 src/Module/Contact/Redir.php:45
#: src/Module/Contact/Redir.php:206 src/Module/Conversation/Community.php:154
#: src/Module/Debug/ItemBody.php:24 src/Module/Diaspora/Receive.php:45
#: src/Module/Debug/ItemBody.php:30 src/Module/Diaspora/Receive.php:45
#: src/Module/Item/Display.php:82 src/Module/Item/Feed.php:45
#: src/Module/Item/Follow.php:27 src/Module/Item/Ignore.php:27
#: src/Module/Item/Language.php:39 src/Module/Item/Pin.php:27
@ -6732,23 +6732,23 @@ msgstr ""
msgid "Activity"
msgstr ""
#: src/Module/Debug/ActivityPubConversion.php:109
#: src/Module/Debug/ActivityPubConversion.php:105
msgid "Object data"
msgstr ""
#: src/Module/Debug/ActivityPubConversion.php:116
#: src/Module/Debug/ActivityPubConversion.php:112
msgid "Result Item"
msgstr ""
#: src/Module/Debug/ActivityPubConversion.php:121
#: src/Module/Debug/Babel.php:286 src/Module/Moderation/Item/Source.php:79
#: src/Module/Debug/ActivityPubConversion.php:117
#: src/Module/Debug/Babel.php:267 src/Module/Moderation/Item/Source.php:79
#: src/Module/Security/TwoFactor/Verify.php:84
msgid "Error"
msgid_plural "Errors"
msgstr[0] ""
msgstr[1] ""
#: src/Module/Debug/ActivityPubConversion.php:130
#: src/Module/Debug/ActivityPubConversion.php:126
msgid "Source activity"
msgstr ""
@ -6884,47 +6884,39 @@ msgstr ""
msgid "HTML::toPlaintext (compact)"
msgstr ""
#: src/Module/Debug/Babel.php:248
#: src/Module/Debug/Babel.php:243
msgid "Decoded post"
msgstr ""
#: src/Module/Debug/Babel.php:269
#: src/Module/Debug/Babel.php:262
msgid "Post array before expand entities"
msgstr ""
#: src/Module/Debug/Babel.php:276
msgid "Post converted"
msgstr ""
#: src/Module/Debug/Babel.php:281
msgid "Converted body"
msgstr ""
#: src/Module/Debug/Babel.php:287
#: src/Module/Debug/Babel.php:268
msgid "Twitter addon is absent from the addon/ folder."
msgstr ""
#: src/Module/Debug/Babel.php:297
#: src/Module/Debug/Babel.php:278
msgid "Babel Diagnostic"
msgstr ""
#: src/Module/Debug/Babel.php:299
#: src/Module/Debug/Babel.php:280
msgid "Source text"
msgstr ""
#: src/Module/Debug/Babel.php:300
#: src/Module/Debug/Babel.php:281
msgid "BBCode"
msgstr ""
#: src/Module/Debug/Babel.php:302
#: src/Module/Debug/Babel.php:283
msgid "Markdown"
msgstr ""
#: src/Module/Debug/Babel.php:303
#: src/Module/Debug/Babel.php:284
msgid "HTML"
msgstr ""
#: src/Module/Debug/Babel.php:305
#: src/Module/Debug/Babel.php:286
msgid "Twitter Source / Tweet URL (requires API key)"
msgstr ""