commit
6e70ad1f0e
14 changed files with 1737 additions and 643 deletions
32
.github/workflows/code-quality.yml
vendored
32
.github/workflows/code-quality.yml
vendored
|
|
@ -75,3 +75,35 @@ jobs:
|
|||
|
||||
- name: Run PHPStan
|
||||
run: composer run phpstan
|
||||
|
||||
phpmd:
|
||||
name: PHPMD (PHP ${{ matrix.php }})
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: ['ubuntu-latest']
|
||||
php: ['8.4']
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Setup PHP with composer and extensions
|
||||
uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: none
|
||||
tools: none
|
||||
|
||||
- name: Clone addon repository
|
||||
run: git clone -b develop --single-branch https://git.friendi.ca/friendica/friendica-addons.git addon
|
||||
|
||||
- name: Install Composer dependencies
|
||||
uses: "ramsey/composer-install@v2"
|
||||
|
||||
- name: Run PHPMD
|
||||
run: vendor/bin/phpmd src/ text .phpmd-ruleset.xml --color
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -89,6 +89,7 @@ venv/
|
|||
#Ignore cache files
|
||||
.php_cs.cache
|
||||
.php-cs-fixer.cache
|
||||
.phpmd.result-cache.php
|
||||
|
||||
#ignore avatar picture cache path
|
||||
/avatar
|
||||
|
|
|
|||
26
.phpmd-ruleset.xml
Normal file
26
.phpmd-ruleset.xml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0"?>
|
||||
<ruleset name="Friendica Ruleset"
|
||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
|
||||
http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="
|
||||
http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>
|
||||
PHPMD ruleset for friendica code.
|
||||
</description>
|
||||
|
||||
<rule ref="rulesets/codesize.xml/ExcessiveClassComplexity">
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="maximum" value="800" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml/CyclomaticComplexity">
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="reportLevel" value="100" />
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
||||
3
.phpmd-ruleset.xml.license
Normal file
3
.phpmd-ruleset.xml.license
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||
|
||||
SPDX-License-Identifier: CC0-1.0
|
||||
46
.woodpecker/.phpmd_check.yml
Normal file
46
.woodpecker/.phpmd_check.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# SPDX-FileCopyrightText: 2010 - 2024 the Friendica project
|
||||
#
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
# The phpmd check is just triggered for PRs and pushes to non-stable branches of Friendica
|
||||
when:
|
||||
branch:
|
||||
exclude: [ stable ]
|
||||
event: [ pull_request, push ]
|
||||
|
||||
steps:
|
||||
restore_cache:
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: "{{ .Repo.Name }}_php${PHP_MAJOR_VERSION}_{{ arch }}_{{ os }}"
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- /tmp/drone-cache:/tmp/cache
|
||||
|
||||
composer_install:
|
||||
image: friendicaci/php8.3:php8.3.3
|
||||
commands:
|
||||
- mkdir addon # create empty addon folder to appease composer
|
||||
- export COMPOSER_HOME=.composer
|
||||
- ./bin/composer.phar install --prefer-dist
|
||||
|
||||
rebuild_cache:
|
||||
image: meltwater/drone-cache:dev
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: "{{ .Repo.Name }}_php${PHP_MAJOR_VERSION}_{{ arch }}_{{ os }}"
|
||||
archive_format: "gzip"
|
||||
mount:
|
||||
- '.composer'
|
||||
volumes:
|
||||
- /tmp/drone-cache:/tmp/cache
|
||||
|
||||
phpmd:
|
||||
image: friendicaci/php8.3:php8.3.3
|
||||
commands:
|
||||
- ./bin/composer.phar run phpmd
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
"pragmarx/google2fa": "^5.0",
|
||||
"pragmarx/recovery": "^0.2",
|
||||
"psr/clock": "^1.0",
|
||||
"psr/container": "^2.0",
|
||||
"psr/container": "^1.1|^2.0",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"psr/log": "^1.1",
|
||||
"seld/cli-prompt": "^1.0",
|
||||
|
|
@ -154,12 +154,14 @@
|
|||
"mikey179/vfsstream": "^1.6",
|
||||
"mockery/mockery": "^1.3",
|
||||
"php-mock/php-mock-phpunit": "^2.10",
|
||||
"phpmd/phpmd": "^2.15",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^9"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit",
|
||||
"test:unit": "phpunit -c tests/phpunit.xml --testsuite unit",
|
||||
"phpmd": "phpmd src/ text .phpmd-ruleset.xml --color --cache",
|
||||
"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",
|
||||
|
|
|
|||
892
composer.lock
generated
892
composer.lock
generated
|
|
@ -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": "8ee8f9186d271b65b83c2ddbd12c5c03",
|
||||
"content-hash": "b77bf714197f04022a5feb001bf07852",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asika/simple-console",
|
||||
|
|
@ -3139,6 +3139,9 @@
|
|||
"psr",
|
||||
"psr-6"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/cache/tree/master"
|
||||
},
|
||||
"time": "2016-08-06T20:24:11+00:00"
|
||||
},
|
||||
{
|
||||
|
|
@ -3187,27 +3190,22 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "2.0.2",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
|
|
@ -3232,7 +3230,11 @@
|
|||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"time": "2021-11-05T16:47:00+00:00"
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/container/issues",
|
||||
"source": "https://github.com/php-fig/container/tree/1.1.2"
|
||||
},
|
||||
"time": "2021-11-05T16:50:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/event-dispatcher",
|
||||
|
|
@ -3480,6 +3482,9 @@
|
|||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/1.1.4"
|
||||
},
|
||||
"time": "2021-05-03T11:20:27+00:00"
|
||||
},
|
||||
{
|
||||
|
|
@ -3697,16 +3702,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v2.5.2",
|
||||
"version": "v2.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
|
||||
"reference": "605389f2a7e5625f273b53960dc46aeaf9c62918"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918",
|
||||
"reference": "605389f2a7e5625f273b53960dc46aeaf9c62918",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3714,12 +3719,12 @@
|
|||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/contracts",
|
||||
"name": "symfony/contracts"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -3743,6 +3748,9 @@
|
|||
],
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
|
|
@ -3757,7 +3765,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:53:40+00:00"
|
||||
"time": "2024-09-25T14:11:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
|
|
@ -4591,6 +4599,151 @@
|
|||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<1.11.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.12 || ^2",
|
||||
"phpstan/phpstan-strict-rules": "^1 || ^2",
|
||||
"phpunit/phpunit": "^8 || ^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Pcre\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||
"keywords": [
|
||||
"PCRE",
|
||||
"preg",
|
||||
"regex",
|
||||
"regular expression"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-12T16:29:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
"version": "3.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/xdebug-handler.git",
|
||||
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
|
||||
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/pcre": "^1 || ^2 || ^3",
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"psr/log": "^1 || ^2 || ^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.1",
|
||||
"phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\XdebugHandler\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "John Stevenson",
|
||||
"email": "john-stevenson@blueyonder.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Restarts a process without Xdebug.",
|
||||
"keywords": [
|
||||
"Xdebug",
|
||||
"performance"
|
||||
],
|
||||
"support": {
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/xdebug-handler/issues",
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-06T16:37:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dms/phpunit-arraysubset-asserts",
|
||||
"version": "v0.3.1",
|
||||
|
|
@ -4976,6 +5129,69 @@
|
|||
],
|
||||
"time": "2024-03-05T20:51:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pdepend/pdepend",
|
||||
"version": "2.16.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pdepend/pdepend.git",
|
||||
"reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
|
||||
"reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.7",
|
||||
"symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||
"symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||
"symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.19"
|
||||
},
|
||||
"require-dev": {
|
||||
"easy-doc/easy-doc": "0.0.0|^1.2.3",
|
||||
"gregwar/rst": "^1.0",
|
||||
"squizlabs/php_codesniffer": "^2.0.0"
|
||||
},
|
||||
"bin": [
|
||||
"src/bin/pdepend"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PDepend\\": "src/main/php/PDepend"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Official version of pdepend to be handled with Composer",
|
||||
"keywords": [
|
||||
"PHP Depend",
|
||||
"PHP_Depend",
|
||||
"dev",
|
||||
"pdepend"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/pdepend/pdepend/issues",
|
||||
"source": "https://github.com/pdepend/pdepend/tree/2.16.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-17T18:09:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
"version": "2.0.4",
|
||||
|
|
@ -5293,6 +5509,89 @@
|
|||
],
|
||||
"time": "2024-02-11T07:24:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpmd/phpmd",
|
||||
"version": "2.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpmd/phpmd.git",
|
||||
"reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0",
|
||||
"reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0",
|
||||
"ext-xml": "*",
|
||||
"pdepend/pdepend": "^2.16.1",
|
||||
"php": ">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"easy-doc/easy-doc": "0.0.0 || ^1.3.2",
|
||||
"ext-json": "*",
|
||||
"ext-simplexml": "*",
|
||||
"gregwar/rst": "^1.0",
|
||||
"mikey179/vfsstream": "^1.6.8",
|
||||
"squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2"
|
||||
},
|
||||
"bin": [
|
||||
"src/bin/phpmd"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"PHPMD\\": "src/main/php"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Manuel Pichler",
|
||||
"email": "github@manuel-pichler.de",
|
||||
"homepage": "https://github.com/manuelpichler",
|
||||
"role": "Project Founder"
|
||||
},
|
||||
{
|
||||
"name": "Marc Würth",
|
||||
"email": "ravage@bluewin.ch",
|
||||
"homepage": "https://github.com/ravage84",
|
||||
"role": "Project Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "Other contributors",
|
||||
"homepage": "https://github.com/phpmd/phpmd/graphs/contributors",
|
||||
"role": "Contributors"
|
||||
}
|
||||
],
|
||||
"description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
|
||||
"homepage": "https://phpmd.org/",
|
||||
"keywords": [
|
||||
"dev",
|
||||
"mess detection",
|
||||
"mess detector",
|
||||
"pdepend",
|
||||
"phpmd",
|
||||
"pmd"
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/phpmd",
|
||||
"issues": "https://github.com/phpmd/phpmd/issues",
|
||||
"source": "https://github.com/phpmd/phpmd/tree/2.15.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-11T08:22:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "2.0.1",
|
||||
|
|
@ -6647,6 +6946,559 @@
|
|||
],
|
||||
"time": "2020-09-28T06:39:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v5.4.46",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/config.git",
|
||||
"reference": "977c88a02d7d3f16904a81907531b19666a08e78"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/977c88a02d7d3f16904a81907531b19666a08e78",
|
||||
"reference": "977c88a02d7d3f16904a81907531b19666a08e78",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"symfony/filesystem": "^4.4|^5.0|^6.0",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/polyfill-php81": "^1.22"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/finder": "<4.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/event-dispatcher": "^4.4|^5.0|^6.0",
|
||||
"symfony/finder": "^4.4|^5.0|^6.0",
|
||||
"symfony/messenger": "^4.4|^5.0|^6.0",
|
||||
"symfony/service-contracts": "^1.1|^2|^3",
|
||||
"symfony/yaml": "^4.4|^5.0|^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "To use the yaml reference dumper"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Config\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/config/tree/v5.4.46"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-30T07:58:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"version": "v5.4.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dependency-injection.git",
|
||||
"reference": "e5ca16dee39ef7d63e552ff0bf0a2526a1142c92"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e5ca16dee39ef7d63e552ff0bf0a2526a1142c92",
|
||||
"reference": "e5ca16dee39ef7d63e552ff0bf0a2526a1142c92",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/container": "^1.1.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/polyfill-php81": "^1.22",
|
||||
"symfony/service-contracts": "^1.1.6|^2"
|
||||
},
|
||||
"conflict": {
|
||||
"ext-psr": "<1.1|>=2",
|
||||
"symfony/config": "<5.3",
|
||||
"symfony/finder": "<4.4",
|
||||
"symfony/proxy-manager-bridge": "<4.4",
|
||||
"symfony/yaml": "<4.4.26"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "1.0",
|
||||
"symfony/service-implementation": "1.0|2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "^5.3|^6.0",
|
||||
"symfony/expression-language": "^4.4|^5.0|^6.0",
|
||||
"symfony/yaml": "^4.4.26|^5.0|^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/config": "",
|
||||
"symfony/expression-language": "For using expressions in service container configuration",
|
||||
"symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required",
|
||||
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
|
||||
"symfony/yaml": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\DependencyInjection\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.48"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-20T10:51:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v5.4.45",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "57c8294ed37d4a055b77057827c67f9558c95c54"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/57c8294ed37d4a055b77057827c67f9558c95c54",
|
||||
"reference": "57c8294ed37d4a055b77057827c67f9558c95c54",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-mbstring": "~1.8",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/process": "^5.4|^6.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Filesystem\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v5.4.45"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-22T13:05:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php81\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v2.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "f37b419f7aea2e9abf10abd261832cace12e3300"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/f37b419f7aea2e9abf10abd261832cace12e3300",
|
||||
"reference": "f37b419f7aea2e9abf10abd261832cace12e3300",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/container": "^1.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"ext-psr": "<1.1|>=2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/service-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/contracts",
|
||||
"name": "symfony/contracts"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Service\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to writing services",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v2.5.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-25T14:11:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
"version": "1.2.3",
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ class APContact
|
|||
DI::cache()->set($cachekey, System::callstack(20), Duration::FIVE_MINUTES);
|
||||
}
|
||||
|
||||
$local_owner = [];
|
||||
|
||||
if (DI::baseUrl()->isLocalUrl($url) && ($local_uid = User::getIdForURL($url))) {
|
||||
try {
|
||||
$data = Transmitter::getProfile($local_uid);
|
||||
|
|
@ -205,6 +207,15 @@ class APContact
|
|||
return $fetched_contact;
|
||||
}
|
||||
|
||||
return self::compactProfile($apcontact, $compacted, $url, $fetched_contact, $webfinger, $local_owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|bool $fetched_contact
|
||||
* @param array|bool $local_owner
|
||||
*/
|
||||
private static function compactProfile(array $apcontact, array $compacted, string $url, $fetched_contact, bool $webfinger, $local_owner): array
|
||||
{
|
||||
$apcontact['url'] = $compacted['@id'];
|
||||
$apcontact['uuid'] = JsonLD::fetchElement($compacted, 'diaspora:guid', '@value');
|
||||
$apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type'));
|
||||
|
|
|
|||
|
|
@ -817,6 +817,25 @@ class GServer
|
|||
}
|
||||
|
||||
// Count the number of known contacts from this server
|
||||
self::countNumberOfKnownContacts((int) $id, $serverdata);
|
||||
|
||||
if (in_array($serverdata['network'], [Protocol::DFRN, Protocol::DIASPORA])) {
|
||||
self::discoverRelay($url);
|
||||
}
|
||||
|
||||
if (!empty($systemactor)) {
|
||||
$contact = Contact::getByURL($systemactor, true, ['gsid', 'baseurl', 'id', 'network', 'url', 'name']);
|
||||
DI::logger()->debug('Fetched system actor', ['url' => $url, 'gsid' => $id, 'contact' => $contact]);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of known contacts from this server
|
||||
*/
|
||||
private static function countNumberOfKnownContacts(int $id, array $serverdata): void
|
||||
{
|
||||
if (!empty($id) && !in_array($serverdata['network'], [Protocol::PHANTOM, Protocol::FEED])) {
|
||||
$apcontacts = DBA::count('apcontact', ['gsid' => $id]);
|
||||
$contacts = DBA::count('contact', ['uid' => 0, 'gsid' => $id, 'failed' => false]);
|
||||
|
|
@ -842,17 +861,6 @@ class GServer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($serverdata['network'], [Protocol::DFRN, Protocol::DIASPORA])) {
|
||||
self::discoverRelay($url);
|
||||
}
|
||||
|
||||
if (!empty($systemactor)) {
|
||||
$contact = Contact::getByURL($systemactor, true, ['gsid', 'baseurl', 'id', 'network', 'url', 'name']);
|
||||
DI::logger()->debug('Fetched system actor', ['url' => $url, 'gsid' => $id, 'contact' => $contact]);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -580,52 +580,6 @@ class Item
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the item array is a duplicate
|
||||
*
|
||||
* @param array $item Item record
|
||||
* @return boolean is it a duplicate?
|
||||
*/
|
||||
private static function isDuplicate(array $item): bool
|
||||
{
|
||||
// Checking if there is already an item with the same guid
|
||||
$condition = ['guid' => $item['guid'], 'network' => $item['network'], 'uid' => $item['uid']];
|
||||
if (Post::exists($condition)) {
|
||||
DI::logger()->notice('Found already existing item', $condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
$condition = [
|
||||
'uri-id' => $item['uri-id'], 'uid' => $item['uid'],
|
||||
'network' => [$item['network'], Protocol::DFRN]
|
||||
];
|
||||
if (Post::exists($condition)) {
|
||||
DI::logger()->notice('duplicated item with the same uri found.', $condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
// On Friendica and Diaspora the GUID is unique
|
||||
if (in_array($item['network'], [Protocol::DFRN, Protocol::DIASPORA])) {
|
||||
$condition = ['guid' => $item['guid'], 'uid' => $item['uid']];
|
||||
if (Post::exists($condition)) {
|
||||
DI::logger()->notice('duplicated item with the same guid found.', $condition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for already added items.
|
||||
* There is a timing issue here that sometimes creates double postings.
|
||||
* An unique index would help - but the limitations of MySQL (maximum size of index values) prevent this.
|
||||
*/
|
||||
if (($item['uid'] == 0) && Post::exists(['uri-id' => $item['uri-id'], 'uid' => 0])) {
|
||||
DI::logger()->notice('Global item already stored.', ['uri-id' => $item['uri-id'], 'network' => $item['network']]);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the item array is valid
|
||||
*
|
||||
|
|
@ -694,42 +648,6 @@ class Item
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the given item array if it has been stored before
|
||||
*
|
||||
* @param array $item Item record
|
||||
* @return integer Item id or zero on error
|
||||
*/
|
||||
private static function getDuplicateID(array $item): int
|
||||
{
|
||||
if (empty($item['network']) || in_array($item['network'], Protocol::FEDERATED)) {
|
||||
$condition = [
|
||||
'`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?)',
|
||||
$item['uri-id'],
|
||||
$item['uid'],
|
||||
Protocol::ACTIVITYPUB,
|
||||
Protocol::DIASPORA,
|
||||
Protocol::DFRN
|
||||
];
|
||||
$existing = Post::selectFirst(['id', 'network'], $condition);
|
||||
if (DBA::isResult($existing)) {
|
||||
// We only log the entries with a different user id than 0. Otherwise we would have too many false positives
|
||||
if ($item['uid'] != 0) {
|
||||
DI::logger()->notice('Item already existed for user', [
|
||||
'uri-id' => $item['uri-id'],
|
||||
'uid' => $item['uid'],
|
||||
'network' => $item['network'],
|
||||
'existing_id' => $existing['id'],
|
||||
'existing_network' => $existing['network']
|
||||
]);
|
||||
}
|
||||
|
||||
return $existing['id'];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the uri-id of the parent for the given uri-id
|
||||
*
|
||||
|
|
@ -750,106 +668,6 @@ class Item
|
|||
return self::getParent($thread_parent['thr-parent-id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch top-level parent data for the given item array
|
||||
*
|
||||
* @param array $item
|
||||
* @return array item array with parent data
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function getTopLevelParent(array $item): array
|
||||
{
|
||||
$fields = [
|
||||
'uid', 'uri', 'parent-uri', 'id', 'deleted',
|
||||
'uri-id', 'parent-uri-id', 'restrictions', 'verb',
|
||||
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
|
||||
'wall', 'private', 'origin', 'author-id'
|
||||
];
|
||||
$condition = ['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => $item['uid']];
|
||||
$params = ['order' => ['id' => false]];
|
||||
$parent = Post::selectFirst($fields, $condition, $params);
|
||||
|
||||
if (!DBA::isResult($parent) && Post::exists(['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => 0])) {
|
||||
$stored = Item::storeForUserByUriId($item['thr-parent-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]);
|
||||
if (!$stored && ($item['thr-parent-id'] != $item['parent-uri-id'])) {
|
||||
$stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]);
|
||||
}
|
||||
if ($stored) {
|
||||
DI::logger()->info('Stored thread parent item for user', ['uri-id' => $item['thr-parent-id'], 'uid' => $item['uid'], 'stored' => $stored]);
|
||||
$parent = Post::selectFirst($fields, $condition, $params);
|
||||
}
|
||||
}
|
||||
|
||||
if (!DBA::isResult($parent)) {
|
||||
DI::logger()->notice('item parent was not found - ignoring item', ['uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
|
||||
return [];
|
||||
}
|
||||
|
||||
if (self::hasRestrictions($item, $parent['author-id'], $parent['restrictions'])) {
|
||||
DI::logger()->notice('Restrictions apply - ignoring item', ['restrictions' => $parent['restrictions'], 'verb' => $parent['verb'], 'uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($parent['uri-id'] == $parent['parent-uri-id']) {
|
||||
return $parent;
|
||||
}
|
||||
|
||||
$condition = [
|
||||
'uri-id' => $parent['parent-uri-id'],
|
||||
'parent-uri-id' => $parent['parent-uri-id'],
|
||||
'uid' => $parent['uid']
|
||||
];
|
||||
$params = ['order' => ['id' => false]];
|
||||
$toplevel_parent = Post::selectFirst($fields, $condition, $params);
|
||||
|
||||
if (!DBA::isResult($toplevel_parent) && $item['origin']) {
|
||||
$stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]);
|
||||
DI::logger()->info('Stored parent item for user', ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid'], 'stored' => $stored]);
|
||||
$toplevel_parent = Post::selectFirst($fields, $condition, $params);
|
||||
}
|
||||
|
||||
if (!DBA::isResult($toplevel_parent)) {
|
||||
DI::logger()->notice('item top level parent was not found - ignoring item', ['parent-uri-id' => $parent['parent-uri-id'], 'uid' => $parent['uid']]);
|
||||
return [];
|
||||
}
|
||||
|
||||
return $toplevel_parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the gravity for the given item array
|
||||
*
|
||||
* @param array $item
|
||||
* @return integer gravity
|
||||
*/
|
||||
private static function getGravity(array $item): int
|
||||
{
|
||||
$activity = DI::activity();
|
||||
|
||||
if (isset($item['gravity'])) {
|
||||
return intval($item['gravity']);
|
||||
} elseif ($item['parent-uri-id'] === $item['uri-id']) {
|
||||
return self::GRAVITY_PARENT;
|
||||
} elseif ($activity->match($item['verb'], Activity::POST)) {
|
||||
return self::GRAVITY_COMMENT;
|
||||
} elseif ($activity->match($item['verb'], Activity::FOLLOW)) {
|
||||
return self::GRAVITY_ACTIVITY;
|
||||
} elseif ($activity->match($item['verb'], Activity::ANNOUNCE)) {
|
||||
return self::GRAVITY_ACTIVITY;
|
||||
}
|
||||
|
||||
DI::logger()->info('Unknown gravity for verb', ['verb' => $item['verb']]);
|
||||
return self::GRAVITY_UNKNOWN; // Should not happen
|
||||
}
|
||||
|
||||
private static function prepareOriginPost(array $item): array
|
||||
{
|
||||
$item = DI::contentItem()->initializePost($item);
|
||||
$item = DI::contentItem()->finalizePost($item, false);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts item record
|
||||
*
|
||||
|
|
@ -860,6 +678,14 @@ class Item
|
|||
*/
|
||||
public static function insert(array $item, int $notify = 0, bool $post_local = true): int
|
||||
{
|
||||
$itemHelper = new ItemHelper(
|
||||
DI::contentItem(),
|
||||
DI::activity(),
|
||||
DI::logger(),
|
||||
DI::dba(),
|
||||
DI::baseUrl(),
|
||||
);
|
||||
|
||||
$orig_item = $item;
|
||||
|
||||
$priority = Worker::PRIORITY_HIGH;
|
||||
|
|
@ -868,7 +694,7 @@ class Item
|
|||
|
||||
// If it is a posting where users should get notifications, then define it as wall posting
|
||||
if ($notify) {
|
||||
$item = self::prepareOriginPost($item);
|
||||
$item = $itemHelper->prepareOriginPost($item);
|
||||
|
||||
if (is_int($notify) && in_array($notify, Worker::PRIORITIES)) {
|
||||
$priority = $notify;
|
||||
|
|
@ -881,23 +707,7 @@ class Item
|
|||
$item['network'] = trim(($item['network'] ?? '') ?: Protocol::PHANTOM);
|
||||
}
|
||||
|
||||
$uid = intval($item['uid']);
|
||||
|
||||
$item['guid'] = self::guid($item, $notify);
|
||||
$item['uri'] = substr(trim($item['uri'] ?? '') ?: self::newURI($item['guid']), 0, 255);
|
||||
|
||||
// Store URI data
|
||||
$item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
|
||||
|
||||
// Backward compatibility: parent-uri used to be the direct parent uri.
|
||||
// If it is provided without a thr-parent, it probably is the old behavior.
|
||||
if (empty($item['thr-parent']) || empty($item['parent-uri'])) {
|
||||
$item['thr-parent'] = trim($item['thr-parent'] ?? $item['parent-uri'] ?? $item['uri']);
|
||||
$item['parent-uri'] = $item['thr-parent'];
|
||||
}
|
||||
|
||||
$item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']);
|
||||
$item['parent-uri-id'] = ItemURI::getIdByURI($item['parent-uri']);
|
||||
$item = $itemHelper->prepareItemData($item, (bool) $notify);
|
||||
|
||||
// Store conversation data
|
||||
$source = $item['source'] ?? '';
|
||||
|
|
@ -910,14 +720,14 @@ class Item
|
|||
* We have to check several networks since Friendica posts could be repeated
|
||||
* via Diaspora.
|
||||
*/
|
||||
$duplicate = self::getDuplicateID($item);
|
||||
$duplicate = $itemHelper->getDuplicateID($item);
|
||||
if ($duplicate) {
|
||||
return $duplicate;
|
||||
}
|
||||
|
||||
// Additional duplicate checks
|
||||
/// @todo Check why the first duplication check returns the item number and the second a 0
|
||||
if (self::isDuplicate($item)) {
|
||||
if ($itemHelper->isDuplicate($item)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -927,44 +737,7 @@ class Item
|
|||
|
||||
$defined_permissions = isset($item['allow_cid']) && isset($item['allow_gid']) && isset($item['deny_cid']) && isset($item['deny_gid']) && isset($item['private']);
|
||||
|
||||
$item['wall'] = intval($item['wall'] ?? 0);
|
||||
$item['extid'] = trim($item['extid'] ?? '');
|
||||
$item['author-name'] = trim($item['author-name'] ?? '');
|
||||
$item['author-link'] = trim($item['author-link'] ?? '');
|
||||
$item['author-avatar'] = trim($item['author-avatar'] ?? '');
|
||||
$item['owner-name'] = trim($item['owner-name'] ?? '');
|
||||
$item['owner-link'] = trim($item['owner-link'] ?? '');
|
||||
$item['owner-avatar'] = trim($item['owner-avatar'] ?? '');
|
||||
$item['received'] = (isset($item['received']) ? DateTimeFormat::utc($item['received']) : DateTimeFormat::utcNow());
|
||||
$item['created'] = (isset($item['created']) ? DateTimeFormat::utc($item['created']) : $item['received']);
|
||||
$item['edited'] = (isset($item['edited']) ? DateTimeFormat::utc($item['edited']) : $item['created']);
|
||||
$item['changed'] = (isset($item['changed']) ? DateTimeFormat::utc($item['changed']) : $item['created']);
|
||||
$item['commented'] = (isset($item['commented']) ? DateTimeFormat::utc($item['commented']) : $item['created']);
|
||||
$item['title'] = substr(trim($item['title'] ?? ''), 0, 255);
|
||||
$item['location'] = trim($item['location'] ?? '');
|
||||
$item['coord'] = trim($item['coord'] ?? '');
|
||||
$item['visible'] = (isset($item['visible']) ? intval($item['visible']) : 1);
|
||||
$item['deleted'] = 0;
|
||||
$item['verb'] = trim($item['verb'] ?? '');
|
||||
$item['object-type'] = trim($item['object-type'] ?? '');
|
||||
$item['object'] = trim($item['object'] ?? '');
|
||||
$item['target-type'] = trim($item['target-type'] ?? '');
|
||||
$item['target'] = trim($item['target'] ?? '');
|
||||
$item['plink'] = substr(trim($item['plink'] ?? ''), 0, 255);
|
||||
$item['allow_cid'] = trim($item['allow_cid'] ?? '');
|
||||
$item['allow_gid'] = trim($item['allow_gid'] ?? '');
|
||||
$item['deny_cid'] = trim($item['deny_cid'] ?? '');
|
||||
$item['deny_gid'] = trim($item['deny_gid'] ?? '');
|
||||
$item['private'] = intval($item['private'] ?? self::PUBLIC);
|
||||
$item['body'] = trim($item['body'] ?? '');
|
||||
$item['raw-body'] = trim($item['raw-body'] ?? $item['body']);
|
||||
$item['app'] = trim($item['app'] ?? '');
|
||||
$item['origin'] = intval($item['origin'] ?? 0);
|
||||
$item['postopts'] = trim($item['postopts'] ?? '');
|
||||
$item['resource-id'] = trim($item['resource-id'] ?? '');
|
||||
$item['event-id'] = intval($item['event-id'] ?? 0);
|
||||
$item['inform'] = trim($item['inform'] ?? '');
|
||||
$item['file'] = trim($item['file'] ?? '');
|
||||
$uid = intval($item['uid']);
|
||||
|
||||
// Communities aren't working with the Diaspora protocol
|
||||
if (($uid != 0) && ($item['network'] == Protocol::DIASPORA)) {
|
||||
|
|
@ -975,33 +748,7 @@ class Item
|
|||
}
|
||||
}
|
||||
|
||||
// Items cannot be stored before they happen ...
|
||||
if ($item['created'] > DateTimeFormat::utcNow()) {
|
||||
$item['created'] = DateTimeFormat::utcNow();
|
||||
}
|
||||
|
||||
// We haven't invented time travel by now.
|
||||
if ($item['edited'] > DateTimeFormat::utcNow()) {
|
||||
$item['edited'] = DateTimeFormat::utcNow();
|
||||
}
|
||||
|
||||
$item['plink'] = ($item['plink'] ?? '') ?: DI::baseUrl() . '/display/' . urlencode($item['guid']);
|
||||
|
||||
$item['gravity'] = self::getGravity($item);
|
||||
|
||||
$default = [
|
||||
'url' => $item['author-link'], 'name' => $item['author-name'],
|
||||
'photo' => $item['author-avatar'], 'network' => $item['network']
|
||||
];
|
||||
$item['author-id'] = ($item['author-id'] ?? 0) ?: Contact::getIdForURL($item['author-link'], 0, null, $default);
|
||||
|
||||
$default = [
|
||||
'url' => $item['owner-link'], 'name' => $item['owner-name'],
|
||||
'photo' => $item['owner-avatar'], 'network' => $item['network']
|
||||
];
|
||||
$item['owner-id'] = ($item['owner-id'] ?? 0) ?: Contact::getIdForURL($item['owner-link'], 0, null, $default);
|
||||
|
||||
$item['post-reason'] = self::getPostReason($item);
|
||||
$item = $itemHelper->validateItemData($item);
|
||||
|
||||
// Ensure that there is an avatar cache
|
||||
Contact::checkAvatarCache($item['author-id']);
|
||||
|
|
@ -1022,55 +769,14 @@ class Item
|
|||
}
|
||||
|
||||
if ($item['gravity'] !== self::GRAVITY_PARENT) {
|
||||
$toplevel_parent = self::getTopLevelParent($item);
|
||||
$toplevel_parent = $itemHelper->getTopLevelParent($item);
|
||||
if (empty($toplevel_parent)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$parent_id = $toplevel_parent['id'];
|
||||
$item['parent-uri'] = $toplevel_parent['uri'];
|
||||
$item['parent-uri-id'] = $toplevel_parent['uri-id'];
|
||||
$item['deleted'] = $toplevel_parent['deleted'];
|
||||
$item['wall'] = $toplevel_parent['wall'];
|
||||
|
||||
// Reshares have to keep their permissions to allow groups to work
|
||||
if (!$defined_permissions && (!$item['origin'] || ($item['verb'] != Activity::ANNOUNCE))) {
|
||||
// Don't store the permissions on pure AP posts
|
||||
$store_permissions = ($item['network'] != Protocol::ACTIVITYPUB) || $item['origin'] || !empty($item['diaspora_signed_text']);
|
||||
$item['allow_cid'] = $store_permissions ? $toplevel_parent['allow_cid'] : '';
|
||||
$item['allow_gid'] = $store_permissions ? $toplevel_parent['allow_gid'] : '';
|
||||
$item['deny_cid'] = $store_permissions ? $toplevel_parent['deny_cid'] : '';
|
||||
$item['deny_gid'] = $store_permissions ? $toplevel_parent['deny_gid'] : '';
|
||||
}
|
||||
|
||||
$parent_id = (int) $toplevel_parent['id'];
|
||||
$item = $itemHelper->handleToplevelParent($item, $toplevel_parent, $defined_permissions);
|
||||
$parent_origin = $toplevel_parent['origin'];
|
||||
|
||||
// Don't federate received participation messages
|
||||
if ($item['verb'] != Activity::FOLLOW) {
|
||||
$item['wall'] = $toplevel_parent['wall'];
|
||||
} else {
|
||||
$item['wall'] = false;
|
||||
// Participations are technical messages, so they are set to "seen" automatically
|
||||
$item['unseen'] = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the parent is private, force privacy for the entire conversation
|
||||
* This differs from the above settings as it subtly allows comments from
|
||||
* email correspondents to be private even if the overall thread is not.
|
||||
*/
|
||||
if (!$defined_permissions && $toplevel_parent['private']) {
|
||||
$item['private'] = $toplevel_parent['private'];
|
||||
}
|
||||
|
||||
// If its a post that originated here then tag the thread as "mention"
|
||||
if ($item['origin'] && $item['uid']) {
|
||||
DBA::update('post-thread-user', ['mention' => true], ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
|
||||
DI::logger()->info('tagged thread as mention', ['parent' => $parent_id, 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
|
||||
}
|
||||
|
||||
// Update the contact relations
|
||||
Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']);
|
||||
} else {
|
||||
$parent_id = 0;
|
||||
$parent_origin = $item['origin'];
|
||||
|
|
@ -1344,6 +1050,11 @@ class Item
|
|||
|
||||
DI::logger()->notice('created item', ['post-id' => $post_user_id, 'uid' => $item['uid'], 'network' => $item['network'], 'uri-id' => $item['uri-id'], 'guid' => $item['guid']]);
|
||||
|
||||
return self::handleCreatedItem($orig_item, $post_user_id, $uid, $notify, $copy_permissions, $parent_origin, $priority, $notify_type, $inserted, $source);
|
||||
}
|
||||
|
||||
private static function handleCreatedItem(array $orig_item, int $post_user_id, int $uid, int $notify, bool $copy_permissions, $parent_origin, int $priority, string $notify_type, bool $inserted, $source): int
|
||||
{
|
||||
$posted_item = Post::selectFirst(self::ITEM_FIELDLIST, ['post-user-id' => $post_user_id]);
|
||||
if (!DBA::isResult($posted_item)) {
|
||||
// On failure store the data into a spool file so that the "SpoolPost" worker can try again later.
|
||||
|
|
@ -1484,33 +1195,6 @@ class Item
|
|||
return $post_user_id;
|
||||
}
|
||||
|
||||
private static function hasRestrictions(array $item, int $author_id, int $restrictions = null): bool
|
||||
{
|
||||
if (empty($restrictions) || ($author_id == $item['author-id'])) {
|
||||
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)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($restrictions & self::CANT_ANNOUNCE) && ($item['verb'] == Activity::ANNOUNCE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($restrictions & self::CANT_LIKE) && in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE, Activity::ATTEND, Activity::ATTENDMAYBE, Activity::ATTENDNO])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function reshareChannelPost(int $uri_id, int $reshare_id = 0)
|
||||
{
|
||||
if (!DI::config()->get('system', 'allow_relay_channels')) {
|
||||
|
|
@ -1890,7 +1574,7 @@ class Item
|
|||
*
|
||||
* @param int $uriid
|
||||
* @param int $uid
|
||||
* @return int
|
||||
* @return int|null
|
||||
*/
|
||||
private static function GetOriginUidForUriId(int $uriid, int $uid)
|
||||
{
|
||||
|
|
|
|||
404
src/Model/ItemHelper.php
Normal file
404
src/Model/ItemHelper.php
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
<?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\Model;
|
||||
|
||||
use Friendica\App\BaseURL;
|
||||
use Friendica\Content\Item as ItemContent;
|
||||
use Friendica\Core\Protocol;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* A helper class for handling an Item Model
|
||||
*
|
||||
* @internal ONLY for use in Friendica\Content\Item class
|
||||
*
|
||||
* @see Item::insert()
|
||||
*/
|
||||
final class ItemHelper
|
||||
{
|
||||
private ItemContent $itemContent;
|
||||
|
||||
private Activity $activity;
|
||||
|
||||
private LoggerInterface $logger;
|
||||
|
||||
private Database $database;
|
||||
|
||||
private string $baseUrl;
|
||||
|
||||
public function __construct(
|
||||
ItemContent $itemContent,
|
||||
Activity $activity,
|
||||
LoggerInterface $logger,
|
||||
Database $database,
|
||||
BaseURL $baseURL
|
||||
) {
|
||||
$this->itemContent = $itemContent;
|
||||
$this->activity = $activity;
|
||||
$this->logger = $logger;
|
||||
$this->database = $database;
|
||||
$this->baseUrl = $baseURL->__toString();
|
||||
}
|
||||
|
||||
public function prepareOriginPost(array $item): array
|
||||
{
|
||||
$item = $this->itemContent->initializePost($item);
|
||||
$item = $this->itemContent->finalizePost($item, false);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
public function prepareItemData(array $item, bool $notify): array
|
||||
{
|
||||
$item['guid'] = Item::guid($item, $notify);
|
||||
$item['uri'] = substr(trim($item['uri'] ?? '') ?: Item::newURI($item['guid']), 0, 255);
|
||||
|
||||
// Store URI data
|
||||
$item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
|
||||
|
||||
// Backward compatibility: parent-uri used to be the direct parent uri.
|
||||
// If it is provided without a thr-parent, it probably is the old behavior.
|
||||
if (empty($item['thr-parent']) || empty($item['parent-uri'])) {
|
||||
$item['thr-parent'] = trim($item['thr-parent'] ?? $item['parent-uri'] ?? $item['uri']);
|
||||
$item['parent-uri'] = $item['thr-parent'];
|
||||
}
|
||||
|
||||
$item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']);
|
||||
$item['parent-uri-id'] = ItemURI::getIdByURI($item['parent-uri']);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the given item array if it has been stored before
|
||||
*
|
||||
* @param array $item Item record
|
||||
* @return integer Item id or zero on error
|
||||
*/
|
||||
public function getDuplicateID(array $item): int
|
||||
{
|
||||
if (empty($item['network']) || in_array($item['network'], Protocol::FEDERATED)) {
|
||||
$condition = [
|
||||
'`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?)',
|
||||
$item['uri-id'],
|
||||
$item['uid'],
|
||||
Protocol::ACTIVITYPUB,
|
||||
Protocol::DIASPORA,
|
||||
Protocol::DFRN
|
||||
];
|
||||
|
||||
$existing = Post::selectFirst(['id', 'network'], $condition);
|
||||
|
||||
if ($this->database->isResult($existing)) {
|
||||
// We only log the entries with a different user id than 0. Otherwise we would have too many false positives
|
||||
if ($item['uid'] != 0) {
|
||||
$this->logger->notice('Item already existed for user', [
|
||||
'uri-id' => $item['uri-id'],
|
||||
'uid' => $item['uid'],
|
||||
'network' => $item['network'],
|
||||
'existing_id' => $existing['id'],
|
||||
'existing_network' => $existing['network']
|
||||
]);
|
||||
}
|
||||
|
||||
return $existing['id'];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the item array is a duplicate
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param array $item Item record
|
||||
* @return boolean is it a duplicate?
|
||||
*/
|
||||
public function isDuplicate(array $item): bool
|
||||
{
|
||||
// Checking if there is already an item with the same guid
|
||||
$condition = ['guid' => $item['guid'], 'network' => $item['network'], 'uid' => $item['uid']];
|
||||
if (Post::exists($condition)) {
|
||||
$this->logger->notice('Found already existing item', $condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
$condition = [
|
||||
'uri-id' => $item['uri-id'], 'uid' => $item['uid'],
|
||||
'network' => [$item['network'], Protocol::DFRN]
|
||||
];
|
||||
if (Post::exists($condition)) {
|
||||
$this->logger->notice('duplicated item with the same uri found.', $condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
// On Friendica and Diaspora the GUID is unique
|
||||
if (in_array($item['network'], [Protocol::DFRN, Protocol::DIASPORA])) {
|
||||
$condition = ['guid' => $item['guid'], 'uid' => $item['uid']];
|
||||
if (Post::exists($condition)) {
|
||||
$this->logger->notice('duplicated item with the same guid found.', $condition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for already added items.
|
||||
* There is a timing issue here that sometimes creates double postings.
|
||||
* An unique index would help - but the limitations of MySQL (maximum size of index values) prevent this.
|
||||
*/
|
||||
if (($item['uid'] == 0) && Post::exists(['uri-id' => $item['uri-id'], 'uid' => 0])) {
|
||||
$this->logger->notice('Global item already stored.', ['uri-id' => $item['uri-id'], 'network' => $item['network']]);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function validateItemData(array $item): array
|
||||
{
|
||||
$item['wall'] = intval($item['wall'] ?? 0);
|
||||
$item['extid'] = trim($item['extid'] ?? '');
|
||||
$item['author-name'] = trim($item['author-name'] ?? '');
|
||||
$item['author-link'] = trim($item['author-link'] ?? '');
|
||||
$item['author-avatar'] = trim($item['author-avatar'] ?? '');
|
||||
$item['owner-name'] = trim($item['owner-name'] ?? '');
|
||||
$item['owner-link'] = trim($item['owner-link'] ?? '');
|
||||
$item['owner-avatar'] = trim($item['owner-avatar'] ?? '');
|
||||
$item['received'] = (isset($item['received']) ? DateTimeFormat::utc($item['received']) : DateTimeFormat::utcNow());
|
||||
$item['created'] = (isset($item['created']) ? DateTimeFormat::utc($item['created']) : $item['received']);
|
||||
$item['edited'] = (isset($item['edited']) ? DateTimeFormat::utc($item['edited']) : $item['created']);
|
||||
$item['changed'] = (isset($item['changed']) ? DateTimeFormat::utc($item['changed']) : $item['created']);
|
||||
$item['commented'] = (isset($item['commented']) ? DateTimeFormat::utc($item['commented']) : $item['created']);
|
||||
$item['title'] = substr(trim($item['title'] ?? ''), 0, 255);
|
||||
$item['location'] = trim($item['location'] ?? '');
|
||||
$item['coord'] = trim($item['coord'] ?? '');
|
||||
$item['visible'] = (isset($item['visible']) ? intval($item['visible']) : 1);
|
||||
$item['deleted'] = 0;
|
||||
$item['verb'] = trim($item['verb'] ?? '');
|
||||
$item['object-type'] = trim($item['object-type'] ?? '');
|
||||
$item['object'] = trim($item['object'] ?? '');
|
||||
$item['target-type'] = trim($item['target-type'] ?? '');
|
||||
$item['target'] = trim($item['target'] ?? '');
|
||||
$item['plink'] = substr(trim($item['plink'] ?? ''), 0, 255);
|
||||
$item['allow_cid'] = trim($item['allow_cid'] ?? '');
|
||||
$item['allow_gid'] = trim($item['allow_gid'] ?? '');
|
||||
$item['deny_cid'] = trim($item['deny_cid'] ?? '');
|
||||
$item['deny_gid'] = trim($item['deny_gid'] ?? '');
|
||||
$item['private'] = intval($item['private'] ?? Item::PUBLIC);
|
||||
$item['body'] = trim($item['body'] ?? '');
|
||||
$item['raw-body'] = trim($item['raw-body'] ?? $item['body']);
|
||||
$item['app'] = trim($item['app'] ?? '');
|
||||
$item['origin'] = intval($item['origin'] ?? 0);
|
||||
$item['postopts'] = trim($item['postopts'] ?? '');
|
||||
$item['resource-id'] = trim($item['resource-id'] ?? '');
|
||||
$item['event-id'] = intval($item['event-id'] ?? 0);
|
||||
$item['inform'] = trim($item['inform'] ?? '');
|
||||
$item['file'] = trim($item['file'] ?? '');
|
||||
|
||||
// Items cannot be stored before they happen ...
|
||||
if ($item['created'] > DateTimeFormat::utcNow()) {
|
||||
$item['created'] = DateTimeFormat::utcNow();
|
||||
}
|
||||
|
||||
// We haven't invented time travel by now.
|
||||
if ($item['edited'] > DateTimeFormat::utcNow()) {
|
||||
$item['edited'] = DateTimeFormat::utcNow();
|
||||
}
|
||||
|
||||
$item['plink'] = ($item['plink'] ?? '') ?: $this->baseUrl . '/display/' . urlencode($item['guid']);
|
||||
|
||||
$item['gravity'] = $this->getGravity($item);
|
||||
|
||||
if ($item['gravity'] === Item::GRAVITY_UNKNOWN) {
|
||||
$this->logger->info('Unknown gravity for verb', ['verb' => $item['verb']]);
|
||||
}
|
||||
|
||||
$default = [
|
||||
'url' => $item['author-link'], 'name' => $item['author-name'],
|
||||
'photo' => $item['author-avatar'], 'network' => $item['network']
|
||||
];
|
||||
$item['author-id'] = ($item['author-id'] ?? 0) ?: Contact::getIdForURL($item['author-link'], 0, null, $default);
|
||||
|
||||
$default = [
|
||||
'url' => $item['owner-link'], 'name' => $item['owner-name'],
|
||||
'photo' => $item['owner-avatar'], 'network' => $item['network']
|
||||
];
|
||||
$item['owner-id'] = ($item['owner-id'] ?? 0) ?: Contact::getIdForURL($item['owner-link'], 0, null, $default);
|
||||
|
||||
$item['post-reason'] = Item::getPostReason($item);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch top-level parent data for the given item array
|
||||
*
|
||||
* @param array $item
|
||||
* @return array item array with parent data
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getTopLevelParent(array $item): array
|
||||
{
|
||||
$fields = [
|
||||
'uid', 'uri', 'parent-uri', 'id', 'deleted',
|
||||
'uri-id', 'parent-uri-id', 'restrictions', 'verb',
|
||||
'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
|
||||
'wall', 'private', 'origin', 'author-id'
|
||||
];
|
||||
$condition = ['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => $item['uid']];
|
||||
$params = ['order' => ['id' => false]];
|
||||
$parent = Post::selectFirst($fields, $condition, $params);
|
||||
|
||||
if (!$this->database->isResult($parent) && Post::exists(['uri-id' => [$item['thr-parent-id'], $item['parent-uri-id']], 'uid' => 0])) {
|
||||
$stored = Item::storeForUserByUriId($item['thr-parent-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]);
|
||||
if (!$stored && ($item['thr-parent-id'] != $item['parent-uri-id'])) {
|
||||
$stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]);
|
||||
}
|
||||
if ($stored) {
|
||||
$this->logger->info('Stored thread parent item for user', ['uri-id' => $item['thr-parent-id'], 'uid' => $item['uid'], 'stored' => $stored]);
|
||||
$parent = Post::selectFirst($fields, $condition, $params);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->database->isResult($parent)) {
|
||||
$this->logger->notice('item parent was not found - ignoring item', ['uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($this->hasRestrictions($item, $parent['author-id'], $parent['restrictions'])) {
|
||||
$this->logger->notice('Restrictions apply - ignoring item', ['restrictions' => $parent['restrictions'], 'verb' => $parent['verb'], 'uri-id' => $item['uri-id'], 'thr-parent-id' => $item['thr-parent-id'], 'uid' => $item['uid']]);
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($parent['uri-id'] == $parent['parent-uri-id']) {
|
||||
return $parent;
|
||||
}
|
||||
|
||||
$condition = [
|
||||
'uri-id' => $parent['parent-uri-id'],
|
||||
'parent-uri-id' => $parent['parent-uri-id'],
|
||||
'uid' => $parent['uid']
|
||||
];
|
||||
$params = ['order' => ['id' => false]];
|
||||
$toplevel_parent = Post::selectFirst($fields, $condition, $params);
|
||||
|
||||
if (!$this->database->isResult($toplevel_parent) && $item['origin']) {
|
||||
$stored = Item::storeForUserByUriId($item['parent-uri-id'], $item['uid'], ['post-reason' => Item::PR_COMPLETION]);
|
||||
$this->logger->info('Stored parent item for user', ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid'], 'stored' => $stored]);
|
||||
$toplevel_parent = Post::selectFirst($fields, $condition, $params);
|
||||
}
|
||||
|
||||
if (!$this->database->isResult($toplevel_parent)) {
|
||||
$this->logger->notice('item top level parent was not found - ignoring item', ['parent-uri-id' => $parent['parent-uri-id'], 'uid' => $parent['uid']]);
|
||||
return [];
|
||||
}
|
||||
|
||||
return $toplevel_parent;
|
||||
}
|
||||
|
||||
public function handleToplevelParent(array $item, array $toplevel_parent, bool $defined_permissions): array
|
||||
{
|
||||
$parent_id = (int) $toplevel_parent['id'];
|
||||
$item['parent-uri'] = $toplevel_parent['uri'];
|
||||
$item['parent-uri-id'] = $toplevel_parent['uri-id'];
|
||||
$item['deleted'] = $toplevel_parent['deleted'];
|
||||
$item['wall'] = $toplevel_parent['wall'];
|
||||
|
||||
// Reshares have to keep their permissions to allow groups to work
|
||||
if (!$defined_permissions && (!$item['origin'] || ($item['verb'] != Activity::ANNOUNCE))) {
|
||||
// Don't store the permissions on pure AP posts
|
||||
$store_permissions = ($item['network'] != Protocol::ACTIVITYPUB) || $item['origin'] || !empty($item['diaspora_signed_text']);
|
||||
$item['allow_cid'] = $store_permissions ? $toplevel_parent['allow_cid'] : '';
|
||||
$item['allow_gid'] = $store_permissions ? $toplevel_parent['allow_gid'] : '';
|
||||
$item['deny_cid'] = $store_permissions ? $toplevel_parent['deny_cid'] : '';
|
||||
$item['deny_gid'] = $store_permissions ? $toplevel_parent['deny_gid'] : '';
|
||||
}
|
||||
|
||||
// Don't federate received participation messages
|
||||
if ($item['verb'] != Activity::FOLLOW) {
|
||||
$item['wall'] = $toplevel_parent['wall'];
|
||||
} else {
|
||||
$item['wall'] = false;
|
||||
// Participations are technical messages, so they are set to "seen" automatically
|
||||
$item['unseen'] = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the parent is private, force privacy for the entire conversation
|
||||
* This differs from the above settings as it subtly allows comments from
|
||||
* email correspondents to be private even if the overall thread is not.
|
||||
*/
|
||||
if (!$defined_permissions && $toplevel_parent['private']) {
|
||||
$item['private'] = $toplevel_parent['private'];
|
||||
}
|
||||
|
||||
// If its a post that originated here then tag the thread as "mention"
|
||||
if ($item['origin'] && $item['uid']) {
|
||||
$this->database->update('post-thread-user', ['mention' => true], ['uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
|
||||
$this->logger->info('tagged thread as mention', ['parent' => $parent_id, 'parent-uri-id' => $item['parent-uri-id'], 'uid' => $item['uid']]);
|
||||
}
|
||||
|
||||
// Update the contact relations
|
||||
Contact\Relation::store($toplevel_parent['author-id'], $item['author-id'], $item['created']);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
private function hasRestrictions(array $item, int $author_id, int $restrictions = null): bool
|
||||
{
|
||||
if (empty($restrictions) || ($author_id == $item['author-id'])) {
|
||||
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 & Item::CANT_REPLY) && ($item['verb'] == Activity::POST)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($restrictions & Item::CANT_ANNOUNCE) && ($item['verb'] == Activity::ANNOUNCE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($restrictions & Item::CANT_LIKE) && in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE, Activity::ATTEND, Activity::ATTENDMAYBE, Activity::ATTENDNO])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the gravity for the given item array
|
||||
*
|
||||
* @return int gravity
|
||||
*/
|
||||
private function getGravity(array $item): int
|
||||
{
|
||||
if (isset($item['gravity'])) {
|
||||
return intval($item['gravity']);
|
||||
} elseif ($item['parent-uri-id'] === $item['uri-id']) {
|
||||
return Item::GRAVITY_PARENT;
|
||||
} elseif ($this->activity->match($item['verb'], Activity::POST)) {
|
||||
return Item::GRAVITY_COMMENT;
|
||||
} elseif ($this->activity->match($item['verb'], Activity::FOLLOW)) {
|
||||
return Item::GRAVITY_ACTIVITY;
|
||||
} elseif ($this->activity->match($item['verb'], Activity::ANNOUNCE)) {
|
||||
return Item::GRAVITY_ACTIVITY;
|
||||
}
|
||||
|
||||
return Item::GRAVITY_UNKNOWN; // Should not happen
|
||||
}
|
||||
}
|
||||
|
|
@ -807,25 +807,45 @@ class Transmitter
|
|||
}
|
||||
}
|
||||
|
||||
$data = self::filterReceiverData($data, $item['author-link']);
|
||||
|
||||
$receivers = ['to' => array_values($data['to']), 'cc' => array_values($data['cc']), 'bto' => array_values($data['bto']), 'bcc' => array_values($data['bcc']), 'audience' => array_values($data['audience'])];
|
||||
|
||||
if (!$blindcopy) {
|
||||
unset($receivers['bto']);
|
||||
unset($receivers['bcc']);
|
||||
}
|
||||
|
||||
if (!$blindcopy && count($receivers['audience']) == 1) {
|
||||
$receivers['audience'] = $receivers['audience'][0];
|
||||
} elseif (!$receivers['audience']) {
|
||||
unset($receivers['audience']);
|
||||
}
|
||||
|
||||
return $receivers;
|
||||
}
|
||||
|
||||
private static function filterReceiverData(array $data, string $author_link): array
|
||||
{
|
||||
$data['to'] = array_unique($data['to']);
|
||||
$data['cc'] = array_unique($data['cc']);
|
||||
$data['bto'] = array_unique($data['bto']);
|
||||
$data['bcc'] = array_unique($data['bcc']);
|
||||
$data['audience'] = array_unique($data['audience']);
|
||||
|
||||
if (($key = array_search($item['author-link'], $data['to'])) !== false) {
|
||||
if (($key = array_search($author_link, $data['to'])) !== false) {
|
||||
unset($data['to'][$key]);
|
||||
}
|
||||
|
||||
if (($key = array_search($item['author-link'], $data['cc'])) !== false) {
|
||||
if (($key = array_search($author_link, $data['cc'])) !== false) {
|
||||
unset($data['cc'][$key]);
|
||||
}
|
||||
|
||||
if (($key = array_search($item['author-link'], $data['bto'])) !== false) {
|
||||
if (($key = array_search($author_link, $data['bto'])) !== false) {
|
||||
unset($data['bto'][$key]);
|
||||
}
|
||||
|
||||
if (($key = array_search($item['author-link'], $data['bcc'])) !== false) {
|
||||
if (($key = array_search($author_link, $data['bcc'])) !== false) {
|
||||
unset($data['bcc'][$key]);
|
||||
}
|
||||
|
||||
|
|
@ -859,20 +879,7 @@ class Transmitter
|
|||
}
|
||||
}
|
||||
|
||||
$receivers = ['to' => array_values($data['to']), 'cc' => array_values($data['cc']), 'bto' => array_values($data['bto']), 'bcc' => array_values($data['bcc']), 'audience' => array_values($data['audience'])];
|
||||
|
||||
if (!$blindcopy) {
|
||||
unset($receivers['bto']);
|
||||
unset($receivers['bcc']);
|
||||
}
|
||||
|
||||
if (!$blindcopy && count($receivers['audience']) == 1) {
|
||||
$receivers['audience'] = $receivers['audience'][0];
|
||||
} elseif (!$receivers['audience']) {
|
||||
unset($receivers['audience']);
|
||||
}
|
||||
|
||||
return $receivers;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ namespace Friendica\Protocol;
|
|||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use DOMNode;
|
||||
use DOMNodeList;
|
||||
use DOMXPath;
|
||||
use Friendica\App;
|
||||
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship;
|
||||
|
|
@ -67,12 +69,12 @@ class Feed
|
|||
return [];
|
||||
}
|
||||
|
||||
$basepath = '';
|
||||
|
||||
if (!empty($contact['poll'])) {
|
||||
$basepath = $contact['poll'];
|
||||
$basepath = (string) $contact['poll'];
|
||||
} elseif (!empty($contact['url'])) {
|
||||
$basepath = $contact['url'];
|
||||
} else {
|
||||
$basepath = '';
|
||||
$basepath = (string) $contact['url'];
|
||||
}
|
||||
|
||||
$doc = new DOMDocument();
|
||||
|
|
@ -287,6 +289,77 @@ class Feed
|
|||
$total_items = $max_items;
|
||||
}
|
||||
|
||||
$postings = self::importOlderEntries($entries, $total_items, $header, $author, $contact, $importer, $xpath, $atomns, $basepath, $dryRun);
|
||||
|
||||
if (!empty($postings)) {
|
||||
$min_posting = DI::config()->get('system', 'minimum_posting_interval', 0);
|
||||
$total = count($postings);
|
||||
if ($total > 1) {
|
||||
// Posts shouldn't be delayed more than a day
|
||||
$interval = min(1440, self::getPollInterval($contact));
|
||||
$delay = max(round(($interval * 60) / $total), 60 * $min_posting);
|
||||
DI::logger()->info('Got posting delay', ['delay' => $delay, 'interval' => $interval, 'items' => $total, 'cid' => $contact['id'], 'url' => $contact['url']]);
|
||||
} else {
|
||||
$delay = 0;
|
||||
}
|
||||
|
||||
$post_delay = 0;
|
||||
|
||||
foreach ($postings as $posting) {
|
||||
if ($delay > 0) {
|
||||
$publish_time = time() + $post_delay;
|
||||
$post_delay += $delay;
|
||||
} else {
|
||||
$publish_time = time();
|
||||
}
|
||||
|
||||
$last_publish = DI::pConfig()->get($posting['item']['uid'], 'system', 'last_publish', 0, true);
|
||||
$next_publish = max($last_publish + (60 * $min_posting), time());
|
||||
if ($publish_time < $next_publish) {
|
||||
$publish_time = $next_publish;
|
||||
}
|
||||
$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'])) {
|
||||
DI::pConfig()->set($posting['item']['uid'], 'system', 'last_publish', $publish_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$dryRun && DI::config()->get('system', 'adjust_poll_frequency')) {
|
||||
self::adjustPollFrequency($contact, $creation_dates);
|
||||
}
|
||||
|
||||
return ['header' => $author, 'items' => $items];
|
||||
}
|
||||
|
||||
private static function getTitleFromItemOrEntry(array $item, DOMXPath $xpath, string $atomns, ?DOMNode $entry): string
|
||||
{
|
||||
$title = (string) $item['title'];
|
||||
|
||||
if (empty($title)) {
|
||||
$title = XML::getFirstNodeValue($xpath, $atomns . ':title/text()', $entry);
|
||||
}
|
||||
|
||||
if (empty($title)) {
|
||||
$title = XML::getFirstNodeValue($xpath, 'title/text()', $entry);
|
||||
}
|
||||
|
||||
if (empty($title)) {
|
||||
$title = XML::getFirstNodeValue($xpath, 'rss:title/text()', $entry);
|
||||
}
|
||||
|
||||
if (empty($title)) {
|
||||
$title = XML::getFirstNodeValue($xpath, 'itunes:title/text()', $entry);
|
||||
}
|
||||
|
||||
$title = trim(html_entity_decode($title, ENT_QUOTES, 'UTF-8'));
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
private static function importOlderEntries(DOMNodeList $entries, int $total_items, array $header, array $author, array $contact, array $importer, DOMXPath $xpath, string $atomns, string $basepath, bool $dryRun): array
|
||||
{
|
||||
$postings = [];
|
||||
|
||||
// Importing older entries first
|
||||
|
|
@ -386,23 +459,7 @@ class Feed
|
|||
}
|
||||
}
|
||||
|
||||
if (empty($item['title'])) {
|
||||
$item['title'] = XML::getFirstNodeValue($xpath, $atomns . ':title/text()', $entry);
|
||||
}
|
||||
|
||||
if (empty($item['title'])) {
|
||||
$item['title'] = XML::getFirstNodeValue($xpath, 'title/text()', $entry);
|
||||
}
|
||||
|
||||
if (empty($item['title'])) {
|
||||
$item['title'] = XML::getFirstNodeValue($xpath, 'rss:title/text()', $entry);
|
||||
}
|
||||
|
||||
if (empty($item['title'])) {
|
||||
$item['title'] = XML::getFirstNodeValue($xpath, 'itunes:title/text()', $entry);
|
||||
}
|
||||
|
||||
$item['title'] = trim(html_entity_decode($item['title'], ENT_QUOTES, 'UTF-8'));
|
||||
$item['title'] = self::getTitleFromItemOrEntry($item, $xpath, $atomns, $entry);
|
||||
|
||||
$published = XML::getFirstNodeValue($xpath, $atomns . ':published/text()', $entry);
|
||||
|
||||
|
|
@ -705,46 +762,7 @@ class Feed
|
|||
}
|
||||
}
|
||||
|
||||
if (!empty($postings)) {
|
||||
$min_posting = DI::config()->get('system', 'minimum_posting_interval', 0);
|
||||
$total = count($postings);
|
||||
if ($total > 1) {
|
||||
// Posts shouldn't be delayed more than a day
|
||||
$interval = min(1440, self::getPollInterval($contact));
|
||||
$delay = max(round(($interval * 60) / $total), 60 * $min_posting);
|
||||
DI::logger()->info('Got posting delay', ['delay' => $delay, 'interval' => $interval, 'items' => $total, 'cid' => $contact['id'], 'url' => $contact['url']]);
|
||||
} else {
|
||||
$delay = 0;
|
||||
}
|
||||
|
||||
$post_delay = 0;
|
||||
|
||||
foreach ($postings as $posting) {
|
||||
if ($delay > 0) {
|
||||
$publish_time = time() + $post_delay;
|
||||
$post_delay += $delay;
|
||||
} else {
|
||||
$publish_time = time();
|
||||
}
|
||||
|
||||
$last_publish = DI::pConfig()->get($posting['item']['uid'], 'system', 'last_publish', 0, true);
|
||||
$next_publish = max($last_publish + (60 * $min_posting), time());
|
||||
if ($publish_time < $next_publish) {
|
||||
$publish_time = $next_publish;
|
||||
}
|
||||
$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'])) {
|
||||
DI::pConfig()->set($posting['item']['uid'], 'system', 'last_publish', $publish_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$dryRun && DI::config()->get('system', 'adjust_poll_frequency')) {
|
||||
self::adjustPollFrequency($contact, $creation_dates);
|
||||
}
|
||||
|
||||
return ['header' => $author, 'items' => $items];
|
||||
return $postings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 2025.02-dev\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-09 20:13+0000\n"
|
||||
"POT-Creation-Date: 2025-02-11 07:41+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"
|
||||
|
|
@ -45,7 +45,7 @@ msgid "Item not found."
|
|||
msgstr ""
|
||||
|
||||
#: mod/item.php:447 mod/message.php:54 mod/message.php:100 mod/notes.php:34
|
||||
#: mod/photos.php:132 mod/photos.php:624 src/Model/Event.php:506
|
||||
#: mod/photos.php:131 mod/photos.php:623 src/Model/Event.php:506
|
||||
#: src/Module/Attach.php:40 src/Module/BaseApi.php:90
|
||||
#: src/Module/BaseNotifications.php:83 src/Module/BaseSettings.php:38
|
||||
#: src/Module/Calendar/Event/API.php:75 src/Module/Calendar/Event/Form.php:70
|
||||
|
|
@ -289,8 +289,8 @@ msgstr ""
|
|||
msgid "Please wait"
|
||||
msgstr ""
|
||||
|
||||
#: mod/message.php:189 mod/message.php:343 mod/photos.php:655
|
||||
#: mod/photos.php:775 mod/photos.php:1052 mod/photos.php:1093
|
||||
#: mod/message.php:189 mod/message.php:343 mod/photos.php:654
|
||||
#: mod/photos.php:774 mod/photos.php:1051 mod/photos.php:1093
|
||||
#: mod/photos.php:1149 mod/photos.php:1229
|
||||
#: src/Module/Calendar/Event/Form.php:236 src/Module/Contact/Advanced.php:118
|
||||
#: src/Module/Contact/Profile.php:376
|
||||
|
|
@ -377,7 +377,7 @@ msgstr ""
|
|||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:51 mod/photos.php:114 mod/photos.php:534
|
||||
#: mod/photos.php:50 mod/photos.php:113 mod/photos.php:533
|
||||
#: src/Model/Event.php:498 src/Model/Profile.php:211
|
||||
#: src/Module/Calendar/Export.php:60 src/Module/Calendar/Show.php:62
|
||||
#: src/Module/Feed.php:52 src/Module/HCard.php:37
|
||||
|
|
@ -389,100 +389,100 @@ msgstr ""
|
|||
msgid "User not found."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:88 src/Module/BaseProfile.php:53
|
||||
#: mod/photos.php:87 src/Module/BaseProfile.php:53
|
||||
#: src/Module/Profile/Photos.php:372
|
||||
msgid "Photo Albums"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:89 src/Module/Profile/Photos.php:373
|
||||
#: mod/photos.php:88 src/Module/Profile/Photos.php:373
|
||||
#: src/Module/Profile/Photos.php:393
|
||||
msgid "Recent Photos"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:91 mod/photos.php:823 src/Module/Profile/Photos.php:375
|
||||
#: mod/photos.php:90 mod/photos.php:822 src/Module/Profile/Photos.php:375
|
||||
#: src/Module/Profile/Photos.php:395
|
||||
msgid "Upload New Photos"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:103 src/Module/BaseSettings.php:60
|
||||
#: mod/photos.php:102 src/Module/BaseSettings.php:60
|
||||
#: src/Module/Profile/Photos.php:356
|
||||
msgid "everybody"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:139
|
||||
#: mod/photos.php:138
|
||||
msgid "Contact information unavailable"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:168
|
||||
#: mod/photos.php:167
|
||||
msgid "Album not found."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:224
|
||||
#: mod/photos.php:223
|
||||
msgid "Album successfully deleted"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:226
|
||||
#: mod/photos.php:225
|
||||
msgid "Album was empty."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:257
|
||||
#: mod/photos.php:256
|
||||
msgid "Failed to delete the photo."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:501
|
||||
#: mod/photos.php:500
|
||||
msgid "a photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:501
|
||||
#: mod/photos.php:500
|
||||
#, php-format
|
||||
msgid "%1$s was tagged in %2$s by %3$s"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:538 src/Module/Conversation/Community.php:148
|
||||
#: mod/photos.php:537 src/Module/Conversation/Community.php:148
|
||||
#: src/Module/Directory.php:34 src/Module/Profile/Photos.php:290
|
||||
#: src/Module/Search/Index.php:50
|
||||
msgid "Public access denied."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:543
|
||||
#: mod/photos.php:542
|
||||
msgid "No photos selected"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:671
|
||||
#: mod/photos.php:670
|
||||
#, php-format
|
||||
msgid "The maximum accepted image size is %s"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:678
|
||||
#: mod/photos.php:677
|
||||
msgid "Upload Photos"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:682 mod/photos.php:771
|
||||
#: mod/photos.php:681 mod/photos.php:770
|
||||
msgid "New album name: "
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:683
|
||||
#: mod/photos.php:682
|
||||
msgid "or select existing album:"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:684
|
||||
#: mod/photos.php:683
|
||||
msgid "Do not show a status post for this upload"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:687 mod/photos.php:1048 src/Content/Conversation.php:391
|
||||
#: mod/photos.php:686 mod/photos.php:1047 src/Content/Conversation.php:391
|
||||
#: src/Module/Calendar/Event/Form.php:239 src/Module/Post/Edit.php:174
|
||||
msgid "Permissions"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:752
|
||||
#: mod/photos.php:751
|
||||
msgid "Do you really want to delete this photo album and all its photos?"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:753 mod/photos.php:776
|
||||
#: mod/photos.php:752 mod/photos.php:775
|
||||
msgid "Delete Album"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:754 mod/photos.php:854 src/Content/Conversation.php:406
|
||||
#: mod/photos.php:753 mod/photos.php:853 src/Content/Conversation.php:406
|
||||
#: src/Module/Contact/Follow.php:158 src/Module/Contact/Revoke.php:92
|
||||
#: src/Module/Contact/Unfollow.php:112
|
||||
#: src/Module/Media/Attachment/Browser.php:64
|
||||
|
|
@ -492,99 +492,99 @@ msgstr ""
|
|||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:780
|
||||
#: mod/photos.php:779
|
||||
msgid "Edit Album"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:781
|
||||
#: mod/photos.php:780
|
||||
msgid "Drop Album"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:785
|
||||
#: mod/photos.php:784
|
||||
msgid "Show Newest First"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:787
|
||||
#: mod/photos.php:786
|
||||
msgid "Show Oldest First"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:808 src/Module/Profile/Photos.php:343
|
||||
#: mod/photos.php:807 src/Module/Profile/Photos.php:343
|
||||
msgid "View Photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:840
|
||||
#: mod/photos.php:839
|
||||
msgid "Permission denied. Access to this item may be restricted."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:842
|
||||
#: mod/photos.php:841
|
||||
msgid "Photo not available"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:852
|
||||
#: mod/photos.php:851
|
||||
msgid "Do you really want to delete this photo?"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:853 mod/photos.php:1053
|
||||
#: mod/photos.php:852 mod/photos.php:1052
|
||||
msgid "Delete Photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:951
|
||||
#: mod/photos.php:950
|
||||
msgid "View photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:953
|
||||
#: mod/photos.php:952
|
||||
msgid "Edit photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:954
|
||||
#: mod/photos.php:953
|
||||
msgid "Delete photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:955
|
||||
#: mod/photos.php:954
|
||||
msgid "Use as profile photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:962
|
||||
#: mod/photos.php:961
|
||||
msgid "Private Photo"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:968
|
||||
#: mod/photos.php:967
|
||||
msgid "View Full Size"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1021
|
||||
#: mod/photos.php:1020
|
||||
msgid "Tags: "
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1024
|
||||
#: mod/photos.php:1023
|
||||
msgid "[Select tags to remove]"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1039
|
||||
#: mod/photos.php:1038
|
||||
msgid "New album name"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1040
|
||||
#: mod/photos.php:1039
|
||||
msgid "Caption"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1041
|
||||
#: mod/photos.php:1040
|
||||
msgid "Add a Tag"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1041
|
||||
#: mod/photos.php:1040
|
||||
msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1042
|
||||
#: mod/photos.php:1041
|
||||
msgid "Do not rotate"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1043
|
||||
#: mod/photos.php:1042
|
||||
msgid "Rotate CW (right)"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1044
|
||||
#: mod/photos.php:1043
|
||||
msgid "Rotate CCW (left)"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -646,7 +646,7 @@ msgstr ""
|
|||
msgid "Map"
|
||||
msgstr ""
|
||||
|
||||
#: src/App.php:442
|
||||
#: src/App.php:451
|
||||
msgid "Apologies but the website is unavailable at the moment."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -752,17 +752,17 @@ msgstr ""
|
|||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: src/App/Router.php:286
|
||||
#: src/App/Router.php:287
|
||||
#, php-format
|
||||
msgid "Method not allowed for this module. Allowed method(s): %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/App/Router.php:288 src/Module/HTTPException/PageNotFound.php:35
|
||||
#: src/App/Router.php:289 src/Module/HTTPException/PageNotFound.php:35
|
||||
#: src/Module/Stats.php:56
|
||||
msgid "Page not found."
|
||||
msgstr ""
|
||||
|
||||
#: src/App/Router.php:300
|
||||
#: src/App/Router.php:301
|
||||
msgid "You must be logged in to use addons. "
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -779,19 +779,19 @@ msgid "All contacts"
|
|||
msgstr ""
|
||||
|
||||
#: src/BaseModule.php:440 src/Content/Conversation/Factory/Channel.php:32
|
||||
#: src/Content/Widget.php:254 src/Core/ACL.php:182 src/Module/Contact.php:394
|
||||
#: src/Content/Widget.php:257 src/Core/ACL.php:182 src/Module/Contact.php:394
|
||||
#: src/Module/Privacy/PermissionTooltip.php:150
|
||||
#: src/Module/Privacy/PermissionTooltip.php:172
|
||||
#: src/Module/Settings/Channels.php:146
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#: src/BaseModule.php:445 src/Content/Widget.php:255 src/Module/Contact.php:397
|
||||
#: src/BaseModule.php:445 src/Content/Widget.php:258 src/Module/Contact.php:397
|
||||
#: src/Module/Settings/Channels.php:145
|
||||
msgid "Following"
|
||||
msgstr ""
|
||||
|
||||
#: src/BaseModule.php:450 src/Content/Widget.php:256 src/Module/Contact.php:400
|
||||
#: src/BaseModule.php:450 src/Content/Widget.php:259 src/Module/Contact.php:400
|
||||
msgid "Mutual friends"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -799,15 +799,15 @@ msgstr ""
|
|||
msgid "Common"
|
||||
msgstr ""
|
||||
|
||||
#: src/Console/Addon.php:163 src/Console/Addon.php:187
|
||||
#: src/Console/Addon.php:164 src/Console/Addon.php:188
|
||||
msgid "Addon not found"
|
||||
msgstr ""
|
||||
|
||||
#: src/Console/Addon.php:167
|
||||
#: src/Console/Addon.php:168
|
||||
msgid "Addon already enabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/Console/Addon.php:191
|
||||
#: src/Console/Addon.php:192
|
||||
msgid "Addon already disabled"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1701,7 +1701,7 @@ msgstr ""
|
|||
msgid "Network Widgets"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Feature.php:126 src/Content/Widget.php:230
|
||||
#: src/Content/Feature.php:126 src/Content/Widget.php:233
|
||||
#: src/Model/Circle.php:587 src/Module/Contact.php:380
|
||||
#: src/Module/Welcome.php:62
|
||||
msgid "Circles"
|
||||
|
|
@ -1713,7 +1713,7 @@ msgstr ""
|
|||
|
||||
#: src/Content/Feature.php:127 src/Content/GroupManager.php:128
|
||||
#: src/Content/Nav.php:274 src/Content/Text/HTML.php:868
|
||||
#: src/Content/Widget.php:555 src/Model/User.php:1393
|
||||
#: src/Content/Widget.php:558 src/Model/User.php:1393
|
||||
msgid "Groups"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1721,7 +1721,7 @@ msgstr ""
|
|||
msgid "Display posts that have been distributed by the selected group."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Feature.php:128 src/Content/Widget.php:524
|
||||
#: src/Content/Feature.php:128 src/Content/Widget.php:527
|
||||
msgid "Archives"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1729,7 +1729,7 @@ msgstr ""
|
|||
msgid "Display an archive where posts can be selected by month and year."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Feature.php:129 src/Content/Widget.php:303
|
||||
#: src/Content/Feature.php:129 src/Content/Widget.php:306
|
||||
msgid "Protocols"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1737,7 +1737,7 @@ msgstr ""
|
|||
msgid "Display posts with the selected protocols."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Feature.php:130 src/Content/Widget.php:561
|
||||
#: src/Content/Feature.php:130 src/Content/Widget.php:564
|
||||
#: src/Module/Settings/Account.php:391
|
||||
msgid "Account Types"
|
||||
msgstr ""
|
||||
|
|
@ -1746,7 +1746,7 @@ msgstr ""
|
|||
msgid "Display posts done by accounts with the selected account type."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Feature.php:131 src/Content/Widget.php:610
|
||||
#: src/Content/Feature.php:131 src/Content/Widget.php:613
|
||||
#: src/Module/Admin/Site.php:463 src/Module/BaseSettings.php:113
|
||||
#: src/Module/Settings/Channels.php:211 src/Module/Settings/Display.php:313
|
||||
msgid "Channels"
|
||||
|
|
@ -1764,7 +1764,7 @@ msgstr ""
|
|||
msgid "Display posts that contain subscribed hashtags."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Feature.php:133 src/Content/Widget.php:333
|
||||
#: src/Content/Feature.php:133 src/Content/Widget.php:336
|
||||
msgid "Saved Folders"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1824,12 +1824,12 @@ msgstr ""
|
|||
msgid "External link to group"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/GroupManager.php:134 src/Content/Widget.php:530
|
||||
#: src/Content/GroupManager.php:134 src/Content/Widget.php:533
|
||||
msgid "show less"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/GroupManager.php:135 src/Content/Widget.php:425
|
||||
#: src/Content/Widget.php:531
|
||||
#: src/Content/GroupManager.php:135 src/Content/Widget.php:428
|
||||
#: src/Content/Widget.php:534
|
||||
msgid "show more"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1837,7 +1837,7 @@ msgstr ""
|
|||
msgid "Create new group"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:321 src/Model/Item.php:3296
|
||||
#: src/Content/Item.php:321 src/Model/Item.php:2980
|
||||
msgid "event"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1845,7 +1845,7 @@ msgstr ""
|
|||
msgid "status"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:330 src/Model/Item.php:3298
|
||||
#: src/Content/Item.php:330 src/Model/Item.php:2982
|
||||
#: src/Module/Post/Tag/Add.php:109
|
||||
msgid "photo"
|
||||
msgstr ""
|
||||
|
|
@ -1922,7 +1922,7 @@ msgstr ""
|
|||
msgid "Search Text"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:440 src/Content/Widget.php:66
|
||||
#: src/Content/Item.php:440 src/Content/Widget.php:65
|
||||
#: src/Model/Contact.php:1247 src/Model/Contact.php:1259
|
||||
#: src/Module/Contact/Follow.php:152 view/theme/vier/theme.php:183
|
||||
msgid "Connect/Follow"
|
||||
|
|
@ -2102,7 +2102,7 @@ msgstr ""
|
|||
msgid "People directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Nav.php:294 src/Module/BaseAdmin.php:71
|
||||
#: src/Content/Nav.php:294 src/Module/BaseAdmin.php:70
|
||||
#: src/Module/BaseModeration.php:97
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
|
|
@ -2112,7 +2112,7 @@ msgid "Information about this friendica instance"
|
|||
msgstr ""
|
||||
|
||||
#: src/Content/Nav.php:297 src/Module/Admin/Tos.php:64
|
||||
#: src/Module/BaseAdmin.php:81 src/Module/Register.php:169
|
||||
#: src/Module/BaseAdmin.php:80 src/Module/Register.php:169
|
||||
#: src/Module/Tos.php:87
|
||||
msgid "Terms of Service"
|
||||
msgstr ""
|
||||
|
|
@ -2178,7 +2178,7 @@ msgstr ""
|
|||
msgid "Manage other pages"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Nav.php:323 src/Module/Admin/Addons/Details.php:98
|
||||
#: src/Content/Nav.php:323 src/Module/Admin/Addons/Details.php:101
|
||||
#: src/Module/Admin/Themes/Details.php:85 src/Module/BaseSettings.php:177
|
||||
#: src/Module/Welcome.php:38 view/theme/frio/theme.php:231
|
||||
msgid "Settings"
|
||||
|
|
@ -2192,7 +2192,7 @@ msgstr ""
|
|||
msgid "Manage/edit friends and contacts"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Nav.php:330 src/Module/BaseAdmin.php:105
|
||||
#: src/Content/Nav.php:330 src/Module/BaseAdmin.php:114
|
||||
msgid "Admin"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2247,8 +2247,8 @@ msgstr ""
|
|||
msgid "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Text/BBCode.php:926 src/Model/Item.php:4103
|
||||
#: src/Model/Item.php:4109 src/Model/Item.php:4110
|
||||
#: src/Content/Text/BBCode.php:926 src/Model/Item.php:3787
|
||||
#: src/Model/Item.php:3793 src/Model/Item.php:3794
|
||||
msgid "Link to source"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2285,129 +2285,129 @@ msgstr ""
|
|||
msgid "Follow"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:37
|
||||
#: src/Content/Widget.php:36
|
||||
msgid "Add New Contact"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:38
|
||||
#: src/Content/Widget.php:37
|
||||
msgid "Enter address or web location"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:39
|
||||
#: src/Content/Widget.php:38
|
||||
msgid "Example: bob@example.com, http://example.com/barbara"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:41
|
||||
#: src/Content/Widget.php:40
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:58
|
||||
#: src/Content/Widget.php:57
|
||||
#, php-format
|
||||
msgid "%d invitation available"
|
||||
msgid_plural "%d invitations available"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Content/Widget.php:64 view/theme/vier/theme.php:181
|
||||
#: src/Content/Widget.php:63 view/theme/vier/theme.php:181
|
||||
msgid "Find People"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:65 view/theme/vier/theme.php:182
|
||||
#: src/Content/Widget.php:64 view/theme/vier/theme.php:182
|
||||
msgid "Enter name or interest"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:67 view/theme/vier/theme.php:184
|
||||
#: src/Content/Widget.php:66 view/theme/vier/theme.php:184
|
||||
msgid "Examples: Robert Morgenstein, Fishing"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:68 src/Module/Contact.php:440
|
||||
#: src/Content/Widget.php:67 src/Module/Contact.php:440
|
||||
#: src/Module/Directory.php:82 view/theme/vier/theme.php:185
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:69 src/Module/Contact/Suggestions.php:59
|
||||
#: src/Content/Widget.php:68 src/Module/Contact/Suggestions.php:59
|
||||
#: view/theme/vier/theme.php:186
|
||||
msgid "Friend Suggestions"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:70 view/theme/vier/theme.php:187
|
||||
#: src/Content/Widget.php:69 view/theme/vier/theme.php:187
|
||||
msgid "Similar Interests"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:71 view/theme/vier/theme.php:188
|
||||
#: src/Content/Widget.php:70 view/theme/vier/theme.php:188
|
||||
msgid "Random Profile"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:72 view/theme/vier/theme.php:189
|
||||
#: src/Content/Widget.php:71 view/theme/vier/theme.php:189
|
||||
msgid "Invite Friends"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:73 src/Module/Directory.php:74
|
||||
#: src/Content/Widget.php:72 src/Module/Directory.php:74
|
||||
#: view/theme/vier/theme.php:190
|
||||
msgid "Global Directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:75 view/theme/vier/theme.php:192
|
||||
#: src/Content/Widget.php:74 view/theme/vier/theme.php:192
|
||||
msgid "Local Directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:232
|
||||
#: src/Content/Widget.php:235
|
||||
msgid "Everyone"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:257 src/Module/Contact.php:403
|
||||
#: src/Content/Widget.php:260 src/Module/Contact.php:403
|
||||
msgid "No relationship"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:262
|
||||
#: src/Content/Widget.php:265
|
||||
msgid "Relationships"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:264 src/Module/Circle.php:281
|
||||
#: src/Content/Widget.php:267 src/Module/Circle.php:281
|
||||
#: src/Module/Contact.php:324
|
||||
msgid "All Contacts"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:305
|
||||
#: src/Content/Widget.php:308
|
||||
msgid "All Protocols"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:335 src/Content/Widget.php:366
|
||||
#: src/Content/Widget.php:338 src/Content/Widget.php:369
|
||||
msgid "Everything"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:364
|
||||
#: src/Content/Widget.php:367
|
||||
msgid "Categories"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:421
|
||||
#: src/Content/Widget.php:424
|
||||
#, php-format
|
||||
msgid "%d contact in common"
|
||||
msgid_plural "%d contacts in common"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Content/Widget.php:532
|
||||
#: src/Content/Widget.php:535
|
||||
msgid "On this date"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:552
|
||||
#: src/Content/Widget.php:555
|
||||
msgid "Persons"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:553
|
||||
#: src/Content/Widget.php:556
|
||||
msgid "Organisations"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:554 src/Model/Contact.php:1757
|
||||
#: src/Content/Widget.php:557 src/Model/Contact.php:1757
|
||||
msgid "News"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:556
|
||||
#: src/Content/Widget.php:559
|
||||
msgid "Relays"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:563 src/Module/Moderation/BaseUsers.php:58
|
||||
#: src/Content/Widget.php:566 src/Module/Moderation/BaseUsers.php:58
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2836,7 +2836,7 @@ msgstr ""
|
|||
msgid "Could not connect to database."
|
||||
msgstr ""
|
||||
|
||||
#: src/Core/L10n.php:426 src/Model/Item.php:2339
|
||||
#: src/Core/L10n.php:426 src/Model/Item.php:2023
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -3224,7 +3224,7 @@ msgstr ""
|
|||
msgid "Disallowed profile URL."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3096 src/Module/Friendica.php:88
|
||||
#: src/Model/Contact.php:3096 src/Module/Friendica.php:90
|
||||
msgid "Blocked domain"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -3378,92 +3378,92 @@ msgstr ""
|
|||
msgid "Happy Birthday %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:2346
|
||||
#: src/Model/Item.php:2030
|
||||
#, php-format
|
||||
msgid "%s (%s - %s): %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:2348
|
||||
#: src/Model/Item.php:2032
|
||||
#, php-format
|
||||
msgid "%s (%s): %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:2351
|
||||
#: src/Model/Item.php:2035
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Detected languages in this post:\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3300
|
||||
#: src/Model/Item.php:2984
|
||||
msgid "activity"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3302
|
||||
#: src/Model/Item.php:2986
|
||||
msgid "comment"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3305 src/Module/Post/Tag/Add.php:109
|
||||
#: src/Model/Item.php:2989 src/Module/Post/Tag/Add.php:109
|
||||
msgid "post"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3478
|
||||
#: src/Model/Item.php:3162
|
||||
#, php-format
|
||||
msgid "%s is blocked"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3480
|
||||
#: src/Model/Item.php:3164
|
||||
#, php-format
|
||||
msgid "%s is ignored"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3482
|
||||
#: src/Model/Item.php:3166
|
||||
#, php-format
|
||||
msgid "Content from %s is collapsed"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3486
|
||||
#: src/Model/Item.php:3170
|
||||
msgid "Sensitive content"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:4003
|
||||
#: src/Model/Item.php:3687
|
||||
msgid "bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:4034
|
||||
#: src/Model/Item.php:3718
|
||||
#, php-format
|
||||
msgid "%2$s (%3$d%%, %1$d vote)"
|
||||
msgid_plural "%2$s (%3$d%%, %1$d votes)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:4036
|
||||
#: src/Model/Item.php:3720
|
||||
#, php-format
|
||||
msgid "%2$s (%1$d vote)"
|
||||
msgid_plural "%2$s (%1$d votes)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:4041
|
||||
#: src/Model/Item.php:3725
|
||||
#, php-format
|
||||
msgid "%d voter. Poll end: %s"
|
||||
msgid_plural "%d voters. Poll end: %s"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:4043
|
||||
#: src/Model/Item.php:3727
|
||||
#, php-format
|
||||
msgid "%d voter."
|
||||
msgid_plural "%d voters."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:4045
|
||||
#: src/Model/Item.php:3729
|
||||
#, php-format
|
||||
msgid "Poll end: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:4086 src/Model/Item.php:4087
|
||||
#: src/Model/Item.php:3770 src/Model/Item.php:3771
|
||||
msgid "View on separate page"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -3574,7 +3574,7 @@ msgstr ""
|
|||
msgid "Title/Description:"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Profile.php:793 src/Module/Admin/Summary.php:174
|
||||
#: src/Model/Profile.php:793 src/Module/Admin/Summary.php:184
|
||||
#: src/Module/Moderation/Report/Create.php:266
|
||||
#: src/Module/Moderation/Summary.php:65
|
||||
msgid "Summary"
|
||||
|
|
@ -3860,71 +3860,71 @@ msgstr ""
|
|||
msgid "User with delegates can't be removed, please remove delegate users first"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:49
|
||||
#: src/Module/Admin/Addons/Details.php:48
|
||||
msgid "Addon not found."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:60 src/Module/Admin/Addons/Index.php:41
|
||||
#: src/Module/Admin/Addons/Details.php:59 src/Module/Admin/Addons/Index.php:43
|
||||
#, php-format
|
||||
msgid "Addon %s disabled."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:63 src/Module/Admin/Addons/Index.php:43
|
||||
#: src/Module/Admin/Addons/Details.php:62 src/Module/Admin/Addons/Index.php:45
|
||||
#, php-format
|
||||
msgid "Addon %s enabled."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:72
|
||||
#: src/Module/Admin/Addons/Details.php:71
|
||||
#: src/Module/Admin/Themes/Details.php:38
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:75
|
||||
#: src/Module/Admin/Addons/Details.php:74
|
||||
#: src/Module/Admin/Themes/Details.php:41 src/Module/Settings/Display.php:341
|
||||
msgid "Enable"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:95 src/Module/Admin/Addons/Index.php:59
|
||||
#: src/Module/Admin/Addons/Details.php:98 src/Module/Admin/Addons/Index.php:77
|
||||
#: src/Module/Admin/Federation.php:213 src/Module/Admin/Logs/Settings.php:74
|
||||
#: src/Module/Admin/Logs/View.php:71 src/Module/Admin/Queue.php:59
|
||||
#: src/Module/Admin/Site.php:446 src/Module/Admin/Storage.php:124
|
||||
#: src/Module/Admin/Summary.php:173 src/Module/Admin/Themes/Details.php:82
|
||||
#: src/Module/Admin/Summary.php:183 src/Module/Admin/Themes/Details.php:82
|
||||
#: src/Module/Admin/Themes/Index.php:103 src/Module/Admin/Tos.php:63
|
||||
#: src/Module/Moderation/Users/Create.php:47
|
||||
#: src/Module/Moderation/Users/Pending.php:82
|
||||
msgid "Administration"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:96 src/Module/Admin/Addons/Index.php:60
|
||||
#: src/Module/BaseAdmin.php:78 src/Module/BaseSettings.php:127
|
||||
#: src/Module/Admin/Addons/Details.php:99 src/Module/Admin/Addons/Index.php:78
|
||||
#: src/Module/BaseAdmin.php:77 src/Module/BaseSettings.php:127
|
||||
msgid "Addons"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:97
|
||||
#: src/Module/Admin/Addons/Details.php:100
|
||||
#: src/Module/Admin/Themes/Details.php:84
|
||||
msgid "Toggle"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:104
|
||||
#: src/Module/Admin/Addons/Details.php:113
|
||||
#: src/Module/Admin/Themes/Details.php:92
|
||||
msgid "Author: "
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Details.php:105
|
||||
#: src/Module/Admin/Addons/Details.php:114
|
||||
#: src/Module/Admin/Themes/Details.php:93
|
||||
msgid "Maintainer: "
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Index.php:34
|
||||
#: src/Module/Admin/Addons/Index.php:35
|
||||
msgid "Addons reloaded"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Index.php:45
|
||||
#: src/Module/Admin/Addons/Index.php:47
|
||||
#, php-format
|
||||
msgid "Addon %s failed to install."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Index.php:61 src/Module/Admin/Features.php:69
|
||||
#: src/Module/Admin/Addons/Index.php:79 src/Module/Admin/Features.php:69
|
||||
#: src/Module/Admin/Logs/Settings.php:76 src/Module/Admin/Site.php:449
|
||||
#: src/Module/Admin/Themes/Index.php:105 src/Module/Admin/Tos.php:72
|
||||
#: src/Module/Settings/Account.php:507 src/Module/Settings/Addons.php:64
|
||||
|
|
@ -3936,11 +3936,11 @@ msgstr ""
|
|||
msgid "Save Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Index.php:62
|
||||
#: src/Module/Admin/Addons/Index.php:80
|
||||
msgid "Reload active addons"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Addons/Index.php:66
|
||||
#: src/Module/Admin/Addons/Index.php:84
|
||||
#, php-format
|
||||
msgid "There are currently no addons available on your node. You can find the official addon repository at %1$s."
|
||||
msgstr ""
|
||||
|
|
@ -4088,7 +4088,7 @@ msgstr[1] ""
|
|||
msgid "This page offers you some numbers to the known part of the federated social network your Friendica node is part of. These numbers are not complete but only reflect the part of the network your node is aware of."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Federation.php:214 src/Module/BaseAdmin.php:73
|
||||
#: src/Module/Admin/Federation.php:214 src/Module/BaseAdmin.php:72
|
||||
msgid "Federation Statistics"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4112,8 +4112,8 @@ msgstr ""
|
|||
msgid "PHP log currently disabled."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Logs/Settings.php:75 src/Module/BaseAdmin.php:88
|
||||
#: src/Module/BaseAdmin.php:89
|
||||
#: src/Module/Admin/Logs/Settings.php:75 src/Module/BaseAdmin.php:87
|
||||
#: src/Module/BaseAdmin.php:88
|
||||
msgid "Logs"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4161,7 +4161,7 @@ msgstr ""
|
|||
msgid "Couldn't open <strong>%1$s</strong> log file.<br/>Check to see if file %1$s is readable."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Logs/View.php:72 src/Module/BaseAdmin.php:90
|
||||
#: src/Module/Admin/Logs/View.php:72 src/Module/BaseAdmin.php:89
|
||||
msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4351,7 +4351,7 @@ msgstr ""
|
|||
msgid "Interactors"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Site.php:447 src/Module/BaseAdmin.php:76
|
||||
#: src/Module/Admin/Site.php:447 src/Module/BaseAdmin.php:75
|
||||
msgid "Site"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -5324,7 +5324,7 @@ msgstr ""
|
|||
msgid "Storage Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Storage.php:127 src/Module/BaseAdmin.php:77
|
||||
#: src/Module/Admin/Storage.php:127 src/Module/BaseAdmin.php:76
|
||||
msgid "Storage"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -5408,39 +5408,39 @@ msgstr ""
|
|||
msgid "Friendica's configuration now is stored in config/local.config.php, please copy config/local-sample.config.php and move your config from <code>config/local.ini.php</code>. See <a href=\"%s\">the Config help page</a> for help with the transition."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:104
|
||||
#: src/Module/Admin/Summary.php:105
|
||||
#, php-format
|
||||
msgid "<a href=\"%s\">%s</a> is not reachable on your system. This is a severe configuration issue that prevents server to server communication. See <a href=\"%s\">the installation page</a> for help."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:128
|
||||
#: src/Module/Admin/Summary.php:133
|
||||
#, php-format
|
||||
msgid "Friendica's system.basepath was updated from '%s' to '%s'. Please remove the system.basepath from your db to avoid differences."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:136
|
||||
#: src/Module/Admin/Summary.php:143
|
||||
#, php-format
|
||||
msgid "Friendica's current system.basepath '%s' is wrong and the config file '%s' isn't used."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:144
|
||||
#: src/Module/Admin/Summary.php:153
|
||||
#, php-format
|
||||
msgid "Friendica's current system.basepath '%s' is not equal to the config file '%s'. Please fix your configuration."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:155
|
||||
#: src/Module/Admin/Summary.php:165
|
||||
msgid "Message queues"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:158
|
||||
#: src/Module/Admin/Summary.php:168
|
||||
msgid "Server Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:176
|
||||
#: src/Module/Admin/Summary.php:186
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Summary.php:180
|
||||
#: src/Module/Admin/Summary.php:190
|
||||
msgid "Active addons"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -5464,7 +5464,7 @@ msgid "Screenshot"
|
|||
msgstr ""
|
||||
|
||||
#: src/Module/Admin/Themes/Details.php:83 src/Module/Admin/Themes/Index.php:104
|
||||
#: src/Module/BaseAdmin.php:79
|
||||
#: src/Module/BaseAdmin.php:78
|
||||
msgid "Themes"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -5581,76 +5581,76 @@ msgstr ""
|
|||
msgid "Item was not found."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:40 src/Module/BaseAdmin.php:44
|
||||
#: src/Module/BaseAdmin.php:39 src/Module/BaseAdmin.php:43
|
||||
#: src/Module/BaseModeration.php:66 src/Module/BaseModeration.php:70
|
||||
msgid "Please login to continue."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:49
|
||||
#: src/Module/BaseAdmin.php:48
|
||||
msgid "You don't have access to administration pages."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:53
|
||||
#: src/Module/BaseAdmin.php:52
|
||||
msgid "Submanaged account can't access the administration pages. Please log back in as the main account."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:72 src/Module/BaseModeration.php:98
|
||||
#: src/Module/BaseAdmin.php:71 src/Module/BaseModeration.php:98
|
||||
msgid "Overview"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:75 src/Module/BaseModeration.php:101
|
||||
#: src/Module/BaseAdmin.php:74 src/Module/BaseModeration.php:101
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:80 src/Module/BaseSettings.php:98
|
||||
#: src/Module/BaseAdmin.php:79 src/Module/BaseSettings.php:98
|
||||
msgid "Additional features"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:83
|
||||
#: src/Module/BaseAdmin.php:82
|
||||
msgid "Database"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:84
|
||||
#: src/Module/BaseAdmin.php:83
|
||||
msgid "DB updates"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:85
|
||||
#: src/Module/BaseAdmin.php:84
|
||||
msgid "Inspect Deferred Workers"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:86
|
||||
#: src/Module/BaseAdmin.php:85
|
||||
msgid "Inspect worker Queue"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:92 src/Module/BaseModeration.php:109
|
||||
#: src/Module/BaseAdmin.php:91 src/Module/BaseModeration.php:109
|
||||
msgid "Diagnostics"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:93
|
||||
#: src/Module/BaseAdmin.php:92
|
||||
msgid "PHP Info"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:94
|
||||
#: src/Module/BaseAdmin.php:93
|
||||
msgid "probe address"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:95
|
||||
#: src/Module/BaseAdmin.php:94
|
||||
msgid "check webfinger"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:96
|
||||
#: src/Module/BaseAdmin.php:95
|
||||
msgid "Babel"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:97 src/Module/Debug/ActivityPubConversion.php:125
|
||||
#: src/Module/BaseAdmin.php:96 src/Module/Debug/ActivityPubConversion.php:125
|
||||
msgid "ActivityPub Conversion"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:106
|
||||
#: src/Module/BaseAdmin.php:115
|
||||
msgid "Addon Features"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/BaseAdmin.php:107 src/Module/BaseModeration.php:118
|
||||
#: src/Module/BaseAdmin.php:116 src/Module/BaseModeration.php:118
|
||||
msgid "User registrations waiting for confirmation"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -7049,52 +7049,52 @@ msgstr ""
|
|||
msgid "Suggest a friend for %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:69
|
||||
#: src/Module/Friendica.php:71
|
||||
msgid "Installed addons/apps:"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:74
|
||||
#: src/Module/Friendica.php:76
|
||||
msgid "No installed addons/apps"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:79
|
||||
#: src/Module/Friendica.php:81
|
||||
#, php-format
|
||||
msgid "Read about the <a href=\"%1$s/tos\">Terms of Service</a> of this node."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:86
|
||||
#: src/Module/Friendica.php:88
|
||||
msgid "On this server the following remote servers are blocked."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:89
|
||||
#: src/Module/Friendica.php:91
|
||||
#: src/Module/Moderation/Blocklist/Server/Index.php:76
|
||||
#: src/Module/Moderation/Blocklist/Server/Index.php:100
|
||||
#: src/Module/Settings/Channels.php:218
|
||||
msgid "Reason for the block"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:91
|
||||
#: src/Module/Friendica.php:93
|
||||
msgid "Download this list in CSV format"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:105
|
||||
#: src/Module/Friendica.php:108
|
||||
#, php-format
|
||||
msgid "This is Friendica, version %s that is running at the web location %s. The database version is %s, the post update version is %s."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:110
|
||||
#: src/Module/Friendica.php:114
|
||||
msgid "Please visit <a href=\"https://friendi.ca\">Friendi.ca</a> to learn more about the Friendica project."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:111
|
||||
#: src/Module/Friendica.php:115
|
||||
msgid "Bug reports and issues: please visit"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:111
|
||||
#: src/Module/Friendica.php:115
|
||||
msgid "the bugtracker at github"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Friendica.php:112
|
||||
#: src/Module/Friendica.php:116
|
||||
msgid "Suggestions, praise, etc. - please email \"info\" at \"friendi - dot - ca"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -8571,19 +8571,19 @@ msgid "No contacts."
|
|||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Conversations.php:96 src/Module/Profile/Profile.php:342
|
||||
#: src/Protocol/Feed.php:1096
|
||||
#: src/Protocol/Feed.php:1114
|
||||
#, php-format
|
||||
msgid "%s's posts"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Conversations.php:97 src/Module/Profile/Profile.php:343
|
||||
#: src/Protocol/Feed.php:1099
|
||||
#: src/Protocol/Feed.php:1117
|
||||
#, php-format
|
||||
msgid "%s's comments"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Conversations.php:98 src/Module/Profile/Profile.php:344
|
||||
#: src/Protocol/Feed.php:1092
|
||||
#: src/Protocol/Feed.php:1110
|
||||
#, php-format
|
||||
msgid "%s's timeline"
|
||||
msgstr ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue