Compare commits
21 Commits
5319bd35a5
...
9a061411c4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a061411c4 | ||
|
|
c13476bcd0 | ||
|
|
47e55d8f48 | ||
|
|
2e75454bb0 | ||
| 30f3dd37d0 | |||
|
|
f8fece3a93 | ||
|
|
8af2d4f3f7 | ||
|
|
ec08e04c0d | ||
|
|
3f075992ec | ||
|
|
879adc63ed | ||
|
|
503fec2f1b | ||
|
|
683098116c | ||
|
|
932a5a028b | ||
|
|
0ce8dcdfbe | ||
|
|
5a22d7c152 | ||
|
|
3a7abf9a73 | ||
|
|
6cd429c808 | ||
|
|
f45e6b5c3b | ||
|
|
f7c940a828 | ||
|
|
9a9b4a7bcb | ||
|
|
1cbf71637f |
6
.gitattributes
vendored
Normal file
6
.gitattributes
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/.github export-ignore
|
||||
/Build export-ignore
|
||||
/Tests export-ignore
|
||||
/.gitattributes export-ignore
|
||||
/.gitignore export-ignore
|
||||
/.gitlab-ci.yml export-ignore
|
||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
.cache/
|
||||
.idea/
|
||||
Build/
|
||||
bin/
|
||||
Documentation-GENERATED-temp/
|
||||
typo3temp/
|
||||
var/
|
||||
public/
|
||||
vendor/
|
||||
composer.lock
|
||||
.php-cs-fixer.cache
|
||||
0
.gitlab-ci.yml
Executable file → Normal file
0
.gitlab-ci.yml
Executable file → Normal file
412
Build/Scripts/additionalTests.sh
Executable file
412
Build/Scripts/additionalTests.sh
Executable file
@ -0,0 +1,412 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# TYPO3 core test runner based on docker or podman
|
||||
#
|
||||
|
||||
trap 'cleanUp;exit 2' SIGINT
|
||||
|
||||
waitFor() {
|
||||
local HOST=${1}
|
||||
local PORT=${2}
|
||||
local TESTCOMMAND="
|
||||
COUNT=0;
|
||||
while ! nc -z ${HOST} ${PORT}; do
|
||||
if [ \"\${COUNT}\" -gt 10 ]; then
|
||||
echo \"Can not connect to ${HOST} port ${PORT}. Aborting.\";
|
||||
exit 1;
|
||||
fi;
|
||||
sleep 1;
|
||||
COUNT=\$((COUNT + 1));
|
||||
done;
|
||||
"
|
||||
${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name wait-for-${SUFFIX} ${XDEBUG_MODE} -e XDEBUG_CONFIG="${XDEBUG_CONFIG}" ${IMAGE_ALPINE} /bin/sh -c "${TESTCOMMAND}"
|
||||
if [[ $? -gt 0 ]]; then
|
||||
kill -SIGINT -$$
|
||||
fi
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
ATTACHED_CONTAINERS=$(${CONTAINER_BIN} ps --filter network=${NETWORK} --format='{{.Names}}')
|
||||
for ATTACHED_CONTAINER in ${ATTACHED_CONTAINERS}; do
|
||||
${CONTAINER_BIN} kill ${ATTACHED_CONTAINER} >/dev/null
|
||||
done
|
||||
if [ ${CONTAINER_BIN} = "docker" ]; then
|
||||
${CONTAINER_BIN} network rm ${NETWORK} >/dev/null
|
||||
else
|
||||
${CONTAINER_BIN} network rm -f ${NETWORK} >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
handleDbmsOptions() {
|
||||
# -a, -d, -i depend on each other. Validate input combinations and set defaults.
|
||||
case ${DBMS} in
|
||||
mariadb)
|
||||
[ -z "${DATABASE_DRIVER}" ] && DATABASE_DRIVER="mysqli"
|
||||
if [ "${DATABASE_DRIVER}" != "mysqli" ] && [ "${DATABASE_DRIVER}" != "pdo_mysql" ]; then
|
||||
echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
[ -z "${DBMS_VERSION}" ] && DBMS_VERSION="10.4"
|
||||
if ! [[ ${DBMS_VERSION} =~ ^(10.4|10.5|10.6|10.7|10.8|10.9|10.10|10.11|11.0|11.1)$ ]]; then
|
||||
echo "Invalid combination -d ${DBMS} -i ${DBMS_VERSION}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
mysql)
|
||||
[ -z "${DATABASE_DRIVER}" ] && DATABASE_DRIVER="mysqli"
|
||||
if [ "${DATABASE_DRIVER}" != "mysqli" ] && [ "${DATABASE_DRIVER}" != "pdo_mysql" ]; then
|
||||
echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
[ -z "${DBMS_VERSION}" ] && DBMS_VERSION="8.0"
|
||||
if ! [[ ${DBMS_VERSION} =~ ^(8.0|8.1|8.2|8.3)$ ]]; then
|
||||
echo "Invalid combination -d ${DBMS} -i ${DBMS_VERSION}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
postgres)
|
||||
if [ -n "${DATABASE_DRIVER}" ]; then
|
||||
echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
[ -z "${DBMS_VERSION}" ] && DBMS_VERSION="10"
|
||||
if ! [[ ${DBMS_VERSION} =~ ^(10|11|12|13|14|15|16)$ ]]; then
|
||||
echo "Invalid combination -d ${DBMS} -i ${DBMS_VERSION}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
sqlite)
|
||||
if [ -n "${DATABASE_DRIVER}" ]; then
|
||||
echo "Invalid combination -d ${DBMS} -a ${DATABASE_DRIVER}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "${DBMS_VERSION}" ]; then
|
||||
echo "Invalid combination -d ${DBMS} -i ${DATABASE_DRIVER}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option -d ${DBMS}" >&2
|
||||
echo >&2
|
||||
echo "Use \".Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
cleanBuildFiles() {
|
||||
echo -n "Clean builds ... "
|
||||
rm -rf \
|
||||
.cache \
|
||||
Build/JavaScript \
|
||||
Build/node_modules \
|
||||
Documentation-GENERATED-temp
|
||||
echo "done"
|
||||
}
|
||||
|
||||
cleanTestFiles() {
|
||||
# test related
|
||||
echo -n "Clean test related files ... "
|
||||
rm -rf \
|
||||
bin/ \
|
||||
Build/phpunit \
|
||||
public/ \
|
||||
typo3temp/ \
|
||||
vendor/ \
|
||||
var/ \
|
||||
composer.lock
|
||||
git checkout composer.json
|
||||
echo "done"
|
||||
}
|
||||
|
||||
getPhpImageVersion() {
|
||||
case ${1} in
|
||||
8.1)
|
||||
echo -n "2.12"
|
||||
;;
|
||||
8.2)
|
||||
echo -n "1.12"
|
||||
;;
|
||||
8.3)
|
||||
echo -n "1.13"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
loadHelp() {
|
||||
# Load help text into $HELP
|
||||
read -r -d '' HELP <<EOF
|
||||
TYPO3 core test runner. Execute acceptance, unit, functional and other test suites in
|
||||
a container based test environment. Handles execution of single test files, sending
|
||||
xdebug information to a local IDE and more.
|
||||
|
||||
Usage: $0 [options] [file]
|
||||
|
||||
Options:
|
||||
-s <...>
|
||||
Specifies the test suite to run
|
||||
- buildDocumentation: test build the documentation
|
||||
- clean: clean up build, cache and testing related files and folders
|
||||
- composerInstallPackage: install a package with composer
|
||||
- lintXliff: test XLIFF language files
|
||||
|
||||
-b <docker|podman>
|
||||
Container environment:
|
||||
- podman (default)
|
||||
- docker
|
||||
|
||||
-p <8.1|8.2|8.3>
|
||||
Specifies the PHP minor version to be used
|
||||
- 8.1: use PHP 8.1
|
||||
- 8.2 (default): use PHP 8.2
|
||||
- 8.3: use PHP 8.3
|
||||
|
||||
-q
|
||||
package to be installed by composer
|
||||
|
||||
-r
|
||||
parameters used with composer commands
|
||||
|
||||
-h
|
||||
Show this help.
|
||||
|
||||
-v
|
||||
Enable verbose script output. Shows variables and docker commands.
|
||||
|
||||
Examples:
|
||||
# Run install a package with composer
|
||||
./Build/Scripts/additionalTests.sh -p 8.2 -s composerInstallPackage "typo3/cms-core:13.0"
|
||||
|
||||
# Test build the documentation
|
||||
./Build/Scripts/additionalTests.sh -s buildDocumentation
|
||||
|
||||
# Test XLIFF language files
|
||||
./Build/Scripts/additionalTests.sh -s lintXliff
|
||||
EOF
|
||||
}
|
||||
|
||||
# Test if docker exists, else exit out with error
|
||||
if ! type "docker" >/dev/null; then
|
||||
echo "This script relies on docker. Please install" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Option defaults
|
||||
TEST_SUITE="unit"
|
||||
DBMS="sqlite"
|
||||
DBMS_VERSION=""
|
||||
PHP_VERSION="8.1"
|
||||
PHP_XDEBUG_ON=0
|
||||
PHP_XDEBUG_PORT=9003
|
||||
ACCEPTANCE_HEADLESS=1
|
||||
EXTRA_TEST_OPTIONS=""
|
||||
PHPUNIT_RANDOM=""
|
||||
CGLCHECK_DRY_RUN=""
|
||||
DATABASE_DRIVER=""
|
||||
CHUNKS=0
|
||||
THISCHUNK=0
|
||||
CONTAINER_BIN="docker"
|
||||
|
||||
SCRIPT_VERBOSE=0
|
||||
COMPOSER_PACKAGE=""
|
||||
COMPOSER_PARAMETER=""
|
||||
|
||||
# Option parsing updates above default vars
|
||||
# Reset in case getopts has been used previously in the shell
|
||||
OPTIND=1
|
||||
# Array for invalid options
|
||||
INVALID_OPTIONS=()
|
||||
# Simple option parsing based on getopts (! not getopt)
|
||||
while getopts ":s:p:q:r:hv" OPT; do
|
||||
case ${OPT} in
|
||||
s)
|
||||
TEST_SUITE=${OPTARG}
|
||||
;;
|
||||
p)
|
||||
PHP_VERSION=${OPTARG}
|
||||
if ! [[ ${PHP_VERSION} =~ ^(8.1|8.2|8.3)$ ]]; then
|
||||
INVALID_OPTIONS+=("${OPTARG}")
|
||||
fi
|
||||
;;
|
||||
q)
|
||||
COMPOSER_PACKAGE=${OPTARG}
|
||||
;;
|
||||
r)
|
||||
COMPOSER_PARAMETER=${OPTARG}
|
||||
;;
|
||||
h)
|
||||
loadHelp
|
||||
echo "${HELP}"
|
||||
exit 0
|
||||
;;
|
||||
v)
|
||||
SCRIPT_VERBOSE=1
|
||||
;;
|
||||
\?)
|
||||
INVALID_OPTIONS+=("${OPTARG}")
|
||||
;;
|
||||
:)
|
||||
INVALID_OPTIONS+=("${OPTARG}")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Exit on invalid options
|
||||
if [ ${#INVALID_OPTIONS[@]} -ne 0 ]; then
|
||||
echo "Invalid option(s):" >&2
|
||||
for I in "${INVALID_OPTIONS[@]}"; do
|
||||
echo "-"${I} >&2
|
||||
done
|
||||
echo >&2
|
||||
echo "Use \"./Build/Scripts/runTests.sh -h\" to display help and valid options" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
handleDbmsOptions
|
||||
|
||||
COMPOSER_ROOT_VERSION="7.0.1"
|
||||
HOST_UID=$(id -u)
|
||||
HOST_PID=$(id -g)
|
||||
USERSET=""
|
||||
if [ $(uname) != "Darwin" ]; then
|
||||
USERSET="--user $HOST_UID"
|
||||
fi
|
||||
|
||||
# Go to the directory this script is located, so everything else is relative
|
||||
# to this dir, no matter from where this script is called, then go up two dirs.
|
||||
THIS_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$THIS_SCRIPT_DIR" || exit 1
|
||||
cd ../../ || exit 1
|
||||
CORE_ROOT="${PWD}"
|
||||
|
||||
# Create .cache dir: composer and various npm jobs need this.
|
||||
mkdir -p .cache
|
||||
mkdir -p typo3temp/var/tests
|
||||
|
||||
PHPSTAN_CONFIG_FILE="phpstan.local.neon"
|
||||
IMAGE_PREFIX="docker.io/"
|
||||
# Non-CI fetches TYPO3 images (php and nodejs) from ghcr.io
|
||||
TYPO3_IMAGE_PREFIX="ghcr.io/"
|
||||
CONTAINER_INTERACTIVE="-it --init"
|
||||
|
||||
IS_CORE_CI=0
|
||||
# ENV var "CI" is set by gitlab-ci. We use it here to distinct 'local' and 'CI' environment.
|
||||
if [ "${CI}" == "true" ]; then
|
||||
IS_CORE_CI=1
|
||||
PHPSTAN_CONFIG_FILE="phpstan.ci.neon"
|
||||
# In CI, we need to pull images from docker.io for the registry proxy to kick in.
|
||||
TYPO3_IMAGE_PREFIX="docker.io/"
|
||||
IMAGE_PREFIX=""
|
||||
CONTAINER_INTERACTIVE=""
|
||||
fi
|
||||
|
||||
|
||||
IMAGE_APACHE="${TYPO3_IMAGE_PREFIX}typo3/core-testing-apache24:latest"
|
||||
IMAGE_PHP="${TYPO3_IMAGE_PREFIX}typo3/core-testing-$(echo "php${PHP_VERSION}" | sed -e 's/\.//'):latest"
|
||||
IMAGE_NODEJS="${TYPO3_IMAGE_PREFIX}typo3/core-testing-nodejs18:latest"
|
||||
IMAGE_NODEJS_CHROME="${TYPO3_IMAGE_PREFIX}typo3/core-testing-nodejs18-chrome:latest"
|
||||
IMAGE_ALPINE="${IMAGE_PREFIX}alpine:3.8"
|
||||
IMAGE_SELENIUM="${IMAGE_PREFIX}selenium/standalone-chrome:4.11.0-20230801"
|
||||
IMAGE_REDIS="${IMAGE_PREFIX}redis:4-alpine"
|
||||
IMAGE_MEMCACHED="${IMAGE_PREFIX}memcached:1.5-alpine"
|
||||
IMAGE_MARIADB="${IMAGE_PREFIX}mariadb:${DBMS_VERSION}"
|
||||
IMAGE_MYSQL="${IMAGE_PREFIX}mysql:${DBMS_VERSION}"
|
||||
IMAGE_POSTGRES="${IMAGE_PREFIX}postgres:${DBMS_VERSION}-alpine"
|
||||
IMAGE_DOCUMENTATION="ghcr.io/t3docs/render-documentation:v3.0.dev30"
|
||||
IMAGE_XLIFF="container.registry.gitlab.typo3.org/qa/example-extension:typo3-ci-xliff-lint"
|
||||
|
||||
# Detect arm64 to use seleniarm image.
|
||||
ARCH=$(uname -m)
|
||||
if [ ${ARCH} = "arm64" ]; then
|
||||
IMAGE_SELENIUM="${IMAGE_PREFIX}seleniarm/standalone-chromium:4.1.2-20220227"
|
||||
echo "Architecture" ${ARCH} "requires" ${IMAGE_SELENIUM} "to run acceptance tests."
|
||||
fi
|
||||
|
||||
# Set $1 to first mass argument, this is the optional test file or test directory to execute
|
||||
shift $((OPTIND - 1))
|
||||
TEST_FILE=${1}
|
||||
|
||||
SUFFIX=$(echo $RANDOM)
|
||||
NETWORK="typo3-core-${SUFFIX}"
|
||||
${CONTAINER_BIN} network create ${NETWORK} >/dev/null
|
||||
|
||||
CONTAINER_COMMON_PARAMS="${CONTAINER_INTERACTIVE} --rm --network $NETWORK --add-host "host.docker.internal:host-gateway" $USERSET -v ${CORE_ROOT}:${CORE_ROOT}"
|
||||
|
||||
if [ ${PHP_XDEBUG_ON} -eq 0 ]; then
|
||||
XDEBUG_MODE="-e XDEBUG_MODE=off"
|
||||
XDEBUG_CONFIG=" "
|
||||
PHP_FPM_OPTIONS="-d xdebug.mode=off"
|
||||
else
|
||||
XDEBUG_MODE="-e XDEBUG_MODE=debug -e XDEBUG_TRIGGER=foo"
|
||||
XDEBUG_CONFIG="client_port=${PHP_XDEBUG_PORT} client_host=host.docker.internal"
|
||||
PHP_FPM_OPTIONS="-d xdebug.mode=debug -d xdebug.start_with_request=yes -d xdebug.client_host=host.docker.internal -d xdebug.client_port=${PHP_XDEBUG_PORT} -d memory_limit=256M"
|
||||
fi
|
||||
# if host uid is root, like for example on ci we need to set additional php-fpm command line options
|
||||
if [ "${HOST_UID}" = 0 ]; then
|
||||
PHP_FPM_OPTIONS+=" --allow-to-run-as-root"
|
||||
fi
|
||||
|
||||
# Suite execution
|
||||
case ${TEST_SUITE} in
|
||||
buildDocumentation)
|
||||
${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} -v ${CORE_ROOT}:/project ghcr.io/typo3-documentation/render-guides:latest render Documentation
|
||||
SUITE_EXIT_CODE=$?
|
||||
;;
|
||||
clean)
|
||||
cleanBuildFiles
|
||||
cleanTestFiles
|
||||
;;
|
||||
composerInstallPackage)
|
||||
COMMAND="[ ${SCRIPT_VERBOSE} -eq 1 ] && set -x; composer require -W -n ${COMPOSER_PARAMETER} ${COMPOSER_PACKAGE};"
|
||||
${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name composer-require-package-${SUFFIX} -w ${CORE_ROOT} -e COMPOSER_CACHE_DIR=${CORE_ROOT}/Build/.cache/composer ${IMAGE_PHP} /bin/sh -c "${COMMAND}"
|
||||
SUITE_EXIT_CODE=$?
|
||||
;;
|
||||
lintXliff)
|
||||
COMMAND="[ ${SCRIPT_VERBOSE} -eq 1 ] && set -x; xmllint --schema /xliff-core-1.2-strict.xsd --noout *.xlf;"
|
||||
${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --name lint-xliff-${SUFFIX} -w ${CORE_ROOT}/Resources/Private/Language ${IMAGE_XLIFF} /bin/sh -c "${COMMAND}"
|
||||
SUITE_EXIT_CODE=$?
|
||||
;;
|
||||
esac
|
||||
|
||||
cleanUp
|
||||
|
||||
# Print summary
|
||||
echo "" >&2
|
||||
echo "###########################################################################" >&2
|
||||
echo "Result of ${TEST_SUITE}" >&2
|
||||
if [[ ${IS_CORE_CI} -eq 1 ]]; then
|
||||
echo "Environment: CI" >&2
|
||||
else
|
||||
echo "Environment: local" >&2
|
||||
fi
|
||||
echo "PHP: ${PHP_VERSION}" >&2
|
||||
if [[ "${COMPOSER_PACKAGE}" != "" ]]; then
|
||||
echo "Package: ${COMPOSER_PACKAGE}" >&2
|
||||
fi
|
||||
if [[ ${SUITE_EXIT_CODE} -eq 0 ]]; then
|
||||
echo "SUCCESS" >&2
|
||||
else
|
||||
echo "FAILURE" >&2
|
||||
fi
|
||||
echo "###########################################################################" >&2
|
||||
echo "" >&2
|
||||
|
||||
# Exit with code of test suite - This script return non-zero if the executed test failed.
|
||||
exit $SUITE_EXIT_CODE
|
||||
1147
Build/Scripts/runTests.sh
Executable file
1147
Build/Scripts/runTests.sh
Executable file
File diff suppressed because it is too large
Load Diff
143
Build/Scripts/test.sh
Executable file
143
Build/Scripts/test.sh
Executable file
@ -0,0 +1,143 @@
|
||||
#!/bin/bash
|
||||
|
||||
export NC='\e[0m'
|
||||
export RED='\e[0;31m'
|
||||
export GREEN='\e[0;32m'
|
||||
|
||||
THIS_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$THIS_SCRIPT_DIR" || exit 1
|
||||
|
||||
#################################################
|
||||
# Run resource tests.
|
||||
# Arguments:
|
||||
# none
|
||||
#################################################
|
||||
checkResources () {
|
||||
echo "#################################################################" >&2
|
||||
echo "Checking documentation, TypeScript and Scss files" >&2
|
||||
echo "#################################################################" >&2
|
||||
|
||||
./additionalTests.sh -s lintXliff
|
||||
EXIT_CODE_XLIFF=$?
|
||||
|
||||
./additionalTests.sh -s buildDocumentation
|
||||
EXIT_CODE_DOCUMENTATION=$?
|
||||
|
||||
echo "#################################################################" >&2
|
||||
echo "Checked documentation, TypeScript and Scss files" >&2
|
||||
if [[ ${EXIT_CODE_SCSS} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_TYPESCRIPT} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_XLIFF} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_DOCUMENTATION} -eq 0 ]]
|
||||
then
|
||||
echo -e "${GREEN}Resources valid${NC}" >&2
|
||||
else
|
||||
echo -e "${RED}Resources invalid${NC}" >&2
|
||||
fi
|
||||
echo "#################################################################" >&2
|
||||
echo "" >&2
|
||||
|
||||
./additionalTests.sh -s clean
|
||||
}
|
||||
|
||||
#################################################
|
||||
# Run test matrix.
|
||||
# Arguments:
|
||||
# php version
|
||||
# typo3 version
|
||||
# testing framework version
|
||||
# test path
|
||||
# prefer lowest
|
||||
#################################################
|
||||
runFunctionalTests () {
|
||||
local PHP_VERSION="${1}"
|
||||
local TYPO3_VERSION=${2}
|
||||
local TESTING_FRAMEWORK=${3}
|
||||
local TEST_PATH=${4}
|
||||
local PREFER_LOWEST=${5}
|
||||
|
||||
echo "###########################################################################" >&2
|
||||
echo " Run unit and/or functional tests with" >&2
|
||||
echo " - TYPO3 ${TYPO3_VERSION}" >&2
|
||||
echo " - PHP ${PHP_VERSION}">&2
|
||||
echo " - Testing framework ${TESTING_FRAMEWORK}">&2
|
||||
echo " - Test path ${TEST_PATH}">&2
|
||||
echo " - Additional ${PREFER_LOWEST}">&2
|
||||
echo "###########################################################################" >&2
|
||||
|
||||
./runTests.sh -s cleanTests
|
||||
|
||||
./additionalTests.sh \
|
||||
-p ${PHP_VERSION} \
|
||||
-s lintPhp || exit 1 ; \
|
||||
EXIT_CODE_LINT=$?
|
||||
|
||||
./additionalTests.sh \
|
||||
-p ${PHP_VERSION} \
|
||||
-s composerInstallPackage \
|
||||
-q "typo3/cms-core:${TYPO3_VERSION}" \
|
||||
-r " ${PREFER_LOWEST}" || exit 1 ; \
|
||||
EXIT_CODE_CORE=$?
|
||||
|
||||
./additionalTests.sh \
|
||||
-p ${PHP_VERSION} \
|
||||
-s composerInstallPackage \
|
||||
-q "typo3/testing-framework:${TESTING_FRAMEWORK}" \
|
||||
-r " --dev ${PREFER_LOWEST}" || exit 1 ; \
|
||||
EXIT_CODE_FRAMEWORK=$?
|
||||
|
||||
./runTests.sh \
|
||||
-p ${PHP_VERSION} \
|
||||
-s composerValidate || exit 1 ; \
|
||||
EXIT_CODE_VALIDATE=$?
|
||||
|
||||
echo "###########################################################################" >&2
|
||||
echo " Finished unit and/or functional tests with" >&2
|
||||
echo " - TYPO3 ${TYPO3_VERSION}" >&2
|
||||
echo " - PHP ${PHP_VERSION}">&2
|
||||
echo " - Testing framework ${TESTING_FRAMEWORK}">&2
|
||||
echo " - Test path ${TEST_PATH}">&2
|
||||
echo " - Additional ${PREFER_LOWEST}">&2
|
||||
if [[ ${EXIT_CODE_LINT} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_INSTALL} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_CORE} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_FRAMEWORK} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_VALIDATE} -eq 0 ]] && \
|
||||
[[ ${EXIT_CODE_FUNCTIONAL} -eq 0 ]]
|
||||
then
|
||||
echo -e "${GREEN}SUCCESS${NC}" >&2
|
||||
else
|
||||
echo -e "${RED}FAILURE${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "#################################################################" >&2
|
||||
echo "" >&2
|
||||
}
|
||||
|
||||
#################################################
|
||||
# Removes all files created by tests.
|
||||
# Arguments:
|
||||
# none
|
||||
#################################################
|
||||
cleanup () {
|
||||
./runTests.sh -s clean
|
||||
./additionalTests.sh -s clean
|
||||
git checkout ../../composer.json
|
||||
}
|
||||
|
||||
DEBUG_TESTS=false
|
||||
if [[ $DEBUG_TESTS != true ]]; then
|
||||
checkResources
|
||||
|
||||
runFunctionalTests "8.2" "^13.0" "dev-main" "Tests/Functional" || exit 1
|
||||
runFunctionalTests "8.2" "^13.0" "dev-main" "Tests/Functional" "--prefer-lowest" || exit 1
|
||||
runFunctionalTests "8.3" "^13.0" "dev-main" "Tests/Functional" || exit 1
|
||||
runFunctionalTests "8.3" "^13.0" "dev-main" "Tests/Functional" "--prefer-lowest" || exit 1
|
||||
cleanup
|
||||
else
|
||||
cleanup
|
||||
runFunctionalTests "8.2" "^13.0" "dev-main" "Tests/Functional" || exit 1
|
||||
cleanup
|
||||
# ./runTests.sh -x -p 8.2 -d sqlite -s functional -e "--group selected" Tests/Functional
|
||||
# ./runTests.sh -x -p 8.2 -d sqlite -s functional Tests/Functional
|
||||
fi
|
||||
116
Build/php-cs-fixer/config.php
Normal file
116
Build/php-cs-fixer/config.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is copied from the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file represents the configuration for Code Sniffing PER-related
|
||||
* automatic checks of coding guidelines.
|
||||
*
|
||||
* Run it using runTests.sh, see 'runTests.sh -h' for more options.
|
||||
*
|
||||
* Fix entire extension:
|
||||
* > Build/Scripts/additionalTests.sh -p 8.3 -s composerInstallPackage -q "typo3/cms-core:[dev-main,13...]"
|
||||
* > Build/Scripts/runTests.sh -s cgl
|
||||
*
|
||||
* Fix your current patch:
|
||||
* > Build/Scripts/runTests.sh -s cglGit
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
die('This script supports command line usage only. Please check your command.');
|
||||
}
|
||||
|
||||
// Return a Code Sniffing configuration using
|
||||
// all sniffers needed for PER
|
||||
// and additionally:
|
||||
// - Remove leading slashes in use clauses.
|
||||
// - PHP single-line arrays should not have trailing comma.
|
||||
// - Single-line whitespace before closing semicolon are prohibited.
|
||||
// - Remove unused use statements in the PHP source code
|
||||
// - Ensure Concatenation to have at least one whitespace around
|
||||
// - Remove trailing whitespace at the end of blank lines.
|
||||
return (new \PhpCsFixer\Config())
|
||||
->setParallelConfig(\PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->ignoreVCSIgnored(true)
|
||||
->in(realpath(__DIR__ . '/../../'))
|
||||
->exclude('bin')
|
||||
->exclude('public')
|
||||
->exclude('typo3temp')
|
||||
->exclude('vendor')
|
||||
)
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@DoctrineAnnotation' => true,
|
||||
// @todo: Switch to @PER-CS2.0 once php-cs-fixer's todo list is done: https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/7247
|
||||
'@PER-CS1.0' => true,
|
||||
'array_indentation' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'cast_spaces' => ['space' => 'none'],
|
||||
// @todo: Can be dropped once we enable @PER-CS2.0
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'declare_equal_normalize' => ['space' => 'none'],
|
||||
'declare_parentheses' => true,
|
||||
'dir_constant' => true,
|
||||
// @todo: Can be dropped once we enable @PER-CS2.0
|
||||
'function_declaration' => [
|
||||
'closure_fn_spacing' => 'none',
|
||||
],
|
||||
'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']],
|
||||
'type_declaration_spaces' => true,
|
||||
'global_namespace_import' => ['import_classes' => false, 'import_constants' => false, 'import_functions' => false],
|
||||
'list_syntax' => ['syntax' => 'short'],
|
||||
// @todo: Can be dropped once we enable @PER-CS2.0
|
||||
'method_argument_space' => true,
|
||||
'modernize_strpos' => true,
|
||||
'modernize_types_casting' => true,
|
||||
'native_function_casing' => true,
|
||||
'no_alias_functions' => true,
|
||||
'no_blank_lines_after_phpdoc' => true,
|
||||
'no_empty_phpdoc' => true,
|
||||
'no_empty_statement' => true,
|
||||
'no_extra_blank_lines' => true,
|
||||
'no_leading_namespace_whitespace' => true,
|
||||
'no_null_property_initialization' => true,
|
||||
'no_short_bool_cast' => true,
|
||||
'no_singleline_whitespace_before_semicolons' => true,
|
||||
'no_superfluous_elseif' => true,
|
||||
'no_trailing_comma_in_singleline' => true,
|
||||
'no_unneeded_control_parentheses' => true,
|
||||
'no_unused_imports' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_useless_nullsafe_operator' => true,
|
||||
'ordered_imports' => ['imports_order' => ['class', 'function', 'const'], 'sort_algorithm' => 'alpha'],
|
||||
'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']],
|
||||
'php_unit_mock_short_will_return' => true,
|
||||
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
|
||||
'phpdoc_no_access' => true,
|
||||
'phpdoc_no_empty_return' => true,
|
||||
'phpdoc_no_package' => true,
|
||||
'phpdoc_scalar' => true,
|
||||
'phpdoc_trim' => true,
|
||||
'phpdoc_types' => true,
|
||||
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
|
||||
'return_type_declaration' => ['space_before' => 'none'],
|
||||
'single_quote' => true,
|
||||
'single_space_around_construct' => true,
|
||||
'single_line_comment_style' => ['comment_types' => ['hash']],
|
||||
// @todo: Can be dropped once we enable @PER-CS2.0
|
||||
'single_line_empty_body' => true,
|
||||
'trailing_comma_in_multiline' => ['elements' => ['arrays']],
|
||||
'whitespace_after_comma_in_array' => ['ensure_single_space' => true],
|
||||
'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false],
|
||||
]);
|
||||
75
Build/php-cs-fixer/header-comment.php
Normal file
75
Build/php-cs-fixer/header-comment.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file adds header to php file which don't have any.
|
||||
*
|
||||
* Run it using runTests.sh, see 'runTests.sh -h' for more options.
|
||||
*
|
||||
* Fix entire extension:
|
||||
* > Build/Scripts/additionalTests.sh -p 8.3 -s composerInstallPackage -q "typo3/cms-core:[dev-main,13...]"
|
||||
* > Build/Scripts/runTests.sh -s cglHeader
|
||||
*
|
||||
* Fix your current patch:
|
||||
* > Build/Scripts/runTests.sh -s cglHeaderGit
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
die('This script supports command line usage only. Please check your command.');
|
||||
}
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->name('*.php')
|
||||
->in(__DIR__ . '/../../')
|
||||
->exclude('Acceptance/Support/_generated') // EXT:core
|
||||
->exclude('Build')
|
||||
// Configuration files do not need header comments
|
||||
->exclude('Configuration')
|
||||
->notName('*locallang*.php')
|
||||
->notName('ext_localconf.php')
|
||||
->notName('ext_tables.php')
|
||||
->notName('ext_emconf.php')
|
||||
// ClassAliasMap files do not need header comments
|
||||
->notName('ClassAliasMap.php')
|
||||
// CodeSnippets and Examples in Documentation do not need header comments
|
||||
->exclude('Documentation')
|
||||
// Third-party inclusion files should not have a changed comment
|
||||
->notName('Rfc822AddressesParser.php')
|
||||
->notName('ClassMapGenerator.php')
|
||||
;
|
||||
|
||||
$headerComment = <<<COMMENT
|
||||
This file is developed by evoWeb.
|
||||
|
||||
It is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License, either version 2
|
||||
of the License, or any later version.
|
||||
|
||||
For the full copyright and license information, please read the
|
||||
LICENSE.txt file that was distributed with this source code.
|
||||
COMMENT;
|
||||
|
||||
return (new \PhpCsFixer\Config())
|
||||
->setParallelConfig(\PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
|
||||
->setRiskyAllowed(false)
|
||||
->setRules([
|
||||
'no_extra_blank_lines' => true,
|
||||
'header_comment' => [
|
||||
'header' => $headerComment,
|
||||
'comment_type' => 'comment',
|
||||
'separate' => 'both',
|
||||
'location' => 'after_declare_strict',
|
||||
],
|
||||
])
|
||||
->setFinder($finder);
|
||||
6
Classes/Command/ContentElementCommand.php
Executable file → Normal file
6
Classes/Command/ContentElementCommand.php
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\Command;
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
@ -13,6 +13,8 @@ namespace Evoweb\EwBase\Command;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@ -36,7 +38,7 @@ class ContentElementCommand extends Command
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->setAliases(['kc-sitepackage'])
|
||||
|
||||
69
Classes/Configuration/AdditionalConfiguration.php
Executable file → Normal file
69
Classes/Configuration/AdditionalConfiguration.php
Executable file → Normal file
@ -2,44 +2,22 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\Configuration;
|
||||
|
||||
/*
|
||||
* This file is part of TYPO3 CMS-based extension "container" by b13.
|
||||
* This file is part of TYPO3 CMS-based extension "ew-base" by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*/
|
||||
|
||||
use Mfc\OAuth2\ResourceServer\GitLab;
|
||||
use Mfc\OAuth2\ResourceServer\Registry;
|
||||
namespace Evoweb\EwBase\Configuration;
|
||||
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class AdditionalConfiguration
|
||||
{
|
||||
protected string $extensionKey = 'ew_base';
|
||||
|
||||
protected array $oauthOptions = [
|
||||
'enabled' => true, // Enable/Disable the provider
|
||||
'arguments' => [
|
||||
'appId' => '',
|
||||
'appSecret' => '',
|
||||
'projectName' => '',
|
||||
'gitlabServer' => 'https://github.com',
|
||||
// User level at which the user will be given admin permissions
|
||||
'gitlabAdminUserLevel' => 30,
|
||||
// Groups to assign to the User (comma separated list possible)
|
||||
'gitlabDefaultGroups' => 1,
|
||||
// UserConfig db and/or file mount from groups
|
||||
'gitlabUserOption' => 3,
|
||||
// Blocks users with flag external from access the backend
|
||||
'blockExternalUser' => false,
|
||||
],
|
||||
];
|
||||
|
||||
protected array $developConfig = [
|
||||
'BE' => [
|
||||
'debug' => true,
|
||||
@ -70,12 +48,11 @@ class AdditionalConfiguration
|
||||
/**
|
||||
* This is needed to override all mail settings instead of merging them.
|
||||
*
|
||||
* @var array|string[]
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected array $mailConfig = [
|
||||
'transport' => 'smtp',
|
||||
'transport_smtp_server' => '127.0.0.1:1025',
|
||||
'defaultMailFromAddress' => 'test@dev.arpa',
|
||||
'transport_smtp_server' => 'mailpit:1025'
|
||||
];
|
||||
|
||||
public function initialize(array $configuration = []): void
|
||||
@ -83,7 +60,6 @@ class AdditionalConfiguration
|
||||
$this->addContextToSitename();
|
||||
$this->addContextConfiguration($configuration);
|
||||
if (Environment::getContext() == 'Development') {
|
||||
$this->addBaseUrl();
|
||||
$this->addDebugConfiguration();
|
||||
}
|
||||
$this->addFurtherConfigurationFiles();
|
||||
@ -94,28 +70,6 @@ class AdditionalConfiguration
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] .= ' - ' . Environment::getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the baseurl on local environments automatically
|
||||
*/
|
||||
protected function addBaseUrl(): void
|
||||
{
|
||||
if (Environment::isCli()) {
|
||||
return;
|
||||
}
|
||||
$remoteHost = GeneralUtility::getIndpEnv('HTTP_HOST');
|
||||
ExtensionManagementUtility::addTypoScript(
|
||||
$this->extensionKey,
|
||||
'constants',
|
||||
'
|
||||
// condition should trigger different cache hashes
|
||||
[request.getNormalizedParams().getHttpHost() == \'' . $remoteHost . '\']
|
||||
config.baseURL = ' . $remoteHost . '
|
||||
[end]
|
||||
',
|
||||
'defaultContentRendering'
|
||||
);
|
||||
}
|
||||
|
||||
protected function addDebugConfiguration(): void
|
||||
{
|
||||
$GLOBALS['TYPO3_CONF_VARS'] = $this->arrayMergeRecursive(
|
||||
@ -169,19 +123,6 @@ class AdditionalConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
public function addGitlabLogin(array $options = []): void
|
||||
{
|
||||
if (!empty($options)) {
|
||||
$this->oauthOptions['arguments']['gitlabAdminUserLevel'] = GitLab::USER_LEVEL_DEVELOPER;
|
||||
Registry::addServer(
|
||||
'gitlab',
|
||||
'Login mit GitLab',
|
||||
GitLab::class,
|
||||
$this->arrayMergeRecursive($this->oauthOptions, $options)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function arrayMergeRecursive(array $array1, array $array2): array
|
||||
{
|
||||
$merged = $array1;
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\DataProcessing;
|
||||
|
||||
/*
|
||||
* This file is part of TYPO3 CMS-based extension "container" by b13.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*/
|
||||
|
||||
use B13\Container\DataProcessing\ContainerProcessor as BaseContainerProcessor;
|
||||
use B13\Container\Domain\Model\Container;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\RecordsContentObject;
|
||||
|
||||
class ContainerProcessor extends BaseContainerProcessor
|
||||
{
|
||||
protected function processColPos(
|
||||
ContentObjectRenderer $cObj,
|
||||
Container $container,
|
||||
int $colPos,
|
||||
string $as,
|
||||
array $processedData,
|
||||
array $processorConfiguration
|
||||
): array {
|
||||
$children = $container->getChildrenByColPos($colPos);
|
||||
|
||||
if (!$processorConfiguration['doNotProcessChildren']) {
|
||||
$contentRecordRenderer = new RecordsContentObject();
|
||||
$conf = [
|
||||
'tables' => 'tt_content'
|
||||
];
|
||||
foreach ($children as &$child) {
|
||||
if ($child['l18n_parent'] > 0) {
|
||||
$conf['source'] = $child['l18n_parent'];
|
||||
} else {
|
||||
$conf['source'] = $child['uid'];
|
||||
}
|
||||
if ($child['t3ver_oid'] > 0) {
|
||||
$conf['source'] = $child['t3ver_oid'];
|
||||
}
|
||||
$child['renderedContent'] = $cObj->render($contentRecordRenderer, $conf);
|
||||
/** @var ContentObjectRenderer $recordContentObjectRenderer */
|
||||
$recordContentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
|
||||
$recordContentObjectRenderer->start($child, 'tt_content');
|
||||
$child = $this->contentDataProcessor->process($recordContentObjectRenderer, $processorConfiguration, $child);
|
||||
}
|
||||
}
|
||||
|
||||
$processedData[$as] = $children;
|
||||
return $processedData;
|
||||
}
|
||||
}
|
||||
616
Classes/DataProcessing/DatabaseQueryProcessor.php
Normal file
616
Classes/DataProcessing/DatabaseQueryProcessor.php
Normal file
@ -0,0 +1,616 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\DataProcessing;
|
||||
|
||||
use Doctrine\DBAL\Exception as DBALException;
|
||||
use Doctrine\DBAL\Result;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
|
||||
use TYPO3\CMS\Core\Context\LanguageAspect;
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
|
||||
use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryHelper;
|
||||
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
|
||||
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
use TYPO3\CMS\Core\Versioning\VersionState;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentDataProcessor;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
|
||||
use TYPO3\CMS\Frontend\ContentObject\Exception\ContentRenderingException;
|
||||
|
||||
/**
|
||||
* Fetch records from the database, using the default .select syntax from TypoScript.
|
||||
*
|
||||
* This way, e.g. a FLUIDTEMPLATE cObject can iterate over the array of records.
|
||||
*
|
||||
* Example TypoScript configuration:
|
||||
*
|
||||
* 10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
|
||||
* 10 {
|
||||
* table = tt_address
|
||||
* pidInList = 123
|
||||
* where = company="Acme" AND first_name="Ralph"
|
||||
* orderBy = sorting DESC
|
||||
* as = addresses
|
||||
* dataProcessing {
|
||||
* 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
|
||||
* 10 {
|
||||
* references.fieldName = image
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* where "as" means the variable to be containing the result-set from the DB query.
|
||||
*/
|
||||
class DatabaseQueryProcessor implements DataProcessorInterface
|
||||
{
|
||||
protected ContentObjectRenderer $cObj;
|
||||
|
||||
protected ?ServerRequestInterface $request = null;
|
||||
|
||||
protected string $tableName = '';
|
||||
|
||||
public function __construct(protected readonly ContentDataProcessor $contentDataProcessor) {}
|
||||
|
||||
/**
|
||||
* Fetches records from the database as an array
|
||||
*
|
||||
* @param ContentObjectRenderer $cObj The data of the content element or page
|
||||
* @param array $contentObjectConfiguration The configuration of Content Object
|
||||
* @param array $processorConfiguration The configuration of this processor
|
||||
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
|
||||
*
|
||||
* @return array the processed data as key/value store
|
||||
* @throws ContentRenderingException
|
||||
*/
|
||||
public function process(
|
||||
ContentObjectRenderer $cObj,
|
||||
array $contentObjectConfiguration,
|
||||
array $processorConfiguration,
|
||||
array $processedData
|
||||
): array {
|
||||
if (isset($processorConfiguration['if.']) && !$cObj->checkIf($processorConfiguration['if.'])) {
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
// the table to query, if none given, exit
|
||||
$tableName = $cObj->stdWrapValue('table', $processorConfiguration);
|
||||
if (empty($tableName)) {
|
||||
return $processedData;
|
||||
}
|
||||
if (isset($processorConfiguration['table.'])) {
|
||||
unset($processorConfiguration['table.']);
|
||||
}
|
||||
if (isset($processorConfiguration['table'])) {
|
||||
unset($processorConfiguration['table']);
|
||||
}
|
||||
|
||||
$this->request = $cObj->getRequest();
|
||||
$this->tableName = $tableName;
|
||||
$this->cObj = clone $cObj;
|
||||
// @extensionScannerIgnoreLine
|
||||
$this->cObj->start($cObj->data, $tableName);
|
||||
$this->cObj->setRequest($this->request);
|
||||
|
||||
// The variable to be used within the result
|
||||
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, 'records');
|
||||
|
||||
// Execute a SQL statement to fetch the records
|
||||
$records = $this->getRecords($tableName, $processorConfiguration);
|
||||
$request = $cObj->getRequest();
|
||||
$processedRecordVariables = [];
|
||||
foreach ($records as $key => $record) {
|
||||
/** @var ContentObjectRenderer $recordContentObjectRenderer */
|
||||
$recordContentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
|
||||
$recordContentObjectRenderer->setRequest($request);
|
||||
$recordContentObjectRenderer->start($record, $tableName);
|
||||
$processedRecordVariables[$key] = ['data' => $record];
|
||||
$processedRecordVariables[$key] = $this->contentDataProcessor->process(
|
||||
$recordContentObjectRenderer,
|
||||
$processorConfiguration,
|
||||
$processedRecordVariables[$key]
|
||||
);
|
||||
}
|
||||
|
||||
$processedData[$targetVariableName] = $processedRecordVariables;
|
||||
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
protected function getRecords(string $tableName, array $queryConfiguration): array
|
||||
{
|
||||
$records = [];
|
||||
|
||||
$statement = $this->exec_getQuery($tableName, $queryConfiguration);
|
||||
|
||||
$pageRepository = $this->getPageRepository();
|
||||
while ($row = $statement->fetchAssociative()) {
|
||||
// Versioning preview:
|
||||
$pageRepository->versionOL($tableName, $row, true);
|
||||
|
||||
// Language overlay:
|
||||
if (is_array($row)) {
|
||||
$row = $pageRepository->getLanguageOverlay($tableName, $row);
|
||||
}
|
||||
|
||||
// Might be unset in the language overlay
|
||||
if (is_array($row)) {
|
||||
$records[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
protected function exec_getQuery(string $table, array $conf): Result
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
|
||||
$statement = $this->getQuery($connection, $table, $conf);
|
||||
|
||||
return $connection->executeQuery($statement);
|
||||
}
|
||||
|
||||
public function getQuery(Connection $connection, $table, $conf): string
|
||||
{
|
||||
// Resolve stdWrap in these properties first
|
||||
$properties = [
|
||||
'pidInList',
|
||||
'uidInList',
|
||||
'languageField',
|
||||
'selectFields',
|
||||
'max',
|
||||
'begin',
|
||||
'groupBy',
|
||||
'orderBy',
|
||||
'join',
|
||||
'leftjoin',
|
||||
'rightjoin',
|
||||
'recursive',
|
||||
'where',
|
||||
];
|
||||
foreach ($properties as $property) {
|
||||
$conf[$property] = trim(
|
||||
isset($conf[$property . '.'])
|
||||
? (string)$this->cObj->stdWrap($conf[$property] ?? '', $conf[$property . '.'] ?? [])
|
||||
: (string)($conf[$property] ?? '')
|
||||
);
|
||||
if ($conf[$property] === '') {
|
||||
unset($conf[$property]);
|
||||
} elseif (in_array($property, ['languageField', 'selectFields', 'join', 'leftjoin', 'rightjoin', 'where'], true)) {
|
||||
$conf[$property] = QueryHelper::quoteDatabaseIdentifiers($connection, $conf[$property]);
|
||||
}
|
||||
if (isset($conf[$property . '.'])) {
|
||||
// stdWrapping already done, so remove the sub-array
|
||||
unset($conf[$property . '.']);
|
||||
}
|
||||
}
|
||||
// Handle PDO-style named parameter markers first
|
||||
$queryMarkers = $this->cObj->getQueryMarkers($connection, $conf);
|
||||
// Replace the markers in the non-stdWrap properties
|
||||
foreach ($queryMarkers as $marker => $markerValue) {
|
||||
$properties = [
|
||||
'uidInList',
|
||||
'selectFields',
|
||||
'where',
|
||||
'max',
|
||||
'begin',
|
||||
'groupBy',
|
||||
'orderBy',
|
||||
'join',
|
||||
'leftjoin',
|
||||
'rightjoin',
|
||||
];
|
||||
foreach ($properties as $property) {
|
||||
if ($conf[$property] ?? false) {
|
||||
$conf[$property] = str_replace('###' . $marker . '###', $markerValue, $conf[$property]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct WHERE clause:
|
||||
// Handle recursive function for the pidInList
|
||||
if (isset($conf['recursive'])) {
|
||||
$conf['recursive'] = (int)$conf['recursive'];
|
||||
if ($conf['recursive'] > 0) {
|
||||
$pidList = GeneralUtility::trimExplode(',', $conf['pidInList'], true);
|
||||
array_walk($pidList, function (&$storagePid) {
|
||||
if ($storagePid === 'this') {
|
||||
$storagePid = $this->getRequest()->getAttribute('frontend.page.information')->getId();
|
||||
}
|
||||
});
|
||||
$pageRepository = $this->getPageRepository();
|
||||
$expandedPidList = $pageRepository->getPageIdsRecursive($pidList, $conf['recursive']);
|
||||
$conf['pidInList'] = implode(',', $expandedPidList);
|
||||
}
|
||||
}
|
||||
if ((string)($conf['pidInList'] ?? '') === '') {
|
||||
$conf['pidInList'] = 'this';
|
||||
}
|
||||
|
||||
$queryParts = $this->getQueryConstraints($connection, $table, $conf);
|
||||
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
// @todo Check against getQueryConstraints, can probably use FrontendRestrictions
|
||||
// @todo here and remove enableFields there.
|
||||
$queryBuilder->getRestrictions()->removeAll();
|
||||
$queryBuilder->select('*')->from($table);
|
||||
|
||||
if ($queryParts['where'] ?? false) {
|
||||
$queryBuilder->where($queryParts['where']);
|
||||
}
|
||||
|
||||
if (($queryParts['groupBy'] ?? false) && is_array($queryParts['groupBy'])) {
|
||||
$queryBuilder->groupBy(...$queryParts['groupBy']);
|
||||
}
|
||||
|
||||
if (is_array($queryParts['orderBy'] ?? false)) {
|
||||
foreach ($queryParts['orderBy'] as $orderBy) {
|
||||
$queryBuilder->addOrderBy(...$orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
// Fields:
|
||||
if ($conf['selectFields'] ?? false) {
|
||||
$queryBuilder->selectLiteral($this->sanitizeSelectPart($connection, $conf['selectFields'], $table));
|
||||
}
|
||||
|
||||
// Setting LIMIT:
|
||||
if (($conf['max'] ?? false) || ($conf['begin'] ?? false)) {
|
||||
// Finding the total number of records, if used:
|
||||
if (str_contains(strtolower(($conf['begin'] ?? '') . ($conf['max'] ?? '')), 'total')) {
|
||||
$countQueryBuilder = $connection->createQueryBuilder();
|
||||
$countQueryBuilder->getRestrictions()->removeAll();
|
||||
$countQueryBuilder->count('*')
|
||||
->from($table)
|
||||
->where($queryParts['where']);
|
||||
|
||||
if ($queryParts['groupBy']) {
|
||||
$countQueryBuilder->groupBy(...$queryParts['groupBy']);
|
||||
}
|
||||
|
||||
try {
|
||||
$count = $countQueryBuilder->executeQuery()->fetchOne();
|
||||
if (isset($conf['max'])) {
|
||||
$conf['max'] = str_ireplace('total', $count, (string)$conf['max']);
|
||||
}
|
||||
if (isset($conf['begin'])) {
|
||||
$conf['begin'] = str_ireplace('total', $count, (string)$conf['begin']);
|
||||
}
|
||||
} catch (DBALException $e) {
|
||||
$this->getTimeTracker()->setTSlogMessage($e->getPrevious()->getMessage());
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($conf['begin']) && $conf['begin'] > 0) {
|
||||
$conf['begin'] = MathUtility::forceIntegerInRange((int)ceil($this->cObj->calc($conf['begin'])), 0);
|
||||
$queryBuilder->setFirstResult($conf['begin']);
|
||||
}
|
||||
if (isset($conf['max'])) {
|
||||
$conf['max'] = MathUtility::forceIntegerInRange((int)ceil($this->cObj->calc($conf['max'])), 0);
|
||||
$queryBuilder->setMaxResults($conf['max'] ?: 100000);
|
||||
}
|
||||
}
|
||||
|
||||
// Setting up tablejoins:
|
||||
if ($conf['join'] ?? false) {
|
||||
$joinParts = QueryHelper::parseJoin($conf['join']);
|
||||
$queryBuilder->join(
|
||||
$table,
|
||||
$joinParts['tableName'],
|
||||
$joinParts['tableAlias'],
|
||||
$joinParts['joinCondition']
|
||||
);
|
||||
} elseif ($conf['leftjoin'] ?? false) {
|
||||
$joinParts = QueryHelper::parseJoin($conf['leftjoin']);
|
||||
$queryBuilder->leftJoin(
|
||||
$table,
|
||||
$joinParts['tableName'],
|
||||
$joinParts['tableAlias'],
|
||||
$joinParts['joinCondition']
|
||||
);
|
||||
} elseif ($conf['rightjoin'] ?? false) {
|
||||
$joinParts = QueryHelper::parseJoin($conf['rightjoin']);
|
||||
$queryBuilder->rightJoin(
|
||||
$table,
|
||||
$joinParts['tableName'],
|
||||
$joinParts['tableAlias'],
|
||||
$joinParts['joinCondition']
|
||||
);
|
||||
}
|
||||
|
||||
// Convert the QueryBuilder object into a SQL statement.
|
||||
$query = $queryBuilder->getSQL();
|
||||
|
||||
// Replace the markers in the queryParts to handle stdWrap enabled properties
|
||||
foreach ($queryMarkers as $marker => $markerValue) {
|
||||
// @todo Ugly hack that needs to be cleaned up, with the current architecture
|
||||
// @todo for exec_Query / getQuery it's the best we can do.
|
||||
$query = str_replace('###' . $marker . '###', (string)$markerValue, $query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for getQuery(), creating the WHERE clause of the SELECT query
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @param string $table The table name
|
||||
* @param array $conf The TypoScript configuration properties
|
||||
* @return array Associative array containing the prepared data for WHERE, ORDER BY and GROUP BY fragments
|
||||
* @throws AspectNotFoundException
|
||||
* @throws ContentRenderingException
|
||||
* @see getQuery()
|
||||
*/
|
||||
protected function getQueryConstraints(Connection $connection, string $table, array $conf): array
|
||||
{
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$expressionBuilder = $queryBuilder->expr();
|
||||
$request = $this->getRequest();
|
||||
$contentPid = $request->getAttribute('frontend.page.information')->getContentFromPid();
|
||||
$constraints = [];
|
||||
$pid_uid_flag = 0;
|
||||
$enableFieldsIgnore = [];
|
||||
$queryParts = [
|
||||
'where' => null,
|
||||
'groupBy' => null,
|
||||
'orderBy' => null,
|
||||
];
|
||||
|
||||
$isInWorkspace = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('workspace', 'isOffline');
|
||||
$considerMovePointers = (
|
||||
$isInWorkspace && $table !== 'pages'
|
||||
&& !empty($GLOBALS['TCA'][$table]['ctrl']['versioningWS'])
|
||||
);
|
||||
|
||||
if (trim($conf['uidInList'] ?? '')) {
|
||||
$listArr = GeneralUtility::intExplode(',', str_replace('this', (string)$contentPid, $conf['uidInList']));
|
||||
|
||||
// If moved records shall be considered, select via t3ver_oid
|
||||
if ($considerMovePointers) {
|
||||
$constraints[] = (string)$expressionBuilder->or(
|
||||
$expressionBuilder->in($table . '.uid', $listArr),
|
||||
$expressionBuilder->and(
|
||||
$expressionBuilder->eq(
|
||||
$table . '.t3ver_state',
|
||||
VersionState::MOVE_POINTER->value
|
||||
),
|
||||
$expressionBuilder->in($table . '.t3ver_oid', $listArr)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$constraints[] = (string)$expressionBuilder->in($table . '.uid', $listArr);
|
||||
}
|
||||
$pid_uid_flag++;
|
||||
}
|
||||
|
||||
// Static_* tables are allowed to be fetched from root page
|
||||
if (str_starts_with($table, 'static_')) {
|
||||
$pid_uid_flag++;
|
||||
}
|
||||
|
||||
if (trim($conf['pidInList'])) {
|
||||
$listArr = GeneralUtility::intExplode(',', str_replace('this', (string)$contentPid, $conf['pidInList']));
|
||||
// Removes all pages which are not visible for the user!
|
||||
$listArr = $this->cObj->checkPidArray($listArr);
|
||||
if (GeneralUtility::inList($conf['pidInList'], 'root')) {
|
||||
$listArr[] = 0;
|
||||
}
|
||||
if (GeneralUtility::inList($conf['pidInList'], '-1')) {
|
||||
$listArr[] = -1;
|
||||
$enableFieldsIgnore['pid'] = true;
|
||||
}
|
||||
if (!empty($listArr)) {
|
||||
$constraints[] = $expressionBuilder->in($table . '.pid', array_map('intval', $listArr));
|
||||
$pid_uid_flag++;
|
||||
} else {
|
||||
// If not uid and not pid then uid is set to 0 - which results in nothing!!
|
||||
$pid_uid_flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If not uid and not pid then uid is set to 0 - which results in nothing!!
|
||||
if (!$pid_uid_flag && trim($conf['pidInList'] ?? '') !== 'ignore') {
|
||||
$constraints[] = $expressionBuilder->eq($table . '.uid', 0);
|
||||
}
|
||||
|
||||
$where = trim((string)$this->cObj->stdWrapValue('where', $conf));
|
||||
if ($where) {
|
||||
$constraints[] = QueryHelper::stripLogicalOperatorPrefix($where);
|
||||
}
|
||||
|
||||
// Check if the default language should be fetched (= doing overlays), or if only the records of a language should be fetched
|
||||
// but only do this for TCA tables that have languages enabled
|
||||
$languageConstraint = $this->getLanguageRestriction($expressionBuilder, $table, $conf, GeneralUtility::makeInstance(Context::class));
|
||||
if ($languageConstraint !== null) {
|
||||
$constraints[] = $languageConstraint;
|
||||
}
|
||||
|
||||
// default constraints from TCA
|
||||
$pageRepository = $this->getPageRepository();
|
||||
$constraints = array_merge(
|
||||
$constraints,
|
||||
array_values($pageRepository->getDefaultConstraints($table, $enableFieldsIgnore))
|
||||
);
|
||||
|
||||
// MAKE WHERE:
|
||||
if ($constraints !== []) {
|
||||
$queryParts['where'] = $expressionBuilder->and(...$constraints);
|
||||
}
|
||||
// GROUP BY
|
||||
$groupBy = trim((string)$this->cObj->stdWrapValue('groupBy', $conf));
|
||||
if ($groupBy) {
|
||||
$queryParts['groupBy'] = QueryHelper::parseGroupBy($groupBy);
|
||||
}
|
||||
|
||||
// ORDER BY
|
||||
$orderByString = trim((string)$this->cObj->stdWrapValue('orderBy', $conf));
|
||||
if ($orderByString) {
|
||||
$queryParts['orderBy'] = QueryHelper::parseOrderBy($orderByString);
|
||||
}
|
||||
|
||||
// Return result:
|
||||
return $queryParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds parts to the WHERE clause that are related to language.
|
||||
* This only works on TCA tables which have the [ctrl][languageField] field set or if they
|
||||
* have select.languageField = my_language_field set explicitly.
|
||||
*
|
||||
* It is also possible to disable the language restriction for a query by using select.languageField = 0,
|
||||
* if select.languageField is not explicitly set, the TCA default values are taken.
|
||||
*
|
||||
* If the table is "localizeable" (= any of the criteria above is met), then the DB query is restricted:
|
||||
*
|
||||
* If the current language aspect has overlays enabled, then the only records with language "0" or "-1" are
|
||||
* fetched (the overlays are taken care of later-on).
|
||||
* if the current language has overlays but also records without localization-parent (free mode) available,
|
||||
* then these are fetched as well. This can explicitly set via select.includeRecordsWithoutDefaultTranslation = 1
|
||||
* which overrules the overlayType within the language aspect.
|
||||
*
|
||||
* If the language aspect has NO overlays enabled, it behaves as in "free mode" (= only fetch the records
|
||||
* for the current language.
|
||||
*
|
||||
* @throws AspectNotFoundException
|
||||
*/
|
||||
protected function getLanguageRestriction(
|
||||
ExpressionBuilder $expressionBuilder,
|
||||
string $table,
|
||||
array $conf,
|
||||
Context $context
|
||||
): string|CompositeExpression|null {
|
||||
$languageField = '';
|
||||
$localizationParentField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] ?? null;
|
||||
// Check if the table is translatable, and set the language field by default from the TCA information
|
||||
if (!empty($conf['languageField']) || !isset($conf['languageField'])) {
|
||||
if (isset($conf['languageField']) && !empty($GLOBALS['TCA'][$table]['columns'][$conf['languageField']])) {
|
||||
$languageField = $conf['languageField'];
|
||||
} elseif (!empty($GLOBALS['TCA'][$table]['ctrl']['languageField']) && !empty($localizationParentField)) {
|
||||
$languageField = $table . '.' . $GLOBALS['TCA'][$table]['ctrl']['languageField'];
|
||||
}
|
||||
}
|
||||
|
||||
// No language restriction enabled explicitly or available via TCA
|
||||
if (empty($languageField)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var LanguageAspect $languageAspect */
|
||||
$languageAspect = $context->getAspect('language');
|
||||
if ($languageAspect->doOverlays() && !empty($localizationParentField)) {
|
||||
// Sys language content is set to zero/-1 - and it is expected that whatever routine processes the output will
|
||||
// OVERLAY the records with localized versions!
|
||||
$languageQuery = $expressionBuilder->in($languageField, [0, -1]);
|
||||
// Use this option to include records that don't have a default language counterpart ("free mode")
|
||||
// (originalpointerfield is 0 and the language field contains the requested language)
|
||||
if (isset($conf['includeRecordsWithoutDefaultTranslation']) || !empty($conf['includeRecordsWithoutDefaultTranslation.'])) {
|
||||
$includeRecordsWithoutDefaultTranslation = isset($conf['includeRecordsWithoutDefaultTranslation.'])
|
||||
? $this->cObj->stdWrap($conf['includeRecordsWithoutDefaultTranslation'], $conf['includeRecordsWithoutDefaultTranslation.'])
|
||||
: $conf['includeRecordsWithoutDefaultTranslation'];
|
||||
$includeRecordsWithoutDefaultTranslation = trim((string)$includeRecordsWithoutDefaultTranslation);
|
||||
$includeRecordsWithoutDefaultTranslation = $includeRecordsWithoutDefaultTranslation !== '' && $includeRecordsWithoutDefaultTranslation !== '0';
|
||||
} else {
|
||||
// Option was not explicitly set, check what's in for the language overlay type.
|
||||
$includeRecordsWithoutDefaultTranslation = $languageAspect->getOverlayType() === $languageAspect::OVERLAYS_ON_WITH_FLOATING;
|
||||
}
|
||||
if ($includeRecordsWithoutDefaultTranslation) {
|
||||
$languageQuery = $expressionBuilder->or(
|
||||
$languageQuery,
|
||||
$expressionBuilder->and(
|
||||
$expressionBuilder->eq($table . '.' . $localizationParentField, 0),
|
||||
$expressionBuilder->eq($languageField, $languageAspect->getContentId())
|
||||
)
|
||||
);
|
||||
}
|
||||
return $languageQuery;
|
||||
}
|
||||
// No overlays = only fetch records given for the requested language and "all languages"
|
||||
return (string)$expressionBuilder->in($languageField, [$languageAspect->getContentId(), -1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for getQuery, sanitizing the select part
|
||||
*
|
||||
* This functions checks if the necessary fields are part of the select
|
||||
* and adds them if necessary.
|
||||
*
|
||||
* @return string Sanitized select part
|
||||
* @internal
|
||||
* @see getQuery
|
||||
*/
|
||||
protected function sanitizeSelectPart(Connection $connection, string $selectPart, string $table): string
|
||||
{
|
||||
// Pattern matching parts
|
||||
$matchStart = '/(^\\s*|,\\s*|' . $table . '\\.)';
|
||||
$matchEnd = '(\\s*,|\\s*$)/';
|
||||
$necessaryFields = ['uid', 'pid'];
|
||||
$wsFields = ['t3ver_state'];
|
||||
$languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? false;
|
||||
if (isset($GLOBALS['TCA'][$table]) && !preg_match($matchStart . '\\*' . $matchEnd, $selectPart) && !preg_match('/(count|max|min|avg|sum)\\([^\\)]+\\)|distinct/i', $selectPart)) {
|
||||
foreach ($necessaryFields as $field) {
|
||||
$match = $matchStart . $field . $matchEnd;
|
||||
if (!preg_match($match, $selectPart)) {
|
||||
$selectPart .= ', ' . $connection->quoteIdentifier($table . '.' . $field) . ' AS ' . $connection->quoteIdentifier($field);
|
||||
}
|
||||
}
|
||||
if (is_string($languageField)) {
|
||||
$match = $matchStart . $languageField . $matchEnd;
|
||||
if (!preg_match($match, $selectPart)) {
|
||||
$selectPart .= ', ' . $connection->quoteIdentifier($table . '.' . $languageField) . ' AS ' . $connection->quoteIdentifier($languageField);
|
||||
}
|
||||
}
|
||||
if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS'] ?? false) {
|
||||
foreach ($wsFields as $field) {
|
||||
$match = $matchStart . $field . $matchEnd;
|
||||
if (!preg_match($match, $selectPart)) {
|
||||
$selectPart .= ', ' . $connection->quoteIdentifier($table . '.' . $field) . ' AS ' . $connection->quoteIdentifier($field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $selectPart;
|
||||
}
|
||||
|
||||
protected function getPageRepository(): PageRepository
|
||||
{
|
||||
return GeneralUtility::makeInstance(PageRepository::class);
|
||||
}
|
||||
|
||||
protected function getTimeTracker(): TimeTracker
|
||||
{
|
||||
return GeneralUtility::makeInstance(TimeTracker::class);
|
||||
}
|
||||
|
||||
public function getRequest(): ServerRequestInterface
|
||||
{
|
||||
if ($this->request instanceof ServerRequestInterface) {
|
||||
return $this->request;
|
||||
}
|
||||
throw new ContentRenderingException(
|
||||
'PSR-7 request is missing in ContentObjectRenderer. Inject with start(), setRequest() or provide via $GLOBALS[\'TYPO3_REQUEST\'].',
|
||||
1607172972
|
||||
);
|
||||
}
|
||||
}
|
||||
46
Classes/EventListener/CssMerger.php
Executable file → Normal file
46
Classes/EventListener/CssMerger.php
Executable file → Normal file
@ -1,17 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\EventListener;
|
||||
|
||||
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Core\RequestId;
|
||||
use TYPO3\CMS\Core\Page\AssetCollector;
|
||||
use TYPO3\CMS\Core\Page\Event\BeforeStylesheetsRenderingEvent;
|
||||
use TYPO3\CMS\Core\Site\Entity\Site;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
class CssMerger
|
||||
readonly class CssMerger
|
||||
{
|
||||
public function __construct(protected ExtensionConfiguration $extensionConfiguration)
|
||||
{
|
||||
public function __construct(
|
||||
private RequestId $requestId
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(BeforeStylesheetsRenderingEvent $event): void
|
||||
@ -29,12 +45,23 @@ class CssMerger
|
||||
return;
|
||||
}
|
||||
|
||||
$inlineCssStyles = $this->extensionConfiguration->get('ew_base', 'inlineCssStyles');
|
||||
if ($inlineCssStyles) {
|
||||
/** @var Site $site */
|
||||
$site = $this->getRequest()->getAttribute('site');
|
||||
if (
|
||||
$site instanceof Site
|
||||
&& ($siteSettings = $site->getSettings())
|
||||
&& !$siteSettings->isEmpty()
|
||||
&& $siteSettings->get('ew-base.inlineCssStyles')
|
||||
) {
|
||||
$assetCollector->addInlineStyleSheet('ew_base', $styles, [], ['priority' => true]);
|
||||
} else {
|
||||
$temporaryFile = GeneralUtility::writeStyleSheetContentToTemporaryFile($styles);
|
||||
$assetCollector->addStyleSheet('combined_styles', $temporaryFile);
|
||||
// @extensionScannerIgnoreLine
|
||||
$assetCollector->addStyleSheet(
|
||||
'ew_base_combined_styles',
|
||||
$temporaryFile,
|
||||
['nounce' => $this->requestId->nonce]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,4 +123,9 @@ class CssMerger
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
protected function getRequest(): ServerRequestInterface
|
||||
{
|
||||
return $GLOBALS['TYPO3_REQUEST'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\EventListener;
|
||||
|
||||
use TYPO3\CMS\Backend\ViEvoweb\Event\IsContentUsedOnPageLayoutEvent;
|
||||
|
||||
class IsContentUsedOnPageLayout
|
||||
{
|
||||
public function __invoke(IsContentUsedOnPageLayoutEvent $event): void
|
||||
{
|
||||
$event->setUsed($event->isRecordUsed() || $this->findCTypeBegin($event->getRecord()['CType']));
|
||||
}
|
||||
|
||||
public function findCTypeBegin($cType): bool
|
||||
{
|
||||
$found = false;
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['ContentUsedStrings'] ?? [] as $search) {
|
||||
if (strpos($cType, $search) !== false) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
28
Classes/EventListener/JsMerger.php
Executable file → Normal file
28
Classes/EventListener/JsMerger.php
Executable file → Normal file
@ -1,14 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\EventListener;
|
||||
|
||||
use TYPO3\CMS\Core\Core\RequestId;
|
||||
use TYPO3\CMS\Core\Page\AssetCollector;
|
||||
use TYPO3\CMS\Core\Page\Event\BeforeJavaScriptsRenderingEvent;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
class JsMerger
|
||||
readonly class JsMerger
|
||||
{
|
||||
public function __construct(private RequestId $requestId)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(BeforeJavaScriptsRenderingEvent $event): void
|
||||
{
|
||||
if ($event->isInline() && $event->isPriority()) {
|
||||
@ -22,7 +40,11 @@ class JsMerger
|
||||
$scripts = trim(implode(LF, $scripts));
|
||||
if (!empty($scripts)) {
|
||||
$temporaryFile = GeneralUtility::writeJavaScriptContentToTemporaryFile($scripts);
|
||||
$assetCollector->addJavaScript('combined_scripts', $temporaryFile);
|
||||
$assetCollector->addJavaScript(
|
||||
'ew_base_combined_scripts',
|
||||
$temporaryFile,
|
||||
['nounce' => $this->requestId->nonce]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,7 +112,7 @@ class JsMerger
|
||||
'url("' . $relativeFilePath . '/..',
|
||||
'url(\'' . $relativeFilePath . '/..',
|
||||
],
|
||||
$content
|
||||
$content,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
58
Classes/EventListener/ReleaseToolbarItem.php
Normal file
58
Classes/EventListener/ReleaseToolbarItem.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\EventListener;
|
||||
|
||||
use TYPO3\CMS\Backend\Backend\Event\SystemInformationToolbarCollectorEvent;
|
||||
use TYPO3\CMS\Backend\Toolbar\InformationStatus;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class ReleaseToolbarItem
|
||||
{
|
||||
public function __invoke(SystemInformationToolbarCollectorEvent $event): void
|
||||
{
|
||||
$systemInformationToolbarItem = $event->getToolbarItem();
|
||||
|
||||
$release = $this->getRelease();
|
||||
if ($release !== []) {
|
||||
$label = $this->getLanguageService()->sL(
|
||||
'LLL:EXT:ew_base/Resources/Private/Language/locallang_core.xlf:rm.release_label-'
|
||||
. ($release['isTag'] ? 'tag' : 'branch')
|
||||
);
|
||||
$systemInformationToolbarItem->addSystemInformation(
|
||||
$label,
|
||||
$release['release'],
|
||||
'information-git',
|
||||
InformationStatus::OK
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRelease(): array
|
||||
{
|
||||
$release = GeneralUtility::getUrl(Environment::getProjectPath() . '/release');
|
||||
return $release ? [
|
||||
'release' => trim($release),
|
||||
'isTag' => str_contains($release, '.'),
|
||||
] : [];
|
||||
}
|
||||
|
||||
private function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
114
Classes/Form/Element/PickColorFromImage.php
Executable file → Normal file
114
Classes/Form/Element/PickColorFromImage.php
Executable file → Normal file
@ -2,8 +2,6 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\Form\Element;
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
@ -15,11 +13,14 @@ namespace Evoweb\EwBase\Form\Element;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\Form\Element;
|
||||
|
||||
use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
|
||||
use TYPO3\CMS\Backend\Form\NodeFactory;
|
||||
use TYPO3\CMS\Backend\View\BackendViewFactory;
|
||||
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
|
||||
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
|
||||
use TYPO3\CMS\Core\Imaging\ImageManipulation\InvalidConfigurationException;
|
||||
use TYPO3\CMS\Core\Imaging\ImageManipulation\Ratio;
|
||||
use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
|
||||
use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException;
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
@ -27,15 +28,11 @@ use TYPO3\CMS\Core\Resource\ResourceFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
use TYPO3\CMS\Core\Utility\StringUtility;
|
||||
use TYPO3Fluid\Fluid\ViEvoweb\TemplateView;
|
||||
use TYPO3Fluid\Fluid\ViEvoweb\ViewInterface;
|
||||
|
||||
class PickColorFromImage extends AbstractFormElement
|
||||
{
|
||||
/**
|
||||
* Default element configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static array $defaultConfig = [
|
||||
'imageField' => 'image',
|
||||
@ -110,22 +107,10 @@ class PickColorFromImage extends AbstractFormElement
|
||||
],
|
||||
];
|
||||
|
||||
protected ViewInterface $templateView;
|
||||
|
||||
public function __construct(NodeFactory $nodeFactory, array $data)
|
||||
{
|
||||
parent::__construct($nodeFactory, $data);
|
||||
// Would be great, if we could inject the view here, but since the constructor is in the interface, we can't
|
||||
// @todo: It's unfortunate we're using Typo3Fluid TemplateView directly here. We can't
|
||||
// inject BackendViewFactory here since __construct() is polluted by NodeInterface.
|
||||
// Remove __construct() from NodeInterface to have DI, then use BackendViewFactory here.
|
||||
$view = GeneralUtility::makeInstance(TemplateView::class);
|
||||
$templatePaths = $view->getRenderingContext()->getTemplatePaths();
|
||||
$templatePaths
|
||||
->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:ew_base/Resources/Private/Templates')]);
|
||||
$templatePaths
|
||||
->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:ew_base/Resources/Private/Partials')]);
|
||||
$this->templateView = $view;
|
||||
public function __construct(
|
||||
private readonly BackendViewFactory $backendViewFactory,
|
||||
private readonly ResourceFactory $resourceFactory,
|
||||
) {
|
||||
}
|
||||
|
||||
public function render(): array
|
||||
@ -133,40 +118,22 @@ class PickColorFromImage extends AbstractFormElement
|
||||
$resultArray = $this->initializeResultArray();
|
||||
$parameterArray = $this->data['parameterArray'];
|
||||
$config = $this->populateConfiguration($parameterArray['fieldConf']['config']);
|
||||
$fieldId = StringUtility::getUniqueId('formengine-color-');
|
||||
|
||||
$file = $this->getFileObject($this->data['databaseRow'], $config['imageField']);
|
||||
$file = $this->getFile($this->data['databaseRow'], $config['imageField']);
|
||||
if (!$file) {
|
||||
$languageService = $this->getLanguageService();
|
||||
$label = $languageService->sL(
|
||||
'LLL:EXT:ew_base/Resources/Private/Language/locallang_db.xlf:imageField.empty'
|
||||
);
|
||||
$fieldLabel = $this->data['processedTca']['columns'][$config['imageField']]['label'];
|
||||
$resultArray['html'] = '
|
||||
<div class="form-control-wrap">
|
||||
<div class="form-wizards-wrap">
|
||||
<div class="form-wizards-element">
|
||||
<typo3-formengine-element-pick-color recordFieldId="' . htmlspecialchars($fieldId) . '">
|
||||
' . sprintf($label, '<strong>' . $fieldLabel . '</strong>') . '
|
||||
</typo3-formengine-element-pick-color>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
// Early return in case we do not find a file
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
$config = $this->processConfiguration($config, $parameterArray['itemFormElValue'], $file);
|
||||
|
||||
$fieldInformationResult = $this->renderFieldInformation();
|
||||
$fieldInformationHtml = $fieldInformationResult['html'];
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
|
||||
|
||||
$fieldControlResult = $this->renderFieldControl();
|
||||
$fieldControlHtml = $fieldControlResult['html'];
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false);
|
||||
|
||||
$fieldWizardResult = $this->renderFieldWizard();
|
||||
$fieldWizardHtml = $fieldWizardResult['html'];
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
|
||||
|
||||
$width = $this->formMaxWidth(
|
||||
@ -178,9 +145,9 @@ class PickColorFromImage extends AbstractFormElement
|
||||
);
|
||||
|
||||
$arguments = [
|
||||
'fieldInformation' => $fieldInformationHtml,
|
||||
'fieldControl' => $fieldControlHtml,
|
||||
'fieldWizard' => $fieldWizardHtml,
|
||||
'fieldInformation' => $fieldInformationResult['html'],
|
||||
'fieldControl' => $fieldControlResult['html'],
|
||||
'fieldWizard' => $fieldWizardResult['html'],
|
||||
'isAllowedFileExtension' => in_array(
|
||||
strtolower($file->getExtension()),
|
||||
GeneralUtility::trimExplode(',', strtolower($config['allowedExtensions'])),
|
||||
@ -199,6 +166,8 @@ class PickColorFromImage extends AbstractFormElement
|
||||
];
|
||||
|
||||
if ($arguments['isAllowedFileExtension']) {
|
||||
$fieldId = StringUtility::getUniqueId('formengine-color-');
|
||||
|
||||
$resultArray['stylesheetFiles'][] =
|
||||
'EXT:ew_base/Resources/Public/JavaScript/form-engine/element/pick-color-from-image.css';
|
||||
$resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create(
|
||||
@ -215,13 +184,14 @@ class PickColorFromImage extends AbstractFormElement
|
||||
}
|
||||
}
|
||||
|
||||
$this->templateView->assignMultiple($arguments);
|
||||
$resultArray['html'] = $this->templateView->render('Form/ImageManipulationElement');
|
||||
$view = $this->backendViewFactory->create($this->data['request'], ['evoweb/ew-base']);
|
||||
$view->assignMultiple($arguments);
|
||||
$resultArray['html'] = $view->render('Form/ImageManipulationElement');
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
protected function getFileObject(array $row, string $fieldName): ?File
|
||||
protected function getFile(array $row, string $fieldName): ?File
|
||||
{
|
||||
$file = null;
|
||||
$fileUid = !empty($row[$fieldName]) ? $row[$fieldName] : null;
|
||||
@ -230,21 +200,26 @@ class PickColorFromImage extends AbstractFormElement
|
||||
}
|
||||
if (MathUtility::canBeInterpretedAsInteger($fileUid)) {
|
||||
try {
|
||||
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
|
||||
$fileReference = $resourceFactory->getFileReferenceObject($fileUid);
|
||||
$file = $fileReference->getOriginalFile();
|
||||
$file = $this->resourceFactory->getFileObject($fileUid);
|
||||
} catch (FileDoesNotExistException | \InvalidArgumentException) {
|
||||
}
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidConfigurationException
|
||||
*/
|
||||
protected function populateConfiguration(array $baseConfiguration): array
|
||||
{
|
||||
$defaultConfig = self::$defaultConfig;
|
||||
|
||||
// If ratios are set do not add default options
|
||||
if (isset($baseConfiguration['cropVariants'])) {
|
||||
unset($defaultConfig['cropVariants']);
|
||||
}
|
||||
|
||||
$config = array_replace_recursive($defaultConfig, $baseConfiguration);
|
||||
$imageConfig = $this->data['processedTca']['columns'][$config['imageField']];
|
||||
$config['cropVariants'] = $imageConfig['config']['cropVariants'] ?? $defaultConfig['cropVariants'];
|
||||
|
||||
if (!is_array($config['cropVariants'])) {
|
||||
throw new InvalidConfigurationException('Crop variants configuration must be an array', 1485377267);
|
||||
@ -253,12 +228,17 @@ class PickColorFromImage extends AbstractFormElement
|
||||
$cropVariants = [];
|
||||
foreach ($config['cropVariants'] as $id => $cropVariant) {
|
||||
// Filter allowed aspect ratios
|
||||
$cropVariant['allowedAspectRatios'] = array_filter(
|
||||
$cropVariant['allowedAspectRatios'] ?? [],
|
||||
static function ($aspectRatio) {
|
||||
return !(bool)($aspectRatio['disabled'] ?? false);
|
||||
}
|
||||
);
|
||||
$cropVariant['allowedAspectRatios'] = array_filter($cropVariant['allowedAspectRatios'] ?? [], static function (array $aspectRatio): bool {
|
||||
return !(bool)($aspectRatio['disabled'] ?? false);
|
||||
});
|
||||
|
||||
// Aspect ratios may not contain a "." character, see Ratio::__construct()
|
||||
// To match them again properly, same replacement is required here.
|
||||
$preparedAllowedAspectRatios = [];
|
||||
foreach ($cropVariant['allowedAspectRatios'] as $aspectRatio => $aspectRatioDefinition) {
|
||||
$preparedAllowedAspectRatios[Ratio::prepareAspectRatioId($aspectRatio)] = $aspectRatioDefinition;
|
||||
}
|
||||
$cropVariant['allowedAspectRatios'] = $preparedAllowedAspectRatios;
|
||||
|
||||
// Ignore disabled crop variants
|
||||
if (!empty($cropVariant['disabled'])) {
|
||||
@ -266,10 +246,7 @@ class PickColorFromImage extends AbstractFormElement
|
||||
}
|
||||
|
||||
if (empty($cropVariant['allowedAspectRatios'])) {
|
||||
throw new InvalidConfigurationException(
|
||||
'Crop variants configuration ' . $id . ' contains no allowed aspect ratios',
|
||||
1620147893
|
||||
);
|
||||
throw new InvalidConfigurationException('Crop variants configuration ' . $id . ' contains no allowed aspect ratios', 1620147893);
|
||||
}
|
||||
|
||||
// Enforce a crop area (default is full image)
|
||||
@ -282,8 +259,8 @@ class PickColorFromImage extends AbstractFormElement
|
||||
|
||||
$config['cropVariants'] = $cropVariants;
|
||||
|
||||
// By default we allow all image extensions that can be handled by the GFX functionality
|
||||
$config['allowedExtensions'] ??= $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'];
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
@ -295,10 +272,7 @@ class PickColorFromImage extends AbstractFormElement
|
||||
$elementValue = (string)$cropVariantCollection;
|
||||
}
|
||||
$config['cropVariants'] = $cropVariantCollection->asArray();
|
||||
$config['allowedExtensions'] = implode(
|
||||
', ',
|
||||
GeneralUtility::trimExplode(',', $config['allowedExtensions'], true)
|
||||
);
|
||||
$config['allowedExtensions'] = implode(', ', GeneralUtility::trimExplode(',', $config['allowedExtensions'], true));
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\Form\FormDataProvider;
|
||||
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteDatabaseEditRow;
|
||||
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class UsercentricsDatabaseEditRow extends SiteDatabaseEditRow
|
||||
{
|
||||
/**
|
||||
* First level of ['customData']['siteData'] to ['databaseRow']
|
||||
*
|
||||
* @param array $result
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function addData(array $result): array
|
||||
{
|
||||
if ($result['command'] !== 'edit' || $result['tableName'] !== 'site_usercentrics') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$tableName = $result['tableName'];
|
||||
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class, $this->siteConfiguration);
|
||||
if (in_array($tableName, ['site_usercentrics'], true)) {
|
||||
$rootPageId = (int)($result['inlineTopMostParentUid'] ?? $result['inlineParentUid']);
|
||||
try {
|
||||
$rowData = $this->getRawConfigurationForSiteWithRootPageId($siteFinder, $rootPageId);
|
||||
$parentFieldName = $result['inlineParentFieldName'];
|
||||
if (!isset($rowData[$parentFieldName])) {
|
||||
throw new \RuntimeException('Field "' . $parentFieldName . '" not found', 1520886092);
|
||||
}
|
||||
$rowData = $rowData[$parentFieldName][$result['vanillaUid']];
|
||||
$result['databaseRow']['uid'] = $result['vanillaUid'];
|
||||
} catch (SiteNotFoundException $e) {
|
||||
$rowData = [];
|
||||
}
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($rowData as $fieldName => $value) {
|
||||
// Flat values only - databaseRow has no "tree"
|
||||
if (!is_array($value)) {
|
||||
$result['databaseRow'][$fieldName] = $value;
|
||||
}
|
||||
}
|
||||
// All "records" are always on pid 0
|
||||
$result['databaseRow']['pid'] = 0;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\Form\FormDataProvider;
|
||||
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteTcaInline;
|
||||
|
||||
/**
|
||||
* Special data provider for the sites configuration module.
|
||||
*
|
||||
* Handle inline children of 'site'
|
||||
*/
|
||||
class UsercentricsTcaInline extends SiteTcaInline
|
||||
{
|
||||
/**
|
||||
* Resolve inline fields
|
||||
*
|
||||
* @param array $result
|
||||
* @return array
|
||||
*/
|
||||
public function addData(array $result): array
|
||||
{
|
||||
$result = $this->addInlineFirstPid($result);
|
||||
foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
|
||||
if (!$this->isInlineField($fieldConfig)) {
|
||||
continue;
|
||||
}
|
||||
$childTableName = $fieldConfig['config']['foreign_table'] ?? '';
|
||||
if (!in_array($childTableName, ['site_usercentrics'], true)) {
|
||||
continue;
|
||||
}
|
||||
$result['processedTca']['columns'][$fieldName]['children'] = [];
|
||||
$result = $this->resolveSiteRelatedChildren($result, $fieldName);
|
||||
if (!empty($result['processedTca']['columns'][$fieldName]['config']['selectorOrUniqueConfiguration'])) {
|
||||
throw new \RuntimeException('selectorOrUniqueConfiguration not implemented in sites module', 1624313533);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\Hooks;
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class PageLayoutView
|
||||
{
|
||||
public function contentIsUsed(array $params): bool
|
||||
{
|
||||
return $params['used'] || $this->findCTypeBegin($params['record']['CType']);
|
||||
}
|
||||
|
||||
public function findCTypeBegin($cType): bool
|
||||
{
|
||||
$found = false;
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['ContentUsedStrings'] ?? [] as $search) {
|
||||
if (str_contains($cType, $search)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\Hooks;
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Exception;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class UsercentricsPostRenderHook
|
||||
{
|
||||
private array $siteArguments = [
|
||||
'id' => '',
|
||||
'version' => 'loader',
|
||||
'useBlocker' => false,
|
||||
];
|
||||
|
||||
public function executePostRenderHook(array $params): void
|
||||
{
|
||||
$pageUid = $this->getRequest()->getAttribute('frontend.controller')->page['uid'] ?? 0;
|
||||
if ($pageUid < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$siteArguments = $this->getCurrentSiteArguments($pageUid);
|
||||
$id = $siteArguments['id'] ?? '';
|
||||
if ($id !== '') {
|
||||
$extensionConfig = $this->getExtensionConfiguration();
|
||||
|
||||
$preload = [];
|
||||
$usercentrics = [];
|
||||
|
||||
// CMP 1, 2, ...
|
||||
$version = $siteArguments['version'] ?? '';
|
||||
if ($config = $extensionConfig[$version] ?? false) {
|
||||
$preload[] = $config['preload'] ?? '';
|
||||
$usercentrics[] = $config['template'] ?? '';
|
||||
}
|
||||
|
||||
// Blocker
|
||||
if (
|
||||
($siteArguments['useBlocker'] ?? false)
|
||||
&& $config = $extensionConfig['block'] ?? false
|
||||
) {
|
||||
$preload[] = $config['preload'] ?? '';
|
||||
$usercentrics[] = $config['template'] ?? '';
|
||||
}
|
||||
|
||||
$params['titleTag'] .= str_replace('###ID###', $id, implode(LF, array_merge($preload, $usercentrics)));
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCurrentSiteArguments(int $pageUid): array
|
||||
{
|
||||
$siteArguments = $this->siteArguments;
|
||||
|
||||
try {
|
||||
/** @var SiteFinder $siteFinder */
|
||||
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
|
||||
$site = $siteFinder->getSiteByPageId($pageUid);
|
||||
foreach ($site->getAttribute('usercentrics') as $usercentrics) {
|
||||
if (str_contains($usercentrics['applicationContext'] ?? '', (string)Environment::getContext())) {
|
||||
$siteArguments = $usercentrics;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception) {
|
||||
}
|
||||
|
||||
return is_array($siteArguments) ? $siteArguments : [];
|
||||
}
|
||||
|
||||
protected function getExtensionConfiguration(): array
|
||||
{
|
||||
/** @var ExtensionConfiguration $extensionConfiguration */
|
||||
$extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class);
|
||||
try {
|
||||
$configuration = $extensionConfiguration->get('ew_base', 'userCentrics');
|
||||
} catch (Exception) {
|
||||
$configuration = [];
|
||||
}
|
||||
return is_array($configuration) ? $configuration : [];
|
||||
}
|
||||
|
||||
protected function getRequest(): ServerRequestInterface
|
||||
{
|
||||
return $GLOBALS['TYPO3_REQUEST'];
|
||||
}
|
||||
}
|
||||
312
Classes/Services/QueryBuilderHelper.php
Normal file
312
Classes/Services/QueryBuilderHelper.php
Normal file
@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\Services;
|
||||
|
||||
use Doctrine\DBAL\ArrayParameterType;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
|
||||
/**
|
||||
* Utility class that parses sql statements with regard to types and parameters.
|
||||
*/
|
||||
class QueryBuilderHelper
|
||||
{
|
||||
public function getStatement(QueryBuilder $queryBuilder): string
|
||||
{
|
||||
[$sql, $parameters, $types] = $this->expandListParameters(
|
||||
$queryBuilder->getSQL(),
|
||||
$queryBuilder->getParameters(),
|
||||
$queryBuilder->getParameterTypes(),
|
||||
);
|
||||
|
||||
array_walk($parameters, function ($value, $key) use (&$sql, $types) {
|
||||
if ($types[$key] == ParameterType::STRING) {
|
||||
$value = '\'' . $value . '\'';
|
||||
} elseif ($types[$key] == ParameterType::INTEGER) {
|
||||
$value = '' . $value;
|
||||
} elseif ($types[$key] == ArrayParameterType::INTEGER) {
|
||||
$value = implode(', ', $value);
|
||||
} elseif ($types[$key] == ArrayParameterType::STRING) {
|
||||
$value = $value ? '"' . implode('", "', $value) . '"' : '""';
|
||||
}
|
||||
if (is_int($key)) {
|
||||
$sql = substr_replace($sql, (string)$value, strpos($sql, '?'), 1);
|
||||
} else {
|
||||
$sql = str_replace(':' . $key, $value, $sql);
|
||||
}
|
||||
});
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of the placeholders in a sql statements as keys and their positions in the query string.
|
||||
*
|
||||
* For a statement with positional parameters, returns a zero-indexed list of placeholder position.
|
||||
* For a statement with named parameters, returns a map of placeholder positions to their parameter names.
|
||||
*/
|
||||
public function getPlaceholderPositions(string $statement, bool $isPositional = true): array
|
||||
{
|
||||
return $isPositional
|
||||
? $this->getPositionalPlaceholderPositions($statement)
|
||||
: $this->getNamedPlaceholderPositions($statement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a zero-indexed list of placeholder position.
|
||||
*
|
||||
* @return list<int>
|
||||
*/
|
||||
private function getPositionalPlaceholderPositions(string $statement): array
|
||||
{
|
||||
return $this->collectPlaceholders(
|
||||
$statement,
|
||||
'?',
|
||||
'\?',
|
||||
function (string $_, int $placeholderPosition, int $fragmentPosition, array &$carry): void {
|
||||
$carry[] = $placeholderPosition + $fragmentPosition;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of placeholder positions to their parameter names.
|
||||
*
|
||||
* @return array<int,string>
|
||||
*/
|
||||
private function getNamedPlaceholderPositions(string $statement): array
|
||||
{
|
||||
return $this->collectPlaceholders(
|
||||
$statement,
|
||||
':',
|
||||
'(?<!:):[a-zA-Z_][a-zA-Z0-9_]*',
|
||||
function (
|
||||
string $placeholder,
|
||||
int $placeholderPosition,
|
||||
int $fragmentPosition,
|
||||
array &$carry
|
||||
): void {
|
||||
$carry[$placeholderPosition + $fragmentPosition] = substr($placeholder, 1);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private function collectPlaceholders(
|
||||
string $statement,
|
||||
string $match,
|
||||
string $token,
|
||||
callable $collector
|
||||
): array {
|
||||
if (!str_contains($statement, $match)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$carry = [];
|
||||
|
||||
foreach ($this->getUnquotedStatementFragments($statement) as $fragment) {
|
||||
preg_match_all('/' . $token . '/', $fragment[0], $matches, PREG_OFFSET_CAPTURE);
|
||||
foreach ($matches[0] as $placeholder) {
|
||||
$collector($placeholder[0], $placeholder[1], $fragment[1], $carry);
|
||||
}
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a positional query this method can rewrite the sql statement with regard to array parameters.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function expandListParameters(string $query, array $params, array $types): array
|
||||
{
|
||||
$isPositional = is_int(key($params));
|
||||
$bindIndex = -1;
|
||||
$arrayPositions = [];
|
||||
|
||||
if ($isPositional) {
|
||||
// make sure that $types has the same keys as $params
|
||||
// to allow omitting parameters with unspecified types
|
||||
$types += array_fill_keys(array_keys($params), null);
|
||||
|
||||
ksort($params);
|
||||
ksort($types);
|
||||
}
|
||||
|
||||
foreach ($types as $name => $type) {
|
||||
++$bindIndex;
|
||||
|
||||
if ($type !== ArrayParameterType::INTEGER && $type !== ArrayParameterType::STRING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($isPositional) {
|
||||
$name = $bindIndex;
|
||||
}
|
||||
|
||||
$arrayPositions[$name] = false;
|
||||
}
|
||||
|
||||
// parameter are positional and no array parameter given
|
||||
if ($isPositional && !$arrayPositions) {
|
||||
return [$query, $params, $types];
|
||||
}
|
||||
|
||||
return $isPositional
|
||||
? $this->preparePositionalParameters($query, $params, $types, $arrayPositions)
|
||||
: $this->convertNamedParamsToPositionalParams($query, $params, $types, $arrayPositions);
|
||||
}
|
||||
|
||||
private function preparePositionalParameters(
|
||||
string $query,
|
||||
array $params,
|
||||
array $types,
|
||||
array $arrayPositions
|
||||
): array {
|
||||
$paramOffset = 0;
|
||||
$queryOffset = 0;
|
||||
$params = array_values($params);
|
||||
$types = array_values($types);
|
||||
|
||||
$paramPos = $this->getPositionalPlaceholderPositions($query);
|
||||
|
||||
foreach ($paramPos as $needle => $needlePos) {
|
||||
if (!isset($arrayPositions[$needle])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$needle += $paramOffset;
|
||||
$needlePos += $queryOffset;
|
||||
$count = count($params[$needle]);
|
||||
|
||||
$params = array_merge(
|
||||
array_slice($params, 0, $needle),
|
||||
$params[$needle],
|
||||
array_slice($params, $needle + 1)
|
||||
);
|
||||
|
||||
$types = array_merge(
|
||||
array_slice($types, 0, $needle),
|
||||
$count ?
|
||||
// array needles are at {@link \Doctrine\DBAL\ArrayParameterType} constants
|
||||
array_fill(0, $count, $types[$needle]) :
|
||||
[],
|
||||
array_slice($types, $needle + 1)
|
||||
);
|
||||
|
||||
$expandStr = $count ? implode(', ', array_fill(0, $count, '?')) : 'NULL';
|
||||
$query = substr($query, 0, $needlePos) . $expandStr . substr($query, $needlePos + 1);
|
||||
|
||||
$paramOffset += $count - 1; // Grows larger by number of parameters minus the replaced needle.
|
||||
$queryOffset += strlen($expandStr) - 1;
|
||||
}
|
||||
|
||||
return [$query, $params, $types];
|
||||
}
|
||||
|
||||
private function convertNamedParamsToPositionalParams(
|
||||
string $query,
|
||||
array $params,
|
||||
array $types,
|
||||
array $arrayPositions
|
||||
): array {
|
||||
$queryOffset = 0;
|
||||
$typesOrd = [];
|
||||
$paramsOrd = [];
|
||||
|
||||
$paramPos = $this->getNamedPlaceholderPositions($query);
|
||||
|
||||
foreach ($paramPos as $pos => $paramName) {
|
||||
$paramLen = strlen($paramName) + 1;
|
||||
$value = $this->extractParam($paramName, $params, true);
|
||||
|
||||
if (!isset($arrayPositions[$paramName]) && !isset($arrayPositions[':' . $paramName])) {
|
||||
$pos += $queryOffset;
|
||||
$queryOffset -= $paramLen - 1;
|
||||
$paramsOrd[] = $value;
|
||||
$typesOrd[] = $this->extractParam($paramName, $types, false, ParameterType::STRING);
|
||||
$query = substr($query, 0, $pos) . '?' . substr($query, $pos + $paramLen);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$count = count($value);
|
||||
$expandStr = $count > 0 ? implode(', ', array_fill(0, $count, '?')) : 'NULL';
|
||||
|
||||
foreach ($value as $val) {
|
||||
$paramsOrd[] = $val;
|
||||
$type = $this->extractParam($paramName, $types, false);
|
||||
$typesOrd[] = match ($type) {
|
||||
ArrayParameterType::INTEGER => ParameterType::INTEGER,
|
||||
ArrayParameterType::STRING => ParameterType::STRING,
|
||||
default => $type
|
||||
};
|
||||
}
|
||||
|
||||
$pos += $queryOffset;
|
||||
$queryOffset += strlen($expandStr) - $paramLen;
|
||||
$query = substr($query, 0, $pos) . $expandStr . substr($query, $pos + $paramLen);
|
||||
}
|
||||
|
||||
return [$query, $paramsOrd, $typesOrd];
|
||||
}
|
||||
|
||||
/**
|
||||
* Slice the SQL statement around pairs of quotes and
|
||||
* return string fragments of outside SQL of quoted literals.
|
||||
* Each fragment is captured as a 2-element array:
|
||||
*
|
||||
* 0 => matched fragment string,
|
||||
* 1 => offset of fragment in $statement
|
||||
*/
|
||||
private function getUnquotedStatementFragments(string $statement): array
|
||||
{
|
||||
$literal = "(?:'(?:\\\\)+'|'(?:[^'\\\\]|\\\\'?|'')*')"
|
||||
. '|' . '(?:"(?:\\\\)+"|"(?:[^"\\\\]|\\\\"?)*")'
|
||||
. '|' . '(?:`(?:\\\\)+`|`(?:[^`\\\\]|\\\\`?)*`)'
|
||||
. '|' . '(?<!\b(?i:ARRAY))\[(?:[^\]])*\]';
|
||||
$expression = sprintf('/((.+(?i:ARRAY)\\[.+\\])|([^\'"`\\[]+))(?:%s)?/s', $literal);
|
||||
|
||||
preg_match_all($expression, $statement, $fragments, PREG_OFFSET_CAPTURE);
|
||||
|
||||
return $fragments[1];
|
||||
}
|
||||
|
||||
private function extractParam(
|
||||
string $paramName,
|
||||
array $paramsOrTypes,
|
||||
bool $isParam,
|
||||
mixed $defaultValue = null
|
||||
): mixed {
|
||||
if (array_key_exists($paramName, $paramsOrTypes)) {
|
||||
return $paramsOrTypes[$paramName];
|
||||
}
|
||||
if (array_key_exists(':' . $paramName, $paramsOrTypes)) {
|
||||
// Hash keys can be prefixed with a colon for compatibility
|
||||
return $paramsOrTypes[':' . $paramName];
|
||||
}
|
||||
|
||||
if ($defaultValue !== null) {
|
||||
return $defaultValue;
|
||||
}
|
||||
|
||||
if ($isParam) {
|
||||
throw new \Exception($paramName);
|
||||
}
|
||||
|
||||
throw new \Exception($paramName);
|
||||
}
|
||||
}
|
||||
@ -1,98 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ToolbarItems;
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Toolbar\RequestAwareToolbarItemInterface;
|
||||
use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
|
||||
use TYPO3\CMS\Backend\View\BackendViewFactory;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class ReleaseToolbarItem implements ToolbarItemInterface, RequestAwareToolbarItemInterface
|
||||
{
|
||||
private ServerRequestInterface $request;
|
||||
|
||||
public function __construct(
|
||||
private readonly BackendViewFactory $backendViewFactory,
|
||||
) {
|
||||
}
|
||||
|
||||
public function setRequest(ServerRequestInterface $request): void
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function checkAccess(): bool
|
||||
{
|
||||
$result = false;
|
||||
$backendUser = $this->getBackendUser();
|
||||
if ($backendUser->isAdmin()) {
|
||||
$result = true;
|
||||
}
|
||||
if ($backendUser->getTSConfig()['options.']['showSystemInformation'] ?? false) {
|
||||
$result = true;
|
||||
}
|
||||
$release = $this->getRelease();
|
||||
if (empty($release)) {
|
||||
$result = false;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getItem(): string
|
||||
{
|
||||
$view = $this->backendViewFactory->create($this->request, ['typo3/cms-backend', 'evoweb/ew-base']);
|
||||
return $view->render('ToolbarItems/ShowReleaseToolbarItem');
|
||||
}
|
||||
|
||||
public function hasDropDown(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDropDown(): string
|
||||
{
|
||||
$view = $this->backendViewFactory->create($this->request, ['typo3/cms-backend', 'evoweb/ew-base']);
|
||||
$view->assignMultiple([
|
||||
'release' => $this->getRelease(),
|
||||
]);
|
||||
return $view->render('ToolbarItems/ShowReleaseDropDown');
|
||||
}
|
||||
|
||||
public function getAdditionalAttributes(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getIndex(): int
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
protected function getRelease(): array
|
||||
{
|
||||
$release = GeneralUtility::getUrl(Environment::getProjectPath() . '/release');
|
||||
return $release ? [
|
||||
'release' => trim($release),
|
||||
'isTag' => str_contains($release, '.'),
|
||||
] : [];
|
||||
}
|
||||
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\Updates;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* Migrate gridelements elements to container elements
|
||||
*/
|
||||
#[UpgradeWizard('gridelementsToContainer')]
|
||||
class GridelementsToContainerMigration implements UpgradeWizardInterface
|
||||
{
|
||||
private const TABLE_NAME = 'tt_content';
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
protected GridelementsToContainerService $service,
|
||||
protected LogManager $logManager,
|
||||
) {
|
||||
$this->logger = $logManager->getLogger(self::class);
|
||||
}
|
||||
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'gridelementsToContainer';
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Migrate gridelements to container';
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Migrates content elements that are type gridelements to corresponding container elements';
|
||||
}
|
||||
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
return $this->hasRecordsToUpdate();
|
||||
}
|
||||
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$updateSuccessful = true;
|
||||
try {
|
||||
$this->service->migrate();
|
||||
} catch (\Exception $exception) {
|
||||
$this->logger->log(LogLevel::ERROR, $exception->getMessage());
|
||||
$updateSuccessful = false;
|
||||
}
|
||||
|
||||
return $updateSuccessful;
|
||||
}
|
||||
|
||||
protected function hasRecordsToUpdate(): bool
|
||||
{
|
||||
return (bool)$this->getPreparedQueryBuilder()->count('uid')->executeQuery()->fetchOne();
|
||||
}
|
||||
|
||||
protected function getPreparedQueryBuilder(): QueryBuilder
|
||||
{
|
||||
$queryBuilder = $this->getConnectionPool()->getQueryBuilderForTable(self::TABLE_NAME);
|
||||
$queryBuilder->getRestrictions()
|
||||
->removeByType(HiddenRestriction::class)
|
||||
->removeByType(StartTimeRestriction::class)
|
||||
->removeByType(EndTimeRestriction::class);
|
||||
$queryBuilder
|
||||
->from(self::TABLE_NAME)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('gridelements_pi1'))
|
||||
);
|
||||
return $queryBuilder;
|
||||
}
|
||||
|
||||
protected function getConnectionPool(): ConnectionPool
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
}
|
||||
}
|
||||
@ -1,268 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
|
||||
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
||||
use TYPO3\CMS\Core\Service\FlexFormService;
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['migrationResolveContainer'] = [];
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['migrationColPosOffset'] = 0;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['migrationMapping'] = [
|
||||
'130' => [
|
||||
'CType' => 'three-col-columns',
|
||||
],
|
||||
'140' => [
|
||||
'CType' => [
|
||||
'search' => 'pi_flexform/type',
|
||||
'matches' => [
|
||||
0 => 'two-col-columns-11',
|
||||
1 => 'two-col-columns-12',
|
||||
2 => 'two-col-columns-21',
|
||||
],
|
||||
],
|
||||
'map' => [
|
||||
'pi_flexform/row_class' => 'frame_class',
|
||||
]
|
||||
],
|
||||
];
|
||||
*/
|
||||
|
||||
class GridelementsToContainerService
|
||||
{
|
||||
private const TABLE_NAME = 'tt_content';
|
||||
|
||||
protected array $resolveContainer = [];
|
||||
|
||||
protected int $colPosOffset = 0;
|
||||
|
||||
protected array $configuration = [];
|
||||
|
||||
public function __construct(
|
||||
protected ConnectionPool $connectionPool,
|
||||
protected DataHandler $dataHandler,
|
||||
protected FlexFormService $flexFormService,
|
||||
) {
|
||||
$config =& $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base'];
|
||||
$this->resolveContainer = $config['migrationResolveContainer'] ?? [];
|
||||
$this->colPosOffset = $config['migrationColPosOffset'] ?? 0;
|
||||
$this->configuration = $config['migrationMapping'] ?? [];
|
||||
}
|
||||
|
||||
public function migrate(): void
|
||||
{
|
||||
$this->initializeDataHandler();
|
||||
|
||||
// Move children out of container and remove container
|
||||
foreach ($this->resolveContainer as $containerId) {
|
||||
$this->resolveContainers((string)$containerId);
|
||||
}
|
||||
|
||||
$this->migrateConfiguredContainer();
|
||||
}
|
||||
|
||||
protected function initializeDataHandler(): void
|
||||
{
|
||||
$backendUser = GeneralUtility::makeInstance(BackendUserAuthentication::class);
|
||||
$backendUser->user = [
|
||||
'uid' => 0,
|
||||
'admin' => 1,
|
||||
];
|
||||
$this->dataHandler->start([], [], $backendUser);
|
||||
}
|
||||
|
||||
|
||||
protected function resolveContainers(string $layout): void
|
||||
{
|
||||
$containers = $this->getGridElementsByLayout($layout);
|
||||
foreach ($containers as $container) {
|
||||
$this->processContainerResolve($container);
|
||||
}
|
||||
}
|
||||
|
||||
protected function processContainerResolve(array $container): void
|
||||
{
|
||||
$children = $this->getGridContainerChildren($container['uid']);
|
||||
// move first child after container
|
||||
$moveAfterThis = $container;
|
||||
foreach ($children as $child) {
|
||||
[$moveAfterThis, $container] = $this->processContainerResolveChild($child, $moveAfterThis, $container);
|
||||
}
|
||||
|
||||
$this->deleteElement($container['uid']);
|
||||
}
|
||||
|
||||
protected function processContainerResolveChild(array $child, array $moveAfterThis, array $container): array
|
||||
{
|
||||
$this->updateElement(
|
||||
$child['uid'],
|
||||
[
|
||||
'tx_gridelements_container' => 0,
|
||||
'colPos' => $container['colPos'],
|
||||
'header' => $child['header'] ?: $container['header']
|
||||
]
|
||||
);
|
||||
$this->moveElementAfterElement($child['uid'], $moveAfterThis['uid']);
|
||||
// use this child to move the next child after
|
||||
$moveAfterThis = $child;
|
||||
// empty container header so only the first child gets the header
|
||||
$container['header'] = '';
|
||||
|
||||
return [$moveAfterThis, $container];
|
||||
}
|
||||
|
||||
protected function deleteElement(int $uid): void
|
||||
{
|
||||
$this->connectionPool
|
||||
->getConnectionForTable(self::TABLE_NAME)
|
||||
->update(self::TABLE_NAME, ['delete' => 1], ['uid' => $uid]);
|
||||
}
|
||||
|
||||
protected function moveElementAfterElement(int $elementToMove, int $elementToMoveAfter): void
|
||||
{
|
||||
$this->dataHandler->moveRecord(self::TABLE_NAME, $elementToMove, $elementToMoveAfter * -1);
|
||||
}
|
||||
|
||||
|
||||
protected function migrateConfiguredContainer(): void
|
||||
{
|
||||
array_walk($this->configuration, function($config, $key) {
|
||||
$containers = $this->getGridElementsByLayout((string)$key);
|
||||
foreach ($containers as $container) {
|
||||
$container['pi_flexform'] = $this->flexFormService->convertFlexFormContentToArray(
|
||||
$container['pi_flexform']
|
||||
);
|
||||
$this->processContainerMigration($container, $config);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function processContainerMigration(array $container, array $config): void
|
||||
{
|
||||
$children = $this->getGridContainerChildren($container['uid']);
|
||||
foreach ($children as $child) {
|
||||
$this->processContainerMigrationChild($child, $container);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'CType' => $this->getCType($container, $config),
|
||||
'tx_gridelements_backend_layout' => ''
|
||||
];
|
||||
|
||||
if (isset($config['map']) && is_array($config['map']) && !empty($container['pi_flexform'])) {
|
||||
$data = $this->addMappedValues($data, $container, $config['map']);
|
||||
}
|
||||
|
||||
$this->updateElement($container['uid'], $data);
|
||||
}
|
||||
|
||||
protected function processContainerMigrationChild(array $child, array $container): void
|
||||
{
|
||||
$this->updateElement(
|
||||
$child['uid'],
|
||||
[
|
||||
'hidden' => $child['hidden'] ?: $container['hidden'],
|
||||
'colPos' => $child['tx_gridelements_columns'] + $this->colPosOffset,
|
||||
'tx_container_parent' => $child['tx_gridelements_container'],
|
||||
'tx_gridelements_columns' => 0,
|
||||
'tx_gridelements_container' => 0,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCType(array $container, array $config): string
|
||||
{
|
||||
if (is_array($config['CType'])) {
|
||||
$value = ArrayUtility::getValueByPath($container, $config['CType']['search']);
|
||||
$result = $config['CType']['matches'][$value] ?? null;
|
||||
} else {
|
||||
$result = $config['CType'] ?? null;
|
||||
}
|
||||
|
||||
if (empty($result)) {
|
||||
throw new \Exception('CType must always be set');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function addMappedValues(array $data, array $container, array $config): array
|
||||
{
|
||||
foreach ($config as $from => $to) {
|
||||
try {
|
||||
$value = ArrayUtility::getValueByPath($container, $from);
|
||||
if (empty($container[$to]) && !empty($value)) {
|
||||
$data[$to] = $value;
|
||||
}
|
||||
} catch (\throwable) {}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
protected function updateElement(int $uid, array $changes): void
|
||||
{
|
||||
$this->connectionPool
|
||||
->getConnectionForTable(self::TABLE_NAME)
|
||||
->update(self::TABLE_NAME, $changes, ['uid' => $uid]);
|
||||
}
|
||||
|
||||
protected function getGridContainerChildren(int $containerUid): array
|
||||
{
|
||||
$queryBuilder = $this->getQueryBuilderForTable();
|
||||
|
||||
return $queryBuilder
|
||||
->select('*')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'tx_gridelements_container',
|
||||
$queryBuilder->createNamedParameter($containerUid, \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->orderBy('sorting')
|
||||
->executeQuery()
|
||||
->fetchAllAssociative();
|
||||
}
|
||||
|
||||
protected function getGridElementsByLayout(string $layout): array
|
||||
{
|
||||
$queryBuilder = $this->getQueryBuilderForTable();
|
||||
$expr = $queryBuilder->expr();
|
||||
|
||||
return $queryBuilder
|
||||
->select('*')
|
||||
->where(
|
||||
$expr->eq('CType', $queryBuilder->createNamedParameter('gridelements_pi1')),
|
||||
$expr->eq('tx_gridelements_backend_layout', $queryBuilder->createNamedParameter($layout))
|
||||
)
|
||||
->orderBy('sorting')
|
||||
->executeQuery()
|
||||
->fetchAllAssociative();
|
||||
}
|
||||
|
||||
protected function getQueryBuilderForTable(string $table = 'tt_content'): QueryBuilder
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
$queryBuilder->getRestrictions()
|
||||
->removeByType(HiddenRestriction::class)
|
||||
->removeByType(StartTimeRestriction::class)
|
||||
->removeByType(EndTimeRestriction::class);
|
||||
|
||||
$queryBuilder->from($table);
|
||||
|
||||
return $queryBuilder;
|
||||
}
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\Updates;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* Migrate parent child elements to container elements
|
||||
*/
|
||||
#[UpgradeWizard('parentChildToContainer')]
|
||||
class ParentChildToContainerMigration implements UpgradeWizardInterface
|
||||
{
|
||||
private const TABLE_NAME = 'tt_content';
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
protected ParentChildToContainerService $service,
|
||||
protected LogManager $logManager,
|
||||
) {
|
||||
$this->logger = $logManager->getLogger(self::class);
|
||||
}
|
||||
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'parentChildToContainer';
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Migrate parent/child to container';
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Migrates content elements that are type parent/child to corresponding container elements';
|
||||
}
|
||||
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
return $this->hasRecordsToUpdate();
|
||||
}
|
||||
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$updateSuccessful = true;
|
||||
try {
|
||||
$this->service->migrate();
|
||||
} catch (\Exception $exception) {
|
||||
$this->logger->log(LogLevel::ERROR, $exception->getMessage());
|
||||
$updateSuccessful = false;
|
||||
}
|
||||
|
||||
return $updateSuccessful;
|
||||
}
|
||||
|
||||
protected function hasRecordsToUpdate(): bool
|
||||
{
|
||||
$queryBuilder = $this->getPreparedQueryBuilder();
|
||||
$tableColumns = $queryBuilder
|
||||
->getConnection()
|
||||
->createSchemaManager()
|
||||
->listTableColumns(self::TABLE_NAME);
|
||||
return isset($tableColumns['parent'])
|
||||
&& $queryBuilder
|
||||
->count('uid')
|
||||
->executeQuery()
|
||||
->fetchOne() > 0;
|
||||
}
|
||||
|
||||
protected function getPreparedQueryBuilder(): QueryBuilder
|
||||
{
|
||||
$queryBuilder = $this->getConnectionPool()->getQueryBuilderForTable(self::TABLE_NAME);
|
||||
$queryBuilder->getRestrictions()
|
||||
->removeByType(HiddenRestriction::class)
|
||||
->removeByType(StartTimeRestriction::class)
|
||||
->removeByType(EndTimeRestriction::class);
|
||||
$queryBuilder
|
||||
->from(self::TABLE_NAME)
|
||||
->where(
|
||||
// check if there are still records that have parent instead of tx_container_parent
|
||||
$queryBuilder->expr()->gt('parent', 0)
|
||||
);
|
||||
return $queryBuilder;
|
||||
}
|
||||
|
||||
protected function getConnectionPool(): ConnectionPool
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
}
|
||||
}
|
||||
@ -1,168 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
|
||||
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
||||
use TYPO3\CMS\Core\Service\FlexFormService;
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['childParentColPosOffset'] = 0;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['childParentMigrationMapping'] = [
|
||||
'downloads' => [ 'CType' => 'container-downloads' ],
|
||||
];
|
||||
*/
|
||||
|
||||
class ParentChildToContainerService
|
||||
{
|
||||
private const TABLE_NAME = 'tt_content';
|
||||
|
||||
protected int $colPosOffset = 0;
|
||||
|
||||
protected array $configuration = [];
|
||||
|
||||
public function __construct(
|
||||
protected ConnectionPool $connectionPool,
|
||||
protected DataHandler $dataHandler,
|
||||
protected FlexFormService $flexFormService,
|
||||
) {
|
||||
$config =& $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base'];
|
||||
$this->colPosOffset = $config['childParentColPosOffset'] ?? 0;
|
||||
$this->configuration = $config['childParentMigrationMapping'] ?? [];
|
||||
}
|
||||
|
||||
public function migrate(): void
|
||||
{
|
||||
$this->initializeDataHandler();
|
||||
$this->migrateConfiguredContainer();
|
||||
}
|
||||
|
||||
protected function initializeDataHandler(): void
|
||||
{
|
||||
$backendUser = GeneralUtility::makeInstance(BackendUserAuthentication::class);
|
||||
$backendUser->user = [
|
||||
'uid' => 0,
|
||||
'admin' => 1,
|
||||
];
|
||||
$this->dataHandler->start([], [], $backendUser);
|
||||
}
|
||||
|
||||
|
||||
protected function migrateConfiguredContainer(): void
|
||||
{
|
||||
array_walk($this->configuration, function($config, $key) {
|
||||
$parents = $this->getParentsByCType((string)$key);
|
||||
foreach ($parents as $parent) {
|
||||
$this->processParentMigration($parent, $config);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function processParentMigration(array $parent, array $config): void
|
||||
{
|
||||
$children = $this->getChildren($parent['uid']);
|
||||
foreach ($children as $child) {
|
||||
$this->processChildMigration($child, $parent);
|
||||
}
|
||||
|
||||
$this->updateElement(
|
||||
$parent['uid'],
|
||||
[
|
||||
'CType' => $this->getCType($parent, $config),
|
||||
'children' => 0,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function processChildMigration(array $child, array $parent): void
|
||||
{
|
||||
$this->updateElement(
|
||||
$child['uid'],
|
||||
[
|
||||
'tx_container_parent' => $parent['uid'],
|
||||
'colPos' => $child['colPos'] + $this->colPosOffset,
|
||||
'parent' => 0,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCType(array $container, array $config): string
|
||||
{
|
||||
if (is_array($config['CType'])) {
|
||||
$value = ArrayUtility::getValueByPath($container, $config['CType']['search']);
|
||||
$result = $config['CType']['matches'][$value] ?? null;
|
||||
} else {
|
||||
$result = $config['CType'] ?? null;
|
||||
}
|
||||
|
||||
if (empty($result)) {
|
||||
throw new \Exception('CType must always be set');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function updateElement(int $uid, array $changes): void
|
||||
{
|
||||
$this->connectionPool
|
||||
->getConnectionForTable(self::TABLE_NAME)
|
||||
->update(self::TABLE_NAME, $changes, ['uid' => $uid]);
|
||||
}
|
||||
|
||||
protected function getChildren(int $parentUid): array
|
||||
{
|
||||
$queryBuilder = $this->getQueryBuilderForTable();
|
||||
|
||||
return $queryBuilder
|
||||
->select('*')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'parent',
|
||||
$queryBuilder->createNamedParameter($parentUid, \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->orderBy('sorting')
|
||||
->executeQuery()
|
||||
->fetchAllAssociative();
|
||||
}
|
||||
|
||||
protected function getParentsByCType(string $cType): array
|
||||
{
|
||||
$queryBuilder = $this->getQueryBuilderForTable();
|
||||
$expr = $queryBuilder->expr();
|
||||
|
||||
return $queryBuilder
|
||||
->select('*')
|
||||
->where(
|
||||
$expr->eq('CType', $queryBuilder->createNamedParameter($cType))
|
||||
)
|
||||
->orderBy('sorting')
|
||||
->executeQuery()
|
||||
->fetchAllAssociative();
|
||||
}
|
||||
|
||||
protected function getQueryBuilderForTable(string $table = 'tt_content'): QueryBuilder
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
$queryBuilder->getRestrictions()
|
||||
->removeByType(HiddenRestriction::class)
|
||||
->removeByType(StartTimeRestriction::class)
|
||||
->removeByType(EndTimeRestriction::class);
|
||||
|
||||
$queryBuilder->from($table);
|
||||
|
||||
return $queryBuilder;
|
||||
}
|
||||
}
|
||||
11
Classes/User/AssetPath.php
Executable file → Normal file
11
Classes/User/AssetPath.php
Executable file → Normal file
@ -2,6 +2,17 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\User;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
31
Classes/ViewHelpers/Array/AddViewHelper.php
Executable file → Normal file
31
Classes/ViewHelpers/Array/AddViewHelper.php
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Array;
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
@ -13,42 +13,29 @@ namespace Evoweb\EwBase\ViewHelpers\Array;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
namespace Evoweb\EwBase\ViewHelpers\Array;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class AddViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('array', 'array', 'Array to add value to');
|
||||
$this->registerArgument('key', 'string', 'Key to add value by', true);
|
||||
$this->registerArgument('value', 'mixed', 'Value to add');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$array = $arguments['array'] ?: [];
|
||||
$key = $arguments['key'];
|
||||
$value = !is_null($arguments['value']) ? $arguments['value'] : $renderChildrenClosure();
|
||||
public function render(): array
|
||||
{
|
||||
$array = $this->arguments['array'] ?: [];
|
||||
$key = $this->arguments['key'];
|
||||
$value = !is_null($this->arguments['value']) ? $this->arguments['value'] : $this->renderChildren();
|
||||
|
||||
return array_merge($array, [$key => $value]);
|
||||
}
|
||||
|
||||
84
Classes/ViewHelpers/Array/ExplodeViewHelper.php
Executable file
84
Classes/ViewHelpers/Array/ExplodeViewHelper.php
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Array;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Explode ViewHelper
|
||||
*
|
||||
* Explodes a string by $glue.
|
||||
*
|
||||
* {data.header -> ewb:iterator.explode(glue: 'constant:LF')}
|
||||
*
|
||||
* <ewb:iterator.explode content="{data.header}" as="as" glue="constant:LF">
|
||||
* <span>{as}</span>
|
||||
* </ewb:iterator.explode>
|
||||
*/
|
||||
class ExplodeViewHelper extends AbstractViewHelper
|
||||
{
|
||||
protected string $method = 'explode';
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument(
|
||||
'as',
|
||||
'string',
|
||||
'Template variable name to assign; if not specified the ViewHelper returns the variable instead.',
|
||||
);
|
||||
$this->registerArgument('content', 'string', 'String to be exploded by glue');
|
||||
$this->registerArgument(
|
||||
'glue',
|
||||
'string',
|
||||
'String used as glue in the string to be exploded. Use glue value of "constant:NAMEOFCONSTANT" '
|
||||
. '(fx "constant:LF" for linefeed as glue)',
|
||||
false,
|
||||
','
|
||||
);
|
||||
}
|
||||
|
||||
public function render(): mixed
|
||||
{
|
||||
$content = $this->arguments['content'] ?? $this->renderChildren();
|
||||
$glue = $this->resolveGlue($this->arguments);
|
||||
$content = call_user_func_array($this->method, [$glue, $content]);
|
||||
|
||||
$as = $this->arguments['as'];
|
||||
if ($as !== null) {
|
||||
$templateVariableContainer = $this->renderingContext->getVariableProvider();
|
||||
$templateVariableContainer->add($as, $content);
|
||||
$output = $this->renderChildren();
|
||||
$templateVariableContainer->remove($as);
|
||||
} else {
|
||||
$output = $content;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function resolveGlue(array $arguments): string
|
||||
{
|
||||
$glue = $arguments['glue'];
|
||||
if (str_contains($glue, ':') && strlen($glue) > 1) {
|
||||
// glue contains a special type identifier, resolve the actual glue
|
||||
[$type, $value] = explode(':', $glue);
|
||||
$glue = match ($type) {
|
||||
'constant' => constant($value),
|
||||
default => $value,
|
||||
};
|
||||
}
|
||||
return $glue;
|
||||
}
|
||||
}
|
||||
70
Classes/ViewHelpers/Be/ThumbnailViewHelper.php
Executable file → Normal file
70
Classes/ViewHelpers/Be/ThumbnailViewHelper.php
Executable file → Normal file
@ -19,21 +19,17 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Imaging\IconSize;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Resource\ProcessedFile;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class ThumbnailViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Initializes the arguments
|
||||
*/
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('row', 'array', 'content data', true);
|
||||
@ -44,34 +40,47 @@ class ThumbnailViewHelper extends AbstractViewHelper
|
||||
/**
|
||||
* Render a constant
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return string Value of constant
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$row = $arguments['row'];
|
||||
$tableName = $arguments['tableName'];
|
||||
$fieldName = $arguments['fieldName'];
|
||||
public function render(): string
|
||||
{
|
||||
$table = $this->arguments['tableName'];
|
||||
$field = $this->arguments['fieldName'];
|
||||
$row = $this->arguments['row'];
|
||||
|
||||
return self::linkEditContent(
|
||||
BackendUtility::thumbCode(row: $row, table: $tableName, field: $fieldName, linkInfoPopup: false),
|
||||
$row
|
||||
$fileReferences = BackendUtility::resolveFileReferences($table, $field, $row);
|
||||
$fileObject = is_array($fileReferences) ? $fileReferences[0]->getOriginalFile() : null;
|
||||
|
||||
if ($fileObject && $fileObject->isMissing()) {
|
||||
/** @var IconFactory $iconFactory */
|
||||
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
|
||||
$label = $this->getLanguageService()->sL(
|
||||
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.file_missing'
|
||||
);
|
||||
return $iconFactory
|
||||
->getIcon('mimetypes-other-other', IconSize::MEDIUM, 'overlay-missing')
|
||||
->setTitle($label . ' ' . $fileObject->getName())
|
||||
->render();
|
||||
}
|
||||
|
||||
$previewFile = $fileObject->process(
|
||||
ProcessedFile::CONTEXT_IMAGEPREVIEW,
|
||||
[
|
||||
'width' => 64,
|
||||
'height' => 64,
|
||||
]
|
||||
);
|
||||
|
||||
return $this->linkEditContent('<img src="' . $previewFile->getPublicUrl() . '"/>', $row );
|
||||
}
|
||||
|
||||
protected static function linkEditContent(string $linkText, $row): string
|
||||
protected function linkEditContent(string $linkText, $row): string
|
||||
{
|
||||
if (empty($linkText)) {
|
||||
return $linkText;
|
||||
}
|
||||
|
||||
$backendUser = self::getBackendUser();
|
||||
$backendUser = $this->getBackendUser();
|
||||
if (
|
||||
$backendUser->check('tables_modify', 'tt_content')
|
||||
&& $backendUser->recordEditAccessInternals('tt_content', $row)
|
||||
@ -87,14 +96,15 @@ class ThumbnailViewHelper extends AbstractViewHelper
|
||||
$row['uid'] => 'edit',
|
||||
],
|
||||
],
|
||||
'returnUrl' => self::getRequest()->getAttribute('normalizedParams')->getRequestUri()
|
||||
// @extensionScannerIgnoreLine
|
||||
'returnUrl' => $this->getRequest()->getAttribute('normalizedParams')->getRequestUri()
|
||||
. '#element-tt_content-' . $row['uid'],
|
||||
];
|
||||
/** @var UriBuilder $uriBuilder */
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
$url = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
|
||||
return '<a href="' . htmlspecialchars($url) . '" title="'
|
||||
. htmlspecialchars(self::getLanguageService()->sL(
|
||||
. htmlspecialchars($this->getLanguageService()->sL(
|
||||
'LLL:EXT:typo3/sysext/backend/Resources/Private/Language/locallang_layout.xlf:edit'
|
||||
))
|
||||
. '">' . $linkText . '</a>';
|
||||
@ -102,17 +112,17 @@ class ThumbnailViewHelper extends AbstractViewHelper
|
||||
return $linkText;
|
||||
}
|
||||
|
||||
protected static function getBackendUser(): BackendUserAuthentication
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
protected static function getLanguageService(): LanguageService
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
protected static function getRequest(): ServerRequestInterface
|
||||
protected function getRequest(): ServerRequestInterface
|
||||
{
|
||||
return $GLOBALS['TYPO3_REQUEST'];
|
||||
}
|
||||
|
||||
32
Classes/ViewHelpers/Condition/InArrayViewHelper.php
Executable file → Normal file
32
Classes/ViewHelpers/Condition/InArrayViewHelper.php
Executable file → Normal file
@ -1,14 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Condition;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
/**
|
||||
@ -19,21 +26,14 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
*/
|
||||
class InArrayViewHelper extends AbstractConditionViewHelper
|
||||
{
|
||||
/**
|
||||
* Initialize arguments
|
||||
*/
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('haystack', 'array', 'haystack', true);
|
||||
$this->registerArgument('needle', 'mixed', 'needle', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return bool
|
||||
*/
|
||||
protected static function evaluateCondition($arguments = null)
|
||||
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
|
||||
{
|
||||
$array = $arguments['haystack']->toArray();
|
||||
return in_array($arguments['needle'], $array);
|
||||
|
||||
34
Classes/ViewHelpers/Condition/StringContainsViewHelper.php
Executable file → Normal file
34
Classes/ViewHelpers/Condition/StringContainsViewHelper.php
Executable file → Normal file
@ -1,14 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Condition;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
/**
|
||||
@ -19,22 +26,15 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
*/
|
||||
class StringContainsViewHelper extends AbstractConditionViewHelper
|
||||
{
|
||||
/**
|
||||
* Initialize arguments
|
||||
*/
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('haystack', 'string', 'haystack', true);
|
||||
$this->registerArgument('needle', 'string', 'need', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return bool
|
||||
*/
|
||||
protected static function evaluateCondition($arguments = null)
|
||||
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
|
||||
{
|
||||
return false !== strpos($arguments['haystack'], $arguments['needle']);
|
||||
return str_contains($arguments['haystack'], $arguments['needle']);
|
||||
}
|
||||
}
|
||||
|
||||
27
Classes/ViewHelpers/Context/DevelopmentViewHelper.php
Executable file → Normal file
27
Classes/ViewHelpers/Context/DevelopmentViewHelper.php
Executable file → Normal file
@ -1,24 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Context;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
class DevelopmentViewHelper extends AbstractConditionViewHelper
|
||||
{
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return bool
|
||||
*/
|
||||
protected static function evaluateCondition($arguments = null)
|
||||
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
|
||||
{
|
||||
return Environment::getContext()->isDevelopment();
|
||||
}
|
||||
|
||||
27
Classes/ViewHelpers/Context/ProductionViewHelper.php
Executable file → Normal file
27
Classes/ViewHelpers/Context/ProductionViewHelper.php
Executable file → Normal file
@ -1,24 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Context;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
class ProductionViewHelper extends AbstractConditionViewHelper
|
||||
{
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return bool
|
||||
*/
|
||||
protected static function evaluateCondition($arguments = null)
|
||||
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
|
||||
{
|
||||
return Environment::getContext()->isProduction();
|
||||
}
|
||||
|
||||
27
Classes/ViewHelpers/Context/StagingViewHelper.php
Executable file → Normal file
27
Classes/ViewHelpers/Context/StagingViewHelper.php
Executable file → Normal file
@ -1,24 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Context;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
|
||||
class StagingViewHelper extends AbstractConditionViewHelper
|
||||
{
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return bool
|
||||
*/
|
||||
protected static function evaluateCondition($arguments = null)
|
||||
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
|
||||
{
|
||||
return 'Production/Staging' === (string)Environment::getContext();
|
||||
}
|
||||
|
||||
28
Classes/ViewHelpers/FixFlexformForExtbaseViewHelper.php
Executable file → Normal file
28
Classes/ViewHelpers/FixFlexformForExtbaseViewHelper.php
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
@ -13,10 +13,10 @@ namespace Evoweb\EwBase\ViewHelpers;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
@ -33,8 +33,6 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
*/
|
||||
class FixFlexformForExtbaseViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
@ -46,30 +44,20 @@ class FixFlexformForExtbaseViewHelper extends AbstractViewHelper
|
||||
$this->registerArgument('data', 'array', 'The data array of content element', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$templateVariableContainer = $renderingContext->getVariableProvider();
|
||||
public function render(): string
|
||||
{
|
||||
$templateVariableContainer = $this->renderingContext->getVariableProvider();
|
||||
|
||||
/** @var FlexFormTools $flexFormTools */
|
||||
$flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
|
||||
|
||||
$data = $arguments['data'];
|
||||
$data = $this->arguments['data'];
|
||||
if (is_array($data['pi_flexform'])) {
|
||||
$data['pi_flexform'] = $flexFormTools->flexArray2Xml($data['pi_flexform']);
|
||||
}
|
||||
|
||||
$templateVariableContainer->add('data', $data);
|
||||
$output = $renderChildrenClosure();
|
||||
$output = $this->renderChildren();
|
||||
$templateVariableContainer->remove('data');
|
||||
|
||||
return $output;
|
||||
|
||||
42
Classes/ViewHelpers/FlexFormViewHelper.php
Executable file → Normal file
42
Classes/ViewHelpers/FlexFormViewHelper.php
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
@ -13,10 +13,10 @@ namespace Evoweb\EwBase\ViewHelpers;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* = Examples =
|
||||
@ -32,14 +32,12 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
*/
|
||||
class FlexFormViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('data', 'array', 'Array to get flex form data from', true);
|
||||
@ -47,33 +45,23 @@ class FlexFormViewHelper extends AbstractViewHelper
|
||||
$this->registerArgument('as', 'string', 'Name of the variable to assign', false, 'flexFormData');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
public function render(): string
|
||||
{
|
||||
$data = [];
|
||||
|
||||
if (is_array($arguments['data'])) {
|
||||
if (isset($arguments['data'][$arguments['fieldName']])) {
|
||||
$data = is_array($arguments['data'][$arguments['fieldName']]) ?
|
||||
$arguments['data'][$arguments['fieldName']] :
|
||||
GeneralUtility::xml2array($arguments['data'][$arguments['fieldName']]);
|
||||
if (is_array($this->arguments['data'])) {
|
||||
if (isset($this->arguments['data'][$this->arguments['fieldName']])) {
|
||||
$data = is_array($this->arguments['data'][$this->arguments['fieldName']]) ?
|
||||
$this->arguments['data'][$this->arguments['fieldName']] :
|
||||
GeneralUtility::xml2array($this->arguments['data'][$this->arguments['fieldName']]);
|
||||
$data = $data['data'] ?? $data;
|
||||
}
|
||||
}
|
||||
|
||||
$templateVariableContainer = $renderingContext->getVariableProvider();
|
||||
$templateVariableContainer->add($arguments['as'], $data);
|
||||
$content = $renderChildrenClosure();
|
||||
$templateVariableContainer->remove($arguments['as']);
|
||||
$templateVariableContainer = $this->renderingContext->getVariableProvider();
|
||||
$templateVariableContainer->add($this->arguments['as'], $data);
|
||||
$content = $this->renderChildren();
|
||||
$templateVariableContainer->remove($this->arguments['as']);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class HashViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('action', 'string', 'Target action');
|
||||
$this->registerArgument('arguments', 'array', 'Arguments for the controller action, associative array');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$result = '';
|
||||
if (
|
||||
$arguments['action'] !== null
|
||||
&& $arguments['arguments'] !== null
|
||||
&& isset($arguments['arguments']['user'])
|
||||
) {
|
||||
$result = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac(
|
||||
$arguments['action'] . '::' . $arguments['arguments']['user']
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class AddViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('array', 'array', 'Array to add value to');
|
||||
$this->registerArgument('key', 'string', 'Key to add value by', true);
|
||||
$this->registerArgument('value', 'mixed', 'Value to add');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$array = $arguments['array'] ?: [];
|
||||
$key = $arguments['key'];
|
||||
$value = $arguments['value'] ?: $renderChildrenClosure();
|
||||
|
||||
return array_merge($array, [$key => $value]);
|
||||
}
|
||||
}
|
||||
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Explode ViewHelper
|
||||
*
|
||||
* Explodes a string by $glue.
|
||||
*
|
||||
* {data.header -> ewb:iterator.explode(glue: 'constant:LF')}
|
||||
*
|
||||
* <ewb:iterator.explode content="{data.header}" as="as" glue="constant:LF">
|
||||
* <span>{as}</span>
|
||||
* </ewb:iterator.explode>
|
||||
*/
|
||||
class ExplodeViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
protected static string $method = 'explode';
|
||||
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument(
|
||||
'as',
|
||||
'string',
|
||||
'Template variable name to assign; if not specified the ViewHelper returns the variable instead.'
|
||||
);
|
||||
$this->registerArgument('content', 'string', 'String to be exploded by glue');
|
||||
$this->registerArgument(
|
||||
'glue',
|
||||
'string',
|
||||
'String used as glue in the string to be exploded. Use glue value of "constant:NAMEOFCONSTANT" ' .
|
||||
'(fx "constant:LF" for linefeed as glue)',
|
||||
false,
|
||||
','
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$content = $arguments['content'] ?? $renderChildrenClosure();
|
||||
$glue = static::resolveGlue($arguments);
|
||||
$content = call_user_func_array(static::$method, [$glue, $content]);
|
||||
|
||||
$as = $arguments['as'];
|
||||
if (true === empty($as)) {
|
||||
$output = $content;
|
||||
} else {
|
||||
$templateVariableContainer = $renderingContext->getVariableProvider();
|
||||
$templateVariableContainer->add($as, $content);
|
||||
$output = $renderChildrenClosure();
|
||||
$templateVariableContainer->remove($as);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected static function resolveGlue(array $arguments): string
|
||||
{
|
||||
$glue = $arguments['glue'];
|
||||
if (false !== strpos($glue, ':') && 1 < strlen($glue)) {
|
||||
// glue contains a special type identifier, resolve the actual glue
|
||||
list ($type, $value) = explode(':', $glue);
|
||||
switch ($type) {
|
||||
case 'constant':
|
||||
$glue = constant($value);
|
||||
break;
|
||||
default:
|
||||
$glue = $value;
|
||||
}
|
||||
}
|
||||
return $glue;
|
||||
}
|
||||
}
|
||||
28
Classes/ViewHelpers/PublicPathViewHelper.php
Executable file → Normal file
28
Classes/ViewHelpers/PublicPathViewHelper.php
Executable file → Normal file
@ -2,8 +2,6 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
*
|
||||
@ -15,10 +13,11 @@ namespace Evoweb\EwBase\ViewHelpers;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\Exception\InvalidFileException;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* = Examples =
|
||||
@ -34,34 +33,23 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
*/
|
||||
class PublicPathViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
protected static ?array $frontendGroupIds = null;
|
||||
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('path', 'string', 'Extension resource path', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidFileException
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$path = (string)$arguments['path'];
|
||||
public function renderStatic(): string
|
||||
{
|
||||
$path = (string)$this->arguments['path'];
|
||||
return PathUtility::getPublicResourceWebPath($path);
|
||||
}
|
||||
}
|
||||
|
||||
29
Classes/ViewHelpers/ReplaceViewHelper.php
Executable file → Normal file
29
Classes/ViewHelpers/ReplaceViewHelper.php
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
@ -13,9 +13,9 @@ namespace Evoweb\EwBase\ViewHelpers;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithContentArgumentAndRenderStatic;
|
||||
|
||||
/**
|
||||
* Variable assigning ViewHelper
|
||||
@ -42,31 +42,20 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithContentArgumentAndRenderS
|
||||
*/
|
||||
class ReplaceViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithContentArgumentAndRenderStatic;
|
||||
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('value', 'string', 'String to replace in');
|
||||
$this->registerArgument('search', 'string', 'Search string');
|
||||
$this->registerArgument('replace', 'string', 'Replace value');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return null
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$content = $arguments['value'];
|
||||
public function render(): string
|
||||
{
|
||||
$content = $this->arguments['value'];
|
||||
if ($content === null) {
|
||||
$content = $renderChildrenClosure();
|
||||
$content = $this->renderChildren();
|
||||
}
|
||||
|
||||
return str_replace($arguments['search'], $arguments['replace'], $content);
|
||||
return str_replace($this->arguments['search'], $this->arguments['replace'], $content);
|
||||
}
|
||||
}
|
||||
|
||||
42
Classes/ViewHelpers/SvgViewHelper.php
Executable file → Normal file
42
Classes/ViewHelpers/SvgViewHelper.php
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
@ -13,12 +13,13 @@ namespace Evoweb\EwBase\ViewHelpers;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Imaging\IconSize;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Type\Icon\IconState;
|
||||
use TYPO3\CMS\Core\Imaging\IconState;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Displays icon identified by icon identifier.
|
||||
@ -61,10 +62,8 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
* </span>
|
||||
* </span>
|
||||
*/
|
||||
class SvgViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper
|
||||
class SvgViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* ViewHelper returns HTML, thus we need to disable output escaping
|
||||
*
|
||||
@ -75,30 +74,25 @@ class SvgViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('identifier', 'string', 'Identifier of the icon as registered in the Icon Registry.', true);
|
||||
$this->registerArgument('size', 'string', 'Desired size of the icon. All values of the Icons.sizes enum are allowed, these are: "small", "default", "large" and "overlay".', false, Icon::SIZE_SMALL);
|
||||
$this->registerArgument('overlay', 'string', 'Identifier of an overlay icon as registered in the Icon Registry.', false);
|
||||
$this->registerArgument('size', 'string', 'Desired size of the icon. All values of the Icons.sizes enum are allowed, these are: "small", "default", "large" and "overlay".', false, IconSize::SMALL);
|
||||
$this->registerArgument('overlay', 'string', 'Identifier of an overlay icon as registered in the Icon Registry.');
|
||||
$this->registerArgument('state', 'string', 'Sets the state of the icon. All values of the Icons.states enum are allowed, these are: "default" and "disabled".', false, IconState::STATE_DEFAULT);
|
||||
$this->registerArgument('alternativeMarkupIdentifier', 'string', 'Alternative icon identifier. Takes precedence over the identifier if supported by the IconProvider.', false);
|
||||
$this->registerArgument('alternativeMarkupIdentifier', 'string', 'Alternative icon identifier. Takes precedence over the identifier if supported by the IconProvider.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints icon html for $identifier key
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$identifier = $arguments['identifier'];
|
||||
$size = $arguments['size'];
|
||||
$overlay = $arguments['overlay'];
|
||||
$state = IconState::cast($arguments['state']);
|
||||
$alternativeMarkupIdentifier = $arguments['alternativeMarkupIdentifier'];
|
||||
public function render(): string
|
||||
{
|
||||
$identifier = $this->arguments['identifier'];
|
||||
$size = $this->arguments['size'];
|
||||
$overlay = $this->arguments['overlay'];
|
||||
$state = IconState::tryFrom($this->arguments['state']);
|
||||
$alternativeMarkupIdentifier = $this->arguments['alternativeMarkupIdentifier'];
|
||||
/** @var IconFactory $iconFactory */
|
||||
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
|
||||
return $iconFactory->getIcon($identifier, $size, $overlay, $state)->getMarkup($alternativeMarkupIdentifier);
|
||||
}
|
||||
|
||||
30
Classes/ViewHelpers/TrimViewHelper.php
Executable file → Normal file
30
Classes/ViewHelpers/TrimViewHelper.php
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is developed by evoWeb.
|
||||
@ -13,40 +13,28 @@ namespace Evoweb\EwBase\ViewHelpers;
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
namespace Evoweb\EwBase\ViewHelpers;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class TrimViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('content', 'string', 'Content to be trimmed');
|
||||
$this->registerArgument('characters', 'string', 'Characters to be removed', false);
|
||||
$this->registerArgument('characters', 'string', 'Characters to be removed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$content = $arguments['content'] ? $arguments['content'] : $renderChildrenClosure();
|
||||
$characters = $arguments['characters'] ? $arguments['characters'] : null;
|
||||
public function render(): string
|
||||
{
|
||||
$content = $this->arguments['content'] ?: $this->renderChildren();
|
||||
$characters = $this->arguments['characters'] ?: null;
|
||||
|
||||
if ($characters !== null) {
|
||||
$content = trim($content, $characters);
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\Xclass;
|
||||
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteDatabaseEditRow as BaseSiteDatabaseEditRow;
|
||||
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class SiteDatabaseEditRow extends BaseSiteDatabaseEditRow
|
||||
{
|
||||
/**
|
||||
* First level of ['customData']['siteData'] to ['databaseRow']
|
||||
*
|
||||
* @param array $result
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function addData(array $result): array
|
||||
{
|
||||
if ($result['command'] !== 'edit' || !empty($result['databaseRow'])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$tableName = $result['tableName'];
|
||||
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class, $this->siteConfiguration);
|
||||
if ($tableName === 'site') {
|
||||
$rootPageId = (int)$result['vanillaUid'];
|
||||
$rowData = $this->getRawConfigurationForSiteWithRootPageId($siteFinder, $rootPageId);
|
||||
$result['databaseRow']['uid'] = $rowData['rootPageId'];
|
||||
$result['databaseRow']['identifier'] = $result['customData']['siteIdentifier'];
|
||||
} elseif (in_array($tableName, ['site_errorhandling', 'site_language', 'site_route', 'site_base_variant'], true)) {
|
||||
$rootPageId = (int)($result['inlineTopMostParentUid'] ?? $result['inlineParentUid']);
|
||||
try {
|
||||
$rowData = $this->getRawConfigurationForSiteWithRootPageId($siteFinder, $rootPageId);
|
||||
$parentFieldName = $result['inlineParentFieldName'];
|
||||
if (!isset($rowData[$parentFieldName])) {
|
||||
throw new \RuntimeException('Field "' . $parentFieldName . '" not found', 1520886092);
|
||||
}
|
||||
$rowData = $rowData[$parentFieldName][$result['vanillaUid']];
|
||||
$result['databaseRow']['uid'] = $result['vanillaUid'];
|
||||
} catch (SiteNotFoundException $e) {
|
||||
$rowData = [];
|
||||
}
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($rowData as $fieldName => $value) {
|
||||
// Flat values only - databaseRow has no "tree"
|
||||
if (!is_array($value)) {
|
||||
$result['databaseRow'][$fieldName] = $value;
|
||||
}
|
||||
}
|
||||
// All "records" are always on pid 0
|
||||
$result['databaseRow']['pid'] = 0;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Evoweb\EwBase\Xclass;
|
||||
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteTcaInline as BaseSiteTcaInline;
|
||||
|
||||
class SiteTcaInline extends BaseSiteTcaInline
|
||||
{
|
||||
/**
|
||||
* Resolve inline fields
|
||||
*
|
||||
* @param array $result
|
||||
* @return array
|
||||
*/
|
||||
public function addData(array $result): array
|
||||
{
|
||||
$result = $this->addInlineFirstPid($result);
|
||||
foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
|
||||
if (!$this->isInlineField($fieldConfig)) {
|
||||
continue;
|
||||
}
|
||||
$childTableName = $fieldConfig['config']['foreign_table'] ?? '';
|
||||
if (!in_array($childTableName, ['site_errorhandling', 'site_route', 'site_base_variant'], true)) {
|
||||
return $result;
|
||||
}
|
||||
$result['processedTca']['columns'][$fieldName]['children'] = [];
|
||||
$result = $this->resolveSiteRelatedChildren($result, $fieldName);
|
||||
if (!empty($result['processedTca']['columns'][$fieldName]['config']['selectorOrUniqueConfiguration'])) {
|
||||
throw new \RuntimeException('selectorOrUniqueConfiguration not implemented in sites module', 1624313533);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
5
Configuration/Icons.php
Executable file → Normal file
5
Configuration/Icons.php
Executable file → Normal file
@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
use TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider;
|
||||
use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider;
|
||||
|
||||
return [
|
||||
@ -12,8 +11,4 @@ return [
|
||||
'provider' => SvgIconProvider::class,
|
||||
'source' => 'EXT:ew_base/Resources/Public/Icons/Extension_16.svg',
|
||||
],
|
||||
'ew-usercentrics' => [
|
||||
'provider' => BitmapIconProvider::class,
|
||||
'source' => 'EXT:ew_base/Resources/Public/Icons/usercentrics.svg',
|
||||
],
|
||||
];
|
||||
|
||||
0
Configuration/JavaScriptModules.php
Executable file → Normal file
0
Configuration/JavaScriptModules.php
Executable file → Normal file
21
Configuration/Services.yaml
Executable file → Normal file
21
Configuration/Services.yaml
Executable file → Normal file
@ -16,29 +16,14 @@ services:
|
||||
|
||||
Evoweb\EwBase\EventListener\CssMerger:
|
||||
tags: ['event.listener']
|
||||
public: true
|
||||
|
||||
Evoweb\EwBase\EventListener\JsMerger:
|
||||
tags: ['event.listener']
|
||||
public: true
|
||||
|
||||
Evoweb\EwBase\EventListener\IsContentUsedOnPageLayout:
|
||||
Evoweb\EwBase\EventListener\ReleaseToolbarItem:
|
||||
tags: ['event.listener']
|
||||
|
||||
Evoweb\EwBase\ToolbarItems\ReleaseToolbarItem:
|
||||
tags: ['backend.toolbar.item']
|
||||
|
||||
Evoweb\EwBase\Hooks\UsercentricsPostRenderHook:
|
||||
public: true
|
||||
|
||||
Evoweb\EwBase\Updates\GridelementsToContainerMigration:
|
||||
public: true
|
||||
|
||||
Evoweb\EwBase\Updates\GridelementsToContainerService:
|
||||
public: true
|
||||
|
||||
Evoweb\EwBase\Updates\ParentChildToContainerMigration:
|
||||
public: true
|
||||
|
||||
Evoweb\EwBase\Updates\ParentChildToContainerService:
|
||||
public: true
|
||||
|
||||
Evoweb\EwBase\Form\FormDataProvider\UsercentricsDatabaseEditRow:
|
||||
|
||||
2
Configuration/Sets/EwBase/config.yaml
Normal file
2
Configuration/Sets/EwBase/config.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
name: evoweb/ew-base
|
||||
label: Site Base
|
||||
11
Configuration/Sets/EwBase/settings.definitions.yaml
Normal file
11
Configuration/Sets/EwBase/settings.definitions.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
categories:
|
||||
ew-base:
|
||||
label: 'Evoweb Base'
|
||||
|
||||
settings:
|
||||
ew-base.inlineCssStyles:
|
||||
default: false
|
||||
label: 'Inline css'
|
||||
type: bool
|
||||
description: 'Weather the concatenated css should get added inline style tag or a css file'
|
||||
category: ew-base
|
||||
2
Configuration/Sets/EwBase/settings.yaml
Normal file
2
Configuration/Sets/EwBase/settings.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
ew-base:
|
||||
inlineCssStyles: false
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
$GLOBALS['SiteConfiguration']['site']['columns']['usercentrics'] = [
|
||||
'label' => 'LLL:EXT:ew_base/Resources/Private/Language/locallang_siteconfiguration.xlf:site.usercentrics',
|
||||
'description' => 'LLL:EXT:ew_base/Resources/Private/Language/locallang_siteconfiguration.xlf:site.usercentrics.description',
|
||||
'config' => [
|
||||
'type' => 'inline',
|
||||
'foreign_table' => 'site_usercentrics',
|
||||
'maxitems' => 1,
|
||||
'appearance' => [
|
||||
'enabledControls' => [
|
||||
'info' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$GLOBALS['SiteConfiguration']['site']['types']['0']['showitem'] = str_replace(
|
||||
' routes',
|
||||
' routes, usercentrics,',
|
||||
$GLOBALS['SiteConfiguration']['site']['types']['0']['showitem']
|
||||
);
|
||||
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'ctrl' => [
|
||||
'label' => 'id',
|
||||
'title' => 'LLL:EXT:ew_base/Resources/Private/Language/locallang_siteconfiguration.xlf:site_usercentrics.ctrl.title',
|
||||
'typeicon_classes' => [
|
||||
'default' => 'ew-usercentrics',
|
||||
],
|
||||
],
|
||||
'columns' => [
|
||||
'id' => [
|
||||
'label' => 'LLL:EXT:ew_base/Resources/Private/Language/locallang_siteconfiguration.xlf:site_usercentrics.column.id',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 12,
|
||||
'max' => 12,
|
||||
],
|
||||
],
|
||||
'version' => [
|
||||
'label' => 'LLL:EXT:ew_base/Resources/Private/Language/locallang_siteconfiguration.xlf:site_usercentrics.column.version',
|
||||
'config' => [
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectSingle',
|
||||
'minitems' => 0,
|
||||
'maxitems' => 1,
|
||||
'size' => 1,
|
||||
'items' => [
|
||||
[
|
||||
0 => 'CMP 2',
|
||||
1 => 'loader',
|
||||
],
|
||||
[
|
||||
0 => 'CMP 1',
|
||||
1 => 'main',
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
'applicationContext' => [
|
||||
'label' => 'LLL:EXT:ew_base/Resources/Private/Language/locallang_siteconfiguration.xlf:site_usercentrics.column.applicationContext',
|
||||
'description' => 'Values are separated by line breaks',
|
||||
'config' => [
|
||||
'type' => 'text',
|
||||
'eval' => 'trim',
|
||||
],
|
||||
],
|
||||
'useBlocker' => [
|
||||
'label' => 'LLL:EXT:ew_base/Resources/Private/Language/locallang_siteconfiguration.xlf:site_usercentrics.column.useBlocker',
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'renderType' => 'checkboxToggle',
|
||||
'default' => false,
|
||||
'items' => [
|
||||
[
|
||||
0 => '',
|
||||
1 => true,
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'1' => [
|
||||
'showitem' => '
|
||||
--palette--;;usercentrics,
|
||||
',
|
||||
],
|
||||
],
|
||||
'palettes' => [
|
||||
'usercentrics' => [
|
||||
'showitem' => '
|
||||
id, version, --linebreak--,
|
||||
applicationContext, useBlocker,
|
||||
'
|
||||
]
|
||||
]
|
||||
];
|
||||
4
Configuration/TCA/Overrides/pages.php
Executable file → Normal file
4
Configuration/TCA/Overrides/pages.php
Executable file → Normal file
@ -10,15 +10,15 @@ $newColumns = [
|
||||
'type' => 'group',
|
||||
'allowed' => 'tt_content',
|
||||
'size' => 1,
|
||||
'relationship' => 'manyToOne',
|
||||
'default' => 0,
|
||||
'maxitems' => 1,
|
||||
'minitems' => 0,
|
||||
'suggestOptions' => [
|
||||
'default' => [
|
||||
'additionalSearchFields' => 'header, bodytext',
|
||||
'searchWholePhrase' => false
|
||||
]
|
||||
],
|
||||
'default' => 0,
|
||||
'behaviour' => [
|
||||
'allowLanguageSynchronization' => true
|
||||
]
|
||||
|
||||
0
Configuration/Yaml/Csp/Cookiebot.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/Cookiebot.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAdsConversions.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAdsConversions.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAdsRemarketing.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAdsRemarketing.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAnalytics4.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAnalytics4.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAnalytics4Signals.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAnalytics4Signals.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAnalytics4SignalsEu.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleAnalytics4SignalsEu.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleOptimize.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleOptimize.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleTagManagerPreview.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/GoogleTagManagerPreview.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/MapBox.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/MapBox.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/UniversalAnalytics.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/UniversalAnalytics.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/Youtube.yaml
Executable file → Normal file
0
Configuration/Yaml/Csp/Youtube.yaml
Executable file → Normal file
345
LICENSE.txt
Normal file
345
LICENSE.txt
Normal file
@ -0,0 +1,345 @@
|
||||
Some icons used in the TYPO3 project are retrieved from the "Silk" icon set of
|
||||
Mark James, which can be found at http://famfamfam.com/lab/icons/silk/. This
|
||||
set is distributed under a Creative Commons Attribution 2.5 License. The
|
||||
license can be found at http://creativecommons.org/licenses/by/2.5/.
|
||||
---------------------------------
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
18
README.md
Executable file → Normal file
18
README.md
Executable file → Normal file
@ -1,19 +1 @@
|
||||
# ew-base
|
||||
## Usercentrics Hook Guide
|
||||
|
||||
Add this snippet to your config/sites to enable the hook
|
||||
```yaml
|
||||
usercentrics:
|
||||
-
|
||||
id: LNxzTaK8j
|
||||
version: loader
|
||||
useBlocker: false
|
||||
applicationContext: "Production/Staging\r\nProduction\r\nDevelopment\r\n"
|
||||
```
|
||||
|
||||
```
|
||||
id - Usercentrics Id
|
||||
version (loader | main) - loader is the v2 and main is v1 in usercentrics context
|
||||
useBlocker - if the content blocker script should be rendered
|
||||
applicationContext - multiline string of application contexts that the snippets should be rendered in
|
||||
```
|
||||
|
||||
3
Resources/Private/Language/locallang_core.xlf
Executable file → Normal file
3
Resources/Private/Language/locallang_core.xlf
Executable file → Normal file
@ -3,9 +3,6 @@
|
||||
<file source-language="en" datatype="plaintext" original="messages" date="2023-02-07T14:19:01Z">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="rm.release">
|
||||
<source>Release information</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="rm.release_label-tag">
|
||||
<source>Release tag</source>
|
||||
</trans-unit>
|
||||
|
||||
0
Resources/Private/Language/locallang_db.xlf
Executable file → Normal file
0
Resources/Private/Language/locallang_db.xlf
Executable file → Normal file
@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="messages" date="2020-02-07T14:19:01Z">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="site.usercentrics">
|
||||
<source>UserCentrics</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="site.usercentrics.description">
|
||||
<source>Max one configuration per site</source>
|
||||
</trans-unit>
|
||||
|
||||
<trans-unit id="site_usercentrics.ctrl.title">
|
||||
<source>Usercentrics configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="site_usercentrics.column.id">
|
||||
<source>ID</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="site_usercentrics.column.id.description">
|
||||
<source>ID defining what user centrics account to use</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="site_usercentrics.column.version">
|
||||
<source>Version</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="site_usercentrics.column.applicationContext">
|
||||
<source>Application Context</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="site_usercentrics.column.useBlocker">
|
||||
<source>use Blocker</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
0
Resources/Private/Templates/Form/ImageManipulationElement.html
Executable file → Normal file
0
Resources/Private/Templates/Form/ImageManipulationElement.html
Executable file → Normal file
@ -1,12 +0,0 @@
|
||||
<html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true">
|
||||
|
||||
<h3 class="dropdown-headline"><f:translate id="LLL:EXT:ew_base/Resources/Private/Language/locallang_core.xlf:rm.release" /></h3>
|
||||
<table class="dropdown-table">
|
||||
<tr>
|
||||
<th data-type="icon"><core:icon identifier="information-git" size="small" /></th>
|
||||
<th data-type="title"><f:translate id="LLL:EXT:ew_base/Resources/Private/Language/locallang_core.xlf:rm.release_label-{f:if(condition: release.isTag, then: 'tag', else: 'branch')}" /></th>
|
||||
<td data-type="value" class="text-{f:if(condition: release.isTag, then: 'success', else: 'warning')}">{release.release -> f:format.htmlentities()}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</html>
|
||||
@ -1,8 +0,0 @@
|
||||
<html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true">
|
||||
|
||||
<f:render partial="ToolbarItems/ToolbarItem" arguments="{
|
||||
title: 'LLL:EXT:ew_base/Resources/Private/Language/locallang_core.xlf:rm.release',
|
||||
icon: '{core:icon(identifier: \'ew-base-extension-small\', size: \'small\', alternativeMarkupIdentifier: \'inline\')}'
|
||||
}" />
|
||||
|
||||
</html>
|
||||
0
Resources/Public/Icons/Extension.svg
Executable file → Normal file
0
Resources/Public/Icons/Extension.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
0
Resources/Public/Icons/Extension_16.svg
Executable file → Normal file
0
Resources/Public/Icons/Extension_16.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 413 B After Width: | Height: | Size: 413 B |
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="layer" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 176 176" style="enable-background:new 0 0 176 176;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#0095FF;}
|
||||
.st1{fill:#B8CEE1;}
|
||||
.st2{fill:#0D47A1;}
|
||||
.st3{fill:#F25900;}
|
||||
</style>
|
||||
<circle class="st0" cx="90.9" cy="88.7" r="26.4"/>
|
||||
<circle class="st1" cx="145.1" cy="35.4" r="10.2"/>
|
||||
<circle class="st2" cx="124.8" cy="132" r="18.3"/>
|
||||
<circle class="st3" cx="34.8" cy="110.9" r="14.2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 677 B |
0
Resources/Public/JavaScript/form-engine/element/pick-color-from-image.css
Executable file → Normal file
0
Resources/Public/JavaScript/form-engine/element/pick-color-from-image.css
Executable file → Normal file
0
Resources/Public/JavaScript/form-engine/element/pick-color-from-image.js
Executable file → Normal file
0
Resources/Public/JavaScript/form-engine/element/pick-color-from-image.js
Executable file → Normal file
3
composer.json
Executable file → Normal file
3
composer.json
Executable file → Normal file
@ -1,14 +1,13 @@
|
||||
{
|
||||
"name": "evoweb/ew-base",
|
||||
"type": "typo3-cms-extension",
|
||||
"version": "1.0.0",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Evoweb\\EwBase\\": "Classes/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"typo3/cms-core": "^11.5 || ^12.4 || dev-main",
|
||||
"typo3/cms-core": "*",
|
||||
|
||||
"typo3/cms-backend": "*",
|
||||
"typo3/cms-extbase": "*",
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
# cat=basic//10; type=boolean; label= Weather the content of css files gets inserted to the source code of the page as inline css
|
||||
inlineCssStyles = 0
|
||||
60
ext_localconf.php
Executable file → Normal file
60
ext_localconf.php
Executable file → Normal file
@ -1,67 +1,15 @@
|
||||
<?php
|
||||
|
||||
defined('TYPO3') or die('access denied');
|
||||
defined('TYPO3') or die();
|
||||
|
||||
use Evoweb\EwBase\Form\Element\PickColorFromImage;
|
||||
use Evoweb\EwBase\Form\FormDataProvider\UsercentricsDatabaseEditRow;
|
||||
use Evoweb\EwBase\Form\FormDataProvider\UsercentricsTcaInline;
|
||||
use Evoweb\EwBase\Hooks\UsercentricsPostRenderHook;
|
||||
use Evoweb\EwBase\Xclass\SiteDatabaseEditRow;
|
||||
use Evoweb\EwBase\Xclass\SiteTcaInline;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseParentPageRow;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteDatabaseEditRow as BaseSiteDatabaseEditRow;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\SiteTcaInline as BaseSiteTcaInline;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSiteLanguage;
|
||||
|
||||
call_user_func(function () {
|
||||
(static function () {
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['ewb'] = [ 'Evoweb\\EwBase\\ViewHelpers' ];
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'][] =
|
||||
UsercentricsPostRenderHook::class . '->executePostRenderHook';
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1681197508] = [
|
||||
'nodeName' => 'pick-color-from-image',
|
||||
'priority' => '70',
|
||||
'priority' => 70,
|
||||
'class' => PickColorFromImage::class,
|
||||
];
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][BaseSiteDatabaseEditRow::class] = [
|
||||
'className' => SiteDatabaseEditRow::class
|
||||
];
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][BaseSiteTcaInline::class] = [
|
||||
'className' => SiteTcaInline::class
|
||||
];
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['siteConfiguration'][
|
||||
UsercentricsDatabaseEditRow::class
|
||||
] = [
|
||||
'depends' => [ BaseSiteDatabaseEditRow::class ],
|
||||
'before' => [ DatabaseParentPageRow::class ],
|
||||
];
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['siteConfiguration'][
|
||||
UsercentricsTcaInline::class
|
||||
] = [
|
||||
'depends' => [ BaseSiteTcaInline::class ],
|
||||
'before' => [ TcaSiteLanguage::class ],
|
||||
];
|
||||
|
||||
if (empty($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['userCentrics'] ?? [])) {
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['userCentrics']['loader']['preload'] =
|
||||
'<link rel="preconnect" href="//app.usercentrics.eu">
|
||||
<link rel="preconnect" href="//privacy-proxy.usercentrics.eu">
|
||||
<link rel="preload" href="//app.usercentrics.eu/browser-ui/latest/loader.js" as="script">';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['userCentrics']['loader']['template'] =
|
||||
'<script src="//app.usercentrics.eu/browser-ui/latest/loader.js" data-settings-id="###ID###" id="usercentrics-cmp" async></script>';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['userCentrics']['main']['preload'] =
|
||||
'<link rel="preconnect" href="//app.usercentrics.eu">
|
||||
<link rel="preconnect" href="//api.usercentrics.eu">
|
||||
<link rel="preconnect" href="//privacy-proxy.usercentrics.eu">
|
||||
<link rel="preload" href="//app.usercentrics.eu/latest/main.js" as="script">';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['userCentrics']['main']['template'] =
|
||||
'<script src="//app.usercentrics.eu/latest/main.js" id="###ID###" type="application/javascript"></script>';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['userCentrics']['block']['preload'] =
|
||||
'<link rel="preload" href="//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" as="script">';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ew_base']['userCentrics']['block']['template'] =
|
||||
'<script type="application/javascript" src="https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js"></script>';
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#
|
||||
# Table structure for table 'pages'
|
||||
#
|
||||
CREATE TABLE pages
|
||||
(
|
||||
sectionIndex_uid int(11) unsigned DEFAULT '0' NOT NULL
|
||||
);
|
||||
Loading…
Reference in New Issue
Block a user