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;
@ -54,12 +55,12 @@ Options
-d|--dbdata <database> The name of the mysql/mariadb database (env MYSQL_DATABASE)
-u|--dbuser <username> The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
-P|--dbpass <password> The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
-U|--url <url> The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL)
-U|--url <url> The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL)
-B|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH)
-b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
-t|--tz <timezone> The timezone of Friendica (env FRIENDICA_TZ)
-L|--lang <language> The language of Friendica (env FRIENDICA_LANG)
Environment variables
MYSQL_HOST The host of the mysql/mariadb database (mandatory if mysql and environment is used)
MYSQL_PORT The port of the mysql/mariadb database
@ -73,7 +74,7 @@ Environment variables
FRIENDICA_ADMIN_MAIL The admin email address of Friendica (this email will be used for admin access)
FRIENDICA_TZ The timezone of Friendica
FRIENDICA_LANG The langauge of Friendica
Examples
bin/console autoinstall -f 'input.config.php
Installs Friendica with the prepared 'input.config.php' file

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
*/
@ -53,7 +56,7 @@ Usage
Description
During the 2020.12 RC period some worker task parameters have been corrupted, resulting in the impossibility to execute them.
This command restores their expected parameters.
If you didn't run Friendica during the 2020.12 RC period, you do not need to use this command.
If you didn't run Friendica during the 2020.12 RC period, you do not need to use this command.
Options
-h|--help|-? Show help information
@ -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 ""