Merge branch 'develop' into introduce-phpmd
commit
7d792600b4
|
@ -7,7 +7,7 @@ echo ">>> Friendica Setup"
|
||||||
|
|
||||||
FRIENDICA_PHP_PATH=$(which php)
|
FRIENDICA_PHP_PATH=$(which php)
|
||||||
export FRIENDICA_PHP_PATH
|
export FRIENDICA_PHP_PATH
|
||||||
|
|
||||||
envsubst < $workspaceFolder/.devcontainer/include/autoinstall.config.php > /tmp/autoinstall.config.php
|
envsubst < $workspaceFolder/.devcontainer/include/autoinstall.config.php > /tmp/autoinstall.config.php
|
||||||
cp $workspaceFolder/.devcontainer/include/00apcu.config.php $workspaceFolder/config/00apcu.config.php
|
cp $workspaceFolder/.devcontainer/include/00apcu.config.php $workspaceFolder/config/00apcu.config.php
|
||||||
cp $workspaceFolder/.devcontainer/include/01redis.config.php $workspaceFolder/config/01redis.config.php
|
cp $workspaceFolder/.devcontainer/include/01redis.config.php $workspaceFolder/config/01redis.config.php
|
||||||
|
@ -19,7 +19,7 @@ cd $DocumentRoot
|
||||||
# copy the .htaccess-dist file to .htaccess so that rewrite rules work
|
# copy the .htaccess-dist file to .htaccess so that rewrite rules work
|
||||||
cp $DocumentRoot/.htaccess-dist $DocumentRoot/.htaccess
|
cp $DocumentRoot/.htaccess-dist $DocumentRoot/.htaccess
|
||||||
|
|
||||||
bin/composer.phar --no-dev install
|
bin/composer.phar install
|
||||||
|
|
||||||
# install friendica
|
# install friendica
|
||||||
bin/console autoinstall -f /tmp/autoinstall.config.php
|
bin/console autoinstall -f /tmp/autoinstall.config.php
|
||||||
|
|
|
@ -72,7 +72,6 @@ venv/
|
||||||
/.idea
|
/.idea
|
||||||
|
|
||||||
#ignore addons directory
|
#ignore addons directory
|
||||||
/addons
|
|
||||||
/addon
|
/addon
|
||||||
|
|
||||||
#ignore base .htaccess
|
#ignore base .htaccess
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: 2010 - 2024 the Friendica project
|
# SPDX-FileCopyrightText: 2010 - 2024 the Friendica project
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
dir=$(cd "${0%[/\\]*}" > /dev/null; pwd)
|
dir=$(cd "$(dirname "$0")" > /dev/null 2>&1; pwd)
|
||||||
|
|
||||||
if [[ -d /proc/cygdrive && $(which php) == $(readlink -n /proc/cygdrive)/* ]]; then
|
if [ -d /proc/cygdrive ] && [ "$(which php)" = "$(readlink -n /proc/cygdrive)/*" ]; then
|
||||||
# We are in Cygwin using Windows php, so the path must be translated
|
# We are in Cygwin using Windows php, so the path must be translated
|
||||||
dir=$(cygpath -m "$dir");
|
dir=$(cygpath -m "$dir")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
php "${dir}/console.php" "$@"
|
php "${dir}/console.php" "$@"
|
||||||
|
|
|
@ -24,7 +24,7 @@ chdir(dirname(__DIR__));
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
fwrite(STDOUT, '`bin/daemon.php` is deprecated since 2024.02 and will be removed in 5 months, please use `bin/console.php daemon` instead.' . \PHP_EOL);
|
fwrite(STDOUT, '`bin/daemon.php` is deprecated since 2025.02 and will be removed in 5 months, please use `bin/console.php daemon` instead.' . \PHP_EOL);
|
||||||
|
|
||||||
// BC: Add console command as second argument
|
// BC: Add console command as second argument
|
||||||
$argv = $_SERVER['argv'] ?? [];
|
$argv = $_SERVER['argv'] ?? [];
|
||||||
|
|
|
@ -19,7 +19,7 @@ chdir(dirname(__DIR__));
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
fwrite(STDOUT, '`bin/jetstream.php` is deprecated since 2024.02 and will be removed in 5 months, please use `bin/console.php jetstream` instead.' . \PHP_EOL);
|
fwrite(STDOUT, '`bin/jetstream.php` is deprecated since 2025.02 and will be removed in 5 months, please use `bin/console.php jetstream` instead.' . \PHP_EOL);
|
||||||
|
|
||||||
// BC: Add console command as second argument
|
// BC: Add console command as second argument
|
||||||
$argv = $_SERVER['argv'] ?? [];
|
$argv = $_SERVER['argv'] ?? [];
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: 2010 - 2024 the Friendica project
|
# SPDX-FileCopyrightText: 2010 - 2024 the Friendica project
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
set -eo pipefail
|
set -e
|
||||||
|
|
||||||
function resolve {
|
# Custom function to handle pipefail behavior
|
||||||
if [ "$(uname)" == "Darwin" ]
|
pipefail() {
|
||||||
|
local cmd="$1"
|
||||||
|
shift
|
||||||
|
{ eval "$cmd"; } || exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve() {
|
||||||
|
if [ "$(uname)" = "Darwin" ]
|
||||||
then
|
then
|
||||||
realpath "$1"
|
realpath "$1"
|
||||||
else
|
else
|
||||||
|
@ -17,26 +24,26 @@ function resolve {
|
||||||
|
|
||||||
FULLPATH=$(dirname "$(resolve "$0")")
|
FULLPATH=$(dirname "$(resolve "$0")")
|
||||||
|
|
||||||
if [ "$1" == "--help" ] || [ "$1" == "-h" ]
|
if [ "$1" = "--help" ] || [ "$1" = "-h" ]
|
||||||
then
|
then
|
||||||
echo "$(basename "$(resolve "$0")") [options]"
|
echo "$(basename "$(resolve "$0")") [options]"
|
||||||
echo
|
echo
|
||||||
echo "-a | --addon <name> extract strings from addon 'name'"
|
echo "-a | --addon <name> extract strings from addon 'name'"
|
||||||
echo "-s | --single single addon mode: extract string from current folder"
|
echo "-s | --single single addon mode: extract string from current folder"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MODE='default'
|
MODE='default'
|
||||||
ADDONNAME=
|
ADDONNAME=
|
||||||
if [ "$1" == "--addon" ] || [ "$1" == "-a" ]
|
if [ "$1" = "--addon" ] || [ "$1" = "-a" ]
|
||||||
then
|
then
|
||||||
MODE='addon'
|
MODE='addon'
|
||||||
if [ -z "$2" ]; then echo -e "ERROR: missing addon name\n\nrun_xgettext.sh -a <addonname>"; exit 1; fi
|
if [ -z "$2" ]; then echo "ERROR: missing addon name\n\nrun_xgettext.sh -a <addonname>"; exit 1; fi
|
||||||
ADDONNAME=$2
|
ADDONNAME=$2
|
||||||
if [ ! -d "$FULLPATH/../addon/$ADDONNAME" ]; then echo "ERROR: addon '$ADDONNAME' not found"; exit 2; fi
|
if [ ! -d "$FULLPATH/../addon/$ADDONNAME" ]; then echo "ERROR: addon '$ADDONNAME' not found"; exit 2; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" == "--single" ] || [ "$1" == "-s" ]
|
if [ "$1" = "--single" ] || [ "$1" = "-s" ]
|
||||||
then
|
then
|
||||||
MODE='single'
|
MODE='single'
|
||||||
fi
|
fi
|
||||||
|
@ -70,7 +77,6 @@ case "$MODE" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
KEYWORDS="-k -kt -ktt:1,2"
|
KEYWORDS="-k -kt -ktt:1,2"
|
||||||
|
|
||||||
echo "Extract strings to $OUTFILE.."
|
echo "Extract strings to $OUTFILE.."
|
||||||
|
@ -79,13 +85,13 @@ echo "Extract strings to $OUTFILE.."
|
||||||
# shellcheck disable=SC2086 # $FINDOPTS is meant to be split
|
# shellcheck disable=SC2086 # $FINDOPTS is meant to be split
|
||||||
find_result=$(find "$FINDSTARTDIR" $FINDOPTS -name "*.php" -type f | LC_ALL=C sort -s)
|
find_result=$(find "$FINDSTARTDIR" $FINDOPTS -name "*.php" -type f | LC_ALL=C sort -s)
|
||||||
|
|
||||||
total_files=$(wc -l <<< "${find_result}")
|
total_files=$(echo "${find_result}" | wc -l)
|
||||||
|
|
||||||
count=1
|
count=1
|
||||||
for file in $find_result
|
for file in $find_result
|
||||||
do
|
do
|
||||||
echo -ne " \r"
|
printf " \r"
|
||||||
echo -ne "Reading file $count/$total_files..."
|
printf "Reading file %d/%d..." "$count" "$total_files"
|
||||||
|
|
||||||
# On Windows, find still outputs the name of pruned folders
|
# On Windows, find still outputs the name of pruned folders
|
||||||
if [ ! -d "$file" ]
|
if [ ! -d "$file" ]
|
||||||
|
@ -94,9 +100,8 @@ do
|
||||||
xgettext $KEYWORDS --no-wrap -j -o "$OUTFILE" --from-code=UTF-8 "$file" || exit 1
|
xgettext $KEYWORDS --no-wrap -j -o "$OUTFILE" --from-code=UTF-8 "$file" || exit 1
|
||||||
sed -i.bkp "s/CHARSET/UTF-8/g" "$OUTFILE"
|
sed -i.bkp "s/CHARSET/UTF-8/g" "$OUTFILE"
|
||||||
fi
|
fi
|
||||||
(( count++ ))
|
count=$((count + 1))
|
||||||
done
|
done
|
||||||
echo -ne "\n"
|
|
||||||
|
|
||||||
echo "Interpolate metadata.."
|
echo "Interpolate metadata.."
|
||||||
|
|
||||||
|
@ -119,7 +124,7 @@ case "$MODE" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ "" != "$1" ] && [ "$MODE" == "default" ]
|
if [ -n "$1" ] && [ "$MODE" = "default" ]
|
||||||
then
|
then
|
||||||
UPDATEFILE="$(resolve "${FULLPATH}/$1")"
|
UPDATEFILE="$(resolve "${FULLPATH}/$1")"
|
||||||
echo "Merging new strings to $UPDATEFILE.."
|
echo "Merging new strings to $UPDATEFILE.."
|
||||||
|
|
|
@ -21,7 +21,7 @@ chdir(dirname(__DIR__));
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
fwrite(STDOUT, '`bin/worker.php` is deprecated since 2024.02 and will be removed in 5 months, please use `bin/console.php worker` instead.' . \PHP_EOL);
|
fwrite(STDOUT, '`bin/worker.php` is deprecated since 2025.02 and will be removed in 5 months, please use `bin/console.php worker` instead.' . \PHP_EOL);
|
||||||
|
|
||||||
// BC: Add console command as second argument
|
// BC: Add console command as second argument
|
||||||
$argv = $_SERVER['argv'] ?? [];
|
$argv = $_SERVER['argv'] ?? [];
|
||||||
|
|
|
@ -70,10 +70,12 @@
|
||||||
"pragmarx/google2fa": "^5.0",
|
"pragmarx/google2fa": "^5.0",
|
||||||
"pragmarx/recovery": "^0.2",
|
"pragmarx/recovery": "^0.2",
|
||||||
"psr/clock": "^1.0",
|
"psr/clock": "^1.0",
|
||||||
"psr/container": "^2.0",
|
"psr/container": "^1.1|^2.0",
|
||||||
|
"psr/event-dispatcher": "^1.0",
|
||||||
"psr/log": "^1.1",
|
"psr/log": "^1.1",
|
||||||
"seld/cli-prompt": "^1.0",
|
"seld/cli-prompt": "^1.0",
|
||||||
"smarty/smarty": "^4",
|
"smarty/smarty": "^4",
|
||||||
|
"symfony/event-dispatcher": "^5.4",
|
||||||
"textalk/websocket": "^1.6",
|
"textalk/websocket": "^1.6",
|
||||||
"ua-parser/uap-php": "^3.9",
|
"ua-parser/uap-php": "^3.9",
|
||||||
"xemlock/htmlpurifier-html5": "^0.1.11"
|
"xemlock/htmlpurifier-html5": "^0.1.11"
|
||||||
|
@ -114,7 +116,6 @@
|
||||||
},
|
},
|
||||||
"sort-packages": true,
|
"sort-packages": true,
|
||||||
"autoloader-suffix": "Friendica",
|
"autoloader-suffix": "Friendica",
|
||||||
"optimize-autoloader": true,
|
|
||||||
"preferred-install": "dist",
|
"preferred-install": "dist",
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
"composer/installers": true,
|
"composer/installers": true,
|
||||||
|
@ -174,6 +175,7 @@
|
||||||
"@cs:install",
|
"@cs:install",
|
||||||
"bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix"
|
"bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix"
|
||||||
],
|
],
|
||||||
"cs:fix-develop": "TARGET_BRANCH=develop COMMAND=fix bin/dev/fix-codestyle.sh"
|
"cs:fix-develop": "TARGET_BRANCH=develop COMMAND=fix bin/dev/fix-codestyle.sh",
|
||||||
|
"install:prod": "@composer install -o --no-dev"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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": "1398ab5832571c32982984ffe9bd810f",
|
"content-hash": "b77bf714197f04022a5feb001bf07852",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "asika/simple-console",
|
"name": "asika/simple-console",
|
||||||
|
@ -3139,6 +3139,9 @@
|
||||||
"psr",
|
"psr",
|
||||||
"psr-6"
|
"psr-6"
|
||||||
],
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/cache/tree/master"
|
||||||
|
},
|
||||||
"time": "2016-08-06T20:24:11+00:00"
|
"time": "2016-08-06T20:24:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -3187,27 +3190,22 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
"version": "2.0.2",
|
"version": "1.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/php-fig/container.git",
|
"url": "https://github.com/php-fig/container.git",
|
||||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
|
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.4.0"
|
"php": ">=7.4.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.0.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Psr\\Container\\": "src/"
|
"Psr\\Container\\": "src/"
|
||||||
|
@ -3232,7 +3230,61 @@
|
||||||
"container-interop",
|
"container-interop",
|
||||||
"psr"
|
"psr"
|
||||||
],
|
],
|
||||||
"time": "2021-11-05T16:47:00+00:00"
|
"support": {
|
||||||
|
"issues": "https://github.com/php-fig/container/issues",
|
||||||
|
"source": "https://github.com/php-fig/container/tree/1.1.2"
|
||||||
|
},
|
||||||
|
"time": "2021-11-05T16:50:12+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/event-dispatcher",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/event-dispatcher.git",
|
||||||
|
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
|
||||||
|
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\EventDispatcher\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Standard interfaces for event handling.",
|
||||||
|
"keywords": [
|
||||||
|
"events",
|
||||||
|
"psr",
|
||||||
|
"psr-14"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/php-fig/event-dispatcher/issues",
|
||||||
|
"source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
|
||||||
|
},
|
||||||
|
"time": "2019-01-08T18:20:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/http-client",
|
"name": "psr/http-client",
|
||||||
|
@ -3430,6 +3482,9 @@
|
||||||
"psr",
|
"psr",
|
||||||
"psr-3"
|
"psr-3"
|
||||||
],
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/log/tree/1.1.4"
|
||||||
|
},
|
||||||
"time": "2021-05-03T11:20:27+00:00"
|
"time": "2021-05-03T11:20:27+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -3647,16 +3702,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
"version": "v2.5.2",
|
"version": "v2.5.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
|
"reference": "605389f2a7e5625f273b53960dc46aeaf9c62918"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918",
|
||||||
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
|
"reference": "605389f2a7e5625f273b53960dc46aeaf9c62918",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3664,12 +3719,12 @@
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/contracts",
|
||||||
|
"name": "symfony/contracts"
|
||||||
|
},
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "2.5-dev"
|
"dev-main": "2.5-dev"
|
||||||
},
|
|
||||||
"thanks": {
|
|
||||||
"name": "symfony/contracts",
|
|
||||||
"url": "https://github.com/symfony/contracts"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -3693,6 +3748,9 @@
|
||||||
],
|
],
|
||||||
"description": "A generic function and convention to trigger deprecation notices",
|
"description": "A generic function and convention to trigger deprecation notices",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4"
|
||||||
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"url": "https://symfony.com/sponsor",
|
"url": "https://symfony.com/sponsor",
|
||||||
|
@ -3707,7 +3765,171 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-01-02T09:53:40+00:00"
|
"time": "2024-09-25T14:11:13+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/event-dispatcher",
|
||||||
|
"version": "v5.4.45",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||||
|
"reference": "72982eb416f61003e9bb6e91f8b3213600dcf9e9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/72982eb416f61003e9bb6e91f8b3213600dcf9e9",
|
||||||
|
"reference": "72982eb416f61003e9bb6e91f8b3213600dcf9e9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"symfony/deprecation-contracts": "^2.1|^3",
|
||||||
|
"symfony/event-dispatcher-contracts": "^2|^3",
|
||||||
|
"symfony/polyfill-php80": "^1.16"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/dependency-injection": "<4.4"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/event-dispatcher-implementation": "1.0",
|
||||||
|
"symfony/event-dispatcher-implementation": "2.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"psr/log": "^1|^2|^3",
|
||||||
|
"symfony/config": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/dependency-injection": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/error-handler": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/expression-language": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/http-foundation": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/service-contracts": "^1.1|^2|^3",
|
||||||
|
"symfony/stopwatch": "^4.4|^5.0|^6.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/dependency-injection": "",
|
||||||
|
"symfony/http-kernel": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\EventDispatcher\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/event-dispatcher/tree/v5.4.45"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-25T14:11:13+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/event-dispatcher-contracts",
|
||||||
|
"version": "v2.5.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
|
||||||
|
"reference": "e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f",
|
||||||
|
"reference": "e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"psr/event-dispatcher": "^1"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/event-dispatcher-implementation": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/contracts",
|
||||||
|
"name": "symfony/contracts"
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "2.5-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Contracts\\EventDispatcher\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Generic abstractions related to dispatching event",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"abstractions",
|
||||||
|
"contracts",
|
||||||
|
"decoupling",
|
||||||
|
"interfaces",
|
||||||
|
"interoperability",
|
||||||
|
"standards"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.4"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-25T14:11:13+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php56",
|
"name": "symfony/polyfill-php56",
|
||||||
|
@ -3774,6 +3996,86 @@
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2020-10-23T14:02:19+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-php80",
|
||||||
|
"version": "v1.31.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||||
|
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||||
|
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/polyfill",
|
||||||
|
"name": "symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Php80\\": ""
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"Resources/stubs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ion Bazan",
|
||||||
|
"email": "ion.bazan@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "textalk/websocket",
|
"name": "textalk/websocket",
|
||||||
"version": "1.6.3",
|
"version": "1.6.3",
|
||||||
|
@ -6725,41 +7027,50 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/dependency-injection",
|
"name": "symfony/dependency-injection",
|
||||||
"version": "v3.2.14",
|
"version": "v5.4.48",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/dependency-injection.git",
|
"url": "https://github.com/symfony/dependency-injection.git",
|
||||||
"reference": "d9f2e62e1a93d52ad4e4f6faaf66f6eef723d761"
|
"reference": "e5ca16dee39ef7d63e552ff0bf0a2526a1142c92"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d9f2e62e1a93d52ad4e4f6faaf66f6eef723d761",
|
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e5ca16dee39ef7d63e552ff0bf0a2526a1142c92",
|
||||||
"reference": "d9f2e62e1a93d52ad4e4f6faaf66f6eef723d761",
|
"reference": "e5ca16dee39ef7d63e552ff0bf0a2526a1142c92",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5.9"
|
"php": ">=7.2.5",
|
||||||
|
"psr/container": "^1.1.1",
|
||||||
|
"symfony/deprecation-contracts": "^2.1|^3",
|
||||||
|
"symfony/polyfill-php80": "^1.16",
|
||||||
|
"symfony/polyfill-php81": "^1.22",
|
||||||
|
"symfony/service-contracts": "^1.1.6|^2"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/yaml": "<3.2"
|
"ext-psr": "<1.1|>=2",
|
||||||
|
"symfony/config": "<5.3",
|
||||||
|
"symfony/finder": "<4.4",
|
||||||
|
"symfony/proxy-manager-bridge": "<4.4",
|
||||||
|
"symfony/yaml": "<4.4.26"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/container-implementation": "1.0",
|
||||||
|
"symfony/service-implementation": "1.0|2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/config": "~2.8|~3.0",
|
"symfony/config": "^5.3|^6.0",
|
||||||
"symfony/expression-language": "~2.8|~3.0",
|
"symfony/expression-language": "^4.4|^5.0|^6.0",
|
||||||
"symfony/yaml": "~3.2"
|
"symfony/yaml": "^4.4.26|^5.0|^6.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/config": "",
|
"symfony/config": "",
|
||||||
"symfony/expression-language": "For using expressions in service container configuration",
|
"symfony/expression-language": "For using expressions in service container configuration",
|
||||||
|
"symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required",
|
||||||
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
|
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
|
||||||
"symfony/yaml": ""
|
"symfony/yaml": ""
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "3.2-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Symfony\\Component\\DependencyInjection\\": ""
|
"Symfony\\Component\\DependencyInjection\\": ""
|
||||||
|
@ -6782,12 +7093,26 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony DependencyInjection Component",
|
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/dependency-injection/tree/3.2"
|
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.48"
|
||||||
},
|
},
|
||||||
"time": "2017-07-28T15:22:55+00:00"
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-11-20T10:51:57+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/filesystem",
|
"name": "symfony/filesystem",
|
||||||
|
@ -7015,86 +7340,6 @@
|
||||||
],
|
],
|
||||||
"time": "2024-09-09T11:45:10+00:00"
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "symfony/polyfill-php80",
|
|
||||||
"version": "v1.31.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
|
||||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
|
||||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=7.2"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"thanks": {
|
|
||||||
"url": "https://github.com/symfony/polyfill",
|
|
||||||
"name": "symfony/polyfill"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"bootstrap.php"
|
|
||||||
],
|
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Polyfill\\Php80\\": ""
|
|
||||||
},
|
|
||||||
"classmap": [
|
|
||||||
"Resources/stubs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Ion Bazan",
|
|
||||||
"email": "ion.bazan@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Nicolas Grekas",
|
|
||||||
"email": "p@tchwork.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "https://symfony.com/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
|
||||||
"homepage": "https://symfony.com",
|
|
||||||
"keywords": [
|
|
||||||
"compatibility",
|
|
||||||
"polyfill",
|
|
||||||
"portable",
|
|
||||||
"shim"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://symfony.com/sponsor",
|
|
||||||
"type": "custom"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/fabpot",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2024-09-09T11:45:10+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php81",
|
"name": "symfony/polyfill-php81",
|
||||||
"version": "v1.31.0",
|
"version": "v1.31.0",
|
||||||
|
@ -7171,6 +7416,89 @@
|
||||||
],
|
],
|
||||||
"time": "2024-09-09T11:45:10+00:00"
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/service-contracts",
|
||||||
|
"version": "v2.5.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/service-contracts.git",
|
||||||
|
"reference": "f37b419f7aea2e9abf10abd261832cace12e3300"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/f37b419f7aea2e9abf10abd261832cace12e3300",
|
||||||
|
"reference": "f37b419f7aea2e9abf10abd261832cace12e3300",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"psr/container": "^1.1",
|
||||||
|
"symfony/deprecation-contracts": "^2.1|^3"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"ext-psr": "<1.1|>=2"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/service-implementation": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/contracts",
|
||||||
|
"name": "symfony/contracts"
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "2.5-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Contracts\\Service\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Generic abstractions related to writing services",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"abstractions",
|
||||||
|
"contracts",
|
||||||
|
"decoupling",
|
||||||
|
"interfaces",
|
||||||
|
"interoperability",
|
||||||
|
"standards"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/service-contracts/tree/v2.5.4"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-25T14:11:13+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "theseer/tokenizer",
|
"name": "theseer/tokenizer",
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2025.02-dev (Interrupted Fern)
|
-- Friendica 2025.02-dev (Interrupted Fern)
|
||||||
-- DB_UPDATE_VERSION 1576
|
-- DB_UPDATE_VERSION 1577
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -1609,7 +1609,7 @@ CREATE TABLE IF NOT EXISTS `post-user` (
|
||||||
`psid` int unsigned COMMENT 'ID of the permission set of this post',
|
`psid` int unsigned COMMENT 'ID of the permission set of this post',
|
||||||
PRIMARY KEY(`id`),
|
PRIMARY KEY(`id`),
|
||||||
UNIQUE INDEX `uid_uri-id` (`uid`,`uri-id`),
|
UNIQUE INDEX `uid_uri-id` (`uid`,`uri-id`),
|
||||||
INDEX `uri-id` (`uri-id`),
|
INDEX `uri-id_origin_deleted` (`uri-id`,`origin`,`deleted`),
|
||||||
INDEX `parent-uri-id` (`parent-uri-id`),
|
INDEX `parent-uri-id` (`parent-uri-id`),
|
||||||
INDEX `thr-parent-id` (`thr-parent-id`),
|
INDEX `thr-parent-id` (`thr-parent-id`),
|
||||||
INDEX `external-id` (`external-id`),
|
INDEX `external-id` (`external-id`),
|
||||||
|
@ -3809,7 +3809,8 @@ CREATE VIEW `pending-view` AS SELECT
|
||||||
`contact`.`nick` AS `nick`
|
`contact`.`nick` AS `nick`
|
||||||
FROM `register`
|
FROM `register`
|
||||||
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
||||||
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`;
|
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`
|
||||||
|
WHERE `register`.`uid` != 0;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- VIEW tag-search-view
|
-- VIEW tag-search-view
|
||||||
|
|
|
@ -62,7 +62,7 @@ If you want to have git automatically update the dependencies with composer, you
|
||||||
}
|
}
|
||||||
# `composer install` if the `composer.lock` file gets changed
|
# `composer install` if the `composer.lock` file gets changed
|
||||||
# to update all the php dependencies
|
# to update all the php dependencies
|
||||||
check_run composer.lock "bin/composer.phar install --no-dev"
|
check_run composer.lock "bin/composer.phar install"
|
||||||
|
|
||||||
just place it into `.git/hooks/post-merge` and make it executable.
|
just place it into `.git/hooks/post-merge` and make it executable.
|
||||||
|
|
||||||
|
@ -210,9 +210,9 @@ If the deprecated code is no longer used inside Friendica or the official addons
|
||||||
The code MUST NOT be deleted.
|
The code MUST NOT be deleted.
|
||||||
Starting from the next release, it MUST be stay for at least 5 months.
|
Starting from the next release, it MUST be stay for at least 5 months.
|
||||||
Hard deprecated code COULD remain longer than 5 months, depending on when a release appears.
|
Hard deprecated code COULD remain longer than 5 months, depending on when a release appears.
|
||||||
Addon developer MUST NOT consider that they have more than 5 months to adjust their code.
|
Addon developer SHOULD NOT consider that they have more than 5 months to adjust their code.
|
||||||
|
|
||||||
Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error if it is called.
|
Hard deprecation code means that the code triggers a muted `E_USER_DEPRECATION` error if it is called.
|
||||||
For instance with the deprecated class `Friendica\Core\Logger` the call of every method should trigger an error:
|
For instance with the deprecated class `Friendica\Core\Logger` the call of every method should trigger an error:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
@ -224,7 +224,7 @@ For instance with the deprecated class `Friendica\Core\Logger` the call of every
|
||||||
class Logger {
|
class Logger {
|
||||||
public static function info(string $message, array $context = [])
|
public static function info(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.05 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.05 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->info($message, $context);
|
self::getInstance()->info($message, $context);
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ class Logger {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This way the maintainer or users of addons will be notified that the addon will stop working in one of the next releases.
|
This way the maintainer or users of addons will be notified in the logs that the addon will stop working in one of the next releases.
|
||||||
The addon maintainer now has at least 5 months or at least one release to fix the deprecations.
|
The addon maintainer now has at least 5 months or at least one release to fix the deprecations.
|
||||||
|
|
||||||
Please note that the deprecation message contains the release that will be released next.
|
Please note that the deprecation message contains the release that will be released next.
|
||||||
|
|
|
@ -76,14 +76,6 @@ This makes the software much easier to update.
|
||||||
The Linux commands to clone the repository into a directory "mywebsite" would be
|
The Linux commands to clone the repository into a directory "mywebsite" would be
|
||||||
|
|
||||||
git clone https://github.com/friendica/friendica.git -b stable mywebsite
|
git clone https://github.com/friendica/friendica.git -b stable mywebsite
|
||||||
cd mywebsite
|
|
||||||
bin/composer.phar install --no-dev
|
|
||||||
|
|
||||||
Make sure the folder *view/smarty3* exists and is writable by the webserver user, in this case *www-data*
|
|
||||||
|
|
||||||
mkdir -p view/smarty3
|
|
||||||
chown www-data:www-data view/smarty3
|
|
||||||
chmod 775 view/smarty3
|
|
||||||
|
|
||||||
Get the addons by going into your website folder.
|
Get the addons by going into your website folder.
|
||||||
|
|
||||||
|
@ -91,12 +83,22 @@ Get the addons by going into your website folder.
|
||||||
|
|
||||||
Clone the addon repository (separately):
|
Clone the addon repository (separately):
|
||||||
|
|
||||||
git clone https://github.com/friendica/friendica-addons.git -b stable addon
|
git clone https://github.com/friendica/friendica-addons.git -b stable addon
|
||||||
|
|
||||||
|
Install the dependencies:
|
||||||
|
|
||||||
|
bin/composer.phar run install:prod
|
||||||
|
|
||||||
|
Make sure the folder *view/smarty3* exists and is writable by the webserver user, in this case *www-data*
|
||||||
|
|
||||||
|
mkdir -p view/smarty3
|
||||||
|
chown www-data:www-data view/smarty3
|
||||||
|
chmod 775 view/smarty3
|
||||||
|
|
||||||
If you want to use the development version of Friendica you can switch to the develop branch in the repository by running
|
If you want to use the development version of Friendica you can switch to the develop branch in the repository by running
|
||||||
|
|
||||||
git checkout develop
|
git checkout develop
|
||||||
bin/composer.phar install
|
bin/composer.phar run install:prod
|
||||||
cd addon
|
cd addon
|
||||||
git checkout develop
|
git checkout develop
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ If you installed Friendica in the ``path/to/friendica`` folder:
|
||||||
* ``.htaccess`` if using Apache web server
|
* ``.htaccess`` if using Apache web server
|
||||||
|
|
||||||
The following items only need to be copied if they are located inside your friendica path:
|
The following items only need to be copied if they are located inside your friendica path:
|
||||||
* your storage folder as set in **Admin -> Site -> File Upload -> Storage base path**
|
* your storage folder as set in **Admin -> Site -> File Upload -> Storage base path**
|
||||||
* your item cache as set in **Admin -> Site -> Performance -> Path to item cache**
|
* your item cache as set in **Admin -> Site -> Performance -> Path to item cache**
|
||||||
* your temp folder as set in **Admin -> Site -> Advanced -> Temp path**
|
* your temp folder as set in **Admin -> Site -> Advanced -> Temp path**
|
||||||
3. Rename the ``path/to/friendica`` folder to ``path/to/friendica_old``.
|
3. Rename the ``path/to/friendica`` folder to ``path/to/friendica_old``.
|
||||||
|
@ -30,7 +30,7 @@ You can get the latest changes at any time with
|
||||||
|
|
||||||
cd path/to/friendica
|
cd path/to/friendica
|
||||||
git pull
|
git pull
|
||||||
bin/composer.phar install --no-dev
|
bin/composer.phar run install:prod
|
||||||
|
|
||||||
The addon tree has to be updated separately like so:
|
The addon tree has to be updated separately like so:
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ Some of the updates include the use of foreign keys now that will bump into issu
|
||||||
```
|
```
|
||||||
Error 1452 occurred during database update:
|
Error 1452 occurred during database update:
|
||||||
Cannot add or update a child row: a foreign key constraint fails (`friendica`.`#sql-10ea6_5a6d`, CONSTRAINT `#sql-10ea6_5a6d_ibfk_1` FOREIGN KEY (`contact-id`) REFERENCES `contact` (`id`))
|
Cannot add or update a child row: a foreign key constraint fails (`friendica`.`#sql-10ea6_5a6d`, CONSTRAINT `#sql-10ea6_5a6d_ibfk_1` FOREIGN KEY (`contact-id`) REFERENCES `contact` (`id`))
|
||||||
ALTER TABLE `thread` ADD FOREIGN KEY (`iid`) REFERENCES `item` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE;
|
ALTER TABLE `thread` ADD FOREIGN KEY (`iid`) REFERENCES `item` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE;
|
||||||
```
|
```
|
||||||
|
|
||||||
All current known fixes for possible items that can go wrong are as below.
|
All current known fixes for possible items that can go wrong are as below.
|
||||||
|
|
|
@ -18,7 +18,7 @@ What you need to do:
|
||||||
Please use an up-to-date vagrant version from https://www.vagrantup.com/downloads.html.
|
Please use an up-to-date vagrant version from https://www.vagrantup.com/downloads.html.
|
||||||
2. Git clone your Friendica repository.
|
2. Git clone your Friendica repository.
|
||||||
Inside, you'll find a `Vagrantfile` and some scripts in the `bin/dev` folder.
|
Inside, you'll find a `Vagrantfile` and some scripts in the `bin/dev` folder.
|
||||||
Pull the PHP requirements with `bin/composer install`.
|
Pull the PHP requirements with `bin/composer.phar install`.
|
||||||
3. Run `vagrant up` from inside the friendica clone.
|
3. Run `vagrant up` from inside the friendica clone.
|
||||||
This will start the virtual machine.
|
This will start the virtual machine.
|
||||||
Be patient: When it runs for the first time, it downloads a Debian Server image and installs Friendica.
|
Be patient: When it runs for the first time, it downloads a Debian Server image and installs Friendica.
|
||||||
|
@ -60,7 +60,7 @@ Trouble Shooting
|
||||||
If you see a version mis-match for the _VirtualBox Guest Additions_ between host and guest during the initial setup of the Vagrant VM, you will need to install an addon to Vagrant (ref. [Stack Overflow](https://stackoverflow.com/a/38010683)).
|
If you see a version mis-match for the _VirtualBox Guest Additions_ between host and guest during the initial setup of the Vagrant VM, you will need to install an addon to Vagrant (ref. [Stack Overflow](https://stackoverflow.com/a/38010683)).
|
||||||
Stop the Vagrant VM and run the following command:
|
Stop the Vagrant VM and run the following command:
|
||||||
|
|
||||||
$> vagrant plugin install vagrant-vbguest
|
$> vagrant plugin install vagrant-vbguest
|
||||||
|
|
||||||
On the next Vagrant up, the version problem should be fixed.
|
On the next Vagrant up, the version problem should be fixed.
|
||||||
|
|
||||||
|
|
|
@ -44,31 +44,31 @@ Fields
|
||||||
Indexes
|
Indexes
|
||||||
------------
|
------------
|
||||||
|
|
||||||
| Name | Fields |
|
| Name | Fields |
|
||||||
| -------------------- | ----------------------- |
|
|-----------------------| ----------------------- |
|
||||||
| PRIMARY | id |
|
| PRIMARY | id |
|
||||||
| uid_uri-id | UNIQUE, uid, uri-id |
|
| uid_uri-id | UNIQUE, uid, uri-id |
|
||||||
| uri-id | uri-id |
|
| uri-id_origin_deleted | uri-id, origin, deleted |
|
||||||
| parent-uri-id | parent-uri-id |
|
| parent-uri-id | parent-uri-id |
|
||||||
| thr-parent-id | thr-parent-id |
|
| thr-parent-id | thr-parent-id |
|
||||||
| external-id | external-id |
|
| external-id | external-id |
|
||||||
| replies-id | replies-id |
|
| replies-id | replies-id |
|
||||||
| owner-id | owner-id |
|
| owner-id | owner-id |
|
||||||
| author-id | author-id |
|
| author-id | author-id |
|
||||||
| causer-id | causer-id |
|
| causer-id | causer-id |
|
||||||
| vid | vid |
|
| vid | vid |
|
||||||
| contact-id | contact-id |
|
| contact-id | contact-id |
|
||||||
| event-id | event-id |
|
| event-id | event-id |
|
||||||
| psid | psid |
|
| psid | psid |
|
||||||
| author-id_uid | author-id, uid |
|
| author-id_uid | author-id, uid |
|
||||||
| author-id_created | author-id, created |
|
| author-id_created | author-id, created |
|
||||||
| owner-id_created | owner-id, created |
|
| owner-id_created | owner-id, created |
|
||||||
| parent-uri-id_uid | parent-uri-id, uid |
|
| parent-uri-id_uid | parent-uri-id, uid |
|
||||||
| uid_wall_received | uid, wall, received |
|
| uid_wall_received | uid, wall, received |
|
||||||
| uid_contactid | uid, contact-id |
|
| uid_contactid | uid, contact-id |
|
||||||
| uid_unseen_contactid | uid, unseen, contact-id |
|
| uid_unseen_contactid | uid, unseen, contact-id |
|
||||||
| uid_unseen | uid, unseen |
|
| uid_unseen | uid, unseen |
|
||||||
| uid_hidden_uri-id | uid, hidden, uri-id |
|
| uid_hidden_uri-id | uid, hidden, uri-id |
|
||||||
|
|
||||||
Foreign Keys
|
Foreign Keys
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -59,7 +59,7 @@ Der Linux-Code, mit dem man die Dateien direkt in ein Verzeichnis wie "meinewebs
|
||||||
|
|
||||||
git clone https://github.com/friendica/friendica.git -b stable mywebsite
|
git clone https://github.com/friendica/friendica.git -b stable mywebsite
|
||||||
cd mywebsite
|
cd mywebsite
|
||||||
bin/composer.phar install
|
bin/composer.phar run install:prod
|
||||||
|
|
||||||
Stelle sicher, dass der Ordner *view/smarty3* existiert and von dem Webserver-Benutzer beschreibbar ist
|
Stelle sicher, dass der Ordner *view/smarty3* existiert and von dem Webserver-Benutzer beschreibbar ist
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ Wenn du die Entwickler Version von Friendica verwenden möchtest kannst du auf d
|
||||||
Dies tust du mit den folgenden Befehlen
|
Dies tust du mit den folgenden Befehlen
|
||||||
|
|
||||||
git checkout develop
|
git checkout develop
|
||||||
bin/composer.phar install
|
bin/composer.phar run install:prod
|
||||||
cd addon
|
cd addon
|
||||||
git checkout develop
|
git checkout develop
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
$start_time = microtime(true);
|
$start_time = microtime(true);
|
||||||
|
|
||||||
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
|
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
|
||||||
die('Vendor path not found. Please execute "bin/composer.phar --no-dev install" on the command line in the web root.');
|
die('Vendor path not found. Please execute "bin/composer.phar run install:prod" on the command line in the web root.');
|
||||||
}
|
}
|
||||||
|
|
||||||
require __DIR__ . '/vendor/autoload.php';
|
require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
|
@ -11,7 +11,6 @@ use Friendica\Content\Nav;
|
||||||
use Friendica\Content\Pager;
|
use Friendica\Content\Pager;
|
||||||
use Friendica\Content\Text\BBCode;
|
use Friendica\Content\Text\BBCode;
|
||||||
use Friendica\Core\ACL;
|
use Friendica\Core\ACL;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
|
@ -1067,6 +1066,7 @@ function photos_content()
|
||||||
$cmnt_tpl = Renderer::getMarkupTemplate('comment_item.tpl');
|
$cmnt_tpl = Renderer::getMarkupTemplate('comment_item.tpl');
|
||||||
$tpl = Renderer::getMarkupTemplate('photo_item.tpl');
|
$tpl = Renderer::getMarkupTemplate('photo_item.tpl');
|
||||||
$return_path = DI::args()->getCommand();
|
$return_path = DI::args()->getCommand();
|
||||||
|
$addonHelper = DI::addonHelper();
|
||||||
|
|
||||||
if (!DBA::isResult($items)) {
|
if (!DBA::isResult($items)) {
|
||||||
if (($can_post || Security::canWriteToUserWall($owner_uid))) {
|
if (($can_post || Security::canWriteToUserWall($owner_uid))) {
|
||||||
|
@ -1075,7 +1075,7 @@ function photos_content()
|
||||||
* This should be better if done by a hook
|
* This should be better if done by a hook
|
||||||
*/
|
*/
|
||||||
$qcomment = null;
|
$qcomment = null;
|
||||||
if (Addon::isEnabled('qcomment')) {
|
if ($addonHelper->isAddonEnabled('qcomment')) {
|
||||||
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
|
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
|
||||||
$qcomment = $words ? explode("\n", $words) : [];
|
$qcomment = $words ? explode("\n", $words) : [];
|
||||||
}
|
}
|
||||||
|
@ -1131,7 +1131,7 @@ function photos_content()
|
||||||
* This should be better if done by a hook
|
* This should be better if done by a hook
|
||||||
*/
|
*/
|
||||||
$qcomment = null;
|
$qcomment = null;
|
||||||
if (Addon::isEnabled('qcomment')) {
|
if ($addonHelper->isAddonEnabled('qcomment')) {
|
||||||
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
|
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
|
||||||
$qcomment = $words ? explode("\n", $words) : [];
|
$qcomment = $words ? explode("\n", $words) : [];
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1211,7 @@ function photos_content()
|
||||||
* This should be better if done by a hook
|
* This should be better if done by a hook
|
||||||
*/
|
*/
|
||||||
$qcomment = null;
|
$qcomment = null;
|
||||||
if (Addon::isEnabled('qcomment')) {
|
if ($addonHelper->isAddonEnabled('qcomment')) {
|
||||||
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
|
$words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'qcomment', 'words');
|
||||||
$qcomment = $words ? explode("\n", $words) : [];
|
$qcomment = $words ? explode("\n", $words) : [];
|
||||||
}
|
}
|
||||||
|
|
61
src/App.php
61
src/App.php
|
@ -17,16 +17,14 @@ use Friendica\App\Router;
|
||||||
use Friendica\Capabilities\ICanCreateResponses;
|
use Friendica\Capabilities\ICanCreateResponses;
|
||||||
use Friendica\Capabilities\ICanHandleRequests;
|
use Friendica\Capabilities\ICanHandleRequests;
|
||||||
use Friendica\Content\Nav;
|
use Friendica\Content\Nav;
|
||||||
|
use Friendica\Core\Addon\AddonHelper;
|
||||||
use Friendica\Core\Addon\Capability\ICanLoadAddons;
|
use Friendica\Core\Addon\Capability\ICanLoadAddons;
|
||||||
use Friendica\Core\Config\Factory\Config;
|
use Friendica\Core\Config\Factory\Config;
|
||||||
use Friendica\Core\Container;
|
use Friendica\Core\Container;
|
||||||
|
use Friendica\Core\Hooks\HookEventBridge;
|
||||||
use Friendica\Core\Logger\LoggerManager;
|
use Friendica\Core\Logger\LoggerManager;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||||
use Friendica\Database\Definition\DbaDefinition;
|
|
||||||
use Friendica\Database\Definition\ViewDefinition;
|
|
||||||
use Friendica\Module\Maintenance;
|
|
||||||
use Friendica\Security\Authentication;
|
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\DiceContainer;
|
use Friendica\Core\DiceContainer;
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
|
@ -35,9 +33,15 @@ use Friendica\Core\Logger\Handler\ErrorHandler;
|
||||||
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
use Friendica\Core\Update;
|
use Friendica\Core\Update;
|
||||||
|
use Friendica\Database\Definition\DbaDefinition;
|
||||||
|
use Friendica\Database\Definition\ViewDefinition;
|
||||||
|
use Friendica\Event\ConfigLoadedEvent;
|
||||||
|
use Friendica\Event\Event;
|
||||||
|
use Friendica\Module\Maintenance;
|
||||||
use Friendica\Module\Special\HTTPException as ModuleHTTPException;
|
use Friendica\Module\Special\HTTPException as ModuleHTTPException;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Protocol\ATProtocol\DID;
|
use Friendica\Protocol\ATProtocol\DID;
|
||||||
|
use Friendica\Security\Authentication;
|
||||||
use Friendica\Security\ExAuth;
|
use Friendica\Security\ExAuth;
|
||||||
use Friendica\Security\OpenWebAuth;
|
use Friendica\Security\OpenWebAuth;
|
||||||
use Friendica\Util\BasePath;
|
use Friendica\Util\BasePath;
|
||||||
|
@ -45,6 +49,7 @@ use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\HTTPInputData;
|
use Friendica\Util\HTTPInputData;
|
||||||
use Friendica\Util\HTTPSignature;
|
use Friendica\Util\HTTPSignature;
|
||||||
use Friendica\Util\Profiler;
|
use Friendica\Util\Profiler;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
@ -153,6 +158,8 @@ class App
|
||||||
|
|
||||||
$this->registerErrorHandler();
|
$this->registerErrorHandler();
|
||||||
|
|
||||||
|
$this->registerEventDispatcher();
|
||||||
|
|
||||||
$this->requestId = $this->container->create(Request::class)->getRequestId();
|
$this->requestId = $this->container->create(Request::class)->getRequestId();
|
||||||
$this->auth = $this->container->create(Authentication::class);
|
$this->auth = $this->container->create(Authentication::class);
|
||||||
$this->config = $this->container->create(IManageConfigValues::class);
|
$this->config = $this->container->create(IManageConfigValues::class);
|
||||||
|
@ -165,6 +172,8 @@ class App
|
||||||
$this->session = $this->container->create(IHandleUserSessions::class);
|
$this->session = $this->container->create(IHandleUserSessions::class);
|
||||||
$this->appHelper = $this->container->create(AppHelper::class);
|
$this->appHelper = $this->container->create(AppHelper::class);
|
||||||
|
|
||||||
|
$addonHelper = $this->container->create(AddonHelper::class);
|
||||||
|
|
||||||
$this->load(
|
$this->load(
|
||||||
$request->getServerParams(),
|
$request->getServerParams(),
|
||||||
$this->container->create(DbaDefinition::class),
|
$this->container->create(DbaDefinition::class),
|
||||||
|
@ -172,15 +181,19 @@ class App
|
||||||
$this->mode,
|
$this->mode,
|
||||||
$this->config,
|
$this->config,
|
||||||
$this->profiler,
|
$this->profiler,
|
||||||
|
$this->container->create(EventDispatcherInterface::class),
|
||||||
$this->appHelper,
|
$this->appHelper,
|
||||||
|
$addonHelper,
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->registerTemplateEngine();
|
$this->registerTemplateEngine();
|
||||||
|
|
||||||
$this->runFrontend(
|
$this->runFrontend(
|
||||||
|
$this->container->create(EventDispatcherInterface::class),
|
||||||
$this->container->create(IManagePersonalConfigValues::class),
|
$this->container->create(IManagePersonalConfigValues::class),
|
||||||
$this->container->create(Page::class),
|
$this->container->create(Page::class),
|
||||||
$this->container->create(Nav::class),
|
$this->container->create(Nav::class),
|
||||||
|
$addonHelper,
|
||||||
$this->container->create(ModuleHTTPException::class),
|
$this->container->create(ModuleHTTPException::class),
|
||||||
$start_time,
|
$start_time,
|
||||||
$request
|
$request
|
||||||
|
@ -202,6 +215,8 @@ class App
|
||||||
|
|
||||||
$this->registerErrorHandler();
|
$this->registerErrorHandler();
|
||||||
|
|
||||||
|
$this->registerEventDispatcher();
|
||||||
|
|
||||||
$this->load(
|
$this->load(
|
||||||
$serverParams,
|
$serverParams,
|
||||||
$this->container->create(DbaDefinition::class),
|
$this->container->create(DbaDefinition::class),
|
||||||
|
@ -209,7 +224,9 @@ class App
|
||||||
$this->container->create(Mode::class),
|
$this->container->create(Mode::class),
|
||||||
$this->container->create(IManageConfigValues::class),
|
$this->container->create(IManageConfigValues::class),
|
||||||
$this->container->create(Profiler::class),
|
$this->container->create(Profiler::class),
|
||||||
|
$this->container->create(EventDispatcherInterface::class),
|
||||||
$this->container->create(AppHelper::class),
|
$this->container->create(AppHelper::class),
|
||||||
|
$this->container->create(AddonHelper::class),
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->registerTemplateEngine();
|
$this->registerTemplateEngine();
|
||||||
|
@ -230,6 +247,8 @@ class App
|
||||||
|
|
||||||
$this->registerErrorHandler();
|
$this->registerErrorHandler();
|
||||||
|
|
||||||
|
$this->registerEventDispatcher();
|
||||||
|
|
||||||
$this->load(
|
$this->load(
|
||||||
$serverParams,
|
$serverParams,
|
||||||
$this->container->create(DbaDefinition::class),
|
$this->container->create(DbaDefinition::class),
|
||||||
|
@ -237,7 +256,9 @@ class App
|
||||||
$this->container->create(Mode::class),
|
$this->container->create(Mode::class),
|
||||||
$this->container->create(IManageConfigValues::class),
|
$this->container->create(IManageConfigValues::class),
|
||||||
$this->container->create(Profiler::class),
|
$this->container->create(Profiler::class),
|
||||||
|
$this->container->create(EventDispatcherInterface::class),
|
||||||
$this->container->create(AppHelper::class),
|
$this->container->create(AppHelper::class),
|
||||||
|
$this->container->create(AddonHelper::class),
|
||||||
);
|
);
|
||||||
|
|
||||||
/** @var BasePath */
|
/** @var BasePath */
|
||||||
|
@ -301,6 +322,16 @@ class App
|
||||||
ErrorHandler::register($this->container->create(LoggerInterface::class));
|
ErrorHandler::register($this->container->create(LoggerInterface::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function registerEventDispatcher(): void
|
||||||
|
{
|
||||||
|
/** @var \Friendica\Event\EventDispatcher */
|
||||||
|
$eventDispatcher = $this->container->create(EventDispatcherInterface::class);
|
||||||
|
|
||||||
|
foreach (HookEventBridge::getStaticSubscribedEvents() as $eventName => $methodName) {
|
||||||
|
$eventDispatcher->addListener($eventName, [HookEventBridge::class, $methodName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function registerTemplateEngine(): void
|
private function registerTemplateEngine(): void
|
||||||
{
|
{
|
||||||
Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
|
Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
|
||||||
|
@ -316,7 +347,9 @@ class App
|
||||||
Mode $mode,
|
Mode $mode,
|
||||||
IManageConfigValues $config,
|
IManageConfigValues $config,
|
||||||
Profiler $profiler,
|
Profiler $profiler,
|
||||||
AppHelper $appHelper
|
EventDispatcherInterface $eventDispatcher,
|
||||||
|
AppHelper $appHelper,
|
||||||
|
AddonHelper $addonHelper
|
||||||
): void {
|
): void {
|
||||||
if ($config->get('system', 'ini_max_execution_time') !== false) {
|
if ($config->get('system', 'ini_max_execution_time') !== false) {
|
||||||
set_time_limit((int) $config->get('system', 'ini_max_execution_time'));
|
set_time_limit((int) $config->get('system', 'ini_max_execution_time'));
|
||||||
|
@ -338,8 +371,9 @@ class App
|
||||||
|
|
||||||
if ($mode->has(Mode::DBAVAILABLE)) {
|
if ($mode->has(Mode::DBAVAILABLE)) {
|
||||||
Core\Hook::loadHooks();
|
Core\Hook::loadHooks();
|
||||||
$loader = (new Config())->createConfigFileManager($appHelper->getBasePath(), $serverParams);
|
$loader = (new Config())->createConfigFileManager($appHelper->getBasePath(), $addonHelper->getAddonPath(), $serverParams);
|
||||||
Core\Hook::callAll('load_config', $loader);
|
|
||||||
|
$eventDispatcher->dispatch(new ConfigLoadedEvent(ConfigLoadedEvent::CONFIG_LOADED, $loader));
|
||||||
|
|
||||||
// Hooks are now working, reload the whole definitions with hook enabled
|
// Hooks are now working, reload the whole definitions with hook enabled
|
||||||
$dbaDefinition->load(true);
|
$dbaDefinition->load(true);
|
||||||
|
@ -385,9 +419,11 @@ class App
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
*/
|
*/
|
||||||
private function runFrontend(
|
private function runFrontend(
|
||||||
|
EventDispatcherInterface $eventDispatcher,
|
||||||
IManagePersonalConfigValues $pconfig,
|
IManagePersonalConfigValues $pconfig,
|
||||||
Page $page,
|
Page $page,
|
||||||
Nav $nav,
|
Nav $nav,
|
||||||
|
AddonHelper $addonHelper,
|
||||||
ModuleHTTPException $httpException,
|
ModuleHTTPException $httpException,
|
||||||
float $start_time,
|
float $start_time,
|
||||||
ServerRequestInterface $request
|
ServerRequestInterface $request
|
||||||
|
@ -424,7 +460,8 @@ class App
|
||||||
$serverVars['REQUEST_METHOD'] === 'GET') {
|
$serverVars['REQUEST_METHOD'] === 'GET') {
|
||||||
System::externalRedirect($this->baseURL . '/' . $this->args->getQueryString());
|
System::externalRedirect($this->baseURL . '/' . $this->args->getQueryString());
|
||||||
}
|
}
|
||||||
Core\Hook::callAll('init_1');
|
|
||||||
|
$eventDispatcher->dispatch(new Event(Event::INIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
DID::routeRequest($this->args->getCommand(), $serverVars);
|
DID::routeRequest($this->args->getCommand(), $serverVars);
|
||||||
|
@ -475,12 +512,12 @@ class App
|
||||||
// but we need "view" module for stylesheet
|
// but we need "view" module for stylesheet
|
||||||
if ($this->mode->isInstall() && $moduleName !== 'install') {
|
if ($this->mode->isInstall() && $moduleName !== 'install') {
|
||||||
$this->baseURL->redirect('install');
|
$this->baseURL->redirect('install');
|
||||||
} else {
|
|
||||||
Core\Update::check($this->appHelper->getBasePath(), false);
|
|
||||||
Core\Addon::loadAddons();
|
|
||||||
Core\Hook::loadHooks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core\Update::check($this->appHelper->getBasePath(), false);
|
||||||
|
$addonHelper->loadAddons();
|
||||||
|
Core\Hook::loadHooks();
|
||||||
|
|
||||||
// Compatibility with Hubzilla
|
// Compatibility with Hubzilla
|
||||||
if ($moduleName == 'rpost') {
|
if ($moduleName == 'rpost') {
|
||||||
$this->baseURL->redirect('compose');
|
$this->baseURL->redirect('compose');
|
||||||
|
|
|
@ -14,7 +14,6 @@ use Friendica\App;
|
||||||
use Friendica\AppHelper;
|
use Friendica\AppHelper;
|
||||||
use Friendica\Content\Nav;
|
use Friendica\Content\Nav;
|
||||||
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;
|
||||||
|
@ -22,12 +21,14 @@ use Friendica\Core\Session\Model\UserSession;
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
use Friendica\Core\Theme;
|
use Friendica\Core\Theme;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\HtmlFilterEvent;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Util\Images;
|
use Friendica\Util\Images;
|
||||||
use Friendica\Util\Network;
|
use Friendica\Util\Network;
|
||||||
use Friendica\Util\Profiler;
|
use Friendica\Util\Profiler;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
use GuzzleHttp\Psr7\Utils;
|
use GuzzleHttp\Psr7\Utils;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,6 +71,8 @@ class Page implements ArrayAccess
|
||||||
*/
|
*/
|
||||||
private $basePath;
|
private $basePath;
|
||||||
|
|
||||||
|
private EventDispatcherInterface $eventDispatcher;
|
||||||
|
|
||||||
private $timestamp = 0;
|
private $timestamp = 0;
|
||||||
private $method = '';
|
private $method = '';
|
||||||
private $module = '';
|
private $module = '';
|
||||||
|
@ -78,10 +81,11 @@ class Page implements ArrayAccess
|
||||||
/**
|
/**
|
||||||
* @param string $basepath The Page basepath
|
* @param string $basepath The Page basepath
|
||||||
*/
|
*/
|
||||||
public function __construct(string $basepath)
|
public function __construct(string $basepath, EventDispatcherInterface $eventDispatcher)
|
||||||
{
|
{
|
||||||
$this->timestamp = microtime(true);
|
$this->timestamp = microtime(true);
|
||||||
$this->basePath = $basepath;
|
$this->basePath = $basepath;
|
||||||
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setLogging(string $method, string $module, string $command)
|
public function setLogging(string $method, string $module, string $command)
|
||||||
|
@ -192,17 +196,6 @@ class Page implements ArrayAccess
|
||||||
IManagePersonalConfigValues $pConfig,
|
IManagePersonalConfigValues $pConfig,
|
||||||
int $localUID
|
int $localUID
|
||||||
) {
|
) {
|
||||||
$interval = ($localUID ? $pConfig->get($localUID, 'system', 'update_interval') : 40000);
|
|
||||||
|
|
||||||
// If the update is 'deactivated' set it to the highest integer number (~24 days)
|
|
||||||
if ($interval < 0) {
|
|
||||||
$interval = 2147483647;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($interval < 10000) {
|
|
||||||
$interval = 40000;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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'] = ucfirst($args->getModuleName());
|
||||||
|
@ -229,7 +222,9 @@ class Page implements ArrayAccess
|
||||||
$touch_icon = 'images/friendica-192.png';
|
$touch_icon = 'images/friendica-192.png';
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook::callAll('head', $this->page['htmlhead']);
|
$this->page['htmlhead'] = $this->eventDispatcher->dispatch(
|
||||||
|
new HtmlFilterEvent(HtmlFilterEvent::HEAD, $this->page['htmlhead'])
|
||||||
|
)->getHtml();
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate('head.tpl');
|
$tpl = Renderer::getMarkupTemplate('head.tpl');
|
||||||
/* put the head template at the beginning of page['htmlhead']
|
/* put the head template at the beginning of page['htmlhead']
|
||||||
|
@ -266,13 +261,13 @@ class Page implements ArrayAccess
|
||||||
'dictMaxFilesExceeded' => $l10n->t("You can't upload any more files."),
|
'dictMaxFilesExceeded' => $l10n->t("You can't upload any more files."),
|
||||||
],
|
],
|
||||||
|
|
||||||
'$local_user' => $localUID,
|
'$local_user' => $localUID,
|
||||||
'$generator' => 'Friendica' . ' ' . App::VERSION,
|
'$generator' => 'Friendica' . ' ' . App::VERSION,
|
||||||
'$update_interval' => $interval,
|
'$update_content' => (int)$pConfig->get($localUID, 'system', 'update_content'),
|
||||||
'$shortcut_icon' => $shortcut_icon,
|
'$shortcut_icon' => $shortcut_icon,
|
||||||
'$touch_icon' => $touch_icon,
|
'$touch_icon' => $touch_icon,
|
||||||
'$block_public' => intval($config->get('system', 'block_public')),
|
'$block_public' => intval($config->get('system', 'block_public')),
|
||||||
'$stylesheets' => $this->stylesheets,
|
'$stylesheets' => $this->stylesheets,
|
||||||
|
|
||||||
// Dropzone
|
// Dropzone
|
||||||
'$max_imagesize' => round(Images::getMaxUploadBytes() / 1000000, 0),
|
'$max_imagesize' => round(Images::getMaxUploadBytes() / 1000000, 0),
|
||||||
|
@ -351,11 +346,14 @@ class Page implements ArrayAccess
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook::callAll('footer', $this->page['footer']);
|
$this->page['footer'] = $this->eventDispatcher->dispatch(
|
||||||
|
new HtmlFilterEvent(HtmlFilterEvent::FOOTER, $this->page['footer'])
|
||||||
|
)->getHtml();
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate('footer.tpl');
|
$tpl = Renderer::getMarkupTemplate('footer.tpl');
|
||||||
$this->page['footer'] = Renderer::replaceMacros($tpl, [
|
$this->page['footer'] = Renderer::replaceMacros($tpl, [
|
||||||
'$footerScripts' => array_unique($this->footerScripts),
|
'$footerScripts' => array_unique($this->footerScripts),
|
||||||
|
'$close' => $l10n->t('Close'),
|
||||||
]) . $this->page['footer'];
|
]) . $this->page['footer'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +373,9 @@ class Page implements ArrayAccess
|
||||||
{
|
{
|
||||||
// initialise content region
|
// initialise content region
|
||||||
if ($mode->isNormal()) {
|
if ($mode->isNormal()) {
|
||||||
Hook::callAll('page_content_top', $this->page['content']);
|
$this->page['content'] = $this->eventDispatcher->dispatch(
|
||||||
|
new HtmlFilterEvent(HtmlFilterEvent::PAGE_CONTENT_TOP, $this->page['content'])
|
||||||
|
)->getHtml();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->page['content'] .= (string)$response->getBody();
|
$this->page['content'] .= (string)$response->getBody();
|
||||||
|
@ -473,7 +473,9 @@ class Page implements ArrayAccess
|
||||||
$profiler->set(microtime(true) - $timestamp, 'aftermath');
|
$profiler->set(microtime(true) - $timestamp, 'aftermath');
|
||||||
|
|
||||||
if (!$mode->isAjax()) {
|
if (!$mode->isAjax()) {
|
||||||
Hook::callAll('page_end', $this->page['content']);
|
$this->page['content'] = $this->eventDispatcher->dispatch(
|
||||||
|
new HtmlFilterEvent(HtmlFilterEvent::PAGE_END, $this->page['content'])
|
||||||
|
)->getHtml();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the navigation (menu) template
|
// Add the navigation (menu) template
|
||||||
|
|
|
@ -7,13 +7,11 @@
|
||||||
|
|
||||||
namespace Friendica\App;
|
namespace Friendica\App;
|
||||||
|
|
||||||
use Dice\Dice;
|
|
||||||
use FastRoute\DataGenerator\GroupCountBased;
|
use FastRoute\DataGenerator\GroupCountBased;
|
||||||
use FastRoute\Dispatcher;
|
use FastRoute\Dispatcher;
|
||||||
use FastRoute\RouteCollector;
|
use FastRoute\RouteCollector;
|
||||||
use FastRoute\RouteParser\Std;
|
use FastRoute\RouteParser\Std;
|
||||||
use Friendica\Capabilities\ICanHandleRequests;
|
use Friendica\Core\Addon\AddonHelper;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Cache\Enum\Duration;
|
use Friendica\Core\Cache\Enum\Duration;
|
||||||
use Friendica\Core\Cache\Capability\ICanCache;
|
use Friendica\Core\Cache\Capability\ICanCache;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
@ -86,6 +84,8 @@ class Router
|
||||||
/** @var LoggerInterface */
|
/** @var LoggerInterface */
|
||||||
private $logger;
|
private $logger;
|
||||||
|
|
||||||
|
private AddonHelper $addonHelper;
|
||||||
|
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $isLocalUser;
|
private $isLocalUser;
|
||||||
|
|
||||||
|
@ -110,17 +110,18 @@ class Router
|
||||||
* @param IHandleUserSessions $userSession
|
* @param IHandleUserSessions $userSession
|
||||||
* @param RouteCollector|null $routeCollector
|
* @param RouteCollector|null $routeCollector
|
||||||
*/
|
*/
|
||||||
public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
|
public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, AddonHelper $addonHelper, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
|
||||||
{
|
{
|
||||||
$this->baseRoutesFilepath = $baseRoutesFilepath;
|
$this->baseRoutesFilepath = $baseRoutesFilepath;
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
$this->cache = $cache;
|
$this->cache = $cache;
|
||||||
$this->lock = $lock;
|
$this->lock = $lock;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->isLocalUser = !empty($userSession->getLocalUserId());
|
$this->addonHelper = $addonHelper;
|
||||||
|
$this->isLocalUser = !empty($userSession->getLocalUserId());
|
||||||
|
|
||||||
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
|
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
|
||||||
|
|
||||||
|
@ -275,14 +276,14 @@ class Router
|
||||||
try {
|
try {
|
||||||
// Check if the HTTP method is OPTIONS and return the special Options Module with the possible HTTP methods
|
// Check if the HTTP method is OPTIONS and return the special Options Module with the possible HTTP methods
|
||||||
if ($this->args->getMethod() === static::OPTIONS) {
|
if ($this->args->getMethod() === static::OPTIONS) {
|
||||||
$this->moduleClass = Options::class;
|
$this->moduleClass = Options::class;
|
||||||
$this->parameters[] = ['AllowedMethods' => $dispatcher->getOptions($cmd)];
|
$this->parameters[] = ['AllowedMethods' => $dispatcher->getOptions($cmd)];
|
||||||
} else {
|
} else {
|
||||||
$routeInfo = $dispatcher->dispatch($this->args->getMethod(), $cmd);
|
$routeInfo = $dispatcher->dispatch($this->args->getMethod(), $cmd);
|
||||||
if ($routeInfo[0] === Dispatcher::FOUND) {
|
if ($routeInfo[0] === Dispatcher::FOUND) {
|
||||||
$this->moduleClass = $routeInfo[1];
|
$this->moduleClass = $routeInfo[1];
|
||||||
$this->parameters[] = $routeInfo[2];
|
$this->parameters[] = $routeInfo[2];
|
||||||
} else if ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
|
} elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
|
||||||
throw new HTTPException\MethodNotAllowedException($this->l10n->t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1])));
|
throw new HTTPException\MethodNotAllowedException($this->l10n->t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1])));
|
||||||
} else {
|
} else {
|
||||||
throw new HTTPException\NotFoundException($this->l10n->t('Page not found.'));
|
throw new HTTPException\NotFoundException($this->l10n->t('Page not found.'));
|
||||||
|
@ -293,7 +294,7 @@ class Router
|
||||||
} catch (NotFoundException $e) {
|
} catch (NotFoundException $e) {
|
||||||
$moduleName = $this->args->getModuleName();
|
$moduleName = $this->args->getModuleName();
|
||||||
// Then we try addon-provided modules that we wrap in the LegacyModule class
|
// Then we try addon-provided modules that we wrap in the LegacyModule class
|
||||||
if (Addon::isEnabled($moduleName) && file_exists("addon/{$moduleName}/{$moduleName}.php")) {
|
if ($this->addonHelper->isAddonEnabled($moduleName) && file_exists("addon/{$moduleName}/{$moduleName}.php")) {
|
||||||
//Check if module is an app and if public access to apps is allowed or not
|
//Check if module is an app and if public access to apps is allowed or not
|
||||||
$privateapps = $this->config->get('config', 'private_addons', false);
|
$privateapps = $this->config->get('config', 'private_addons', false);
|
||||||
if (!$this->isLocalUser && Hook::isAddonApp($moduleName) && $privateapps) {
|
if (!$this->isLocalUser && Hook::isAddonApp($moduleName) && $privateapps) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Friendica\Console;
|
||||||
use Console_Table;
|
use Console_Table;
|
||||||
use Friendica\App\Mode;
|
use Friendica\App\Mode;
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\Addon as AddonCore;
|
use Friendica\Core\Addon\AddonHelper;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
@ -34,6 +34,7 @@ class Addon extends \Asika\SimpleConsole\Console
|
||||||
* @var Database
|
* @var Database
|
||||||
*/
|
*/
|
||||||
private $dba;
|
private $dba;
|
||||||
|
private AddonHelper $addonHelper;
|
||||||
|
|
||||||
protected function getHelp()
|
protected function getHelp()
|
||||||
{
|
{
|
||||||
|
@ -56,15 +57,16 @@ HELP;
|
||||||
return $help;
|
return $help;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct(Mode $appMode, L10n $l10n, Database $dba, array $argv = null)
|
public function __construct(Mode $appMode, L10n $l10n, Database $dba, AddonHelper $addonHelper, array $argv = null)
|
||||||
{
|
{
|
||||||
parent::__construct($argv);
|
parent::__construct($argv);
|
||||||
|
|
||||||
$this->appMode = $appMode;
|
$this->appMode = $appMode;
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
$this->dba = $dba;
|
$this->dba = $dba;
|
||||||
|
$this->addonHelper = $addonHelper;
|
||||||
|
|
||||||
AddonCore::loadAddons();
|
$this->addonHelper->loadAddons();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doExecute(): int
|
protected function doExecute(): int
|
||||||
|
@ -122,23 +124,22 @@ HELP;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (AddonCore::getAvailableList() as $addon) {
|
foreach ($this->addonHelper->getAvailableAddons() as $addonId) {
|
||||||
$addon_name = $addon[0];
|
$enabled = $this->addonHelper->isAddonEnabled($addonId);
|
||||||
$enabled = AddonCore::isEnabled($addon_name);
|
|
||||||
|
|
||||||
if ($subCmd === 'all') {
|
if ($subCmd === 'all') {
|
||||||
$table->addRow([$addon_name, $enabled ? 'enabled' : 'disabled']);
|
$table->addRow([$addonId, $enabled ? 'enabled' : 'disabled']);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($subCmd === 'enabled' && $enabled === true) {
|
if ($subCmd === 'enabled' && $enabled === true) {
|
||||||
$table->addRow([$addon_name]);
|
$table->addRow([$addonId]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($subCmd === 'disabled' && $enabled === false) {
|
if ($subCmd === 'disabled' && $enabled === false) {
|
||||||
$table->addRow([$addon_name]);
|
$table->addRow([$addonId]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,11 +164,11 @@ HELP;
|
||||||
throw new RuntimeException($this->l10n->t('Addon not found'));
|
throw new RuntimeException($this->l10n->t('Addon not found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AddonCore::isEnabled($addon)) {
|
if ($this->addonHelper->isAddonEnabled($addon)) {
|
||||||
throw new RuntimeException($this->l10n->t('Addon already enabled'));
|
throw new RuntimeException($this->l10n->t('Addon already enabled'));
|
||||||
}
|
}
|
||||||
|
|
||||||
AddonCore::install($addon);
|
$this->addonHelper->installAddon($addon);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -187,11 +188,11 @@ HELP;
|
||||||
throw new RuntimeException($this->l10n->t('Addon not found'));
|
throw new RuntimeException($this->l10n->t('Addon not found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AddonCore::isEnabled($addon)) {
|
if (!$this->addonHelper->isAddonEnabled($addon)) {
|
||||||
throw new RuntimeException($this->l10n->t('Addon already disabled'));
|
throw new RuntimeException($this->l10n->t('Addon already disabled'));
|
||||||
}
|
}
|
||||||
|
|
||||||
AddonCore::uninstall($addon);
|
$this->addonHelper->uninstallAddon($addon);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Friendica\Console;
|
||||||
|
|
||||||
use Asika\SimpleConsole\Console;
|
use Asika\SimpleConsole\Console;
|
||||||
use Friendica\App\Mode;
|
use Friendica\App\Mode;
|
||||||
use Friendica\Core\Addon;
|
use Friendica\Core\Addon\AddonHelper;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
|
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
|
||||||
|
@ -29,6 +29,7 @@ final class JetstreamDaemon extends Console
|
||||||
private IManageKeyValuePairs $keyValue;
|
private IManageKeyValuePairs $keyValue;
|
||||||
private SysDaemon $daemon;
|
private SysDaemon $daemon;
|
||||||
private Jetstream $jetstream;
|
private Jetstream $jetstream;
|
||||||
|
private AddonHelper $addonHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Mode $mode
|
* @param Mode $mode
|
||||||
|
@ -38,15 +39,16 @@ final class JetstreamDaemon extends Console
|
||||||
* @param Jetstream $jetstream
|
* @param Jetstream $jetstream
|
||||||
* @param array|null $argv
|
* @param array|null $argv
|
||||||
*/
|
*/
|
||||||
public function __construct(Mode $mode, IManageConfigValues $config, IManageKeyValuePairs $keyValue, SysDaemon $daemon, Jetstream $jetstream, array $argv = null)
|
public function __construct(Mode $mode, IManageConfigValues $config, IManageKeyValuePairs $keyValue, SysDaemon $daemon, Jetstream $jetstream, AddonHelper $addonHelper, array $argv = null)
|
||||||
{
|
{
|
||||||
parent::__construct($argv);
|
parent::__construct($argv);
|
||||||
|
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->keyValue = $keyValue;
|
$this->keyValue = $keyValue;
|
||||||
$this->jetstream = $jetstream;
|
$this->jetstream = $jetstream;
|
||||||
$this->daemon = $daemon;
|
$this->daemon = $daemon;
|
||||||
|
$this->addonHelper = $addonHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getHelp(): string
|
protected function getHelp(): string
|
||||||
|
@ -95,10 +97,10 @@ HELP;
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Addon::loadAddons();
|
$this->addonHelper->loadAddons();
|
||||||
Hook::loadHooks();
|
Hook::loadHooks();
|
||||||
|
|
||||||
if (!Addon::isEnabled('bluesky')) {
|
if (!$this->addonHelper->isAddonEnabled('bluesky')) {
|
||||||
throw new RuntimeException("Bluesky has to be enabled.\n");
|
throw new RuntimeException("Bluesky has to be enabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,17 +42,17 @@ console storage - manage storage backend and stored data
|
||||||
Synopsis
|
Synopsis
|
||||||
bin/console storage [-h|--help|-?] [-v]
|
bin/console storage [-h|--help|-?] [-v]
|
||||||
Show this help
|
Show this help
|
||||||
|
|
||||||
bin/console storage list
|
bin/console storage list
|
||||||
List available storage backends
|
List available storage backends
|
||||||
|
|
||||||
bin/console storage clear
|
bin/console storage clear
|
||||||
Remove the contact avatar cache data
|
Remove the contact avatar cache data
|
||||||
|
|
||||||
bin/console storage set <name>
|
bin/console storage set <name>
|
||||||
Set current storage backend
|
Set current storage backend
|
||||||
name storage backend to use. see "list".
|
name storage backend to use. see "list".
|
||||||
|
|
||||||
bin/console storage move [table] [-n 5000]
|
bin/console storage move [table] [-n 5000]
|
||||||
Move stored data to current storage backend.
|
Move stored data to current storage backend.
|
||||||
table one of "photo" or "attach". default to both
|
table one of "photo" or "attach". default to both
|
||||||
|
@ -96,7 +96,7 @@ HELP;
|
||||||
|
|
||||||
protected function doList()
|
protected function doList()
|
||||||
{
|
{
|
||||||
$rowfmt = ' %-3s | %-20s';
|
$rowfmt = ' %-3s | %-20s';
|
||||||
$current = $this->storageManager->getBackend();
|
$current = $this->storageManager->getBackend();
|
||||||
$this->out(sprintf($rowfmt, 'Sel', 'Name'));
|
$this->out(sprintf($rowfmt, 'Sel', 'Name'));
|
||||||
$this->out('-----------------------');
|
$this->out('-----------------------');
|
||||||
|
@ -104,7 +104,7 @@ HELP;
|
||||||
foreach ($this->storageManager->listBackends() as $name) {
|
foreach ($this->storageManager->listBackends() as $name) {
|
||||||
$issel = ' ';
|
$issel = ' ';
|
||||||
if ($current && $current::getName() == $name) {
|
if ($current && $current::getName() == $name) {
|
||||||
$issel = '*';
|
$issel = '*';
|
||||||
$isregisterd = true;
|
$isregisterd = true;
|
||||||
};
|
};
|
||||||
$this->out(sprintf($rowfmt, $issel, $name));
|
$this->out(sprintf($rowfmt, $issel, $name));
|
||||||
|
@ -176,7 +176,7 @@ HELP;
|
||||||
}
|
}
|
||||||
|
|
||||||
$current = $this->storageManager->getBackend();
|
$current = $this->storageManager->getBackend();
|
||||||
$total = 0;
|
$total = 0;
|
||||||
|
|
||||||
if (is_null($current)) {
|
if (is_null($current)) {
|
||||||
throw new StorageException(sprintf("Cannot move to legacy storage. Please select a storage backend."));
|
throw new StorageException(sprintf("Cannot move to legacy storage. Please select a storage backend."));
|
||||||
|
@ -192,5 +192,7 @@ HELP;
|
||||||
} while ($moved);
|
} while ($moved);
|
||||||
|
|
||||||
$this->out(sprintf(date('[Y-m-d H:i:s] ') . 'Moved %d files total', $total));
|
$this->out(sprintf(date('[Y-m-d H:i:s] ') . 'Moved %d files total', $total));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,7 @@ class Conversation
|
||||||
|
|
||||||
if ($total === 0) {
|
if ($total === 0) {
|
||||||
throw new InternalServerErrorException(sprintf('There has to be at least one Liker for verb "%s"', $verb));
|
throw new InternalServerErrorException(sprintf('There has to be at least one Liker for verb "%s"', $verb));
|
||||||
} else if ($total === 1) {
|
} elseif ($total === 1) {
|
||||||
$likerString = $likers[0];
|
$likerString = $likers[0];
|
||||||
} else {
|
} else {
|
||||||
if ($total < $this->config->get('system', 'max_likers')) {
|
if ($total < $this->config->get('system', 'max_likers')) {
|
||||||
|
@ -326,7 +326,7 @@ class Conversation
|
||||||
'$ispublic' => $this->l10n->t('Visible to <strong>everybody</strong>'),
|
'$ispublic' => $this->l10n->t('Visible to <strong>everybody</strong>'),
|
||||||
'$linkurl' => $this->l10n->t('Please enter a image/video/audio/webpage URL:'),
|
'$linkurl' => $this->l10n->t('Please enter a image/video/audio/webpage URL:'),
|
||||||
'$term' => $this->l10n->t('Tag term:'),
|
'$term' => $this->l10n->t('Tag term:'),
|
||||||
'$fileas' => $this->l10n->t('Save to Folder:'),
|
'$fileas' => $this->l10n->t('Save to Folder'),
|
||||||
'$whereareu' => $this->l10n->t('Where are you right now?'),
|
'$whereareu' => $this->l10n->t('Where are you right now?'),
|
||||||
'$delitems' => $this->l10n->t("Delete item\x28s\x29?"),
|
'$delitems' => $this->l10n->t("Delete item\x28s\x29?"),
|
||||||
'$is_mobile' => $this->mode->isMobile(),
|
'$is_mobile' => $this->mode->isMobile(),
|
||||||
|
@ -976,8 +976,8 @@ class Conversation
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($items as $key => $row) {
|
foreach ($items as $key => $row) {
|
||||||
$items[$key]['emojis'] = $emojis[$key] ?? [];
|
$items[$key]['emojis'] = $emojis[$key] ?? [];
|
||||||
$items[$key]['counts'] = $counts[$key] ?? 0;
|
$items[$key]['counts'] = $counts[$key] ?? 0;
|
||||||
$items[$key]['quoteshares'] = $quoteshares[$key] ?? [];
|
$items[$key]['quoteshares'] = $quoteshares[$key] ?? [];
|
||||||
|
|
||||||
$always_display = in_array($mode, [self::MODE_CONTACTS, self::MODE_CONTACT_POSTS]);
|
$always_display = in_array($mode, [self::MODE_CONTACTS, self::MODE_CONTACT_POSTS]);
|
||||||
|
@ -1431,7 +1431,7 @@ class Conversation
|
||||||
public function getContextLessThreadList(array $items, string $mode, bool $preview, bool $pagedrop, string $formSecurityToken): array
|
public function getContextLessThreadList(array $items, string $mode, bool $preview, bool $pagedrop, string $formSecurityToken): array
|
||||||
{
|
{
|
||||||
$threads = [];
|
$threads = [];
|
||||||
$uriids = [];
|
$uriids = [];
|
||||||
|
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
if (in_array($item['uri-id'], $uriids)) {
|
if (in_array($item['uri-id'], $uriids)) {
|
||||||
|
@ -1456,7 +1456,7 @@ class Conversation
|
||||||
|
|
||||||
$tags = Tag::populateFromItem($item);
|
$tags = Tag::populateFromItem($item);
|
||||||
|
|
||||||
$author = [
|
$author = [
|
||||||
'uid' => 0,
|
'uid' => 0,
|
||||||
'id' => $item['author-id'],
|
'id' => $item['author-id'],
|
||||||
'network' => $item['author-network'],
|
'network' => $item['author-network'],
|
||||||
|
@ -1501,7 +1501,7 @@ class Conversation
|
||||||
|
|
||||||
$body_html = ItemModel::prepareBody($item, true, $preview);
|
$body_html = ItemModel::prepareBody($item, true, $preview);
|
||||||
|
|
||||||
[$categories, $folders] = $this->item->determineCategoriesTerms($item, $this->session->getLocalUserId());
|
list($categories, $folders) = $this->item->determineCategoriesTerms($item, $this->session->getLocalUserId());
|
||||||
|
|
||||||
if (!empty($item['featured'])) {
|
if (!empty($item['featured'])) {
|
||||||
$pinned = $this->l10n->t('Pinned item');
|
$pinned = $this->l10n->t('Pinned item');
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
namespace Friendica\Content;
|
namespace Friendica\Content;
|
||||||
|
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
|
|
||||||
class Feature
|
class Feature
|
||||||
{
|
{
|
||||||
|
@ -41,15 +41,23 @@ class Feature
|
||||||
*/
|
*/
|
||||||
public static function isEnabled(int $uid, $feature): bool
|
public static function isEnabled(int $uid, $feature): bool
|
||||||
{
|
{
|
||||||
if (!DI::config()->get('feature_lock', $feature, false)) {
|
$config = DI::config();
|
||||||
$enabled = DI::config()->get('feature', $feature) ?? self::getDefault($feature);
|
$pConfig = DI::pConfig();
|
||||||
$enabled = DI::pConfig()->get($uid, 'feature', $feature) ?? $enabled;
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
if (!$config->get('feature_lock', $feature, false)) {
|
||||||
|
$enabled = $config->get('feature', $feature) ?? self::getDefault($feature);
|
||||||
|
$enabled = $pConfig->get($uid, 'feature', $feature) ?? $enabled;
|
||||||
} else {
|
} else {
|
||||||
$enabled = true;
|
$enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr = ['uid' => $uid, 'feature' => $feature, 'enabled' => $enabled];
|
$arr = ['uid' => $uid, 'feature' => $feature, 'enabled' => $enabled];
|
||||||
Hook::callAll('isEnabled', $arr);
|
|
||||||
|
$arr = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::FEATURE_ENABLED, $arr)
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return (bool)$arr['enabled'];
|
return (bool)$arr['enabled'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,55 +94,58 @@ class Feature
|
||||||
*/
|
*/
|
||||||
public static function get($filtered = true)
|
public static function get($filtered = true)
|
||||||
{
|
{
|
||||||
$arr = [
|
$l10n = DI::l10n();
|
||||||
|
$config = DI::config();
|
||||||
|
$eventDispatcher = DI::eventDispatcher();
|
||||||
|
|
||||||
|
$arr = [
|
||||||
// General
|
// General
|
||||||
'general' => [
|
'general' => [
|
||||||
DI::l10n()->t('General Features'),
|
$l10n->t('General Features'),
|
||||||
//array('expire', DI::l10n()->t('Content Expiration'), DI::l10n()->t('Remove old posts/comments after a period of time')),
|
//array('expire', $l10n->t('Content Expiration'), $l10n->t('Remove old posts/comments after a period of time')),
|
||||||
[self::PHOTO_LOCATION, DI::l10n()->t('Photo Location'), DI::l10n()->t("Photo metadata is normally stripped. This extracts the location \x28if present\x29 prior to stripping metadata and links it to a map."), false, DI::config()->get('feature_lock', self::PHOTO_LOCATION, false)],
|
[self::PHOTO_LOCATION, $l10n->t('Photo Location'), $l10n->t("Photo metadata is normally stripped. This extracts the location \x28if present\x29 prior to stripping metadata and links it to a map."), false, $config->get('feature_lock', self::PHOTO_LOCATION, false)],
|
||||||
[self::COMMUNITY, DI::l10n()->t('Display the community in the navigation'), DI::l10n()->t('If enabled, the community can be accessed via the navigation menu. Independent from this setting, the community timelines can always be accessed via the channels.'), true, DI::config()->get('feature_lock', self::COMMUNITY, false)],
|
[self::COMMUNITY, $l10n->t('Display the community in the navigation'), $l10n->t('If enabled, the community can be accessed via the navigation menu. Independent from this setting, the community timelines can always be accessed via the channels.'), true, $config->get('feature_lock', self::COMMUNITY, false)],
|
||||||
],
|
],
|
||||||
|
|
||||||
// Post composition
|
// Post composition
|
||||||
'composition' => [
|
'composition' => [
|
||||||
DI::l10n()->t('Post Composition Features'),
|
$l10n->t('Post Composition Features'),
|
||||||
[self::EXPLICIT_MENTIONS, DI::l10n()->t('Explicit Mentions'), DI::l10n()->t('Add explicit mentions to comment box for manual control over who gets mentioned in replies.'), false, DI::config()->get('feature_lock', Feature::EXPLICIT_MENTIONS, false)],
|
[self::EXPLICIT_MENTIONS, $l10n->t('Explicit Mentions'), $l10n->t('Add explicit mentions to comment box for manual control over who gets mentioned in replies.'), false, $config->get('feature_lock', Feature::EXPLICIT_MENTIONS, false)],
|
||||||
[self::ADD_ABSTRACT, DI::l10n()->t('Add an abstract from ActivityPub content warnings'), DI::l10n()->t('Add an abstract when commenting on ActivityPub posts with a content warning. Abstracts are displayed as content warning on systems like Mastodon or Pleroma.'), false, DI::config()->get('feature_lock', self::ADD_ABSTRACT, false)],
|
[self::ADD_ABSTRACT, $l10n->t('Add an abstract from ActivityPub content warnings'), $l10n->t('Add an abstract when commenting on ActivityPub posts with a content warning. Abstracts are displayed as content warning on systems like Mastodon or Pleroma.'), false, $config->get('feature_lock', self::ADD_ABSTRACT, false)],
|
||||||
],
|
],
|
||||||
|
|
||||||
// Item tools
|
// Item tools
|
||||||
'tools' => [
|
'tools' => [
|
||||||
DI::l10n()->t('Post/Comment Tools'),
|
$l10n->t('Post/Comment Tools'),
|
||||||
[self::CATEGORIES, DI::l10n()->t('Post Categories'), DI::l10n()->t('Add categories to your posts'), false, DI::config()->get('feature_lock', self::CATEGORIES, false)],
|
[self::CATEGORIES, $l10n->t('Post Categories'), $l10n->t('Add categories to your posts'), false, $config->get('feature_lock', self::CATEGORIES, false)],
|
||||||
],
|
],
|
||||||
|
|
||||||
// Widget visibility on the network stream
|
// Widget visibility on the network stream
|
||||||
'network' => [
|
'network' => [
|
||||||
DI::l10n()->t('Network Widgets'),
|
$l10n->t('Network Widgets'),
|
||||||
[self::CIRCLES, DI::l10n()->t('Circles'), DI::l10n()->t('Display posts that have been created by accounts of the selected circle.'), true, DI::config()->get('feature_lock', self::CIRCLES, false)],
|
[self::CIRCLES, $l10n->t('Circles'), $l10n->t('Display posts that have been created by accounts of the selected circle.'), true, $config->get('feature_lock', self::CIRCLES, false)],
|
||||||
[self::GROUPS, DI::l10n()->t('Groups'), DI::l10n()->t('Display posts that have been distributed by the selected group.'), true, DI::config()->get('feature_lock', self::GROUPS, false)],
|
[self::GROUPS, $l10n->t('Groups'), $l10n->t('Display posts that have been distributed by the selected group.'), true, $config->get('feature_lock', self::GROUPS, false)],
|
||||||
[self::ARCHIVE, DI::l10n()->t('Archives'), DI::l10n()->t('Display an archive where posts can be selected by month and year.'), true, DI::config()->get('feature_lock', self::ARCHIVE, false)],
|
[self::ARCHIVE, $l10n->t('Archives'), $l10n->t('Display an archive where posts can be selected by month and year.'), true, $config->get('feature_lock', self::ARCHIVE, false)],
|
||||||
[self::NETWORKS, DI::l10n()->t('Protocols'), DI::l10n()->t('Display posts with the selected protocols.'), true, DI::config()->get('feature_lock', self::NETWORKS, false)],
|
[self::NETWORKS, $l10n->t('Protocols'), $l10n->t('Display posts with the selected protocols.'), true, $config->get('feature_lock', self::NETWORKS, false)],
|
||||||
[self::ACCOUNTS, DI::l10n()->t('Account Types'), DI::l10n()->t('Display posts done by accounts with the selected account type.'), true, DI::config()->get('feature_lock', self::ACCOUNTS, false)],
|
[self::ACCOUNTS, $l10n->t('Account Types'), $l10n->t('Display posts done by accounts with the selected account type.'), true, $config->get('feature_lock', self::ACCOUNTS, false)],
|
||||||
[self::CHANNELS, DI::l10n()->t('Channels'), DI::l10n()->t('Display posts in the system channels and user defined channels.'), true, DI::config()->get('feature_lock', self::CHANNELS, false)],
|
[self::CHANNELS, $l10n->t('Channels'), $l10n->t('Display posts in the system channels and user defined channels.'), true, $config->get('feature_lock', self::CHANNELS, false)],
|
||||||
[self::SEARCHES, DI::l10n()->t('Saved Searches'), DI::l10n()->t('Display posts that contain subscribed hashtags.'), true, DI::config()->get('feature_lock', self::SEARCHES, false)],
|
[self::SEARCHES, $l10n->t('Saved Searches'), $l10n->t('Display posts that contain subscribed hashtags.'), true, $config->get('feature_lock', self::SEARCHES, false)],
|
||||||
[self::FOLDERS, DI::l10n()->t('Saved Folders'), DI::l10n()->t('Display a list of folders in which posts are stored.'), true, DI::config()->get('feature_lock', self::FOLDERS, false)],
|
[self::FOLDERS, $l10n->t('Saved Folders'), $l10n->t('Display a list of folders in which posts are stored.'), true, $config->get('feature_lock', self::FOLDERS, false)],
|
||||||
[self::NOSHARER, DI::l10n()->t('Own Contacts'), DI::l10n()->t('Include or exclude posts from subscribed accounts. This widget is not visible on all channels.'), true, DI::config()->get('feature_lock', self::NOSHARER, false)],
|
[self::NOSHARER, $l10n->t('Own Contacts'), $l10n->t('Include or exclude posts from subscribed accounts. This widget is not visible on all channels.'), true, $config->get('feature_lock', self::NOSHARER, false)],
|
||||||
[self::TRENDING_TAGS, DI::l10n()->t('Trending Tags'), DI::l10n()->t('Display a list of the most popular tags in recent public posts.'), false, DI::config()->get('feature_lock', self::TRENDING_TAGS, false)],
|
[self::TRENDING_TAGS, $l10n->t('Trending Tags'), $l10n->t('Display a list of the most popular tags in recent public posts.'), false, $config->get('feature_lock', self::TRENDING_TAGS, false)],
|
||||||
],
|
],
|
||||||
|
|
||||||
// Advanced Profile Settings
|
// Advanced Profile Settings
|
||||||
'advanced_profile' => [
|
'advanced_profile' => [
|
||||||
DI::l10n()->t('Advanced Profile Settings'),
|
$l10n->t('Advanced Profile Settings'),
|
||||||
[self::TAGCLOUD, DI::l10n()->t('Tag Cloud'), DI::l10n()->t('Provide a personal tag cloud on your profile page'), false, DI::config()->get('feature_lock', self::TAGCLOUD, false)],
|
[self::TAGCLOUD, $l10n->t('Tag Cloud'), $l10n->t('Provide a personal tag cloud on your profile page'), false, $config->get('feature_lock', self::TAGCLOUD, false)],
|
||||||
[self::MEMBER_SINCE, DI::l10n()->t('Display Membership Date'), DI::l10n()->t('Display membership date in profile'), false, DI::config()->get('feature_lock', self::MEMBER_SINCE, false)],
|
[self::MEMBER_SINCE, $l10n->t('Display Membership Date'), $l10n->t('Display membership date in profile'), false, $config->get('feature_lock', self::MEMBER_SINCE, false)],
|
||||||
],
|
],
|
||||||
|
|
||||||
//Advanced Calendar Settings
|
//Advanced Calendar Settings
|
||||||
'advanced_calendar' => [
|
'advanced_calendar' => [
|
||||||
DI::l10n()->t('Advanced Calendar Settings'),
|
$l10n->t('Advanced Calendar Settings'),
|
||||||
[self::PUBLIC_CALENDAR, DI::l10n()->t('Allow anonymous access to your calendar'), DI::l10n()->t('Allows anonymous visitors to consult your calendar and your public events. Contact birthday events are private to you.'), false, DI::config()->get('feature_lock', self::PUBLIC_CALENDAR, false)],
|
[self::PUBLIC_CALENDAR, $l10n->t('Allow anonymous access to your calendar'), $l10n->t('Allows anonymous visitors to consult your calendar and your public events. Contact birthday events are private to you.'), false, $config->get('feature_lock', self::PUBLIC_CALENDAR, false)],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -144,7 +155,7 @@ class Feature
|
||||||
foreach ($arr as $k => $x) {
|
foreach ($arr as $k => $x) {
|
||||||
$has_items = false;
|
$has_items = false;
|
||||||
$kquantity = count($arr[$k]);
|
$kquantity = count($arr[$k]);
|
||||||
for ($y = 0; $y < $kquantity; $y ++) {
|
for ($y = 0; $y < $kquantity; $y++) {
|
||||||
if (is_array($arr[$k][$y])) {
|
if (is_array($arr[$k][$y])) {
|
||||||
if ($arr[$k][$y][4] === false) {
|
if ($arr[$k][$y][4] === false) {
|
||||||
$has_items = true;
|
$has_items = true;
|
||||||
|
@ -159,7 +170,10 @@ class Feature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook::callAll('get', $arr);
|
$arr = $eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::FEATURE_GET, $arr)
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,8 +108,6 @@ class GroupManager
|
||||||
|
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
$contacts = [];
|
|
||||||
|
|
||||||
foreach ($contacts as $contact) {
|
foreach ($contacts as $contact) {
|
||||||
$entry = [
|
$entry = [
|
||||||
'url' => 'contact/' . $contact['id'] . '/conversations',
|
'url' => 'contact/' . $contact['id'] . '/conversations',
|
||||||
|
|
|
@ -607,7 +607,7 @@ class Item
|
||||||
} else {
|
} else {
|
||||||
$owner_avatar = $item['owner-id'];
|
$owner_avatar = $item['owner-id'];
|
||||||
$owner_updated = $item['owner-updated'];
|
$owner_updated = $item['owner-updated'];
|
||||||
$owner_thumb = $item['owner-avatar'];
|
$owner_thumb = $item['owner-avatar'] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($owner_thumb) || Photo::isPhotoURI($owner_thumb)) {
|
if (empty($owner_thumb) || Photo::isPhotoURI($owner_thumb)) {
|
||||||
|
|
|
@ -10,11 +10,12 @@ namespace Friendica\Content;
|
||||||
use Friendica\App\BaseURL;
|
use Friendica\App\BaseURL;
|
||||||
use Friendica\App\Router;
|
use Friendica\App\Router;
|
||||||
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\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\Event\ArrayFilterEvent;
|
||||||
|
use Friendica\Event\HtmlFilterEvent;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
use Friendica\Model\User;
|
use Friendica\Model\User;
|
||||||
use Friendica\Module\Conversation\Community;
|
use Friendica\Module\Conversation\Community;
|
||||||
|
@ -22,6 +23,7 @@ use Friendica\Module\Home;
|
||||||
use Friendica\Module\Security\Login;
|
use Friendica\Module\Security\Login;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Security\OpenWebAuth;
|
use Friendica\Security\OpenWebAuth;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
|
|
||||||
class Nav
|
class Nav
|
||||||
{
|
{
|
||||||
|
@ -63,14 +65,17 @@ class Nav
|
||||||
/** @var Router */
|
/** @var Router */
|
||||||
private $router;
|
private $router;
|
||||||
|
|
||||||
public function __construct(BaseURL $baseUrl, L10n $l10n, IHandleUserSessions $session, Database $database, IManageConfigValues $config, Router $router)
|
private EventDispatcherInterface $eventDispatcher;
|
||||||
|
|
||||||
|
public function __construct(BaseURL $baseUrl, L10n $l10n, IHandleUserSessions $session, Database $database, IManageConfigValues $config, Router $router, EventDispatcherInterface $eventDispatcher)
|
||||||
{
|
{
|
||||||
$this->baseUrl = $baseUrl;
|
$this->baseUrl = $baseUrl;
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
$this->database = $database;
|
$this->database = $database;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,19 +106,22 @@ class Nav
|
||||||
$tpl = Renderer::getMarkupTemplate('nav.tpl');
|
$tpl = Renderer::getMarkupTemplate('nav.tpl');
|
||||||
|
|
||||||
$nav .= Renderer::replaceMacros($tpl, [
|
$nav .= Renderer::replaceMacros($tpl, [
|
||||||
'$sitelocation' => $nav_info['sitelocation'],
|
'$sitelocation' => $nav_info['sitelocation'],
|
||||||
'$nav' => $nav_info['nav'],
|
'$nav' => $nav_info['nav'],
|
||||||
'$banner' => $nav_info['banner'],
|
'$banner' => $nav_info['banner'],
|
||||||
'$emptynotifications' => $this->l10n->t('Nothing new here'),
|
'$emptynotifications' => $this->l10n->t('Nothing new here'),
|
||||||
'$userinfo' => $nav_info['userinfo'],
|
'$userinfo' => $nav_info['userinfo'],
|
||||||
'$sel' => self::$selected,
|
'$sel' => self::$selected,
|
||||||
'$apps' => $this->getAppMenu(),
|
'$apps' => $this->getAppMenu(),
|
||||||
'$home' => $this->l10n->t('Go back'),
|
'$home' => $this->l10n->t('Home'),
|
||||||
'$clear_notifs' => $this->l10n->t('Clear notifications'),
|
'$skip' => $this->l10n->t('Skip to main content'),
|
||||||
'$search_hint' => $this->l10n->t('@name, !group, #tags, content')
|
'$clear_notifs' => $this->l10n->t('Clear notifications'),
|
||||||
|
'$search_hint' => $this->l10n->t('@name, !group, #tags, content')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Hook::callAll('page_header', $nav);
|
$nav = $this->eventDispatcher->dispatch(
|
||||||
|
new HtmlFilterEvent(HtmlFilterEvent::PAGE_HEADER, $nav)
|
||||||
|
)->getHtml();
|
||||||
|
|
||||||
return $nav;
|
return $nav;
|
||||||
}
|
}
|
||||||
|
@ -150,9 +158,11 @@ class Nav
|
||||||
) {
|
) {
|
||||||
$arr = ['app_menu' => $appMenu];
|
$arr = ['app_menu' => $appMenu];
|
||||||
|
|
||||||
Hook::callAll('app_menu', $arr);
|
$arr = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::APP_MENU, $arr)
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
$appMenu = $arr['app_menu'];
|
$appMenu = $arr['app_menu'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $appMenu;
|
return $appMenu;
|
||||||
|
@ -220,7 +230,7 @@ class Nav
|
||||||
$nav['usermenu'][] = ['notes/', $this->l10n->t('Personal notes'), '', $this->l10n->t('Your personal notes')];
|
$nav['usermenu'][] = ['notes/', $this->l10n->t('Personal notes'), '', $this->l10n->t('Your personal notes')];
|
||||||
|
|
||||||
// user info
|
// user info
|
||||||
$contact = $this->database->selectFirst('contact', ['id', 'url', 'avatar', 'micro', 'name', 'nick', 'baseurl', 'updated'], ['uid' => $this->session->getLocalUserId(), 'self' => true]);
|
$contact = $this->database->selectFirst('contact', ['id', 'url', 'avatar', 'micro', 'name', 'nick', 'baseurl', 'updated'], ['uid' => $this->session->getLocalUserId(), 'self' => true]);
|
||||||
$userinfo = [
|
$userinfo = [
|
||||||
'icon' => Contact::getMicro($contact),
|
'icon' => Contact::getMicro($contact),
|
||||||
'name' => $contact['name'],
|
'name' => $contact['name'],
|
||||||
|
@ -295,16 +305,16 @@ class Nav
|
||||||
|
|
||||||
// Don't show notifications for public communities
|
// Don't show notifications for public communities
|
||||||
if ($this->session->get('page_flags', '') != User::PAGE_FLAGS_COMMUNITY) {
|
if ($this->session->get('page_flags', '') != User::PAGE_FLAGS_COMMUNITY) {
|
||||||
$nav['introductions'] = ['notifications/intros', $this->l10n->t('Introductions'), '', $this->l10n->t('Friend Requests')];
|
$nav['introductions'] = ['notifications/intros', $this->l10n->t('Introductions'), '', $this->l10n->t('Friend Requests')];
|
||||||
$nav['notifications'] = ['notifications', $this->l10n->t('Notifications'), '', $this->l10n->t('Notifications')];
|
$nav['notifications'] = ['notifications', $this->l10n->t('Notifications'), '', $this->l10n->t('Notifications')];
|
||||||
$nav['notifications']['all'] = ['notifications/system', $this->l10n->t('See all notifications'), '', ''];
|
$nav['notifications']['all'] = ['notifications/system', $this->l10n->t('See all notifications'), '', ''];
|
||||||
$nav['notifications']['mark'] = ['', $this->l10n->t('Mark as seen'), '', $this->l10n->t('Mark all system notifications as seen')];
|
$nav['notifications']['mark'] = ['', $this->l10n->t('Mark as seen'), '', $this->l10n->t('Mark all system notifications as seen')];
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav['messages'] = ['message', $this->l10n->t('Messages'), '', $this->l10n->t('Private mail')];
|
$nav['messages'] = ['message', $this->l10n->t('Messages'), '', $this->l10n->t('Private mail')];
|
||||||
$nav['messages']['inbox'] = ['message', $this->l10n->t('Inbox'), '', $this->l10n->t('Inbox')];
|
$nav['messages']['inbox'] = ['message', $this->l10n->t('Inbox'), '', $this->l10n->t('Inbox')];
|
||||||
$nav['messages']['outbox'] = ['message/sent', $this->l10n->t('Outbox'), '', $this->l10n->t('Outbox')];
|
$nav['messages']['outbox'] = ['message/sent', $this->l10n->t('Outbox'), '', $this->l10n->t('Outbox')];
|
||||||
$nav['messages']['new'] = ['message/new', $this->l10n->t('New Message'), '', $this->l10n->t('New Message')];
|
$nav['messages']['new'] = ['message/new', $this->l10n->t('New Message'), '', $this->l10n->t('New Message')];
|
||||||
|
|
||||||
if (User::hasIdentities($this->session->getSubManagedUserId() ?: $this->session->getLocalUserId())) {
|
if (User::hasIdentities($this->session->getSubManagedUserId() ?: $this->session->getLocalUserId())) {
|
||||||
$nav['delegation'] = ['delegation', $this->l10n->t('Accounts'), '', $this->l10n->t('Manage other pages')];
|
$nav['delegation'] = ['delegation', $this->l10n->t('Accounts'), '', $this->l10n->t('Manage other pages')];
|
||||||
|
@ -336,7 +346,9 @@ class Nav
|
||||||
'userinfo' => $userinfo,
|
'userinfo' => $userinfo,
|
||||||
];
|
];
|
||||||
|
|
||||||
Hook::callAll('nav_info', $nav_info);
|
$nav_info = $this->eventDispatcher->dispatch(
|
||||||
|
new ArrayFilterEvent(ArrayFilterEvent::NAV_INFO, $nav_info)
|
||||||
|
)->getArray();
|
||||||
|
|
||||||
return $nav_info;
|
return $nav_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1583,7 +1583,7 @@ class BBCode
|
||||||
// Check for headers
|
// Check for headers
|
||||||
|
|
||||||
if ($simple_html == self::INTERNAL) {
|
if ($simple_html == self::INTERNAL) {
|
||||||
//Ensure to always start with <h4> if possible
|
//Ensure to always start with <h3> if possible
|
||||||
$heading_count = 0;
|
$heading_count = 0;
|
||||||
for ($level = 6; $level > 0; $level--) {
|
for ($level = 6; $level > 0; $level--) {
|
||||||
if (preg_match("(\[h$level\].*?\[\/h$level\])ism", $text)) {
|
if (preg_match("(\[h$level\].*?\[\/h$level\])ism", $text)) {
|
||||||
|
@ -1591,7 +1591,7 @@ class BBCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($heading_count > 0) {
|
if ($heading_count > 0) {
|
||||||
$heading = min($heading_count + 3, 6);
|
$heading = min($heading_count + 2, 6);
|
||||||
for ($level = 6; $level > 0; $level--) {
|
for ($level = 6; $level > 0; $level--) {
|
||||||
if (preg_match("(\[h$level\].*?\[\/h$level\])ism", $text)) {
|
if (preg_match("(\[h$level\].*?\[\/h$level\])ism", $text)) {
|
||||||
$text = preg_replace("(\[h$level\](.*?)\[\/h$level\])ism", "</p><h$heading>$1</h$heading><p>", $text);
|
$text = preg_replace("(\[h$level\](.*?)\[\/h$level\])ism", "</p><h$heading>$1</h$heading><p>", $text);
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Friendica\Content;
|
namespace Friendica\Content;
|
||||||
|
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Cache\Enum\Duration;
|
use Friendica\Core\Cache\Enum\Duration;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
|
@ -33,13 +32,13 @@ class Widget
|
||||||
*/
|
*/
|
||||||
public static function follow(string $value = ''): string
|
public static function follow(string $value = ''): string
|
||||||
{
|
{
|
||||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), array(
|
return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), [
|
||||||
'$connect' => DI::l10n()->t('Add New Contact'),
|
'$connect' => DI::l10n()->t('Add New Contact'),
|
||||||
'$desc' => DI::l10n()->t('Enter address or web location'),
|
'$desc' => DI::l10n()->t('Enter address or web location'),
|
||||||
'$hint' => DI::l10n()->t('Example: bob@example.com, http://example.com/barbara'),
|
'$hint' => DI::l10n()->t('Example: bob@example.com, http://example.com/barbara'),
|
||||||
'$value' => $value,
|
'$value' => $value,
|
||||||
'$follow' => DI::l10n()->t('Connect')
|
'$follow' => DI::l10n()->t('Connect')
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,21 +59,21 @@ class Widget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$nv = [];
|
$nv = [];
|
||||||
$nv['findpeople'] = DI::l10n()->t('Find People');
|
$nv['findpeople'] = DI::l10n()->t('Find People');
|
||||||
$nv['desc'] = DI::l10n()->t('Enter name or interest');
|
$nv['desc'] = DI::l10n()->t('Enter name or interest');
|
||||||
$nv['label'] = DI::l10n()->t('Connect/Follow');
|
$nv['label'] = DI::l10n()->t('Connect/Follow');
|
||||||
$nv['hint'] = DI::l10n()->t('Examples: Robert Morgenstein, Fishing');
|
$nv['hint'] = DI::l10n()->t('Examples: Robert Morgenstein, Fishing');
|
||||||
$nv['findthem'] = DI::l10n()->t('Find');
|
$nv['findthem'] = DI::l10n()->t('Find');
|
||||||
$nv['suggest'] = DI::l10n()->t('Friend Suggestions');
|
$nv['suggest'] = DI::l10n()->t('Friend Suggestions');
|
||||||
$nv['similar'] = DI::l10n()->t('Similar Interests');
|
$nv['similar'] = DI::l10n()->t('Similar Interests');
|
||||||
$nv['random'] = DI::l10n()->t('Random Profile');
|
$nv['random'] = DI::l10n()->t('Random Profile');
|
||||||
$nv['inv'] = DI::l10n()->t('Invite Friends');
|
$nv['inv'] = DI::l10n()->t('Invite Friends');
|
||||||
$nv['directory'] = DI::l10n()->t('Global Directory');
|
$nv['directory'] = DI::l10n()->t('Global Directory');
|
||||||
$nv['global_dir'] = OpenWebAuth::getZrlUrl($global_dir, true);
|
$nv['global_dir'] = OpenWebAuth::getZrlUrl($global_dir, true);
|
||||||
$nv['local_directory'] = DI::l10n()->t('Local Directory');
|
$nv['local_directory'] = DI::l10n()->t('Local Directory');
|
||||||
|
|
||||||
$aside = [];
|
$aside = [];
|
||||||
$aside['$nv'] = $nv;
|
$aside['$nv'] = $nv;
|
||||||
|
|
||||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/peoplefind.tpl'), $aside);
|
return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/peoplefind.tpl'), $aside);
|
||||||
|
@ -87,19 +86,21 @@ class Widget
|
||||||
*/
|
*/
|
||||||
public static function unavailableNetworks(): array
|
public static function unavailableNetworks(): array
|
||||||
{
|
{
|
||||||
|
$addonHelper = DI::addonHelper();
|
||||||
|
|
||||||
// Always hide content from these networks
|
// Always hide content from these networks
|
||||||
$networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::TWITTER, Protocol::ZOT, Protocol::OSTATUS, Protocol::STATUSNET];
|
$networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::TWITTER, Protocol::ZOT, Protocol::OSTATUS, Protocol::STATUSNET];
|
||||||
Addon::loadAddons();
|
$addonHelper->loadAddons();
|
||||||
|
|
||||||
if (!Addon::isEnabled('discourse')) {
|
if (!$addonHelper->isAddonEnabled('discourse')) {
|
||||||
$networks[] = Protocol::DISCOURSE;
|
$networks[] = Protocol::DISCOURSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Addon::isEnabled('pumpio')) {
|
if (!$addonHelper->isAddonEnabled('pumpio')) {
|
||||||
$networks[] = Protocol::PUMPIO;
|
$networks[] = Protocol::PUMPIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Addon::isEnabled('tumblr')) {
|
if (!$addonHelper->isAddonEnabled('tumblr')) {
|
||||||
$networks[] = Protocol::TUMBLR;
|
$networks[] = Protocol::TUMBLR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ class Widget
|
||||||
$networks[] = Protocol::DIASPORA;
|
$networks[] = Protocol::DIASPORA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Addon::isEnabled('pnut')) {
|
if (!$addonHelper->isAddonEnabled('pnut')) {
|
||||||
$networks[] = Protocol::PNUT;
|
$networks[] = Protocol::PNUT;
|
||||||
}
|
}
|
||||||
return $networks;
|
return $networks;
|
||||||
|
@ -120,18 +121,20 @@ class Widget
|
||||||
*/
|
*/
|
||||||
public static function availableNetworks(): array
|
public static function availableNetworks(): array
|
||||||
{
|
{
|
||||||
$networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED];
|
$addonHelper = DI::addonHelper();
|
||||||
Addon::loadAddons();
|
|
||||||
|
|
||||||
if (Addon::isEnabled('discourse')) {
|
$networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::FEED];
|
||||||
|
$addonHelper->loadAddons();
|
||||||
|
|
||||||
|
if ($addonHelper->isAddonEnabled('discourse')) {
|
||||||
$networks[] = Protocol::DISCOURSE;
|
$networks[] = Protocol::DISCOURSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Addon::isEnabled('pumpio')) {
|
if ($addonHelper->isAddonEnabled('pumpio')) {
|
||||||
$networks[] = Protocol::PUMPIO;
|
$networks[] = Protocol::PUMPIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Addon::isEnabled('tumblr')) {
|
if ($addonHelper->isAddonEnabled('tumblr')) {
|
||||||
$networks[] = Protocol::TUMBLR;
|
$networks[] = Protocol::TUMBLR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +146,7 @@ class Widget
|
||||||
$networks[] = Protocol::MAIL;
|
$networks[] = Protocol::MAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Addon::isEnabled('pnut')) {
|
if ($addonHelper->isAddonEnabled('pnut')) {
|
||||||
$networks[] = Protocol::PNUT;
|
$networks[] = Protocol::PNUT;
|
||||||
}
|
}
|
||||||
return $networks;
|
return $networks;
|
||||||
|
@ -174,7 +177,7 @@ class Widget
|
||||||
private static function filter(string $type, string $title, string $desc, string $all, string $baseUrl, array $options, string $selected = null): string
|
private static function filter(string $type, string $title, string $desc, string $all, string $baseUrl, array $options, string $selected = null): string
|
||||||
{
|
{
|
||||||
$queryString = parse_url($baseUrl, PHP_URL_QUERY);
|
$queryString = parse_url($baseUrl, PHP_URL_QUERY);
|
||||||
$queryArray = [];
|
$queryArray = [];
|
||||||
|
|
||||||
if ($queryString) {
|
if ($queryString) {
|
||||||
parse_str($queryString, $queryArray);
|
parse_str($queryString, $queryArray);
|
||||||
|
@ -282,8 +285,8 @@ class Widget
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$networks = self::unavailableNetworks();
|
$networks = self::unavailableNetworks();
|
||||||
$query = "`uid` = ? AND NOT `deleted` AND `network` != '' AND NOT `network` IN (" . substr(str_repeat("?, ", count($networks)), 0, -2) . ")";
|
$query = "`uid` = ? AND NOT `deleted` AND `network` != '' AND NOT `network` IN (" . substr(str_repeat("?, ", count($networks)), 0, -2) . ")";
|
||||||
$condition = array_merge([$query], array_merge([DI::userSession()->getLocalUserId()], $networks));
|
$condition = array_merge([$query], array_merge([DI::userSession()->getLocalUserId()], $networks));
|
||||||
|
|
||||||
$r = DBA::select('contact', ['network'], $condition, ['group_by' => ['network'], 'order' => ['network']]);
|
$r = DBA::select('contact', ['network'], $condition, ['group_by' => ['network'], 'order' => ['network']]);
|
||||||
|
@ -473,7 +476,7 @@ class Widget
|
||||||
$ret = [];
|
$ret = [];
|
||||||
|
|
||||||
$cachekey = 'Widget::postedByYear' . $uid . '-' . (int)$wall;
|
$cachekey = 'Widget::postedByYear' . $uid . '-' . (int)$wall;
|
||||||
$dthen = DI::cache()->get($cachekey);
|
$dthen = DI::cache()->get($cachekey);
|
||||||
if (empty($dthen)) {
|
if (empty($dthen)) {
|
||||||
$dthen = Item::firstPostDate($uid, $wall);
|
$dthen = Item::firstPostDate($uid, $wall);
|
||||||
DI::cache()->set($cachekey, $dthen, Duration::HOUR);
|
DI::cache()->set($cachekey, $dthen, Duration::HOUR);
|
||||||
|
@ -486,30 +489,30 @@ class Widget
|
||||||
if ($dthen) {
|
if ($dthen) {
|
||||||
// Set the start and end date to the beginning of the month
|
// Set the start and end date to the beginning of the month
|
||||||
$cutoffday = $dthen;
|
$cutoffday = $dthen;
|
||||||
$thisday = substr($dnow, 4);
|
$thisday = substr($dnow, 4);
|
||||||
$nextday = date('Y-m-d', strtotime($dnow . ' + 1 day'));
|
$nextday = date('Y-m-d', strtotime($dnow . ' + 1 day'));
|
||||||
$nextday = substr($nextday, 4);
|
$nextday = substr($nextday, 4);
|
||||||
$dnow = substr($dnow, 0, 8) . '01';
|
$dnow = substr($dnow, 0, 8) . '01';
|
||||||
$dthen = substr($dthen, 0, 8) . '01';
|
$dthen = substr($dthen, 0, 8) . '01';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Starting with the current month, get the first and last days of every
|
* Starting with the current month, get the first and last days of every
|
||||||
* month down to and including the month of the first post
|
* month down to and including the month of the first post
|
||||||
*/
|
*/
|
||||||
while (substr($dnow, 0, 7) >= substr($dthen, 0, 7)) {
|
while (substr($dnow, 0, 7) >= substr($dthen, 0, 7)) {
|
||||||
$dyear = intval(substr($dnow, 0, 4));
|
$dyear = intval(substr($dnow, 0, 4));
|
||||||
$dstart = substr($dnow, 0, 8) . '01';
|
$dstart = substr($dnow, 0, 8) . '01';
|
||||||
$dend = substr($dnow, 0, 8) . Temporal::getDaysInMonth(intval($dnow), intval(substr($dnow, 5)));
|
$dend = substr($dnow, 0, 8) . Temporal::getDaysInMonth(intval($dnow), intval(substr($dnow, 5)));
|
||||||
$start_month = DateTimeFormat::utc($dstart, 'Y-m-d');
|
$start_month = DateTimeFormat::utc($dstart, 'Y-m-d');
|
||||||
$end_month = DateTimeFormat::utc($dend, 'Y-m-d');
|
$end_month = DateTimeFormat::utc($dend, 'Y-m-d');
|
||||||
$str = DI::l10n()->getDay(DateTimeFormat::utc($dnow, 'F'));
|
$str = DI::l10n()->getDay(DateTimeFormat::utc($dnow, 'F'));
|
||||||
|
|
||||||
if (empty($ret[$dyear])) {
|
if (empty($ret[$dyear])) {
|
||||||
$ret[$dyear] = [];
|
$ret[$dyear] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$ret[$dyear][] = [$str, $end_month, $start_month];
|
$ret[$dyear][] = [$str, $end_month, $start_month];
|
||||||
$dnow = DateTimeFormat::utc($dnow . ' -1 month', 'Y-m-d');
|
$dnow = DateTimeFormat::utc($dnow . ' -1 month', 'Y-m-d');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,21 +521,21 @@ class Widget
|
||||||
}
|
}
|
||||||
|
|
||||||
$cutoff_year = intval(DateTimeFormat::localNow('Y')) - $visible_years;
|
$cutoff_year = intval(DateTimeFormat::localNow('Y')) - $visible_years;
|
||||||
$cutoff = array_key_exists($cutoff_year, $ret);
|
$cutoff = array_key_exists($cutoff_year, $ret);
|
||||||
|
|
||||||
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/posted_date.tpl'), [
|
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/posted_date.tpl'), [
|
||||||
'$title' => DI::l10n()->t('Archives'),
|
'$title' => DI::l10n()->t('Archives'),
|
||||||
'$size' => $visible_years,
|
'$size' => $visible_years,
|
||||||
'$cutoff_year' => $cutoff_year,
|
'$cutoff_year' => $cutoff_year,
|
||||||
'$cutoff' => $cutoff,
|
'$cutoff' => $cutoff,
|
||||||
'$url' => $url,
|
'$url' => $url,
|
||||||
'$dates' => $ret,
|
'$dates' => $ret,
|
||||||
'$showless' => DI::l10n()->t('show less'),
|
'$showless' => DI::l10n()->t('show less'),
|
||||||
'$showmore' => DI::l10n()->t('show more'),
|
'$showmore' => DI::l10n()->t('show more'),
|
||||||
'$onthisdate' => DI::l10n()->t('On this date'),
|
'$onthisdate' => DI::l10n()->t('On this date'),
|
||||||
'$thisday' => $thisday,
|
'$thisday' => $thisday,
|
||||||
'$nextday' => $nextday,
|
'$nextday' => $nextday,
|
||||||
'$cutoffday' => $cutoffday
|
'$cutoffday' => $cutoffday
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
|
|
|
@ -18,6 +18,9 @@ class Addon
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The addon sub-directory
|
* The addon sub-directory
|
||||||
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAddonPath()` instead
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const DIRECTORY = 'addon';
|
const DIRECTORY = 'addon';
|
||||||
|
@ -34,6 +37,8 @@ class Addon
|
||||||
* This list is made from scanning the addon/ folder.
|
* This list is made from scanning the addon/ folder.
|
||||||
* Unsupported addons are excluded unless they already are enabled or system.show_unsupported_addon is set.
|
* Unsupported addons are excluded unless they already are enabled or system.show_unsupported_addon is set.
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAvailableAddons()` instead
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
|
@ -64,6 +69,8 @@ class Addon
|
||||||
* Returns a list of addons that can be configured at the node level.
|
* Returns a list of addons that can be configured at the node level.
|
||||||
* The list is formatted for display in the admin panel aside.
|
* The list is formatted for display in the admin panel aside.
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getEnabledAddonsWithAdminSettings()` instead
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
|
@ -88,7 +95,6 @@ class Addon
|
||||||
return $addons_admin;
|
return $addons_admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronize addons:
|
* Synchronize addons:
|
||||||
*
|
*
|
||||||
|
@ -100,6 +106,7 @@ class Addon
|
||||||
* Then go through the config list and if we have a addon that isn't installed,
|
* Then go through the config list and if we have a addon that isn't installed,
|
||||||
* call the install procedure and add it to the database.
|
* call the install procedure and add it to the database.
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::loadAddons()` instead
|
||||||
*/
|
*/
|
||||||
public static function loadAddons()
|
public static function loadAddons()
|
||||||
{
|
{
|
||||||
|
@ -109,6 +116,8 @@ class Addon
|
||||||
/**
|
/**
|
||||||
* uninstalls an addon.
|
* uninstalls an addon.
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::uninstallAddon()` instead
|
||||||
|
*
|
||||||
* @param string $addon name of the addon
|
* @param string $addon name of the addon
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
|
@ -135,6 +144,8 @@ class Addon
|
||||||
/**
|
/**
|
||||||
* installs an addon.
|
* installs an addon.
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::installAddon()` instead
|
||||||
|
*
|
||||||
* @param string $addon name of the addon
|
* @param string $addon name of the addon
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
|
@ -173,6 +184,8 @@ class Addon
|
||||||
/**
|
/**
|
||||||
* reload all updated addons
|
* reload all updated addons
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::reloadAddons()` instead
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*
|
*
|
||||||
|
@ -209,6 +222,9 @@ class Addon
|
||||||
* * Maintainer: Jess <email>
|
* * Maintainer: Jess <email>
|
||||||
* *
|
* *
|
||||||
* *\endcode
|
* *\endcode
|
||||||
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getAddonInfo()` instead
|
||||||
|
*
|
||||||
* @param string $addon the name of the addon
|
* @param string $addon the name of the addon
|
||||||
* @return array with the addon information
|
* @return array with the addon information
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
|
@ -275,6 +291,8 @@ class Addon
|
||||||
/**
|
/**
|
||||||
* Checks if the provided addon is enabled
|
* Checks if the provided addon is enabled
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::isAddonEnabled()` instead
|
||||||
|
*
|
||||||
* @param string $addon
|
* @param string $addon
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
|
@ -286,6 +304,8 @@ class Addon
|
||||||
/**
|
/**
|
||||||
* Returns a list of the enabled addon names
|
* Returns a list of the enabled addon names
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getEnabledAddons()` instead
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function getEnabledList(): array
|
public static function getEnabledList(): array
|
||||||
|
@ -296,6 +316,8 @@ class Addon
|
||||||
/**
|
/**
|
||||||
* Returns the list of non-hidden enabled addon names
|
* Returns the list of non-hidden enabled addon names
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 Use `Friendica\Core\Addon\AddonHelper::getVisibleEnabledAddons()` instead
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?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\Addon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some functions to handle addons
|
||||||
|
*/
|
||||||
|
interface AddonHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the absolute path to the addon folder
|
||||||
|
*
|
||||||
|
* e.g. `/var/www/html/addon`
|
||||||
|
*/
|
||||||
|
public function getAddonPath(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of available addons.
|
||||||
|
*
|
||||||
|
* This list is made from scanning the addon/ folder.
|
||||||
|
* Unsupported addons are excluded unless they already are enabled or system.show_unsupported_addon is set.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getAvailableAddons(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs an addon.
|
||||||
|
*
|
||||||
|
* @param string $addonId name of the addon
|
||||||
|
*
|
||||||
|
* @return bool true on success or false on failure
|
||||||
|
*/
|
||||||
|
public function installAddon(string $addonId): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstalls an addon.
|
||||||
|
*
|
||||||
|
* @param string $addonId name of the addon
|
||||||
|
*/
|
||||||
|
public function uninstallAddon(string $addonId): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load addons.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function loadAddons(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload (uninstall and install) all updated addons.
|
||||||
|
*/
|
||||||
|
public function reloadAddons(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the comment block of an addon as value object.
|
||||||
|
*/
|
||||||
|
public function getAddonInfo(string $addonId): AddonInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the provided addon is enabled
|
||||||
|
*/
|
||||||
|
public function isAddonEnabled(string $addonId): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list with the IDs of the enabled addons
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getEnabledAddons(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list with the IDs of the non-hidden enabled addons
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getVisibleEnabledAddons(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list with the IDs of the enabled addons that provides admin settings.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getEnabledAddonsWithAdminSettings(): array;
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
<?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\Addon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about an addon
|
||||||
|
*/
|
||||||
|
final class AddonInfo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @internal Never create this object by yourself, use `Friendica\Core\Addon\AddonHelper::getAddonInfo()` instead.
|
||||||
|
*
|
||||||
|
* @see Friendica\Core\Addon\AddonHelper::getAddonInfo()
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $info): self
|
||||||
|
{
|
||||||
|
$id = array_key_exists('id', $info) ? (string) $info['id'] : '';
|
||||||
|
$name = array_key_exists('name', $info) ? (string) $info['name'] : '';
|
||||||
|
$description = array_key_exists('description', $info) ? (string) $info['description'] : '';
|
||||||
|
$authors = array_key_exists('authors', $info) ? self::parseContributors($info['authors']) : [];
|
||||||
|
$maintainers = array_key_exists('maintainers', $info) ? self::parseContributors($info['maintainers']) : [];
|
||||||
|
$version = array_key_exists('version', $info) ? (string) $info['version'] : '';
|
||||||
|
$status = array_key_exists('status', $info) ? (string) $info['status'] : '';
|
||||||
|
|
||||||
|
return new self(
|
||||||
|
$id,
|
||||||
|
$name,
|
||||||
|
$description,
|
||||||
|
$authors,
|
||||||
|
$maintainers,
|
||||||
|
$version,
|
||||||
|
$status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function parseContributors($entries): array
|
||||||
|
{
|
||||||
|
if (!is_array($entries)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$contributors = [];
|
||||||
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
if (!is_array($entry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists('name', $entry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$contributor = [
|
||||||
|
'name' => (string) $entry['name'],
|
||||||
|
];
|
||||||
|
|
||||||
|
if (array_key_exists('link', $entry)) {
|
||||||
|
$contributor['link'] = (string) $entry['link'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$contributors[] = $contributor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $contributors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string $id = '';
|
||||||
|
|
||||||
|
private string $name = '';
|
||||||
|
|
||||||
|
private string $description = '';
|
||||||
|
|
||||||
|
private array $authors = [];
|
||||||
|
|
||||||
|
private array $maintainers = [];
|
||||||
|
|
||||||
|
private string $version = '';
|
||||||
|
|
||||||
|
private string $status = '';
|
||||||
|
|
||||||
|
private function __construct(
|
||||||
|
string $id,
|
||||||
|
string $name,
|
||||||
|
string $description,
|
||||||
|
array $authors,
|
||||||
|
array $maintainers,
|
||||||
|
string $version,
|
||||||
|
string $status
|
||||||
|
) {
|
||||||
|
$this->id = $id;
|
||||||
|
$this->name = $name;
|
||||||
|
$this->description = $description;
|
||||||
|
$this->authors = $authors;
|
||||||
|
$this->maintainers = $maintainers;
|
||||||
|
$this->version = $version;
|
||||||
|
$this->status = $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): string
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return $this->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAuthors(): array
|
||||||
|
{
|
||||||
|
return $this->authors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMaintainers(): array
|
||||||
|
{
|
||||||
|
return $this->maintainers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVersion(): string
|
||||||
|
{
|
||||||
|
return $this->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStatus(): string
|
||||||
|
{
|
||||||
|
return $this->status;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
<?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\Addon;
|
||||||
|
|
||||||
|
use Friendica\Core\Addon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to the Addon class
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class AddonProxy implements AddonHelper
|
||||||
|
{
|
||||||
|
private string $addonPath;
|
||||||
|
|
||||||
|
public function __construct(string $addonPath)
|
||||||
|
{
|
||||||
|
$this->addonPath = $addonPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the absolute path to the addon folder
|
||||||
|
*
|
||||||
|
* e.g. `/var/www/html/addon`
|
||||||
|
*/
|
||||||
|
public function getAddonPath(): string
|
||||||
|
{
|
||||||
|
return $this->addonPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of available addons.
|
||||||
|
*
|
||||||
|
* This list is made from scanning the addon/ folder.
|
||||||
|
* Unsupported addons are excluded unless they already are enabled or system.show_unsupported_addon is set.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getAvailableAddons(): array
|
||||||
|
{
|
||||||
|
return array_map(
|
||||||
|
function (array $item) {
|
||||||
|
return $item[0];
|
||||||
|
},
|
||||||
|
Addon::getAvailableList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs an addon.
|
||||||
|
*
|
||||||
|
* @param string $addonId name of the addon
|
||||||
|
*
|
||||||
|
* @return bool true on success or false on failure
|
||||||
|
*/
|
||||||
|
public function installAddon(string $addonId): bool
|
||||||
|
{
|
||||||
|
return Addon::install($addonId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstalls an addon.
|
||||||
|
*
|
||||||
|
* @param string $addonId name of the addon
|
||||||
|
*/
|
||||||
|
public function uninstallAddon(string $addonId): void
|
||||||
|
{
|
||||||
|
Addon::uninstall($addonId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load addons.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function loadAddons(): void
|
||||||
|
{
|
||||||
|
Addon::loadAddons();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload (uninstall and install) all updated addons.
|
||||||
|
*/
|
||||||
|
public function reloadAddons(): void
|
||||||
|
{
|
||||||
|
Addon::reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the comment block of an addon as value object.
|
||||||
|
*/
|
||||||
|
public function getAddonInfo(string $addonId): AddonInfo
|
||||||
|
{
|
||||||
|
$data = Addon::getInfo($addonId);
|
||||||
|
|
||||||
|
// add addon ID
|
||||||
|
$data['id'] = $addonId;
|
||||||
|
|
||||||
|
// rename author to authors
|
||||||
|
$data['authors'] = $data['author'];
|
||||||
|
unset($data['author']);
|
||||||
|
|
||||||
|
// rename maintainer to maintainers
|
||||||
|
$data['maintainers'] = $data['maintainer'];
|
||||||
|
unset($data['maintainer']);
|
||||||
|
|
||||||
|
return AddonInfo::fromArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the provided addon is enabled
|
||||||
|
*/
|
||||||
|
public function isAddonEnabled(string $addonId): bool
|
||||||
|
{
|
||||||
|
return Addon::isEnabled($addonId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list with the IDs of the enabled addons
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getEnabledAddons(): array
|
||||||
|
{
|
||||||
|
return Addon::getEnabledList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list with the IDs of the non-hidden enabled addons
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getVisibleEnabledAddons(): array
|
||||||
|
{
|
||||||
|
return Addon::getVisibleList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list with the IDs of the enabled addons that provides admin settings.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getEnabledAddonsWithAdminSettings(): array
|
||||||
|
{
|
||||||
|
return array_keys(Addon::getAdminList());
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ class Config
|
||||||
*
|
*
|
||||||
* @return Util\ConfigFileManager
|
* @return Util\ConfigFileManager
|
||||||
*/
|
*/
|
||||||
public function createConfigFileManager(string $basePath, array $server = []): Util\ConfigFileManager
|
public function createConfigFileManager(string $basePath, string $addonPath, array $server = []): Util\ConfigFileManager
|
||||||
{
|
{
|
||||||
if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
|
if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
|
||||||
$configDir = $server[self::CONFIG_DIR_ENV];
|
$configDir = $server[self::CONFIG_DIR_ENV];
|
||||||
|
@ -51,7 +51,7 @@ class Config
|
||||||
}
|
}
|
||||||
$staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
|
$staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
|
||||||
|
|
||||||
return new Util\ConfigFileManager($basePath, $configDir, $staticDir, $server);
|
return new Util\ConfigFileManager($basePath, $addonPath, $configDir, $staticDir, $server);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Friendica\Core\Config\Util;
|
namespace Friendica\Core\Config\Util;
|
||||||
|
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Config\Exception\ConfigFileException;
|
use Friendica\Core\Config\Exception\ConfigFileException;
|
||||||
use Friendica\Core\Config\ValueObject\Cache;
|
use Friendica\Core\Config\ValueObject\Cache;
|
||||||
|
|
||||||
|
@ -46,6 +45,7 @@ class ConfigFileManager
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $baseDir;
|
private $baseDir;
|
||||||
|
private string $addonDir;
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
|
@ -65,9 +65,10 @@ class ConfigFileManager
|
||||||
* @param string $configDir
|
* @param string $configDir
|
||||||
* @param string $staticDir
|
* @param string $staticDir
|
||||||
*/
|
*/
|
||||||
public function __construct(string $baseDir, string $configDir, string $staticDir, array $server = [])
|
public function __construct(string $baseDir, string $addonDir, string $configDir, string $staticDir, array $server = [])
|
||||||
{
|
{
|
||||||
$this->baseDir = $baseDir;
|
$this->baseDir = $baseDir;
|
||||||
|
$this->addonDir = $addonDir;
|
||||||
$this->configDir = $configDir;
|
$this->configDir = $configDir;
|
||||||
$this->staticDir = $staticDir;
|
$this->staticDir = $staticDir;
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
|
@ -122,7 +123,7 @@ class ConfigFileManager
|
||||||
|
|
||||||
if (file_exists($configName)) {
|
if (file_exists($configName)) {
|
||||||
return $this->loadConfigFile($configName);
|
return $this->loadConfigFile($configName);
|
||||||
} else if (file_exists($iniName)) {
|
} elseif (file_exists($iniName)) {
|
||||||
return $this->loadINIConfigFile($iniName);
|
return $this->loadINIConfigFile($iniName);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
|
@ -160,17 +161,16 @@ class ConfigFileManager
|
||||||
*/
|
*/
|
||||||
public function loadAddonConfig(string $name): array
|
public function loadAddonConfig(string $name): array
|
||||||
{
|
{
|
||||||
$filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
|
$filepath = $this->addonDir . DIRECTORY_SEPARATOR . // /var/www/html/addon/
|
||||||
Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
|
$name . DIRECTORY_SEPARATOR . // openstreetmap/
|
||||||
$name . DIRECTORY_SEPARATOR . // openstreetmap/
|
'config' . DIRECTORY_SEPARATOR . // config/
|
||||||
'config' . DIRECTORY_SEPARATOR . // config/
|
$name . ".config.php"; // openstreetmap.config.php
|
||||||
$name . ".config.php"; // openstreetmap.config.php
|
|
||||||
|
|
||||||
if (file_exists($filepath)) {
|
if (!file_exists($filepath)) {
|
||||||
return $this->loadConfigFile($filepath);
|
|
||||||
} else {
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->loadConfigFile($filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?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\Hooks;
|
||||||
|
|
||||||
|
use Friendica\Core\Hook;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
|
use Friendica\Event\ConfigLoadedEvent;
|
||||||
|
use Friendica\Event\Event;
|
||||||
|
use Friendica\Event\HtmlFilterEvent;
|
||||||
|
use Friendica\Event\NamedEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bridge between the EventDispatcher and the Hook class.
|
||||||
|
*
|
||||||
|
* @internal Provides BC
|
||||||
|
*/
|
||||||
|
final class HookEventBridge
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @internal This allows us to mock the Hook call in tests.
|
||||||
|
*
|
||||||
|
* @var \Closure|null
|
||||||
|
*/
|
||||||
|
private static $mockedCallHook = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This maps the new event names to the legacy Hook names.
|
||||||
|
*/
|
||||||
|
private static array $eventMapper = [
|
||||||
|
Event::INIT => 'init_1',
|
||||||
|
ConfigLoadedEvent::CONFIG_LOADED => 'load_config',
|
||||||
|
ArrayFilterEvent::APP_MENU => 'app_menu',
|
||||||
|
ArrayFilterEvent::NAV_INFO => 'nav_info',
|
||||||
|
ArrayFilterEvent::FEATURE_ENABLED => 'isEnabled',
|
||||||
|
ArrayFilterEvent::FEATURE_GET => 'get',
|
||||||
|
HtmlFilterEvent::HEAD => 'head',
|
||||||
|
HtmlFilterEvent::FOOTER => 'footer',
|
||||||
|
HtmlFilterEvent::PAGE_HEADER => 'page_header',
|
||||||
|
HtmlFilterEvent::PAGE_CONTENT_TOP => 'page_content_top',
|
||||||
|
HtmlFilterEvent::PAGE_END => 'page_end',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
public static function getStaticSubscribedEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Event::INIT => 'onNamedEvent',
|
||||||
|
ConfigLoadedEvent::CONFIG_LOADED => 'onConfigLoadedEvent',
|
||||||
|
ArrayFilterEvent::APP_MENU => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::NAV_INFO => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::FEATURE_ENABLED => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::FEATURE_GET => 'onArrayFilterEvent',
|
||||||
|
HtmlFilterEvent::HEAD => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::FOOTER => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::PAGE_HEADER => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::PAGE_CONTENT_TOP => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::PAGE_END => 'onHtmlFilterEvent',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onNamedEvent(NamedEvent $event): void
|
||||||
|
{
|
||||||
|
static::callHook($event->getName(), '');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onConfigLoadedEvent(ConfigLoadedEvent $event): void
|
||||||
|
{
|
||||||
|
static::callHook($event->getName(), $event->getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onArrayFilterEvent(ArrayFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$event->setArray(
|
||||||
|
static::callHook($event->getName(), $event->getArray())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onHtmlFilterEvent(HtmlFilterEvent $event): void
|
||||||
|
{
|
||||||
|
$event->setHtml(
|
||||||
|
static::callHook($event->getName(), $event->getHtml())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|array|object $data
|
||||||
|
*
|
||||||
|
* @return string|array|object
|
||||||
|
*/
|
||||||
|
private static function callHook(string $name, $data)
|
||||||
|
{
|
||||||
|
// If possible, map the event name to the legacy Hook name
|
||||||
|
$name = static::$eventMapper[$name] ?? $name;
|
||||||
|
|
||||||
|
// Little hack to allow mocking the Hook call in tests.
|
||||||
|
if (static::$mockedCallHook instanceof \Closure) {
|
||||||
|
return (static::$mockedCallHook)->__invoke($name, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Hook::callAll($name, $data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Core;
|
namespace Friendica\Core;
|
||||||
|
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Core\Logger\Type\WorkerLogger;
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,10 +17,7 @@ use Psr\Log\LoggerInterface;
|
||||||
*/
|
*/
|
||||||
class Logger
|
class Logger
|
||||||
{
|
{
|
||||||
/**
|
private static function getInstance(): LoggerInterface
|
||||||
* @return LoggerInterface|WorkerLogger
|
|
||||||
*/
|
|
||||||
private static function getInstance()
|
|
||||||
{
|
{
|
||||||
return DI::logger();
|
return DI::logger();
|
||||||
}
|
}
|
||||||
|
@ -38,6 +34,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function emergency(string $message, array $context = [])
|
public static function emergency(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->emergency($message, $context);
|
self::getInstance()->emergency($message, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +53,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function alert(string $message, array $context = [])
|
public static function alert(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->alert($message, $context);
|
self::getInstance()->alert($message, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +71,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function critical(string $message, array $context = [])
|
public static function critical(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->critical($message, $context);
|
self::getInstance()->critical($message, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +88,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function error(string $message, array $context = [])
|
public static function error(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->error($message, $context);
|
self::getInstance()->error($message, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +107,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function warning(string $message, array $context = [])
|
public static function warning(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->warning($message, $context);
|
self::getInstance()->warning($message, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +123,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function notice(string $message, array $context = [])
|
public static function notice(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->notice($message, $context);
|
self::getInstance()->notice($message, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +142,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function info(string $message, array $context = [])
|
public static function info(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->info($message, $context);
|
self::getInstance()->info($message, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +158,8 @@ class Logger
|
||||||
*/
|
*/
|
||||||
public static function debug(string $message, array $context = [])
|
public static function debug(string $message, array $context = [])
|
||||||
{
|
{
|
||||||
|
@trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
self::getInstance()->debug($message, $context);
|
self::getInstance()->debug($message, $context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ class ErrorHandler
|
||||||
E_STRICT => LogLevel::NOTICE,
|
E_STRICT => LogLevel::NOTICE,
|
||||||
E_RECOVERABLE_ERROR => LogLevel::ERROR,
|
E_RECOVERABLE_ERROR => LogLevel::ERROR,
|
||||||
E_DEPRECATED => LogLevel::NOTICE,
|
E_DEPRECATED => LogLevel::NOTICE,
|
||||||
E_USER_DEPRECATED => LogLevel::NOTICE,
|
E_USER_DEPRECATED => LogLevel::WARNING,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,17 +248,29 @@ class ErrorHandler
|
||||||
*/
|
*/
|
||||||
public function handleError(int $code, string $message, string $file = '', int $line = 0, ?array $context = []): bool
|
public function handleError(int $code, string $message, string $file = '', int $line = 0, ?array $context = []): bool
|
||||||
{
|
{
|
||||||
if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) {
|
if ($this->handleOnlyReportedErrors && !(error_reporting() & $code) && $code !== E_USER_DEPRECATED) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
|
||||||
|
array_shift($trace); // Exclude handleError from trace
|
||||||
|
|
||||||
|
if ($code === E_USER_DEPRECATED && $trace[0]['function'] ?? '' === 'trigger_error') {
|
||||||
|
$calledPlace = $trace[1] ?? [];
|
||||||
|
|
||||||
|
$message .= sprintf(
|
||||||
|
' It was called in `%s`%s.',
|
||||||
|
$calledPlace['file'],
|
||||||
|
isset($calledPlace['line']) ? ' in line ' . $calledPlace['line'] : ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries
|
// fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries
|
||||||
if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) {
|
if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) {
|
||||||
$level = $this->errorLevelMap[$code] ?? LogLevel::CRITICAL;
|
$level = $this->errorLevelMap[$code] ?? LogLevel::CRITICAL;
|
||||||
$this->logger->log($level, self::codeToString($code).': '.$message, ['code' => $code, 'message' => $message, 'file' => $file, 'line' => $line]);
|
$this->logger->log($level, self::codeToString($code).': '.$message, ['code' => $code, 'message' => $message, 'file' => $file, 'line' => $line]);
|
||||||
} else {
|
} else {
|
||||||
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
|
||||||
array_shift($trace); // Exclude handleError from trace
|
|
||||||
$this->lastFatalTrace = $trace;
|
$this->lastFatalTrace = $trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Core\Storage\Repository;
|
namespace Friendica\Core\Storage\Repository;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
|
@ -20,6 +19,7 @@ use Friendica\Core\Storage\Capability\ICanConfigureStorage;
|
||||||
use Friendica\Core\Storage\Capability\ICanWriteToStorage;
|
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\Network\HTTPException\InternalServerErrorException;
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ class StorageManager
|
||||||
/// @fixme Loading the addons & hooks here is really bad practice, but solves https://github.com/friendica/friendica/issues/11178
|
/// @fixme Loading the addons & hooks here is really bad practice, but solves https://github.com/friendica/friendica/issues/11178
|
||||||
/// clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore
|
/// clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore
|
||||||
if ($includeAddon) {
|
if ($includeAddon) {
|
||||||
Addon::loadAddons();
|
DI::addonHelper()->loadAddons();
|
||||||
Hook::loadHooks();
|
Hook::loadHooks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ class StorageManager
|
||||||
// Try the filesystem backend
|
// Try the filesystem backend
|
||||||
case Type\Filesystem::getName():
|
case Type\Filesystem::getName():
|
||||||
return new Type\FilesystemConfig($this->config, $this->l10n);
|
return new Type\FilesystemConfig($this->config, $this->l10n);
|
||||||
// try the database backend
|
// try the database backend
|
||||||
case Type\Database::getName():
|
case Type\Database::getName():
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
|
@ -185,11 +185,11 @@ class StorageManager
|
||||||
$storageConfig = new Type\FilesystemConfig($this->config, $this->l10n);
|
$storageConfig = new Type\FilesystemConfig($this->config, $this->l10n);
|
||||||
$this->backendInstances[$name] = new Type\Filesystem($storageConfig->getStoragePath());
|
$this->backendInstances[$name] = new Type\Filesystem($storageConfig->getStoragePath());
|
||||||
break;
|
break;
|
||||||
// try the database backend
|
// try the database backend
|
||||||
case Type\Database::getName():
|
case Type\Database::getName():
|
||||||
$this->backendInstances[$name] = new Type\Database($this->dba);
|
$this->backendInstances[$name] = new Type\Database($this->dba);
|
||||||
break;
|
break;
|
||||||
// at least, try if there's an addon for the backend
|
// at least, try if there's an addon for the backend
|
||||||
case Type\SystemResource::getName():
|
case Type\SystemResource::getName():
|
||||||
$this->backendInstances[$name] = new Type\SystemResource();
|
$this->backendInstances[$name] = new Type\SystemResource();
|
||||||
break;
|
break;
|
||||||
|
@ -228,11 +228,13 @@ class StorageManager
|
||||||
*/
|
*/
|
||||||
public function isValidBackend(string $name = null, array $validBackends = null): bool
|
public function isValidBackend(string $name = null, array $validBackends = null): bool
|
||||||
{
|
{
|
||||||
$validBackends = $validBackends ?? array_merge($this->validBackends,
|
$validBackends = $validBackends ?? array_merge(
|
||||||
[
|
$this->validBackends,
|
||||||
Type\SystemResource::getName(),
|
[
|
||||||
Type\ExternalResource::getName(),
|
Type\SystemResource::getName(),
|
||||||
]);
|
Type\ExternalResource::getName(),
|
||||||
|
]
|
||||||
|
);
|
||||||
return in_array($name, $validBackends);
|
return in_array($name, $validBackends);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
src/DI.php
22
src/DI.php
|
@ -8,6 +8,7 @@
|
||||||
namespace Friendica;
|
namespace Friendica;
|
||||||
|
|
||||||
use Dice\Dice;
|
use Dice\Dice;
|
||||||
|
use Friendica\Core\Addon\AddonHelper;
|
||||||
use Friendica\Core\Logger\Capability\ICheckLoggerSettings;
|
use Friendica\Core\Logger\Capability\ICheckLoggerSettings;
|
||||||
use Friendica\Core\Logger\LoggerManager;
|
use Friendica\Core\Logger\LoggerManager;
|
||||||
use Friendica\Core\Logger\Util\LoggerSettingsCheck;
|
use Friendica\Core\Logger\Util\LoggerSettingsCheck;
|
||||||
|
@ -280,6 +281,11 @@ abstract class DI
|
||||||
return self::$dice->create(Core\Storage\Repository\StorageManager::class);
|
return self::$dice->create(Core\Storage\Repository\StorageManager::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function addonHelper(): AddonHelper
|
||||||
|
{
|
||||||
|
return self::$dice->create(AddonHelper::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Friendica\Core\System
|
* @return \Friendica\Core\System
|
||||||
*/
|
*/
|
||||||
|
@ -332,9 +338,16 @@ abstract class DI
|
||||||
*/
|
*/
|
||||||
public static function workerLogger()
|
public static function workerLogger()
|
||||||
{
|
{
|
||||||
|
@trigger_error('`' . __METHOD__ . '()` is deprecated since 2025.02 and will be removed after 5 months, use `DI::logger()` instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
return self::$dice->create(Core\Logger\Type\WorkerLogger::class);
|
return self::$dice->create(Core\Logger\Type\WorkerLogger::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal Only for use in Friendica\Core\Worker class
|
||||||
|
*
|
||||||
|
* @see Friendica\Core\Worker::execFunction()
|
||||||
|
*/
|
||||||
public static function loggerManager(): LoggerManager
|
public static function loggerManager(): LoggerManager
|
||||||
{
|
{
|
||||||
return self::$dice->create(LoggerManager::class);
|
return self::$dice->create(LoggerManager::class);
|
||||||
|
@ -782,4 +795,13 @@ abstract class DI
|
||||||
{
|
{
|
||||||
return self::$dice->create(Content\Post\Repository\PostMedia::class);
|
return self::$dice->create(Content\Post\Repository\PostMedia::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal The EventDispatcher should never called outside of the core, like in addons or themes
|
||||||
|
* @deprecated 2025.02 Use constructor injection instead
|
||||||
|
*/
|
||||||
|
public static function eventDispatcher(): \Psr\EventDispatcher\EventDispatcherInterface
|
||||||
|
{
|
||||||
|
return self::$dice->create(\Psr\EventDispatcher\EventDispatcherInterface::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?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\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow Event listener to modify an array.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class ArrayFilterEvent extends Event
|
||||||
|
{
|
||||||
|
public const APP_MENU = 'friendica.data.app_menu';
|
||||||
|
|
||||||
|
public const NAV_INFO = 'friendica.data.nav_info';
|
||||||
|
|
||||||
|
public const FEATURE_ENABLED = 'friendica.data.feature_enabled';
|
||||||
|
|
||||||
|
public const FEATURE_GET = 'friendica.data.feature_get';
|
||||||
|
|
||||||
|
private array $array;
|
||||||
|
|
||||||
|
public function __construct(string $name, array $array)
|
||||||
|
{
|
||||||
|
parent::__construct($name);
|
||||||
|
|
||||||
|
$this->array = $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getArray(): array
|
||||||
|
{
|
||||||
|
return $this->array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setArray(array $array): void
|
||||||
|
{
|
||||||
|
$this->array = $array;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?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\Event;
|
||||||
|
|
||||||
|
use Friendica\Core\Config\Util\ConfigFileManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify that the config was loaded
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class ConfigLoadedEvent extends Event
|
||||||
|
{
|
||||||
|
public const CONFIG_LOADED = 'friendica.config_loaded';
|
||||||
|
|
||||||
|
private ConfigFileManager $config;
|
||||||
|
|
||||||
|
public function __construct(string $name, ConfigFileManager $config)
|
||||||
|
{
|
||||||
|
parent::__construct($name);
|
||||||
|
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfig(): ConfigFileManager
|
||||||
|
{
|
||||||
|
return $this->config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?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\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One-way Event to inform listener about something happend.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class Event implements NamedEvent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Friendica is initialized.
|
||||||
|
*/
|
||||||
|
public const INIT = 'friendica.init';
|
||||||
|
|
||||||
|
private string $name;
|
||||||
|
|
||||||
|
public function __construct(string $name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?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\Event;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyEventDispatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modified Event Dispatcher.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class EventDispatcher extends SymfonyEventDispatcher
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Add support for named events.
|
||||||
|
*
|
||||||
|
* @template T of object
|
||||||
|
* @param T $event
|
||||||
|
*
|
||||||
|
* @return T The passed $event MUST be returned
|
||||||
|
*/
|
||||||
|
public function dispatch(object $event, ?string $eventName = null): object
|
||||||
|
{
|
||||||
|
if ($eventName === null && $event instanceof NamedEvent) {
|
||||||
|
$eventName = $event->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::dispatch($event, $eventName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?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\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow Event listener to modify HTML.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class HtmlFilterEvent extends Event
|
||||||
|
{
|
||||||
|
public const HEAD = 'friendica.html.head';
|
||||||
|
|
||||||
|
public const FOOTER = 'friendica.html.footer';
|
||||||
|
|
||||||
|
public const PAGE_HEADER = 'friendica.html.page_header';
|
||||||
|
|
||||||
|
public const PAGE_CONTENT_TOP = 'friendica.html.page_content_top';
|
||||||
|
|
||||||
|
public const PAGE_END = 'friendica.html.page_end';
|
||||||
|
|
||||||
|
private string $html;
|
||||||
|
|
||||||
|
public function __construct(string $name, string $html)
|
||||||
|
{
|
||||||
|
parent::__construct($name);
|
||||||
|
|
||||||
|
$this->html = $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHtml(): string
|
||||||
|
{
|
||||||
|
return $this->html;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHtml(string $html): void
|
||||||
|
{
|
||||||
|
$this->html = $html;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?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\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for named events.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
interface NamedEvent
|
||||||
|
{
|
||||||
|
public function getName(): string;
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ namespace Friendica\Model\Contact;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\Content\Widget;
|
use Friendica\Content\Widget;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
|
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;
|
||||||
|
@ -22,6 +23,7 @@ use Friendica\Protocol\Activity;
|
||||||
use Friendica\Protocol\ActivityPub;
|
use Friendica\Protocol\ActivityPub;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
|
use Friendica\Worker\AddContact;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides relationship information based on the `contact-relation` table.
|
* This class provides relationship information based on the `contact-relation` table.
|
||||||
|
@ -162,20 +164,22 @@ class Relation
|
||||||
$following_counter = 0;
|
$following_counter = 0;
|
||||||
|
|
||||||
DI::logger()->info('Discover contacts', ['id' => $target, 'url' => $url, 'contacts' => count($contacts)]);
|
DI::logger()->info('Discover contacts', ['id' => $target, 'url' => $url, 'contacts' => count($contacts)]);
|
||||||
foreach ($contacts as $contact) {
|
foreach ($contacts as $contact_url) {
|
||||||
$actor = Contact::getIdForURL($contact);
|
$contact = Contact::getByURL($contact_url, false, ['id']);
|
||||||
if (!empty($actor)) {
|
if (!empty($contact['id'])) {
|
||||||
if (in_array($contact, $followers)) {
|
if (in_array($contact_url, $followers)) {
|
||||||
$fields = ['cid' => $target, 'relation-cid' => $actor, 'follows' => true, 'follow-updated' => DateTimeFormat::utcNow()];
|
$fields = ['cid' => $target, 'relation-cid' => $contact['id'], 'follows' => true, 'follow-updated' => DateTimeFormat::utcNow()];
|
||||||
DBA::insert('contact-relation', $fields, Database::INSERT_UPDATE);
|
DBA::insert('contact-relation', $fields, Database::INSERT_UPDATE);
|
||||||
$follower_counter++;
|
$follower_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($contact, $followings)) {
|
if (in_array($contact_url, $followings)) {
|
||||||
$fields = ['cid' => $actor, 'relation-cid' => $target, 'follows' => true, 'follow-updated' => DateTimeFormat::utcNow()];
|
$fields = ['cid' => $contact['id'], 'relation-cid' => $target, 'follows' => true, 'follow-updated' => DateTimeFormat::utcNow()];
|
||||||
DBA::insert('contact-relation', $fields, Database::INSERT_UPDATE);
|
DBA::insert('contact-relation', $fields, Database::INSERT_UPDATE);
|
||||||
$following_counter++;
|
$following_counter++;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
AddContact::add(Worker::PRIORITY_LOW, 0, $contact_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3182,6 +3182,10 @@ class Item
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($shared_item['uri-id'])) {
|
if (!empty($shared_item['uri-id'])) {
|
||||||
|
if (!$s) {
|
||||||
|
DI::logger()->notice('Unexpected empty item HTML', ['item' => $item]);
|
||||||
|
}
|
||||||
|
|
||||||
$s = self::replacePlatformIcon($s, $shared_item, $uid);
|
$s = self::replacePlatformIcon($s, $shared_item, $uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3258,6 +3262,10 @@ class Item
|
||||||
*/
|
*/
|
||||||
private static function replacePlatformIcon(string $html, array $item, int $uid): string
|
private static function replacePlatformIcon(string $html, array $item, int $uid): string
|
||||||
{
|
{
|
||||||
|
if ($html === '') {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
$dom = new \DOMDocument();
|
$dom = new \DOMDocument();
|
||||||
if (!@$dom->loadHTML($html)) {
|
if (!@$dom->loadHTML($html)) {
|
||||||
return $html;
|
return $html;
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Friendica\Model\Post;
|
||||||
use Friendica\Content\PageInfo;
|
use Friendica\Content\PageInfo;
|
||||||
use Friendica\Content\Text\BBCode;
|
use Friendica\Content\Text\BBCode;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
|
use Friendica\Core\System;
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
@ -255,16 +256,21 @@ class Media
|
||||||
|
|
||||||
private static function isFederatedServer(string $url): bool
|
private static function isFederatedServer(string $url): bool
|
||||||
{
|
{
|
||||||
$baseurl = Network::getBaseUrl(new Uri($url));
|
try {
|
||||||
if (empty($baseurl)) {
|
$baseurl = Network::getBaseUrl(new Uri($url));
|
||||||
|
if (empty($baseurl)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings::compareLink($baseurl, ATProtocol::WEB)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DBA::exists('gserver', ['nurl' => Strings::normaliseLink($baseurl), 'network' => Protocol::FEDERATED]);
|
||||||
|
} catch(\Throwable $e) {
|
||||||
|
DI::logger()->notice('Invalid URL provided', ['url' => $url, 'exception' => $e, 'callstack' => System::callstack(10)]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Strings::compareLink($baseurl, ATProtocol::WEB)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DBA::exists('gserver', ['nurl' => Strings::normaliseLink($baseurl), 'network' => Protocol::FEDERATED]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function addPreviewData(array $media): array
|
private static function addPreviewData(array $media): array
|
||||||
|
@ -790,7 +796,7 @@ class Media
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for links with descriptions
|
// Search for links with descriptions
|
||||||
if (preg_match_all("/\[url\=(https?:.*?)\].*?\[\/url\]/ism", $body, $matches)) {
|
if (preg_match_all("#\[url=(https?://.+?)].+?\[/url]#ism", $body, $matches)) {
|
||||||
foreach ($matches[1] as $url) {
|
foreach ($matches[1] as $url) {
|
||||||
DI::logger()->info('Got page url (link with description)', ['uri-id' => $uriid, 'url' => $url]);
|
DI::logger()->info('Got page url (link with description)', ['uri-id' => $uriid, 'url' => $url]);
|
||||||
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false);
|
$result = self::insert(['uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $url], false);
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Module\Admin\Addons;
|
namespace Friendica\Module\Admin\Addons;
|
||||||
|
|
||||||
use Friendica\Content\Text\Markdown;
|
use Friendica\Content\Text\Markdown;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Module\BaseAdmin;
|
use Friendica\Module\BaseAdmin;
|
||||||
|
@ -42,12 +41,12 @@ class Details extends BaseAdmin
|
||||||
{
|
{
|
||||||
parent::content();
|
parent::content();
|
||||||
|
|
||||||
$addons_admin = Addon::getAdminList();
|
$addonHelper = DI::addonHelper();
|
||||||
|
|
||||||
$addon = Strings::sanitizeFilePathItem($this->parameters['addon']);
|
$addon = Strings::sanitizeFilePathItem($this->parameters['addon']);
|
||||||
if (!is_file("addon/$addon/$addon.php")) {
|
if (!is_file("addon/$addon/$addon.php")) {
|
||||||
DI::sysmsg()->addNotice(DI::l10n()->t('Addon not found.'));
|
DI::sysmsg()->addNotice(DI::l10n()->t('Addon not found.'));
|
||||||
Addon::uninstall($addon);
|
$addonHelper->uninstallAddon($addon);
|
||||||
DI::baseUrl()->redirect('admin/addons');
|
DI::baseUrl()->redirect('admin/addons');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +54,11 @@ class Details extends BaseAdmin
|
||||||
self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons_details', 't');
|
self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons_details', 't');
|
||||||
|
|
||||||
// Toggle addon status
|
// Toggle addon status
|
||||||
if (Addon::isEnabled($addon)) {
|
if ($addonHelper->isAddonEnabled($addon)) {
|
||||||
Addon::uninstall($addon);
|
$addonHelper->uninstallAddon($addon);
|
||||||
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon));
|
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon));
|
||||||
} else {
|
} else {
|
||||||
Addon::install($addon);
|
$addonHelper->installAddon($addon);
|
||||||
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon));
|
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ class Details extends BaseAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
// display addon details
|
// display addon details
|
||||||
if (Addon::isEnabled($addon)) {
|
if ($addonHelper->isAddonEnabled($addon)) {
|
||||||
$status = 'on';
|
$status = 'on';
|
||||||
$action = DI::l10n()->t('Disable');
|
$action = DI::l10n()->t('Disable');
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,32 +81,42 @@ class Details extends BaseAdmin
|
||||||
$readme = '<pre>' . file_get_contents("addon/$addon/README") . '</pre>';
|
$readme = '<pre>' . file_get_contents("addon/$addon/README") . '</pre>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$addons_admin = $addonHelper->getEnabledAddonsWithAdminSettings();
|
||||||
|
|
||||||
$admin_form = '';
|
$admin_form = '';
|
||||||
if (array_key_exists($addon, $addons_admin)) {
|
if (in_array($addon, $addons_admin)) {
|
||||||
require_once "addon/$addon/$addon.php";
|
require_once "addon/$addon/$addon.php";
|
||||||
$func = $addon . '_addon_admin';
|
$func = $addon . '_addon_admin';
|
||||||
$func($admin_form);
|
$func($admin_form);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$addonInfo = $addonHelper->getAddonInfo($addon);
|
||||||
|
|
||||||
$t = Renderer::getMarkupTemplate('admin/addons/details.tpl');
|
$t = Renderer::getMarkupTemplate('admin/addons/details.tpl');
|
||||||
|
|
||||||
return Renderer::replaceMacros($t, [
|
return Renderer::replaceMacros($t, [
|
||||||
'$title' => DI::l10n()->t('Administration'),
|
'$title' => DI::l10n()->t('Administration'),
|
||||||
'$page' => DI::l10n()->t('Addons'),
|
'$page' => DI::l10n()->t('Addons'),
|
||||||
'$toggle' => DI::l10n()->t('Toggle'),
|
'$toggle' => DI::l10n()->t('Toggle'),
|
||||||
'$settings' => DI::l10n()->t('Settings'),
|
'$settings' => DI::l10n()->t('Settings'),
|
||||||
|
|
||||||
'$addon' => $addon,
|
'$addon' => $addon,
|
||||||
'$status' => $status,
|
'$status' => $status,
|
||||||
'$action' => $action,
|
'$action' => $action,
|
||||||
'$info' => Addon::getInfo($addon),
|
'$info' => [
|
||||||
'$str_author' => DI::l10n()->t('Author: '),
|
'name' => $addonInfo->getName(),
|
||||||
|
'version' => $addonInfo->getVersion(),
|
||||||
|
'description' => $addonInfo->getDescription(),
|
||||||
|
'author' => $addonInfo->getAuthors(),
|
||||||
|
'maintainer' => $addonInfo->getMaintainers(),
|
||||||
|
],
|
||||||
|
'$str_author' => DI::l10n()->t('Author: '),
|
||||||
'$str_maintainer' => DI::l10n()->t('Maintainer: '),
|
'$str_maintainer' => DI::l10n()->t('Maintainer: '),
|
||||||
|
|
||||||
'$admin_form' => $admin_form,
|
'$admin_form' => $admin_form,
|
||||||
'$function' => 'addons',
|
'$function' => 'addons',
|
||||||
'$screenshot' => '',
|
'$screenshot' => '',
|
||||||
'$readme' => $readme,
|
'$readme' => $readme,
|
||||||
|
|
||||||
'$form_security_token' => self::getFormSecurityToken('admin_addons_details'),
|
'$form_security_token' => self::getFormSecurityToken('admin_addons_details'),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Friendica\Module\Admin\Addons;
|
namespace Friendica\Module\Admin\Addons;
|
||||||
|
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Module\BaseAdmin;
|
use Friendica\Module\BaseAdmin;
|
||||||
|
@ -24,22 +23,25 @@ class Index extends BaseAdmin
|
||||||
{
|
{
|
||||||
parent::content();
|
parent::content();
|
||||||
|
|
||||||
|
$addonHelper = DI::addonHelper();
|
||||||
|
|
||||||
// reload active themes
|
// reload active themes
|
||||||
if (!empty($_GET['action'])) {
|
if (!empty($_GET['action'])) {
|
||||||
self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons', 't');
|
self::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_addons', 't');
|
||||||
|
|
||||||
switch ($_GET['action']) {
|
switch ($_GET['action']) {
|
||||||
case 'reload':
|
case 'reload':
|
||||||
Addon::reload();
|
$addonHelper->reloadAddons();
|
||||||
DI::sysmsg()->addInfo(DI::l10n()->t('Addons reloaded'));
|
DI::sysmsg()->addInfo(DI::l10n()->t('Addons reloaded'));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'toggle' :
|
case 'toggle':
|
||||||
$addon = $_GET['addon'] ?? '';
|
$addon = $_GET['addon'] ?? '';
|
||||||
if (Addon::isEnabled($addon)) {
|
|
||||||
Addon::uninstall($addon);
|
if ($addonHelper->isAddonEnabled($addon)) {
|
||||||
|
$addonHelper->uninstallAddon($addon);
|
||||||
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon));
|
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s disabled.', $addon));
|
||||||
} elseif (Addon::install($addon)) {
|
} elseif ($addonHelper->installAddon($addon)) {
|
||||||
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon));
|
DI::sysmsg()->addInfo(DI::l10n()->t('Addon %s enabled.', $addon));
|
||||||
} else {
|
} else {
|
||||||
DI::sysmsg()->addNotice(DI::l10n()->t('Addon %s failed to install.', $addon));
|
DI::sysmsg()->addNotice(DI::l10n()->t('Addon %s failed to install.', $addon));
|
||||||
|
@ -52,18 +54,34 @@ class Index extends BaseAdmin
|
||||||
DI::baseUrl()->redirect('admin/addons');
|
DI::baseUrl()->redirect('admin/addons');
|
||||||
}
|
}
|
||||||
|
|
||||||
$addons = Addon::getAvailableList();
|
$addons = [];
|
||||||
|
|
||||||
|
foreach ($addonHelper->getAvailableAddons() as $addonId) {
|
||||||
|
$addonInfo = $addonHelper->getAddonInfo($addonId);
|
||||||
|
|
||||||
|
$info = [
|
||||||
|
'name' => $addonInfo->getName(),
|
||||||
|
'description' => $addonInfo->getDescription(),
|
||||||
|
'version' => $addonInfo->getVersion(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$addons[] = [
|
||||||
|
$addonId,
|
||||||
|
($addonHelper->isAddonEnabled($addonId) ? 'on' : 'off'),
|
||||||
|
$info,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$t = Renderer::getMarkupTemplate('admin/addons/index.tpl');
|
$t = Renderer::getMarkupTemplate('admin/addons/index.tpl');
|
||||||
return Renderer::replaceMacros($t, [
|
return Renderer::replaceMacros($t, [
|
||||||
'$title' => DI::l10n()->t('Administration'),
|
'$title' => DI::l10n()->t('Administration'),
|
||||||
'$page' => DI::l10n()->t('Addons'),
|
'$page' => DI::l10n()->t('Addons'),
|
||||||
'$submit' => DI::l10n()->t('Save Settings'),
|
'$submit' => DI::l10n()->t('Save Settings'),
|
||||||
'$reload' => DI::l10n()->t('Reload active addons'),
|
'$reload' => DI::l10n()->t('Reload active addons'),
|
||||||
'$function' => 'addons',
|
'$function' => 'addons',
|
||||||
'$addons' => $addons,
|
'$addons' => $addons,
|
||||||
'$pcount' => count($addons),
|
'$pcount' => count($addons),
|
||||||
'$noplugshint' => DI::l10n()->t('There are currently no addons available on your node. You can find the official addon repository at %1$s.', 'https://git.friendi.ca/friendica/friendica-addons'),
|
'$noplugshint' => DI::l10n()->t('There are currently no addons available on your node. You can find the official addon repository at %1$s.', 'https://git.friendi.ca/friendica/friendica-addons'),
|
||||||
'$form_security_token' => self::getFormSecurityToken('admin_addons'),
|
'$form_security_token' => self::getFormSecurityToken('admin_addons'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Module\Admin;
|
namespace Friendica\Module\Admin;
|
||||||
|
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Config\ValueObject\Cache;
|
use Friendica\Core\Config\ValueObject\Cache;
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Update;
|
use Friendica\Core\Update;
|
||||||
|
@ -27,13 +26,14 @@ class Summary extends BaseAdmin
|
||||||
{
|
{
|
||||||
parent::content();
|
parent::content();
|
||||||
|
|
||||||
$basePath = DI::appHelper()->getBasePath();
|
$basePath = DI::appHelper()->getBasePath();
|
||||||
|
$addonPath = DI::addonHelper()->getAddonPath();
|
||||||
|
|
||||||
// are there MyISAM tables in the DB? If so, trigger a warning message
|
// are there MyISAM tables in the DB? If so, trigger a warning message
|
||||||
$warningtext = [];
|
$warningtext = [];
|
||||||
|
|
||||||
$templateEngine = Renderer::getTemplateEngine();
|
$templateEngine = Renderer::getTemplateEngine();
|
||||||
$errors = [];
|
$errors = [];
|
||||||
$templateEngine->testInstall($errors);
|
$templateEngine->testInstall($errors);
|
||||||
foreach ($errors as $error) {
|
foreach ($errors as $error) {
|
||||||
$warningtext[] = DI::l10n()->t('Template engine (%s) error: %s', $templateEngine::$name, $error);
|
$warningtext[] = DI::l10n()->t('Template engine (%s) error: %s', $templateEngine::$name, $error);
|
||||||
|
@ -51,7 +51,7 @@ class Summary extends BaseAdmin
|
||||||
// Avoid the database error 1615 "Prepared statement needs to be re-prepared", see https://github.com/friendica/friendica/issues/8550
|
// Avoid the database error 1615 "Prepared statement needs to be re-prepared", see https://github.com/friendica/friendica/issues/8550
|
||||||
if (!DI::config()->get('database', 'pdo_emulate_prepares')) {
|
if (!DI::config()->get('database', 'pdo_emulate_prepares')) {
|
||||||
$table_definition_cache = DBA::getVariable('table_definition_cache');
|
$table_definition_cache = DBA::getVariable('table_definition_cache');
|
||||||
$table_open_cache = DBA::getVariable('table_open_cache');
|
$table_open_cache = DBA::getVariable('table_open_cache');
|
||||||
if (!empty($table_definition_cache) && !empty($table_open_cache)) {
|
if (!empty($table_definition_cache) && !empty($table_open_cache)) {
|
||||||
$suggested_definition_cache = min(400 + round((int) $table_open_cache / 2, 1), 2000);
|
$suggested_definition_cache = min(400 + round((int) $table_open_cache / 2, 1), 2000);
|
||||||
if ($suggested_definition_cache > $table_definition_cache) {
|
if ($suggested_definition_cache > $table_definition_cache) {
|
||||||
|
@ -100,9 +100,13 @@ class Summary extends BaseAdmin
|
||||||
|
|
||||||
// Check server vitality
|
// Check server vitality
|
||||||
if (!self::checkSelfHostMeta()) {
|
if (!self::checkSelfHostMeta()) {
|
||||||
$well_known = DI::baseUrl() . Probe::HOST_META;
|
$well_known = DI::baseUrl() . Probe::HOST_META;
|
||||||
$warningtext[] = DI::l10n()->t('<a href="%s">%s</a> is not reachable on your system. This is a severe configuration issue that prevents server to server communication. See <a href="%s">the installation page</a> for help.',
|
$warningtext[] = DI::l10n()->t(
|
||||||
$well_known, $well_known, DI::baseUrl() . '/help/Install');
|
'<a href="%s">%s</a> is not reachable on your system. This is a severe configuration issue that prevents server to server communication. See <a href="%s">the installation page</a> for help.',
|
||||||
|
$well_known,
|
||||||
|
$well_known,
|
||||||
|
DI::baseUrl() . '/help/Install'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check logfile permission
|
// Check logfile permission
|
||||||
|
@ -114,8 +118,8 @@ class Summary extends BaseAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
// check legacy basepath settings
|
// check legacy basepath settings
|
||||||
$configLoader = (new Config())->createConfigFileManager($basePath, $_SERVER);
|
$configLoader = (new Config())->createConfigFileManager($basePath, $addonPath, $_SERVER);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
$configLoader->setupCache($configCache);
|
$configLoader->setupCache($configCache);
|
||||||
$confBasepath = $configCache->get('system', 'basepath');
|
$confBasepath = $configCache->get('system', 'basepath');
|
||||||
$currBasepath = DI::config()->get('system', 'basepath');
|
$currBasepath = DI::config()->get('system', 'basepath');
|
||||||
|
@ -125,25 +129,31 @@ class Summary extends BaseAdmin
|
||||||
'from' => $currBasepath,
|
'from' => $currBasepath,
|
||||||
'to' => $confBasepath,
|
'to' => $confBasepath,
|
||||||
]);
|
]);
|
||||||
$warningtext[] = DI::l10n()->t('Friendica\'s system.basepath was updated from \'%s\' to \'%s\'. Please remove the system.basepath from your db to avoid differences.',
|
$warningtext[] = DI::l10n()->t(
|
||||||
|
'Friendica\'s system.basepath was updated from \'%s\' to \'%s\'. Please remove the system.basepath from your db to avoid differences.',
|
||||||
$currBasepath,
|
$currBasepath,
|
||||||
$confBasepath);
|
$confBasepath
|
||||||
|
);
|
||||||
} elseif (!is_dir($currBasepath)) {
|
} elseif (!is_dir($currBasepath)) {
|
||||||
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
|
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
|
||||||
'from' => $currBasepath,
|
'from' => $currBasepath,
|
||||||
'to' => $confBasepath,
|
'to' => $confBasepath,
|
||||||
]);
|
]);
|
||||||
$warningtext[] = DI::l10n()->t('Friendica\'s current system.basepath \'%s\' is wrong and the config file \'%s\' isn\'t used.',
|
$warningtext[] = DI::l10n()->t(
|
||||||
|
'Friendica\'s current system.basepath \'%s\' is wrong and the config file \'%s\' isn\'t used.',
|
||||||
$currBasepath,
|
$currBasepath,
|
||||||
$confBasepath);
|
$confBasepath
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
|
DI::logger()->alert('Friendica\'s system.basepath is wrong.', [
|
||||||
'from' => $currBasepath,
|
'from' => $currBasepath,
|
||||||
'to' => $confBasepath,
|
'to' => $confBasepath,
|
||||||
]);
|
]);
|
||||||
$warningtext[] = DI::l10n()->t('Friendica\'s current system.basepath \'%s\' is not equal to the config file \'%s\'. Please fix your configuration.',
|
$warningtext[] = DI::l10n()->t(
|
||||||
|
'Friendica\'s current system.basepath \'%s\' is not equal to the config file \'%s\'. Please fix your configuration.',
|
||||||
$currBasepath,
|
$currBasepath,
|
||||||
$confBasepath);
|
$confBasepath
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +187,7 @@ class Summary extends BaseAdmin
|
||||||
'$platform' => App::PLATFORM,
|
'$platform' => App::PLATFORM,
|
||||||
'$codename' => App::CODENAME,
|
'$codename' => App::CODENAME,
|
||||||
'$build' => DI::config()->get('system', 'build'),
|
'$build' => DI::config()->get('system', 'build'),
|
||||||
'$addons' => [DI::l10n()->t('Active addons'), Addon::getEnabledList()],
|
'$addons' => [DI::l10n()->t('Active addons'), DI::addonHelper()->getEnabledAddons()],
|
||||||
'$serversettings' => $server_settings,
|
'$serversettings' => $server_settings,
|
||||||
'$warningtext' => $warningtext,
|
'$warningtext' => $warningtext,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Module;
|
namespace Friendica\Module;
|
||||||
|
|
||||||
use Friendica\BaseModule;
|
use Friendica\BaseModule;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Renderer;
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
|
@ -69,43 +68,53 @@ abstract class BaseAdmin extends BaseModule
|
||||||
// not part of $aside to make the template more adjustable
|
// not part of $aside to make the template more adjustable
|
||||||
$aside_sub = [
|
$aside_sub = [
|
||||||
'information' => [DI::l10n()->t('Information'), [
|
'information' => [DI::l10n()->t('Information'), [
|
||||||
'overview' => ['admin' , DI::l10n()->t('Overview') , 'overview'],
|
'overview' => ['admin' , DI::l10n()->t('Overview') , 'overview'],
|
||||||
'federation' => ['admin/federation' , DI::l10n()->t('Federation Statistics') , 'federation']
|
'federation' => ['admin/federation' , DI::l10n()->t('Federation Statistics') , 'federation']
|
||||||
]],
|
]],
|
||||||
'configuration' => [DI::l10n()->t('Configuration'), [
|
'configuration' => [DI::l10n()->t('Configuration'), [
|
||||||
'site' => ['admin/site' , DI::l10n()->t('Site') , 'site'],
|
'site' => ['admin/site' , DI::l10n()->t('Site') , 'site'],
|
||||||
'storage' => ['admin/storage' , DI::l10n()->t('Storage') , 'storage'],
|
'storage' => ['admin/storage' , DI::l10n()->t('Storage') , 'storage'],
|
||||||
'addons' => ['admin/addons' , DI::l10n()->t('Addons') , 'addons'],
|
'addons' => ['admin/addons' , DI::l10n()->t('Addons') , 'addons'],
|
||||||
'themes' => ['admin/themes' , DI::l10n()->t('Themes') , 'themes'],
|
'themes' => ['admin/themes' , DI::l10n()->t('Themes') , 'themes'],
|
||||||
'features' => ['admin/features' , DI::l10n()->t('Additional features') , 'features'],
|
'features' => ['admin/features' , DI::l10n()->t('Additional features') , 'features'],
|
||||||
'tos' => ['admin/tos' , DI::l10n()->t('Terms of Service') , 'tos'],
|
'tos' => ['admin/tos' , DI::l10n()->t('Terms of Service') , 'tos'],
|
||||||
]],
|
]],
|
||||||
'database' => [DI::l10n()->t('Database'), [
|
'database' => [DI::l10n()->t('Database'), [
|
||||||
'dbsync' => ['admin/dbsync' , DI::l10n()->t('DB updates') , 'dbsync'],
|
'dbsync' => ['admin/dbsync' , DI::l10n()->t('DB updates') , 'dbsync'],
|
||||||
'deferred' => ['admin/queue/deferred', DI::l10n()->t('Inspect Deferred Workers'), 'deferred'],
|
'deferred' => ['admin/queue/deferred', DI::l10n()->t('Inspect Deferred Workers'), 'deferred'],
|
||||||
'workerqueue' => ['admin/queue' , DI::l10n()->t('Inspect worker Queue') , 'workerqueue'],
|
'workerqueue' => ['admin/queue' , DI::l10n()->t('Inspect worker Queue') , 'workerqueue'],
|
||||||
]],
|
]],
|
||||||
'logs' => [DI::l10n()->t('Logs'), [
|
'logs' => [DI::l10n()->t('Logs'), [
|
||||||
'logsconfig' => ['admin/logs/', DI::l10n()->t('Logs') , 'logs'],
|
'logsconfig' => ['admin/logs/', DI::l10n()->t('Logs') , 'logs'],
|
||||||
'logsview' => ['admin/logs/view' , DI::l10n()->t('View Logs') , 'viewlogs'],
|
'logsview' => ['admin/logs/view' , DI::l10n()->t('View Logs') , 'viewlogs'],
|
||||||
]],
|
]],
|
||||||
'diagnostics' => [DI::l10n()->t('Diagnostics'), [
|
'diagnostics' => [DI::l10n()->t('Diagnostics'), [
|
||||||
'phpinfo' => ['admin/phpinfo?t=' . self::getFormSecurityToken('phpinfo'), DI::l10n()->t('PHP Info') , 'phpinfo'],
|
'phpinfo' => ['admin/phpinfo?t=' . self::getFormSecurityToken('phpinfo'), DI::l10n()->t('PHP Info') , 'phpinfo'],
|
||||||
'probe' => ['probe' , DI::l10n()->t('probe address') , 'probe'],
|
'probe' => ['probe' , DI::l10n()->t('probe address') , 'probe'],
|
||||||
'webfinger' => ['webfinger' , DI::l10n()->t('check webfinger') , 'webfinger'],
|
'webfinger' => ['webfinger' , DI::l10n()->t('check webfinger') , 'webfinger'],
|
||||||
'babel' => ['babel' , DI::l10n()->t('Babel') , 'babel'],
|
'babel' => ['babel' , DI::l10n()->t('Babel') , 'babel'],
|
||||||
'debug/ap' => ['debug/ap' , DI::l10n()->t('ActivityPub Conversion') , 'debug/ap'],
|
'debug/ap' => ['debug/ap' , DI::l10n()->t('ActivityPub Conversion') , 'debug/ap'],
|
||||||
]],
|
]],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$addons_admin = [];
|
||||||
|
|
||||||
|
foreach (DI::addonHelper()->getEnabledAddonsWithAdminSettings() as $addonId) {
|
||||||
|
$addons_admin[$addonId] = [
|
||||||
|
'url' => 'admin/addons/' . $addonId,
|
||||||
|
'name' => $addonId,
|
||||||
|
'class' => 'addon',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$t = Renderer::getMarkupTemplate('admin/aside.tpl');
|
$t = Renderer::getMarkupTemplate('admin/aside.tpl');
|
||||||
DI::page()['aside'] .= Renderer::replaceMacros($t, [
|
DI::page()['aside'] .= Renderer::replaceMacros($t, [
|
||||||
'$admin' => ['addons_admin' => Addon::getAdminList()],
|
'$admin' => ['addons_admin' => $addons_admin],
|
||||||
'$subpages' => $aside_sub,
|
'$subpages' => $aside_sub,
|
||||||
'$admtxt' => DI::l10n()->t('Admin'),
|
'$admtxt' => DI::l10n()->t('Admin'),
|
||||||
'$plugadmtxt' => DI::l10n()->t('Addon Features'),
|
'$plugadmtxt' => DI::l10n()->t('Addon Features'),
|
||||||
'$h_pending' => DI::l10n()->t('User registrations waiting for confirmation'),
|
'$h_pending' => DI::l10n()->t('User registrations waiting for confirmation'),
|
||||||
'$admurl' => 'admin/'
|
'$admurl' => 'admin/'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
|
|
|
@ -31,35 +31,35 @@ class BaseProfile extends BaseModule
|
||||||
|
|
||||||
$tabs = [
|
$tabs = [
|
||||||
[
|
[
|
||||||
'label' => DI::l10n()->t('Profile'),
|
'label' => DI::l10n()->t('Profile'),
|
||||||
'url' => $baseProfileUrl . '/profile',
|
'url' => $baseProfileUrl . '/profile',
|
||||||
'sel' => $current == 'profile' ? 'active' : '',
|
'sel' => $current == 'profile' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Profile Details'),
|
'title' => DI::l10n()->t('Profile Details'),
|
||||||
'id' => 'profile-tab',
|
'id' => 'profile-tab',
|
||||||
'accesskey' => 'r',
|
'accesskey' => 'r',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => DI::l10n()->t('Conversations'),
|
'label' => DI::l10n()->t('Conversations'),
|
||||||
'url' => $baseProfileUrl . '/conversations',
|
'url' => $baseProfileUrl . '/conversations',
|
||||||
'sel' => $current == 'status' ? 'active' : '',
|
'sel' => $current == 'status' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Conversations started'),
|
'title' => DI::l10n()->t('Conversations started'),
|
||||||
'id' => 'status-tab',
|
'id' => 'status-tab',
|
||||||
'accesskey' => 'm',
|
'accesskey' => 'm',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => DI::l10n()->t('Photos'),
|
'label' => DI::l10n()->t('Photos'),
|
||||||
'url' => $baseProfileUrl . '/photos',
|
'url' => $baseProfileUrl . '/photos',
|
||||||
'sel' => $current == 'photos' ? 'active' : '',
|
'sel' => $current == 'photos' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Photo Albums'),
|
'title' => DI::l10n()->t('Photo Albums'),
|
||||||
'id' => 'photo-tab',
|
'id' => 'photo-tab',
|
||||||
'accesskey' => 'h',
|
'accesskey' => 'h',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => DI::l10n()->t('Media'),
|
'label' => DI::l10n()->t('Media'),
|
||||||
'url' => $baseProfileUrl . '/media',
|
'url' => $baseProfileUrl . '/media',
|
||||||
'sel' => $current == 'media' ? 'active' : '',
|
'sel' => $current == 'media' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Media'),
|
'title' => DI::l10n()->t('Media'),
|
||||||
'id' => 'media-tab',
|
'id' => 'media-tab',
|
||||||
'accesskey' => 'd',
|
'accesskey' => 'd',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -67,22 +67,22 @@ class BaseProfile extends BaseModule
|
||||||
// the calendar link for the full-featured events calendar
|
// the calendar link for the full-featured events calendar
|
||||||
if ($is_owner) {
|
if ($is_owner) {
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'label' => DI::l10n()->t('Calendar'),
|
'label' => DI::l10n()->t('Calendar'),
|
||||||
'url' => DI::baseUrl() . '/calendar',
|
'url' => DI::baseUrl() . '/calendar',
|
||||||
'sel' => $current == 'calendar' ? 'active' : '',
|
'sel' => $current == 'calendar' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Calendar'),
|
'title' => DI::l10n()->t('Calendar'),
|
||||||
'id' => 'calendar-tab',
|
'id' => 'calendar-tab',
|
||||||
'accesskey' => 'c',
|
'accesskey' => 'c',
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
$owner = User::getByNickname($nickname, ['uid']);
|
$owner = User::getByNickname($nickname, ['uid']);
|
||||||
if(DI::userSession()->isAuthenticated() || $owner && Feature::isEnabled($owner['uid'], Feature::PUBLIC_CALENDAR)) {
|
if(DI::userSession()->isAuthenticated() || $owner && Feature::isEnabled($owner['uid'], Feature::PUBLIC_CALENDAR)) {
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'label' => DI::l10n()->t('Calendar'),
|
'label' => DI::l10n()->t('Calendar'),
|
||||||
'url' => DI::baseUrl() . '/calendar/show/' . $nickname,
|
'url' => DI::baseUrl() . '/calendar/show/' . $nickname,
|
||||||
'sel' => $current == 'calendar' ? 'active' : '',
|
'sel' => $current == 'calendar' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Calendar'),
|
'title' => DI::l10n()->t('Calendar'),
|
||||||
'id' => 'calendar-tab',
|
'id' => 'calendar-tab',
|
||||||
'accesskey' => 'c',
|
'accesskey' => 'c',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -90,30 +90,30 @@ class BaseProfile extends BaseModule
|
||||||
|
|
||||||
if ($is_owner) {
|
if ($is_owner) {
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'label' => DI::l10n()->t('Personal Notes'),
|
'label' => DI::l10n()->t('Personal Notes'),
|
||||||
'url' => DI::baseUrl() . '/notes',
|
'url' => DI::baseUrl() . '/notes',
|
||||||
'sel' => $current == 'notes' ? 'active' : '',
|
'sel' => $current == 'notes' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Only You Can See This'),
|
'title' => DI::l10n()->t('Only You Can See This'),
|
||||||
'id' => 'notes-tab',
|
'id' => 'notes-tab',
|
||||||
'accesskey' => 't',
|
'accesskey' => 't',
|
||||||
];
|
];
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'label' => DI::l10n()->t('Scheduled Posts'),
|
'label' => DI::l10n()->t('Scheduled Posts'),
|
||||||
'url' => $baseProfileUrl . '/schedule',
|
'url' => $baseProfileUrl . '/schedule',
|
||||||
'sel' => $current == 'schedule' ? 'active' : '',
|
'sel' => $current == 'schedule' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Posts that are scheduled for publishing'),
|
'title' => DI::l10n()->t('Posts that are scheduled for publishing'),
|
||||||
'id' => 'schedule-tab',
|
'id' => 'schedule-tab',
|
||||||
'accesskey' => 'o',
|
'accesskey' => 'o',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hide_friends) {
|
if (!$hide_friends) {
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'label' => DI::l10n()->t('Contacts'),
|
'label' => DI::l10n()->t('Contacts'),
|
||||||
'url' => $baseProfileUrl . '/contacts',
|
'url' => $baseProfileUrl . '/contacts',
|
||||||
'sel' => $current == 'contacts' ? 'active' : '',
|
'sel' => $current == 'contacts' ? 'active' : '',
|
||||||
'title' => DI::l10n()->t('Contacts'),
|
'title' => DI::l10n()->t('Contacts'),
|
||||||
'id' => 'viewcontacts-tab',
|
'id' => 'viewcontacts-tab',
|
||||||
'accesskey' => 'k',
|
'accesskey' => 'k',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -134,6 +134,6 @@ class BaseProfile extends BaseModule
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
|
|
||||||
return Renderer::replaceMacros($tpl, ['$tabs' => $arr['tabs']]);
|
return Renderer::replaceMacros($tpl, ['$tabs' => $arr['tabs'], '$more' => DI::l10n()->t('More')]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ class BaseSettings extends BaseModule
|
||||||
$tabs[] = [
|
$tabs[] = [
|
||||||
'label' => $this->t('Import Contacts'),
|
'label' => $this->t('Import Contacts'),
|
||||||
'url' => 'settings/importcontacts',
|
'url' => 'settings/importcontacts',
|
||||||
'selected' => static::class == Settings\UserExport::class ? 'active' : '',
|
'selected' => static::class == Settings\ContactImport::class ? 'active' : '',
|
||||||
'accesskey' => '',
|
'accesskey' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||||
use Friendica\Core\Theme;
|
use Friendica\Core\Theme;
|
||||||
use Friendica\Model\Event;
|
use Friendica\Model\Event;
|
||||||
use Friendica\Model\Profile;
|
use Friendica\Model\Profile;
|
||||||
use Friendica\Model\User;
|
|
||||||
use Friendica\Module\BaseProfile;
|
use Friendica\Module\BaseProfile;
|
||||||
use Friendica\Module\Response;
|
use Friendica\Module\Response;
|
||||||
use Friendica\Module\Security\Login;
|
use Friendica\Module\Security\Login;
|
||||||
|
@ -119,6 +118,8 @@ class Show extends BaseModule
|
||||||
'$week' => $this->t('week'),
|
'$week' => $this->t('week'),
|
||||||
'$day' => $this->t('day'),
|
'$day' => $this->t('day'),
|
||||||
'$list' => $this->t('list'),
|
'$list' => $this->t('list'),
|
||||||
|
'$prev' => $this->t('prev'),
|
||||||
|
'$next' => $this->t('next'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
|
|
|
@ -387,7 +387,7 @@ class Contact extends BaseModule
|
||||||
];
|
];
|
||||||
|
|
||||||
$tabs_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tabs_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
$tabs_html = Renderer::replaceMacros($tabs_tpl, ['$tabs' => $tabs]);
|
$tabs_html = Renderer::replaceMacros($tabs_tpl, ['$tabs' => $tabs, '$more' => DI::l10n()->t('More')]);
|
||||||
|
|
||||||
switch ($rel) {
|
switch ($rel) {
|
||||||
case 'followers':
|
case 'followers':
|
||||||
|
@ -534,7 +534,7 @@ class Contact extends BaseModule
|
||||||
}
|
}
|
||||||
|
|
||||||
$tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
$tab_str = Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs]);
|
$tab_str = Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs, '$more' => DI::l10n()->t('More')]);
|
||||||
|
|
||||||
return $tab_str;
|
return $tab_str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ class Channel extends Timeline
|
||||||
$tabs = array_merge($tabs, $this->getTabArray($this->community->getTimelines(true), 'channel'));
|
$tabs = array_merge($tabs, $this->getTabArray($this->community->getTimelines(true), 'channel'));
|
||||||
|
|
||||||
$tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
$o .= Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs]);
|
$o .= Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs, '$more' => $this->l10n->t('More')]);
|
||||||
|
|
||||||
Nav::setSelected('channel');
|
Nav::setSelected('channel');
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ class Channel extends Timeline
|
||||||
throw new HTTPException\BadRequestException($this->l10n->t('Channel not available.'));
|
throw new HTTPException\BadRequestException($this->l10n->t('Channel not available.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->maxId = $request['last_created'] ?? $this->maxId;
|
$this->maxId = $request['last_created'] ?? $this->maxId;
|
||||||
$this->minId = $request['first_created'] ?? $this->minId;
|
$this->minId = $request['first_created'] ?? $this->minId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,10 @@ class Community extends Timeline
|
||||||
|
|
||||||
$t = Renderer::getMarkupTemplate("community.tpl");
|
$t = Renderer::getMarkupTemplate("community.tpl");
|
||||||
$o = Renderer::replaceMacros($t, [
|
$o = Renderer::replaceMacros($t, [
|
||||||
'$content' => '',
|
'$content' => '',
|
||||||
'$header' => '',
|
'$header' => '',
|
||||||
'$show_global_community_hint' => ($this->selectedTab == CommunityEntity::GLOBAL) && $this->config->get('system', 'show_global_community_hint'),
|
'$show_global_community_hint' => ($this->selectedTab == CommunityEntity::GLOBAL) && $this->config->get('system', 'show_global_community_hint'),
|
||||||
'$global_community_hint' => $this->l10n->t("This community stream shows all public posts received by this node. They may not reflect the opinions of this node’s users.")
|
'$global_community_hint' => $this->l10n->t("This community stream shows all public posts received by this node. They may not reflect the opinions of this node’s users.")
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($this->pConfig->get($this->session->getLocalUserId(), 'system', 'infinite_scroll')) {
|
if ($this->pConfig->get($this->session->getLocalUserId(), 'system', 'infinite_scroll')) {
|
||||||
|
@ -88,7 +88,7 @@ class Community extends Timeline
|
||||||
if (!$this->raw) {
|
if (!$this->raw) {
|
||||||
$tabs = $this->getTabArray($this->community->getTimelines($this->session->isAuthenticated()), 'community');
|
$tabs = $this->getTabArray($this->community->getTimelines($this->session->isAuthenticated()), 'community');
|
||||||
$tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
$o .= Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs]);
|
$o .= Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs, '$more' => $this->l10n->t('More')]);
|
||||||
|
|
||||||
Nav::setSelected('community');
|
Nav::setSelected('community');
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ class Community extends Timeline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->maxId = $request['last_received'] ?? $this->maxId;
|
$this->maxId = $request['last_received'] ?? $this->maxId;
|
||||||
$this->minId = $request['first_received'] ?? $this->minId;
|
$this->minId = $request['first_received'] ?? $this->minId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,9 +192,9 @@ class Network extends Timeline
|
||||||
|
|
||||||
$x = [
|
$x = [
|
||||||
'lockstate' => $this->circleId || $this->network || ACL::getLockstateForUserId($this->session->getLocalUserId()) ? 'lock' : 'unlock',
|
'lockstate' => $this->circleId || $this->network || ACL::getLockstateForUserId($this->session->getLocalUserId()) ? 'lock' : 'unlock',
|
||||||
'acl' => ACL::getFullSelectorHTML($this->page, $this->session->getLocalUserId(), true, $default_permissions),
|
'acl' => ACL::getFullSelectorHTML($this->page, $this->session->getLocalUserId(), true, $default_permissions),
|
||||||
'bang' => (($this->circleId || $this->network) ? '!' : ''),
|
'bang' => (($this->circleId || $this->network) ? '!' : ''),
|
||||||
'content' => '',
|
'content' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$o .= $this->conversation->statusEditor($x);
|
$o .= $this->conversation->statusEditor($x);
|
||||||
|
@ -236,7 +236,7 @@ class Network extends Timeline
|
||||||
$pager = new BoundariesPager(
|
$pager = new BoundariesPager(
|
||||||
$this->l10n,
|
$this->l10n,
|
||||||
$this->args->getQueryString(),
|
$this->args->getQueryString(),
|
||||||
$items[0][$this->order] ?? null,
|
$items[0][$this->order] ?? null,
|
||||||
$items[count($items) - 1][$this->order] ?? null,
|
$items[count($items) - 1][$this->order] ?? null,
|
||||||
$this->itemsPerPage
|
$this->itemsPerPage
|
||||||
);
|
);
|
||||||
|
@ -292,7 +292,7 @@ class Network extends Timeline
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
|
|
||||||
return Renderer::replaceMacros($tpl, ['$tabs' => $tabs]);
|
return Renderer::replaceMacros($tpl, ['$tabs' => $tabs, '$more' => $this->l10n->t('More')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parseRequest(array $request)
|
protected function parseRequest(array $request)
|
||||||
|
@ -313,23 +313,23 @@ class Network extends Timeline
|
||||||
|
|
||||||
if (!empty($request['star'])) {
|
if (!empty($request['star'])) {
|
||||||
$this->selectedTab = NetworkEntity::STAR;
|
$this->selectedTab = NetworkEntity::STAR;
|
||||||
$this->star = true;
|
$this->star = true;
|
||||||
} else {
|
} else {
|
||||||
$this->star = $this->selectedTab == NetworkEntity::STAR;
|
$this->star = $this->selectedTab == NetworkEntity::STAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($request['mention'])) {
|
if (!empty($request['mention'])) {
|
||||||
$this->selectedTab = NetworkEntity::MENTION;
|
$this->selectedTab = NetworkEntity::MENTION;
|
||||||
$this->mention = true;
|
$this->mention = true;
|
||||||
} else {
|
} else {
|
||||||
$this->mention = $this->selectedTab == NetworkEntity::MENTION;
|
$this->mention = $this->selectedTab == NetworkEntity::MENTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($request['order'])) {
|
if (!empty($request['order'])) {
|
||||||
$this->selectedTab = $request['order'];
|
$this->selectedTab = $request['order'];
|
||||||
$this->order = $request['order'];
|
$this->order = $request['order'];
|
||||||
$this->star = false;
|
$this->star = false;
|
||||||
$this->mention = false;
|
$this->mention = false;
|
||||||
} elseif (in_array($this->selectedTab, [NetworkEntity::RECEIVED, NetworkEntity::STAR]) || $this->community->isTimeline($this->selectedTab)) {
|
} elseif (in_array($this->selectedTab, [NetworkEntity::RECEIVED, NetworkEntity::STAR]) || $this->community->isTimeline($this->selectedTab)) {
|
||||||
$this->order = 'received';
|
$this->order = 'received';
|
||||||
} elseif (($this->selectedTab == NetworkEntity::CREATED) || $this->channel->isTimeline($this->selectedTab) || $this->userDefinedChannel->isTimeline($this->selectedTab, $this->session->getLocalUserId())) {
|
} elseif (($this->selectedTab == NetworkEntity::CREATED) || $this->channel->isTimeline($this->selectedTab) || $this->userDefinedChannel->isTimeline($this->selectedTab, $this->session->getLocalUserId())) {
|
||||||
|
@ -344,7 +344,8 @@ class Network extends Timeline
|
||||||
// since otherwise the feed will optically jump, when some already visible thread has been updated.
|
// since otherwise the feed will optically jump, when some already visible thread has been updated.
|
||||||
if ($this->update && ($this->selectedTab == NetworkEntity::COMMENTED)) {
|
if ($this->update && ($this->selectedTab == NetworkEntity::COMMENTED)) {
|
||||||
$this->order = 'received';
|
$this->order = 'received';
|
||||||
$request['last_received'] = $request['last_commented'] ?? null;
|
|
||||||
|
$request['last_received'] = $request['last_commented'] ?? null;
|
||||||
$request['first_received'] = $request['first_commented'] ?? null;
|
$request['first_received'] = $request['first_commented'] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +362,7 @@ class Network extends Timeline
|
||||||
$this->network = $request['nets'] ?? '';
|
$this->network = $request['nets'] ?? '';
|
||||||
|
|
||||||
$this->dateFrom = $this->parameters['from'] ?? '';
|
$this->dateFrom = $this->parameters['from'] ?? '';
|
||||||
$this->dateTo = $this->parameters['to'] ?? '';
|
$this->dateTo = $this->parameters['to'] ?? '';
|
||||||
|
|
||||||
$this->setMaxMinByOrder($request);
|
$this->setMaxMinByOrder($request);
|
||||||
|
|
||||||
|
|
|
@ -150,20 +150,20 @@ class Timeline extends BaseModule
|
||||||
{
|
{
|
||||||
switch ($this->order) {
|
switch ($this->order) {
|
||||||
case 'received':
|
case 'received':
|
||||||
$this->maxId = $request['last_received'] ?? $this->maxId;
|
$this->maxId = $request['last_received'] ?? $this->maxId;
|
||||||
$this->minId = $request['first_received'] ?? $this->minId;
|
$this->minId = $request['first_received'] ?? $this->minId;
|
||||||
break;
|
break;
|
||||||
case 'created':
|
case 'created':
|
||||||
$this->maxId = $request['last_created'] ?? $this->maxId;
|
$this->maxId = $request['last_created'] ?? $this->maxId;
|
||||||
$this->minId = $request['first_created'] ?? $this->minId;
|
$this->minId = $request['first_created'] ?? $this->minId;
|
||||||
break;
|
break;
|
||||||
case 'uri-id':
|
case 'uri-id':
|
||||||
$this->maxId = $request['last_uriid'] ?? $this->maxId;
|
$this->maxId = $request['last_uriid'] ?? $this->maxId;
|
||||||
$this->minId = $request['first_uriid'] ?? $this->minId;
|
$this->minId = $request['first_uriid'] ?? $this->minId;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->order = 'commented';
|
$this->order = 'commented';
|
||||||
$this->maxId = $request['last_commented'] ?? $this->maxId;
|
$this->maxId = $request['last_commented'] ?? $this->maxId;
|
||||||
$this->minId = $request['first_commented'] ?? $this->minId;
|
$this->minId = $request['first_commented'] ?? $this->minId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,8 +256,8 @@ class Timeline extends BaseModule
|
||||||
|
|
||||||
while (count($selected_items) < $total && ++$count < 50 && count($items) > 0) {
|
while (count($selected_items) < $total && ++$count < 50 && count($items) > 0) {
|
||||||
$maxposts = round((count($items) / $total) * $maxpostperauthor);
|
$maxposts = round((count($items) / $total) * $maxpostperauthor);
|
||||||
$minId = $items[array_key_first($items)][$this->order];
|
$minId = $items[array_key_first($items)][$this->order];
|
||||||
$maxId = $items[array_key_last($items)][$this->order];
|
$maxId = $items[array_key_last($items)][$this->order];
|
||||||
|
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
if (!in_array($item['owner-id'], $reduced)) {
|
if (!in_array($item['owner-id'], $reduced)) {
|
||||||
|
@ -373,9 +373,9 @@ class Timeline extends BaseModule
|
||||||
} elseif (is_numeric($this->selectedTab) && !empty($channel = $this->channelRepository->selectById($this->selectedTab, $uid))) {
|
} elseif (is_numeric($this->selectedTab) && !empty($channel = $this->channelRepository->selectById($this->selectedTab, $uid))) {
|
||||||
$condition = $this->getUserChannelConditions($channel, $uid);
|
$condition = $this->getUserChannelConditions($channel, $uid);
|
||||||
if (in_array($channel->circle, [-3, -4, -5])) {
|
if (in_array($channel->circle, [-3, -4, -5])) {
|
||||||
$table = SearchIndex::getSearchView();
|
$table = SearchIndex::getSearchView();
|
||||||
$condition = DBA::mergeConditions($condition, ['uid' => $uid]);
|
$condition = DBA::mergeConditions($condition, ['uid' => $uid]);
|
||||||
$orders = ['-3' => 'created', '-4' => 'received', '-5' => 'commented'];
|
$orders = ['-3' => 'created', '-4' => 'received', '-5' => 'commented'];
|
||||||
$this->order = $orders[$channel->circle];
|
$this->order = $orders[$channel->circle];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,10 +421,10 @@ class Timeline extends BaseModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
$fields = ['uri-id', 'owner-id', 'comments', 'activities'];
|
$fields = ['uri-id', 'owner-id', 'comments', 'activities'];
|
||||||
$fields[] = $this->order;
|
$fields[] = $this->order;
|
||||||
$result = $this->database->select($table, $fields, $condition, $params);
|
$result = $this->database->select($table, $fields, $condition, $params);
|
||||||
if ($this->database->errorNo()) {
|
if ($this->database->errorNo()) {
|
||||||
throw new \Exception($this->database->errorMessage(), $this->database->errorNo());
|
throw new \Exception($this->database->errorMessage(), $this->database->errorNo());
|
||||||
}
|
}
|
||||||
|
@ -691,16 +691,19 @@ class Timeline extends BaseModule
|
||||||
$items = $this->selectItems();
|
$items = $this->selectItems();
|
||||||
$key = '';
|
$key = '';
|
||||||
|
|
||||||
|
$maxpostperauthor = 0;
|
||||||
if ($this->selectedTab == Community::LOCAL) {
|
if ($this->selectedTab == Community::LOCAL) {
|
||||||
$maxpostperauthor = (int)$this->config->get('system', 'max_author_posts_community_page');
|
$maxpostperauthor = (int)$this->config->get('system', 'max_author_posts_community_page');
|
||||||
$key = 'author-id';
|
$key = 'author-id';
|
||||||
} elseif ($this->selectedTab == Community::GLOBAL) {
|
} elseif ($this->selectedTab == Community::GLOBAL) {
|
||||||
$maxpostperauthor = (int)$this->config->get('system', 'max_server_posts_community_page');
|
$maxpostperauthor = (int)$this->config->get('system', 'max_server_posts_community_page');
|
||||||
$key = 'author-gsid';
|
$key = 'author-gsid';
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if ($maxpostperauthor === 0) {
|
||||||
$this->setItemsSeenByCondition([
|
$this->setItemsSeenByCondition([
|
||||||
'unseen' => true,
|
'unseen' => true,
|
||||||
'uid' => $this->session->getLocalUserId(),
|
'uid' => $this->session->getLocalUserId(),
|
||||||
'parent-uri-id' => array_column($items, 'uri-id')
|
'parent-uri-id' => array_column($items, 'uri-id')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -713,8 +716,8 @@ class Timeline extends BaseModule
|
||||||
|
|
||||||
while (count($selected_items) < $this->itemsPerPage && ++$count < 50 && count($items) > 0) {
|
while (count($selected_items) < $this->itemsPerPage && ++$count < 50 && count($items) > 0) {
|
||||||
$maxposts = round((count($items) / $this->itemsPerPage) * $maxpostperauthor);
|
$maxposts = round((count($items) / $this->itemsPerPage) * $maxpostperauthor);
|
||||||
$minId = $items[array_key_first($items)]['received'];
|
$minId = $items[array_key_first($items)]['received'];
|
||||||
$maxId = $items[array_key_last($items)]['received'];
|
$maxId = $items[array_key_last($items)]['received'];
|
||||||
|
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$author_posts[$item[$key]][$item['uri-id']] = $item['received'];
|
$author_posts[$item[$key]][$item['uri-id']] = $item['received'];
|
||||||
|
@ -799,7 +802,7 @@ class Timeline extends BaseModule
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
if ($this->selectedTab == Community::LOCAL) {
|
if ($this->selectedTab == Community::LOCAL) {
|
||||||
$result = Post::selectOriginThread(['uri-id', 'received', 'author-id', 'author-gsid'], $condition, $params);
|
$result = Post::selectOriginThread(['uri-id', 'received', 'author-id', 'author-gsid'], $condition, $params);
|
||||||
} else {
|
} else {
|
||||||
$result = Post::selectThreadForUser($this->session->getLocalUserId() ?: 0, ['uri-id', 'received', 'author-id', 'author-gsid'], $condition, $params);
|
$result = Post::selectThreadForUser($this->session->getLocalUserId() ?: 0, ['uri-id', 'received', 'author-id', 'author-gsid'], $condition, $params);
|
||||||
|
|
|
@ -56,7 +56,7 @@ class SaveTag extends BaseModule
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate("filer_dialog.tpl");
|
$tpl = Renderer::getMarkupTemplate("filer_dialog.tpl");
|
||||||
echo Renderer::replaceMacros($tpl, [
|
echo Renderer::replaceMacros($tpl, [
|
||||||
'$field' => ['term', $this->t("Save to Folder:"), '', '', $filetags, $this->t('- select -')],
|
'$field' => ['term', $this->t("Folder:"), '', '', $filetags, $this->t('- select -')],
|
||||||
'$submit' => $this->t('Save'),
|
'$submit' => $this->t('Save'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use Friendica\App;
|
||||||
use Friendica\App\Arguments;
|
use Friendica\App\Arguments;
|
||||||
use Friendica\App\BaseURL;
|
use Friendica\App\BaseURL;
|
||||||
use Friendica\BaseModule;
|
use Friendica\BaseModule;
|
||||||
use Friendica\Core\Addon;
|
use Friendica\Core\Addon\AddonHelper;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
|
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
|
||||||
|
@ -31,6 +31,7 @@ use Psr\Log\LoggerInterface;
|
||||||
*/
|
*/
|
||||||
class Friendica extends BaseModule
|
class Friendica extends BaseModule
|
||||||
{
|
{
|
||||||
|
private AddonHelper $addonHelper;
|
||||||
/** @var IManageConfigValues */
|
/** @var IManageConfigValues */
|
||||||
private $config;
|
private $config;
|
||||||
/** @var IManageKeyValuePairs */
|
/** @var IManageKeyValuePairs */
|
||||||
|
@ -38,18 +39,19 @@ class Friendica extends BaseModule
|
||||||
/** @var IHandleUserSessions */
|
/** @var IHandleUserSessions */
|
||||||
private $session;
|
private $session;
|
||||||
|
|
||||||
public function __construct(IHandleUserSessions $session, IManageKeyValuePairs $keyValue, IManageConfigValues $config, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
|
public function __construct(AddonHelper $addonHelper, IHandleUserSessions $session, IManageKeyValuePairs $keyValue, IManageConfigValues $config, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
|
||||||
{
|
{
|
||||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||||
|
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->keyValue = $keyValue;
|
$this->keyValue = $keyValue;
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
|
$this->addonHelper = $addonHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function content(array $request = []): string
|
protected function content(array $request = []): string
|
||||||
{
|
{
|
||||||
$visibleAddonList = Addon::getVisibleList();
|
$visibleAddonList = $this->addonHelper->getVisibleEnabledAddons();
|
||||||
if (!empty($visibleAddonList)) {
|
if (!empty($visibleAddonList)) {
|
||||||
|
|
||||||
$sorted = $visibleAddonList;
|
$sorted = $visibleAddonList;
|
||||||
|
@ -83,8 +85,8 @@ class Friendica extends BaseModule
|
||||||
|
|
||||||
if (!empty($blockList) && ($this->config->get('blocklist', 'public') || $this->session->isAuthenticated())) {
|
if (!empty($blockList) && ($this->config->get('blocklist', 'public') || $this->session->isAuthenticated())) {
|
||||||
$blocked = [
|
$blocked = [
|
||||||
'title' => $this->t('On this server the following remote servers are blocked.'),
|
'title' => $this->t('On this server the following remote servers are blocked.'),
|
||||||
'header' => [
|
'header' => [
|
||||||
$this->t('Blocked domain'),
|
$this->t('Blocked domain'),
|
||||||
$this->t('Reason for the block'),
|
$this->t('Reason for the block'),
|
||||||
],
|
],
|
||||||
|
@ -102,11 +104,13 @@ class Friendica extends BaseModule
|
||||||
$tpl = Renderer::getMarkupTemplate('friendica.tpl');
|
$tpl = Renderer::getMarkupTemplate('friendica.tpl');
|
||||||
|
|
||||||
return Renderer::replaceMacros($tpl, [
|
return Renderer::replaceMacros($tpl, [
|
||||||
'about' => $this->t('This is Friendica, version %s that is running at the web location %s. The database version is %s, the post update version is %s.',
|
'about' => $this->t(
|
||||||
|
'This is Friendica, version %s that is running at the web location %s. The database version is %s, the post update version is %s.',
|
||||||
'<strong>' . App::VERSION . '</strong>',
|
'<strong>' . App::VERSION . '</strong>',
|
||||||
$this->baseUrl,
|
$this->baseUrl,
|
||||||
'<strong>' . $this->config->get('system', 'build') . '/' . DB_UPDATE_VERSION . '</strong>',
|
'<strong>' . $this->config->get('system', 'build') . '/' . DB_UPDATE_VERSION . '</strong>',
|
||||||
'<strong>' . $this->keyValue->get('post_update_version') . '/' . PostUpdate::VERSION . '</strong>'),
|
'<strong>' . $this->keyValue->get('post_update_version') . '/' . PostUpdate::VERSION . '</strong>'
|
||||||
|
),
|
||||||
'friendica' => $this->t('Please visit <a href="https://friendi.ca">Friendi.ca</a> to learn more about the Friendica project.'),
|
'friendica' => $this->t('Please visit <a href="https://friendi.ca">Friendi.ca</a> to learn more about the Friendica project.'),
|
||||||
'bugs' => $this->t('Bug reports and issues: please visit') . ' ' . '<a href="https://github.com/friendica/friendica/issues?state=open">' . $this->t('the bugtracker at github') . '</a>',
|
'bugs' => $this->t('Bug reports and issues: please visit') . ' ' . '<a href="https://github.com/friendica/friendica/issues?state=open">' . $this->t('the bugtracker at github') . '</a>',
|
||||||
'info' => $this->t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'),
|
'info' => $this->t('Suggestions, praise, etc. - please email "info" at "friendi - dot - ca'),
|
||||||
|
@ -148,7 +152,7 @@ class Friendica extends BaseModule
|
||||||
$register_policy = $register_policies[$register_policy_int];
|
$register_policy = $register_policies[$register_policy_int];
|
||||||
}
|
}
|
||||||
|
|
||||||
$admin = [];
|
$admin = [];
|
||||||
$administrator = User::getFirstAdmin(['username', 'nickname']);
|
$administrator = User::getFirstAdmin(['username', 'nickname']);
|
||||||
if (!empty($administrator)) {
|
if (!empty($administrator)) {
|
||||||
$admin = [
|
$admin = [
|
||||||
|
@ -157,11 +161,11 @@ class Friendica extends BaseModule
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$visible_addons = Addon::getVisibleList();
|
$visible_addons = $this->addonHelper->getVisibleEnabledAddons();
|
||||||
|
|
||||||
$this->config->reload();
|
$this->config->reload();
|
||||||
$locked_features = [];
|
$locked_features = [];
|
||||||
$featureLocks = $this->config->get('config', 'feature_lock');
|
$featureLocks = $this->config->get('config', 'feature_lock');
|
||||||
if (isset($featureLocks)) {
|
if (isset($featureLocks)) {
|
||||||
foreach ($featureLocks as $feature => $lock) {
|
foreach ($featureLocks as $feature => $lock) {
|
||||||
if ($feature === 'config_loaded') {
|
if ($feature === 'config_loaded') {
|
||||||
|
|
|
@ -235,22 +235,22 @@ class Install extends BaseModule
|
||||||
'$system_url' => $this->configCache->get('system', 'url'),
|
'$system_url' => $this->configCache->get('system', 'url'),
|
||||||
'$dbhost' => ['database-hostname',
|
'$dbhost' => ['database-hostname',
|
||||||
$this->t('Database Server Name'),
|
$this->t('Database Server Name'),
|
||||||
$this->configCache->get('database', 'hostname'),
|
$this->configCache->get('database', 'hostname') ? : getenv('MYSQL_HOST') ? : 'localhost',
|
||||||
'',
|
'',
|
||||||
$this->t('Required')],
|
$this->t('Required')],
|
||||||
'$dbuser' => ['database-username',
|
'$dbuser' => ['database-username',
|
||||||
$this->t('Database Login Name'),
|
$this->t('Database Login Name'),
|
||||||
$this->configCache->get('database', 'username'),
|
$this->configCache->get('database', 'username') ? : getenv('MYSQL_USER') ? : '',
|
||||||
'',
|
'',
|
||||||
$this->t('Required'),
|
$this->t('Required'),
|
||||||
'autofocus'],
|
'autofocus'],
|
||||||
'$dbpass' => ['database-password',
|
'$dbpass' => ['database-password',
|
||||||
$this->t('Database Login Password'),
|
$this->t('Database Login Password'),
|
||||||
$this->configCache->get('database', 'password'),
|
$this->configCache->get('database', 'password') ? : getenv('MYSQL_PASSWORD') ? : '',
|
||||||
$this->t("For security reasons the password must not be empty"),
|
$this->t("For security reasons the password must not be empty"),
|
||||||
$this->t('Required')],
|
$this->t('Required')],
|
||||||
'$dbdata' => ['database-database',
|
'$dbdata' => ['database-database',
|
||||||
$this->t('Database Name'),
|
$this->t('Database Name') ? : getenv('MYSQL_DATABASE') ? : '',
|
||||||
$this->configCache->get('database', 'database'),
|
$this->configCache->get('database', 'database'),
|
||||||
'',
|
'',
|
||||||
$this->t('Required')],
|
$this->t('Required')],
|
||||||
|
|
|
@ -99,7 +99,7 @@ abstract class BaseUsers extends BaseModeration
|
||||||
Hook::callAll('moderation_users_tabs', $tabs_arr);
|
Hook::callAll('moderation_users_tabs', $tabs_arr);
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
|
||||||
return Renderer::replaceMacros($tpl, ['$tabs' => $tabs_arr['tabs']]);
|
return Renderer::replaceMacros($tpl, ['$tabs' => $tabs_arr['tabs'], '$more' => $this->t('More')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setupUserCallback(): \Closure
|
protected function setupUserCallback(): \Closure
|
||||||
|
|
|
@ -124,8 +124,8 @@ class Active extends BaseUsers
|
||||||
*/
|
*/
|
||||||
private function processGetActions(): void
|
private function processGetActions(): void
|
||||||
{
|
{
|
||||||
$action = (string)$this->parameters['action'] ?? '';
|
$action = (string) ($this->parameters['action'] ?? '');
|
||||||
$uid = (int)$this->parameters['uid'] ?? 0;
|
$uid = (int) ($this->parameters['uid'] ?? 0);
|
||||||
|
|
||||||
if ($uid === 0) {
|
if ($uid === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -150,6 +150,7 @@ class Active extends BaseUsers
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->baseUrl->redirect('moderation/users/active');
|
$this->baseUrl->redirect('moderation/users/active');
|
||||||
|
// no break
|
||||||
case 'block':
|
case 'block':
|
||||||
self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't');
|
self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't');
|
||||||
User::block($uid);
|
User::block($uid);
|
||||||
|
|
|
@ -123,8 +123,8 @@ class Blocked extends BaseUsers
|
||||||
*/
|
*/
|
||||||
private function processGetActions(): void
|
private function processGetActions(): void
|
||||||
{
|
{
|
||||||
$action = (string)$this->parameters['action'] ?? '';
|
$action = (string) ($this->parameters['action'] ?? '');
|
||||||
$uid = (int)$this->parameters['uid'] ?? 0;
|
$uid = (int) ($this->parameters['uid'] ?? 0);
|
||||||
|
|
||||||
if ($uid === 0) {
|
if ($uid === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -148,6 +148,7 @@ class Blocked extends BaseUsers
|
||||||
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
|
$this->systemMessages->addNotice($this->t('You can\'t remove yourself'));
|
||||||
}
|
}
|
||||||
$this->baseUrl->redirect('moderation/users/blocked');
|
$this->baseUrl->redirect('moderation/users/blocked');
|
||||||
|
// no break
|
||||||
case 'unblock':
|
case 'unblock':
|
||||||
self::checkFormSecurityTokenRedirectOnError('/moderation/users/blocked', 'moderation_users_blocked', 't');
|
self::checkFormSecurityTokenRedirectOnError('/moderation/users/blocked', 'moderation_users_blocked', 't');
|
||||||
User::block($uid, false);
|
User::block($uid, false);
|
||||||
|
|
|
@ -135,8 +135,8 @@ class Index extends BaseUsers
|
||||||
*/
|
*/
|
||||||
private function processGetActions(): void
|
private function processGetActions(): void
|
||||||
{
|
{
|
||||||
$action = (string) $this->parameters['action'] ?? '';
|
$action = (string) ($this->parameters['action'] ?? '');
|
||||||
$uid = (int) $this->parameters['uid'] ?? 0;
|
$uid = (int) ($this->parameters['uid'] ?? 0);
|
||||||
|
|
||||||
if ($uid === 0) {
|
if ($uid === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -161,11 +161,13 @@ class Index extends BaseUsers
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->baseUrl->redirect('moderation/users');
|
$this->baseUrl->redirect('moderation/users');
|
||||||
|
// no break
|
||||||
case 'block':
|
case 'block':
|
||||||
self::checkFormSecurityTokenRedirectOnError('moderation/users', 'moderation_users', 't');
|
self::checkFormSecurityTokenRedirectOnError('moderation/users', 'moderation_users', 't');
|
||||||
User::block($uid);
|
User::block($uid);
|
||||||
$this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username']));
|
$this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username']));
|
||||||
$this->baseUrl->redirect('moderation/users');
|
$this->baseUrl->redirect('moderation/users');
|
||||||
|
// no break
|
||||||
case 'unblock':
|
case 'unblock':
|
||||||
self::checkFormSecurityTokenRedirectOnError('moderation/users', 'moderation_users', 't');
|
self::checkFormSecurityTokenRedirectOnError('moderation/users', 'moderation_users', 't');
|
||||||
User::block($uid, false);
|
User::block($uid, false);
|
||||||
|
|
|
@ -148,8 +148,8 @@ class Register extends BaseModule
|
||||||
'$fillext' => $fillext,
|
'$fillext' => $fillext,
|
||||||
'$oidlabel' => $oidlabel,
|
'$oidlabel' => $oidlabel,
|
||||||
'$openid' => $openid_url,
|
'$openid' => $openid_url,
|
||||||
'$namelabel' => DI::l10n()->t('Your Display Name (as you would like it to be displayed on this system'),
|
'$namelabel' => DI::l10n()->t('Your Display Name (as you would like it to be displayed on this system):'),
|
||||||
'$addrlabel' => DI::l10n()->t('Your Email Address: (Initial information will be send there, so this has to be an existing address.)'),
|
'$addrlabel' => DI::l10n()->t('Your Email Address (initial information will be sent there, so this must be a valid address):'),
|
||||||
'$addrlabel2' => DI::l10n()->t('Please repeat your e-mail address:'),
|
'$addrlabel2' => DI::l10n()->t('Please repeat your e-mail address:'),
|
||||||
'$ask_password' => $ask_password,
|
'$ask_password' => $ask_password,
|
||||||
'$password1' => ['password1', DI::l10n()->t('New Password:'), '', DI::l10n()->t('Leave empty for an auto generated password.')],
|
'$password1' => ['password1', DI::l10n()->t('New Password:'), '', DI::l10n()->t('Leave empty for an auto generated password.')],
|
||||||
|
|
|
@ -127,7 +127,7 @@ class Channels extends BaseSettings
|
||||||
throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
|
throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::getById($uid, ['account-type']);
|
$user = User::getById($uid, ['account-type']);
|
||||||
$account_type = $user['account-type'];
|
$account_type = $user['account-type'];
|
||||||
|
|
||||||
if (in_array($account_type, [User::ACCOUNT_TYPE_COMMUNITY, User::ACCOUNT_TYPE_RELAY])) {
|
if (in_array($account_type, [User::ACCOUNT_TYPE_COMMUNITY, User::ACCOUNT_TYPE_RELAY])) {
|
||||||
|
@ -151,7 +151,7 @@ class Channels extends BaseSettings
|
||||||
$circles[$circle['id']] = $circle['name'];
|
$circles[$circle['id']] = $circle['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$languages = $this->l10n->getLanguageCodes(true);
|
$languages = $this->l10n->getLanguageCodes(true);
|
||||||
$channel_languages = User::getWantedLanguages($uid);
|
$channel_languages = User::getWantedLanguages($uid);
|
||||||
|
|
||||||
$channels = [];
|
$channels = [];
|
||||||
|
@ -185,7 +185,7 @@ class Channels extends BaseSettings
|
||||||
'image' => ["image[$channel->code]", $this->t("Images"), $channel->mediaType & 1],
|
'image' => ["image[$channel->code]", $this->t("Images"), $channel->mediaType & 1],
|
||||||
'video' => ["video[$channel->code]", $this->t("Videos"), $channel->mediaType & 2],
|
'video' => ["video[$channel->code]", $this->t("Videos"), $channel->mediaType & 2],
|
||||||
'audio' => ["audio[$channel->code]", $this->t("Audio"), $channel->mediaType & 4],
|
'audio' => ["audio[$channel->code]", $this->t("Audio"), $channel->mediaType & 4],
|
||||||
'languages' => ["languages[$channel->code][]", $this->t('Languages'), $channel->languages ?? $channel_languages, $this->t('Select all languages that you want to see in this channel.'), $languages, 'multiple'],
|
'languages' => ["languages[$channel->code][]", $this->t('Languages'), $channel->languages ?? $channel_languages, $this->t('Select all languages that you want to see in this channel. "Unspecified" describes all posts for which no language information was detected (e.g. posts with just an image or too little text to be sure of the language). If you want to see all languages, you will need to select all items in the list.'), $languages, 'multiple'],
|
||||||
'publish' => $publish,
|
'publish' => $publish,
|
||||||
'delete' => ["delete[$channel->code]", $this->t("Delete channel") . ' (' . $channel->label . ')', false, $this->t("Check to delete this entry from the channel list")]
|
'delete' => ["delete[$channel->code]", $this->t("Delete channel") . ' (' . $channel->label . ')', false, $this->t("Check to delete this entry from the channel list")]
|
||||||
];
|
];
|
||||||
|
|
|
@ -103,13 +103,7 @@ class Display extends BaseSettings
|
||||||
$show_page_drop = (bool)$request['show_page_drop'];
|
$show_page_drop = (bool)$request['show_page_drop'];
|
||||||
$display_eventlist = (bool)$request['display_eventlist'];
|
$display_eventlist = (bool)$request['display_eventlist'];
|
||||||
$preview_mode = (int)$request['preview_mode'];
|
$preview_mode = (int)$request['preview_mode'];
|
||||||
$browser_update = (int)$request['browser_update'];
|
$update_content = (int)$request['update_content'];
|
||||||
if ($browser_update != -1) {
|
|
||||||
$browser_update = $browser_update * 1000;
|
|
||||||
if ($browser_update < 10000) {
|
|
||||||
$browser_update = 10000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$enabled_timelines = [];
|
$enabled_timelines = [];
|
||||||
foreach ($enable as $code => $enabled) {
|
foreach ($enable as $code => $enabled) {
|
||||||
|
@ -144,7 +138,7 @@ class Display extends BaseSettings
|
||||||
|
|
||||||
$this->pConfig->set($uid, 'system', 'itemspage_network', $itemspage_network);
|
$this->pConfig->set($uid, 'system', 'itemspage_network', $itemspage_network);
|
||||||
$this->pConfig->set($uid, 'system', 'itemspage_mobile_network', $itemspage_mobile_network);
|
$this->pConfig->set($uid, 'system', 'itemspage_mobile_network', $itemspage_mobile_network);
|
||||||
$this->pConfig->set($uid, 'system', 'update_interval', $browser_update);
|
$this->pConfig->set($uid, 'system', 'update_content', $update_content);
|
||||||
$this->pConfig->set($uid, 'system', 'no_smilies', !$enable_smile);
|
$this->pConfig->set($uid, 'system', 'no_smilies', !$enable_smile);
|
||||||
$this->pConfig->set($uid, 'system', 'infinite_scroll', $infinite_scroll);
|
$this->pConfig->set($uid, 'system', 'infinite_scroll', $infinite_scroll);
|
||||||
$this->pConfig->set($uid, 'system', 'no_smart_threading', !$enable_smart_threading);
|
$this->pConfig->set($uid, 'system', 'no_smart_threading', !$enable_smart_threading);
|
||||||
|
@ -208,7 +202,7 @@ class Display extends BaseSettings
|
||||||
|
|
||||||
$allowed_themes = Theme::getAllowedList();
|
$allowed_themes = Theme::getAllowedList();
|
||||||
|
|
||||||
$themes = [];
|
$themes = [];
|
||||||
$mobile_themes = ['---' => $this->t('No special theme for mobile devices')];
|
$mobile_themes = ['---' => $this->t('No special theme for mobile devices')];
|
||||||
foreach ($allowed_themes as $theme) {
|
foreach ($allowed_themes as $theme) {
|
||||||
$is_experimental = file_exists('view/theme/' . $theme . '/experimental');
|
$is_experimental = file_exists('view/theme/' . $theme . '/experimental');
|
||||||
|
@ -233,29 +227,25 @@ class Display extends BaseSettings
|
||||||
$theme_selected = $user['theme'] ?: $default_theme;
|
$theme_selected = $user['theme'] ?: $default_theme;
|
||||||
$mobile_theme_selected = $this->session->get('mobile-theme', $default_mobile_theme);
|
$mobile_theme_selected = $this->session->get('mobile-theme', $default_mobile_theme);
|
||||||
|
|
||||||
$itemspage_network = intval($this->pConfig->get($uid, 'system', 'itemspage_network'));
|
$itemspage_network = intval($this->pConfig->get($uid, 'system', 'itemspage_network'));
|
||||||
$itemspage_network = (($itemspage_network > 0 && $itemspage_network < 101) ? $itemspage_network : $this->config->get('system', 'itemspage_network'));
|
$itemspage_network = (($itemspage_network > 0 && $itemspage_network < 101) ? $itemspage_network : $this->config->get('system', 'itemspage_network'));
|
||||||
$itemspage_mobile_network = intval($this->pConfig->get($uid, 'system', 'itemspage_mobile_network'));
|
$itemspage_mobile_network = intval($this->pConfig->get($uid, 'system', 'itemspage_mobile_network'));
|
||||||
$itemspage_mobile_network = (($itemspage_mobile_network > 0 && $itemspage_mobile_network < 101) ? $itemspage_mobile_network : $this->config->get('system', 'itemspage_network_mobile'));
|
$itemspage_mobile_network = (($itemspage_mobile_network > 0 && $itemspage_mobile_network < 101) ? $itemspage_mobile_network : $this->config->get('system', 'itemspage_network_mobile'));
|
||||||
|
|
||||||
$browser_update = intval($this->pConfig->get($uid, 'system', 'update_interval'));
|
$update_content = $this->pConfig->get($uid, 'system', 'update_content') ?? false;
|
||||||
if ($browser_update != -1) {
|
|
||||||
$browser_update = (($browser_update == 0) ? 40 : $browser_update / 1000); // default if not set: 40 seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
$enable_smile = !$this->pConfig->get($uid, 'system', 'no_smilies', false);
|
$enable_smile = !$this->pConfig->get($uid, 'system', 'no_smilies', false);
|
||||||
$infinite_scroll = $this->pConfig->get($uid, 'system', 'infinite_scroll', false);
|
$infinite_scroll = $this->pConfig->get($uid, 'system', 'infinite_scroll', false);
|
||||||
$enable_smart_threading = !$this->pConfig->get($uid, 'system', 'no_smart_threading', false);
|
$enable_smart_threading = !$this->pConfig->get($uid, 'system', 'no_smart_threading', false);
|
||||||
$enable_dislike = !$this->pConfig->get($uid, 'system', 'hide_dislike', false);
|
$enable_dislike = !$this->pConfig->get($uid, 'system', 'hide_dislike', false);
|
||||||
$display_resharer = $this->pConfig->get($uid, 'system', 'display_resharer', false);
|
$display_resharer = $this->pConfig->get($uid, 'system', 'display_resharer', false);
|
||||||
$stay_local = $this->pConfig->get($uid, 'system', 'stay_local', false);
|
$stay_local = $this->pConfig->get($uid, 'system', 'stay_local', false);
|
||||||
$show_page_drop = $this->pConfig->get($uid, 'system', 'show_page_drop', true);
|
$show_page_drop = $this->pConfig->get($uid, 'system', 'show_page_drop', true);
|
||||||
$display_eventlist = $this->pConfig->get($uid, 'system', 'display_eventlist', true);
|
$display_eventlist = $this->pConfig->get($uid, 'system', 'display_eventlist', true);
|
||||||
|
|
||||||
$hide_empty_descriptions = $this->pConfig->get($uid, 'accessibility', 'hide_empty_descriptions', false);
|
$hide_empty_descriptions = $this->pConfig->get($uid, 'accessibility', 'hide_empty_descriptions', false);
|
||||||
$hide_custom_emojis = $this->pConfig->get($uid, 'accessibility', 'hide_custom_emojis', false);
|
$hide_custom_emojis = $this->pConfig->get($uid, 'accessibility', 'hide_custom_emojis', false);
|
||||||
$platform_icon_style = $this->pConfig->get($uid, 'accessibility', 'platform_icon_style', ContactSelector::SVG_COLOR_BLACK);
|
$platform_icon_style = $this->pConfig->get($uid, 'accessibility', 'platform_icon_style', ContactSelector::SVG_COLOR_BLACK);
|
||||||
$platform_icon_styles = [
|
$platform_icon_styles = [
|
||||||
ContactSelector::SVG_DISABLED => $this->t('Disabled'),
|
ContactSelector::SVG_DISABLED => $this->t('Disabled'),
|
||||||
ContactSelector::SVG_COLOR_BLACK => $this->t('Color/Black'),
|
ContactSelector::SVG_COLOR_BLACK => $this->t('Color/Black'),
|
||||||
ContactSelector::SVG_BLACK => $this->t('Black'),
|
ContactSelector::SVG_BLACK => $this->t('Black'),
|
||||||
|
@ -263,7 +253,7 @@ class Display extends BaseSettings
|
||||||
ContactSelector::SVG_WHITE => $this->t('White'),
|
ContactSelector::SVG_WHITE => $this->t('White'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$preview_mode = $this->pConfig->get($uid, 'system', 'preview_mode', BBCode::PREVIEW_LARGE);
|
$preview_mode = $this->pConfig->get($uid, 'system', 'preview_mode', BBCode::PREVIEW_LARGE);
|
||||||
$preview_modes = [
|
$preview_modes = [
|
||||||
BBCode::PREVIEW_NONE => $this->t('No preview'),
|
BBCode::PREVIEW_NONE => $this->t('No preview'),
|
||||||
BBCode::PREVIEW_NO_IMAGE => $this->t('No image'),
|
BBCode::PREVIEW_NO_IMAGE => $this->t('No image'),
|
||||||
|
@ -273,16 +263,16 @@ class Display extends BaseSettings
|
||||||
|
|
||||||
$bookmarked_timelines = $this->pConfig->get($uid, 'system', 'network_timelines', $this->getAvailableTimelines($uid, true)->column('code'));
|
$bookmarked_timelines = $this->pConfig->get($uid, 'system', 'network_timelines', $this->getAvailableTimelines($uid, true)->column('code'));
|
||||||
$enabled_timelines = $this->pConfig->get($uid, 'system', 'enabled_timelines', $this->getAvailableTimelines($uid, false)->column('code'));
|
$enabled_timelines = $this->pConfig->get($uid, 'system', 'enabled_timelines', $this->getAvailableTimelines($uid, false)->column('code'));
|
||||||
$channel_languages = User::getWantedLanguages($uid);
|
$channel_languages = User::getWantedLanguages($uid);
|
||||||
$languages = $this->l10n->getLanguageCodes(true);
|
$languages = $this->l10n->getLanguageCodes(true);
|
||||||
|
|
||||||
$timelines = [];
|
$timelines = [];
|
||||||
foreach ($this->getAvailableTimelines($uid) as $timeline) {
|
foreach ($this->getAvailableTimelines($uid) as $timeline) {
|
||||||
$timelines[] = [
|
$timelines[] = [
|
||||||
'label' => $timeline->label,
|
'label' => $timeline->label,
|
||||||
'description' => $timeline->description,
|
'description' => $timeline->description,
|
||||||
'enable' => ["enable[{$timeline->code}]", '', in_array($timeline->code, $enabled_timelines)],
|
'enable' => ["enable[{$timeline->code}]", '', in_array($timeline->code, $enabled_timelines)],
|
||||||
'bookmark' => ["bookmark[{$timeline->code}]", '', in_array($timeline->code, $bookmarked_timelines)],
|
'bookmark' => ["bookmark[{$timeline->code}]", '', in_array($timeline->code, $bookmarked_timelines)],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,14 +316,14 @@ class Display extends BaseSettings
|
||||||
'$form_security_token' => self::getFormSecurityToken('settings_display'),
|
'$form_security_token' => self::getFormSecurityToken('settings_display'),
|
||||||
'$uid' => $uid,
|
'$uid' => $uid,
|
||||||
|
|
||||||
'$theme' => ['theme', $this->t('Display Theme:'), $theme_selected, '', $themes, true],
|
'$theme' => ['theme', $this->t('Display Theme:'), $theme_selected, '', $themes, true],
|
||||||
'$mobile_theme' => ['mobile_theme', $this->t('Mobile Theme:'), $mobile_theme_selected, '', $mobile_themes, false],
|
'$mobile_theme' => ['mobile_theme', $this->t('Mobile Theme:'), $mobile_theme_selected, '', $mobile_themes, false],
|
||||||
'$theme_config' => $theme_config,
|
'$theme_config' => $theme_config,
|
||||||
|
|
||||||
'$itemspage_network' => ['itemspage_network', $this->t('Number of items to display per page:'), $itemspage_network, $this->t('Maximum of 100 items')],
|
'$itemspage_network' => ['itemspage_network', $this->t('Number of items to display per page:'), $itemspage_network, $this->t('Maximum of 100 items')],
|
||||||
'$itemspage_mobile_network' => ['itemspage_mobile_network', $this->t('Number of items to display per page when viewed from mobile device:'), $itemspage_mobile_network, $this->t('Maximum of 100 items')],
|
'$itemspage_mobile_network' => ['itemspage_mobile_network', $this->t('Number of items to display per page when viewed from mobile device:'), $itemspage_mobile_network, $this->t('Maximum of 100 items')],
|
||||||
'$ajaxint' => ['browser_update', $this->t('Update browser every xx seconds'), $browser_update, $this->t('Minimum of 10 seconds. Enter -1 to disable it.')],
|
'$update_content' => ['update_content', $this->t('Regularly update the page content'), $update_content, $this->t('When enabled, new content on network, community and channels are added on top.')],
|
||||||
'$enable_smile' => ['enable_smile', $this->t('Display emoticons'), $enable_smile, $this->t('When enabled, emoticons are replaced with matching symbols.')],
|
'$enable_smile' => ['enable_smile', $this->t('Display emoticons'), $enable_smile, $this->t('When enabled, emoticons are replaced with matching symbols.')],
|
||||||
'$infinite_scroll' => ['infinite_scroll', $this->t('Infinite scroll'), $infinite_scroll, $this->t('Automatic fetch new items when reaching the page end.')],
|
'$infinite_scroll' => ['infinite_scroll', $this->t('Infinite scroll'), $infinite_scroll, $this->t('Automatic fetch new items when reaching the page end.')],
|
||||||
'$enable_smart_threading' => ['enable_smart_threading', $this->t('Enable Smart Threading'), $enable_smart_threading, $this->t('Enable the automatic suppression of extraneous thread indentation.')],
|
'$enable_smart_threading' => ['enable_smart_threading', $this->t('Enable Smart Threading'), $enable_smart_threading, $this->t('Enable the automatic suppression of extraneous thread indentation.')],
|
||||||
'$enable_dislike' => ['enable_dislike', $this->t('Display the Dislike feature'), $enable_dislike, $this->t('Display the Dislike button and dislike reactions on posts and comments.')],
|
'$enable_dislike' => ['enable_dislike', $this->t('Display the Dislike feature'), $enable_dislike, $this->t('Display the Dislike button and dislike reactions on posts and comments.')],
|
||||||
|
@ -353,7 +343,7 @@ class Display extends BaseSettings
|
||||||
'$timelines' => $timelines,
|
'$timelines' => $timelines,
|
||||||
'$timeline_explanation' => $this->t('Enable timelines that you want to see in the channels widget. Bookmark timelines that you want to see in the top menu.'),
|
'$timeline_explanation' => $this->t('Enable timelines that you want to see in the channels widget. Bookmark timelines that you want to see in the top menu.'),
|
||||||
|
|
||||||
'$channel_languages' => ['channel_languages[]', $this->t('Channel languages:'), $channel_languages, $this->t('Select all languages that you want to see in your channels.'), $languages, 'multiple'],
|
'$channel_languages' => ['channel_languages[]', $this->t('Channel languages:'), $channel_languages, $this->t('Select all the languages you want to see in your channels. "Unspecified" describes all posts for which no language information was detected (e.g. posts with just an image or too little text to be sure of the language). If you want to see all languages, you will need to select all items in the list.'), $languages, 'multiple'],
|
||||||
|
|
||||||
'$first_day_of_week' => ['first_day_of_week', $this->t('Beginning of week:'), $first_day_of_week, '', $weekdays, false],
|
'$first_day_of_week' => ['first_day_of_week', $this->t('Beginning of week:'), $first_day_of_week, '', $weekdays, false],
|
||||||
'$calendar_default_view' => ['calendar_default_view', $this->t('Default calendar view:'), $calendar_default_view, '', $calendarViews, false],
|
'$calendar_default_view' => ['calendar_default_view', $this->t('Default calendar view:'), $calendar_default_view, '', $calendarViews, false],
|
||||||
|
|
|
@ -45,19 +45,16 @@ class Display extends DisplayModule
|
||||||
$parentUriId = $item['parent-uri-id'];
|
$parentUriId = $item['parent-uri-id'];
|
||||||
|
|
||||||
if (empty($force)) {
|
if (empty($force)) {
|
||||||
$browserUpdate = intval($this->pConfig->get($profileUid, 'system', 'update_interval') ?? 40000);
|
if ($this->pConfig->get($profileUid, 'system', 'update_content')) {
|
||||||
if ($browserUpdate >= 1000) {
|
$updateDate = date(DateTimeFormat::MYSQL, time() - 120);
|
||||||
$updateDate = date(DateTimeFormat::MYSQL, time() - ($browserUpdate * 2 / 1000));
|
|
||||||
if (!Post::exists([
|
if (!Post::exists([
|
||||||
"`parent-uri-id` = ? AND `uid` IN (?, ?) AND `received` > ?",
|
"`parent-uri-id` = ? AND `uid` IN (?, ?) AND `received` > ?",
|
||||||
$parentUriId, 0,
|
$parentUriId, 0,
|
||||||
$profileUid, $updateDate])) {
|
$profileUid, $updateDate])) {
|
||||||
$this->logger->debug('No updated content. Ending process',
|
$this->logger->debug('No updated content. Ending process', ['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
|
||||||
['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
|
|
||||||
return '';
|
return '';
|
||||||
} else {
|
} else {
|
||||||
$this->logger->debug('Updated content found.',
|
$this->logger->debug('Updated content found.', ['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
|
||||||
['uri-id' => $uriId, 'uid' => $profileUid, 'updated' => $updateDate]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,7 +15,6 @@ use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\System;
|
|
||||||
use Friendica\Database\Database;
|
use Friendica\Database\Database;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\Factory\Api\Mastodon\Notification as NotificationFactory;
|
use Friendica\Factory\Api\Mastodon\Notification as NotificationFactory;
|
||||||
|
@ -205,7 +204,7 @@ class Notify extends BaseRepository
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
function createFromArray($params)
|
public function createFromArray($params)
|
||||||
{
|
{
|
||||||
/** @var string the common prefix of a notification subject */
|
/** @var string the common prefix of a notification subject */
|
||||||
$subjectPrefix = $this->l10n->t('[Friendica:Notify]');
|
$subjectPrefix = $this->l10n->t('[Friendica:Notify]');
|
||||||
|
@ -217,10 +216,10 @@ class Notify extends BaseRepository
|
||||||
|
|
||||||
// Ensure that the important fields are set at any time
|
// Ensure that the important fields are set at any time
|
||||||
$fields = ['nickname', 'account-type', 'notify-flags', 'language', 'username', 'email', 'account_removed', 'account_expired'];
|
$fields = ['nickname', 'account-type', 'notify-flags', 'language', 'username', 'email', 'account_removed', 'account_expired'];
|
||||||
$user = DBA::selectFirst('user', $fields, ['uid' => $params['uid']]);
|
$user = DBA::selectFirst('user', $fields, ['uid' => $params['uid']]);
|
||||||
|
|
||||||
if (!DBA::isResult($user)) {
|
if (!DBA::isResult($user)) {
|
||||||
$this->logger->error('Unknown user', ['uid' => $params['uid']]);
|
$this->logger->error('Unknown user', ['uid' => $params['uid']]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,13 +243,13 @@ class Notify extends BaseRepository
|
||||||
if (!empty($params['cid'])) {
|
if (!empty($params['cid'])) {
|
||||||
$contact = Model\Contact::getById($params['cid'], ['url', 'name', 'photo']);
|
$contact = Model\Contact::getById($params['cid'], ['url', 'name', 'photo']);
|
||||||
if (DBA::isResult($contact)) {
|
if (DBA::isResult($contact)) {
|
||||||
$params['source_link'] = $contact['url'];
|
$params['source_link'] = $contact['url'];
|
||||||
$params['source_name'] = $contact['name'];
|
$params['source_name'] = $contact['name'];
|
||||||
$params['source_photo'] = $contact['photo'];
|
$params['source_photo'] = $contact['photo'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$siteurl = (string)$this->baseUrl;
|
$siteurl = (string)$this->baseUrl;
|
||||||
$sitename = $this->config->get('config', 'sitename');
|
$sitename = $this->config->get('config', 'sitename');
|
||||||
|
|
||||||
// with $params['show_in_notification_page'] == false, the notification isn't inserted into
|
// with $params['show_in_notification_page'] == false, the notification isn't inserted into
|
||||||
|
@ -259,9 +258,9 @@ class Notify extends BaseRepository
|
||||||
$show_in_notification_page = isset($params['show_in_notification_page']) ? $params['show_in_notification_page'] : true;
|
$show_in_notification_page = isset($params['show_in_notification_page']) ? $params['show_in_notification_page'] : true;
|
||||||
|
|
||||||
$title = $params['item']['title'] ?? '';
|
$title = $params['item']['title'] ?? '';
|
||||||
$body = $params['item']['body'] ?? '';
|
$body = $params['item']['body'] ?? '';
|
||||||
|
|
||||||
$parent_id = $params['item']['parent'] ?? 0;
|
$parent_id = $params['item']['parent'] ?? 0;
|
||||||
$parent_uri_id = $params['item']['parent-uri-id'] ?? 0;
|
$parent_uri_id = $params['item']['parent-uri-id'] ?? 0;
|
||||||
|
|
||||||
$epreamble = '';
|
$epreamble = '';
|
||||||
|
@ -278,10 +277,10 @@ class Notify extends BaseRepository
|
||||||
|
|
||||||
$subject = $l10n->t('%s New mail received at %s', $subjectPrefix, $sitename);
|
$subject = $l10n->t('%s New mail received at %s', $subjectPrefix, $sitename);
|
||||||
|
|
||||||
$preamble = $l10n->t('%1$s sent you a new private message at %2$s.', $params['source_name'], $sitename);
|
$preamble = $l10n->t('%1$s sent you a new private message at %2$s.', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('%1$s sent you %2$s.', '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', '[url=' . $itemlink . ']' . $l10n->t('a private message').'[/url]');
|
$epreamble = $l10n->t('%1$s sent you %2$s.', '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', '[url=' . $itemlink . ']' . $l10n->t('a private message').'[/url]');
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s to view and/or reply to your private messages.');
|
$sitelink = $l10n->t('Please visit %s to view and/or reply to your private messages.');
|
||||||
$tsitelink = sprintf($sitelink, $itemlink);
|
$tsitelink = sprintf($sitelink, $itemlink);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="' . $itemlink . '">' . $sitename . '</a>');
|
$hsitelink = sprintf($sitelink, '<a href="' . $itemlink . '">' . $sitename . '</a>');
|
||||||
|
|
||||||
|
@ -302,7 +301,7 @@ class Notify extends BaseRepository
|
||||||
|
|
||||||
$item_post_type = Model\Item::postType($item, $l10n);
|
$item_post_type = Model\Item::postType($item, $l10n);
|
||||||
|
|
||||||
$body = BBCode::toPlaintext($item['body'], false);
|
$body = BBCode::toPlaintext($item['body'], false);
|
||||||
$title = Plaintext::shorten($body, 70);
|
$title = Plaintext::shorten($body, 70);
|
||||||
if (!empty($title)) {
|
if (!empty($title)) {
|
||||||
$title = '"' . trim(str_replace("\n", " ", $title)) . '"';
|
$title = '"' . trim(str_replace("\n", " ", $title)) . '"';
|
||||||
|
@ -311,16 +310,16 @@ class Notify extends BaseRepository
|
||||||
// First go for the general message
|
// First go for the general message
|
||||||
|
|
||||||
// "George Bull's post"
|
// "George Bull's post"
|
||||||
$message = $l10n->t('%1$s commented on %2$s\'s %3$s %4$s');
|
$message = $l10n->t('%1$s commented on %2$s\'s %3$s %4$s');
|
||||||
$dest_str = sprintf($message, $params['source_name'], $item['author-name'], $item_post_type, $title);
|
$dest_str = sprintf($message, $params['source_name'], $item['author-name'], $item_post_type, $title);
|
||||||
|
|
||||||
// "your post"
|
// "your post"
|
||||||
if ($item['wall']) {
|
if ($item['wall']) {
|
||||||
$message = $l10n->t('%1$s commented on your %2$s %3$s');
|
$message = $l10n->t('%1$s commented on your %2$s %3$s');
|
||||||
$dest_str = sprintf($message, $params['source_name'], $item_post_type, $title);
|
$dest_str = sprintf($message, $params['source_name'], $item_post_type, $title);
|
||||||
// "their post"
|
// "their post"
|
||||||
} elseif ($item['author-link'] == $params['source_link']) {
|
} elseif ($item['author-link'] == $params['source_link']) {
|
||||||
$message = $l10n->t('%1$s commented on their %2$s %3$s');
|
$message = $l10n->t('%1$s commented on their %2$s %3$s');
|
||||||
$dest_str = sprintf($message, $params['source_name'], $item_post_type, $title);
|
$dest_str = sprintf($message, $params['source_name'], $item_post_type, $title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,40 +329,42 @@ class Notify extends BaseRepository
|
||||||
|
|
||||||
$epreamble = $dest_str;
|
$epreamble = $dest_str;
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.');
|
$sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.');
|
||||||
$tsitelink = sprintf($sitelink, $siteurl);
|
$tsitelink = sprintf($sitelink, $siteurl);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
$hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Model\Notification\Type::WALL:
|
case Model\Notification\Type::WALL:
|
||||||
$subject = $l10n->t('%s %s posted to your profile wall', $subjectPrefix, $params['source_name']);
|
$subject = $l10n->t('%s %s posted to your profile wall', $subjectPrefix, $params['source_name']);
|
||||||
|
|
||||||
$preamble = $l10n->t('%1$s posted to your profile wall at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('%1$s posted to your profile wall at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('%1$s posted to [url=%2$s]your wall[/url]',
|
$epreamble = $l10n->t(
|
||||||
|
'%1$s posted to [url=%2$s]your wall[/url]',
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
|
||||||
$params['link']
|
$params['link']
|
||||||
);
|
);
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.');
|
$sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.');
|
||||||
$tsitelink = sprintf($sitelink, $siteurl);
|
$tsitelink = sprintf($sitelink, $siteurl);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Model\Notification\Type::INTRO:
|
case Model\Notification\Type::INTRO:
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
$subject = $l10n->t('%s Introduction received', $subjectPrefix);
|
$subject = $l10n->t('%s Introduction received', $subjectPrefix);
|
||||||
|
|
||||||
$preamble = $l10n->t('You\'ve received an introduction from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('You\'ve received an introduction from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('You\'ve received [url=%1$s]an introduction[/url] from %2$s.',
|
$epreamble = $l10n->t(
|
||||||
|
'You\'ve received [url=%1$s]an introduction[/url] from %2$s.',
|
||||||
$itemlink,
|
$itemlink,
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
||||||
);
|
);
|
||||||
|
|
||||||
$body = $l10n->t('You may visit their profile at %s', $params['source_link']);
|
$body = $l10n->t('You may visit their profile at %s', $params['source_link']);
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s to approve or reject the introduction.');
|
$sitelink = $l10n->t('Please visit %s to approve or reject the introduction.');
|
||||||
$tsitelink = sprintf($sitelink, $siteurl);
|
$tsitelink = sprintf($sitelink, $siteurl);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
||||||
|
|
||||||
|
@ -372,8 +373,9 @@ class Notify extends BaseRepository
|
||||||
// someone started to share with user (mostly OStatus)
|
// someone started to share with user (mostly OStatus)
|
||||||
$subject = $l10n->t('%s A new person is sharing with you', $subjectPrefix);
|
$subject = $l10n->t('%s A new person is sharing with you', $subjectPrefix);
|
||||||
|
|
||||||
$preamble = $l10n->t('%1$s is sharing with you at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('%1$s is sharing with you at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('%1$s is sharing with you at %2$s',
|
$epreamble = $l10n->t(
|
||||||
|
'%1$s is sharing with you at %2$s',
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
|
||||||
$sitename
|
$sitename
|
||||||
);
|
);
|
||||||
|
@ -382,8 +384,9 @@ class Notify extends BaseRepository
|
||||||
// someone started to follow the user (mostly OStatus)
|
// someone started to follow the user (mostly OStatus)
|
||||||
$subject = $l10n->t('%s You have a new follower', $subjectPrefix);
|
$subject = $l10n->t('%s You have a new follower', $subjectPrefix);
|
||||||
|
|
||||||
$preamble = $l10n->t('You have a new follower at %2$s : %1$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('You have a new follower at %2$s : %1$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('You have a new follower at %2$s : %1$s',
|
$epreamble = $l10n->t(
|
||||||
|
'You have a new follower at %2$s : %1$s',
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
|
||||||
$sitename
|
$sitename
|
||||||
);
|
);
|
||||||
|
@ -395,11 +398,12 @@ class Notify extends BaseRepository
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Model\Notification\Type::SUGGEST:
|
case Model\Notification\Type::SUGGEST:
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
$subject = $l10n->t('%s Friend suggestion received', $subjectPrefix);
|
$subject = $l10n->t('%s Friend suggestion received', $subjectPrefix);
|
||||||
|
|
||||||
$preamble = $l10n->t('You\'ve received a friend suggestion from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('You\'ve received a friend suggestion from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.',
|
$epreamble = $l10n->t(
|
||||||
|
'You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.',
|
||||||
$itemlink,
|
$itemlink,
|
||||||
'[url='.$params['item']['url'].']'.$params['item']['name'].'[/url]',
|
'[url='.$params['item']['url'].']'.$params['item']['name'].'[/url]',
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
||||||
|
@ -409,42 +413,44 @@ class Notify extends BaseRepository
|
||||||
$body .= $l10n->t('Photo:').' '.$params['item']['photo']."\n";
|
$body .= $l10n->t('Photo:').' '.$params['item']['photo']."\n";
|
||||||
$body .= $l10n->t('You may visit their profile at %s', $params['item']['url']);
|
$body .= $l10n->t('You may visit their profile at %s', $params['item']['url']);
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s to approve or reject the suggestion.');
|
$sitelink = $l10n->t('Please visit %s to approve or reject the suggestion.');
|
||||||
$tsitelink = sprintf($sitelink, $siteurl);
|
$tsitelink = sprintf($sitelink, $siteurl);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Model\Notification\Type::CONFIRM:
|
case Model\Notification\Type::CONFIRM:
|
||||||
if ($params['verb'] == Activity::FRIEND) { // mutual connection
|
if ($params['verb'] == Activity::FRIEND) { // mutual connection
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
$subject = $l10n->t('%s Connection accepted', $subjectPrefix);
|
$subject = $l10n->t('%s Connection accepted', $subjectPrefix);
|
||||||
|
|
||||||
$preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('%2$s has accepted your [url=%1$s]connection request[/url].',
|
$epreamble = $l10n->t(
|
||||||
|
'%2$s has accepted your [url=%1$s]connection request[/url].',
|
||||||
$itemlink,
|
$itemlink,
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
||||||
);
|
);
|
||||||
|
|
||||||
$body = $l10n->t('You are now mutual friends and may exchange status updates, photos, and email without restriction.');
|
$body = $l10n->t('You are now mutual friends and may exchange status updates, photos, and email without restriction.');
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.');
|
$sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.');
|
||||||
$tsitelink = sprintf($sitelink, $siteurl);
|
$tsitelink = sprintf($sitelink, $siteurl);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
||||||
} else { // ACTIVITY_FOLLOW
|
} else { // ACTIVITY_FOLLOW
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
$subject = $l10n->t('%s Connection accepted', $subjectPrefix);
|
$subject = $l10n->t('%s Connection accepted', $subjectPrefix);
|
||||||
|
|
||||||
$preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('%2$s has accepted your [url=%1$s]connection request[/url].',
|
$epreamble = $l10n->t(
|
||||||
|
'%2$s has accepted your [url=%1$s]connection request[/url].',
|
||||||
$itemlink,
|
$itemlink,
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
||||||
);
|
);
|
||||||
|
|
||||||
$body = $l10n->t('\'%1$s\' has chosen to accept you a fan, which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically.', $params['source_name']);
|
$body = $l10n->t('\'%1$s\' has chosen to accept you a fan, which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically.', $params['source_name']);
|
||||||
$body .= "\n\n";
|
$body .= "\n\n";
|
||||||
$body .= $l10n->t('\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future.', $params['source_name']);
|
$body .= $l10n->t('\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future.', $params['source_name']);
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.');
|
$sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.');
|
||||||
$tsitelink = sprintf($sitelink, $siteurl);
|
$tsitelink = sprintf($sitelink, $siteurl);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
|
||||||
}
|
}
|
||||||
|
@ -453,43 +459,49 @@ class Notify extends BaseRepository
|
||||||
case Model\Notification\Type::SYSTEM:
|
case Model\Notification\Type::SYSTEM:
|
||||||
switch($params['event']) {
|
switch($params['event']) {
|
||||||
case 'SYSTEM_REGISTER_REQUEST':
|
case 'SYSTEM_REGISTER_REQUEST':
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
$subject = $l10n->t('[Friendica System Notify]') . ' ' . $l10n->t('registration request');
|
$subject = $l10n->t('[Friendica System Notify]') . ' ' . $l10n->t('registration request');
|
||||||
|
|
||||||
$preamble = $l10n->t('You\'ve received a registration request from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('You\'ve received a registration request from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('You\'ve received a [url=%1$s]registration request[/url] from %2$s.',
|
$epreamble = $l10n->t(
|
||||||
|
'You\'ve received a [url=%1$s]registration request[/url] from %2$s.',
|
||||||
$itemlink,
|
$itemlink,
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
||||||
);
|
);
|
||||||
|
|
||||||
$body = $l10n->t("Display Name: %s\nSite Location: %s\nLogin Name: %s (%s)",
|
$body = $l10n->t(
|
||||||
|
"Display Name: %s\nSite Location: %s\nLogin Name: %s (%s)",
|
||||||
$params['source_name'],
|
$params['source_name'],
|
||||||
$siteurl, $params['source_mail'],
|
$siteurl,
|
||||||
|
$params['source_mail'],
|
||||||
$params['source_nick']
|
$params['source_nick']
|
||||||
);
|
);
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s to approve or reject the request.');
|
$sitelink = $l10n->t('Please visit %s to approve or reject the request.');
|
||||||
$tsitelink = sprintf($sitelink, $params['link']);
|
$tsitelink = sprintf($sitelink, $params['link']);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="' . $params['link'] . '">' . $sitename . '</a><br><br>');
|
$hsitelink = sprintf($sitelink, '<a href="' . $params['link'] . '">' . $sitename . '</a><br><br>');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'SYSTEM_REGISTER_NEW':
|
case 'SYSTEM_REGISTER_NEW':
|
||||||
$itemlink = $params['link'];
|
$itemlink = $params['link'];
|
||||||
$subject = $l10n->t('[Friendica System Notify]') . ' ' . $l10n->t('new registration');
|
$subject = $l10n->t('[Friendica System Notify]') . ' ' . $l10n->t('new registration');
|
||||||
|
|
||||||
$preamble = $l10n->t('You\'ve received a new registration from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
$preamble = $l10n->t('You\'ve received a new registration from \'%1$s\' at %2$s', $params['source_name'], $sitename);
|
||||||
$epreamble = $l10n->t('You\'ve received a [url=%1$s]new registration[/url] from %2$s.',
|
$epreamble = $l10n->t(
|
||||||
|
'You\'ve received a [url=%1$s]new registration[/url] from %2$s.',
|
||||||
$itemlink,
|
$itemlink,
|
||||||
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
|
||||||
);
|
);
|
||||||
|
|
||||||
$body = $l10n->t("Display Name: %s\nSite Location: %s\nLogin Name: %s (%s)",
|
$body = $l10n->t(
|
||||||
|
"Display Name: %s\nSite Location: %s\nLogin Name: %s (%s)",
|
||||||
$params['source_name'],
|
$params['source_name'],
|
||||||
$siteurl, $params['source_mail'],
|
$siteurl,
|
||||||
|
$params['source_mail'],
|
||||||
$params['source_nick']
|
$params['source_nick']
|
||||||
);
|
);
|
||||||
|
|
||||||
$sitelink = $l10n->t('Please visit %s to have a look at the new registration.');
|
$sitelink = $l10n->t('Please visit %s to have a look at the new registration.');
|
||||||
$tsitelink = sprintf($sitelink, $params['link']);
|
$tsitelink = sprintf($sitelink, $params['link']);
|
||||||
$hsitelink = sprintf($sitelink, '<a href="' . $params['link'] . '">' . $sitename . '</a><br><br>');
|
$hsitelink = sprintf($sitelink, '<a href="' . $params['link'] . '">' . $sitename . '</a><br><br>');
|
||||||
break;
|
break;
|
||||||
|
@ -509,14 +521,14 @@ class Notify extends BaseRepository
|
||||||
|
|
||||||
private function storeAndSend(array $params, string $sitelink, string $tsitelink, string $hsitelink, string $title, string $subject, string $preamble, string $epreamble, string $body, string $itemlink, bool $show_in_notification_page): bool
|
private function storeAndSend(array $params, string $sitelink, string $tsitelink, string $hsitelink, string $title, string $subject, string $preamble, string $epreamble, string $body, string $itemlink, bool $show_in_notification_page): bool
|
||||||
{
|
{
|
||||||
$item_id = $params['item']['id'] ?? 0;
|
$item_id = $params['item']['id'] ?? 0;
|
||||||
$uri_id = $params['item']['uri-id'] ?? null;
|
$uri_id = $params['item']['uri-id'] ?? null;
|
||||||
$parent_id = $params['item']['parent'] ?? 0;
|
$parent_id = $params['item']['parent'] ?? 0;
|
||||||
$parent_uri_id = $params['item']['parent-uri-id'] ?? null;
|
$parent_uri_id = $params['item']['parent-uri-id'] ?? null;
|
||||||
|
|
||||||
// Ensure that the important fields are set at any time
|
// Ensure that the important fields are set at any time
|
||||||
$fields = ['nickname', 'account_removed', 'account_expired'];
|
$fields = ['nickname', 'account_removed', 'account_expired'];
|
||||||
$user = Model\User::getById($params['uid'], $fields);
|
$user = Model\User::getById($params['uid'], $fields);
|
||||||
if ($user['account_removed'] || $user['account_expired']) {
|
if ($user['account_removed'] || $user['account_expired']) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -551,12 +563,12 @@ class Notify extends BaseRepository
|
||||||
|
|
||||||
Hook::callAll('enotify', $h);
|
Hook::callAll('enotify', $h);
|
||||||
|
|
||||||
$subject = $h['subject'];
|
$subject = $h['subject'];
|
||||||
|
|
||||||
$preamble = $h['preamble'];
|
$preamble = $h['preamble'];
|
||||||
$epreamble = $h['epreamble'];
|
$epreamble = $h['epreamble'];
|
||||||
|
|
||||||
$body = $h['body'];
|
$body = $h['body'];
|
||||||
|
|
||||||
$tsitelink = $h['tsitelink'];
|
$tsitelink = $h['tsitelink'];
|
||||||
$hsitelink = $h['hsitelink'];
|
$hsitelink = $h['hsitelink'];
|
||||||
|
@ -587,7 +599,7 @@ class Notify extends BaseRepository
|
||||||
$this->logger->notice('sending notification email');
|
$this->logger->notice('sending notification email');
|
||||||
|
|
||||||
if (isset($params['parent']) && (intval($params['parent']) != 0)) {
|
if (isset($params['parent']) && (intval($params['parent']) != 0)) {
|
||||||
$parent = Model\Post::selectFirst(['guid'], ['id' => $params['parent']]);
|
$parent = Model\Post::selectFirst(['guid'], ['id' => $params['parent']]);
|
||||||
$message_id = "<" . $parent['guid'] . "@" . gethostname() . ">";
|
$message_id = "<" . $parent['guid'] . "@" . gethostname() . ">";
|
||||||
|
|
||||||
// Is this the first email notification for this parent item and user?
|
// Is this the first email notification for this parent item and user?
|
||||||
|
@ -595,13 +607,11 @@ class Notify extends BaseRepository
|
||||||
$this->logger->info("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']));
|
$this->logger->info("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']));
|
||||||
|
|
||||||
$fields = ['notify-id' => $notify_id, 'master-parent-uri-id' => $parent_uri_id,
|
$fields = ['notify-id' => $notify_id, 'master-parent-uri-id' => $parent_uri_id,
|
||||||
'receiver-uid' => $params['uid'], 'parent-item' => 0];
|
'receiver-uid' => $params['uid'], 'parent-item' => 0];
|
||||||
DBA::insert('notify-threads', $fields);
|
DBA::insert('notify-threads', $fields);
|
||||||
|
|
||||||
$emailBuilder->setHeader('Message-ID', $message_id);
|
$emailBuilder->setHeader('Message-ID', $message_id);
|
||||||
$log_msg = "No previous notification found for this parent:\n" .
|
$this->logger->info('No previous notification found for this parent', ['parent' => $params['parent'], 'uid' => $params['uid']]);
|
||||||
" parent: {$params['parent']}\n" . " uid : {$params['uid']}\n";
|
|
||||||
$this->logger->info($log_msg);
|
|
||||||
} else {
|
} else {
|
||||||
// If not, just "follow" the thread.
|
// If not, just "follow" the thread.
|
||||||
$emailBuilder->setHeader('References', $message_id);
|
$emailBuilder->setHeader('References', $message_id);
|
||||||
|
@ -614,8 +624,8 @@ class Notify extends BaseRepository
|
||||||
'preamble' => $preamble,
|
'preamble' => $preamble,
|
||||||
'type' => $params['type'],
|
'type' => $params['type'],
|
||||||
'parent' => $parent_id,
|
'parent' => $parent_id,
|
||||||
'source_name' => $params['source_name'] ?? null,
|
'source_name' => $params['source_name'] ?? null,
|
||||||
'source_link' => $params['source_link'] ?? null,
|
'source_link' => $params['source_link'] ?? null,
|
||||||
'source_photo' => $params['source_photo'] ?? null,
|
'source_photo' => $params['source_photo'] ?? null,
|
||||||
'uid' => $params['uid'],
|
'uid' => $params['uid'],
|
||||||
'hsitelink' => $hsitelink,
|
'hsitelink' => $hsitelink,
|
||||||
|
@ -633,7 +643,7 @@ class Notify extends BaseRepository
|
||||||
->withHeaders($datarray['headers'])
|
->withHeaders($datarray['headers'])
|
||||||
->withRecipient($params['to_email'])
|
->withRecipient($params['to_email'])
|
||||||
->forUser([
|
->forUser([
|
||||||
'uid' => $datarray['uid'],
|
'uid' => $datarray['uid'],
|
||||||
'language' => $params['language'],
|
'language' => $params['language'],
|
||||||
])
|
])
|
||||||
->withNotification($datarray['subject'], $datarray['preamble'], $datarray['title'], $datarray['body'])
|
->withNotification($datarray['subject'], $datarray['preamble'], $datarray['title'], $datarray['body'])
|
||||||
|
@ -645,7 +655,8 @@ class Notify extends BaseRepository
|
||||||
$emailBuilder->withPhoto(
|
$emailBuilder->withPhoto(
|
||||||
$datarray['source_photo'],
|
$datarray['source_photo'],
|
||||||
$datarray['source_link'] ?? $sitelink,
|
$datarray['source_link'] ?? $sitelink,
|
||||||
$datarray['source_name'] ?? $sitename);
|
$datarray['source_name'] ?? $sitename
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$email = $emailBuilder->build();
|
$email = $emailBuilder->build();
|
||||||
|
@ -681,7 +692,7 @@ class Notify extends BaseRepository
|
||||||
|
|
||||||
// Fallback for the case when the notify type isn't set at all
|
// Fallback for the case when the notify type isn't set at all
|
||||||
if (is_null($notify_type) && !in_array($type, [Notification::TYPE_RESHARE, Notification::TYPE_LIKE])) {
|
if (is_null($notify_type) && !in_array($type, [Notification::TYPE_RESHARE, Notification::TYPE_LIKE])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($notify_type) && ($notify_type & $Notification->type)) {
|
if (!is_null($notify_type) && ($notify_type & $Notification->type)) {
|
||||||
|
@ -700,7 +711,7 @@ class Notify extends BaseRepository
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$params = [];
|
$params = [];
|
||||||
$params['verb'] = $Notification->verb;
|
$params['verb'] = $Notification->verb;
|
||||||
$params['uid'] = $Notification->uid;
|
$params['uid'] = $Notification->uid;
|
||||||
$params['otype'] = Model\Notification\ObjectType::ITEM;
|
$params['otype'] = Model\Notification\ObjectType::ITEM;
|
||||||
|
@ -725,9 +736,12 @@ class Notify extends BaseRepository
|
||||||
$params['source_photo'] = $contact['photo'];
|
$params['source_photo'] = $contact['photo'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$item = Model\Post::selectFirstForUser($Notification->uid, Model\Item::ITEM_FIELDLIST,
|
$item = Model\Post::selectFirstForUser(
|
||||||
['uid' => [0, $Notification->uid], 'uri-id' => $Notification->targetUriId, 'deleted' => false],
|
$Notification->uid,
|
||||||
['order' => ['uid' => true]]);
|
Model\Item::ITEM_FIELDLIST,
|
||||||
|
['uid' => [0, $Notification->uid], 'uri-id' => $Notification->targetUriId, 'deleted' => false],
|
||||||
|
['order' => ['uid' => true]]
|
||||||
|
);
|
||||||
if (empty($item)) {
|
if (empty($item)) {
|
||||||
$this->logger->info('Item not found', ['uri-id' => $Notification->targetUriId, 'type' => $Notification->type]);
|
$this->logger->info('Item not found', ['uri-id' => $Notification->targetUriId, 'type' => $Notification->type]);
|
||||||
return false;
|
return false;
|
||||||
|
@ -747,13 +761,13 @@ class Notify extends BaseRepository
|
||||||
// Check to see if there was already a tag notify or comment notify for this post.
|
// Check to see if there was already a tag notify or comment notify for this post.
|
||||||
// If so don't create a second notification
|
// If so don't create a second notification
|
||||||
$condition = ['type' => [Model\Notification\Type::TAG_SELF, Model\Notification\Type::COMMENT, Model\Notification\Type::SHARE],
|
$condition = ['type' => [Model\Notification\Type::TAG_SELF, Model\Notification\Type::COMMENT, Model\Notification\Type::SHARE],
|
||||||
'link' => $params['link'], 'verb' => Activity::POST];
|
'link' => $params['link'], 'verb' => Activity::POST];
|
||||||
if ($this->existsForUser($Notification->uid, $condition)) {
|
if ($this->existsForUser($Notification->uid, $condition)) {
|
||||||
$this->logger->info('Duplicate found, quitting', $condition + ['uid' => $Notification->uid]);
|
$this->logger->info('Duplicate found, quitting', $condition + ['uid' => $Notification->uid]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$body = BBCode::toPlaintext($item['body'], false);
|
$body = BBCode::toPlaintext($item['body'], false);
|
||||||
$title = Plaintext::shorten($body, 70);
|
$title = Plaintext::shorten($body, 70);
|
||||||
if (!empty($title)) {
|
if (!empty($title)) {
|
||||||
$title = '"' . trim(str_replace("\n", " ", $title)) . '"';
|
$title = '"' . trim(str_replace("\n", " ", $title)) . '"';
|
||||||
|
|
|
@ -24,40 +24,24 @@ use Friendica\Object\Api\Mastodon\InstanceV2\Configuration;
|
||||||
*/
|
*/
|
||||||
class Instance extends BaseDataTransferObject
|
class Instance extends BaseDataTransferObject
|
||||||
{
|
{
|
||||||
/** @var string (URL) */
|
protected string $uri;
|
||||||
protected $uri;
|
protected string $title;
|
||||||
/** @var string */
|
protected string $short_description;
|
||||||
protected $title;
|
protected string $description;
|
||||||
/** @var string */
|
protected string $email;
|
||||||
protected $short_description;
|
protected string $version;
|
||||||
/** @var string */
|
protected array $urls;
|
||||||
protected $description;
|
protected Stats $stats;
|
||||||
/** @var string */
|
/** This is meant as a server banner, default Mastodon "thumbnail" is 1600×620px */
|
||||||
protected $email;
|
protected ?string $thumbnail = null;
|
||||||
/** @var string */
|
protected array $languages;
|
||||||
protected $version;
|
protected int $max_toot_chars;
|
||||||
/** @var array */
|
protected bool $registrations;
|
||||||
protected $urls;
|
protected bool $approval_required;
|
||||||
/** @var Stats */
|
protected bool $invites_enabled;
|
||||||
protected $stats;
|
protected Configuration $configuration;
|
||||||
/** @var string|null This is meant as a server banner, default Mastodon "thumbnail" is 1600×620px */
|
protected ?Account $contact_account = null;
|
||||||
protected $thumbnail = null;
|
protected array $rules = [];
|
||||||
/** @var array */
|
|
||||||
protected $languages;
|
|
||||||
/** @var int */
|
|
||||||
protected $max_toot_chars;
|
|
||||||
/** @var bool */
|
|
||||||
protected $registrations;
|
|
||||||
/** @var bool */
|
|
||||||
protected $approval_required;
|
|
||||||
/** @var bool */
|
|
||||||
protected $invites_enabled;
|
|
||||||
/** @var Configuration */
|
|
||||||
protected $configuration;
|
|
||||||
/** @var Account|null */
|
|
||||||
protected $contact_account = null;
|
|
||||||
/** @var array */
|
|
||||||
protected $rules = [];
|
|
||||||
|
|
||||||
public function __construct(IManageConfigValues $config, BaseURL $baseUrl, Database $database, Configuration $configuration, ?Account $contact_account, array $rules)
|
public function __construct(IManageConfigValues $config, BaseURL $baseUrl, Database $database, Configuration $configuration, ?Account $contact_account, array $rules)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +61,7 @@ class Instance extends BaseDataTransferObject
|
||||||
$this->approval_required = ($register_policy === Register::APPROVE);
|
$this->approval_required = ($register_policy === Register::APPROVE);
|
||||||
$this->invites_enabled = false;
|
$this->invites_enabled = false;
|
||||||
$this->configuration = $configuration;
|
$this->configuration = $configuration;
|
||||||
$this->contact_account = $contact_account ?? [];
|
$this->contact_account = $contact_account;
|
||||||
$this->rules = $rules;
|
$this->rules = $rules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,8 +498,10 @@ class Post
|
||||||
}
|
}
|
||||||
|
|
||||||
$languages = [];
|
$languages = [];
|
||||||
|
$language = '';
|
||||||
if (!empty($item['language'])) {
|
if (!empty($item['language'])) {
|
||||||
$languages = DI::l10n()->t('Languages');
|
$languages = DI::l10n()->t('Languages');
|
||||||
|
$language = array_key_first(json_decode($item['language'], true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]) && in_array($item['network'], Protocol::FEDERATED)) {
|
if (in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]) && in_array($item['network'], Protocol::FEDERATED)) {
|
||||||
|
@ -553,6 +555,7 @@ class Post
|
||||||
'title' => $item['title'],
|
'title' => $item['title'],
|
||||||
'summary' => $item['content-warning'],
|
'summary' => $item['content-warning'],
|
||||||
'localtime' => DateTimeFormat::local($item['created'], 'r'),
|
'localtime' => DateTimeFormat::local($item['created'], 'r'),
|
||||||
|
'utc' => DateTimeFormat::utc($item['created']),
|
||||||
'ago' => $item['app'] ? DI::l10n()->t('%s from %s', $ago, $item['app']) : $ago,
|
'ago' => $item['app'] ? DI::l10n()->t('%s from %s', $ago, $item['app']) : $ago,
|
||||||
'app' => $item['app'],
|
'app' => $item['app'],
|
||||||
'created' => $ago,
|
'created' => $ago,
|
||||||
|
@ -579,6 +582,7 @@ class Post
|
||||||
'tagger' => $tagger,
|
'tagger' => $tagger,
|
||||||
'filer' => $filer,
|
'filer' => $filer,
|
||||||
'language' => $languages,
|
'language' => $languages,
|
||||||
|
'lang' => $language,
|
||||||
'searchtext' => DI::l10n()->t('Search Text'),
|
'searchtext' => DI::l10n()->t('Search Text'),
|
||||||
'drop' => $drop,
|
'drop' => $drop,
|
||||||
'block' => $block,
|
'block' => $block,
|
||||||
|
|
|
@ -906,15 +906,15 @@ class Processor
|
||||||
if ($id) {
|
if ($id) {
|
||||||
$shared_item = Post::selectFirst(['uri-id'], ['id' => $id]);
|
$shared_item = Post::selectFirst(['uri-id'], ['id' => $id]);
|
||||||
$item['quote-uri-id'] = $shared_item['uri-id'];
|
$item['quote-uri-id'] = $shared_item['uri-id'];
|
||||||
DI::logger()->debug('Quote is found', ['guid' => $item['guid'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url'], 'quote-uri-id' => $item['quote-uri-id']]);
|
DI::logger()->debug('Quote is found', ['uri' => $item['uri'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url'], 'quote-uri-id' => $item['quote-uri-id']]);
|
||||||
} elseif ($uri_id = ItemURI::getIdByURI($activity['quote-url'], false)) {
|
} elseif ($uri_id = ItemURI::getIdByURI($activity['quote-url'], false)) {
|
||||||
DI::logger()->info('Quote was not fetched but the uri-id existed', ['guid' => $item['guid'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url'], 'quote-uri-id' => $uri_id]);
|
DI::logger()->info('Quote was not fetched but the uri-id existed', ['uri' => $item['uri'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url'], 'quote-uri-id' => $uri_id]);
|
||||||
$item['quote-uri-id'] = $uri_id;
|
$item['quote-uri-id'] = $uri_id;
|
||||||
} elseif (Queue::exists($activity['quote-url'], 'as:Create')) {
|
} elseif (Queue::exists($activity['quote-url'], 'as:Create')) {
|
||||||
$item['quote-uri-id'] = ItemURI::getIdByURI($activity['quote-url']);
|
$item['quote-uri-id'] = ItemURI::getIdByURI($activity['quote-url']);
|
||||||
DI::logger()->info('Quote is queued but not processed yet', ['guid' => $item['guid'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url'], 'quote-uri-id' => $item['quote-uri-id']]);
|
DI::logger()->info('Quote is queued but not processed yet', ['uri' => $item['uri'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url'], 'quote-uri-id' => $item['quote-uri-id']]);
|
||||||
} else {
|
} else {
|
||||||
DI::logger()->notice('Quote was not fetched', ['guid' => $item['guid'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url']]);
|
DI::logger()->notice('Quote was not fetched', ['uri' => $item['uri'], 'uri-id' => $item['uri-id'], 'quote' => $activity['quote-url']]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -798,10 +798,12 @@ class Transmitter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($item['quote-uri-id']) && in_array($item['private'], [Item::PUBLIC, Item::UNLISTED])) {
|
if (!empty($item['quote-uri-id']) && in_array($item['private'], [Item::PUBLIC, Item::UNLISTED])) {
|
||||||
$quoted = Post::selectFirst(['author-link'], ['uri-id' => $item['quote-uri-id']]);
|
$quoted = Post::selectFirst(['author-link'], ['uri-id' => $item['quote-uri-id']]);
|
||||||
$profile = APContact::getByURL($quoted['author-link'], false);
|
if (!empty($quoted['author-link'])) {
|
||||||
if (!empty($profile)) {
|
$profile = APContact::getByURL($quoted['author-link'], false);
|
||||||
$data['cc'][] = $profile['url'];
|
if (!empty($profile)) {
|
||||||
|
$data['cc'][] = $profile['url'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ class Delivery
|
||||||
$atom = DFRN::entries($msgitems, $owner);
|
$atom = DFRN::entries($msgitems, $owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
DI::logger()->debug('Notifier entry: ' . $contact['url'] . ' ' . ($target_item_id ?? 'relocation') . ' entry: ' . $atom);
|
DI::logger()->debug('Notifier entry', ['url' => $contact['url'], 'target_item_id' => ($target_item_id ?? 'relocation'), 'entry' => $atom]);
|
||||||
|
|
||||||
$protocol = Post\DeliveryData::DFRN;
|
$protocol = Post\DeliveryData::DFRN;
|
||||||
|
|
||||||
|
|
|
@ -2790,7 +2790,7 @@ class Diaspora
|
||||||
*/
|
*/
|
||||||
public static function encodePrivateData(string $msg, array $user, array $contact, string $prvkey, string $pubkey): string
|
public static function encodePrivateData(string $msg, array $user, array $contact, string $prvkey, string $pubkey): string
|
||||||
{
|
{
|
||||||
DI::logger()->debug('Message: ' . $msg);
|
DI::logger()->debug('Diaspora message', ['msg' => $msg]);
|
||||||
|
|
||||||
// without a public key nothing will work
|
// without a public key nothing will work
|
||||||
if (!$pubkey) {
|
if (!$pubkey) {
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Protocol;
|
namespace Friendica\Protocol;
|
||||||
|
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Module;
|
use Friendica\Module;
|
||||||
use Friendica\Module\Register;
|
use Friendica\Module\Register;
|
||||||
|
@ -43,6 +42,11 @@ class ZOT
|
||||||
*/
|
*/
|
||||||
public static function getSiteInfo(): array
|
public static function getSiteInfo(): array
|
||||||
{
|
{
|
||||||
|
$baseUrl = (string) DI::baseUrl();
|
||||||
|
$keyValue = DI::keyValue();
|
||||||
|
$addonHelper = DI::addonHelper();
|
||||||
|
$config = DI::config();
|
||||||
|
|
||||||
$policies = [
|
$policies = [
|
||||||
Module\Register::OPEN => 'open',
|
Module\Register::OPEN => 'open',
|
||||||
Module\Register::APPROVE => 'approve',
|
Module\Register::APPROVE => 'approve',
|
||||||
|
@ -50,14 +54,14 @@ class ZOT
|
||||||
];
|
];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'url' => (string)DI::baseUrl(),
|
'url' => $baseUrl,
|
||||||
'openWebAuth' => (string)DI::baseUrl() . '/owa',
|
'openWebAuth' => $baseUrl . '/owa',
|
||||||
'authRedirect' => (string)DI::baseUrl() . '/magic',
|
'authRedirect' => $baseUrl . '/magic',
|
||||||
'register_policy' => $policies[Register::getPolicy()],
|
'register_policy' => $policies[Register::getPolicy()],
|
||||||
'accounts' => DI::keyValue()->get('nodeinfo_total_users'),
|
'accounts' => $keyValue->get('nodeinfo_total_users'),
|
||||||
'plugins' => Addon::getVisibleList(),
|
'plugins' => $addonHelper->getVisibleEnabledAddons(),
|
||||||
'sitename' => DI::config()->get('config', 'sitename'),
|
'sitename' => $config->get('config', 'sitename'),
|
||||||
'about' => DI::config()->get('config', 'info'),
|
'about' => $config->get('config', 'info'),
|
||||||
'project' => App::PLATFORM,
|
'project' => App::PLATFORM,
|
||||||
'version' => App::VERSION,
|
'version' => App::VERSION,
|
||||||
];
|
];
|
||||||
|
|
|
@ -299,12 +299,19 @@ class Crypto
|
||||||
* Creates cryptographic secure random digits
|
* Creates cryptographic secure random digits
|
||||||
*
|
*
|
||||||
* @param string $digits The count of digits
|
* @param string $digits The count of digits
|
||||||
* @return int The random Digits
|
* @return string The random Digits
|
||||||
*
|
*
|
||||||
* @throws \Exception In case 'random_int' isn't usable
|
* @throws \Exception In case 'random_int' isn't usable
|
||||||
*/
|
*/
|
||||||
public static function randomDigits($digits)
|
public static function randomDigits($digits): string
|
||||||
{
|
{
|
||||||
return random_int(0, 10 ** $digits - 1);
|
$rn = '';
|
||||||
|
|
||||||
|
// generating cryptographically secure pseudo-random integers
|
||||||
|
for ($i = 0; $i < $digits; $i++) {
|
||||||
|
$rn .= random_int(0, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,14 +40,18 @@ class Emailer
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $siteEmailName;
|
private $siteEmailName;
|
||||||
|
|
||||||
public function __construct(IManageConfigValues $config, IManagePersonalConfigValues $pConfig, BaseURL $baseURL, LoggerInterface $logger,
|
public function __construct(
|
||||||
L10n $defaultLang)
|
IManageConfigValues $config,
|
||||||
{
|
IManagePersonalConfigValues $pConfig,
|
||||||
$this->config = $config;
|
BaseURL $baseURL,
|
||||||
$this->pConfig = $pConfig;
|
LoggerInterface $logger,
|
||||||
$this->logger = $logger;
|
L10n $defaultLang
|
||||||
$this->baseUrl = $baseURL;
|
) {
|
||||||
$this->l10n = $defaultLang;
|
$this->config = $config;
|
||||||
|
$this->pConfig = $pConfig;
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->baseUrl = $baseURL;
|
||||||
|
$this->l10n = $defaultLang;
|
||||||
|
|
||||||
$this->siteEmailAddress = $this->config->get('config', 'sender_email');
|
$this->siteEmailAddress = $this->config->get('config', 'sender_email');
|
||||||
if (empty($this->siteEmailAddress)) {
|
if (empty($this->siteEmailAddress)) {
|
||||||
|
@ -89,8 +93,14 @@ class Emailer
|
||||||
*/
|
*/
|
||||||
public function newSystemMail()
|
public function newSystemMail()
|
||||||
{
|
{
|
||||||
return new SystemMailBuilder($this->l10n, $this->baseUrl, $this->config, $this->logger,
|
return new SystemMailBuilder(
|
||||||
$this->getSiteEmailAddress(), $this->getSiteEmailName());
|
$this->l10n,
|
||||||
|
$this->baseUrl,
|
||||||
|
$this->config,
|
||||||
|
$this->logger,
|
||||||
|
$this->getSiteEmailAddress(),
|
||||||
|
$this->getSiteEmailName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,8 +110,14 @@ class Emailer
|
||||||
*/
|
*/
|
||||||
public function newNotifyMail()
|
public function newNotifyMail()
|
||||||
{
|
{
|
||||||
return new NotifyMailBuilder($this->l10n, $this->baseUrl, $this->config, $this->logger,
|
return new NotifyMailBuilder(
|
||||||
$this->getSiteEmailAddress(), $this->getSiteEmailName());
|
$this->l10n,
|
||||||
|
$this->baseUrl,
|
||||||
|
$this->config,
|
||||||
|
$this->logger,
|
||||||
|
$this->getSiteEmailAddress(),
|
||||||
|
$this->getSiteEmailName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,9 +159,9 @@ class Emailer
|
||||||
|
|
||||||
// generate a mime boundary
|
// generate a mime boundary
|
||||||
$mimeBoundary = rand(0, 9) . '-'
|
$mimeBoundary = rand(0, 9) . '-'
|
||||||
. rand(100000000, 999999999) . '-'
|
. rand(100000000, 999999999) . '-'
|
||||||
. rand(100000000, 999999999) . '=:'
|
. rand(100000000, 999999999) . '=:'
|
||||||
. rand(10000, 99999);
|
. rand(10000, 99999);
|
||||||
|
|
||||||
$messageHeader = $email->getAdditionalMailHeaderString();
|
$messageHeader = $email->getAdditionalMailHeaderString();
|
||||||
if ($countMessageId === 0) {
|
if ($countMessageId === 0) {
|
||||||
|
@ -163,9 +179,9 @@ class Emailer
|
||||||
$textBody = chunk_split(base64_encode($email->getMessage(true)));
|
$textBody = chunk_split(base64_encode($email->getMessage(true)));
|
||||||
$htmlBody = chunk_split(base64_encode($email->getMessage()));
|
$htmlBody = chunk_split(base64_encode($email->getMessage()));
|
||||||
$multipartMessageBody = "--" . $mimeBoundary . "\n" . // plain text section
|
$multipartMessageBody = "--" . $mimeBoundary . "\n" . // plain text section
|
||||||
"Content-Type: text/plain; charset=UTF-8\n" .
|
"Content-Type: text/plain; charset=UTF-8\n" .
|
||||||
"Content-Transfer-Encoding: base64\n\n" .
|
"Content-Transfer-Encoding: base64\n\n" .
|
||||||
$textBody . "\n";
|
$textBody . "\n";
|
||||||
|
|
||||||
if (!$email_textonly && !is_null($email->getMessage())) {
|
if (!$email_textonly && !is_null($email->getMessage())) {
|
||||||
$multipartMessageBody .=
|
$multipartMessageBody .=
|
||||||
|
@ -207,8 +223,7 @@ class Emailer
|
||||||
$hookdata['parameters']
|
$hookdata['parameters']
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->logger->debug('header ' . 'To: ' . $email->getToAddress() . '\n' . $messageHeader);
|
$this->logger->debug('Email message header', ['To' => $email->getToAddress(), 'messageHeader' => $messageHeader, 'return' => ($res) ? 'true' : 'false']);
|
||||||
$this->logger->debug('return value ' . (($res) ? 'true' : 'false'));
|
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ class Temporal
|
||||||
$o .= '<optgroup label="' . DI::l10n()->t($continent) . '">';
|
$o .= '<optgroup label="' . DI::l10n()->t($continent) . '">';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$city = str_replace('_', ' ', DI::l10n()->t($city));
|
$city = str_replace('_', ' ', DI::l10n()->t($city));
|
||||||
$selected = (($value == $current) ? " selected=\"selected\" " : "");
|
$selected = (($value == $current) ? " selected=\"selected\" " : "");
|
||||||
$o .= "<option value=\"$value\" $selected >$city</option>";
|
$o .= "<option value=\"$value\" $selected >$city</option>";
|
||||||
}
|
}
|
||||||
|
@ -137,27 +137,29 @@ class Temporal
|
||||||
|
|
||||||
if ($dob < '0000-01-01') {
|
if ($dob < '0000-01-01') {
|
||||||
$value = '';
|
$value = '';
|
||||||
$age = 0;
|
$age = 0;
|
||||||
} elseif ($dob < '0001-00-00') {
|
} elseif ($dob < '0001-00-00') {
|
||||||
$value = substr($dob, 5);
|
$value = substr($dob, 5);
|
||||||
$age = 0;
|
$age = 0;
|
||||||
} else {
|
} else {
|
||||||
$value = DateTimeFormat::utc($dob, 'Y-m-d');
|
$value = DateTimeFormat::utc($dob, 'Y-m-d');
|
||||||
$age = self::getAgeByTimezone($value, $timezone);
|
$age = self::getAgeByTimezone($value, $timezone);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tpl = Renderer::getMarkupTemplate("field_input.tpl");
|
$tpl = Renderer::getMarkupTemplate("field_input.tpl");
|
||||||
$o = Renderer::replaceMacros($tpl,
|
$o = Renderer::replaceMacros(
|
||||||
|
$tpl,
|
||||||
[
|
[
|
||||||
'$field' => [
|
'$field' => [
|
||||||
'dob',
|
'dob',
|
||||||
DI::l10n()->t('Birthday:'),
|
DI::l10n()->t('Birthday:'),
|
||||||
$value,
|
$value,
|
||||||
intval($age) > 0 ? DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', $age) : '',
|
intval($age) > 0 ? DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', $age) : '',
|
||||||
'',
|
'',
|
||||||
'placeholder="' . DI::l10n()->t('YYYY-MM-DD or MM-DD') . '"'
|
'placeholder="' . DI::l10n()->t('YYYY-MM-DD or MM-DD') . '"'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]);
|
);
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
|
@ -218,26 +220,28 @@ class Temporal
|
||||||
DateTime $maxDate,
|
DateTime $maxDate,
|
||||||
DateTime $defaultDate = null,
|
DateTime $defaultDate = null,
|
||||||
$label,
|
$label,
|
||||||
string $id = 'datetimepicker',
|
string $id = 'datetimepicker',
|
||||||
bool $pickdate = true,
|
bool $pickdate = true,
|
||||||
bool $picktime = true,
|
bool $picktime = true,
|
||||||
string $minfrom = '',
|
string $minfrom = '',
|
||||||
string $maxfrom = '',
|
string $maxfrom = '',
|
||||||
bool $required = false): string
|
bool $required = false
|
||||||
{
|
): string {
|
||||||
// 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;
|
||||||
|
|
||||||
$lang = DI::l10n()->toISO6391(DI::l10n()->getCurrentLang());
|
$lang = DI::l10n()->toISO6391(DI::l10n()->getCurrentLang());
|
||||||
|
|
||||||
// Check if the detected language is supported by the picker
|
// Check if the detected language is supported by the picker
|
||||||
if (!in_array($lang,
|
if (!in_array(
|
||||||
['ar', 'ro', 'id', 'bg', 'fa', 'ru', 'uk', 'en', 'el', 'de', 'nl', 'tr', 'fr', 'es', 'th', 'pl', 'pt', 'ch', 'se', 'kr',
|
$lang,
|
||||||
'it', 'da', 'no', 'ja', 'vi', 'sl', 'cs', 'hu'])) {
|
['ar', 'ro', 'id', 'bg', 'fa', 'ru', 'uk', 'en', 'el', 'de', 'nl', 'tr', 'fr', 'es', 'th', 'pl', 'pt', 'ch', 'se', 'kr',
|
||||||
|
'it', 'da', 'no', 'ja', 'vi', 'sl', 'cs', 'hu']
|
||||||
|
)) {
|
||||||
$lang = 'en';
|
$lang = 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
$o = '';
|
$o = '';
|
||||||
$dateformat = '';
|
$dateformat = '';
|
||||||
|
|
||||||
if ($pickdate) {
|
if ($pickdate) {
|
||||||
|
@ -271,14 +275,14 @@ class Temporal
|
||||||
'placeholder="' . $readable_format . '"'
|
'placeholder="' . $readable_format . '"'
|
||||||
],
|
],
|
||||||
'$datetimepicker' => [
|
'$datetimepicker' => [
|
||||||
'minDate' => $minDate,
|
'minDate' => $minDate,
|
||||||
'maxDate' => $maxDate,
|
'maxDate' => $maxDate,
|
||||||
'defaultDate' => $defaultDate,
|
'defaultDate' => $defaultDate,
|
||||||
'dateformat' => $dateformat,
|
'dateformat' => $dateformat,
|
||||||
'firstDay' => $firstDay,
|
'firstDay' => $firstDay,
|
||||||
'lang' => $lang,
|
'lang' => $lang,
|
||||||
'minfrom' => $minfrom,
|
'minfrom' => $minfrom,
|
||||||
'maxfrom' => $maxfrom,
|
'maxfrom' => $maxfrom,
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -309,7 +313,7 @@ class Temporal
|
||||||
$clock = $clock ?? new SystemClock();
|
$clock = $clock ?? new SystemClock();
|
||||||
|
|
||||||
$localtime = $posted_date . ' UTC';
|
$localtime = $posted_date . ' UTC';
|
||||||
$abs = strtotime($localtime);
|
$abs = strtotime($localtime);
|
||||||
|
|
||||||
if ($abs === false) {
|
if ($abs === false) {
|
||||||
return DI::l10n()->t('never');
|
return DI::l10n()->t('never');
|
||||||
|
@ -323,25 +327,25 @@ class Temporal
|
||||||
}
|
}
|
||||||
|
|
||||||
$isfuture = false;
|
$isfuture = false;
|
||||||
$etime = $now - $abs;
|
$etime = $now - $abs;
|
||||||
|
|
||||||
if ($etime >= 0 && $etime < 1) {
|
if ($etime >= 0 && $etime < 1) {
|
||||||
return $compare_time ? DI::l10n()->t('less than a second ago') : DI::l10n()->t('today');
|
return $compare_time ? DI::l10n()->t('less than a second ago') : DI::l10n()->t('today');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($etime < 0){
|
if ($etime < 0) {
|
||||||
$etime = -$etime;
|
$etime = -$etime;
|
||||||
$isfuture = true;
|
$isfuture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$a = [
|
$a = [
|
||||||
12 * 30 * 24 * 60 * 60 => [DI::l10n()->t('year'), DI::l10n()->t('years')],
|
12 * 30 * 24 * 60 * 60 => [DI::l10n()->t('year'), DI::l10n()->t('years')],
|
||||||
30 * 24 * 60 * 60 => [DI::l10n()->t('month'), DI::l10n()->t('months')],
|
30 * 24 * 60 * 60 => [DI::l10n()->t('month'), DI::l10n()->t('months')],
|
||||||
7 * 24 * 60 * 60 => [DI::l10n()->t('week'), DI::l10n()->t('weeks')],
|
7 * 24 * 60 * 60 => [DI::l10n()->t('week'), DI::l10n()->t('weeks')],
|
||||||
24 * 60 * 60 => [DI::l10n()->t('day'), DI::l10n()->t('days')],
|
24 * 60 * 60 => [DI::l10n()->t('day'), DI::l10n()->t('days')],
|
||||||
60 * 60 => [DI::l10n()->t('hour'), DI::l10n()->t('hours')],
|
60 * 60 => [DI::l10n()->t('hour'), DI::l10n()->t('hours')],
|
||||||
60 => [DI::l10n()->t('minute'), DI::l10n()->t('minutes')],
|
60 => [DI::l10n()->t('minute'), DI::l10n()->t('minutes')],
|
||||||
1 => [DI::l10n()->t('second'), DI::l10n()->t('seconds')],
|
1 => [DI::l10n()->t('second'), DI::l10n()->t('seconds')],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($a as $secs => $str) {
|
foreach ($a as $secs => $str) {
|
||||||
|
@ -349,10 +353,9 @@ class Temporal
|
||||||
if ($d >= 1) {
|
if ($d >= 1) {
|
||||||
$r = floor($d);
|
$r = floor($d);
|
||||||
// translators - e.g. 22 hours ago, 1 minute ago
|
// translators - e.g. 22 hours ago, 1 minute ago
|
||||||
if($isfuture){
|
if($isfuture) {
|
||||||
$format = DI::l10n()->t('in %1$d %2$s');
|
$format = DI::l10n()->t('in %1$d %2$s');
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$format = DI::l10n()->t('%1$d %2$s ago');
|
$format = DI::l10n()->t('%1$d %2$s ago');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +384,7 @@ class Temporal
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$birthdate = new DateTime($dob . ' 00:00:00', new DateTimeZone($timezone));
|
$birthdate = new DateTime($dob . ' 00:00:00', new DateTimeZone($timezone));
|
||||||
$currentDate = new DateTime('now', new DateTimeZone('UTC'));
|
$currentDate = new DateTime('now', new DateTimeZone('UTC'));
|
||||||
|
|
||||||
$interval = $birthdate->diff($currentDate);
|
$interval = $birthdate->diff($currentDate);
|
||||||
|
@ -451,7 +454,7 @@ class Temporal
|
||||||
'October', 'November', 'December'
|
'October', 'November', 'December'
|
||||||
];
|
];
|
||||||
|
|
||||||
$thisyear = DateTimeFormat::localNow('Y');
|
$thisyear = DateTimeFormat::localNow('Y');
|
||||||
$thismonth = DateTimeFormat::localNow('m');
|
$thismonth = DateTimeFormat::localNow('m');
|
||||||
if (!$y) {
|
if (!$y) {
|
||||||
$y = $thisyear;
|
$y = $thisyear;
|
||||||
|
@ -461,11 +464,11 @@ class Temporal
|
||||||
$m = intval($thismonth);
|
$m = intval($thismonth);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dn = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
$dn = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||||
$f = self::getFirstDayInMonth($y, $m);
|
$f = self::getFirstDayInMonth($y, $m);
|
||||||
$l = self::getDaysInMonth($y, $m);
|
$l = self::getDaysInMonth($y, $m);
|
||||||
$d = 1;
|
$d = 1;
|
||||||
$dow = 0;
|
$dow = 0;
|
||||||
$started = false;
|
$started = false;
|
||||||
|
|
||||||
if (($y == $thisyear) && ($m == $thismonth)) {
|
if (($y == $thisyear) && ($m == $thismonth)) {
|
||||||
|
@ -473,9 +476,9 @@ class Temporal
|
||||||
}
|
}
|
||||||
|
|
||||||
$str_month = DI::l10n()->getDay($mtab[$m]);
|
$str_month = DI::l10n()->getDay($mtab[$m]);
|
||||||
$o = '<table class="calendar' . $class . '">';
|
$o = '<table class="calendar' . $class . '">';
|
||||||
$o .= "<caption>$str_month $y</caption><tr>";
|
$o .= "<caption>$str_month $y</caption><tr>";
|
||||||
for ($a = 0; $a < 7; $a ++) {
|
for ($a = 0; $a < 7; $a++) {
|
||||||
$o .= '<th>' . mb_substr(DI::l10n()->getDay($dn[$a]), 0, 3, 'UTF-8') . '</th>';
|
$o .= '<th>' . mb_substr(DI::l10n()->getDay($dn[$a]), 0, 3, 'UTF-8') . '</th>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,13 +499,13 @@ class Temporal
|
||||||
$o .= $day;
|
$o .= $day;
|
||||||
}
|
}
|
||||||
|
|
||||||
$d ++;
|
$d++;
|
||||||
} else {
|
} else {
|
||||||
$o .= ' ';
|
$o .= ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
$o .= '</td>';
|
$o .= '</td>';
|
||||||
$dow ++;
|
$dow++;
|
||||||
if (($dow == 7) && ($d <= $l)) {
|
if (($dow == 7) && ($d <= $l)) {
|
||||||
$dow = 0;
|
$dow = 0;
|
||||||
$o .= '</tr><tr>';
|
$o .= '</tr><tr>';
|
||||||
|
@ -510,7 +513,7 @@ class Temporal
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($dow) {
|
if ($dow) {
|
||||||
for ($a = $dow; $a < 7; $a ++) {
|
for ($a = $dow; $a < 7; $a++) {
|
||||||
$o .= '<td> </td>';
|
$o .= '<td> </td>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,12 @@
|
||||||
|
|
||||||
namespace Friendica\Worker;
|
namespace Friendica\Worker;
|
||||||
|
|
||||||
|
use Friendica\Core\Worker;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||||
use Friendica\Network\HTTPException\NotFoundException;
|
use Friendica\Network\HTTPException\NotFoundException;
|
||||||
|
use Friendica\Util\Network;
|
||||||
|
|
||||||
class AddContact
|
class AddContact
|
||||||
{
|
{
|
||||||
|
@ -39,4 +41,20 @@ class AddContact
|
||||||
DI::logger()->notice('Imagick not found.', ['exception' => $e, 'uid' => $uid, 'url' => $url]);
|
DI::logger()->notice('Imagick not found.', ['exception' => $e, 'uid' => $uid, 'url' => $url]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|int $run_parameters Priority constant or array of options described in Worker::add
|
||||||
|
* @param int $uid User ID
|
||||||
|
* @param string $url Contact link
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function add($run_parameters, int $uid, string $url): int
|
||||||
|
{
|
||||||
|
if (Network::isUrlBlocked($url)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DI::logger()->debug('Add contact', ['uid' => $uid, 'url' => $url]);
|
||||||
|
return Worker::add($run_parameters, 'AddContact', 0, $url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Friendica\Worker;
|
namespace Friendica\Worker;
|
||||||
|
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\Core\Worker;
|
use Friendica\Core\Worker;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
|
@ -145,7 +144,7 @@ class Cron
|
||||||
// Update "blocked" status of servers
|
// Update "blocked" status of servers
|
||||||
Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers');
|
Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers');
|
||||||
|
|
||||||
Addon::reload();
|
DI::addonHelper()->reloadAddons();
|
||||||
|
|
||||||
DI::keyValue()->set('last_cron_daily', time());
|
DI::keyValue()->set('last_cron_daily', time());
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ use Friendica\Database\DBA;
|
||||||
|
|
||||||
// This file is required several times during the test in DbaDefinition which justifies this condition
|
// This file is required several times during the test in DbaDefinition which justifies this condition
|
||||||
if (!defined('DB_UPDATE_VERSION')) {
|
if (!defined('DB_UPDATE_VERSION')) {
|
||||||
define('DB_UPDATE_VERSION', 1576);
|
define('DB_UPDATE_VERSION', 1577);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -1604,7 +1604,7 @@ return [
|
||||||
"indexes" => [
|
"indexes" => [
|
||||||
"PRIMARY" => ["id"],
|
"PRIMARY" => ["id"],
|
||||||
"uid_uri-id" => ["UNIQUE", "uid", "uri-id"],
|
"uid_uri-id" => ["UNIQUE", "uid", "uri-id"],
|
||||||
"uri-id" => ["uri-id"],
|
"uri-id_origin_deleted" => ["uri-id", "origin", "deleted"],
|
||||||
"parent-uri-id" => ["parent-uri-id"],
|
"parent-uri-id" => ["parent-uri-id"],
|
||||||
"thr-parent-id" => ["thr-parent-id"],
|
"thr-parent-id" => ["thr-parent-id"],
|
||||||
"external-id" => ["external-id"],
|
"external-id" => ["external-id"],
|
||||||
|
|
|
@ -1763,7 +1763,8 @@ return [
|
||||||
],
|
],
|
||||||
"query" => "FROM `register`
|
"query" => "FROM `register`
|
||||||
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
|
||||||
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`"
|
INNER JOIN `user` ON `register`.`uid` = `user`.`uid`
|
||||||
|
WHERE `register`.`uid` != 0"
|
||||||
],
|
],
|
||||||
"tag-search-view" => [
|
"tag-search-view" => [
|
||||||
"fields" => [
|
"fields" => [
|
||||||
|
|
|
@ -42,6 +42,12 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
|
||||||
[Dice::INSTANCE => Dice::SELF],
|
[Dice::INSTANCE => Dice::SELF],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
\Friendica\Core\Addon\AddonHelper::class => [
|
||||||
|
'instanceOf' => \Friendica\Core\Addon\AddonProxy::class,
|
||||||
|
'constructParams' => [
|
||||||
|
$basepath . '/addon',
|
||||||
|
],
|
||||||
|
],
|
||||||
\Friendica\Util\BasePath::class => [
|
\Friendica\Util\BasePath::class => [
|
||||||
'constructParams' => [
|
'constructParams' => [
|
||||||
$basepath,
|
$basepath,
|
||||||
|
@ -81,6 +87,7 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
|
||||||
'call' => [
|
'call' => [
|
||||||
['createConfigFileManager', [
|
['createConfigFileManager', [
|
||||||
$basepath,
|
$basepath,
|
||||||
|
$basepath . '/addon',
|
||||||
$serverVars,
|
$serverVars,
|
||||||
], Dice::CHAIN_CALL],
|
], Dice::CHAIN_CALL],
|
||||||
],
|
],
|
||||||
|
@ -182,6 +189,9 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
|
||||||
['create', [], Dice::CHAIN_CALL],
|
['create', [], Dice::CHAIN_CALL],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
\Psr\EventDispatcher\EventDispatcherInterface::class => [
|
||||||
|
'instanceOf' => \Friendica\Event\EventDispatcher::class,
|
||||||
|
],
|
||||||
\Friendica\Core\Logger\Capability\IHaveCallIntrospections::class => [
|
\Friendica\Core\Logger\Capability\IHaveCallIntrospections::class => [
|
||||||
'instanceOf' => \Friendica\Core\Logger\Util\Introspection::class,
|
'instanceOf' => \Friendica\Core\Logger\Util\Introspection::class,
|
||||||
'constructParams' => [
|
'constructParams' => [
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
namespace Friendica\Test;
|
namespace Friendica\Test;
|
||||||
|
|
||||||
use Friendica\Capabilities\ICanCreateResponses;
|
use Friendica\Capabilities\ICanCreateResponses;
|
||||||
use Friendica\Core\Addon;
|
use Friendica\Core\Addon\AddonHelper;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
use Friendica\Core\Hook;
|
use Friendica\Core\Hook;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
@ -124,7 +124,7 @@ abstract class ApiTestCase extends FixtureTestCase
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
$tmpFile,
|
$tmpFile,
|
||||||
base64_decode(
|
base64_decode(
|
||||||
// Empty 1x1 px PNG image
|
// Empty 1x1 px PNG image
|
||||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=='
|
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=='
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -201,7 +201,7 @@ abstract class ApiTestCase extends FixtureTestCase
|
||||||
'plugin_admin' => function_exists($addon . '_addon_admin'),
|
'plugin_admin' => function_exists($addon . '_addon_admin'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Addon::loadAddons();
|
$this->dice->create(AddonHelper::class)->loadAddons();
|
||||||
Hook::loadHooks();
|
Hook::loadHooks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ trait FixtureTestTrait
|
||||||
->addRules(include __DIR__ . '/../static/dependencies.config.php')
|
->addRules(include __DIR__ . '/../static/dependencies.config.php')
|
||||||
->addRule(ConfigFileManager::class, [
|
->addRule(ConfigFileManager::class, [
|
||||||
'instanceOf' => Config::class,
|
'instanceOf' => Config::class,
|
||||||
'call' => [['createConfigFileManager', [$this->root->url(), $server,], Dice::CHAIN_CALL]]])
|
'call' => [['createConfigFileManager', [$this->root->url(), $this->root->url() . '/addon', $server,], Dice::CHAIN_CALL]]])
|
||||||
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
|
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
|
||||||
->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null])
|
->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null])
|
||||||
->addRule(Arguments::class, [
|
->addRule(Arguments::class, [
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?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\Test\Unit\Core\Addon;
|
||||||
|
|
||||||
|
use Friendica\Core\Addon\AddonInfo;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class AddonInfoTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testFromArrayCreatesObject(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'id' => '',
|
||||||
|
'name' => '',
|
||||||
|
'description' => '',
|
||||||
|
'authors' => [],
|
||||||
|
'maintainers' => [],
|
||||||
|
'version' => '',
|
||||||
|
'status' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->assertInstanceOf(AddonInfo::class, AddonInfo::fromArray($data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetterReturningCorrectValues(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'id' => 'test',
|
||||||
|
'name' => 'Test-Addon',
|
||||||
|
'description' => 'This is an addon for tests',
|
||||||
|
'authors' => [['name' => 'Sam']],
|
||||||
|
'maintainers' => [['name' => 'Sam', 'link' => 'https://example.com']],
|
||||||
|
'version' => '0.1',
|
||||||
|
'status' => 'In Development',
|
||||||
|
];
|
||||||
|
|
||||||
|
$info = AddonInfo::fromArray($data);
|
||||||
|
|
||||||
|
$this->assertSame($data['id'], $info->getId());
|
||||||
|
$this->assertSame($data['name'], $info->getName());
|
||||||
|
$this->assertSame($data['description'], $info->getDescription());
|
||||||
|
$this->assertSame($data['description'], $info->getDescription());
|
||||||
|
$this->assertSame($data['authors'], $info->getAuthors());
|
||||||
|
$this->assertSame($data['maintainers'], $info->getMaintainers());
|
||||||
|
$this->assertSame($data['version'], $info->getVersion());
|
||||||
|
$this->assertSame($data['status'], $info->getStatus());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
<?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\Test\Unit\Core\Hooks;
|
||||||
|
|
||||||
|
use Friendica\Core\Config\Util\ConfigFileManager;
|
||||||
|
use Friendica\Core\Hooks\HookEventBridge;
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
|
use Friendica\Event\ConfigLoadedEvent;
|
||||||
|
use Friendica\Event\Event;
|
||||||
|
use Friendica\Event\HtmlFilterEvent;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class HookEventBridgeTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testGetStaticSubscribedEventsReturnsStaticMethods(): void
|
||||||
|
{
|
||||||
|
$expected = [
|
||||||
|
Event::INIT => 'onNamedEvent',
|
||||||
|
ConfigLoadedEvent::CONFIG_LOADED => 'onConfigLoadedEvent',
|
||||||
|
ArrayFilterEvent::APP_MENU => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::NAV_INFO => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::FEATURE_ENABLED => 'onArrayFilterEvent',
|
||||||
|
ArrayFilterEvent::FEATURE_GET => 'onArrayFilterEvent',
|
||||||
|
HtmlFilterEvent::HEAD => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::FOOTER => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::PAGE_HEADER => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::PAGE_CONTENT_TOP => 'onHtmlFilterEvent',
|
||||||
|
HtmlFilterEvent::PAGE_END => 'onHtmlFilterEvent',
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->assertSame(
|
||||||
|
$expected,
|
||||||
|
HookEventBridge::getStaticSubscribedEvents()
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($expected as $methodName) {
|
||||||
|
$this->assertTrue(
|
||||||
|
method_exists(HookEventBridge::class, $methodName),
|
||||||
|
$methodName . '() is not defined'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
(new \ReflectionMethod(HookEventBridge::class, $methodName))->isStatic(),
|
||||||
|
$methodName . '() is not static'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getNamedEventData(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['test', 'test'],
|
||||||
|
[Event::INIT, 'init_1'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getNamedEventData
|
||||||
|
*/
|
||||||
|
public function testOnNamedEventCallsHook($name, $expected): void
|
||||||
|
{
|
||||||
|
$event = new Event($name);
|
||||||
|
|
||||||
|
$reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
|
||||||
|
$reflectionProperty->setAccessible(true);
|
||||||
|
|
||||||
|
$reflectionProperty->setValue(null, function (string $name, $data) use ($expected) {
|
||||||
|
$this->assertSame($expected, $name);
|
||||||
|
$this->assertSame('', $data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
});
|
||||||
|
|
||||||
|
HookEventBridge::onNamedEvent($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getConfigLoadedEventData(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['test', 'test'],
|
||||||
|
[ConfigLoadedEvent::CONFIG_LOADED, 'load_config'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getConfigLoadedEventData
|
||||||
|
*/
|
||||||
|
public function testOnConfigLoadedEventCallsHookWithCorrectValue($name, $expected): void
|
||||||
|
{
|
||||||
|
$config = $this->createStub(ConfigFileManager::class);
|
||||||
|
|
||||||
|
$event = new ConfigLoadedEvent($name, $config);
|
||||||
|
|
||||||
|
$reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
|
||||||
|
$reflectionProperty->setAccessible(true);
|
||||||
|
|
||||||
|
$reflectionProperty->setValue(null, function (string $name, $data) use ($expected, $config) {
|
||||||
|
$this->assertSame($expected, $name);
|
||||||
|
$this->assertSame($config, $data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
});
|
||||||
|
|
||||||
|
HookEventBridge::onConfigLoadedEvent($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getArrayFilterEventData(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['test', 'test'],
|
||||||
|
[ArrayFilterEvent::APP_MENU, 'app_menu'],
|
||||||
|
[ArrayFilterEvent::NAV_INFO, 'nav_info'],
|
||||||
|
[ArrayFilterEvent::FEATURE_ENABLED, 'isEnabled'],
|
||||||
|
[ArrayFilterEvent::FEATURE_GET, 'get'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getArrayFilterEventData
|
||||||
|
*/
|
||||||
|
public function testOnArrayFilterEventCallsHookWithCorrectValue($name, $expected): void
|
||||||
|
{
|
||||||
|
$event = new ArrayFilterEvent($name, ['original']);
|
||||||
|
|
||||||
|
$reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
|
||||||
|
$reflectionProperty->setAccessible(true);
|
||||||
|
|
||||||
|
$reflectionProperty->setValue(null, function (string $name, $data) use ($expected) {
|
||||||
|
$this->assertSame($expected, $name);
|
||||||
|
$this->assertSame(['original'], $data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
});
|
||||||
|
|
||||||
|
HookEventBridge::onArrayFilterEvent($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getHtmlFilterEventData(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['test', 'test'],
|
||||||
|
[HtmlFilterEvent::HEAD, 'head'],
|
||||||
|
[HtmlFilterEvent::FOOTER, 'footer'],
|
||||||
|
[HtmlFilterEvent::PAGE_HEADER, 'page_header'],
|
||||||
|
[HtmlFilterEvent::PAGE_CONTENT_TOP, 'page_content_top'],
|
||||||
|
[HtmlFilterEvent::PAGE_END, 'page_end'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getHtmlFilterEventData
|
||||||
|
*/
|
||||||
|
public function testOnHtmlFilterEventCallsHookWithCorrectValue($name, $expected): void
|
||||||
|
{
|
||||||
|
$event = new HtmlFilterEvent($name, 'original');
|
||||||
|
|
||||||
|
$reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
|
||||||
|
$reflectionProperty->setAccessible(true);
|
||||||
|
|
||||||
|
$reflectionProperty->setValue(null, function (string $name, $data) use ($expected) {
|
||||||
|
$this->assertSame($expected, $name);
|
||||||
|
$this->assertSame('original', $data);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
});
|
||||||
|
|
||||||
|
HookEventBridge::onHtmlFilterEvent($event);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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\Test\Unit\Event;
|
||||||
|
|
||||||
|
use Friendica\Event\ArrayFilterEvent;
|
||||||
|
use Friendica\Event\NamedEvent;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ArrayFilterEventTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testImplementationOfInstances(): void
|
||||||
|
{
|
||||||
|
$event = new ArrayFilterEvent('test', []);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(NamedEvent::class, $event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPublicConstants(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[ArrayFilterEvent::APP_MENU, 'friendica.data.app_menu'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getPublicConstants
|
||||||
|
*/
|
||||||
|
public function testPublicConstantsAreAvailable($value, $expected): void
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetNameReturnsName(): void
|
||||||
|
{
|
||||||
|
$event = new ArrayFilterEvent('test', []);
|
||||||
|
|
||||||
|
$this->assertSame('test', $event->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetArrayReturnsCorrectString(): void
|
||||||
|
{
|
||||||
|
$data = ['original'];
|
||||||
|
|
||||||
|
$event = new ArrayFilterEvent('test', $data);
|
||||||
|
|
||||||
|
$this->assertSame($data, $event->getArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetArrayUpdatesHtml(): void
|
||||||
|
{
|
||||||
|
$event = new ArrayFilterEvent('test', ['original']);
|
||||||
|
|
||||||
|
$expected = ['updated'];
|
||||||
|
|
||||||
|
$event->setArray($expected);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $event->getArray());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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\Test\Unit\Event;
|
||||||
|
|
||||||
|
use Friendica\Core\Config\Util\ConfigFileManager;
|
||||||
|
use Friendica\Event\ConfigLoadedEvent;
|
||||||
|
use Friendica\Event\NamedEvent;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ConfigLoadedEventTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testImplementationOfInstances(): void
|
||||||
|
{
|
||||||
|
$event = new ConfigLoadedEvent('test', $this->createStub(ConfigFileManager::class));
|
||||||
|
|
||||||
|
$this->assertInstanceOf(NamedEvent::class, $event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPublicConstants(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[ConfigLoadedEvent::CONFIG_LOADED, 'friendica.config_loaded'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getPublicConstants
|
||||||
|
*/
|
||||||
|
public function testPublicConstantsAreAvailable($value, $expected): void
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetNameReturnsName(): void
|
||||||
|
{
|
||||||
|
$event = new ConfigLoadedEvent('test', $this->createStub(ConfigFileManager::class));
|
||||||
|
|
||||||
|
$this->assertSame('test', $event->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetConfigReturnsCorrectString(): void
|
||||||
|
{
|
||||||
|
$config = $this->createStub(ConfigFileManager::class);
|
||||||
|
|
||||||
|
$event = new ConfigLoadedEvent('test', $config);
|
||||||
|
|
||||||
|
$this->assertSame($config, $event->getConfig());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?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\Test\Unit\Event;
|
||||||
|
|
||||||
|
use Friendica\Event\Event;
|
||||||
|
use Friendica\Event\EventDispatcher;
|
||||||
|
use Friendica\Event\NamedEvent;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
|
|
||||||
|
class EventDispatcherTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testImplementationOfInstances(): void
|
||||||
|
{
|
||||||
|
$eventDispatcher = new EventDispatcher();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(EventDispatcherInterface::class, $eventDispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDispatchANamedEventUsesNameAsEventName(): void
|
||||||
|
{
|
||||||
|
$eventDispatcher = new EventDispatcher();
|
||||||
|
|
||||||
|
$eventDispatcher->addListener('test', function (NamedEvent $event) {
|
||||||
|
$this->assertSame('test', $event->getName());
|
||||||
|
});
|
||||||
|
|
||||||
|
$eventDispatcher->dispatch(new Event('test'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Test\Unit\Event;
|
||||||
|
|
||||||
|
use Friendica\Event\Event;
|
||||||
|
use Friendica\Event\NamedEvent;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class EventTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testImplementationOfInstances(): void
|
||||||
|
{
|
||||||
|
$event = new Event('test');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(NamedEvent::class, $event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPublicConstants(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[Event::INIT, 'friendica.init'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getPublicConstants
|
||||||
|
*/
|
||||||
|
public function testPublicConstantsAreAvailable($value, $expected): void
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetNameReturnsName(): void
|
||||||
|
{
|
||||||
|
$event = new Event('test');
|
||||||
|
|
||||||
|
$this->assertSame('test', $event->getName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?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\Test\Unit\Event;
|
||||||
|
|
||||||
|
use Friendica\Event\HtmlFilterEvent;
|
||||||
|
use Friendica\Event\NamedEvent;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class HtmlFilterEventTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testImplementationOfInstances(): void
|
||||||
|
{
|
||||||
|
$event = new HtmlFilterEvent('test', 'original');
|
||||||
|
|
||||||
|
$this->assertInstanceOf(NamedEvent::class, $event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPublicConstants(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[HtmlFilterEvent::HEAD, 'friendica.html.head'],
|
||||||
|
[HtmlFilterEvent::FOOTER, 'friendica.html.footer'],
|
||||||
|
[HtmlFilterEvent::PAGE_CONTENT_TOP, 'friendica.html.page_content_top'],
|
||||||
|
[HtmlFilterEvent::PAGE_END, 'friendica.html.page_end'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getPublicConstants
|
||||||
|
*/
|
||||||
|
public function testPublicConstantsAreAvailable($value, $expected): void
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetNameReturnsName(): void
|
||||||
|
{
|
||||||
|
$event = new HtmlFilterEvent('test', '');
|
||||||
|
|
||||||
|
$this->assertSame('test', $event->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetHtmlReturnsCorrectString(): void
|
||||||
|
{
|
||||||
|
$data = 'original';
|
||||||
|
|
||||||
|
$event = new HtmlFilterEvent('test', $data);
|
||||||
|
|
||||||
|
$this->assertSame($data, $event->getHtml());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetHtmlUpdatesHtml(): void
|
||||||
|
{
|
||||||
|
$event = new HtmlFilterEvent('test', 'original');
|
||||||
|
|
||||||
|
$expected = 'updated';
|
||||||
|
|
||||||
|
$event->setHtml($expected);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $event->getHtml());
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
declare(strict_types = 1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Friendica\Test\Unit\Util;
|
namespace Friendica\Test\Unit\Util;
|
||||||
|
|
||||||
|
@ -16,48 +16,48 @@ class BasePathTest extends TestCase
|
||||||
{
|
{
|
||||||
public static function getDataPaths(): array
|
public static function getDataPaths(): array
|
||||||
{
|
{
|
||||||
$basePath = dirname(__DIR__, 3);
|
$basePath = dirname(__DIR__, 3);
|
||||||
$configPath = $basePath . DIRECTORY_SEPARATOR . 'config';
|
$configPath = $basePath . DIRECTORY_SEPARATOR . 'config';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'fullPath' => [
|
'fullPath' => [
|
||||||
'server' => [],
|
'server' => [],
|
||||||
'baseDir' => $configPath,
|
'baseDir' => $configPath,
|
||||||
'expected' => $configPath,
|
'expected' => $configPath,
|
||||||
],
|
],
|
||||||
'relative' => [
|
'relative' => [
|
||||||
'server' => [],
|
'server' => [],
|
||||||
'baseDir' => 'config',
|
'baseDir' => 'config',
|
||||||
'expected' => $configPath,
|
'expected' => $configPath,
|
||||||
],
|
],
|
||||||
'document_root' => [
|
'document_root' => [
|
||||||
'server' => [
|
'server' => [
|
||||||
'DOCUMENT_ROOT' => $configPath,
|
'DOCUMENT_ROOT' => $configPath,
|
||||||
],
|
],
|
||||||
'baseDir' => '/noooop',
|
'baseDir' => '/noooop',
|
||||||
'expected' => $configPath,
|
'expected' => $configPath,
|
||||||
],
|
],
|
||||||
'pwd' => [
|
'pwd' => [
|
||||||
'server' => [
|
'server' => [
|
||||||
'PWD' => $configPath,
|
'PWD' => $configPath,
|
||||||
],
|
],
|
||||||
'baseDir' => '/noooop',
|
'baseDir' => '/noooop',
|
||||||
'expected' => $configPath,
|
'expected' => $configPath,
|
||||||
],
|
],
|
||||||
'no_overwrite' => [
|
'no_overwrite' => [
|
||||||
'server' => [
|
'server' => [
|
||||||
'DOCUMENT_ROOT' => $basePath,
|
'DOCUMENT_ROOT' => $basePath,
|
||||||
'PWD' => $basePath,
|
'PWD' => $basePath,
|
||||||
],
|
],
|
||||||
'baseDir' => 'config',
|
'baseDir' => 'config',
|
||||||
'expected' => $configPath,
|
'expected' => $configPath,
|
||||||
],
|
],
|
||||||
'no_overwrite_if_invalid' => [
|
'no_overwrite_if_invalid' => [
|
||||||
'server' => [
|
'server' => [
|
||||||
'DOCUMENT_ROOT' => '/nopopop',
|
'DOCUMENT_ROOT' => '/nopopop',
|
||||||
'PWD' => $configPath,
|
'PWD' => $configPath,
|
||||||
],
|
],
|
||||||
'baseDir' => '/noatgawe22fafa',
|
'baseDir' => '/noatgawe22fafa',
|
||||||
'expected' => $configPath,
|
'expected' => $configPath,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue