Merge remote-tracking branch 'origin/develop' into develop.randompenguin1
This commit is contained in:
commit
7ca99aa194
204 changed files with 5699 additions and 2767 deletions
32
.github/workflows/code-quality.yml
vendored
32
.github/workflows/code-quality.yml
vendored
|
@ -76,6 +76,38 @@ jobs:
|
||||||
- name: Run PHPStan
|
- name: Run PHPStan
|
||||||
run: composer run phpstan
|
run: composer run phpstan
|
||||||
|
|
||||||
|
phpstan-addons:
|
||||||
|
name: PHPStan in addons (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: xdebug
|
||||||
|
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 PHPStan in addons
|
||||||
|
run: composer run phpstan-addons
|
||||||
|
|
||||||
phpmd:
|
phpmd:
|
||||||
name: PHPMD (PHP ${{ matrix.php }})
|
name: PHPMD (PHP ${{ matrix.php }})
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
52
.phpstan-addons.neon
Normal file
52
.phpstan-addons.neon
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
# SPDX-FileCopyrightText: 2010 - 2024 the Friendica project
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
level: 3
|
||||||
|
|
||||||
|
paths:
|
||||||
|
- addon/
|
||||||
|
|
||||||
|
excludePaths:
|
||||||
|
analyse:
|
||||||
|
- addon/*/lang/*
|
||||||
|
- addon/*/vendor/*
|
||||||
|
- addon/convert/UnitConvertor.php
|
||||||
|
- addon/pumpio/oauth/*
|
||||||
|
|
||||||
|
scanDirectories:
|
||||||
|
- mod
|
||||||
|
- src
|
||||||
|
- static
|
||||||
|
- vendor
|
||||||
|
- view
|
||||||
|
|
||||||
|
dynamicConstantNames:
|
||||||
|
- DB_UPDATE_VERSION
|
||||||
|
|
||||||
|
ignoreErrors:
|
||||||
|
|
||||||
|
-
|
||||||
|
# Ignore missing SMTP class in PHPMailer 5.2.21
|
||||||
|
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
||||||
|
message: '(^.+ an unknown class SMTP\.$)'
|
||||||
|
path: addon/mailstream/phpmailer
|
||||||
|
|
||||||
|
-
|
||||||
|
# Ignore missing SMTP class in PHPMailer 5.2.21
|
||||||
|
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
||||||
|
message: '(^Property .+ has unknown class SMTP as its type\.$)'
|
||||||
|
path: addon/mailstream/phpmailer
|
||||||
|
|
||||||
|
-
|
||||||
|
# Ignore missing SMTP class in PHPMailer 5.2.21
|
||||||
|
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
||||||
|
message: '(^Method .+ has invalid return type SMTP\.$)'
|
||||||
|
path: addon/mailstream/phpmailer
|
||||||
|
|
||||||
|
-
|
||||||
|
# Ignore missing SMTP class in PHPMailer 5.2.21
|
||||||
|
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
||||||
|
message: '(^Instantiated class SMTP not found\.$)'
|
||||||
|
path: addon/mailstream/phpmailer
|
|
@ -3,10 +3,9 @@
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
level: 2
|
level: 3
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
- addon/
|
|
||||||
- bin/auth_ejabberd.php
|
- bin/auth_ejabberd.php
|
||||||
- bin/console.php
|
- bin/console.php
|
||||||
- bin/daemon.php
|
- bin/daemon.php
|
||||||
|
@ -15,13 +14,6 @@ parameters:
|
||||||
- index.php
|
- index.php
|
||||||
- src/
|
- src/
|
||||||
|
|
||||||
excludePaths:
|
|
||||||
analyse:
|
|
||||||
- addon/*/lang/*
|
|
||||||
- addon/*/vendor/*
|
|
||||||
- addon/convert/UnitConvertor.php
|
|
||||||
- addon/pumpio/oauth/*
|
|
||||||
|
|
||||||
scanDirectories:
|
scanDirectories:
|
||||||
- mod
|
- mod
|
||||||
- static
|
- static
|
||||||
|
@ -46,27 +38,3 @@ parameters:
|
||||||
# Ignore missing IMAP\Connection class in PHP <= 8.0
|
# Ignore missing IMAP\Connection class in PHP <= 8.0
|
||||||
message: '(^Parameter .+ has invalid type IMAP\\Connection\.$)'
|
message: '(^Parameter .+ has invalid type IMAP\\Connection\.$)'
|
||||||
path: src
|
path: src
|
||||||
|
|
||||||
-
|
|
||||||
# Ignore missing SMTP class in PHPMailer 5.2.21
|
|
||||||
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
|
||||||
message: '(^.+ an unknown class SMTP\.$)'
|
|
||||||
path: addon/mailstream/phpmailer
|
|
||||||
|
|
||||||
-
|
|
||||||
# Ignore missing SMTP class in PHPMailer 5.2.21
|
|
||||||
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
|
||||||
message: '(^Property .+ has unknown class SMTP as its type\.$)'
|
|
||||||
path: addon/mailstream/phpmailer
|
|
||||||
|
|
||||||
-
|
|
||||||
# Ignore missing SMTP class in PHPMailer 5.2.21
|
|
||||||
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
|
||||||
message: '(^Method .+ has invalid return type SMTP\.$)'
|
|
||||||
path: addon/mailstream/phpmailer
|
|
||||||
|
|
||||||
-
|
|
||||||
# Ignore missing SMTP class in PHPMailer 5.2.21
|
|
||||||
# see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.smtp.php
|
|
||||||
message: '(^Instantiated class SMTP not found\.$)'
|
|
||||||
path: addon/mailstream/phpmailer
|
|
||||||
|
|
|
@ -43,14 +43,10 @@ steps:
|
||||||
- apt-get update -q
|
- apt-get update -q
|
||||||
- DEBIAN_FRONTEND=noninteractive apt-get install -q -y git
|
- DEBIAN_FRONTEND=noninteractive apt-get install -q -y git
|
||||||
- if [ ! -z "$${CI_COMMIT_PULL_REQUEST}" ]; then
|
- if [ ! -z "$${CI_COMMIT_PULL_REQUEST}" ]; then
|
||||||
git fetch --no-tags origin ${CI_COMMIT_TARGET_BRANCH};
|
git fetch --no-tags --unshallow origin ${CI_COMMIT_TARGET_BRANCH}:refs/remotes/origin/${CI_COMMIT_TARGET_BRANCH};
|
||||||
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB $(git merge-base FETCH_HEAD origin/${CI_COMMIT_TARGET_BRANCH})..${CI_COMMIT_SHA})";
|
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB $(git merge-base ${CI_COMMIT_SHA} origin/${CI_COMMIT_TARGET_BRANCH})..${CI_COMMIT_SHA})";
|
||||||
else
|
else
|
||||||
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB ${CI_COMMIT_SHA})";
|
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB ${CI_COMMIT_SHA})";
|
||||||
fi
|
fi
|
||||||
- if ! echo "$${CHANGED_FILES}" | grep -qE "^(\\.php-cs-fixer(\\.dist)?\\.php|composer\\.lock)$"; then
|
- EXTRA_ARGS="--path-mode=intersection -- $${CHANGED_FILES}";
|
||||||
EXTRA_ARGS=$(printf -- '--path-mode=intersection\n--\n%s' "$${CHANGED_FILES}");
|
|
||||||
else
|
|
||||||
EXTRA_ARGS='';
|
|
||||||
fi
|
|
||||||
- ./bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php -v --diff --using-cache=no $${EXTRA_ARGS}
|
- ./bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php -v --diff --using-cache=no $${EXTRA_ARGS}
|
||||||
|
|
|
@ -78,9 +78,16 @@ steps:
|
||||||
image: friendicaci/php${PHP_MAJOR_VERSION}:php${PHP_VERSION}
|
image: friendicaci/php${PHP_MAJOR_VERSION}:php${PHP_VERSION}
|
||||||
when:
|
when:
|
||||||
matrix:
|
matrix:
|
||||||
PHP_MAJOR_VERSION: 8.2
|
PHP_MAJOR_VERSION: 8.3
|
||||||
commands:
|
commands:
|
||||||
- bin/composer.phar run phpstan;
|
- bin/composer.phar run phpstan;
|
||||||
|
phpstan-addons:
|
||||||
|
image: friendicaci/php${PHP_MAJOR_VERSION}:php${PHP_VERSION}
|
||||||
|
when:
|
||||||
|
matrix:
|
||||||
|
PHP_MAJOR_VERSION: 8.3
|
||||||
|
commands:
|
||||||
|
- bin/composer.phar run phpstan-addons;
|
||||||
test:
|
test:
|
||||||
image: friendicaci/php${PHP_MAJOR_VERSION}:php${PHP_VERSION}
|
image: friendicaci/php${PHP_MAJOR_VERSION}:php${PHP_VERSION}
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
"friendica/json-ld": "^1.0",
|
"friendica/json-ld": "^1.0",
|
||||||
"geekwright/po": "^2.0",
|
"geekwright/po": "^2.0",
|
||||||
"guzzlehttp/guzzle": "^7",
|
"guzzlehttp/guzzle": "^7",
|
||||||
"guzzlehttp/oauth-subscriber": "^0.6",
|
"guzzlehttp/oauth-subscriber": "^0.8",
|
||||||
"kornrunner/blurhash": "^1.2",
|
"kornrunner/blurhash": "^1.2",
|
||||||
"league/html-to-markdown": "^4.8",
|
"league/html-to-markdown": "^4.8",
|
||||||
"level-2/dice": "^4",
|
"level-2/dice": "^4",
|
||||||
|
@ -153,6 +153,7 @@
|
||||||
"dms/phpunit-arraysubset-asserts": "^0.3.1",
|
"dms/phpunit-arraysubset-asserts": "^0.3.1",
|
||||||
"mikey179/vfsstream": "^1.6",
|
"mikey179/vfsstream": "^1.6",
|
||||||
"mockery/mockery": "^1.3",
|
"mockery/mockery": "^1.3",
|
||||||
|
"php-mock/php-mock-mockery": "^1.5",
|
||||||
"php-mock/php-mock-phpunit": "^2.10",
|
"php-mock/php-mock-phpunit": "^2.10",
|
||||||
"phpmd/phpmd": "^2.15",
|
"phpmd/phpmd": "^2.15",
|
||||||
"phpstan/phpstan": "^2.0",
|
"phpstan/phpstan": "^2.0",
|
||||||
|
@ -163,6 +164,7 @@
|
||||||
"test:unit": "phpunit -c tests/phpunit.xml --testsuite unit",
|
"test:unit": "phpunit -c tests/phpunit.xml --testsuite unit",
|
||||||
"phpmd": "phpmd src/ text .phpmd-ruleset.xml --color --cache",
|
"phpmd": "phpmd src/ text .phpmd-ruleset.xml --color --cache",
|
||||||
"phpstan": "phpstan analyze --memory-limit 1024M --configuration .phpstan.neon",
|
"phpstan": "phpstan analyze --memory-limit 1024M --configuration .phpstan.neon",
|
||||||
|
"phpstan-addons": "phpstan analyze --memory-limit 1024M --configuration .phpstan-addons.neon",
|
||||||
"lint": "find . -name \\*.php -not -path './vendor/*' -not -path './view/asset/*' -print0 | xargs -0 -n1 php -l",
|
"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",
|
"docker:translate": "docker run --rm -v $PWD:/data -w /data friendicaci/transifex bin/run_xgettext.sh",
|
||||||
"lang:recreate": "bin/run_xgettext.sh",
|
"lang:recreate": "bin/run_xgettext.sh",
|
||||||
|
|
227
composer.lock
generated
227
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "b77bf714197f04022a5feb001bf07852",
|
"content-hash": "8aa73e21ed198d8013c09de14e8230cd",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "asika/simple-console",
|
"name": "asika/simple-console",
|
||||||
|
@ -893,22 +893,22 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
"version": "7.8.1",
|
"version": "7.9.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/guzzle.git",
|
"url": "https://github.com/guzzle/guzzle.git",
|
||||||
"reference": "41042bc7ab002487b876a0683fc8dce04ddce104"
|
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104",
|
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
|
||||||
"reference": "41042bc7ab002487b876a0683fc8dce04ddce104",
|
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"guzzlehttp/promises": "^1.5.3 || ^2.0.1",
|
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
|
||||||
"guzzlehttp/psr7": "^1.9.1 || ^2.5.1",
|
"guzzlehttp/psr7": "^2.7.0",
|
||||||
"php": "^7.2.5 || ^8.0",
|
"php": "^7.2.5 || ^8.0",
|
||||||
"psr/http-client": "^1.0",
|
"psr/http-client": "^1.0",
|
||||||
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||||
|
@ -919,9 +919,9 @@
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
|
"guzzle/client-integration-tests": "3.0.2",
|
||||||
"php-http/message-factory": "^1.1",
|
"php-http/message-factory": "^1.1",
|
||||||
"phpunit/phpunit": "^8.5.36 || ^9.6.15",
|
"phpunit/phpunit": "^8.5.39 || ^9.6.20",
|
||||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
@ -997,6 +997,10 @@
|
||||||
"rest",
|
"rest",
|
||||||
"web service"
|
"web service"
|
||||||
],
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||||
|
"source": "https://github.com/guzzle/guzzle/tree/7.9.3"
|
||||||
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"url": "https://github.com/GrahamCampbell",
|
"url": "https://github.com/GrahamCampbell",
|
||||||
|
@ -1011,37 +1015,39 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-12-03T20:35:24+00:00"
|
"time": "2025-03-27T13:37:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/oauth-subscriber",
|
"name": "guzzlehttp/oauth-subscriber",
|
||||||
"version": "0.6.0",
|
"version": "0.8.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/oauth-subscriber.git",
|
"url": "https://github.com/guzzle/oauth-subscriber.git",
|
||||||
"reference": "8d6cab29f8397e5712d00a383eeead36108a3c1f"
|
"reference": "92b619b03bd21396e51c62e6bce83467d2ce8f53"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/oauth-subscriber/zipball/8d6cab29f8397e5712d00a383eeead36108a3c1f",
|
"url": "https://api.github.com/repos/guzzle/oauth-subscriber/zipball/92b619b03bd21396e51c62e6bce83467d2ce8f53",
|
||||||
"reference": "8d6cab29f8397e5712d00a383eeead36108a3c1f",
|
"reference": "92b619b03bd21396e51c62e6bce83467d2ce8f53",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"guzzlehttp/guzzle": "^6.5|^7.2",
|
"guzzlehttp/guzzle": "^7.9",
|
||||||
"guzzlehttp/psr7": "^1.7|^2.0",
|
"guzzlehttp/psr7": "^2.7",
|
||||||
"php": ">=5.5.0"
|
"php": "^7.2.5 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~4.0|^9.3.3"
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
|
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-openssl": "Required to sign using RSA-SHA1"
|
"ext-openssl": "Required to sign using RSA-SHA1"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"bamarni-bin": {
|
||||||
"dev-master": "0.6-dev"
|
"bin-links": true,
|
||||||
|
"forward-command": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -1054,32 +1060,64 @@
|
||||||
"MIT"
|
"MIT"
|
||||||
],
|
],
|
||||||
"authors": [
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Graham Campbell",
|
||||||
|
"email": "hello@gjcampbell.co.uk",
|
||||||
|
"homepage": "https://github.com/GrahamCampbell"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Michael Dowling",
|
"name": "Michael Dowling",
|
||||||
"email": "mtdowling@gmail.com",
|
"email": "mtdowling@gmail.com",
|
||||||
"homepage": "https://github.com/mtdowling"
|
"homepage": "https://github.com/mtdowling"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "George Mponos",
|
||||||
|
"email": "gmponos@gmail.com",
|
||||||
|
"homepage": "https://github.com/gmponos"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tobias Nyholm",
|
||||||
|
"email": "tobias.nyholm@gmail.com",
|
||||||
|
"homepage": "https://github.com/Nyholm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Guzzle OAuth 1.0 subscriber",
|
"description": "Guzzle OAuth 1.0 subscriber",
|
||||||
"homepage": "http://guzzlephp.org/",
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Guzzle",
|
"Guzzle",
|
||||||
"oauth"
|
"oauth"
|
||||||
],
|
],
|
||||||
"time": "2021-07-13T12:01:32+00:00"
|
"support": {
|
||||||
|
"issues": "https://github.com/guzzle/oauth-subscriber/issues",
|
||||||
|
"source": "https://github.com/guzzle/oauth-subscriber/tree/0.8.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/GrahamCampbell",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/Nyholm",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/oauth-subscriber",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-01-06T19:15:59+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/promises",
|
"name": "guzzlehttp/promises",
|
||||||
"version": "2.0.2",
|
"version": "2.2.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/promises.git",
|
"url": "https://github.com/guzzle/promises.git",
|
||||||
"reference": "bbff78d96034045e58e13dedd6ad91b5d1253223"
|
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223",
|
"url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c",
|
||||||
"reference": "bbff78d96034045e58e13dedd6ad91b5d1253223",
|
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1087,7 +1125,7 @@
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
|
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
@ -1131,6 +1169,10 @@
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"promise"
|
"promise"
|
||||||
],
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/guzzle/promises/issues",
|
||||||
|
"source": "https://github.com/guzzle/promises/tree/2.2.0"
|
||||||
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"url": "https://github.com/GrahamCampbell",
|
"url": "https://github.com/GrahamCampbell",
|
||||||
|
@ -1145,20 +1187,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-12-03T20:19:20+00:00"
|
"time": "2025-03-27T13:27:01+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/psr7",
|
"name": "guzzlehttp/psr7",
|
||||||
"version": "2.6.2",
|
"version": "2.7.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/psr7.git",
|
"url": "https://github.com/guzzle/psr7.git",
|
||||||
"reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221"
|
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221",
|
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16",
|
||||||
"reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221",
|
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1173,8 +1215,8 @@
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"http-interop/http-factory-tests": "^0.9",
|
"http-interop/http-factory-tests": "0.9.0",
|
||||||
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
|
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
||||||
|
@ -1243,6 +1285,10 @@
|
||||||
"uri",
|
"uri",
|
||||||
"url"
|
"url"
|
||||||
],
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/guzzle/psr7/issues",
|
||||||
|
"source": "https://github.com/guzzle/psr7/tree/2.7.1"
|
||||||
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"url": "https://github.com/GrahamCampbell",
|
"url": "https://github.com/GrahamCampbell",
|
||||||
|
@ -1257,7 +1303,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-12-03T20:05:35+00:00"
|
"time": "2025-03-27T12:30:47+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "kornrunner/blurhash",
|
"name": "kornrunner/blurhash",
|
||||||
|
@ -3333,24 +3379,27 @@
|
||||||
"psr",
|
"psr",
|
||||||
"psr-18"
|
"psr-18"
|
||||||
],
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-client"
|
||||||
|
},
|
||||||
"time": "2023-09-23T14:17:50+00:00"
|
"time": "2023-09-23T14:17:50+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/http-factory",
|
"name": "psr/http-factory",
|
||||||
"version": "1.0.2",
|
"version": "1.1.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/php-fig/http-factory.git",
|
"url": "https://github.com/php-fig/http-factory.git",
|
||||||
"reference": "e616d01114759c4c489f93b099585439f795fe35"
|
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
|
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||||
"reference": "e616d01114759c4c489f93b099585439f795fe35",
|
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.0.0",
|
"php": ">=7.1",
|
||||||
"psr/http-message": "^1.0 || ^2.0"
|
"psr/http-message": "^1.0 || ^2.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
@ -3374,7 +3423,7 @@
|
||||||
"homepage": "https://www.php-fig.org/"
|
"homepage": "https://www.php-fig.org/"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Common interfaces for PSR-7 HTTP message factories",
|
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"factory",
|
"factory",
|
||||||
"http",
|
"http",
|
||||||
|
@ -3385,7 +3434,10 @@
|
||||||
"request",
|
"request",
|
||||||
"response"
|
"response"
|
||||||
],
|
],
|
||||||
"time": "2023-04-10T20:10:41+00:00"
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-factory"
|
||||||
|
},
|
||||||
|
"time": "2024-04-15T12:06:14+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/http-message",
|
"name": "psr/http-message",
|
||||||
|
@ -3435,6 +3487,9 @@
|
||||||
"request",
|
"request",
|
||||||
"response"
|
"response"
|
||||||
],
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/http-message/tree/1.1"
|
||||||
|
},
|
||||||
"time": "2023-04-04T09:50:52+00:00"
|
"time": "2023-04-04T09:50:52+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -3525,6 +3580,10 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "A polyfill for getallheaders.",
|
"description": "A polyfill for getallheaders.",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/ralouphie/getallheaders/issues",
|
||||||
|
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
|
||||||
|
},
|
||||||
"time": "2019-03-08T08:55:37+00:00"
|
"time": "2019-03-08T08:55:37+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -3580,16 +3639,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "smarty/smarty",
|
"name": "smarty/smarty",
|
||||||
"version": "v4.5.1",
|
"version": "v4.5.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/smarty-php/smarty.git",
|
"url": "https://github.com/smarty-php/smarty.git",
|
||||||
"reference": "42b869e3a098b1c8ee07922ccded0e5a5dceadcd"
|
"reference": "9fc96a13dbaf546c3d7bcf95466726578cd4e0fa"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/42b869e3a098b1c8ee07922ccded0e5a5dceadcd",
|
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/9fc96a13dbaf546c3d7bcf95466726578cd4e0fa",
|
||||||
"reference": "42b869e3a098b1c8ee07922ccded0e5a5dceadcd",
|
"reference": "9fc96a13dbaf546c3d7bcf95466726578cd4e0fa",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3637,7 +3696,12 @@
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"templating"
|
"templating"
|
||||||
],
|
],
|
||||||
"time": "2024-03-18T14:19:07+00:00"
|
"support": {
|
||||||
|
"forum": "https://github.com/smarty-php/smarty/discussions",
|
||||||
|
"issues": "https://github.com/smarty-php/smarty/issues",
|
||||||
|
"source": "https://github.com/smarty-php/smarty/tree/v4.5.3"
|
||||||
|
},
|
||||||
|
"time": "2024-05-28T21:46:01+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spomky-labs/base64url",
|
"name": "spomky-labs/base64url",
|
||||||
|
@ -5441,6 +5505,71 @@
|
||||||
],
|
],
|
||||||
"time": "2024-02-10T21:37:25+00:00"
|
"time": "2024-02-10T21:37:25+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "php-mock/php-mock-mockery",
|
||||||
|
"version": "1.5.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-mock/php-mock-mockery.git",
|
||||||
|
"reference": "291994acdc26daf1e3c659cfbe58b01eeb180b7f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-mock/php-mock-mockery/zipball/291994acdc26daf1e3c659cfbe58b01eeb180b7f",
|
||||||
|
"reference": "291994acdc26daf1e3c659cfbe58b01eeb180b7f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"mockery/mockery": "^1",
|
||||||
|
"php": ">=5.6",
|
||||||
|
"php-mock/php-mock-integration": "^2.2.1 || ^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4|^5|^8"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"phpmock\\mockery\\": "classes/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"WTFPL"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Markus Malkusch",
|
||||||
|
"email": "markus@malkusch.de",
|
||||||
|
"homepage": "http://markus.malkusch.de",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Mock built-in PHP functions (e.g. time()) with Mockery. This package relies on PHP's namespace fallback policy. No further extension is needed.",
|
||||||
|
"homepage": "https://github.com/php-mock/php-mock-mockery",
|
||||||
|
"keywords": [
|
||||||
|
"BDD",
|
||||||
|
"TDD",
|
||||||
|
"function",
|
||||||
|
"mock",
|
||||||
|
"mockery",
|
||||||
|
"stub",
|
||||||
|
"test",
|
||||||
|
"test double",
|
||||||
|
"testing"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/php-mock/php-mock-mockery/issues",
|
||||||
|
"source": "https://github.com/php-mock/php-mock-mockery/tree/1.5.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/michalbundyra",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-03-08T19:46:20+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "php-mock/php-mock-phpunit",
|
"name": "php-mock/php-mock-phpunit",
|
||||||
"version": "2.10.0",
|
"version": "2.10.0",
|
||||||
|
@ -7569,9 +7698,9 @@
|
||||||
"ext-simplexml": "*",
|
"ext-simplexml": "*",
|
||||||
"ext-xml": "*"
|
"ext-xml": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": [],
|
||||||
"platform-overrides": {
|
"platform-overrides": {
|
||||||
"php": "7.4"
|
"php": "7.4"
|
||||||
},
|
},
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.3.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,16 +156,6 @@ $a->config['register_policy'] = REGISTER_CLOSED;
|
||||||
'config' => [
|
'config' => [
|
||||||
'register_policy' => \Friendica\Module\Register::CLOSED,
|
'register_policy' => \Friendica\Module\Register::CLOSED,
|
||||||
],
|
],
|
||||||
</pre></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><pre>
|
|
||||||
$a->path = "value";
|
|
||||||
</pre></td>
|
|
||||||
<td><pre>
|
|
||||||
'system' => [
|
|
||||||
'urlpath' => 'value',
|
|
||||||
],
|
|
||||||
</pre></td>
|
</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -218,7 +218,6 @@ All options will be saved in the `config/local.config.php` and are overruling th
|
||||||
- `-U|--dbuser <username>` The username of the mysql/mariadb database login (env `MYSQL_USER` or `MYSQL_USERNAME`)
|
- `-U|--dbuser <username>` The username of the mysql/mariadb database login (env `MYSQL_USER` or `MYSQL_USERNAME`)
|
||||||
- `-P|--dbpass <password>` The password of the mysql/mariadb database login (env `MYSQL_PASSWORD`)
|
- `-P|--dbpass <password>` The password of the mysql/mariadb database login (env `MYSQL_PASSWORD`)
|
||||||
- `-d|--dbdata <database>` The name of the mysql/mariadb database (env `MYSQL_DATABASE`)
|
- `-d|--dbdata <database>` The name of the mysql/mariadb database (env `MYSQL_DATABASE`)
|
||||||
- `-u|--urlpath <url_path>` The URL path of Friendica - f.e. '/friendica' (env `FRIENDICA_URL_PATH`)
|
|
||||||
- `-b|--phppath <php_path>` The path of the PHP binary (env `FRIENDICA_PHP_PATH`)
|
- `-b|--phppath <php_path>` The path of the PHP binary (env `FRIENDICA_PHP_PATH`)
|
||||||
- `-A|--admin <mail>` The admin email address of Friendica (env `FRIENDICA_ADMIN_MAIL`)
|
- `-A|--admin <mail>` The admin email address of Friendica (env `FRIENDICA_ADMIN_MAIL`)
|
||||||
- `-T|--tz <timezone>` The timezone of Friendica (env `FRIENDICA_TZ`)
|
- `-T|--tz <timezone>` The timezone of Friendica (env `FRIENDICA_TZ`)
|
||||||
|
|
|
@ -419,7 +419,7 @@ We strongly discourage you from doing so, as this will break federation to other
|
||||||
Say you have a subdirectory for tests and put Friendica into a further subdirectory, the config would be:
|
Say you have a subdirectory for tests and put Friendica into a further subdirectory, the config would be:
|
||||||
|
|
||||||
'system' => [
|
'system' => [
|
||||||
'urlpath' => 'tests/friendica',
|
'url' => 'https://example.com/tests/friendica',
|
||||||
],
|
],
|
||||||
|
|
||||||
## Other exceptions
|
## Other exceptions
|
||||||
|
|
|
@ -410,7 +410,7 @@ Wir raten allerdings dringen davon ab, da es die Interoperabilität mit anderen
|
||||||
Mal angenommen, du hast ein Unterverzeichnis tests und willst Friendica in ein weiteres Unterverzeichnis installieren, dann lautet die Konfiguration hierfür:
|
Mal angenommen, du hast ein Unterverzeichnis tests und willst Friendica in ein weiteres Unterverzeichnis installieren, dann lautet die Konfiguration hierfür:
|
||||||
|
|
||||||
'system' => [
|
'system' => [
|
||||||
'urlpath' => 'tests/friendica',
|
'url' => 'https://example.com/tests/friendica',
|
||||||
],
|
],
|
||||||
|
|
||||||
## Weitere Ausnahmen
|
## Weitere Ausnahmen
|
||||||
|
|
35
doc/stats.md
Normal file
35
doc/stats.md
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
Monitoring
|
||||||
|
===========
|
||||||
|
|
||||||
|
* [Home](help)
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
Currently, there are two endpoints for statistics available
|
||||||
|
|
||||||
|
- `/stats` Returns some basic statistics of the current node
|
||||||
|
- `/stats/caching` Returns statistics of cache or lock instances, which are used for the currend node
|
||||||
|
|
||||||
|
### `/stats`
|
||||||
|
|
||||||
|
The statistics contain data about the worker performance, the last cron call, number of reports, inbound and outbound packets, posts and comments.
|
||||||
|
|
||||||
|
### `/stats/caching`
|
||||||
|
|
||||||
|
The statistics contain data about the opcache, the used caching (like memory usage, hits/misses, entries, ...) and the used lock (including the cache data)
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Please define 'stats_key' in your local.config.php in the 'system' section to be able to access the statistics page at /stats?key=your-defined-stats_key
|
||||||
|
|
||||||
|
## 3rd Party monitoring tools
|
||||||
|
|
||||||
|
### Zabbix
|
||||||
|
|
||||||
|
To monitor the health status of your Friendica installation, you can use for example a tool like Zabbix.
|
||||||
|
|
||||||
|
### Prometheus
|
||||||
|
|
||||||
|
To use [prometheus](https://prometheus.io) for gathering metrics, use the [Friendica exporter](https://git.friendi.ca/friendica/friendica-exporter).
|
||||||
|
|
||||||
|
You can find the installation instructions here: https://git.friendi.ca/friendica/friendica-exporter#installation
|
12
doc/tools.md
12
doc/tools.md
|
@ -78,15 +78,3 @@ The following will compress */var/log/friendica* (assuming this is the location
|
||||||
daily
|
daily
|
||||||
rotate 2
|
rotate 2
|
||||||
}
|
}
|
||||||
|
|
||||||
### Zabbix
|
|
||||||
|
|
||||||
To monitor the health status of your Friendica installation, you can use for example a tool like Zabbix. Please define 'stats_key' in your local.config.php in the 'system' section to be able to access the statistics page at /stats?key=your-defined-stats_key
|
|
||||||
|
|
||||||
The statistics contain data about the worker performance, the last cron call, number of reports, inbound and outbound packets, posts and comments.
|
|
||||||
|
|
||||||
### Prometheus
|
|
||||||
|
|
||||||
To use [prometheus](https://prometheus.io) for gathering metrics, use the [Friendica exporter](https://git.friendi.ca/friendica/friendica-exporter).
|
|
||||||
|
|
||||||
You can find the installation instructions here: https://git.friendi.ca/friendica/friendica-exporter#installation
|
|
||||||
|
|
12
mod/item.php
12
mod/item.php
|
@ -46,7 +46,7 @@ function item_post()
|
||||||
$eventDispatcher = DI::eventDispatcher();
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
$_REQUEST = $eventDispatcher->dispatch(
|
$_REQUEST = $eventDispatcher->dispatch(
|
||||||
new ArrayFilterEvent(ArrayFilterEvent::POST_LOCAL_START, $_REQUEST)
|
new ArrayFilterEvent(ArrayFilterEvent::INSERT_POST_LOCAL_START, $_REQUEST)
|
||||||
)->getArray();
|
)->getArray();
|
||||||
|
|
||||||
$return_path = $_REQUEST['return'] ?? '';
|
$return_path = $_REQUEST['return'] ?? '';
|
||||||
|
@ -281,10 +281,16 @@ function item_process(array $post, array $request, bool $preview, string $return
|
||||||
|
|
||||||
$eventDispatcher = DI::eventDispatcher();
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
$post = $eventDispatcher->dispatch(
|
$hook_data = [
|
||||||
new ArrayFilterEvent(ArrayFilterEvent::POST_LOCAL, $post)
|
'item' => $post,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::INSERT_POST_LOCAL, $hook_data)
|
||||||
)->getArray();
|
)->getArray();
|
||||||
|
|
||||||
|
$post = $hook_data['item'] ?? $post;
|
||||||
|
|
||||||
unset($post['edit']);
|
unset($post['edit']);
|
||||||
unset($post['self']);
|
unset($post['self']);
|
||||||
unset($post['api_source']);
|
unset($post['api_source']);
|
||||||
|
|
|
@ -1022,7 +1022,7 @@ function photos_content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$tags = ['title' => DI::l10n()->t('Tags: '), 'tags' => $tag_arr];
|
$tags = ['title' => DI::l10n()->t('Tags: '), 'tags' => $tag_arr];
|
||||||
if ($cmd === 'edit') {
|
if ($cmd === 'edit' && !empty($tag_arr)) {
|
||||||
$tags['removeanyurl'] = 'post/' . $link_item['id'] . '/tag/remove?return=' . urlencode(DI::args()->getCommand());
|
$tags['removeanyurl'] = 'post/' . $link_item['id'] . '/tag/remove?return=' . urlencode(DI::args()->getCommand());
|
||||||
$tags['removetitle'] = DI::l10n()->t('[Select tags to remove]');
|
$tags['removetitle'] = DI::l10n()->t('[Select tags to remove]');
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,7 @@ use Psr\Http\Message\UriInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which checks and contains the basic
|
* A class which checks and contains the basic environment for the BaseURL (url)
|
||||||
* environment for the BaseURL (url, urlpath, ssl_policy, hostname, scheme)
|
|
||||||
*/
|
*/
|
||||||
class BaseURL extends Uri implements UriInterface
|
class BaseURL extends Uri implements UriInterface
|
||||||
{
|
{
|
||||||
|
@ -43,8 +42,7 @@ class BaseURL extends Uri implements UriInterface
|
||||||
/* Relative script path to the web server root
|
/* Relative script path to the web server root
|
||||||
* Not all of those $_SERVER properties can be present, so we do by inverse priority order
|
* Not all of those $_SERVER properties can be present, so we do by inverse priority order
|
||||||
*/
|
*/
|
||||||
$relativeScriptPath =
|
$relativeScriptPath = ($server['REDIRECT_URL'] ?? '') ?:
|
||||||
($server['REDIRECT_URL'] ?? '') ?:
|
|
||||||
($server['REDIRECT_URI'] ?? '') ?:
|
($server['REDIRECT_URI'] ?? '') ?:
|
||||||
($server['REDIRECT_SCRIPT_URL'] ?? '') ?:
|
($server['REDIRECT_SCRIPT_URL'] ?? '') ?:
|
||||||
($server['SCRIPT_URL'] ?? '') ?:
|
($server['SCRIPT_URL'] ?? '') ?:
|
||||||
|
|
|
@ -198,7 +198,7 @@ class Page implements ArrayAccess
|
||||||
) {
|
) {
|
||||||
// Default title: current module called
|
// Default title: current module called
|
||||||
if (empty($this->page['title']) && $args->getModuleName()) {
|
if (empty($this->page['title']) && $args->getModuleName()) {
|
||||||
$this->page['title'] = ucfirst($args->getModuleName());
|
$this->page['title'] = $l10n->t(ucfirst($args->getModuleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepend the sitename to the page title
|
// Prepend the sitename to the page title
|
||||||
|
|
|
@ -24,7 +24,7 @@ class BaseCollection extends \ArrayIterator
|
||||||
* @param BaseEntity[] $entities
|
* @param BaseEntity[] $entities
|
||||||
* @param int|null $totalCount
|
* @param int|null $totalCount
|
||||||
*/
|
*/
|
||||||
public function __construct(array $entities = [], int $totalCount = null)
|
public function __construct(array $entities = [], ?int $totalCount = null)
|
||||||
{
|
{
|
||||||
parent::__construct($entities);
|
parent::__construct($entities);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ class BaseCollection extends \ArrayIterator
|
||||||
* @return BaseCollection
|
* @return BaseCollection
|
||||||
* @see array_filter()
|
* @see array_filter()
|
||||||
*/
|
*/
|
||||||
public function filter(callable $callback = null, int $flag = 0): BaseCollection
|
public function filter(?callable $callback = null, int $flag = 0): BaseCollection
|
||||||
{
|
{
|
||||||
$class = get_class($this);
|
$class = get_class($this);
|
||||||
|
|
||||||
|
@ -111,8 +111,6 @@ class BaseCollection extends \ArrayIterator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse the orders of the elements in the collection
|
* Reverse the orders of the elements in the collection
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
*/
|
||||||
public function reverse(): BaseCollection
|
public function reverse(): BaseCollection
|
||||||
{
|
{
|
||||||
|
@ -125,7 +123,6 @@ class BaseCollection extends \ArrayIterator
|
||||||
* Split the collection in smaller collections no bigger than the provided length
|
* Split the collection in smaller collections no bigger than the provided length
|
||||||
*
|
*
|
||||||
* @param int $length
|
* @param int $length
|
||||||
* @return static[]
|
|
||||||
*/
|
*/
|
||||||
public function chunk(int $length): array
|
public function chunk(int $length): array
|
||||||
{
|
{
|
||||||
|
@ -133,11 +130,14 @@ class BaseCollection extends \ArrayIterator
|
||||||
throw new \RangeException('BaseCollection->chunk(): Size parameter expected to be greater than 0');
|
throw new \RangeException('BaseCollection->chunk(): Size parameter expected to be greater than 0');
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_map(function ($array) {
|
return array_map(
|
||||||
|
function ($array) {
|
||||||
$class = get_class($this);
|
$class = get_class($this);
|
||||||
|
|
||||||
return new $class($array);
|
return new $class($array);
|
||||||
}, array_chunk($this->getArrayCopy(), $length));
|
},
|
||||||
|
array_chunk($this->getArrayCopy(), $length)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -130,17 +130,33 @@ abstract class BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $condition
|
* Selects the fields of the first row as array
|
||||||
* @param array $params
|
*
|
||||||
* @return BaseEntity
|
* @throws NotFoundException
|
||||||
|
*
|
||||||
|
* @return array The resulted fields as array
|
||||||
|
*/
|
||||||
|
final protected function _selectFirstRowAsArray(array $condition, array $params = []): array
|
||||||
|
{
|
||||||
|
$fields = $this->db->selectFirst(static::$table_name, [], $condition, $params);
|
||||||
|
|
||||||
|
if (!$this->db->isResult($fields)) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 2025.05 Use `\Friendica\BaseRepository::_selectFirstRowAsArray()` instead
|
||||||
|
*
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
protected function _selectOne(array $condition, array $params = []): BaseEntity
|
protected function _selectOne(array $condition, array $params = []): BaseEntity
|
||||||
{
|
{
|
||||||
$fields = $this->db->selectFirst(static::$table_name, [], $condition, $params);
|
@trigger_error('`' . __METHOD__ . '()` is deprecated since 2025.05 and will be removed after 5 months, use `\Friendica\BaseRepository::_selectFirstRowAsArray()` instead.', E_USER_DEPRECATED);
|
||||||
if (!$this->db->isResult($fields)) {
|
|
||||||
throw new NotFoundException();
|
$fields = $this->_selectFirstRowAsArray( $condition, $params);
|
||||||
}
|
|
||||||
|
|
||||||
return $this->factory->createFromTableRow($fields);
|
return $this->factory->createFromTableRow($fields);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ HELP;
|
||||||
return $help;
|
return $help;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct(Mode $appMode, array $argv = null)
|
public function __construct(Mode $appMode, ?array $argv = null)
|
||||||
{
|
{
|
||||||
parent::__construct($argv);
|
parent::__construct($argv);
|
||||||
|
|
||||||
|
@ -84,13 +84,13 @@ HELP;
|
||||||
|
|
||||||
switch ($command) {
|
switch ($command) {
|
||||||
case 'add':
|
case 'add':
|
||||||
return $this->addContact();
|
return ($this->addContact()) ? 0 : 1;
|
||||||
case 'remove':
|
case 'remove':
|
||||||
return $this->removeContact();
|
return ($this->removeContact()) ? 0 : 1;
|
||||||
case 'search':
|
case 'search':
|
||||||
return $this->searchContact();
|
return ($this->searchContact()) ? 0 : 1;
|
||||||
case 'terminate':
|
case 'terminate':
|
||||||
return $this->terminateContact();
|
return ($this->terminateContact()) ? 0 : 1;
|
||||||
default:
|
default:
|
||||||
throw new \Asika\SimpleConsole\CommandArgsException('Wrong command.');
|
throw new \Asika\SimpleConsole\CommandArgsException('Wrong command.');
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ HELP;
|
||||||
/**
|
/**
|
||||||
* Marks a contact for removal
|
* Marks a contact for removal
|
||||||
*/
|
*/
|
||||||
private function removeContact()
|
private function removeContact(): bool
|
||||||
{
|
{
|
||||||
$cid = $this->getArgument(1);
|
$cid = $this->getArgument(1);
|
||||||
if (empty($cid)) {
|
if (empty($cid)) {
|
||||||
|
@ -218,6 +218,8 @@ HELP;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactModel::remove($cid);
|
ContactModel::remove($cid);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -175,11 +175,11 @@ HELP;
|
||||||
* @param string $string
|
* @param string $string
|
||||||
* @param array|string $node
|
* @param array|string $node
|
||||||
*/
|
*/
|
||||||
private static function parse(string $string, &$node = [])
|
private static function parse(string $string, &$node)
|
||||||
{
|
{
|
||||||
// Removes extra outward parentheses
|
// Removes extra outward parentheses
|
||||||
if (strpos($string, '(') === 0 && strrpos($string, ')') === strlen($string) - 1) {
|
if (strpos($string, '(') === 0 && strrpos($string, ')') === strlen($string) - 1) {
|
||||||
$string = substr($string, 1, -1);
|
$string = (string) substr($string, 1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$q = strpos($string, '?');
|
$q = strpos($string, '?');
|
||||||
|
|
|
@ -106,21 +106,21 @@ HELP;
|
||||||
case 'password':
|
case 'password':
|
||||||
return $this->password();
|
return $this->password();
|
||||||
case 'add':
|
case 'add':
|
||||||
return $this->addUser();
|
return ($this->addUser()) ? 0 : 1;
|
||||||
case 'allow':
|
case 'allow':
|
||||||
return $this->pendingUser(true);
|
return ($this->pendingUser(true)) ? 0 : 1;
|
||||||
case 'deny':
|
case 'deny':
|
||||||
return $this->pendingUser(false);
|
return ($this->pendingUser(false)) ? 0 : 1;
|
||||||
case 'block':
|
case 'block':
|
||||||
return $this->blockUser(true);
|
return ($this->blockUser(true)) ? 0 : 1;
|
||||||
case 'unblock':
|
case 'unblock':
|
||||||
return $this->blockUser(false);
|
return ($this->blockUser(false)) ? 0 : 1;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
return $this->deleteUser();
|
return ($this->deleteUser()) ? 0 : 1;
|
||||||
case 'list':
|
case 'list':
|
||||||
return $this->listUser();
|
return ($this->listUser()) ? 0 : 1;
|
||||||
case 'search':
|
case 'search':
|
||||||
return $this->searchUser();
|
return ($this->searchUser()) ? 0 : 1;
|
||||||
case 'config':
|
case 'config':
|
||||||
return ($this->configUser()) ? 0 : 1;
|
return ($this->configUser()) ? 0 : 1;
|
||||||
default:
|
default:
|
||||||
|
@ -178,7 +178,7 @@ HELP;
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function password()
|
private function password(): int
|
||||||
{
|
{
|
||||||
$user = $this->getUserByNick(1);
|
$user = $this->getUserByNick(1);
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ HELP;
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
*/
|
*/
|
||||||
private function addUser()
|
private function addUser(): bool
|
||||||
{
|
{
|
||||||
$name = $this->getArgument(1);
|
$name = $this->getArgument(1);
|
||||||
$nick = $this->getArgument(2);
|
$nick = $this->getArgument(2);
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
namespace Friendica\Contact\FriendSuggest\Repository;
|
namespace Friendica\Contact\FriendSuggest\Repository;
|
||||||
|
|
||||||
use Friendica\BaseRepository;
|
use Friendica\BaseRepository;
|
||||||
use Friendica\Contact\FriendSuggest\Collection;
|
use Friendica\Contact\FriendSuggest\Collection\FriendSuggests as FriendSuggestsCollection;
|
||||||
use Friendica\Contact\FriendSuggest\Entity\FriendSuggest as FriendSuggestEntity;
|
use Friendica\Contact\FriendSuggest\Entity\FriendSuggest as FriendSuggestEntity;
|
||||||
use Friendica\Contact\FriendSuggest\Exception\FriendSuggestNotFoundException;
|
use Friendica\Contact\FriendSuggest\Exception\FriendSuggestNotFoundException;
|
||||||
use Friendica\Contact\FriendSuggest\Exception\FriendSuggestPersistenceException;
|
use Friendica\Contact\FriendSuggest\Exception\FriendSuggestPersistenceException;
|
||||||
use Friendica\Contact\FriendSuggest\Factory;
|
use Friendica\Contact\FriendSuggest\Factory\FriendSuggest as FriendSuggestFactory;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Network\HTTPException\NotFoundException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
@ -20,12 +20,12 @@ use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class FriendSuggest extends BaseRepository
|
class FriendSuggest extends BaseRepository
|
||||||
{
|
{
|
||||||
/** @var Factory\FriendSuggest */
|
/** @var FriendSuggestFactory */
|
||||||
protected $factory;
|
protected $factory;
|
||||||
|
|
||||||
protected static $table_name = 'fsuggest';
|
protected static $table_name = 'fsuggest';
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\FriendSuggest $factory)
|
public function __construct(Database $database, LoggerInterface $logger, FriendSuggestFactory $factory)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
parent::__construct($database, $logger, $factory);
|
||||||
}
|
}
|
||||||
|
@ -49,20 +49,17 @@ class FriendSuggest extends BaseRepository
|
||||||
*/
|
*/
|
||||||
private function selectOne(array $condition, array $params = []): FriendSuggestEntity
|
private function selectOne(array $condition, array $params = []): FriendSuggestEntity
|
||||||
{
|
{
|
||||||
return parent::_selectOne($condition, $params);
|
$fields = $this->_selectFirstRowAsArray($condition, $params);
|
||||||
|
|
||||||
|
return $this->factory->createFromTableRow($fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $condition
|
|
||||||
* @param array $params
|
|
||||||
*
|
|
||||||
* @return Collection\FriendSuggests
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function select(array $condition, array $params = []): Collection\FriendSuggests
|
private function select(array $condition, array $params = []): FriendSuggestsCollection
|
||||||
{
|
{
|
||||||
return new Collection\FriendSuggests(parent::_select($condition, $params)->getArrayCopy());
|
return new FriendSuggestsCollection(parent::_select($condition, $params)->getArrayCopy());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,13 +75,9 @@ class FriendSuggest extends BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $cid
|
|
||||||
*
|
|
||||||
* @return Collection\FriendSuggests
|
|
||||||
*
|
|
||||||
* @throws FriendSuggestPersistenceException In case the underlying storage cannot select the suggestion
|
* @throws FriendSuggestPersistenceException In case the underlying storage cannot select the suggestion
|
||||||
*/
|
*/
|
||||||
public function selectForContact(int $cid): Collection\FriendSuggests
|
public function selectForContact(int $cid): FriendSuggestsCollection
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->select(['cid' => $cid]);
|
return $this->select(['cid' => $cid]);
|
||||||
|
@ -114,13 +107,9 @@ class FriendSuggest extends BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection\FriendSuggests $fsuggests
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @throws FriendSuggestNotFoundException in case the underlying storage cannot delete the suggestion
|
* @throws FriendSuggestNotFoundException in case the underlying storage cannot delete the suggestion
|
||||||
*/
|
*/
|
||||||
public function delete(Collection\FriendSuggests $fsuggests): bool
|
public function delete(FriendSuggestsCollection $fsuggests): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$ids = $fsuggests->column('id');
|
$ids = $fsuggests->column('id');
|
||||||
|
|
|
@ -10,9 +10,9 @@ namespace Friendica\Contact\Introduction\Repository;
|
||||||
use Friendica\BaseRepository;
|
use Friendica\BaseRepository;
|
||||||
use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException;
|
use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException;
|
||||||
use Friendica\Contact\Introduction\Exception\IntroductionPersistenceException;
|
use Friendica\Contact\Introduction\Exception\IntroductionPersistenceException;
|
||||||
use Friendica\Contact\Introduction\Collection;
|
use Friendica\Contact\Introduction\Collection\Introductions as IntroductionsCollection;
|
||||||
use Friendica\Contact\Introduction\Entity;
|
use Friendica\Contact\Introduction\Entity\Introduction as IntroductionEntity;
|
||||||
use Friendica\Contact\Introduction\Factory;
|
use Friendica\Contact\Introduction\Factory\Introduction as IntroductionFactory;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Network\HTTPException\NotFoundException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
@ -20,37 +20,30 @@ use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class Introduction extends BaseRepository
|
class Introduction extends BaseRepository
|
||||||
{
|
{
|
||||||
/** @var Factory\Introduction */
|
/** @var IntroductionFactory */
|
||||||
protected $factory;
|
protected $factory;
|
||||||
|
|
||||||
protected static $table_name = 'intro';
|
protected static $table_name = 'intro';
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\Introduction $factory)
|
public function __construct(Database $database, LoggerInterface $logger, IntroductionFactory $factory)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
parent::__construct($database, $logger, $factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $condition
|
|
||||||
* @param array $params
|
|
||||||
*
|
|
||||||
* @return Entity\Introduction
|
|
||||||
*
|
|
||||||
* @throws NotFoundException the underlying exception if there's no Introduction with the given conditions
|
* @throws NotFoundException the underlying exception if there's no Introduction with the given conditions
|
||||||
*/
|
*/
|
||||||
private function selectOne(array $condition, array $params = []): Entity\Introduction
|
private function selectOne(array $condition, array $params = []): IntroductionEntity
|
||||||
{
|
{
|
||||||
return parent::_selectOne($condition, $params);
|
$fields = $this->_selectFirstRowAsArray( $condition, $params);
|
||||||
|
|
||||||
|
return $this->factory->createFromTableRow($fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a given Introduction into a DB compatible row array
|
* Converts a given Introduction into a DB compatible row array
|
||||||
*
|
|
||||||
* @param Entity\Introduction $introduction
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
protected function convertToTableRow(Entity\Introduction $introduction): array
|
protected function convertToTableRow(IntroductionEntity $introduction): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'uid' => $introduction->uid,
|
'uid' => $introduction->uid,
|
||||||
|
@ -65,14 +58,9 @@ class Introduction extends BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $id
|
|
||||||
* @param int $uid
|
|
||||||
*
|
|
||||||
* @return Entity\Introduction
|
|
||||||
*
|
|
||||||
* @throws IntroductionNotFoundException in case there is no Introduction with this id
|
* @throws IntroductionNotFoundException in case there is no Introduction with this id
|
||||||
*/
|
*/
|
||||||
public function selectOneById(int $id, int $uid): Entity\Introduction
|
public function selectOneById(int $id, int $uid): IntroductionEntity
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->selectOne(['id' => $id, 'uid' => $uid]);
|
return $this->selectOne(['id' => $id, 'uid' => $uid]);
|
||||||
|
@ -88,33 +76,30 @@ class Introduction extends BaseRepository
|
||||||
* @param int|null $min_id
|
* @param int|null $min_id
|
||||||
* @param int|null $max_id
|
* @param int|null $max_id
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
|
||||||
* @return Collection\Introductions
|
|
||||||
*/
|
*/
|
||||||
public function selectForUser(int $uid, int $min_id = null, int $max_id = null, int $limit = self::LIMIT): Collection\Introductions
|
public function selectForUser(int $uid, ?int $min_id = null, ?int $max_id = null, int $limit = self::LIMIT): IntroductionsCollection
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$BaseCollection = parent::_selectByBoundaries(
|
$BaseCollection = parent::_selectByBoundaries(
|
||||||
['`uid` = ? AND NOT `ignore`',$uid],
|
['`uid` = ? AND NOT `ignore`',$uid],
|
||||||
['order' => ['id' => 'DESC']],
|
['order' => ['id' => 'DESC']],
|
||||||
$min_id, $max_id, $limit);
|
$min_id,
|
||||||
|
$max_id,
|
||||||
|
$limit
|
||||||
|
);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw new IntroductionPersistenceException(sprintf('Cannot select Introductions for used %d', $uid), $e);
|
throw new IntroductionPersistenceException(sprintf('Cannot select Introductions for used %d', $uid), $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Collection\Introductions($BaseCollection->getArrayCopy(), $BaseCollection->getTotalCount());
|
return new IntroductionsCollection($BaseCollection->getArrayCopy(), $BaseCollection->getTotalCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the introduction for a given contact
|
* Selects the introduction for a given contact
|
||||||
*
|
*
|
||||||
* @param int $cid
|
|
||||||
*
|
|
||||||
* @return Entity\Introduction
|
|
||||||
*
|
|
||||||
* @throws IntroductionNotFoundException in case there is not Introduction for this contact
|
* @throws IntroductionNotFoundException in case there is not Introduction for this contact
|
||||||
*/
|
*/
|
||||||
public function selectForContact(int $cid): Entity\Introduction
|
public function selectForContact(int $cid): IntroductionEntity
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->selectOne(['contact-id' => $cid]);
|
return $this->selectOne(['contact-id' => $cid]);
|
||||||
|
@ -150,13 +135,9 @@ class Introduction extends BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Entity\Introduction $introduction
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @throws IntroductionPersistenceException in case the underlying storage cannot delete the Introduction
|
* @throws IntroductionPersistenceException in case the underlying storage cannot delete the Introduction
|
||||||
*/
|
*/
|
||||||
public function delete(Entity\Introduction $introduction): bool
|
public function delete(IntroductionEntity $introduction): bool
|
||||||
{
|
{
|
||||||
if (!$introduction->id) {
|
if (!$introduction->id) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -170,13 +151,9 @@ class Introduction extends BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Entity\Introduction $introduction
|
|
||||||
*
|
|
||||||
* @return Entity\Introduction
|
|
||||||
*
|
|
||||||
* @throws IntroductionPersistenceException In case the underlying storage cannot save the Introduction
|
* @throws IntroductionPersistenceException In case the underlying storage cannot save the Introduction
|
||||||
*/
|
*/
|
||||||
public function save(Entity\Introduction $introduction): Entity\Introduction
|
public function save(IntroductionEntity $introduction): IntroductionEntity
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$fields = $this->convertToTableRow($introduction);
|
$fields = $this->convertToTableRow($introduction);
|
||||||
|
|
|
@ -7,59 +7,54 @@
|
||||||
|
|
||||||
namespace Friendica\Contact\LocalRelationship\Repository;
|
namespace Friendica\Contact\LocalRelationship\Repository;
|
||||||
|
|
||||||
use Friendica\Contact\LocalRelationship\Entity;
|
use Exception;
|
||||||
use Friendica\Contact\LocalRelationship\Exception;
|
use Friendica\BaseRepository;
|
||||||
use Friendica\Contact\LocalRelationship\Factory;
|
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship as LocalRelationshipEntity;
|
||||||
|
use Friendica\Contact\LocalRelationship\Exception\LocalRelationshipPersistenceException;
|
||||||
|
use Friendica\Contact\LocalRelationship\Factory\LocalRelationship as LocalRelationshipFactory;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class LocalRelationship extends \Friendica\BaseRepository
|
class LocalRelationship extends BaseRepository
|
||||||
{
|
{
|
||||||
protected static $table_name = 'user-contact';
|
protected static $table_name = 'user-contact';
|
||||||
|
|
||||||
/** @var Factory\LocalRelationship */
|
/** @var LocalRelationshipFactory */
|
||||||
protected $factory;
|
protected $factory;
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\LocalRelationship $factory)
|
public function __construct(Database $database, LoggerInterface $logger, LocalRelationshipFactory $factory)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
parent::__construct($database, $logger, $factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $uid
|
* @throws NotFoundException
|
||||||
* @param int $cid
|
|
||||||
* @return Entity\LocalRelationship
|
|
||||||
* @throws HTTPException\NotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function selectForUserContact(int $uid, int $cid): Entity\LocalRelationship
|
public function selectForUserContact(int $uid, int $cid): LocalRelationshipEntity
|
||||||
{
|
{
|
||||||
return $this->_selectOne(['uid' => $uid, 'cid' => $cid]);
|
$fields = $this->_selectFirstRowAsArray(['uid' => $uid, 'cid' => $cid]);
|
||||||
|
|
||||||
|
return $this->factory->createFromTableRow($fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the existing local relationship between a user and a public contact or a default
|
* Returns the existing local relationship between a user and a public contact or a default
|
||||||
* relationship if it doesn't.
|
* relationship if it doesn't.
|
||||||
*
|
*
|
||||||
* @param int $uid
|
* @throws NotFoundException
|
||||||
* @param int $cid
|
|
||||||
* @return Entity\LocalRelationship
|
|
||||||
* @throws HTTPException\NotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function getForUserContact(int $uid, int $cid): Entity\LocalRelationship
|
public function getForUserContact(int $uid, int $cid): LocalRelationshipEntity
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->selectForUserContact($uid, $cid);
|
return $this->selectForUserContact($uid, $cid);
|
||||||
} catch (HTTPException\NotFoundException $e) {
|
} catch (NotFoundException $e) {
|
||||||
return $this->factory->createFromTableRow(['uid' => $uid, 'cid' => $cid]);
|
return $this->factory->createFromTableRow(['uid' => $uid, 'cid' => $cid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $uid
|
* @throws Exception
|
||||||
* @param int $cid
|
|
||||||
* @return bool
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
*/
|
||||||
public function existsForUserContact(int $uid, int $cid): bool
|
public function existsForUserContact(int $uid, int $cid): bool
|
||||||
{
|
{
|
||||||
|
@ -68,12 +63,8 @@ class LocalRelationship extends \Friendica\BaseRepository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a given local relationship into a DB compatible row array
|
* Converts a given local relationship into a DB compatible row array
|
||||||
*
|
|
||||||
* @param Entity\LocalRelationship $localRelationship
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
protected function convertToTableRow(Entity\LocalRelationship $localRelationship): array
|
protected function convertToTableRow(LocalRelationshipEntity $localRelationship): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'uid' => $localRelationship->userId,
|
'uid' => $localRelationship->userId,
|
||||||
|
@ -97,13 +88,9 @@ class LocalRelationship extends \Friendica\BaseRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Entity\LocalRelationship $localRelationship
|
* @throws LocalRelationshipPersistenceException In case the underlying storage cannot save the LocalRelationship
|
||||||
*
|
|
||||||
* @return Entity\LocalRelationship
|
|
||||||
*
|
|
||||||
* @throws Exception\LocalRelationshipPersistenceException In case the underlying storage cannot save the LocalRelationship
|
|
||||||
*/
|
*/
|
||||||
public function save(Entity\LocalRelationship $localRelationship): Entity\LocalRelationship
|
public function save(LocalRelationshipEntity $localRelationship): LocalRelationshipEntity
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$fields = $this->convertToTableRow($localRelationship);
|
$fields = $this->convertToTableRow($localRelationship);
|
||||||
|
@ -111,8 +98,8 @@ class LocalRelationship extends \Friendica\BaseRepository
|
||||||
$this->db->insert(self::$table_name, $fields, Database::INSERT_UPDATE);
|
$this->db->insert(self::$table_name, $fields, Database::INSERT_UPDATE);
|
||||||
|
|
||||||
return $localRelationship;
|
return $localRelationship;
|
||||||
} catch (\Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
throw new Exception\LocalRelationshipPersistenceException(sprintf('Cannot insert/update the local relationship %d for user %d', $localRelationship->contactId, $localRelationship->userId), $exception);
|
throw new LocalRelationshipPersistenceException(sprintf('Cannot insert/update the local relationship %d for user %d', $localRelationship->contactId, $localRelationship->userId), $exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,10 @@ class Conversation
|
||||||
$phrase = $this->l10n->tt('<button type="button" %2$s>%1$d person</button> likes this', '<button type="button" %2$s>%1$d people</button> like this', $total, $spanatts);
|
$phrase = $this->l10n->tt('<button type="button" %2$s>%1$d person</button> likes this', '<button type="button" %2$s>%1$d people</button> like this', $total, $spanatts);
|
||||||
break;
|
break;
|
||||||
case 'dislike':
|
case 'dislike':
|
||||||
$phrase = $this->l10n->tt('<button type="button" %2$s>%1$d person</button> doesn\'t like this', '<button type="button" %2$s>%1$d peiple</button> don\'t like this', $total, $spanatts);
|
$dislike_translation_plural = '<button type="button" %2$s>%1$d people</button> don\'t like this';
|
||||||
|
// @deprecated 2025.04 this translation is scheduled for removal as a new translation has been added without the typo
|
||||||
|
$dislike_translation_plural = '<button type="button" %2$s>%1$d peiple</button> don\'t like this';
|
||||||
|
$phrase = $this->l10n->tt('<button type="button" %2$s>%1$d person</button> doesn\'t like this', $dislike_translation_plural, $total, $spanatts);
|
||||||
break;
|
break;
|
||||||
case 'attendyes':
|
case 'attendyes':
|
||||||
$phrase = $this->l10n->tt('<button type="button" %2$s>%1$d person</button> attends', '<button type="button" %2$s>%1$d people</button> attend', $total, $spanatts);
|
$phrase = $this->l10n->tt('<button type="button" %2$s>%1$d person</button> attends', '<button type="button" %2$s>%1$d people</button> attend', $total, $spanatts);
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
|
|
||||||
namespace Friendica\Content\Conversation\Repository;
|
namespace Friendica\Content\Conversation\Repository;
|
||||||
|
|
||||||
use Friendica\BaseCollection;
|
use Friendica\BaseRepository;
|
||||||
use Friendica\Content\Conversation\Collection\UserDefinedChannels;
|
use Friendica\Content\Conversation\Collection\UserDefinedChannels;
|
||||||
use Friendica\Content\Conversation\Entity;
|
use Friendica\Content\Conversation\Entity\UserDefinedChannel as UserDefinedChannelEntity;
|
||||||
use Friendica\Content\Conversation\Factory;
|
use Friendica\Content\Conversation\Factory\UserDefinedChannel as UserDefinedChannelFactory;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
|
@ -21,13 +21,16 @@ use Friendica\Model\User;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class UserDefinedChannel extends \Friendica\BaseRepository
|
class UserDefinedChannel extends BaseRepository
|
||||||
{
|
{
|
||||||
protected static $table_name = 'channel';
|
protected static $table_name = 'channel';
|
||||||
|
|
||||||
|
/** @var UserDefinedChannelFactory */
|
||||||
|
protected $factory;
|
||||||
|
|
||||||
private IManageConfigValues $config;
|
private IManageConfigValues $config;
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\UserDefinedChannel $factory, IManageConfigValues $config)
|
public function __construct(Database $database, LoggerInterface $logger, UserDefinedChannelFactory $factory, IManageConfigValues $config)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
parent::__construct($database, $logger, $factory);
|
||||||
|
|
||||||
|
@ -40,7 +43,7 @@ class UserDefinedChannel extends \Friendica\BaseRepository
|
||||||
* @return UserDefinedChannels
|
* @return UserDefinedChannels
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function _select(array $condition, array $params = []): BaseCollection
|
protected function _select(array $condition, array $params = []): UserDefinedChannels
|
||||||
{
|
{
|
||||||
$rows = $this->db->selectToArray(static::$table_name, [], $condition, $params);
|
$rows = $this->db->selectToArray(static::$table_name, [], $condition, $params);
|
||||||
|
|
||||||
|
@ -62,12 +65,13 @@ class UserDefinedChannel extends \Friendica\BaseRepository
|
||||||
*
|
*
|
||||||
* @param int $id The id of the user defined channel
|
* @param int $id The id of the user defined channel
|
||||||
* @param int $uid The user that this channel belongs to. (Not part of the primary key)
|
* @param int $uid The user that this channel belongs to. (Not part of the primary key)
|
||||||
* @return Entity\UserDefinedChannel
|
|
||||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||||
*/
|
*/
|
||||||
public function selectById(int $id, int $uid): Entity\UserDefinedChannel
|
public function selectById(int $id, int $uid): UserDefinedChannelEntity
|
||||||
{
|
{
|
||||||
return $this->_selectOne(['id' => $id, 'uid' => $uid]);
|
$fields = $this->_selectFirstRowAsArray(['id' => $id, 'uid' => $uid]);
|
||||||
|
|
||||||
|
return $this->factory->createFromTableRow($fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,7 +110,7 @@ class UserDefinedChannel extends \Friendica\BaseRepository
|
||||||
return $this->_select(['uid' => $uid]);
|
return $this->_select(['uid' => $uid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(Entity\UserDefinedChannel $Channel): Entity\UserDefinedChannel
|
public function save(UserDefinedChannelEntity $Channel): UserDefinedChannelEntity
|
||||||
{
|
{
|
||||||
$fields = [
|
$fields = [
|
||||||
'label' => $Channel->label,
|
'label' => $Channel->label,
|
||||||
|
@ -210,7 +214,7 @@ class UserDefinedChannel extends \Friendica\BaseRepository
|
||||||
$disposableFullTextSearch = new DisposableFullTextSearch($this->db, $searchtext);
|
$disposableFullTextSearch = new DisposableFullTextSearch($this->db, $searchtext);
|
||||||
|
|
||||||
$filteredChannels = $this->select(['uid' => array_column($users, 'uid'), 'publish' => true, 'valid' => true])->filter(
|
$filteredChannels = $this->select(['uid' => array_column($users, 'uid'), 'publish' => true, 'valid' => true])->filter(
|
||||||
function (Entity\UserDefinedChannel $channel) use ($owner_id, $reshare_id, $language, $tags, $media_type, $disposableFullTextSearch, $searchtext) {
|
function (UserDefinedChannelEntity $channel) use ($owner_id, $reshare_id, $language, $tags, $media_type, $disposableFullTextSearch, $searchtext) {
|
||||||
static $uids = [];
|
static $uids = [];
|
||||||
|
|
||||||
// Filter out channels from already picked users
|
// Filter out channels from already picked users
|
||||||
|
|
|
@ -1011,10 +1011,16 @@ class Item
|
||||||
Tag::createImplicitMentions($post['uri-id'], $post['thr-parent-id']);
|
Tag::createImplicitMentions($post['uri-id'], $post['thr-parent-id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$post = $this->eventDispatcher->dispatch(
|
$hook_data = [
|
||||||
new ArrayFilterEvent(ArrayFilterEvent::POST_LOCAL_END, $post)
|
'item' => $post,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::INSERT_POST_LOCAL_END, $hook_data)
|
||||||
)->getArray();
|
)->getArray();
|
||||||
|
|
||||||
|
$post = $hook_data['item'] ?? $post;
|
||||||
|
|
||||||
$author = DBA::selectFirst('contact', ['thumb'], ['uid' => $post['uid'], 'self' => true]);
|
$author = DBA::selectFirst('contact', ['thumb'], ['uid' => $post['uid'], 'self' => true]);
|
||||||
|
|
||||||
foreach ($recipients as $recipient) {
|
foreach ($recipients as $recipient) {
|
||||||
|
|
|
@ -92,6 +92,7 @@ class PageInfo
|
||||||
{
|
{
|
||||||
$eventDispatcher = DI::eventDispatcher();
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
/** @var array<string,mixed> */
|
||||||
$data = $eventDispatcher->dispatch(
|
$data = $eventDispatcher->dispatch(
|
||||||
new ArrayFilterEvent(ArrayFilterEvent::PAGE_INFO, $data),
|
new ArrayFilterEvent(ArrayFilterEvent::PAGE_INFO, $data),
|
||||||
)->getArray();
|
)->getArray();
|
||||||
|
|
|
@ -13,7 +13,6 @@ use Friendica\Util\Images;
|
||||||
use Friendica\Util\Proxy;
|
use Friendica\Util\Proxy;
|
||||||
use Psr\Http\Message\UriInterface;
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property-read int $id
|
* @property-read int $id
|
||||||
* @property-read int $uriId
|
* @property-read int $uriId
|
||||||
|
@ -122,8 +121,7 @@ class PostMedia extends BaseEntity
|
||||||
?UriInterface $publisherImage = null,
|
?UriInterface $publisherImage = null,
|
||||||
?string $blurhash = null,
|
?string $blurhash = null,
|
||||||
int $id = null
|
int $id = null
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
$this->uriId = $uriId;
|
$this->uriId = $uriId;
|
||||||
$this->url = $url;
|
$this->url = $url;
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
|
@ -210,7 +208,7 @@ class PostMedia extends BaseEntity
|
||||||
*
|
*
|
||||||
* @param \GuzzleHttp\Psr7\Uri $preview
|
* @param \GuzzleHttp\Psr7\Uri $preview
|
||||||
* @param string $size
|
* @param string $size
|
||||||
* @return $this
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function withPreview(\GuzzleHttp\Psr7\Uri $preview, string $size = ''): self
|
public function withPreview(\GuzzleHttp\Psr7\Uri $preview, string $size = ''): self
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,8 +9,9 @@ namespace Friendica\Content\Post\Factory;
|
||||||
|
|
||||||
use Friendica\BaseFactory;
|
use Friendica\BaseFactory;
|
||||||
use Friendica\Capabilities\ICanCreateFromTableRow;
|
use Friendica\Capabilities\ICanCreateFromTableRow;
|
||||||
use Friendica\Content\Post\Entity;
|
use Friendica\Content\Post\Entity\PostMedia as PostMediaEntity;
|
||||||
use Friendica\Network;
|
use Friendica\Network\Entity\MimeType as MimeTypeEntity;
|
||||||
|
use Friendica\Network\Factory\MimeType as MimeTypeFactory;
|
||||||
use Friendica\Util\Network as UtilNetwork;
|
use Friendica\Util\Network as UtilNetwork;
|
||||||
use GuzzleHttp\Psr7\Uri;
|
use GuzzleHttp\Psr7\Uri;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
@ -18,10 +19,10 @@ use stdClass;
|
||||||
|
|
||||||
class PostMedia extends BaseFactory implements ICanCreateFromTableRow
|
class PostMedia extends BaseFactory implements ICanCreateFromTableRow
|
||||||
{
|
{
|
||||||
/** @var Network\Factory\MimeType */
|
/** @var MimeTypeFactory */
|
||||||
private $mimeTypeFactory;
|
private $mimeTypeFactory;
|
||||||
|
|
||||||
public function __construct(Network\Factory\MimeType $mimeTypeFactory, LoggerInterface $logger)
|
public function __construct(MimeTypeFactory $mimeTypeFactory, LoggerInterface $logger)
|
||||||
{
|
{
|
||||||
parent::__construct($logger);
|
parent::__construct($logger);
|
||||||
|
|
||||||
|
@ -31,9 +32,9 @@ class PostMedia extends BaseFactory implements ICanCreateFromTableRow
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function createFromTableRow(array $row)
|
public function createFromTableRow(array $row): PostMediaEntity
|
||||||
{
|
{
|
||||||
return new Entity\PostMedia(
|
return new PostMediaEntity(
|
||||||
$row['uri-id'],
|
$row['uri-id'],
|
||||||
UtilNetwork::createUriFromString($row['url']),
|
UtilNetwork::createUriFromString($row['url']),
|
||||||
$row['type'],
|
$row['type'],
|
||||||
|
@ -58,13 +59,13 @@ class PostMedia extends BaseFactory implements ICanCreateFromTableRow
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createFromBlueskyImageEmbed(int $uriId, stdClass $image): Entity\PostMedia
|
public function createFromBlueskyImageEmbed(int $uriId, stdClass $image): PostMediaEntity
|
||||||
{
|
{
|
||||||
return new Entity\PostMedia(
|
return new PostMediaEntity(
|
||||||
$uriId,
|
$uriId,
|
||||||
new Uri($image->fullsize),
|
new Uri($image->fullsize),
|
||||||
Entity\PostMedia::TYPE_IMAGE,
|
PostMediaEntity::TYPE_IMAGE,
|
||||||
new Network\Entity\MimeType('unkn', 'unkn'),
|
new MimeTypeEntity('unkn', 'unkn'),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
@ -77,13 +78,13 @@ class PostMedia extends BaseFactory implements ICanCreateFromTableRow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function createFromBlueskyExternalEmbed(int $uriId, stdClass $external): Entity\PostMedia
|
public function createFromBlueskyExternalEmbed(int $uriId, stdClass $external): PostMediaEntity
|
||||||
{
|
{
|
||||||
return new Entity\PostMedia(
|
return new PostMediaEntity(
|
||||||
$uriId,
|
$uriId,
|
||||||
new Uri($external->uri),
|
new Uri($external->uri),
|
||||||
Entity\PostMedia::TYPE_HTML,
|
PostMediaEntity::TYPE_HTML,
|
||||||
new Network\Entity\MimeType('text', 'html'),
|
new MimeTypeEntity('text', 'html'),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -7,11 +7,10 @@
|
||||||
|
|
||||||
namespace Friendica\Content\Post\Repository;
|
namespace Friendica\Content\Post\Repository;
|
||||||
|
|
||||||
use Friendica\BaseCollection;
|
|
||||||
use Friendica\BaseRepository;
|
use Friendica\BaseRepository;
|
||||||
use Friendica\Content\Post\Collection;
|
use Friendica\Content\Post\Collection\PostMedias as PostMediasCollection;
|
||||||
use Friendica\Content\Post\Entity;
|
use Friendica\Content\Post\Entity\PostMedia as PostMediaEntity;
|
||||||
use Friendica\Content\Post\Factory;
|
use Friendica\Content\Post\Factory\PostMedia as PostMediaFactory;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
|
@ -21,16 +20,19 @@ class PostMedia extends BaseRepository
|
||||||
{
|
{
|
||||||
protected static $table_name = 'post-media';
|
protected static $table_name = 'post-media';
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\PostMedia $factory)
|
/** @var PostMediaFactory */
|
||||||
|
protected $factory;
|
||||||
|
|
||||||
|
public function __construct(Database $database, LoggerInterface $logger, PostMediaFactory $factory)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
parent::__construct($database, $logger, $factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _select(array $condition, array $params = []): BaseCollection
|
protected function _select(array $condition, array $params = []): PostMediasCollection
|
||||||
{
|
{
|
||||||
$rows = $this->db->selectToArray(static::$table_name, [], $condition, $params);
|
$rows = $this->db->selectToArray(static::$table_name, [], $condition, $params);
|
||||||
|
|
||||||
$Entities = new Collection\PostMedias();
|
$Entities = new PostMediasCollection();
|
||||||
foreach ($rows as $fields) {
|
foreach ($rows as $fields) {
|
||||||
try {
|
try {
|
||||||
$Entities[] = $this->factory->createFromTableRow($fields);
|
$Entities[] = $this->factory->createFromTableRow($fields);
|
||||||
|
@ -42,17 +44,19 @@ class PostMedia extends BaseRepository
|
||||||
return $Entities;
|
return $Entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function selectOneById(int $postMediaId): Entity\PostMedia
|
public function selectOneById(int $postMediaId): PostMediaEntity
|
||||||
{
|
{
|
||||||
return $this->_selectOne(['id' => $postMediaId]);
|
$fields = $this->_selectFirstRowAsArray(['id' => $postMediaId]);
|
||||||
|
|
||||||
|
return $this->factory->createFromTableRow($fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function selectByUriId(int $uriId): Collection\PostMedias
|
public function selectByUriId(int $uriId): PostMediasCollection
|
||||||
{
|
{
|
||||||
return $this->_select(["`uri-id` = ? AND `type` != ?", $uriId, Post\Media::UNKNOWN]);
|
return $this->_select(["`uri-id` = ? AND `type` != ?", $uriId, Post\Media::UNKNOWN]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(Entity\PostMedia $PostMedia): Entity\PostMedia
|
public function save(PostMediaEntity $PostMedia): PostMediaEntity
|
||||||
{
|
{
|
||||||
$fields = [
|
$fields = [
|
||||||
'uri-id' => $PostMedia->uriId,
|
'uri-id' => $PostMedia->uriId,
|
||||||
|
@ -97,14 +101,14 @@ class PostMedia extends BaseRepository
|
||||||
* @param int $uri_id URI id
|
* @param int $uri_id URI id
|
||||||
* @param array $links list of links that shouldn't be added
|
* @param array $links list of links that shouldn't be added
|
||||||
* @param bool $has_media
|
* @param bool $has_media
|
||||||
* @return Collection\PostMedias[] Three collections in "visual", "link" and "additional" keys
|
* @return PostMediasCollection[] Three collections in "visual", "link" and "additional" keys
|
||||||
*/
|
*/
|
||||||
public function splitAttachments(int $uri_id, array $links = [], bool $has_media = true): array
|
public function splitAttachments(int $uri_id, array $links = [], bool $has_media = true): array
|
||||||
{
|
{
|
||||||
$attachments = [
|
$attachments = [
|
||||||
'visual' => new Collection\PostMedias(),
|
'visual' => new PostMediasCollection(),
|
||||||
'link' => new Collection\PostMedias(),
|
'link' => new PostMediasCollection(),
|
||||||
'additional' => new Collection\PostMedias(),
|
'additional' => new PostMediasCollection(),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!$has_media) {
|
if (!$has_media) {
|
||||||
|
@ -137,7 +141,7 @@ class PostMedia extends BaseRepository
|
||||||
|
|
||||||
// Currently these two types are ignored here.
|
// Currently these two types are ignored here.
|
||||||
// Posts are added differently and contacts are not displayed as attachments.
|
// Posts are added differently and contacts are not displayed as attachments.
|
||||||
if (in_array($PostMedia->type, [Entity\PostMedia::TYPE_ACCOUNT, Entity\PostMedia::TYPE_ACTIVITY])) {
|
if (in_array($PostMedia->type, [PostMediaEntity::TYPE_ACCOUNT, PostMediaEntity::TYPE_ACTIVITY])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,17 +152,17 @@ class PostMedia extends BaseRepository
|
||||||
//$PostMedia->filetype = $filetype;
|
//$PostMedia->filetype = $filetype;
|
||||||
//$PostMedia->subtype = $subtype;
|
//$PostMedia->subtype = $subtype;
|
||||||
|
|
||||||
if ($PostMedia->type == Entity\PostMedia::TYPE_HTML || ($PostMedia->mimetype->type == 'text' && $PostMedia->mimetype->subtype == 'html')) {
|
if ($PostMedia->type == PostMediaEntity::TYPE_HTML || ($PostMedia->mimetype->type == 'text' && $PostMedia->mimetype->subtype == 'html')) {
|
||||||
$attachments['link'][] = $PostMedia;
|
$attachments['link'][] = $PostMedia;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
in_array($PostMedia->type, [Entity\PostMedia::TYPE_AUDIO, Entity\PostMedia::TYPE_IMAGE, Entity\PostMedia::TYPE_HLS]) ||
|
in_array($PostMedia->type, [PostMediaEntity::TYPE_AUDIO, PostMediaEntity::TYPE_IMAGE, PostMediaEntity::TYPE_HLS]) ||
|
||||||
in_array($PostMedia->mimetype->type, ['audio', 'image'])
|
in_array($PostMedia->mimetype->type, ['audio', 'image'])
|
||||||
) {
|
) {
|
||||||
$attachments['visual'][] = $PostMedia;
|
$attachments['visual'][] = $PostMedia;
|
||||||
} elseif (($PostMedia->type == Entity\PostMedia::TYPE_VIDEO) || ($PostMedia->mimetype->type == 'video')) {
|
} elseif (($PostMedia->type == PostMediaEntity::TYPE_VIDEO) || ($PostMedia->mimetype->type == 'video')) {
|
||||||
if (!empty($PostMedia->height)) {
|
if (!empty($PostMedia->height)) {
|
||||||
// Peertube videos are delivered in many different resolutions. We pick a moderate one.
|
// Peertube videos are delivered in many different resolutions. We pick a moderate one.
|
||||||
// Since only Peertube provides a "height" parameter, this wouldn't be executed
|
// Since only Peertube provides a "height" parameter, this wouldn't be executed
|
||||||
|
|
|
@ -913,13 +913,18 @@ class BBCode
|
||||||
default:
|
default:
|
||||||
$text = ($is_quote_share ? "\n" : '');
|
$text = ($is_quote_share ? "\n" : '');
|
||||||
|
|
||||||
$contact = Contact::getByURL($attributes['profile'], false, ['network']);
|
$contact = Contact::getByURL($attributes['profile'], false, ['network', 'url', 'alias']);
|
||||||
$network = $contact['network'] ?? Protocol::PHANTOM;
|
$network = $contact['network'] ?? Protocol::PHANTOM;
|
||||||
|
if (!empty($contact)) {
|
||||||
|
$profile = Contact::getProfileLink($contact);
|
||||||
|
} else {
|
||||||
|
$profile = $attributes['profile'];
|
||||||
|
}
|
||||||
|
|
||||||
$gsid = ContactSelector::getServerIdForProfile($attributes['profile']);
|
$gsid = ContactSelector::getServerIdForProfile($attributes['profile']);
|
||||||
$tpl = Renderer::getMarkupTemplate('shared_content.tpl');
|
$tpl = Renderer::getMarkupTemplate('shared_content.tpl');
|
||||||
$text .= self::SHARED_ANCHOR . Renderer::replaceMacros($tpl, [
|
$text .= self::SHARED_ANCHOR . Renderer::replaceMacros($tpl, [
|
||||||
'$profile' => $attributes['profile'],
|
'$profile' => $profile,
|
||||||
'$avatar' => $attributes['avatar'],
|
'$avatar' => $attributes['avatar'],
|
||||||
'$author' => $attributes['author'],
|
'$author' => $attributes['author'],
|
||||||
'$link' => $attributes['link'],
|
'$link' => $attributes['link'],
|
||||||
|
@ -1205,13 +1210,13 @@ class BBCode
|
||||||
*/
|
*/
|
||||||
private static function normalizeVideoLinks(string $text): string
|
private static function normalizeVideoLinks(string $text): string
|
||||||
{
|
{
|
||||||
$text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
|
$text = preg_replace("/\[youtube\]https?:\/\/(www\.)?youtube\.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$2[/youtube]', $text);
|
||||||
$text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
|
$text = preg_replace("/\[youtube\]https?:\/\/(www\.)?youtube\.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$2[/youtube]', $text);
|
||||||
$text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/shorts\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
|
$text = preg_replace("/\[youtube\]https?:\/\/(www\.)?youtube\.com\/shorts\/(.*?)\[\/youtube\]/ism", '[youtube]$2[/youtube]', $text);
|
||||||
$text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
|
$text = preg_replace("/\[youtube\]https?:\/\/youtu\.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
|
||||||
|
|
||||||
$text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
|
$text = preg_replace("/\[vimeo\]https?:\/\/player\.vimeo\.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
|
||||||
$text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
|
$text = preg_replace("/\[vimeo\]https?:\/\/vimeo\.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
|
||||||
|
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
|
@ -1984,12 +1989,25 @@ class BBCode
|
||||||
'<a href="$2" class="mention hashtag" rel="tag">$1<span>$3</span></a>',
|
'<a href="$2" class="mention hashtag" rel="tag">$1<span>$3</span></a>',
|
||||||
$text
|
$text
|
||||||
);
|
);
|
||||||
} elseif (in_array($simple_html, [self::INTERNAL, self::EXTERNAL, self::TWITTER_API])) {
|
} elseif (in_array($simple_html, [self::EXTERNAL, self::TWITTER_API])) {
|
||||||
$text = preg_replace(
|
$text = preg_replace(
|
||||||
"/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
|
"/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
|
||||||
'<bdi>$1<a href="$2" class="userinfo mention" title="$3">$3</a></bdi>',
|
'<bdi>$1<a href="$2" class="userinfo mention" title="$3">$3</a></bdi>',
|
||||||
$text
|
$text
|
||||||
);
|
);
|
||||||
|
} elseif ($simple_html == self::INTERNAL) {
|
||||||
|
if (preg_match_all("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", $text, $matches, PREG_SET_ORDER)) {
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$contact = Contact::getByURL($match[2], false, ['network', 'url', 'alias']);
|
||||||
|
if (!empty($contact)) {
|
||||||
|
$url = Contact::getProfileLink($contact);
|
||||||
|
} else {
|
||||||
|
$url = $match[2];
|
||||||
|
}
|
||||||
|
$text = str_replace($match[0], '<bdi>' . $match[1] . '<a href="' . $url . '" class="userinfo mention" title="' . $match[3] . '">' . $match[3] . '</a></bdi>', $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
} elseif ($simple_html == self::MASTODON_API) {
|
} elseif ($simple_html == self::MASTODON_API) {
|
||||||
$text = preg_replace(
|
$text = preg_replace(
|
||||||
"/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
|
"/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
|
||||||
|
|
|
@ -121,11 +121,13 @@ class Markdown
|
||||||
$s = str_replace('♲', html_entity_decode('♲', ENT_QUOTES, 'UTF-8'), $s);
|
$s = str_replace('♲', html_entity_decode('♲', ENT_QUOTES, 'UTF-8'), $s);
|
||||||
|
|
||||||
//$s = preg_replace("/([^\]\=]|^)(https?\:\/\/)(vimeo|youtu|www\.youtube|soundcloud)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2$3$4]$2$3$4[/url]',$s);
|
//$s = preg_replace("/([^\]\=]|^)(https?\:\/\/)(vimeo|youtu|www\.youtube|soundcloud)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2$3$4]$2$3$4[/url]',$s);
|
||||||
$s = BBCode::pregReplaceInTag('/\[url\=?(.*?)\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/url\]/ism', '[youtube]$2[/youtube]', 'url', $s);
|
$s = BBCode::pregReplaceInTag('/\[url\=?(.*?)\]https?:\/\/www\.youtube\.com\/watch\?v\=(.*?)\[\/url\]/ism', '[youtube]$2[/youtube]', 'url', $s);
|
||||||
$s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/www.youtube.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism', '[youtube]$1[/youtube]', 'url', $s);
|
$s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/(www\.)?youtube\.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism', '[youtube]$2[/youtube]', 'url', $s);
|
||||||
$s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/www.youtube.com\/shorts\/(.*?)\].*?\[\/url\]/ism', '[youtube]$1[/youtube]', 'url', $s);
|
$s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/(www\.)?youtube\.com\/embed\/(.*?)\].*?\[\/url\]/ism', '[youtube]$2[/youtube]', 'url', $s);
|
||||||
$s = BBCode::pregReplaceInTag('/\[url\=?(.*?)\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/url\]/ism', '[vimeo]$2[/vimeo]', 'url', $s);
|
$s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/(www\.)?youtube\.com\/shorts\/(.*?)\].*?\[\/url\]/ism', '[youtube]$2[/youtube]', 'url', $s);
|
||||||
$s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/vimeo.com\/([0-9]+)\](.*?)\[\/url\]/ism', '[vimeo]$1[/vimeo]', 'url', $s);
|
$s = BBCode::pregReplaceInTag('/\[url\=?(.*?)\]https?:\/\/vimeo\.com\/([0-9]+)(.*?)\[\/url\]/ism', '[vimeo]$2[/vimeo]', 'url', $s);
|
||||||
|
$s = BBCode::pregReplaceInTag('/\[url\=?(.*?)\]https?:\/\/player\.vimeo\.com\/video\/([0-9]+)(.*?)\[\/url\]/ism', '[vimeo]$2[/vimeo]', 'url', $s);
|
||||||
|
$s = BBCode::pregReplaceInTag('/\[url\=https?:\/\/vimeo\.com\/([0-9]+)\](.*?)\[\/url\]/ism', '[vimeo]$1[/vimeo]', 'url', $s);
|
||||||
|
|
||||||
// remove duplicate adjacent code tags
|
// remove duplicate adjacent code tags
|
||||||
$s = preg_replace('/(\[code\])+(.*?)(\[\/code\])+/ism', '[code]$2[/code]', $s);
|
$s = preg_replace('/(\[code\])+(.*?)(\[\/code\])+/ism', '[code]$2[/code]', $s);
|
||||||
|
|
|
@ -38,6 +38,8 @@ class TrendingTags
|
||||||
$o = Renderer::replaceMacros($tpl, [
|
$o = Renderer::replaceMacros($tpl, [
|
||||||
'$title' => DI::l10n()->tt('Trending Tags (last %d hour)', 'Trending Tags (last %d hours)', $period),
|
'$title' => DI::l10n()->tt('Trending Tags (last %d hour)', 'Trending Tags (last %d hours)', $period),
|
||||||
'$more' => DI::l10n()->t('More Trending Tags'),
|
'$more' => DI::l10n()->t('More Trending Tags'),
|
||||||
|
'$showmore' => DI::l10n()->t('Show More'),
|
||||||
|
'$showless' => DI::l10n()->t('Show Less'),
|
||||||
'$tags' => $tags,
|
'$tags' => $tags,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Core;
|
namespace Friendica\Core;
|
||||||
|
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\Contact;
|
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,12 +266,6 @@ class Addon
|
||||||
if ($type == "author" || $type == "maintainer") {
|
if ($type == "author" || $type == "maintainer") {
|
||||||
$r = preg_match("|([^<]+)<([^>]+)>|", $v, $m);
|
$r = preg_match("|([^<]+)<([^>]+)>|", $v, $m);
|
||||||
if ($r) {
|
if ($r) {
|
||||||
if (!empty($m[2]) && empty(parse_url($m[2], PHP_URL_SCHEME))) {
|
|
||||||
$contact = Contact::getByURL($m[2], false);
|
|
||||||
if (!empty($contact['url'])) {
|
|
||||||
$m[2] = $contact['url'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$info[$type][] = ['name' => $m[1], 'link' => $m[2]];
|
$info[$type][] = ['name' => $m[1], 'link' => $m[2]];
|
||||||
} else {
|
} else {
|
||||||
$info[$type][] = ['name' => $v];
|
$info[$type][] = ['name' => $v];
|
||||||
|
|
|
@ -53,4 +53,11 @@ interface ICanCacheInMemory extends ICanCache
|
||||||
* @throws CachePersistenceException In case the underlying cache driver has errors during persistence
|
* @throws CachePersistenceException In case the underlying cache driver has errors during persistence
|
||||||
*/
|
*/
|
||||||
public function compareDelete(string $key, $value): bool;
|
public function compareDelete(string $key, $value): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns some basic statistics of the used Cache instance
|
||||||
|
*
|
||||||
|
* @return array Returns an associative array of statistics
|
||||||
|
*/
|
||||||
|
public function getStats(): array;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,9 @@ use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
|
||||||
*/
|
*/
|
||||||
class APCuCache extends AbstractCache implements ICanCacheInMemory
|
class APCuCache extends AbstractCache implements ICanCacheInMemory
|
||||||
{
|
{
|
||||||
const NAME = 'apcu';
|
|
||||||
|
|
||||||
use CompareSetTrait;
|
use CompareSetTrait;
|
||||||
use CompareDeleteTrait;
|
use CompareDeleteTrait;
|
||||||
|
const NAME = 'apcu';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws InvalidCacheDriverException
|
* @throws InvalidCacheDriverException
|
||||||
|
@ -147,4 +146,19 @@ class APCuCache extends AbstractCache implements ICanCacheInMemory
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public function getStats(): array
|
||||||
|
{
|
||||||
|
$apcu = apcu_cache_info();
|
||||||
|
$sma = apcu_sma_info();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'entries' => $apcu['num_entries'] ?? null,
|
||||||
|
'used_memory' => $apcu['mem_size'] ?? null,
|
||||||
|
'hits' => $apcu['num_hits'] ?? null,
|
||||||
|
'misses' => $apcu['num_misses'] ?? null,
|
||||||
|
'avail_mem' => $sma['avail_mem'] ?? null,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,8 @@ use Friendica\Core\Cache\Enum;
|
||||||
*/
|
*/
|
||||||
class ArrayCache extends AbstractCache implements ICanCacheInMemory
|
class ArrayCache extends AbstractCache implements ICanCacheInMemory
|
||||||
{
|
{
|
||||||
const NAME = 'array';
|
|
||||||
|
|
||||||
use CompareDeleteTrait;
|
use CompareDeleteTrait;
|
||||||
|
const NAME = 'array';
|
||||||
|
|
||||||
/** @var array Array with the cached data */
|
/** @var array Array with the cached data */
|
||||||
protected $cachedData = [];
|
protected $cachedData = [];
|
||||||
|
@ -96,4 +95,10 @@ class ArrayCache extends AbstractCache implements ICanCacheInMemory
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public function getStats(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@ use Memcache;
|
||||||
*/
|
*/
|
||||||
class MemcacheCache extends AbstractCache implements ICanCacheInMemory
|
class MemcacheCache extends AbstractCache implements ICanCacheInMemory
|
||||||
{
|
{
|
||||||
const NAME = 'memcache';
|
|
||||||
|
|
||||||
use CompareSetTrait;
|
use CompareSetTrait;
|
||||||
use CompareDeleteTrait;
|
use CompareDeleteTrait;
|
||||||
use MemcacheCommandTrait;
|
use MemcacheCommandTrait;
|
||||||
|
const NAME = 'memcache';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Memcache
|
* @var Memcache
|
||||||
|
@ -156,4 +155,21 @@ class MemcacheCache extends AbstractCache implements ICanCacheInMemory
|
||||||
$cacheKey = $this->getCacheKey($key);
|
$cacheKey = $this->getCacheKey($key);
|
||||||
return $this->memcache->add($cacheKey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
|
return $this->memcache->add($cacheKey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public function getStats(): array
|
||||||
|
{
|
||||||
|
$stats = $this->memcache->getStats();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'version' => $stats['version'] ?? null,
|
||||||
|
'entries' => $stats['curr_items'] ?? null,
|
||||||
|
'used_memory' => $stats['bytes'] ?? null,
|
||||||
|
'uptime' => $stats['uptime'] ?? null,
|
||||||
|
'connected_clients' => $stats['curr_connections'] ?? null,
|
||||||
|
'hits' => $stats['get_hits'] ?? null,
|
||||||
|
'misses' => $stats['get_misses'] ?? null,
|
||||||
|
'evictions' => $stats['evictions'] ?? null,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,10 @@ use Psr\Log\LoggerInterface;
|
||||||
*/
|
*/
|
||||||
class MemcachedCache extends AbstractCache implements ICanCacheInMemory
|
class MemcachedCache extends AbstractCache implements ICanCacheInMemory
|
||||||
{
|
{
|
||||||
const NAME = 'memcached';
|
|
||||||
|
|
||||||
use CompareSetTrait;
|
use CompareSetTrait;
|
||||||
use CompareDeleteTrait;
|
use CompareDeleteTrait;
|
||||||
use MemcacheCommandTrait;
|
use MemcacheCommandTrait;
|
||||||
|
const NAME = 'memcached';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Memcached
|
* @var \Memcached
|
||||||
|
@ -172,4 +171,27 @@ class MemcachedCache extends AbstractCache implements ICanCacheInMemory
|
||||||
$cacheKey = $this->getCacheKey($key);
|
$cacheKey = $this->getCacheKey($key);
|
||||||
return $this->memcached->add($cacheKey, $value, $ttl);
|
return $this->memcached->add($cacheKey, $value, $ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public function getStats(): array
|
||||||
|
{
|
||||||
|
$stats = $this->memcached->getStats();
|
||||||
|
|
||||||
|
// get statistics of the first instance
|
||||||
|
foreach ($stats as $value) {
|
||||||
|
$stats = $value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'version' => $stats['version'] ?? null,
|
||||||
|
'entries' => $stats['curr_items'] ?? null,
|
||||||
|
'used_memory' => $stats['bytes'] ?? null,
|
||||||
|
'uptime' => $stats['uptime'] ?? null,
|
||||||
|
'connected_clients' => $stats['curr_connections'] ?? null,
|
||||||
|
'hits' => $stats['get_hits'] ?? null,
|
||||||
|
'misses' => $stats['get_misses'] ?? null,
|
||||||
|
'evictions' => $stats['evictions'] ?? null,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,4 +166,14 @@ class ProfilerCacheDecorator implements ICanCache, ICanCacheInMemory
|
||||||
{
|
{
|
||||||
return $this->cache->getName() . ' (with profiler)';
|
return $this->cache->getName() . ' (with profiler)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public function getStats(): array
|
||||||
|
{
|
||||||
|
if ($this->cache instanceof ICanCacheInMemory) {
|
||||||
|
return $this->cache->getStats();
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,4 +207,21 @@ class RedisCache extends AbstractCache implements ICanCacheInMemory
|
||||||
$this->redis->unwatch();
|
$this->redis->unwatch();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public function getStats(): array
|
||||||
|
{
|
||||||
|
$info = $this->redis->info();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'version' => $info['redis_version'] ?? null,
|
||||||
|
'entries' => $this->redis->dbSize() ?? null,
|
||||||
|
'used_memory' => $info['used_memory'] ?? null,
|
||||||
|
'connected_clients' => $info['connected_clients'] ?? null,
|
||||||
|
'uptime' => $info['uptime_in_seconds'] ?? null,
|
||||||
|
'hits' => $info['keyspace_hits'] ?? null,
|
||||||
|
'misses' => $info['keyspace_misses'] ?? null,
|
||||||
|
'evictions' => $info['evicted_keys'] ?? null,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,7 @@ class ConfigFileManager
|
||||||
|
|
||||||
// map the legacy configuration structure to the current structure
|
// map the legacy configuration structure to the current structure
|
||||||
foreach ($htConfigCategories as $htConfigCategory) {
|
foreach ($htConfigCategories as $htConfigCategory) {
|
||||||
|
/** @phpstan-ignore-next-line $a->config could be modified after `include $fullName` */
|
||||||
if (is_array($a->config[$htConfigCategory])) {
|
if (is_array($a->config[$htConfigCategory])) {
|
||||||
$keys = array_keys($a->config[$htConfigCategory]);
|
$keys = array_keys($a->config[$htConfigCategory]);
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ class Hook
|
||||||
* the provided data.
|
* the provided data.
|
||||||
*
|
*
|
||||||
* @param string $name of the hook to call
|
* @param string $name of the hook to call
|
||||||
* @param string|array &$data to transmit to the callback handler
|
* @param int|string|array|null $data to transmit to the callback handler
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -43,15 +43,45 @@ final class HookEventBridge
|
||||||
ArrayFilterEvent::NAV_INFO => 'nav_info',
|
ArrayFilterEvent::NAV_INFO => 'nav_info',
|
||||||
ArrayFilterEvent::FEATURE_ENABLED => 'isEnabled',
|
ArrayFilterEvent::FEATURE_ENABLED => 'isEnabled',
|
||||||
ArrayFilterEvent::FEATURE_GET => 'get',
|
ArrayFilterEvent::FEATURE_GET => 'get',
|
||||||
ArrayFilterEvent::POST_LOCAL_START => 'post_local_start',
|
ArrayFilterEvent::PERMISSION_TOOLTIP_CONTENT => 'lockview_content',
|
||||||
ArrayFilterEvent::POST_LOCAL => 'post_local',
|
ArrayFilterEvent::INSERT_POST_LOCAL_START => 'post_local_start',
|
||||||
ArrayFilterEvent::POST_LOCAL_END => 'post_local_end',
|
ArrayFilterEvent::INSERT_POST_LOCAL => 'post_local',
|
||||||
|
ArrayFilterEvent::INSERT_POST_LOCAL_END => 'post_local_end',
|
||||||
|
ArrayFilterEvent::INSERT_POST_REMOTE => 'post_remote',
|
||||||
|
ArrayFilterEvent::INSERT_POST_REMOTE_END => 'post_remote_end',
|
||||||
|
ArrayFilterEvent::PREPARE_POST_START => 'prepare_body_init',
|
||||||
|
ArrayFilterEvent::PREPARE_POST_FILTER_CONTENT => 'prepare_body_content_filter',
|
||||||
|
ArrayFilterEvent::PREPARE_POST => 'prepare_body',
|
||||||
|
ArrayFilterEvent::PREPARE_POST_END => 'prepare_body_final',
|
||||||
ArrayFilterEvent::PHOTO_UPLOAD_FORM => 'photo_upload_form',
|
ArrayFilterEvent::PHOTO_UPLOAD_FORM => 'photo_upload_form',
|
||||||
|
ArrayFilterEvent::PHOTO_UPLOAD_START => 'photo_post_init',
|
||||||
|
ArrayFilterEvent::PHOTO_UPLOAD => 'photo_post_file',
|
||||||
|
ArrayFilterEvent::PHOTO_UPLOAD_END => 'photo_post_end',
|
||||||
ArrayFilterEvent::NETWORK_TO_NAME => 'network_to_name',
|
ArrayFilterEvent::NETWORK_TO_NAME => 'network_to_name',
|
||||||
|
ArrayFilterEvent::NETWORK_CONTENT_START => 'network_content_init',
|
||||||
|
ArrayFilterEvent::NETWORK_CONTENT_TABS => 'network_tabs',
|
||||||
|
ArrayFilterEvent::PARSE_LINK => 'parse_link',
|
||||||
ArrayFilterEvent::CONVERSATION_START => 'conversation_start',
|
ArrayFilterEvent::CONVERSATION_START => 'conversation_start',
|
||||||
|
ArrayFilterEvent::FETCH_ITEM_BY_LINK => 'item_by_link',
|
||||||
|
ArrayFilterEvent::ITEM_TAGGED => 'tagged',
|
||||||
ArrayFilterEvent::DISPLAY_ITEM => 'display_item',
|
ArrayFilterEvent::DISPLAY_ITEM => 'display_item',
|
||||||
|
ArrayFilterEvent::CACHE_ITEM => 'put_item_in_cache',
|
||||||
|
ArrayFilterEvent::CHECK_ITEM_NOTIFICATION => 'check_item_notification',
|
||||||
|
ArrayFilterEvent::ENOTIFY => 'enotify',
|
||||||
|
ArrayFilterEvent::ENOTIFY_STORE => 'enotify_store',
|
||||||
|
ArrayFilterEvent::ENOTIFY_MAIL => 'enotify_mail',
|
||||||
|
ArrayFilterEvent::DETECT_LANGUAGES => 'detect_languages',
|
||||||
ArrayFilterEvent::RENDER_LOCATION => 'render_location',
|
ArrayFilterEvent::RENDER_LOCATION => 'render_location',
|
||||||
ArrayFilterEvent::ITEM_PHOTO_MENU => 'item_photo_menu',
|
ArrayFilterEvent::ITEM_PHOTO_MENU => 'item_photo_menu',
|
||||||
|
ArrayFilterEvent::DIRECTORY_ITEM => 'directory_item',
|
||||||
|
ArrayFilterEvent::CONTACT_PHOTO_MENU => 'contact_photo_menu',
|
||||||
|
ArrayFilterEvent::PROFILE_SIDEBAR_ENTRY => 'profile_sidebar_enter',
|
||||||
|
ArrayFilterEvent::PROFILE_SIDEBAR => 'profile_sidebar',
|
||||||
|
ArrayFilterEvent::PROFILE_TABS => 'profile_tabs',
|
||||||
|
ArrayFilterEvent::PROFILE_SETTINGS_FORM => 'profile_edit',
|
||||||
|
ArrayFilterEvent::PROFILE_SETTINGS_POST => 'profile_post',
|
||||||
|
ArrayFilterEvent::MODERATION_USERS_TABS => 'moderation_users_tabs',
|
||||||
|
ArrayFilterEvent::ACL_LOOKUP_END => 'acl_lookup_end',
|
||||||
ArrayFilterEvent::OEMBED_FETCH_END => 'oembed_fetch_url',
|
ArrayFilterEvent::OEMBED_FETCH_END => 'oembed_fetch_url',
|
||||||
ArrayFilterEvent::PAGE_INFO => 'page_info_data',
|
ArrayFilterEvent::PAGE_INFO => 'page_info_data',
|
||||||
ArrayFilterEvent::SMILEY_LIST => 'smilie',
|
ArrayFilterEvent::SMILEY_LIST => 'smilie',
|
||||||
|
@ -62,11 +92,34 @@ final class HookEventBridge
|
||||||
ArrayFilterEvent::PROTOCOL_SUPPORTS_FOLLOW => 'support_follow',
|
ArrayFilterEvent::PROTOCOL_SUPPORTS_FOLLOW => 'support_follow',
|
||||||
ArrayFilterEvent::PROTOCOL_SUPPORTS_REVOKE_FOLLOW => 'support_revoke_follow',
|
ArrayFilterEvent::PROTOCOL_SUPPORTS_REVOKE_FOLLOW => 'support_revoke_follow',
|
||||||
ArrayFilterEvent::PROTOCOL_SUPPORTS_PROBE => 'support_probe',
|
ArrayFilterEvent::PROTOCOL_SUPPORTS_PROBE => 'support_probe',
|
||||||
|
ArrayFilterEvent::FOLLOW_CONTACT => 'follow',
|
||||||
|
ArrayFilterEvent::UNFOLLOW_CONTACT => 'unfollow',
|
||||||
|
ArrayFilterEvent::REVOKE_FOLLOW_CONTACT => 'revoke_follow',
|
||||||
|
ArrayFilterEvent::BLOCK_CONTACT => 'block',
|
||||||
|
ArrayFilterEvent::UNBLOCK_CONTACT => 'unblock',
|
||||||
|
ArrayFilterEvent::EDIT_CONTACT_FORM => 'contact_edit',
|
||||||
|
ArrayFilterEvent::EDIT_CONTACT_POST => 'contact_edit_post',
|
||||||
|
ArrayFilterEvent::AVATAR_LOOKUP => 'avatar_lookup',
|
||||||
|
ArrayFilterEvent::ACCOUNT_AUTHENTICATE => 'authenticate',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REGISTER_FORM => 'register_form',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REGISTER_POST => 'register_post',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REGISTER => 'register_account',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REMOVE => 'remove_user',
|
||||||
|
ArrayFilterEvent::EVENT_CREATED => 'event_created',
|
||||||
|
ArrayFilterEvent::EVENT_UPDATED => 'event_updated',
|
||||||
|
ArrayFilterEvent::ADD_WORKER_TASK => 'proc_run',
|
||||||
|
ArrayFilterEvent::STORAGE_CONFIG => 'storage_config',
|
||||||
|
ArrayFilterEvent::STORAGE_INSTANCE => 'storage_instance',
|
||||||
|
ArrayFilterEvent::DB_STRUCTURE_DEFINITION => 'dbstructure_definition',
|
||||||
|
ArrayFilterEvent::DB_VIEW_DEFINITION => 'dbview_definition',
|
||||||
HtmlFilterEvent::HEAD => 'head',
|
HtmlFilterEvent::HEAD => 'head',
|
||||||
HtmlFilterEvent::FOOTER => 'footer',
|
HtmlFilterEvent::FOOTER => 'footer',
|
||||||
HtmlFilterEvent::PAGE_HEADER => 'page_header',
|
HtmlFilterEvent::PAGE_HEADER => 'page_header',
|
||||||
HtmlFilterEvent::PAGE_CONTENT_TOP => 'page_content_top',
|
HtmlFilterEvent::PAGE_CONTENT_TOP => 'page_content_top',
|
||||||
HtmlFilterEvent::PAGE_END => 'page_end',
|
HtmlFilterEvent::PAGE_END => 'page_end',
|
||||||
|
HtmlFilterEvent::MOD_HOME_CONTENT => 'home_content',
|
||||||
|
HtmlFilterEvent::MOD_ABOUT_CONTENT => 'about_hook',
|
||||||
|
HtmlFilterEvent::MOD_PROFILE_CONTENT => 'profile_advanced',
|
||||||
HtmlFilterEvent::JOT_TOOL => 'jot_tool',
|
HtmlFilterEvent::JOT_TOOL => 'jot_tool',
|
||||||
HtmlFilterEvent::CONTACT_BLOCK_END => 'contact_block_end',
|
HtmlFilterEvent::CONTACT_BLOCK_END => 'contact_block_end',
|
||||||
];
|
];
|
||||||
|
@ -85,15 +138,45 @@ final class HookEventBridge
|
||||||
ArrayFilterEvent::NAV_INFO => 'onArrayFilterEvent',
|
ArrayFilterEvent::NAV_INFO => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::FEATURE_ENABLED => 'onArrayFilterEvent',
|
ArrayFilterEvent::FEATURE_ENABLED => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::FEATURE_GET => 'onArrayFilterEvent',
|
ArrayFilterEvent::FEATURE_GET => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::POST_LOCAL_START => 'onArrayFilterEvent',
|
ArrayFilterEvent::PERMISSION_TOOLTIP_CONTENT => 'onPermissionTooltipContentEvent',
|
||||||
ArrayFilterEvent::POST_LOCAL => 'onArrayFilterEvent',
|
ArrayFilterEvent::INSERT_POST_LOCAL_START => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::POST_LOCAL_END => 'onArrayFilterEvent',
|
ArrayFilterEvent::INSERT_POST_LOCAL => 'onInsertPostLocalEvent',
|
||||||
|
ArrayFilterEvent::INSERT_POST_LOCAL_END => 'onInsertPostLocalEndEvent',
|
||||||
|
ArrayFilterEvent::INSERT_POST_REMOTE => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::INSERT_POST_REMOTE_END => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PREPARE_POST_START => 'onPreparePostStartEvent',
|
||||||
|
ArrayFilterEvent::PREPARE_POST_FILTER_CONTENT => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PREPARE_POST => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PREPARE_POST_END => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::PHOTO_UPLOAD_FORM => 'onArrayFilterEvent',
|
ArrayFilterEvent::PHOTO_UPLOAD_FORM => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PHOTO_UPLOAD_START => 'onPhotoUploadStartEvent',
|
||||||
|
ArrayFilterEvent::PHOTO_UPLOAD => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PHOTO_UPLOAD_END => 'onPhotoUploadEndEvent',
|
||||||
ArrayFilterEvent::NETWORK_TO_NAME => 'onArrayFilterEvent',
|
ArrayFilterEvent::NETWORK_TO_NAME => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::NETWORK_CONTENT_START => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::NETWORK_CONTENT_TABS => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PARSE_LINK => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::CONVERSATION_START => 'onArrayFilterEvent',
|
ArrayFilterEvent::CONVERSATION_START => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::FETCH_ITEM_BY_LINK => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ITEM_TAGGED => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::DISPLAY_ITEM => 'onArrayFilterEvent',
|
ArrayFilterEvent::DISPLAY_ITEM => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::CACHE_ITEM => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::CHECK_ITEM_NOTIFICATION => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ENOTIFY => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ENOTIFY_STORE => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ENOTIFY_MAIL => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::DETECT_LANGUAGES => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::RENDER_LOCATION => 'onArrayFilterEvent',
|
ArrayFilterEvent::RENDER_LOCATION => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::ITEM_PHOTO_MENU => 'onArrayFilterEvent',
|
ArrayFilterEvent::ITEM_PHOTO_MENU => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::DIRECTORY_ITEM => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::CONTACT_PHOTO_MENU => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PROFILE_SIDEBAR_ENTRY => 'onProfileSidebarEntryEvent',
|
||||||
|
ArrayFilterEvent::PROFILE_SIDEBAR => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PROFILE_TABS => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PROFILE_SETTINGS_FORM => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::PROFILE_SETTINGS_POST => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::MODERATION_USERS_TABS => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ACL_LOOKUP_END => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::OEMBED_FETCH_END => 'onOembedFetchEndEvent',
|
ArrayFilterEvent::OEMBED_FETCH_END => 'onOembedFetchEndEvent',
|
||||||
ArrayFilterEvent::PAGE_INFO => 'onArrayFilterEvent',
|
ArrayFilterEvent::PAGE_INFO => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::SMILEY_LIST => 'onArrayFilterEvent',
|
ArrayFilterEvent::SMILEY_LIST => 'onArrayFilterEvent',
|
||||||
|
@ -104,11 +187,34 @@ final class HookEventBridge
|
||||||
ArrayFilterEvent::PROTOCOL_SUPPORTS_FOLLOW => 'onArrayFilterEvent',
|
ArrayFilterEvent::PROTOCOL_SUPPORTS_FOLLOW => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::PROTOCOL_SUPPORTS_REVOKE_FOLLOW => 'onArrayFilterEvent',
|
ArrayFilterEvent::PROTOCOL_SUPPORTS_REVOKE_FOLLOW => 'onArrayFilterEvent',
|
||||||
ArrayFilterEvent::PROTOCOL_SUPPORTS_PROBE => 'onArrayFilterEvent',
|
ArrayFilterEvent::PROTOCOL_SUPPORTS_PROBE => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::FOLLOW_CONTACT => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::UNFOLLOW_CONTACT => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::REVOKE_FOLLOW_CONTACT => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::BLOCK_CONTACT => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::UNBLOCK_CONTACT => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::EDIT_CONTACT_FORM => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::EDIT_CONTACT_POST => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::AVATAR_LOOKUP => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ACCOUNT_AUTHENTICATE => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REGISTER_FORM => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REGISTER_POST => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REGISTER => 'onAccountRegisterEvent',
|
||||||
|
ArrayFilterEvent::ACCOUNT_REMOVE => 'onAccountRemoveEvent',
|
||||||
|
ArrayFilterEvent::EVENT_CREATED => 'onEventCreatedEvent',
|
||||||
|
ArrayFilterEvent::EVENT_UPDATED => 'onEventUpdatedEvent',
|
||||||
|
ArrayFilterEvent::ADD_WORKER_TASK => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::STORAGE_CONFIG => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::STORAGE_INSTANCE => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::DB_STRUCTURE_DEFINITION => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::DB_VIEW_DEFINITION => 'onArrayFilterEvent',
|
||||||
HtmlFilterEvent::HEAD => 'onHtmlFilterEvent',
|
HtmlFilterEvent::HEAD => 'onHtmlFilterEvent',
|
||||||
HtmlFilterEvent::FOOTER => 'onHtmlFilterEvent',
|
HtmlFilterEvent::FOOTER => 'onHtmlFilterEvent',
|
||||||
HtmlFilterEvent::PAGE_HEADER => 'onHtmlFilterEvent',
|
HtmlFilterEvent::PAGE_HEADER => 'onHtmlFilterEvent',
|
||||||
HtmlFilterEvent::PAGE_CONTENT_TOP => 'onHtmlFilterEvent',
|
HtmlFilterEvent::PAGE_CONTENT_TOP => 'onHtmlFilterEvent',
|
||||||
HtmlFilterEvent::PAGE_END => 'onHtmlFilterEvent',
|
HtmlFilterEvent::PAGE_END => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::MOD_HOME_CONTENT => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::MOD_ABOUT_CONTENT => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::MOD_PROFILE_CONTENT => 'onHtmlFilterEvent',
|
||||||
HtmlFilterEvent::JOT_TOOL => 'onHtmlFilterEvent',
|
HtmlFilterEvent::JOT_TOOL => 'onHtmlFilterEvent',
|
||||||
HtmlFilterEvent::CONTACT_BLOCK_END => 'onHtmlFilterEvent',
|
HtmlFilterEvent::CONTACT_BLOCK_END => 'onHtmlFilterEvent',
|
||||||
];
|
];
|
||||||
|
@ -131,6 +237,103 @@ final class HookEventBridge
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the PERMISSION_TOOLTIP_CONTENT event to `lockview_content` hook
|
||||||
|
*/
|
||||||
|
public static function onPermissionTooltipContentEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$model = (array) $data['model'] ?? [];
|
||||||
|
|
||||||
|
$data['model'] = static::callHook($event->getName(), $model);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the INSERT_POST_LOCAL event to `post_local` hook
|
||||||
|
*/
|
||||||
|
public static function onInsertPostLocalEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$item = (array) $data['item'] ?? [];
|
||||||
|
|
||||||
|
$data['item'] = static::callHook($event->getName(), $item);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the INSERT_POST_LOCAL_END event to `post_local_end` hook
|
||||||
|
*/
|
||||||
|
public static function onInsertPostLocalEndEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$item = (array) $data['item'] ?? [];
|
||||||
|
|
||||||
|
$data['item'] = static::callHook($event->getName(), $item);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the PREPARE_POST_START event to `prepare_body_init` hook
|
||||||
|
*/
|
||||||
|
public static function onPreparePostStartEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$item = (array) $data['item'] ?? [];
|
||||||
|
|
||||||
|
$data['item'] = static::callHook($event->getName(), $item);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the PHOTO_UPLOAD_START event to `photo_post_init` hook
|
||||||
|
*/
|
||||||
|
public static function onPhotoUploadStartEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$request = (array) $data['request'] ?? [];
|
||||||
|
|
||||||
|
$data['request'] = static::callHook($event->getName(), $request);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the PHOTO_UPLOAD_END event to `photo_post_end` hook
|
||||||
|
*/
|
||||||
|
public static function onPhotoUploadEndEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$id = (int) $data['id'] ?? 0;
|
||||||
|
|
||||||
|
// one-way-event: we don't care about the returned value
|
||||||
|
static::callHook($event->getName(), $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the PROFILE_SIDEBAR_ENTRY event to `profile_sidebar_enter` hook
|
||||||
|
*/
|
||||||
|
public static function onProfileSidebarEntryEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$profile = (array) $data['profile'] ?? [];
|
||||||
|
|
||||||
|
$data['profile'] = static::callHook($event->getName(), $profile);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map the OEMBED_FETCH_END event to `oembed_fetch_url` hook
|
* Map the OEMBED_FETCH_END event to `oembed_fetch_url` hook
|
||||||
*/
|
*/
|
||||||
|
@ -187,6 +390,60 @@ final class HookEventBridge
|
||||||
$event->setArray($data);
|
$event->setArray($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the ACCOUNT_REGISTER event to `register_account` hook
|
||||||
|
*/
|
||||||
|
public static function onAccountRegisterEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$uid = (int) $data['uid'] ?? 0;
|
||||||
|
|
||||||
|
$data['uid'] = static::callHook($event->getName(), $uid);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the ACCOUNT_REMOVE event to `remove_account` hook
|
||||||
|
*/
|
||||||
|
public static function onAccountRemoveEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$user = (array) $data['user'] ?? [];
|
||||||
|
|
||||||
|
$data['user'] = static::callHook($event->getName(), $user);
|
||||||
|
|
||||||
|
$event->setArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the EVENT_CREATED event to `event_created` hook
|
||||||
|
*/
|
||||||
|
public static function onEventCreatedEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$id = (int) $data['event']['id'] ?? 0;
|
||||||
|
|
||||||
|
// one-way-event: we don't care about the returned value
|
||||||
|
static::callHook($event->getName(), $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the EVENT_UPDATED event to `event_updated` hook
|
||||||
|
*/
|
||||||
|
public static function onEventUpdatedEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$data = $event->getArray();
|
||||||
|
|
||||||
|
$id = (int) $data['event']['id'] ?? 0;
|
||||||
|
|
||||||
|
// one-way-event: we don't care about the returned value
|
||||||
|
static::callHook($event->getName(), $id);
|
||||||
|
}
|
||||||
|
|
||||||
public static function onArrayFilterEvent(ArrayFilterEvent $event): void
|
public static function onArrayFilterEvent(ArrayFilterEvent $event): void
|
||||||
{
|
{
|
||||||
$event->setArray(
|
$event->setArray(
|
||||||
|
@ -202,9 +459,9 @@ final class HookEventBridge
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|array|object $data
|
* @param int|string|array|object $data
|
||||||
*
|
*
|
||||||
* @return string|array|object
|
* @return int|string|array|object
|
||||||
*/
|
*/
|
||||||
private static function callHook(string $name, $data)
|
private static function callHook(string $name, $data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Friendica\Core\Lock\Type;
|
namespace Friendica\Core\Lock\Type;
|
||||||
|
|
||||||
use Friendica\Core\Cache\Capability\ICanCache;
|
|
||||||
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
|
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
|
||||||
use Friendica\Core\Cache\Enum\Duration;
|
use Friendica\Core\Cache\Enum\Duration;
|
||||||
use Friendica\Core\Cache\Exception\CachePersistenceException;
|
use Friendica\Core\Cache\Exception\CachePersistenceException;
|
||||||
|
@ -156,6 +155,16 @@ class CacheLock extends AbstractLock
|
||||||
return $success;
|
return $success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns stats about the cache provider
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getCacheStats(): array
|
||||||
|
{
|
||||||
|
return $this->cache->getStats();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $key The original key
|
* @param string $key The original key
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,6 +12,8 @@ use Psr\Log\LogLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for creating logger types, which includes common necessary logic/content
|
* Abstract class for creating logger types, which includes common necessary logic/content
|
||||||
|
*
|
||||||
|
* @deprecated 2025.02 Implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead
|
||||||
*/
|
*/
|
||||||
abstract class AbstractLoggerTypeFactory
|
abstract class AbstractLoggerTypeFactory
|
||||||
{
|
{
|
||||||
|
@ -25,6 +27,8 @@ abstract class AbstractLoggerTypeFactory
|
||||||
*/
|
*/
|
||||||
public function __construct(IHaveCallIntrospections $introspection, string $channel)
|
public function __construct(IHaveCallIntrospections $introspection, string $channel)
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
$this->channel = $channel;
|
$this->channel = $channel;
|
||||||
$this->introspection = $introspection;
|
$this->introspection = $introspection;
|
||||||
}
|
}
|
||||||
|
|
73
src/Core/Logger/Factory/DelegatingLoggerFactory.php
Normal file
73
src/Core/Logger/Factory/DelegatingLoggerFactory.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Core\Logger\Factory;
|
||||||
|
|
||||||
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates the creation of a logger based on config to other factories
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class DelegatingLoggerFactory implements LoggerFactory
|
||||||
|
{
|
||||||
|
private IManageConfigValues $config;
|
||||||
|
|
||||||
|
/** @var array<string,LoggerFactory> */
|
||||||
|
private array $factories = [];
|
||||||
|
|
||||||
|
public function __construct(IManageConfigValues $config)
|
||||||
|
{
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerFactory(string $name, LoggerFactory $factory): void
|
||||||
|
{
|
||||||
|
$this->factories[$name] = $factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a PSR-3 Logger instance.
|
||||||
|
*
|
||||||
|
* Calling this method multiple times with the same parameters SHOULD return the same object.
|
||||||
|
*
|
||||||
|
* @param \Psr\Log\LogLevel::* $logLevel The log level
|
||||||
|
* @param \Friendica\Core\Logger\Capability\LogChannel::* $logChannel The log channel
|
||||||
|
*/
|
||||||
|
public function createLogger(string $logLevel, string $logChannel): LoggerInterface
|
||||||
|
{
|
||||||
|
$factoryName = $this->config->get('system', 'logger_config') ?? '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 2025.02 The value `monolog` for `system.logger_config` inside the `config/local.config.php` file is deprecated, please use `stream` or `syslog` instead.
|
||||||
|
*/
|
||||||
|
if ($factoryName === 'monolog') {
|
||||||
|
@trigger_error('The config `system.logger_config` with value `monolog` is deprecated since 2025.02 and will stop working in 5 months, please change the value to `stream` or `syslog` in the `config/local.config.php` file.', \E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
$factoryName = 'stream';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($factoryName, $this->factories)) {
|
||||||
|
return new NullLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
$factory = $this->factories[$factoryName];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$logger = $factory->createLogger($logLevel, $logChannel);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
return new NullLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $logger;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,61 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
// Copyright (C) 2010-2024, the Friendica project
|
|
||||||
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Friendica\Core\Logger\Factory;
|
|
||||||
|
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
|
||||||
use Friendica\Core\Hooks\Capability\ICanCreateInstances;
|
|
||||||
use Friendica\Util\Profiler;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bridge for the legacy Logger factory.
|
|
||||||
*
|
|
||||||
* This class can be removed after the following classes are replaced or
|
|
||||||
* refactored implementing the `\Friendica\Core\Logger\Factory\LoggerFactory`:
|
|
||||||
*
|
|
||||||
* - Friendica\Core\Logger\Factory\StreamLogger
|
|
||||||
* - Friendica\Core\Logger\Factory\SyslogLogger
|
|
||||||
* - monolog addon: Friendica\Addon\monolog\src\Factory\Monolog
|
|
||||||
*
|
|
||||||
* @see \Friendica\Core\Logger\Factory\StreamLogger
|
|
||||||
* @see \Friendica\Core\Logger\Factory\SyslogLogger
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class LegacyLoggerFactory implements LoggerFactory
|
|
||||||
{
|
|
||||||
private ICanCreateInstances $instanceCreator;
|
|
||||||
|
|
||||||
private IManageConfigValues $config;
|
|
||||||
|
|
||||||
private Profiler $profiler;
|
|
||||||
|
|
||||||
public function __construct(ICanCreateInstances $instanceCreator, IManageConfigValues $config, Profiler $profiler)
|
|
||||||
{
|
|
||||||
$this->instanceCreator = $instanceCreator;
|
|
||||||
$this->config = $config;
|
|
||||||
$this->profiler = $profiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and returns a PSR-3 Logger instance.
|
|
||||||
*
|
|
||||||
* Calling this method multiple times with the same parameters SHOULD return the same object.
|
|
||||||
*
|
|
||||||
* @param \Psr\Log\LogLevel::* $logLevel The log level
|
|
||||||
* @param \Friendica\Core\Logger\Capability\LogChannel::* $logChannel The log channel
|
|
||||||
*/
|
|
||||||
public function createLogger(string $logLevel, string $logChannel): LoggerInterface
|
|
||||||
{
|
|
||||||
$factory = new Logger($logChannel);
|
|
||||||
|
|
||||||
return $factory->create($this->instanceCreator, $this->config, $this->profiler);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,6 +18,8 @@ use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger factory for the core logging instances
|
* The logger factory for the core logging instances
|
||||||
|
*
|
||||||
|
* @deprecated 2025.02 Implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead
|
||||||
*/
|
*/
|
||||||
class Logger
|
class Logger
|
||||||
{
|
{
|
||||||
|
@ -26,6 +28,8 @@ class Logger
|
||||||
|
|
||||||
public function __construct(string $channel = LogChannel::DEFAULT)
|
public function __construct(string $channel = LogChannel::DEFAULT)
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
$this->channel = $channel;
|
$this->channel = $channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ use Psr\Log\NullLogger;
|
||||||
/**
|
/**
|
||||||
* The logger factory for the StreamLogger instance
|
* The logger factory for the StreamLogger instance
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead
|
||||||
|
* @see StreamLoggerFactory
|
||||||
* @see StreamLoggerClass
|
* @see StreamLoggerClass
|
||||||
*/
|
*/
|
||||||
class StreamLogger extends AbstractLoggerTypeFactory
|
class StreamLogger extends AbstractLoggerTypeFactory
|
||||||
|
@ -38,6 +40,8 @@ class StreamLogger extends AbstractLoggerTypeFactory
|
||||||
*/
|
*/
|
||||||
public function create(IManageConfigValues $config, string $logfile = null, string $channel = null): LoggerInterface
|
public function create(IManageConfigValues $config, string $logfile = null, string $channel = null): LoggerInterface
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
$fileSystem = new FileSystem();
|
$fileSystem = new FileSystem();
|
||||||
|
|
||||||
$logfile = $logfile ?? $config->get('system', 'logfile');
|
$logfile = $logfile ?? $config->get('system', 'logfile');
|
||||||
|
|
76
src/Core/Logger/Factory/StreamLoggerFactory.php
Normal file
76
src/Core/Logger/Factory/StreamLoggerFactory.php
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Core\Logger\Factory;
|
||||||
|
|
||||||
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Friendica\Core\Logger\Capability\IHaveCallIntrospections;
|
||||||
|
use Friendica\Core\Logger\Exception\LoggerArgumentException;
|
||||||
|
use Friendica\Core\Logger\Exception\LogLevelException;
|
||||||
|
use Friendica\Core\Logger\Type\StreamLogger;
|
||||||
|
use Friendica\Core\Logger\Util\FileSystemUtil;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger factory for the StreamLogger instance
|
||||||
|
*
|
||||||
|
* @see StreamLogger
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class StreamLoggerFactory implements LoggerFactory
|
||||||
|
{
|
||||||
|
private IManageConfigValues $config;
|
||||||
|
|
||||||
|
private IHaveCallIntrospections $introspection;
|
||||||
|
|
||||||
|
private FileSystemUtil $fileSystem;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
IManageConfigValues $config,
|
||||||
|
IHaveCallIntrospections $introspection,
|
||||||
|
FileSystemUtil $fileSystem
|
||||||
|
) {
|
||||||
|
$this->config = $config;
|
||||||
|
$this->introspection = $introspection;
|
||||||
|
$this->fileSystem = $fileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a PSR-3 Logger instance.
|
||||||
|
*
|
||||||
|
* Calling this method multiple times with the same parameters SHOULD return the same object.
|
||||||
|
*
|
||||||
|
* @param \Psr\Log\LogLevel::* $logLevel The log level
|
||||||
|
* @param \Friendica\Core\Logger\Capability\LogChannel::* $logChannel The log channel
|
||||||
|
*
|
||||||
|
* @throws LoggerArgumentException
|
||||||
|
* @throws LogLevelException
|
||||||
|
*/
|
||||||
|
public function createLogger(string $logLevel, string $logChannel): LoggerInterface
|
||||||
|
{
|
||||||
|
$logfile = $this->config->get('system', 'logfile');
|
||||||
|
|
||||||
|
if (!file_exists($logfile) || !is_writable($logfile)) {
|
||||||
|
throw new LoggerArgumentException(sprintf('"%s" is not a valid logfile.', $logfile));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! array_key_exists($logLevel, StreamLogger::levelToInt)) {
|
||||||
|
throw new LogLevelException(sprintf('The log level "%s" is not supported by "%s".', $logLevel, StreamLogger::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StreamLogger(
|
||||||
|
$logChannel,
|
||||||
|
$this->introspection,
|
||||||
|
$this->fileSystem->createStream($logfile),
|
||||||
|
StreamLogger::levelToInt[$logLevel],
|
||||||
|
getmypid()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,8 @@ use Psr\Log\LoggerInterface;
|
||||||
/**
|
/**
|
||||||
* The logger factory for the SyslogLogger instance
|
* The logger factory for the SyslogLogger instance
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead
|
||||||
|
* @see SyslogLoggerFactory
|
||||||
* @see SyslogLoggerClass
|
* @see SyslogLoggerClass
|
||||||
*/
|
*/
|
||||||
class SyslogLogger extends AbstractLoggerTypeFactory
|
class SyslogLogger extends AbstractLoggerTypeFactory
|
||||||
|
@ -31,6 +33,8 @@ class SyslogLogger extends AbstractLoggerTypeFactory
|
||||||
*/
|
*/
|
||||||
public function create(IManageConfigValues $config): LoggerInterface
|
public function create(IManageConfigValues $config): LoggerInterface
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, implement `\Friendica\Core\Logger\Factory\LoggerFactory` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
$logOpts = $config->get('system', 'syslog_flags') ?? SyslogLoggerClass::DEFAULT_FLAGS;
|
$logOpts = $config->get('system', 'syslog_flags') ?? SyslogLoggerClass::DEFAULT_FLAGS;
|
||||||
$logFacility = $config->get('system', 'syslog_facility') ?? SyslogLoggerClass::DEFAULT_FACILITY;
|
$logFacility = $config->get('system', 'syslog_facility') ?? SyslogLoggerClass::DEFAULT_FACILITY;
|
||||||
$loglevel = SyslogLogger::mapLegacyConfigDebugLevel($config->get('system', 'loglevel'));
|
$loglevel = SyslogLogger::mapLegacyConfigDebugLevel($config->get('system', 'loglevel'));
|
||||||
|
|
66
src/Core/Logger/Factory/SyslogLoggerFactory.php
Normal file
66
src/Core/Logger/Factory/SyslogLoggerFactory.php
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Core\Logger\Factory;
|
||||||
|
|
||||||
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Friendica\Core\Logger\Capability\IHaveCallIntrospections;
|
||||||
|
use Friendica\Core\Logger\Exception\LogLevelException;
|
||||||
|
use Friendica\Core\Logger\Type\SyslogLogger;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger factory for the SyslogLogger instance
|
||||||
|
*
|
||||||
|
* @see SyslogLogger
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class SyslogLoggerFactory implements LoggerFactory
|
||||||
|
{
|
||||||
|
private IManageConfigValues $config;
|
||||||
|
|
||||||
|
private IHaveCallIntrospections $introspection;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
IManageConfigValues $config,
|
||||||
|
IHaveCallIntrospections $introspection
|
||||||
|
) {
|
||||||
|
$this->config = $config;
|
||||||
|
$this->introspection = $introspection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a PSR-3 Logger instance.
|
||||||
|
*
|
||||||
|
* Calling this method multiple times with the same parameters SHOULD return the same object.
|
||||||
|
*
|
||||||
|
* @param \Psr\Log\LogLevel::* $logLevel The log level
|
||||||
|
* @param \Friendica\Core\Logger\Capability\LogChannel::* $logChannel The log channel
|
||||||
|
*
|
||||||
|
* @throws LogLevelException
|
||||||
|
*/
|
||||||
|
public function createLogger(string $logLevel, string $logChannel): LoggerInterface
|
||||||
|
{
|
||||||
|
$logOpts = (int) $this->config->get('system', 'syslog_flags') ?? SyslogLogger::DEFAULT_FLAGS;
|
||||||
|
$logFacility = (int) $this->config->get('system', 'syslog_facility') ?? SyslogLogger::DEFAULT_FACILITY;
|
||||||
|
|
||||||
|
if (!array_key_exists($logLevel, SyslogLogger::logLevels)) {
|
||||||
|
throw new LogLevelException(sprintf('The log level "%s" is not supported by "%s".', $logLevel, SyslogLogger::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SyslogLogger(
|
||||||
|
$logChannel,
|
||||||
|
$this->introspection,
|
||||||
|
SyslogLogger::logLevels[$logLevel],
|
||||||
|
$logOpts,
|
||||||
|
$logFacility
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,21 +22,19 @@ class StreamLogger extends AbstractLogger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum loglevel at which this logger will be triggered
|
* The minimum loglevel at which this logger will be triggered
|
||||||
* @var string
|
|
||||||
*/
|
*/
|
||||||
private $logLevel;
|
private int $logLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The stream, where the current logger is writing into
|
* The stream, where the current logger is writing into
|
||||||
* @var resource
|
* @var resource|null
|
||||||
*/
|
*/
|
||||||
private $stream;
|
private $stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current process ID
|
* The current process ID
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $pid;
|
private int $pid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates LogLevel log levels to integer values
|
* Translates LogLevel log levels to integer values
|
||||||
|
|
|
@ -29,7 +29,7 @@ class SyslogLogger extends AbstractLogger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates LogLevel log levels to syslog log priorities.
|
* Translates LogLevel log levels to syslog log priorities.
|
||||||
* @var array
|
* @var array<string,int>
|
||||||
*/
|
*/
|
||||||
public const logLevels = [
|
public const logLevels = [
|
||||||
LogLevel::DEBUG => LOG_DEBUG,
|
LogLevel::DEBUG => LOG_DEBUG,
|
||||||
|
@ -60,39 +60,33 @@ class SyslogLogger extends AbstractLogger
|
||||||
/**
|
/**
|
||||||
* Indicates what logging options will be used when generating a log message
|
* Indicates what logging options will be used when generating a log message
|
||||||
* @see http://php.net/manual/en/function.openlog.php#refsect1-function.openlog-parameters
|
* @see http://php.net/manual/en/function.openlog.php#refsect1-function.openlog-parameters
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $logOpts;
|
private int $logOpts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to specify what type of program is logging the message
|
* Used to specify what type of program is logging the message
|
||||||
* @see http://php.net/manual/en/function.openlog.php#refsect1-function.openlog-parameters
|
* @see http://php.net/manual/en/function.openlog.php#refsect1-function.openlog-parameters
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $logFacility;
|
private int $logFacility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum loglevel at which this logger will be triggered
|
* The minimum loglevel at which this logger will be triggered
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $logLevel;
|
private int $logLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A error message of the current operation
|
* A error message of the current operation
|
||||||
* @var string
|
|
||||||
*/
|
*/
|
||||||
private $errorMessage;
|
private string $errorMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* @param string $logLevel The minimum loglevel at which this logger will be triggered
|
* @param int $logLevel The minimum loglevel at which this logger will be triggered
|
||||||
* @param string $logOptions
|
* @param int $logOptions
|
||||||
* @param string $logFacility
|
* @param int $logFacility
|
||||||
*/
|
*/
|
||||||
public function __construct(string $channel, IHaveCallIntrospections $introspection, string $logLevel, string $logOptions, string $logFacility)
|
public function __construct(string $channel, IHaveCallIntrospections $introspection, int $logLevel, int $logOptions, int $logFacility)
|
||||||
{
|
{
|
||||||
parent::__construct($channel, $introspection);
|
parent::__construct($channel, $introspection);
|
||||||
|
|
||||||
|
@ -166,7 +160,7 @@ class SyslogLogger extends AbstractLogger
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
|
|
||||||
if (!$opened) {
|
if (!$opened) {
|
||||||
throw new LoggerException(sprintf('Can\'t open syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, $this->logFacility));
|
throw new LoggerException(sprintf('Can\'t open syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, (string) $this->logFacility));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->syslogWrapper($priority, $message);
|
$this->syslogWrapper($priority, $message);
|
||||||
|
@ -215,7 +209,7 @@ class SyslogLogger extends AbstractLogger
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
|
|
||||||
if (!$written) {
|
if (!$written) {
|
||||||
throw new LoggerException(sprintf('Can\'t write into syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, $this->logFacility));
|
throw new LoggerException(sprintf('Can\'t write into syslog for ident "%s" and facility "%s": ' . $this->errorMessage, $this->channel, (string) $this->logFacility));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use Friendica\Core\Logger\Exception\LoggerUnusableException;
|
||||||
/**
|
/**
|
||||||
* Util class for filesystem manipulation for Logger classes
|
* Util class for filesystem manipulation for Logger classes
|
||||||
*/
|
*/
|
||||||
class FileSystem
|
class FileSystem implements FileSystemUtil
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string a error message
|
* @var string a error message
|
||||||
|
|
40
src/Core/Logger/Util/FileSystemUtil.php
Normal file
40
src/Core/Logger/Util/FileSystemUtil.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?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\Core\Logger\Util;
|
||||||
|
|
||||||
|
use Friendica\Core\Logger\Exception\LoggerUnusableException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* interface for Util class for filesystem manipulation for Logger classes
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
interface FileSystemUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a directory based on a file, which gets accessed
|
||||||
|
*
|
||||||
|
* @param string $file The file
|
||||||
|
*
|
||||||
|
* @return string The directory name (empty if no directory is found, like urls)
|
||||||
|
*
|
||||||
|
* @throws LoggerUnusableException
|
||||||
|
*/
|
||||||
|
public function createDir(string $file): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a stream based on a URL (could be a local file or a real URL)
|
||||||
|
*
|
||||||
|
* @param string $url The file/url
|
||||||
|
*
|
||||||
|
* @return resource the open stream resource
|
||||||
|
*
|
||||||
|
* @throws LoggerUnusableException
|
||||||
|
*/
|
||||||
|
public function createStream(string $url);
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ class PConfig
|
||||||
*/
|
*/
|
||||||
public function isConnected(): bool
|
public function isConnected(): bool
|
||||||
{
|
{
|
||||||
return $this->db->isConnected() & !$this->mode->isInstall();
|
return $this->db->isConnected() && !$this->mode->isInstall();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -183,7 +183,12 @@ class Protocol
|
||||||
'uid' => $owner['uid'],
|
'uid' => $owner['uid'],
|
||||||
'result' => null,
|
'result' => null,
|
||||||
];
|
];
|
||||||
Hook::callAll('unfollow', $hook_data);
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::UNFOLLOW_CONTACT, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return $hook_data['result'];
|
return $hook_data['result'];
|
||||||
}
|
}
|
||||||
|
@ -218,7 +223,12 @@ class Protocol
|
||||||
'uid' => $owner['uid'],
|
'uid' => $owner['uid'],
|
||||||
'result' => null,
|
'result' => null,
|
||||||
];
|
];
|
||||||
Hook::callAll('revoke_follow', $hook_data);
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::REVOKE_FOLLOW_CONTACT, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return $hook_data['result'];
|
return $hook_data['result'];
|
||||||
}
|
}
|
||||||
|
@ -256,7 +266,12 @@ class Protocol
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
'result' => null,
|
'result' => null,
|
||||||
];
|
];
|
||||||
Hook::callAll('block', $hook_data);
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::BLOCK_CONTACT, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return $hook_data['result'];
|
return $hook_data['result'];
|
||||||
}
|
}
|
||||||
|
@ -295,7 +310,12 @@ class Protocol
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
'result' => null,
|
'result' => null,
|
||||||
];
|
];
|
||||||
Hook::callAll('unblock', $hook_data);
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::UNBLOCK_CONTACT, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return $hook_data['result'];
|
return $hook_data['result'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ class UserSession implements IHandleUserSessions
|
||||||
public function getUserIDForVisitorContactID(int $cid): int
|
public function getUserIDForVisitorContactID(int $cid): int
|
||||||
{
|
{
|
||||||
if (empty($this->session->get('remote'))) {
|
if (empty($this->session->get('remote'))) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_search($cid, $this->session->get('remote'));
|
return array_search($cid, $this->session->get('remote'));
|
||||||
|
|
|
@ -20,7 +20,9 @@ use Friendica\Core\Storage\Capability\ICanWriteToStorage;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Core\Storage\Type;
|
use Friendica\Core\Storage\Type;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,6 +57,7 @@ class StorageManager
|
||||||
private $config;
|
private $config;
|
||||||
/** @var LoggerInterface */
|
/** @var LoggerInterface */
|
||||||
private $logger;
|
private $logger;
|
||||||
|
private EventDispatcherInterface $eventDispatcher;
|
||||||
/** @var L10n */
|
/** @var L10n */
|
||||||
private $l10n;
|
private $l10n;
|
||||||
|
|
||||||
|
@ -71,11 +74,12 @@ class StorageManager
|
||||||
* @throws InvalidClassStorageException in case the active backend class is invalid
|
* @throws InvalidClassStorageException in case the active backend class is invalid
|
||||||
* @throws StorageException in case of unexpected errors during the active backend class loading
|
* @throws StorageException in case of unexpected errors during the active backend class loading
|
||||||
*/
|
*/
|
||||||
public function __construct(Database $dba, IManageConfigValues $config, LoggerInterface $logger, L10n $l10n, bool $includeAddon = true)
|
public function __construct(Database $dba, IManageConfigValues $config, LoggerInterface $logger, EventDispatcherInterface $eventDispatcher, L10n $l10n, bool $includeAddon = true)
|
||||||
{
|
{
|
||||||
$this->dba = $dba;
|
$this->dba = $dba;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
$this->validBackends = $config->get('storage', 'backends', self::DEFAULT_BACKENDS);
|
$this->validBackends = $config->get('storage', 'backends', self::DEFAULT_BACKENDS);
|
||||||
|
|
||||||
|
@ -146,8 +150,12 @@ class StorageManager
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'storage_config' => null,
|
'storage_config' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Hook::callAll('storage_config', $data);
|
$data = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::STORAGE_CONFIG, $data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if (!($data['storage_config'] ?? null) instanceof ICanConfigureStorage) {
|
if (!($data['storage_config'] ?? null) instanceof ICanConfigureStorage) {
|
||||||
throw new InvalidClassStorageException(sprintf('Configuration for backend %s was not found', $name));
|
throw new InvalidClassStorageException(sprintf('Configuration for backend %s was not found', $name));
|
||||||
}
|
}
|
||||||
|
@ -201,8 +209,12 @@ class StorageManager
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'storage' => null,
|
'storage' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Hook::callAll('storage_instance', $data);
|
$data = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::STORAGE_INSTANCE, $data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if (!($data['storage'] ?? null) instanceof ICanReadFromStorage) {
|
if (!($data['storage'] ?? null) instanceof ICanReadFromStorage) {
|
||||||
throw new InvalidClassStorageException(sprintf('Backend %s was not found', $name));
|
throw new InvalidClassStorageException(sprintf('Backend %s was not found', $name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ class Database implements ICanWriteToStorage
|
||||||
throw new StorageException(sprintf('Database storage failed to update %s', $reference), 500, new Exception($this->dba->errorMessage(), $this->dba->errorNo()));
|
throw new StorageException(sprintf('Database storage failed to update %s', $reference), 500, new Exception($this->dba->errorMessage(), $this->dba->errorNo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->dba->lastInsertId();
|
return (string) $this->dba->lastInsertId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -452,19 +452,17 @@ class System
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current Load of the System
|
* Returns the current Load of the System
|
||||||
*
|
|
||||||
* @return integer
|
|
||||||
*/
|
*/
|
||||||
public static function currentLoad()
|
public static function currentLoad(): float
|
||||||
{
|
{
|
||||||
if (!function_exists('sys_getloadavg')) {
|
if (!function_exists('sys_getloadavg')) {
|
||||||
return false;
|
return (float) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$load_arr = sys_getloadavg();
|
$load_arr = sys_getloadavg();
|
||||||
|
|
||||||
if (!is_array($load_arr)) {
|
if (!is_array($load_arr)) {
|
||||||
return false;
|
return (float) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return round(max($load_arr[0], $load_arr[1]), 2);
|
return round(max($load_arr[0], $load_arr[1]), 2);
|
||||||
|
|
|
@ -217,7 +217,7 @@ class Update
|
||||||
->set('system', 'maintenance', false)
|
->set('system', 'maintenance', false)
|
||||||
->delete('system', 'maintenance_reason')
|
->delete('system', 'maintenance_reason')
|
||||||
->commit();
|
->commit();
|
||||||
return $r;
|
return 'Pre update failed';
|
||||||
} else {
|
} else {
|
||||||
DI::logger()->notice('Pre update executed.', ['version' => $version]);
|
DI::logger()->notice('Pre update executed.', ['version' => $version]);
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ class Update
|
||||||
->set('system', 'maintenance', false)
|
->set('system', 'maintenance', false)
|
||||||
->delete('system', 'maintenance_reason')
|
->delete('system', 'maintenance_reason')
|
||||||
->commit();
|
->commit();
|
||||||
return $r;
|
return 'Post update failed';
|
||||||
} else {
|
} else {
|
||||||
DI::config()->set('system', 'build', $version);
|
DI::config()->set('system', 'build', $version);
|
||||||
DI::logger()->notice('Post update executed.', ['version' => $version]);
|
DI::logger()->notice('Post update executed.', ['version' => $version]);
|
||||||
|
|
|
@ -13,6 +13,7 @@ use Friendica\Core\Logger\Type\WorkerLogger;
|
||||||
use Friendica\Core\Worker\Entity\Process;
|
use Friendica\Core\Worker\Entity\Process;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -271,12 +272,13 @@ class Worker
|
||||||
*
|
*
|
||||||
* @param integer $priority The priority that should be checked
|
* @param integer $priority The priority that should be checked
|
||||||
*
|
*
|
||||||
* @return integer Is there a process running with that priority?
|
* @return bool Is there a process running with that priority?
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private static function processWithPriorityActive(int $priority): int
|
private static function processWithPriorityActive(int $priority): bool
|
||||||
{
|
{
|
||||||
$condition = ["`priority` <= ? AND `pid` != 0 AND NOT `done`", $priority];
|
$condition = ["`priority` <= ? AND `pid` != 0 AND NOT `done`", $priority];
|
||||||
|
|
||||||
return DBA::exists('workerqueue', $condition);
|
return DBA::exists('workerqueue', $condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -955,7 +957,7 @@ class Worker
|
||||||
/**
|
/**
|
||||||
* Returns the priority of the next workerqueue job
|
* Returns the priority of the next workerqueue job
|
||||||
*
|
*
|
||||||
* @return string|bool priority or FALSE on failure
|
* @return int|false priority or FALSE on failure
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private static function nextPriority()
|
private static function nextPriority()
|
||||||
|
@ -1237,10 +1239,6 @@ class Worker
|
||||||
* @return int '0' if worker queue entry already existed or there had been an error, otherwise the ID of the worker task
|
* @return int '0' if worker queue entry already existed or there had been an error, otherwise the ID of the worker task
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
* @note $cmd and string args are surrounded with ''
|
* @note $cmd and string args are surrounded with ''
|
||||||
*
|
|
||||||
* @hooks 'proc_run'
|
|
||||||
* array $arr
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static function add(...$args)
|
public static function add(...$args)
|
||||||
{
|
{
|
||||||
|
@ -1250,7 +1248,12 @@ class Worker
|
||||||
|
|
||||||
$arr = ['args' => $args, 'run_cmd' => true];
|
$arr = ['args' => $args, 'run_cmd' => true];
|
||||||
|
|
||||||
Hook::callAll('proc_run', $arr);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$arr = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::ADD_WORKER_TASK, $arr),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if (!$arr['run_cmd'] || !count($args)) {
|
if (!$arr['run_cmd'] || !count($args)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
namespace Friendica\Core\Worker\Repository;
|
namespace Friendica\Core\Worker\Repository;
|
||||||
|
|
||||||
use Friendica\BaseRepository;
|
use Friendica\BaseRepository;
|
||||||
|
use Friendica\Core\Worker\Entity\Process as ProcessEntity;
|
||||||
use Friendica\Core\Worker\Exception\ProcessPersistenceException;
|
use Friendica\Core\Worker\Exception\ProcessPersistenceException;
|
||||||
|
use Friendica\Core\Worker\Factory\Process as ProcessFactory;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Core\Worker\Factory;
|
|
||||||
use Friendica\Core\Worker\Entity;
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,13 +24,13 @@ class Process extends BaseRepository
|
||||||
|
|
||||||
protected static $table_name = 'process';
|
protected static $table_name = 'process';
|
||||||
|
|
||||||
/** @var Factory\Process */
|
/** @var ProcessFactory */
|
||||||
protected $factory;
|
protected $factory;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $currentHost;
|
private $currentHost;
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\Process $factory, array $server)
|
public function __construct(Database $database, LoggerInterface $logger, ProcessFactory $factory, array $server)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
parent::__construct($database, $logger, $factory);
|
||||||
|
|
||||||
|
@ -39,13 +39,8 @@ class Process extends BaseRepository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts and Returns the process for a given PID at the current host
|
* Starts and Returns the process for a given PID at the current host
|
||||||
*
|
|
||||||
* @param int $pid
|
|
||||||
* @param string $command
|
|
||||||
*
|
|
||||||
* @return Entity\Process
|
|
||||||
*/
|
*/
|
||||||
public function create(int $pid, string $command): Entity\Process
|
public function create(int $pid, string $command): ProcessEntity
|
||||||
{
|
{
|
||||||
// Cleanup inactive process
|
// Cleanup inactive process
|
||||||
$this->deleteInactive();
|
$this->deleteInactive();
|
||||||
|
@ -64,7 +59,9 @@ class Process extends BaseRepository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->_selectOne(['pid' => $pid, 'hostname' => $this->currentHost]);
|
$fields = $this->_selectFirstRowAsArray(['pid' => $pid, 'hostname' => $this->currentHost]);
|
||||||
|
|
||||||
|
$result = $this->factory->createFromTableRow($fields);
|
||||||
|
|
||||||
$this->db->commit();
|
$this->db->commit();
|
||||||
|
|
||||||
|
@ -74,7 +71,7 @@ class Process extends BaseRepository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete(Entity\Process $process)
|
public function delete(ProcessEntity $process)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (!$this->db->delete(static::$table_name, [
|
if (!$this->db->delete(static::$table_name, [
|
||||||
|
|
|
@ -60,7 +60,7 @@ class Database
|
||||||
protected $syslock = null;
|
protected $syslock = null;
|
||||||
|
|
||||||
protected $server_info = '';
|
protected $server_info = '';
|
||||||
/** @var PDO|mysqli */
|
/** @var PDO|mysqli|null */
|
||||||
protected $connection;
|
protected $connection;
|
||||||
protected $driver = '';
|
protected $driver = '';
|
||||||
protected $pdo_emulate_prepares = false;
|
protected $pdo_emulate_prepares = false;
|
||||||
|
@ -253,7 +253,7 @@ class Database
|
||||||
/**
|
/**
|
||||||
* Return the database object.
|
* Return the database object.
|
||||||
*
|
*
|
||||||
* @return PDO|mysqli
|
* @return PDO|mysqli|null
|
||||||
*/
|
*/
|
||||||
public function getConnection()
|
public function getConnection()
|
||||||
{
|
{
|
||||||
|
@ -474,7 +474,7 @@ class Database
|
||||||
*
|
*
|
||||||
* @param string $sql SQL statement
|
* @param string $sql SQL statement
|
||||||
*
|
*
|
||||||
* @return bool|object statement object or result object
|
* @return bool|mysqli_result|mysqli_stmt|object|PDOStatement statement object or result object
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function p(string $sql)
|
public function p(string $sql)
|
||||||
|
|
|
@ -8,9 +8,8 @@
|
||||||
namespace Friendica\Database\Definition;
|
namespace Friendica\Database\Definition;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the whole database definition
|
* Stores the whole database definition
|
||||||
|
@ -109,12 +108,16 @@ class DbaDefinition
|
||||||
{
|
{
|
||||||
$definition = require $this->configFile;
|
$definition = require $this->configFile;
|
||||||
|
|
||||||
if (!$definition) {
|
if (!is_array($definition)) {
|
||||||
throw new Exception('Corrupted database structure config file static/dbstructure.config.php');
|
throw new Exception('Corrupted database structure config file static/dbstructure.config.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($withAddonStructure) {
|
if ($withAddonStructure) {
|
||||||
Hook::callAll('dbstructure_definition', $definition);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$definition = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::DB_STRUCTURE_DEFINITION, $definition),
|
||||||
|
)->getArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->definition = $definition;
|
$this->definition = $definition;
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
namespace Friendica\Database\Definition;
|
namespace Friendica\Database\Definition;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the whole View definitions
|
* Stores the whole View definitions
|
||||||
|
@ -62,12 +63,16 @@ class ViewDefinition
|
||||||
{
|
{
|
||||||
$definition = require $this->configFile;
|
$definition = require $this->configFile;
|
||||||
|
|
||||||
if (!$definition) {
|
if (!is_array($definition)) {
|
||||||
throw new Exception('Corrupted database structure config file static/dbstructure.config.php');
|
throw new Exception('Corrupted database structure config file static/dbstructure.config.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($withAddonStructure) {
|
if ($withAddonStructure) {
|
||||||
Hook::callAll('dbview_definition', $definition);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$definition = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::DB_VIEW_DEFINITION, $definition),
|
||||||
|
)->getArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->definition = $definition;
|
$this->definition = $definition;
|
||||||
|
|
|
@ -24,24 +24,96 @@ final class ArrayFilterEvent extends Event
|
||||||
|
|
||||||
public const FEATURE_GET = 'friendica.data.feature_get';
|
public const FEATURE_GET = 'friendica.data.feature_get';
|
||||||
|
|
||||||
public const POST_LOCAL_START = 'friendica.data.post_local_start';
|
public const PERMISSION_TOOLTIP_CONTENT = 'friendica.data.permission_tooltip_content';
|
||||||
|
|
||||||
public const POST_LOCAL = 'friendica.data.post_local';
|
public const INSERT_POST_LOCAL_START = 'friendica.data.insert_post_local_start';
|
||||||
|
|
||||||
public const POST_LOCAL_END = 'friendica.data.post_local_end';
|
public const INSERT_POST_LOCAL = 'friendica.data.insert_post_local';
|
||||||
|
|
||||||
|
public const INSERT_POST_LOCAL_END = 'friendica.data.insert_post_local_end';
|
||||||
|
|
||||||
|
public const INSERT_POST_REMOTE = 'friendica.data.insert_post_remote';
|
||||||
|
|
||||||
|
public const INSERT_POST_REMOTE_END = 'friendica.data.insert_post_remote_end';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* item array before any work
|
||||||
|
*/
|
||||||
|
public const PREPARE_POST_START = 'friendica.data.prepare_post_start';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* before first bbcode to html
|
||||||
|
*/
|
||||||
|
public const PREPARE_POST_FILTER_CONTENT = 'friendica.data.prepare_post_filter_content';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* after first bbcode to html
|
||||||
|
*/
|
||||||
|
public const PREPARE_POST = 'friendica.data.prepare_post';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* after attach icons and blockquote special case handling (spoiler, author)
|
||||||
|
*/
|
||||||
|
public const PREPARE_POST_END = 'friendica.data.prepare_post_end';
|
||||||
|
|
||||||
public const PHOTO_UPLOAD_FORM = 'friendica.data.photo_upload_form';
|
public const PHOTO_UPLOAD_FORM = 'friendica.data.photo_upload_form';
|
||||||
|
|
||||||
|
public const PHOTO_UPLOAD_START = 'friendica.data.photo_upload_start';
|
||||||
|
|
||||||
|
public const PHOTO_UPLOAD = 'friendica.data.photo_upload';
|
||||||
|
|
||||||
|
public const PHOTO_UPLOAD_END = 'friendica.data.photo_upload_end';
|
||||||
|
|
||||||
public const NETWORK_TO_NAME = 'friendica.data.network_to_name';
|
public const NETWORK_TO_NAME = 'friendica.data.network_to_name';
|
||||||
|
|
||||||
|
public const NETWORK_CONTENT_START = 'friendica.data.network_content_start';
|
||||||
|
|
||||||
|
public const NETWORK_CONTENT_TABS = 'friendica.data.network_content_tabs';
|
||||||
|
|
||||||
|
public const PARSE_LINK = 'friendica.data.parse_link';
|
||||||
|
|
||||||
public const CONVERSATION_START = 'friendica.data.conversation_start';
|
public const CONVERSATION_START = 'friendica.data.conversation_start';
|
||||||
|
|
||||||
|
public const FETCH_ITEM_BY_LINK = 'friendica.data.fetch_item_by_link';
|
||||||
|
|
||||||
|
public const ITEM_TAGGED = 'friendica.data.item_tagged';
|
||||||
|
|
||||||
public const DISPLAY_ITEM = 'friendica.data.display_item';
|
public const DISPLAY_ITEM = 'friendica.data.display_item';
|
||||||
|
|
||||||
|
public const CACHE_ITEM = 'friendica.data.cache_item';
|
||||||
|
|
||||||
|
public const CHECK_ITEM_NOTIFICATION = 'friendica.data.check_item_notification';
|
||||||
|
|
||||||
|
public const ENOTIFY = 'friendica.data.enotify';
|
||||||
|
|
||||||
|
public const ENOTIFY_STORE = 'friendica.data.enotify_store';
|
||||||
|
|
||||||
|
public const ENOTIFY_MAIL = 'friendica.data.enotify_mail';
|
||||||
|
|
||||||
|
public const DETECT_LANGUAGES = 'friendica.data.detect_languages';
|
||||||
|
|
||||||
public const RENDER_LOCATION = 'friendica.data.render_location';
|
public const RENDER_LOCATION = 'friendica.data.render_location';
|
||||||
|
|
||||||
public const ITEM_PHOTO_MENU = 'friendica.data.item_photo_menu';
|
public const ITEM_PHOTO_MENU = 'friendica.data.item_photo_menu';
|
||||||
|
|
||||||
|
public const DIRECTORY_ITEM = 'friendica.data.directory_item';
|
||||||
|
|
||||||
|
public const CONTACT_PHOTO_MENU = 'friendica.data.contact_photo_menu';
|
||||||
|
|
||||||
|
public const PROFILE_SIDEBAR_ENTRY = 'friendica.data.profile_sidebar_entry';
|
||||||
|
|
||||||
|
public const PROFILE_SIDEBAR = 'friendica.data.profile_sidebar';
|
||||||
|
|
||||||
|
public const PROFILE_TABS = 'friendica.data.profile_tabs';
|
||||||
|
|
||||||
|
public const PROFILE_SETTINGS_FORM = 'friendica.data.profile_settings_form';
|
||||||
|
|
||||||
|
public const PROFILE_SETTINGS_POST = 'friendica.data.profile_settings_post';
|
||||||
|
|
||||||
|
public const MODERATION_USERS_TABS = 'friendica.data.moderation_users_tabs';
|
||||||
|
|
||||||
|
public const ACL_LOOKUP_END = 'friendica.data.acl_lookup_end';
|
||||||
|
|
||||||
public const OEMBED_FETCH_END = 'friendica.data.oembed_fetch_end';
|
public const OEMBED_FETCH_END = 'friendica.data.oembed_fetch_end';
|
||||||
|
|
||||||
public const PAGE_INFO = 'friendica.data.page_info';
|
public const PAGE_INFO = 'friendica.data.page_info';
|
||||||
|
@ -62,6 +134,46 @@ final class ArrayFilterEvent extends Event
|
||||||
|
|
||||||
public const PROTOCOL_SUPPORTS_PROBE = 'friendica.data.protocol_supports_probe';
|
public const PROTOCOL_SUPPORTS_PROBE = 'friendica.data.protocol_supports_probe';
|
||||||
|
|
||||||
|
public const FOLLOW_CONTACT = 'friendica.data.follow_contact';
|
||||||
|
|
||||||
|
public const UNFOLLOW_CONTACT = 'friendica.data.unfollow_contact';
|
||||||
|
|
||||||
|
public const REVOKE_FOLLOW_CONTACT = 'friendica.data.revoke_follow_contact';
|
||||||
|
|
||||||
|
public const BLOCK_CONTACT = 'friendica.data.block_contact';
|
||||||
|
|
||||||
|
public const UNBLOCK_CONTACT = 'friendica.data.unblock_contact';
|
||||||
|
|
||||||
|
public const EDIT_CONTACT_FORM = 'friendica.data.edit_contact_form';
|
||||||
|
|
||||||
|
public const EDIT_CONTACT_POST = 'friendica.data.edit_contact_post';
|
||||||
|
|
||||||
|
public const AVATAR_LOOKUP = 'friendica.data.avatar_lookup';
|
||||||
|
|
||||||
|
public const ACCOUNT_AUTHENTICATE = 'friendica.data.account_authenticate';
|
||||||
|
|
||||||
|
public const ACCOUNT_REGISTER_FORM = 'friendica.data.account_register_form';
|
||||||
|
|
||||||
|
public const ACCOUNT_REGISTER_POST = 'friendica.data.account_register_post';
|
||||||
|
|
||||||
|
public const ACCOUNT_REGISTER = 'friendica.data.account_register';
|
||||||
|
|
||||||
|
public const ACCOUNT_REMOVE = 'friendica.data.account_remove';
|
||||||
|
|
||||||
|
public const EVENT_CREATED = 'friendica.data.event_created';
|
||||||
|
|
||||||
|
public const EVENT_UPDATED = 'friendica.data.event_updated';
|
||||||
|
|
||||||
|
public const ADD_WORKER_TASK = 'friendica.data.add_worker_task';
|
||||||
|
|
||||||
|
public const STORAGE_CONFIG = 'friendica.data.storage_config';
|
||||||
|
|
||||||
|
public const STORAGE_INSTANCE = 'friendica.data.storage_instance';
|
||||||
|
|
||||||
|
public const DB_STRUCTURE_DEFINITION = 'friendica.data.db_structure_definition';
|
||||||
|
|
||||||
|
public const DB_VIEW_DEFINITION = 'friendica.data.db_view_definition';
|
||||||
|
|
||||||
private array $array;
|
private array $array;
|
||||||
|
|
||||||
public function __construct(string $name, array $array)
|
public function __construct(string $name, array $array)
|
||||||
|
|
|
@ -26,6 +26,12 @@ final class HtmlFilterEvent extends Event
|
||||||
|
|
||||||
public const PAGE_END = 'friendica.html.page_end';
|
public const PAGE_END = 'friendica.html.page_end';
|
||||||
|
|
||||||
|
public const MOD_HOME_CONTENT = 'friendica.html.mod_home_content';
|
||||||
|
|
||||||
|
public const MOD_ABOUT_CONTENT = 'friendica.html.mod_about_content';
|
||||||
|
|
||||||
|
public const MOD_PROFILE_CONTENT = 'friendica.html.mod_profile_content';
|
||||||
|
|
||||||
public const JOT_TOOL = 'friendica.html.jot_tool';
|
public const JOT_TOOL = 'friendica.html.jot_tool';
|
||||||
|
|
||||||
public const CONTACT_BLOCK_END = 'friendica.html.contact_block_end';
|
public const CONTACT_BLOCK_END = 'friendica.html.contact_block_end';
|
||||||
|
|
|
@ -41,7 +41,6 @@ class Photo extends BaseFactory
|
||||||
* @param int $scale
|
* @param int $scale
|
||||||
* @param int $uid
|
* @param int $uid
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return Array
|
|
||||||
*/
|
*/
|
||||||
public function createFromId(string $photo_id, int $scale = null, int $uid, string $type = 'json', bool $with_posts = true): array
|
public function createFromId(string $photo_id, int $scale = null, int $uid, string $type = 'json', bool $with_posts = true): array
|
||||||
{
|
{
|
||||||
|
@ -66,7 +65,7 @@ class Photo extends BaseFactory
|
||||||
$data['id'] = $data['resource-id'];
|
$data['id'] = $data['resource-id'];
|
||||||
|
|
||||||
if (is_int($scale)) {
|
if (is_int($scale)) {
|
||||||
$data['data'] = base64_encode(ModelPhoto::getImageDataForPhoto($data));
|
$data['data'] = base64_encode(ModelPhoto::getImageDataForPhoto($data) ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type == 'xml') {
|
if ($type == 'xml') {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use Friendica\App\BaseURL;
|
||||||
use Friendica\BaseFactory;
|
use Friendica\BaseFactory;
|
||||||
use Friendica\Model\Attach;
|
use Friendica\Model\Attach;
|
||||||
use Friendica\Model\Photo;
|
use Friendica\Model\Photo;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
use Friendica\Util\Images;
|
use Friendica\Util\Images;
|
||||||
use Friendica\Util\Proxy;
|
use Friendica\Util\Proxy;
|
||||||
|
@ -32,7 +32,7 @@ class Attachment extends BaseFactory
|
||||||
/**
|
/**
|
||||||
* @param int $uriId Uri-ID of the attachments
|
* @param int $uriId Uri-ID of the attachments
|
||||||
* @return array
|
* @return array
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function createFromUriId(int $uriId): array
|
public function createFromUriId(int $uriId): array
|
||||||
{
|
{
|
||||||
|
@ -47,21 +47,23 @@ class Attachment extends BaseFactory
|
||||||
/**
|
/**
|
||||||
* @param int $id id of the media
|
* @param int $id id of the media
|
||||||
* @return \Friendica\Object\Api\Mastodon\Attachment
|
* @return \Friendica\Object\Api\Mastodon\Attachment
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function createFromId(int $id): \Friendica\Object\Api\Mastodon\Attachment
|
public function createFromId(int $id): \Friendica\Object\Api\Mastodon\Attachment
|
||||||
{
|
{
|
||||||
$attachment = Post\Media::getById($id);
|
$attachment = Post\Media::getById($id);
|
||||||
|
|
||||||
if (empty($attachment)) {
|
if (empty($attachment)) {
|
||||||
return [];
|
throw new InternalServerErrorException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->createFromMediaArray($attachment);
|
return $this->createFromMediaArray($attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $attachment
|
* @param array $attachment
|
||||||
* @return \Friendica\Object\Api\Mastodon\Attachment
|
* @return \Friendica\Object\Api\Mastodon\Attachment
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
private function createFromMediaArray(array $attachment): \Friendica\Object\Api\Mastodon\Attachment
|
private function createFromMediaArray(array $attachment): \Friendica\Object\Api\Mastodon\Attachment
|
||||||
{
|
{
|
||||||
|
@ -100,7 +102,7 @@ class Attachment extends BaseFactory
|
||||||
* @param int $id id of the photo
|
* @param int $id id of the photo
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function createFromPhoto(int $id): array
|
public function createFromPhoto(int $id): array
|
||||||
{
|
{
|
||||||
|
@ -136,7 +138,7 @@ class Attachment extends BaseFactory
|
||||||
* @param int $id id of the attachment
|
* @param int $id id of the attachment
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function createFromAttach(int $id): array
|
public function createFromAttach(int $id): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Status extends BaseFactory
|
||||||
private $mention;
|
private $mention;
|
||||||
/** @var Activities entity */
|
/** @var Activities entity */
|
||||||
private $activities;
|
private $activities;
|
||||||
/** @var Activities entity */
|
/** @var Attachment entity */
|
||||||
private $attachment;
|
private $attachment;
|
||||||
/** @var ContentItem */
|
/** @var ContentItem */
|
||||||
private $contentItem;
|
private $contentItem;
|
||||||
|
@ -165,7 +165,7 @@ class Status extends BaseFactory
|
||||||
$urls = $this->url->createFromUriId($item['uri-id']);
|
$urls = $this->url->createFromUriId($item['uri-id']);
|
||||||
$mentions = $this->mention->createFromUriId($item['uri-id']);
|
$mentions = $this->mention->createFromUriId($item['uri-id']);
|
||||||
} else {
|
} else {
|
||||||
$attachments = $this->attachment->createFromUriId($item['uri-id'], $text);
|
$attachments = $this->attachment->createFromUriId($item['uri-id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$friendica_activities = $this->activities->createFromUriId($item['uri-id'], $uid);
|
$friendica_activities = $this->activities->createFromUriId($item['uri-id'], $uid);
|
||||||
|
@ -180,7 +180,7 @@ class Status extends BaseFactory
|
||||||
$urls = array_merge($urls, $this->url->createFromUriId($shared_uri_id));
|
$urls = array_merge($urls, $this->url->createFromUriId($shared_uri_id));
|
||||||
$mentions = array_merge($mentions, $this->mention->createFromUriId($shared_uri_id));
|
$mentions = array_merge($mentions, $this->mention->createFromUriId($shared_uri_id));
|
||||||
} else {
|
} else {
|
||||||
$attachments = array_merge($attachments, $this->attachment->createFromUriId($shared_uri_id, $text));
|
$attachments = array_merge($attachments, $this->attachment->createFromUriId($shared_uri_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,26 +8,37 @@
|
||||||
namespace Friendica\Federation\Repository;
|
namespace Friendica\Federation\Repository;
|
||||||
|
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Federation\Factory;
|
use Friendica\Federation\Entity\GServer as GServerEntity;
|
||||||
use Friendica\Federation\Entity;
|
use Friendica\Federation\Factory\GServer as GServerFactory;
|
||||||
use Psr\Log\LoggerInterface;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
|
|
||||||
class GServer extends \Friendica\BaseRepository
|
final class GServer
|
||||||
{
|
{
|
||||||
protected static $table_name = 'gserver';
|
private string $table_name = 'gserver';
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\GServer $factory)
|
private Database $db;
|
||||||
|
|
||||||
|
private GServerFactory $factory;
|
||||||
|
|
||||||
|
public function __construct(Database $database, GServerFactory $factory)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
$this->db = $database;
|
||||||
|
$this->factory = $factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $gsid
|
* @param int $gsid
|
||||||
* @return Entity\GServer
|
*
|
||||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||||
*/
|
*/
|
||||||
public function selectOneById(int $gsid): Entity\GServer
|
public function selectOneById(int $gsid): GServerEntity
|
||||||
{
|
{
|
||||||
return $this->_selectOne(['id' => $gsid]);
|
$fields = $this->db->selectFirst($this->table_name, [], ['id' => $gsid], []);
|
||||||
|
|
||||||
|
if (!$this->db->isResult($fields)) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->factory->createFromTableRow($fields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException;
|
||||||
use Friendica\Content\Conversation as ConversationContent;
|
use Friendica\Content\Conversation as ConversationContent;
|
||||||
use Friendica\Content\Pager;
|
use Friendica\Content\Pager;
|
||||||
use Friendica\Content\Text\HTML;
|
use Friendica\Content\Text\HTML;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
|
@ -22,6 +21,7 @@ use Friendica\Core\Worker;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
||||||
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
||||||
use Friendica\Network\HTTPException\NotFoundException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
|
@ -1311,9 +1311,17 @@ class Contact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = ['contact' => $contact, 'menu' => &$menu];
|
$args = ['contact' => $contact, 'menu' => $menu];
|
||||||
|
|
||||||
Hook::callAll('contact_photo_menu', $args);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$args = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::CONTACT_PHOTO_MENU, $args),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
if (is_array($args['menu'])) {
|
||||||
|
$menu = $args['menu'];
|
||||||
|
}
|
||||||
|
|
||||||
$menucondensed = [];
|
$menucondensed = [];
|
||||||
|
|
||||||
|
@ -2196,7 +2204,11 @@ class Contact
|
||||||
$avatar['url'] = '';
|
$avatar['url'] = '';
|
||||||
$avatar['success'] = false;
|
$avatar['success'] = false;
|
||||||
|
|
||||||
Hook::callAll('avatar_lookup', $avatar);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$avatar = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::AVATAR_LOOKUP, $avatar),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if ($avatar['success'] && !empty($avatar['url'])) {
|
if ($avatar['success'] && !empty($avatar['url'])) {
|
||||||
return $avatar['url'];
|
return $avatar['url'];
|
||||||
|
@ -3144,7 +3156,11 @@ class Contact
|
||||||
|
|
||||||
$arr = ['url' => $url, 'uid' => $uid, 'contact' => []];
|
$arr = ['url' => $url, 'uid' => $uid, 'contact' => []];
|
||||||
|
|
||||||
Hook::callAll('follow', $arr);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$arr = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::FOLLOW_CONTACT, $arr),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if (empty($arr)) {
|
if (empty($arr)) {
|
||||||
$result['message'] = DI::l10n()->t('The contact could not be added. Please check the relevant network credentials in your Settings -> Social Networks page.');
|
$result['message'] = DI::l10n()->t('The contact could not be added. Please check the relevant network credentials in your Settings -> Social Networks page.');
|
||||||
|
|
|
@ -30,9 +30,8 @@ class User
|
||||||
* Insert a user-contact for a given contact array
|
* Insert a user-contact for a given contact array
|
||||||
*
|
*
|
||||||
* @param array $contact
|
* @param array $contact
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function insertForContactArray(array $contact)
|
public static function insertForContactArray(array $contact): bool
|
||||||
{
|
{
|
||||||
if (empty($contact['uid'])) {
|
if (empty($contact['uid'])) {
|
||||||
// We don't create entries for the public user - by now
|
// We don't create entries for the public user - by now
|
||||||
|
@ -339,7 +338,7 @@ class User
|
||||||
{
|
{
|
||||||
$pcid = Contact::getPublicContactId($cid, $uid);
|
$pcid = Contact::getPublicContactId($cid, $uid);
|
||||||
if (!$pcid) {
|
if (!$pcid) {
|
||||||
return false;
|
return self::FREQUENCY_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
$public_contact = DBA::selectFirst('user-contact', ['channel-frequency'], ['cid' => $pcid, 'uid' => $uid]);
|
$public_contact = DBA::selectFirst('user-contact', ['channel-frequency'], ['cid' => $pcid, 'uid' => $uid]);
|
||||||
|
|
|
@ -9,11 +9,11 @@ namespace Friendica\Model;
|
||||||
|
|
||||||
use Friendica\Content\Feature;
|
use Friendica\Content\Feature;
|
||||||
use Friendica\Content\Text\BBCode;
|
use Friendica\Content\Text\BBCode;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Friendica\Network\HTTPException\NotFoundException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
use Friendica\Network\HTTPException\UnauthorizedException;
|
use Friendica\Network\HTTPException\UnauthorizedException;
|
||||||
|
@ -255,6 +255,7 @@ class Event
|
||||||
'finish' => DateTimeFormat::utc(($arr['finish'] ?? '') ?: DBA::NULL_DATETIME),
|
'finish' => DateTimeFormat::utc(($arr['finish'] ?? '') ?: DBA::NULL_DATETIME),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
if ($event['finish'] < DBA::NULL_DATETIME) {
|
if ($event['finish'] < DBA::NULL_DATETIME) {
|
||||||
$event['finish'] = DBA::NULL_DATETIME;
|
$event['finish'] = DBA::NULL_DATETIME;
|
||||||
|
@ -295,17 +296,21 @@ class Event
|
||||||
Item::update($fields, ['id' => $item['id']]);
|
Item::update($fields, ['id' => $item['id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook::callAll('event_updated', $event['id']);
|
$eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::EVENT_UPDATED, ['event' => $event]),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// New event. Store it.
|
// New event. Store it.
|
||||||
DBA::insert('event', $event);
|
DBA::insert('event', $event);
|
||||||
|
|
||||||
$event['id'] = DBA::lastInsertId();
|
$event['id'] = DBA::lastInsertId();
|
||||||
|
|
||||||
Hook::callAll("event_created", $event['id']);
|
$eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::EVENT_CREATED, ['event' => $event]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $event['id'];
|
return (int) $event['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getItemArrayForId(int $event_id, array $item = []): array
|
public static function getItemArrayForId(int $event_id, array $item = []): array
|
||||||
|
@ -397,7 +402,7 @@ class Event
|
||||||
{
|
{
|
||||||
// First day of the week (0 = Sunday).
|
// First day of the week (0 = Sunday).
|
||||||
$firstDay = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'calendar', 'first_day_of_week') ?? 0;
|
$firstDay = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'calendar', 'first_day_of_week') ?? 0;
|
||||||
$defaultView = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'calendar', 'defaultView') ?? 'month';
|
$defaultView = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'calendar', 'default_view') ?? 'month';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'firstDay' => $firstDay,
|
'firstDay' => $firstDay,
|
||||||
|
|
|
@ -2200,8 +2200,6 @@ class GServer
|
||||||
* Converts input value to a boolean value
|
* Converts input value to a boolean value
|
||||||
*
|
*
|
||||||
* @param string|integer $val
|
* @param string|integer $val
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
private static function toBoolean($val): bool
|
private static function toBoolean($val): bool
|
||||||
{
|
{
|
||||||
|
@ -2211,7 +2209,7 @@ class GServer
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $val;
|
return (bool) $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,7 +14,6 @@ use Friendica\Content\Post\Collection\PostMedias;
|
||||||
use Friendica\Content\Post\Entity\PostMedia;
|
use Friendica\Content\Post\Entity\PostMedia;
|
||||||
use Friendica\Content\Text\BBCode;
|
use Friendica\Content\Text\BBCode;
|
||||||
use Friendica\Content\Text\HTML;
|
use Friendica\Content\Text\HTML;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
|
@ -672,7 +671,7 @@ class Item
|
||||||
/**
|
/**
|
||||||
* Inserts item record
|
* Inserts item record
|
||||||
*
|
*
|
||||||
* @param array $item Item array to be inserted
|
* @param array<string,mixed> $item Item array to be inserted
|
||||||
* @param int $notify Notification (type?)
|
* @param int $notify Notification (type?)
|
||||||
* @param bool $post_local (???)
|
* @param bool $post_local (???)
|
||||||
* @return int Zero means error, otherwise primary key (id) is being returned
|
* @return int Zero means error, otherwise primary key (id) is being returned
|
||||||
|
@ -695,6 +694,7 @@ class Item
|
||||||
|
|
||||||
// If it is a posting where users should get notifications, then define it as wall posting
|
// If it is a posting where users should get notifications, then define it as wall posting
|
||||||
if ($notify) {
|
if ($notify) {
|
||||||
|
/** @var array<string,mixed> */
|
||||||
$item = $itemHelper->prepareOriginPost($item);
|
$item = $itemHelper->prepareOriginPost($item);
|
||||||
|
|
||||||
if (is_int($notify) && in_array($notify, Worker::PRIORITIES)) {
|
if (is_int($notify) && in_array($notify, Worker::PRIORITIES)) {
|
||||||
|
@ -708,6 +708,7 @@ class Item
|
||||||
$item['network'] = trim(($item['network'] ?? '') ?: Protocol::PHANTOM);
|
$item['network'] = trim(($item['network'] ?? '') ?: Protocol::PHANTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var array<string,mixed> */
|
||||||
$item = $itemHelper->prepareItemData($item, (bool) $notify);
|
$item = $itemHelper->prepareItemData($item, (bool) $notify);
|
||||||
|
|
||||||
// Store conversation data
|
// Store conversation data
|
||||||
|
@ -749,6 +750,7 @@ class Item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var array<string,mixed> */
|
||||||
$item = $itemHelper->validateItemData($item);
|
$item = $itemHelper->validateItemData($item);
|
||||||
|
|
||||||
// Ensure that there is an avatar cache
|
// Ensure that there is an avatar cache
|
||||||
|
@ -846,16 +848,26 @@ class Item
|
||||||
$dummy_session = false;
|
$dummy_session = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$item = $eventDispatcher->dispatch(
|
$hook_data = [
|
||||||
new ArrayFilterEvent(ArrayFilterEvent::POST_LOCAL, $item)
|
'item' => $item,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::INSERT_POST_LOCAL, $hook_data)
|
||||||
)->getArray();
|
)->getArray();
|
||||||
|
|
||||||
|
/** @var array<string,mixed> */
|
||||||
|
$item = $hook_data['item'] ?? $item;
|
||||||
|
|
||||||
if ($dummy_session) {
|
if ($dummy_session) {
|
||||||
unset($_SESSION['authenticated']);
|
unset($_SESSION['authenticated']);
|
||||||
unset($_SESSION['uid']);
|
unset($_SESSION['uid']);
|
||||||
}
|
}
|
||||||
} elseif (!$notify) {
|
} elseif (!$notify) {
|
||||||
Hook::callAll('post_remote', $item);
|
/** @var array<string,mixed> */
|
||||||
|
$item = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::INSERT_POST_REMOTE, $item)
|
||||||
|
)->getArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($item['cancel'])) {
|
if (!empty($item['cancel'])) {
|
||||||
|
@ -1112,7 +1124,11 @@ class Item
|
||||||
DI::contentItem()->copyPermissions($posted_item['thr-parent-id'], $posted_item['uri-id'], $posted_item['parent-uri-id']);
|
DI::contentItem()->copyPermissions($posted_item['thr-parent-id'], $posted_item['uri-id'], $posted_item['parent-uri-id']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Hook::callAll('post_remote_end', $posted_item);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$posted_item = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::INSERT_POST_REMOTE_END, $posted_item)
|
||||||
|
)->getArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($posted_item['gravity'] === self::GRAVITY_PARENT) {
|
if ($posted_item['gravity'] === self::GRAVITY_PARENT) {
|
||||||
|
@ -1897,18 +1913,23 @@ class Item
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
foreach (self::splitByBlocks($searchtext) as $block) {
|
foreach (self::splitByBlocks($searchtext) as $block) {
|
||||||
$languages = $ld->detect($block)->close() ?: [];
|
$languages = $ld->detect($block)->close() ?: [];
|
||||||
|
|
||||||
$data = [
|
$hook_data = [
|
||||||
'text' => $block,
|
'text' => $block,
|
||||||
'detected' => $languages,
|
'detected' => $languages,
|
||||||
'uri-id' => $uri_id,
|
'uri-id' => $uri_id,
|
||||||
'author-id' => $author_id,
|
'author-id' => $author_id,
|
||||||
];
|
];
|
||||||
Hook::callAll('detect_languages', $data);
|
|
||||||
|
|
||||||
foreach ($data['detected'] as $language => $quality) {
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::DETECT_LANGUAGES, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
foreach ($hook_data['detected'] as $language => $quality) {
|
||||||
$result[$language] = max($result[$language] ?? 0, $quality * (strlen($block) / strlen($searchtext)));
|
$result[$language] = max($result[$language] ?? 0, $quality * (strlen($block) / strlen($searchtext)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2274,9 +2295,16 @@ class Item
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr = ['item' => $item, 'user' => $owner];
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
Hook::callAll('tagged', $arr);
|
$arr = [
|
||||||
|
'item' => $item,
|
||||||
|
'user' => $owner,
|
||||||
|
];
|
||||||
|
|
||||||
|
$eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::ITEM_TAGGED, $arr),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (Tag::isMentioned($item['parent-uri-id'], $owner['url'])) {
|
if (Tag::isMentioned($item['parent-uri-id'], $owner['url'])) {
|
||||||
DI::logger()->info('Mention found in parent tag.', ['uri' => $item['uri'], 'uid' => $uid, 'id' => $item_id, 'uri-id' => $item['uri-id'], 'guid' => $item['guid']]);
|
DI::logger()->info('Mention found in parent tag.', ['uri' => $item['uri'], 'uid' => $uid, 'id' => $item_id, 'uri-id' => $item['uri-id'], 'guid' => $item['guid']]);
|
||||||
|
@ -3020,8 +3048,18 @@ class Item
|
||||||
$item['rendered-html'] = BBCode::convertForUriId($item['uri-id'], $item['body']);
|
$item['rendered-html'] = BBCode::convertForUriId($item['uri-id'], $item['body']);
|
||||||
$item['rendered-hash'] = hash('md5', BBCode::VERSION . '::' . $body);
|
$item['rendered-hash'] = hash('md5', BBCode::VERSION . '::' . $body);
|
||||||
|
|
||||||
$hook_data = ['item' => $item, 'rendered-html' => $item['rendered-html'], 'rendered-hash' => $item['rendered-hash']];
|
$hook_data = [
|
||||||
Hook::callAll('put_item_in_cache', $hook_data);
|
'rendered-html' => $item['rendered-html'],
|
||||||
|
'rendered-hash' => $item['rendered-hash'],
|
||||||
|
'item' => $item,
|
||||||
|
];
|
||||||
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::CACHE_ITEM, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
$item['rendered-html'] = $hook_data['rendered-html'];
|
$item['rendered-html'] = $hook_data['rendered-html'];
|
||||||
$item['rendered-hash'] = $hook_data['rendered-hash'];
|
$item['rendered-hash'] = $hook_data['rendered-hash'];
|
||||||
unset($hook_data);
|
unset($hook_data);
|
||||||
|
@ -3052,16 +3090,22 @@ class Item
|
||||||
* @return string item body html
|
* @return string item body html
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
* @hook prepare_body_init item array before any work
|
|
||||||
* @hook prepare_body_content_filter ('item'=>item array, 'filter_reasons'=>string array) before first bbcode to html
|
|
||||||
* @hook prepare_body ('item'=>item array, 'html'=>body string, 'is_preview'=>boolean, 'filter_reasons'=>string array) after first bbcode to html
|
|
||||||
* @hook prepare_body_final ('item'=>item array, 'html'=>body string) after attach icons and blockquote special case handling (spoiler, author)
|
|
||||||
*/
|
*/
|
||||||
public static function prepareBody(array &$item, bool $attach = false, bool $is_preview = false, bool $only_cache = false): string
|
public static function prepareBody(array &$item, bool $attach = false, bool $is_preview = false, bool $only_cache = false): string
|
||||||
{
|
{
|
||||||
$appHelper = DI::appHelper();
|
$appHelper = DI::appHelper();
|
||||||
$uid = DI::userSession()->getLocalUserId();
|
$uid = DI::userSession()->getLocalUserId();
|
||||||
Hook::callAll('prepare_body_init', $item);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = [
|
||||||
|
'item' => $item,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::PREPARE_POST_START, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
$item = $hook_data['item'] ?? $item;
|
||||||
|
|
||||||
// In order to provide theme developers more possibilities, event items
|
// In order to provide theme developers more possibilities, event items
|
||||||
// are treated differently.
|
// are treated differently.
|
||||||
|
@ -3180,7 +3224,11 @@ class Item
|
||||||
'item' => $item,
|
'item' => $item,
|
||||||
'filter_reasons' => $filter_reasons
|
'filter_reasons' => $filter_reasons
|
||||||
];
|
];
|
||||||
Hook::callAll('prepare_body_content_filter', $hook_data);
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::PREPARE_POST_FILTER_CONTENT, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
$filter_reasons = $hook_data['filter_reasons'];
|
$filter_reasons = $hook_data['filter_reasons'];
|
||||||
unset($hook_data);
|
unset($hook_data);
|
||||||
}
|
}
|
||||||
|
@ -3199,7 +3247,11 @@ class Item
|
||||||
'preview' => $is_preview,
|
'preview' => $is_preview,
|
||||||
'filter_reasons' => $filter_reasons
|
'filter_reasons' => $filter_reasons
|
||||||
];
|
];
|
||||||
Hook::callAll('prepare_body', $hook_data);
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::PREPARE_POST, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
$s = $hook_data['html'];
|
$s = $hook_data['html'];
|
||||||
|
|
||||||
unset($hook_data);
|
unset($hook_data);
|
||||||
|
@ -3251,9 +3303,16 @@ class Item
|
||||||
|
|
||||||
$s = HTML::applyContentFilter($s, $filter_reasons);
|
$s = HTML::applyContentFilter($s, $filter_reasons);
|
||||||
|
|
||||||
$hook_data = ['item' => $item, 'html' => $s];
|
$hook_data = [
|
||||||
Hook::callAll('prepare_body_final', $hook_data);
|
'item' => $item,
|
||||||
return $hook_data['html'];
|
'html' => $s,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::PREPARE_POST_END, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
return (string) $hook_data['html'] ?? $s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3271,7 +3330,7 @@ class Item
|
||||||
}
|
}
|
||||||
|
|
||||||
$dom = new \DOMDocument();
|
$dom = new \DOMDocument();
|
||||||
if (!@$dom->loadHTML($html)) {
|
if (empty($html) || !@$dom->loadHTML($html)) {
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3902,17 +3961,21 @@ class Item
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hookData = [
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = [
|
||||||
'uri' => $uri,
|
'uri' => $uri,
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
'item_id' => null,
|
'item_id' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
Hook::callAll('item_by_link', $hookData);
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::FETCH_ITEM_BY_LINK, $hook_data)
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if (isset($hookData['item_id'])) {
|
if (isset($hook_data['item_id'])) {
|
||||||
DI::logger()->info('Hook link fetched', ['uid' => $uid, 'uri' => $uri, 'id' => $hookData['item_id']]);
|
DI::logger()->info('Hook link fetched', ['uid' => $uid, 'uri' => $uri, 'id' => $hook_data['item_id']]);
|
||||||
return is_numeric($hookData['item_id']) ? $hookData['item_id'] : 0;
|
return is_numeric($hook_data['item_id']) ? $hook_data['item_id'] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$mimetype) {
|
if (!$mimetype) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ class ParsedLogIterator implements \Iterator
|
||||||
/** @var ReversedFileReader */
|
/** @var ReversedFileReader */
|
||||||
private $reader;
|
private $reader;
|
||||||
|
|
||||||
/** @var ParsedLogLine current iterator value*/
|
/** @var ParsedLogLine|null current iterator value*/
|
||||||
private $value = null;
|
private $value = null;
|
||||||
|
|
||||||
/** @var int max number of lines to read */
|
/** @var int max number of lines to read */
|
||||||
|
|
|
@ -7,11 +7,9 @@
|
||||||
|
|
||||||
namespace Friendica\Model;
|
namespace Friendica\Model;
|
||||||
|
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\Item;
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,11 +26,12 @@ class Nodeinfo
|
||||||
{
|
{
|
||||||
$config = DI::config();
|
$config = DI::config();
|
||||||
$logger = DI::logger();
|
$logger = DI::logger();
|
||||||
|
$addonHelper = DI::addonHelper();
|
||||||
|
|
||||||
// If the addon 'statistics_json' is enabled then disable it and activate nodeinfo.
|
// If the addon 'statistics_json' is enabled then disable it and activate nodeinfo.
|
||||||
if (Addon::isEnabled('statistics_json')) {
|
if ($addonHelper->isAddonEnabled('statistics_json')) {
|
||||||
$config->set('system', 'nodeinfo', true);
|
$config->set('system', 'nodeinfo', true);
|
||||||
Addon::uninstall('statistics_json');
|
$addonHelper->uninstallAddon('statistics_json');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($config->get('system', 'nodeinfo'))) {
|
if (empty($config->get('system', 'nodeinfo'))) {
|
||||||
|
@ -66,14 +65,14 @@ class Nodeinfo
|
||||||
/**
|
/**
|
||||||
* Return the supported services
|
* Return the supported services
|
||||||
*
|
*
|
||||||
* @return Object with supported services
|
* @return stdClass with supported services
|
||||||
*/
|
*/
|
||||||
public static function getUsage(bool $version2 = false)
|
public static function getUsage(bool $version2 = false): stdClass
|
||||||
{
|
{
|
||||||
$config = DI::config();
|
$config = DI::config();
|
||||||
|
|
||||||
$usage = new stdClass();
|
$usage = new stdClass();
|
||||||
$usage->users = new \stdClass;
|
$usage->users = new stdClass();
|
||||||
|
|
||||||
if (!empty($config->get('system', 'nodeinfo'))) {
|
if (!empty($config->get('system', 'nodeinfo'))) {
|
||||||
$usage->users->total = intval(DI::keyValue()->get('nodeinfo_total_users'));
|
$usage->users->total = intval(DI::keyValue()->get('nodeinfo_total_users'));
|
||||||
|
@ -97,45 +96,47 @@ class Nodeinfo
|
||||||
*/
|
*/
|
||||||
public static function getServices(): array
|
public static function getServices(): array
|
||||||
{
|
{
|
||||||
|
$addonHelper = DI::addonHelper();
|
||||||
|
|
||||||
$services = [
|
$services = [
|
||||||
'inbound' => [],
|
'inbound' => [],
|
||||||
'outbound' => [],
|
'outbound' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
if (Addon::isEnabled('bluesky')) {
|
if ($addonHelper->isAddonEnabled('bluesky')) {
|
||||||
$services['inbound'][] = 'bluesky';
|
$services['inbound'][] = 'bluesky';
|
||||||
$services['outbound'][] = 'bluesky';
|
$services['outbound'][] = 'bluesky';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('dwpost')) {
|
if ($addonHelper->isAddonEnabled('dwpost')) {
|
||||||
$services['outbound'][] = 'dreamwidth';
|
$services['outbound'][] = 'dreamwidth';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('statusnet')) {
|
if ($addonHelper->isAddonEnabled('statusnet')) {
|
||||||
$services['inbound'][] = 'gnusocial';
|
$services['inbound'][] = 'gnusocial';
|
||||||
$services['outbound'][] = 'gnusocial';
|
$services['outbound'][] = 'gnusocial';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('ijpost')) {
|
if ($addonHelper->isAddonEnabled('ijpost')) {
|
||||||
$services['outbound'][] = 'insanejournal';
|
$services['outbound'][] = 'insanejournal';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('libertree')) {
|
if ($addonHelper->isAddonEnabled('libertree')) {
|
||||||
$services['outbound'][] = 'libertree';
|
$services['outbound'][] = 'libertree';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('ljpost')) {
|
if ($addonHelper->isAddonEnabled('ljpost')) {
|
||||||
$services['outbound'][] = 'livejournal';
|
$services['outbound'][] = 'livejournal';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('pumpio')) {
|
if ($addonHelper->isAddonEnabled('pumpio')) {
|
||||||
$services['inbound'][] = 'pumpio';
|
$services['inbound'][] = 'pumpio';
|
||||||
$services['outbound'][] = 'pumpio';
|
$services['outbound'][] = 'pumpio';
|
||||||
}
|
}
|
||||||
|
|
||||||
$services['outbound'][] = 'smtp';
|
$services['outbound'][] = 'smtp';
|
||||||
|
|
||||||
if (Addon::isEnabled('tumblr')) {
|
if ($addonHelper->isAddonEnabled('tumblr')) {
|
||||||
$services['outbound'][] = 'tumblr';
|
$services['outbound'][] = 'tumblr';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('twitter')) {
|
if ($addonHelper->isAddonEnabled('twitter')) {
|
||||||
$services['outbound'][] = 'twitter';
|
$services['outbound'][] = 'twitter';
|
||||||
}
|
}
|
||||||
if (Addon::isEnabled('wppost')) {
|
if ($addonHelper->isAddonEnabled('wppost')) {
|
||||||
$services['outbound'][] = 'wordpress';
|
$services['outbound'][] = 'wordpress';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,7 +244,7 @@ class Photo
|
||||||
*
|
*
|
||||||
* @param array $photo Photo data. Needs at least 'id', 'type', 'backend-class', 'backend-ref'
|
* @param array $photo Photo data. Needs at least 'id', 'type', 'backend-class', 'backend-ref'
|
||||||
*
|
*
|
||||||
* @return \Friendica\Object\Image|null Image object or null on error
|
* @return string|null Image data as string or null on error
|
||||||
*/
|
*/
|
||||||
public static function getImageDataForPhoto(array $photo)
|
public static function getImageDataForPhoto(array $photo)
|
||||||
{
|
{
|
||||||
|
@ -254,7 +254,7 @@ class Photo
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$backendClass = DI::storageManager()->getByName($photo['backend-class'] ?? '');
|
$backendClass = DI::storageManager()->getByName($photo['backend-class'] ?? '');
|
||||||
/// @todo refactoring this returning, because the storage returns a "string" which is casted in different ways - a check "instanceof Image" will fail!
|
|
||||||
return $backendClass->get($photo['backend-ref'] ?? '');
|
return $backendClass->get($photo['backend-ref'] ?? '');
|
||||||
} catch (InvalidClassStorageException $storageException) {
|
} catch (InvalidClassStorageException $storageException) {
|
||||||
try {
|
try {
|
||||||
|
@ -834,10 +834,9 @@ class Photo
|
||||||
* - Sharing a post with a group will create a photo that only the group can see.
|
* - Sharing a post with a group will create a photo that only the group can see.
|
||||||
* - Sharing a photo again that been shared non public before doesn't alter the permissions.
|
* - Sharing a photo again that been shared non public before doesn't alter the permissions.
|
||||||
*
|
*
|
||||||
* @return string
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function setPermissionFromBody($body, $uid, $original_contact_id, $str_contact_allow, $str_circle_allow, $str_contact_deny, $str_circle_deny)
|
public static function setPermissionFromBody($body, $uid, $original_contact_id, $str_contact_allow, $str_circle_allow, $str_contact_deny, $str_circle_deny): bool
|
||||||
{
|
{
|
||||||
// Simplify image codes
|
// Simplify image codes
|
||||||
$img_body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
|
$img_body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
|
||||||
|
|
|
@ -170,9 +170,8 @@ class Delayed
|
||||||
* @param array $attachments
|
* @param array $attachments
|
||||||
* @param int $preparation_mode
|
* @param int $preparation_mode
|
||||||
* @param string $uri
|
* @param string $uri
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public static function publish(array $item, int $notify = 0, array $taglist = [], array $attachments = [], int $preparation_mode = self::PREPARED, string $uri = '')
|
public static function publish(array $item, int $notify = 0, array $taglist = [], array $attachments = [], int $preparation_mode = self::PREPARED, string $uri = ''): int
|
||||||
{
|
{
|
||||||
if (!empty($attachments)) {
|
if (!empty($attachments)) {
|
||||||
$item['attachments'] = $attachments;
|
$item['attachments'] = $attachments;
|
||||||
|
|
|
@ -9,10 +9,10 @@ namespace Friendica\Model\Post;
|
||||||
|
|
||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
use Friendica\Model\Item;
|
use Friendica\Model\Item;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
|
@ -396,7 +396,12 @@ class UserNotification
|
||||||
$profiles = [$owner['nurl']];
|
$profiles = [$owner['nurl']];
|
||||||
|
|
||||||
$notification_data = ['uid' => $uid, 'profiles' => []];
|
$notification_data = ['uid' => $uid, 'profiles' => []];
|
||||||
Hook::callAll('check_item_notification', $notification_data);
|
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$notification_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::CHECK_ITEM_NOTIFICATION, $notification_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
// Normalize the connector profiles
|
// Normalize the connector profiles
|
||||||
foreach ($notification_data['profiles'] as $profile) {
|
foreach ($notification_data['profiles'] as $profile) {
|
||||||
|
|
|
@ -12,13 +12,13 @@ use Friendica\AppHelper;
|
||||||
use Friendica\Content\Text\BBCode;
|
use Friendica\Content\Text\BBCode;
|
||||||
use Friendica\Content\Widget\ContactBlock;
|
use Friendica\Content\Widget\ContactBlock;
|
||||||
use Friendica\Core\Cache\Enum\Duration;
|
use Friendica\Core\Cache\Enum\Duration;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Search;
|
use Friendica\Core\Search;
|
||||||
use Friendica\Core\Worker;
|
use Friendica\Core\Worker;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Protocol\Activity;
|
use Friendica\Protocol\Activity;
|
||||||
use Friendica\Protocol\Diaspora;
|
use Friendica\Protocol\Diaspora;
|
||||||
|
@ -258,11 +258,6 @@ class Profile
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
* @note Returns empty string if passed $profile is wrong type or not populated
|
* @note Returns empty string if passed $profile is wrong type or not populated
|
||||||
*
|
|
||||||
* @hooks 'profile_sidebar_enter'
|
|
||||||
* array $profile - profile data
|
|
||||||
* @hooks 'profile_sidebar'
|
|
||||||
* array $arr
|
|
||||||
*/
|
*/
|
||||||
public static function getVCardHtml(array $profile, bool $block, bool $show_contacts): string
|
public static function getVCardHtml(array $profile, bool $block, bool $show_contacts): string
|
||||||
{
|
{
|
||||||
|
@ -282,7 +277,17 @@ class Profile
|
||||||
|
|
||||||
$profile['network_link'] = '';
|
$profile['network_link'] = '';
|
||||||
|
|
||||||
Hook::callAll('profile_sidebar_enter', $profile);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = [
|
||||||
|
'profile' => $profile,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::PROFILE_SIDEBAR_ENTRY, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
$profile = $hook_data['profile'] ?? $profile;
|
||||||
|
|
||||||
$profile_url = $profile['url'];
|
$profile_url = $profile['url'];
|
||||||
|
|
||||||
|
@ -473,9 +478,17 @@ class Profile
|
||||||
'$network_url' => $network_url,
|
'$network_url' => $network_url,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$arr = ['profile' => &$profile, 'entry' => &$o];
|
$hook_data = [
|
||||||
|
'profile' => &$profile,
|
||||||
|
'entry' => &$o,
|
||||||
|
];
|
||||||
|
|
||||||
Hook::callAll('profile_sidebar', $arr);
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::PROFILE_SIDEBAR, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
$profile = $hook_data['profile'] ?? $profile;
|
||||||
|
$o = $hook_data['entry'] ?? $o;
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ use ErrorException;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
use Friendica\Content\Pager;
|
use Friendica\Content\Pager;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\Search;
|
use Friendica\Core\Search;
|
||||||
|
@ -21,6 +20,7 @@ use Friendica\Core\System;
|
||||||
use Friendica\Core\Worker;
|
use Friendica\Core\Worker;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Module;
|
use Friendica\Module;
|
||||||
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
||||||
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
||||||
|
@ -758,12 +758,16 @@ class User
|
||||||
'user_record' => null
|
'user_record' => null
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
/**
|
||||||
* An addon indicates successful login by setting 'authenticated' to non-zero value and returning a user record
|
* An addon indicates successful login by setting 'authenticated' to non-zero value and returning a user record
|
||||||
* Addons should never set 'authenticated' except to indicate success - as hooks may be chained
|
* Addons should never set 'authenticated' except to indicate success - as hooks may be chained
|
||||||
* and later addons should not interfere with an earlier one that succeeded.
|
* and later addons should not interfere with an earlier one that succeeded.
|
||||||
*/
|
*/
|
||||||
Hook::callAll('authenticate', $addon_auth);
|
$addon_auth = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_AUTHENTICATE, $addon_auth),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if ($addon_auth['authenticated'] && $addon_auth['user_record']) {
|
if ($addon_auth['authenticated'] && $addon_auth['user_record']) {
|
||||||
return $addon_auth['user_record']['uid'];
|
return $addon_auth['user_record']['uid'];
|
||||||
|
@ -1460,11 +1464,20 @@ class User
|
||||||
Contact::updateSelfFromUserID($uid, true);
|
Contact::updateSelfFromUserID($uid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook::callAll('register_account', $uid);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = [
|
||||||
|
'uid' => $uid,
|
||||||
|
];
|
||||||
|
|
||||||
|
$eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_REGISTER, $hook_data),
|
||||||
|
);
|
||||||
|
|
||||||
self::setRegisterMethodByUserCount();
|
self::setRegisterMethodByUserCount();
|
||||||
|
|
||||||
$return['user'] = $user;
|
$return['user'] = $user;
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1787,7 +1800,17 @@ class User
|
||||||
throw new \RuntimeException(DI::l10n()->t("User with delegates can't be removed, please remove delegate users first"));
|
throw new \RuntimeException(DI::l10n()->t("User with delegates can't be removed, please remove delegate users first"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook::callAll('remove_user', $user);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = [
|
||||||
|
'user' => $user,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::ACCOUNT_REMOVE, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
$user = $hook_data['user'] ?? $user;
|
||||||
|
|
||||||
// save username (actually the nickname as it is guaranteed
|
// save username (actually the nickname as it is guaranteed
|
||||||
// unique), so it cannot be re-registered in the future.
|
// unique), so it cannot be re-registered in the future.
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
|
|
||||||
namespace Friendica\Moderation\Repository;
|
namespace Friendica\Moderation\Repository;
|
||||||
|
|
||||||
use Friendica\BaseEntity;
|
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\DI;
|
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
use Friendica\Moderation\Factory;
|
use Friendica\Moderation\Collection\Report\Posts as PostsCollection;
|
||||||
use Friendica\Moderation\Collection;
|
use Friendica\Moderation\Collection\Report\Rules as RulesCollection;
|
||||||
|
use Friendica\Moderation\Entity\Report as ReportEntity;
|
||||||
|
use Friendica\Moderation\Factory\Report as ReportFactory;
|
||||||
|
use Friendica\Moderation\Factory\Report\Post as PostFactory;
|
||||||
|
use Friendica\Moderation\Factory\Report\Rule as RuleFactory;
|
||||||
use Friendica\Network\HTTPException\NotFoundException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
@ -21,14 +23,14 @@ final class Report extends \Friendica\BaseRepository
|
||||||
{
|
{
|
||||||
protected static $table_name = 'report';
|
protected static $table_name = 'report';
|
||||||
|
|
||||||
/** @var Factory\Report */
|
/** @var ReportFactory */
|
||||||
protected $factory;
|
protected $factory;
|
||||||
/** @var Factory\Report\Post */
|
/** @var PostFactory */
|
||||||
protected $postFactory;
|
protected $postFactory;
|
||||||
/** @var Factory\Report\Rule */
|
/** @var RuleFactory */
|
||||||
protected $ruleFactory;
|
protected $ruleFactory;
|
||||||
|
|
||||||
public function __construct(Database $database, LoggerInterface $logger, Factory\Report $factory, Factory\Report\Post $postFactory, Factory\Report\Rule $ruleFactory)
|
public function __construct(Database $database, LoggerInterface $logger, ReportFactory $factory, PostFactory $postFactory, RuleFactory $ruleFactory)
|
||||||
{
|
{
|
||||||
parent::__construct($database, $logger, $factory);
|
parent::__construct($database, $logger, $factory);
|
||||||
|
|
||||||
|
@ -37,12 +39,12 @@ final class Report extends \Friendica\BaseRepository
|
||||||
$this->ruleFactory = $ruleFactory;
|
$this->ruleFactory = $ruleFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function selectOneById(int $lastInsertId): \Friendica\Moderation\Entity\Report
|
public function selectOneById(int $lastInsertId): ReportEntity
|
||||||
{
|
{
|
||||||
return $this->_selectOne(['id' => $lastInsertId]);
|
return $this->_selectOne(['id' => $lastInsertId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(\Friendica\Moderation\Entity\Report $Report): \Friendica\Moderation\Entity\Report
|
public function save(ReportEntity $Report): ReportEntity
|
||||||
{
|
{
|
||||||
$fields = [
|
$fields = [
|
||||||
'reporter-id' => $Report->reporterCid,
|
'reporter-id' => $Report->reporterCid,
|
||||||
|
@ -73,7 +75,7 @@ final class Report extends \Friendica\BaseRepository
|
||||||
if (Post::exists(['uri-id' => $post->uriId])) {
|
if (Post::exists(['uri-id' => $post->uriId])) {
|
||||||
$this->db->insert('report-post', ['rid' => $newReportId, 'uri-id' => $post->uriId, 'status' => $post->status]);
|
$this->db->insert('report-post', ['rid' => $newReportId, 'uri-id' => $post->uriId, 'status' => $post->status]);
|
||||||
} else {
|
} else {
|
||||||
DI::logger()->notice('Post does not exist', ['uri-id' => $post->uriId, 'report' => $Report]);
|
$this->logger->notice('Post does not exist', ['uri-id' => $post->uriId, 'report' => $Report]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,15 +89,18 @@ final class Report extends \Friendica\BaseRepository
|
||||||
return $Report;
|
return $Report;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _selectOne(array $condition, array $params = []): BaseEntity
|
/**
|
||||||
|
* @throws NotFoundException
|
||||||
|
*/
|
||||||
|
protected function _selectOne(array $condition, array $params = []): ReportEntity
|
||||||
{
|
{
|
||||||
$fields = $this->db->selectFirst(self::$table_name, [], $condition, $params);
|
$fields = $this->db->selectFirst(self::$table_name, [], $condition, $params);
|
||||||
if (!$this->db->isResult($fields)) {
|
if (!$this->db->isResult($fields)) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
$reportPosts = new Collection\Report\Posts(array_map([$this->postFactory, 'createFromTableRow'], $this->db->selectToArray('report-post', ['uri-id', 'status'], ['rid' => $condition['id'] ?? 0])));
|
$reportPosts = new PostsCollection(array_map([$this->postFactory, 'createFromTableRow'], $this->db->selectToArray('report-post', ['uri-id', 'status'], ['rid' => $condition['id'] ?? 0])));
|
||||||
$reportRules = new Collection\Report\Rules(array_map([$this->ruleFactory, 'createFromTableRow'], $this->db->selectToArray('report-rule', ['line-id', 'text'], ['rid' => $condition['id'] ?? 0])));
|
$reportRules = new RulesCollection(array_map([$this->ruleFactory, 'createFromTableRow'], $this->db->selectToArray('report-rule', ['line-id', 'text'], ['rid' => $condition['id'] ?? 0])));
|
||||||
|
|
||||||
return $this->factory->createFromTableRow($fields, $reportPosts, $reportRules);
|
return $this->factory->createFromTableRow($fields, $reportPosts, $reportRules);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Friendica\Module\Admin\Addons;
|
||||||
use Friendica\Content\Text\Markdown;
|
use Friendica\Content\Text\Markdown;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Model\Contact;
|
||||||
use Friendica\Module\BaseAdmin;
|
use Friendica\Module\BaseAdmin;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
|
|
||||||
|
@ -92,6 +93,35 @@ class Details extends BaseAdmin
|
||||||
|
|
||||||
$addonInfo = $addonHelper->getAddonInfo($addon);
|
$addonInfo = $addonHelper->getAddonInfo($addon);
|
||||||
|
|
||||||
|
$addonAuthors = [];
|
||||||
|
|
||||||
|
foreach ($addonInfo->getAuthors() as $addonAuthor) {
|
||||||
|
$addonAuthor['link'] = 'foo@bar.com';
|
||||||
|
if (array_key_exists('link', $addonAuthor) && empty(parse_url($addonAuthor['link'], PHP_URL_SCHEME))) {
|
||||||
|
$contact = Contact::getByURL($addonAuthor['link'], false);
|
||||||
|
|
||||||
|
if (!empty($contact['url'])) {
|
||||||
|
$addonAuthor['link'] = $contact['url'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$addonAuthors[] = $addonAuthor;
|
||||||
|
}
|
||||||
|
|
||||||
|
$addonMaintainers = [];
|
||||||
|
|
||||||
|
foreach ($addonInfo->getMaintainers() as $addonMaintainer) {
|
||||||
|
if (array_key_exists('link', $addonMaintainer) && empty(parse_url($addonMaintainer['link'], PHP_URL_SCHEME))) {
|
||||||
|
$contact = Contact::getByURL($addonMaintainer['link'], false);
|
||||||
|
|
||||||
|
if (!empty($contact['url'])) {
|
||||||
|
$addonMaintainer['link'] = $contact['url'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$addonMaintainers[] = $addonMaintainer;
|
||||||
|
}
|
||||||
|
|
||||||
$t = Renderer::getMarkupTemplate('admin/addons/details.tpl');
|
$t = Renderer::getMarkupTemplate('admin/addons/details.tpl');
|
||||||
|
|
||||||
return Renderer::replaceMacros($t, [
|
return Renderer::replaceMacros($t, [
|
||||||
|
@ -107,8 +137,8 @@ class Details extends BaseAdmin
|
||||||
'name' => $addonInfo->getName(),
|
'name' => $addonInfo->getName(),
|
||||||
'version' => $addonInfo->getVersion(),
|
'version' => $addonInfo->getVersion(),
|
||||||
'description' => $addonInfo->getDescription(),
|
'description' => $addonInfo->getDescription(),
|
||||||
'author' => $addonInfo->getAuthors(),
|
'author' => $addonAuthors,
|
||||||
'maintainer' => $addonInfo->getMaintainers(),
|
'maintainer' => $addonMaintainers,
|
||||||
],
|
],
|
||||||
'$str_author' => DI::l10n()->t('Author: '),
|
'$str_author' => DI::l10n()->t('Author: '),
|
||||||
'$str_maintainer' => DI::l10n()->t('Maintainer: '),
|
'$str_maintainer' => DI::l10n()->t('Maintainer: '),
|
||||||
|
|
|
@ -41,13 +41,13 @@ class Site extends BaseAdmin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sitename = (!empty($_POST['sitename']) ? trim($_POST['sitename']) : '');
|
$sitename = (!empty($_POST['sitename']) ? strip_tags(trim($_POST['sitename'])) : '');
|
||||||
$sender_email = (!empty($_POST['sender_email']) ? trim($_POST['sender_email']) : '');
|
$sender_email = (!empty($_POST['sender_email']) ? trim($_POST['sender_email']) : '');
|
||||||
$banner = (!empty($_POST['banner']) ? trim($_POST['banner']) : false);
|
$banner = (!empty($_POST['banner']) ? trim($_POST['banner']) : false);
|
||||||
$email_banner = (!empty($_POST['email_banner']) ? trim($_POST['email_banner']) : false);
|
$email_banner = (!empty($_POST['email_banner']) ? trim($_POST['email_banner']) : false);
|
||||||
$shortcut_icon = (!empty($_POST['shortcut_icon']) ? trim($_POST['shortcut_icon']) : '');
|
$shortcut_icon = (!empty($_POST['shortcut_icon']) ? trim($_POST['shortcut_icon']) : '');
|
||||||
$touch_icon = (!empty($_POST['touch_icon']) ? trim($_POST['touch_icon']) : '');
|
$touch_icon = (!empty($_POST['touch_icon']) ? trim($_POST['touch_icon']) : '');
|
||||||
$additional_info = (!empty($_POST['additional_info']) ? trim($_POST['additional_info']) : '');
|
$additional_info = (!empty($_POST['additional_info']) ? strip_tags(trim($_POST['additional_info'])) : '');
|
||||||
$language = (!empty($_POST['language']) ? trim($_POST['language']) : '');
|
$language = (!empty($_POST['language']) ? trim($_POST['language']) : '');
|
||||||
$theme = (!empty($_POST['theme']) ? trim($_POST['theme']) : '');
|
$theme = (!empty($_POST['theme']) ? trim($_POST['theme']) : '');
|
||||||
$theme_mobile = (!empty($_POST['theme_mobile']) ? trim($_POST['theme_mobile']) : '');
|
$theme_mobile = (!empty($_POST['theme_mobile']) ? trim($_POST['theme_mobile']) : '');
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Accounts extends BaseApi
|
||||||
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity());
|
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Circle::removeMembers($this->parameters['id'], $request['account_ids']);
|
Circle::removeMembers($this->parameters['id'], $request['account_ids']);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function post(array $request = [])
|
protected function post(array $request = [])
|
||||||
|
|
|
@ -13,6 +13,7 @@ use Friendica\Model\Contact;
|
||||||
use Friendica\Model\Photo;
|
use Friendica\Model\Photo;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
use Friendica\Module\BaseApi;
|
use Friendica\Module\BaseApi;
|
||||||
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,12 +44,13 @@ class Media extends BaseApi
|
||||||
|
|
||||||
if (in_array($type, [Post\Media::IMAGE, Post\Media::UNKNOWN, Post\Media::APPLICATION])) {
|
if (in_array($type, [Post\Media::IMAGE, Post\Media::UNKNOWN, Post\Media::APPLICATION])) {
|
||||||
$media = Photo::upload($uid, $request['file'], '', null, null, '', '', $request['description']);
|
$media = Photo::upload($uid, $request['file'], '', null, null, '', '', $request['description']);
|
||||||
if (!empty($media)) {
|
|
||||||
|
if (empty($media)) {
|
||||||
|
$this->logAndJsonError(422, $this->errorFactory->UnprocessableEntity('Error while uploading media.'));
|
||||||
|
}
|
||||||
|
|
||||||
$this->logger->info('Uploaded photo', ['media' => $media]);
|
$this->logger->info('Uploaded photo', ['media' => $media]);
|
||||||
$this->jsonExit(DI::mstdnAttachment()->createFromPhoto($media['id']));
|
$this->jsonExit(DI::mstdnAttachment()->createFromPhoto($media['id']));
|
||||||
} elseif ($type == Post\Media::IMAGE) {
|
|
||||||
$this->jsonExit(DI::mstdnAttachment()->createFromPhoto($media['id']));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tempFileName = $request['file']['tmp_name'];
|
$tempFileName = $request['file']['tmp_name'];
|
||||||
|
@ -97,14 +99,24 @@ class Media extends BaseApi
|
||||||
$photo = Photo::selectFirst(['resource-id'], ['id' => $this->parameters['id'], 'uid' => $uid]);
|
$photo = Photo::selectFirst(['resource-id'], ['id' => $this->parameters['id'], 'uid' => $uid]);
|
||||||
if (empty($photo['resource-id'])) {
|
if (empty($photo['resource-id'])) {
|
||||||
$media = Post\Media::getById($this->parameters['id']);
|
$media = Post\Media::getById($this->parameters['id']);
|
||||||
|
|
||||||
if (empty($media['uri-id'])) {
|
if (empty($media['uri-id'])) {
|
||||||
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
|
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Post::exists(['uri-id' => $media['uri-id'], 'uid' => $uid, 'origin' => true])) {
|
if (!Post::exists(['uri-id' => $media['uri-id'], 'uid' => $uid, 'origin' => true])) {
|
||||||
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
|
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
Post\Media::updateById(['description' => $request['description']], $this->parameters['id']);
|
Post\Media::updateById(['description' => $request['description']], $this->parameters['id']);
|
||||||
$this->jsonExit(DI::mstdnAttachment()->createFromId($this->parameters['id']));
|
|
||||||
|
try {
|
||||||
|
$attachment = DI::mstdnAttachment()->createFromId($this->parameters['id'] . '1');
|
||||||
|
} catch (InternalServerErrorException $th) {
|
||||||
|
$this->logAndJsonError(404, $this->errorFactory->RecordNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->jsonExit($attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
Photo::update(['desc' => $request['description']], ['resource-id' => $photo['resource-id']]);
|
Photo::update(['desc' => $request['description']], ['resource-id' => $photo['resource-id']]);
|
||||||
|
|
|
@ -219,9 +219,10 @@ class Search extends BaseApi
|
||||||
|
|
||||||
$condition = ["`id` IN (SELECT `tid` FROM `post-tag` WHERE `type` = ?) AND `name` LIKE ?", Tag::HASHTAG, $q . '%'];
|
$condition = ["`id` IN (SELECT `tid` FROM `post-tag` WHERE `type` = ?) AND `name` LIKE ?", Tag::HASHTAG, $q . '%'];
|
||||||
|
|
||||||
$tags = DBA::select('tag', ['name'], $condition, $params);
|
$tags = DBA::selectToArray('tag', ['name'], $condition, $params);
|
||||||
|
|
||||||
$hashtags = [];
|
$hashtags = [];
|
||||||
|
|
||||||
foreach ($tags as $tag) {
|
foreach ($tags as $tag) {
|
||||||
if ($version == 1) {
|
if ($version == 1) {
|
||||||
$hashtags[] = $tag['name'];
|
$hashtags[] = $tag['name'];
|
||||||
|
|
|
@ -44,10 +44,11 @@ class Ownership extends BaseApi
|
||||||
$this->checkAllowedScope(BaseApi::SCOPE_READ);
|
$this->checkAllowedScope(BaseApi::SCOPE_READ);
|
||||||
$uid = BaseApi::getCurrentUserID();
|
$uid = BaseApi::getCurrentUserID();
|
||||||
|
|
||||||
$circles = $this->dba->select('group', [], ['deleted' => false, 'uid' => $uid, 'cid' => null]);
|
$circles = $this->dba->selectToArray('group', [], ['deleted' => false, 'uid' => $uid, 'cid' => null]);
|
||||||
|
|
||||||
// loop through all circles
|
// loop through all circles
|
||||||
$lists = [];
|
$lists = [];
|
||||||
|
|
||||||
foreach ($circles as $circle) {
|
foreach ($circles as $circle) {
|
||||||
$lists[] = $this->friendicaCircle->createFromId($circle['id']);
|
$lists[] = $this->friendicaCircle->createFromId($circle['id']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace Friendica\Module;
|
||||||
|
|
||||||
use Friendica\BaseModule;
|
use Friendica\BaseModule;
|
||||||
use Friendica\Content\Feature;
|
use Friendica\Content\Feature;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Model\User;
|
use Friendica\Model\User;
|
||||||
|
|
||||||
class BaseProfile extends BaseModule
|
class BaseProfile extends BaseModule
|
||||||
|
@ -128,12 +128,16 @@ class BaseProfile extends BaseModule
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr = ['is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => $current, 'tabs' => $tabs];
|
$hook_data = ['is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => $current, 'tabs' => $tabs];
|
||||||
|
|
||||||
Hook::callAll('profile_tabs', $arr);
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::PROFILE_TABS, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
|
|
||||||
return Renderer::replaceMacros($tpl, ['$tabs' => $arr['tabs'], '$more' => DI::l10n()->t('More')]);
|
return Renderer::replaceMacros($tpl, ['$tabs' => $hook_data['tabs'], '$more' => DI::l10n()->t('More')]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,31 +7,37 @@
|
||||||
|
|
||||||
namespace Friendica\Module\Contact;
|
namespace Friendica\Module\Contact;
|
||||||
|
|
||||||
use Friendica\App;
|
use Friendica\App\Arguments;
|
||||||
|
use Friendica\App\BaseURL;
|
||||||
|
use Friendica\App\Page;
|
||||||
use Friendica\BaseModule;
|
use Friendica\BaseModule;
|
||||||
use Friendica\Contact\LocalRelationship;
|
|
||||||
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship as LocalRelationshipEntity;
|
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship as LocalRelationshipEntity;
|
||||||
|
use Friendica\Contact\LocalRelationship\Repository\LocalRelationship as LocalRelationshipRepository;
|
||||||
use Friendica\Content\ContactSelector;
|
use Friendica\Content\ContactSelector;
|
||||||
use Friendica\Content\Nav;
|
use Friendica\Content\Nav;
|
||||||
use Friendica\Content\Text\BBCode;
|
use Friendica\Content\Text\BBCode;
|
||||||
use Friendica\Content\Widget;
|
use Friendica\Content\Widget;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Model\Circle;
|
use Friendica\Model\Circle;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact as ContactModel;
|
||||||
use Friendica\Module;
|
use Friendica\Model\Contact\User as UserContact;
|
||||||
|
use Friendica\Module\Contact as ContactModule;
|
||||||
use Friendica\Module\Response;
|
use Friendica\Module\Response;
|
||||||
|
use Friendica\Module\Security\Login;
|
||||||
use Friendica\Navigation\SystemMessages;
|
use Friendica\Navigation\SystemMessages;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Friendica\User\Settings;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
|
use Friendica\User\Settings\Repository\UserGServer as UserGServerRepository;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\Profiler;
|
use Friendica\Util\Profiler;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,9 +45,9 @@ use Psr\Log\LoggerInterface;
|
||||||
*/
|
*/
|
||||||
class Profile extends BaseModule
|
class Profile extends BaseModule
|
||||||
{
|
{
|
||||||
/** @var LocalRelationship\Repository\LocalRelationship */
|
/** @var LocalRelationshipRepository */
|
||||||
private $localRelationship;
|
private $localRelationship;
|
||||||
/** @var App\Page */
|
/** @var Page */
|
||||||
private $page;
|
private $page;
|
||||||
/** @var IManageConfigValues */
|
/** @var IManageConfigValues */
|
||||||
private $config;
|
private $config;
|
||||||
|
@ -51,11 +57,28 @@ class Profile extends BaseModule
|
||||||
private $systemMessages;
|
private $systemMessages;
|
||||||
/** @var Database */
|
/** @var Database */
|
||||||
private $db;
|
private $db;
|
||||||
/** @var Settings\Repository\UserGServer */
|
/** @var UserGServerRepository */
|
||||||
private $userGServer;
|
private $userGServer;
|
||||||
|
private EventDispatcherInterface $eventDispatcher;
|
||||||
|
|
||||||
public function __construct(Settings\Repository\UserGServer $userGServer, Database $db, SystemMessages $systemMessages, IHandleUserSessions $session, L10n $l10n, LocalRelationship\Repository\LocalRelationship $localRelationship, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, App\Page $page, IManageConfigValues $config, array $server, array $parameters = [])
|
public function __construct(
|
||||||
{
|
UserGServerRepository $userGServer,
|
||||||
|
EventDispatcherInterface $eventDispatcher,
|
||||||
|
Database $db,
|
||||||
|
SystemMessages $systemMessages,
|
||||||
|
IHandleUserSessions $session,
|
||||||
|
L10n $l10n,
|
||||||
|
LocalRelationshipRepository $localRelationship,
|
||||||
|
BaseURL $baseUrl,
|
||||||
|
Arguments $args,
|
||||||
|
LoggerInterface $logger,
|
||||||
|
Profiler $profiler,
|
||||||
|
Response $response,
|
||||||
|
Page $page,
|
||||||
|
IManageConfigValues $config,
|
||||||
|
array $server,
|
||||||
|
array $parameters = []
|
||||||
|
) {
|
||||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||||
|
|
||||||
$this->localRelationship = $localRelationship;
|
$this->localRelationship = $localRelationship;
|
||||||
|
@ -65,6 +88,7 @@ class Profile extends BaseModule
|
||||||
$this->systemMessages = $systemMessages;
|
$this->systemMessages = $systemMessages;
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
$this->userGServer = $userGServer;
|
$this->userGServer = $userGServer;
|
||||||
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function post(array $request = [])
|
protected function post(array $request = [])
|
||||||
|
@ -77,12 +101,14 @@ class Profile extends BaseModule
|
||||||
|
|
||||||
// Backward compatibility: The update still needs a user-specific contact ID
|
// Backward compatibility: The update still needs a user-specific contact ID
|
||||||
// Change to user-contact table check by version 2022.03
|
// Change to user-contact table check by version 2022.03
|
||||||
$ucid = Contact::getUserContactId($contact_id, $this->session->getLocalUserId());
|
$ucid = ContactModel::getUserContactId($contact_id, $this->session->getLocalUserId());
|
||||||
if (!$ucid || !$this->db->exists('contact', ['id' => $ucid, 'deleted' => false])) {
|
if (!$ucid || !$this->db->exists('contact', ['id' => $ucid, 'deleted' => false])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook::callAll('contact_edit_post', $request);
|
$request = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::EDIT_CONTACT_POST, $request),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
$fields = [];
|
$fields = [];
|
||||||
|
|
||||||
|
@ -120,14 +146,14 @@ class Profile extends BaseModule
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($request['channel_frequency'])) {
|
if (isset($request['channel_frequency'])) {
|
||||||
Contact\User::setChannelFrequency($ucid, $this->session->getLocalUserId(), $request['channel_frequency']);
|
UserContact::setChannelFrequency($ucid, $this->session->getLocalUserId(), $request['channel_frequency']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($request['channel_only'])) {
|
if (isset($request['channel_only'])) {
|
||||||
Contact\User::setChannelOnly($ucid, $this->session->getLocalUserId(), $request['channel_only']);
|
UserContact::setChannelOnly($ucid, $this->session->getLocalUserId(), $request['channel_only']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Contact::update($fields, ['id' => $ucid, 'uid' => $this->session->getLocalUserId()])) {
|
if (!ContactModel::update($fields, ['id' => $ucid, 'uid' => $this->session->getLocalUserId()])) {
|
||||||
$this->systemMessages->addNotice($this->t('Failed to update contact record.'));
|
$this->systemMessages->addNotice($this->t('Failed to update contact record.'));
|
||||||
}
|
}
|
||||||
$this->baseUrl->redirect('contact/' . $contact_id);
|
$this->baseUrl->redirect('contact/' . $contact_id);
|
||||||
|
@ -136,43 +162,43 @@ class Profile extends BaseModule
|
||||||
protected function content(array $request = []): string
|
protected function content(array $request = []): string
|
||||||
{
|
{
|
||||||
if (!$this->session->getLocalUserId()) {
|
if (!$this->session->getLocalUserId()) {
|
||||||
return Module\Security\Login::form($_SERVER['REQUEST_URI']);
|
return Login::form($_SERVER['REQUEST_URI']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backward compatibility: Ensure to use the public contact when the user contact is provided
|
// Backward compatibility: Ensure to use the public contact when the user contact is provided
|
||||||
// Remove by version 2022.03
|
// Remove by version 2022.03
|
||||||
$data = Contact::getPublicAndUserContactID(intval($this->parameters['id']), $this->session->getLocalUserId());
|
$data = ContactModel::getPublicAndUserContactID(intval($this->parameters['id']), $this->session->getLocalUserId());
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
|
throw new NotFoundException($this->t('Contact not found.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$contact = Contact::getById($data['public']);
|
$contact = ContactModel::getById($data['public']);
|
||||||
if (!$this->db->isResult($contact)) {
|
if (!$this->db->isResult($contact)) {
|
||||||
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
|
throw new NotFoundException($this->t('Contact not found.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the protocol from the user's contact.
|
// Fetch the protocol from the user's contact.
|
||||||
if ($data['user']) {
|
if ($data['user']) {
|
||||||
$usercontact = Contact::getById($data['user'], ['network', 'protocol']);
|
$usercontact = ContactModel::getById($data['user'], ['network', 'protocol']);
|
||||||
if ($this->db->isResult($usercontact)) {
|
if ($this->db->isResult($usercontact)) {
|
||||||
$contact['network'] = $usercontact['network'];
|
$contact['network'] = $usercontact['network'];
|
||||||
$contact['protocol'] = $usercontact['protocol'];
|
$contact['protocol'] = $usercontact['protocol'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($contact['network']) && Contact::isLocal($contact['url']) ) {
|
if (empty($contact['network']) && ContactModel::isLocal($contact['url']) ) {
|
||||||
$contact['network'] = Protocol::DFRN;
|
$contact['network'] = Protocol::DFRN;
|
||||||
$contact['protocol'] = Protocol::ACTIVITYPUB;
|
$contact['protocol'] = Protocol::ACTIVITYPUB;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't display contacts that are about to be deleted
|
// Don't display contacts that are about to be deleted
|
||||||
if ($contact['deleted'] || $contact['network'] == Protocol::PHANTOM) {
|
if ($contact['deleted'] || $contact['network'] == Protocol::PHANTOM) {
|
||||||
throw new HTTPException\NotFoundException($this->t('Contact not found.'));
|
throw new NotFoundException($this->t('Contact not found.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$localRelationship = $this->localRelationship->getForUserContact($this->session->getLocalUserId(), $contact['id']);
|
$localRelationship = $this->localRelationship->getForUserContact($this->session->getLocalUserId(), $contact['id']);
|
||||||
|
|
||||||
if ($localRelationship->rel === Contact::SELF) {
|
if ($localRelationship->rel === ContactModel::SELF) {
|
||||||
$this->baseUrl->redirect('profile/' . $contact['nick'] . '/profile');
|
$this->baseUrl->redirect('profile/' . $contact['nick'] . '/profile');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,8 +206,8 @@ class Profile extends BaseModule
|
||||||
self::checkFormSecurityTokenRedirectOnError('contact/' . $contact['id'], 'contact_action', 't');
|
self::checkFormSecurityTokenRedirectOnError('contact/' . $contact['id'], 'contact_action', 't');
|
||||||
|
|
||||||
$cmd = $this->parameters['action'];
|
$cmd = $this->parameters['action'];
|
||||||
if ($cmd === 'update' && $localRelationship->rel !== Contact::NOTHING) {
|
if ($cmd === 'update' && $localRelationship->rel !== ContactModel::NOTHING) {
|
||||||
Module\Contact::updateContactFromPoll($contact['id']);
|
ContactModule::updateContactFromPoll($contact['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cmd === 'updateprofile') {
|
if ($cmd === 'updateprofile') {
|
||||||
|
@ -191,12 +217,12 @@ class Profile extends BaseModule
|
||||||
if ($cmd === 'block') {
|
if ($cmd === 'block') {
|
||||||
if ($localRelationship->blocked) {
|
if ($localRelationship->blocked) {
|
||||||
// @TODO Backward compatibility, replace with $localRelationship->unblock()
|
// @TODO Backward compatibility, replace with $localRelationship->unblock()
|
||||||
Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), false);
|
UserContact::setBlocked($contact['id'], $this->session->getLocalUserId(), false);
|
||||||
|
|
||||||
$message = $this->t('Contact has been unblocked');
|
$message = $this->t('Contact has been unblocked');
|
||||||
} else {
|
} else {
|
||||||
// @TODO Backward compatibility, replace with $localRelationship->block()
|
// @TODO Backward compatibility, replace with $localRelationship->block()
|
||||||
Contact\User::setBlocked($contact['id'], $this->session->getLocalUserId(), true);
|
UserContact::setBlocked($contact['id'], $this->session->getLocalUserId(), true);
|
||||||
$message = $this->t('Contact has been blocked');
|
$message = $this->t('Contact has been blocked');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,12 +233,12 @@ class Profile extends BaseModule
|
||||||
if ($cmd === 'ignore') {
|
if ($cmd === 'ignore') {
|
||||||
if ($localRelationship->ignored) {
|
if ($localRelationship->ignored) {
|
||||||
// @TODO Backward compatibility, replace with $localRelationship->unblock()
|
// @TODO Backward compatibility, replace with $localRelationship->unblock()
|
||||||
Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), false);
|
UserContact::setIgnored($contact['id'], $this->session->getLocalUserId(), false);
|
||||||
|
|
||||||
$message = $this->t('Contact has been unignored');
|
$message = $this->t('Contact has been unignored');
|
||||||
} else {
|
} else {
|
||||||
// @TODO Backward compatibility, replace with $localRelationship->block()
|
// @TODO Backward compatibility, replace with $localRelationship->block()
|
||||||
Contact\User::setIgnored($contact['id'], $this->session->getLocalUserId(), true);
|
UserContact::setIgnored($contact['id'], $this->session->getLocalUserId(), true);
|
||||||
$message = $this->t('Contact has been ignored');
|
$message = $this->t('Contact has been ignored');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,12 +249,12 @@ class Profile extends BaseModule
|
||||||
if ($cmd === 'collapse') {
|
if ($cmd === 'collapse') {
|
||||||
if ($localRelationship->collapsed) {
|
if ($localRelationship->collapsed) {
|
||||||
// @TODO Backward compatibility, replace with $localRelationship->unblock()
|
// @TODO Backward compatibility, replace with $localRelationship->unblock()
|
||||||
Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), false);
|
UserContact::setCollapsed($contact['id'], $this->session->getLocalUserId(), false);
|
||||||
|
|
||||||
$message = $this->t('Contact has been uncollapsed');
|
$message = $this->t('Contact has been uncollapsed');
|
||||||
} else {
|
} else {
|
||||||
// @TODO Backward compatibility, replace with $localRelationship->block()
|
// @TODO Backward compatibility, replace with $localRelationship->block()
|
||||||
Contact\User::setCollapsed($contact['id'], $this->session->getLocalUserId(), true);
|
UserContact::setCollapsed($contact['id'], $this->session->getLocalUserId(), true);
|
||||||
$message = $this->t('Contact has been collapsed');
|
$message = $this->t('Contact has been collapsed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +268,7 @@ class Profile extends BaseModule
|
||||||
$vcard_widget = Widget\VCard::getHTML($contact);
|
$vcard_widget = Widget\VCard::getHTML($contact);
|
||||||
$circles_widget = '';
|
$circles_widget = '';
|
||||||
|
|
||||||
if (!in_array($localRelationship->rel, [Contact::NOTHING, Contact::SELF])) {
|
if (!in_array($localRelationship->rel, [ContactModel::NOTHING, ContactModel::SELF])) {
|
||||||
$circles_widget = Circle::sidebarWidget('contact', 'circle', 'full', 'everyone', $data['user']);
|
$circles_widget = Circle::sidebarWidget('contact', 'circle', 'full', 'everyone', $data['user']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,9 +283,15 @@ class Profile extends BaseModule
|
||||||
]);
|
]);
|
||||||
|
|
||||||
switch ($localRelationship->rel) {
|
switch ($localRelationship->rel) {
|
||||||
case Contact::FRIEND: $relation_text = $this->t('You are mutual friends with %s', $contact['name']); break;
|
case ContactModel::FRIEND:
|
||||||
case Contact::FOLLOWER: $relation_text = $this->t('You are sharing with %s', $contact['name']); break;
|
$relation_text = $this->t('You are mutual friends with %s', $contact['name']);
|
||||||
case Contact::SHARING: $relation_text = $this->t('%s is sharing with you', $contact['name']); break;
|
break;
|
||||||
|
case ContactModel::FOLLOWER:
|
||||||
|
$relation_text = $this->t('You are sharing with %s', $contact['name']);
|
||||||
|
break;
|
||||||
|
case ContactModel::SHARING:
|
||||||
|
$relation_text = $this->t('%s is sharing with you', $contact['name']);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$relation_text = '';
|
$relation_text = '';
|
||||||
}
|
}
|
||||||
|
@ -268,7 +300,7 @@ class Profile extends BaseModule
|
||||||
$relation_text = '';
|
$relation_text = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = Contact::magicLinkByContact($contact);
|
$url = ContactModel::magicLinkByContact($contact);
|
||||||
if (strpos($url, 'contact/redir/') === 0) {
|
if (strpos($url, 'contact/redir/') === 0) {
|
||||||
$sparkle = ' class="sparkle" ';
|
$sparkle = ' class="sparkle" ';
|
||||||
} else {
|
} else {
|
||||||
|
@ -282,8 +314,7 @@ class Profile extends BaseModule
|
||||||
$this->logger->notice('Empty gsid for contact', ['contact' => $contact]);
|
$this->logger->notice('Empty gsid for contact', ['contact' => $contact]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$serverIgnored =
|
$serverIgnored = $contact['gsid'] &&
|
||||||
$contact['gsid'] &&
|
|
||||||
$this->userGServer->isIgnoredByUser($this->session->getLocalUserId(), $contact['gsid']) ?
|
$this->userGServer->isIgnoredByUser($this->session->getLocalUserId(), $contact['gsid']) ?
|
||||||
$this->t('This contact is on a server you ignored.')
|
$this->t('This contact is on a server you ignored.')
|
||||||
: '';
|
: '';
|
||||||
|
@ -300,7 +331,7 @@ class Profile extends BaseModule
|
||||||
$nettype = $this->t('Network type: %s', ContactSelector::networkToName($contact['network'], $contact['protocol'], $contact['gsid']));
|
$nettype = $this->t('Network type: %s', ContactSelector::networkToName($contact['network'], $contact['protocol'], $contact['gsid']));
|
||||||
|
|
||||||
// tabs
|
// tabs
|
||||||
$tab_str = Module\Contact::getTabsHTML($contact, Module\Contact::TAB_PROFILE);
|
$tab_str = ContactModule::getTabsHTML($contact, ContactModule::TAB_PROFILE);
|
||||||
|
|
||||||
$lost_contact = (($contact['archive'] && $contact['term-date'] > DBA::NULL_DATETIME && $contact['term-date'] < DateTimeFormat::utcNow()) ? $this->t('Communications lost with this contact!') : '');
|
$lost_contact = (($contact['archive'] && $contact['term-date'] > DBA::NULL_DATETIME && $contact['term-date'] < DateTimeFormat::utcNow()) ? $this->t('Communications lost with this contact!') : '');
|
||||||
|
|
||||||
|
@ -312,10 +343,10 @@ class Profile extends BaseModule
|
||||||
$localRelationship->fetchFurtherInformation,
|
$localRelationship->fetchFurtherInformation,
|
||||||
$this->t('Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn\'t contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags.'),
|
$this->t('Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn\'t contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags.'),
|
||||||
[
|
[
|
||||||
LocalRelationship\Entity\LocalRelationship::FFI_NONE => $this->t('Disabled'),
|
LocalRelationshipEntity::FFI_NONE => $this->t('Disabled'),
|
||||||
LocalRelationship\Entity\LocalRelationship::FFI_INFORMATION => $this->t('Fetch information'),
|
LocalRelationshipEntity::FFI_INFORMATION => $this->t('Fetch information'),
|
||||||
LocalRelationship\Entity\LocalRelationship::FFI_KEYWORD => $this->t('Fetch keywords'),
|
LocalRelationshipEntity::FFI_KEYWORD => $this->t('Fetch keywords'),
|
||||||
LocalRelationship\Entity\LocalRelationship::FFI_BOTH => $this->t('Fetch information and keywords')
|
LocalRelationshipEntity::FFI_BOTH => $this->t('Fetch information and keywords')
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -346,8 +377,8 @@ class Profile extends BaseModule
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$channel_frequency = Contact\User::getChannelFrequency($contact['id'], $this->session->getLocalUserId());
|
$channel_frequency = UserContact::getChannelFrequency($contact['id'], $this->session->getLocalUserId());
|
||||||
$channel_only = Contact\User::getChannelOnly($contact['id'], $this->session->getLocalUserId());
|
$channel_only = UserContact::getChannelOnly($contact['id'], $this->session->getLocalUserId());
|
||||||
|
|
||||||
$poll_interval = null;
|
$poll_interval = null;
|
||||||
if ((($contact['network'] == Protocol::FEED) && !$this->config->get('system', 'adjust_poll_frequency')) || ($contact['network'] == Protocol::MAIL)) {
|
if ((($contact['network'] == Protocol::FEED) && !$this->config->get('system', 'adjust_poll_frequency')) || ($contact['network'] == Protocol::MAIL)) {
|
||||||
|
@ -356,12 +387,12 @@ class Profile extends BaseModule
|
||||||
|
|
||||||
$contact_actions = $this->getContactActions($contact, $localRelationship);
|
$contact_actions = $this->getContactActions($contact, $localRelationship);
|
||||||
|
|
||||||
if (Contact\User::isIsBlocked($contact['id'], $this->session->getLocalUserId())) {
|
if (UserContact::isIsBlocked($contact['id'], $this->session->getLocalUserId())) {
|
||||||
$relation_text = $this->t('%s has blocked you', $contact['name'] ?: $contact['nick']);
|
$relation_text = $this->t('%s has blocked you', $contact['name'] ?: $contact['nick']);
|
||||||
unset($contact_actions['follow']);
|
unset($contact_actions['follow']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($localRelationship->rel !== Contact::NOTHING) {
|
if ($localRelationship->rel !== ContactModel::NOTHING) {
|
||||||
$lbl_info1 = $this->t('Contact Information / Notes');
|
$lbl_info1 = $this->t('Contact Information / Notes');
|
||||||
$contact_settings_label = $this->t('Contact Settings');
|
$contact_settings_label = $this->t('Contact Settings');
|
||||||
} else {
|
} else {
|
||||||
|
@ -407,13 +438,13 @@ class Profile extends BaseModule
|
||||||
'$notify_new_posts' => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')],
|
'$notify_new_posts' => ['notify_new_posts', $this->t('Notification for new posts'), ($localRelationship->notifyNewPosts), $this->t('Send a notification of every new post of this contact')],
|
||||||
'$fetch_further_information' => $fetch_further_information,
|
'$fetch_further_information' => $fetch_further_information,
|
||||||
'$ffi_keyword_denylist' => ['ffi_keyword_denylist', $this->t('Keyword Deny List'), $localRelationship->ffiKeywordDenylist, $this->t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')],
|
'$ffi_keyword_denylist' => ['ffi_keyword_denylist', $this->t('Keyword Deny List'), $localRelationship->ffiKeywordDenylist, $this->t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')],
|
||||||
'$photo' => Contact::getPhoto($contact),
|
'$photo' => ContactModel::getPhoto($contact),
|
||||||
'$name' => $contact['name'],
|
'$name' => $contact['name'],
|
||||||
'$sparkle' => $sparkle,
|
'$sparkle' => $sparkle,
|
||||||
'$url' => $url,
|
'$url' => $url,
|
||||||
'$profileurllabel' => $this->t('Profile URL'),
|
'$profileurllabel' => $this->t('Profile URL'),
|
||||||
'$profileurl' => $contact['url'],
|
'$profileurl' => $contact['url'],
|
||||||
'$account_type' => Contact::getAccountType($contact['contact-type']),
|
'$account_type' => ContactModel::getAccountType($contact['contact-type']),
|
||||||
'$location' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['location']),
|
'$location' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['location']),
|
||||||
'$location_label' => $this->t('Location:'),
|
'$location_label' => $this->t('Location:'),
|
||||||
'$xmpp' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['xmpp']),
|
'$xmpp' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $contact['xmpp']),
|
||||||
|
@ -440,18 +471,23 @@ class Profile extends BaseModule
|
||||||
'$channel_settings_label' => $this->t('Channel Settings'),
|
'$channel_settings_label' => $this->t('Channel Settings'),
|
||||||
'$frequency_label' => $this->t('Frequency of this contact in relevant channels'),
|
'$frequency_label' => $this->t('Frequency of this contact in relevant channels'),
|
||||||
'$frequency_description' => $this->t("Depending on the type of the channel not all posts from this contact are displayed. By default, posts need to have a minimum amount of interactions (comments, likes) to show in your channels. On the other hand there can be contacts who flood the channel, so you might want to see only some of their posts. Or you don't want to see their content at all, but you don't want to block or hide the contact completely."),
|
'$frequency_description' => $this->t("Depending on the type of the channel not all posts from this contact are displayed. By default, posts need to have a minimum amount of interactions (comments, likes) to show in your channels. On the other hand there can be contacts who flood the channel, so you might want to see only some of their posts. Or you don't want to see their content at all, but you don't want to block or hide the contact completely."),
|
||||||
'$frequency_default' => ['channel_frequency', $this->t('Default frequency'), Contact\User::FREQUENCY_DEFAULT, $this->t('Posts by this contact are displayed in the "for you" channel if you interact often with this contact or if a post reached some level of interaction.'), $channel_frequency == Contact\User::FREQUENCY_DEFAULT],
|
'$frequency_default' => ['channel_frequency', $this->t('Default frequency'), UserContact::FREQUENCY_DEFAULT, $this->t('Posts by this contact are displayed in the "for you" channel if you interact often with this contact or if a post reached some level of interaction.'), $channel_frequency == UserContact::FREQUENCY_DEFAULT],
|
||||||
'$frequency_always' => ['channel_frequency', $this->t('Display all posts of this contact'), Contact\User::FREQUENCY_ALWAYS, $this->t('All posts from this contact will appear on the "for you" channel'), $channel_frequency == Contact\User::FREQUENCY_ALWAYS],
|
'$frequency_always' => ['channel_frequency', $this->t('Display all posts of this contact'), UserContact::FREQUENCY_ALWAYS, $this->t('All posts from this contact will appear on the "for you" channel'), $channel_frequency == UserContact::FREQUENCY_ALWAYS],
|
||||||
'$frequency_reduced' => ['channel_frequency', $this->t('Display only few posts'), Contact\User::FREQUENCY_REDUCED, $this->t('When a contact creates a lot of posts in a short period, this setting reduces the number of displayed posts in every channel.'), $channel_frequency == Contact\User::FREQUENCY_REDUCED],
|
'$frequency_reduced' => ['channel_frequency', $this->t('Display only few posts'), UserContact::FREQUENCY_REDUCED, $this->t('When a contact creates a lot of posts in a short period, this setting reduces the number of displayed posts in every channel.'), $channel_frequency == UserContact::FREQUENCY_REDUCED],
|
||||||
'$frequency_never' => ['channel_frequency', $this->t('Never display posts'), Contact\User::FREQUENCY_NEVER, $this->t('Posts from this contact will never be displayed in any channel'), $channel_frequency == Contact\User::FREQUENCY_NEVER],
|
'$frequency_never' => ['channel_frequency', $this->t('Never display posts'), UserContact::FREQUENCY_NEVER, $this->t('Posts from this contact will never be displayed in any channel'), $channel_frequency == UserContact::FREQUENCY_NEVER],
|
||||||
'$channel_only' => ['channel_only', $this->t('Channel Only'), $channel_only, $this->t('If enabled, posts from this contact will only appear in channels and network streams in circles, but not in the general network stream.')],
|
'$channel_only' => ['channel_only', $this->t('Channel Only'), $channel_only, $this->t('If enabled, posts from this contact will only appear in channels and network streams in circles, but not in the general network stream.')],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$arr = ['contact' => $contact, 'output' => $o];
|
$hook_data = [
|
||||||
|
'contact' => $contact,
|
||||||
|
'output' => $o,
|
||||||
|
];
|
||||||
|
|
||||||
Hook::callAll('contact_edit', $arr);
|
$hook_data = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::EDIT_CONTACT_FORM, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return $arr['output'];
|
return $hook_data['output'] ?? $o;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -460,18 +496,18 @@ class Profile extends BaseModule
|
||||||
* This includes actions like e.g. 'block', 'hide', 'delete' and others
|
* This includes actions like e.g. 'block', 'hide', 'delete' and others
|
||||||
*
|
*
|
||||||
* @param array $contact Public contact row
|
* @param array $contact Public contact row
|
||||||
* @param LocalRelationship\Entity\LocalRelationship $localRelationship
|
*
|
||||||
* @return array with contact related actions
|
* @return array with contact related actions
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
private function getContactActions(array $contact, LocalRelationship\Entity\LocalRelationship $localRelationship): array
|
private function getContactActions(array $contact, LocalRelationshipEntity $localRelationship): array
|
||||||
{
|
{
|
||||||
$poll_enabled = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED, Protocol::MAIL]);
|
$poll_enabled = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED, Protocol::MAIL]);
|
||||||
$contact_actions = [];
|
$contact_actions = [];
|
||||||
|
|
||||||
$formSecurityToken = self::getFormSecurityToken('contact_action');
|
$formSecurityToken = self::getFormSecurityToken('contact_action');
|
||||||
|
|
||||||
if ($localRelationship->rel & Contact::SHARING) {
|
if ($localRelationship->rel & ContactModel::SHARING) {
|
||||||
$contact_actions['unfollow'] = [
|
$contact_actions['unfollow'] = [
|
||||||
'label' => $this->t('Unfollow'),
|
'label' => $this->t('Unfollow'),
|
||||||
'url' => 'contact/unfollow?url=' . urlencode($contact['url']) . '&auto=1',
|
'url' => 'contact/unfollow?url=' . urlencode($contact['url']) . '&auto=1',
|
||||||
|
@ -544,7 +580,7 @@ class Profile extends BaseModule
|
||||||
'id' => 'toggle-collapse',
|
'id' => 'toggle-collapse',
|
||||||
];
|
];
|
||||||
|
|
||||||
if (Protocol::supportsRevokeFollow($contact['network']) && in_array($localRelationship->rel, [Contact::FOLLOWER, Contact::FRIEND])) {
|
if (Protocol::supportsRevokeFollow($contact['network']) && in_array($localRelationship->rel, [ContactModel::FOLLOWER, ContactModel::FRIEND])) {
|
||||||
$contact_actions['revoke_follow'] = [
|
$contact_actions['revoke_follow'] = [
|
||||||
'label' => $this->t('Revoke Follow'),
|
'label' => $this->t('Revoke Follow'),
|
||||||
'url' => 'contact/' . $contact['id'] . '/revoke',
|
'url' => 'contact/' . $contact['id'] . '/revoke',
|
||||||
|
@ -562,7 +598,7 @@ class Profile extends BaseModule
|
||||||
*
|
*
|
||||||
* @param int $contact_id Id of the contact with uid != 0
|
* @param int $contact_id Id of the contact with uid != 0
|
||||||
* @return void
|
* @return void
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws InternalServerErrorException
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
*/
|
*/
|
||||||
private function updateContactFromProbe(int $contact_id)
|
private function updateContactFromProbe(int $contact_id)
|
||||||
|
@ -572,6 +608,6 @@ class Profile extends BaseModule
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the entry in the contact table
|
// Update the entry in the contact table
|
||||||
Contact::updateFromProbe($contact_id);
|
ContactModel::updateFromProbe($contact_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ use Friendica\Content\Widget\TrendingTags;
|
||||||
use Friendica\Core\ACL;
|
use Friendica\Core\ACL;
|
||||||
use Friendica\Core\Cache\Capability\ICanCache;
|
use Friendica\Core\Cache\Capability\ICanCache;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
|
@ -39,6 +38,7 @@ use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||||
use Friendica\Core\Worker;
|
use Friendica\Core\Worker;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
use Friendica\Model\Circle;
|
use Friendica\Model\Circle;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
|
@ -49,6 +49,7 @@ use Friendica\Network\HTTPException;
|
||||||
use Friendica\Navigation\SystemMessages;
|
use Friendica\Navigation\SystemMessages;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\Profiler;
|
use Friendica\Util\Profiler;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class Network extends Timeline
|
class Network extends Timeline
|
||||||
|
@ -59,9 +60,9 @@ class Network extends Timeline
|
||||||
protected $dateFrom;
|
protected $dateFrom;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $dateTo;
|
protected $dateTo;
|
||||||
/** @var int */
|
/** @var bool */
|
||||||
protected $star;
|
protected $star;
|
||||||
/** @var int */
|
/** @var bool */
|
||||||
protected $mention;
|
protected $mention;
|
||||||
|
|
||||||
/** @var AppHelper */
|
/** @var AppHelper */
|
||||||
|
@ -90,12 +91,55 @@ class Network extends Timeline
|
||||||
protected $community;
|
protected $community;
|
||||||
/** @var NetworkFactory */
|
/** @var NetworkFactory */
|
||||||
protected $networkFactory;
|
protected $networkFactory;
|
||||||
|
private EventDispatcherInterface $eventDispatcher;
|
||||||
|
|
||||||
public function __construct(UserDefinedChannelFactory $userDefinedChannel, NetworkFactory $network, CommunityFactory $community, ChannelFactory $channelFactory, UserDefinedChannel $channel, AppHelper $appHelper, TimelineFactory $timeline, SystemMessages $systemMessages, Mode $mode, Conversation $conversation, Page $page, IHandleUserSessions $session, Database $database, IManagePersonalConfigValues $pConfig, IManageConfigValues $config, ICanCache $cache, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
|
public function __construct(
|
||||||
{
|
UserDefinedChannelFactory $userDefinedChannel,
|
||||||
parent::__construct($channel, $mode, $session, $database, $pConfig, $config, $cache, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
NetworkFactory $network,
|
||||||
|
CommunityFactory $community,
|
||||||
|
ChannelFactory $channelFactory,
|
||||||
|
UserDefinedChannel $channel,
|
||||||
|
AppHelper $appHelper,
|
||||||
|
EventDispatcherInterface $eventDispatcher,
|
||||||
|
TimelineFactory $timeline,
|
||||||
|
SystemMessages $systemMessages,
|
||||||
|
Mode $mode,
|
||||||
|
Conversation $conversation,
|
||||||
|
Page $page,
|
||||||
|
IHandleUserSessions $session,
|
||||||
|
Database $database,
|
||||||
|
IManagePersonalConfigValues $pConfig,
|
||||||
|
IManageConfigValues $config,
|
||||||
|
ICanCache $cache,
|
||||||
|
L10n $l10n,
|
||||||
|
BaseURL $baseUrl,
|
||||||
|
Arguments $args,
|
||||||
|
LoggerInterface $logger,
|
||||||
|
Profiler $profiler,
|
||||||
|
Response $response,
|
||||||
|
array $server,
|
||||||
|
array $parameters = []
|
||||||
|
) {
|
||||||
|
parent::__construct(
|
||||||
|
$channel,
|
||||||
|
$mode,
|
||||||
|
$session,
|
||||||
|
$database,
|
||||||
|
$pConfig,
|
||||||
|
$config,
|
||||||
|
$cache,
|
||||||
|
$l10n,
|
||||||
|
$baseUrl,
|
||||||
|
$args,
|
||||||
|
$logger,
|
||||||
|
$profiler,
|
||||||
|
$response,
|
||||||
|
$server,
|
||||||
|
$parameters,
|
||||||
|
);
|
||||||
|
|
||||||
$this->appHelper = $appHelper;
|
$this->appHelper = $appHelper;
|
||||||
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->timeline = $timeline;
|
$this->timeline = $timeline;
|
||||||
$this->systemMessages = $systemMessages;
|
$this->systemMessages = $systemMessages;
|
||||||
$this->conversation = $conversation;
|
$this->conversation = $conversation;
|
||||||
|
@ -116,8 +160,13 @@ class Network extends Timeline
|
||||||
|
|
||||||
$module = 'network';
|
$module = 'network';
|
||||||
|
|
||||||
$arr = ['query' => $this->args->getQueryString()];
|
$hook_data = [
|
||||||
Hook::callAll('network_content_init', $arr);
|
'query' => $this->args->getQueryString(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::NETWORK_CONTENT_START, $hook_data)
|
||||||
|
);
|
||||||
|
|
||||||
$o = '';
|
$o = '';
|
||||||
|
|
||||||
|
@ -275,19 +324,24 @@ class Network extends Timeline
|
||||||
$tabs = array_merge($tabs, $this->getTabArray($this->community->getTimelines(true), 'network', 'channel'));
|
$tabs = array_merge($tabs, $this->getTabArray($this->community->getTimelines(true), 'network', 'channel'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr = ['tabs' => $tabs];
|
$hook_data = [
|
||||||
Hook::callAll('network_tabs', $arr);
|
'tabs' => $tabs,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::NETWORK_CONTENT_TABS, $hook_data)
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
if (!empty($network_timelines)) {
|
if (!empty($network_timelines)) {
|
||||||
$tabs = [];
|
$tabs = [];
|
||||||
|
|
||||||
foreach ($arr['tabs'] as $tab) {
|
foreach ($hook_data['tabs'] as $tab) {
|
||||||
if (in_array($tab['code'], $network_timelines)) {
|
if (in_array($tab['code'], $network_timelines)) {
|
||||||
$tabs[] = $tab;
|
$tabs[] = $tab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$tabs = $arr['tabs'];
|
$tabs = $hook_data['tabs'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
|
|
|
@ -11,10 +11,10 @@ use Friendica\BaseModule;
|
||||||
use Friendica\Content\Nav;
|
use Friendica\Content\Nav;
|
||||||
use Friendica\Content\Pager;
|
use Friendica\Content\Pager;
|
||||||
use Friendica\Content\Widget;
|
use Friendica\Content\Widget;
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Search;
|
use Friendica\Core\Search;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
use Friendica\Model;
|
use Friendica\Model;
|
||||||
use Friendica\Model\Profile;
|
use Friendica\Model\Profile;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
|
@ -161,13 +161,22 @@ class Directory extends BaseModule
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$hook = ['contact' => $contact, 'entry' => $entry];
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
Hook::callAll('directory_item', $hook);
|
$hook_data = [
|
||||||
|
'contact' => $contact,
|
||||||
|
'entry' => $entry,
|
||||||
|
];
|
||||||
|
|
||||||
|
$hook_data = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::DIRECTORY_ITEM, $hook_data),
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
|
$entry = $hook_data['entry'] ?? $entry;
|
||||||
|
|
||||||
unset($profile);
|
unset($profile);
|
||||||
unset($location);
|
unset($location);
|
||||||
|
|
||||||
return $hook['entry'];
|
return $entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue