diff --git a/.ddev/apache/10.conf b/.ddev/apache/10.conf
new file mode 100644
index 0000000..be59f2a
--- /dev/null
+++ b/.ddev/apache/10.conf
@@ -0,0 +1,39 @@
+
+ ServerName xima-typo3-content-planner.ddev.site
+ DocumentRoot /var/www/html/.test
+
+ AllowOverride All
+ Allow from All
+
+
+ RewriteEngine On
+ RewriteCond %{HTTP:X-Forwarded-Proto} =https
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
+ RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
+ ErrorLog /dev/stdout
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+ Alias "/phpstatus" "/var/www/phpstatus.php"
+
+
+
+ ServerName xima-typo3-content-planner.ddev.site
+ DocumentRoot /var/www/html/.test
+
+ AllowOverride All
+ Allow from All
+
+
+ RewriteEngine On
+ RewriteCond %{HTTP:X-Forwarded-Proto} =https
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
+ RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
+ ErrorLog /dev/stdout
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+ Alias "/phpstatus" "/var/www/phpstatus.php"
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/certs/master.crt
+ SSLCertificateKeyFile /etc/ssl/certs/master.key
+
diff --git a/.ddev/apache/20.conf b/.ddev/apache/20.conf
new file mode 100644
index 0000000..a6a2970
--- /dev/null
+++ b/.ddev/apache/20.conf
@@ -0,0 +1,47 @@
+
+ ServerName sub.xima-typo3-content-planner.ddev.site
+ ServerAlias *.xima-typo3-content-planner.ddev.site
+ DocumentRoot /var/www/html/.test
+
+ AllowOverride All
+ Allow from All
+
+
+ RewriteEngine On
+ RewriteCond %{HTTP_HOST} ^([a-z0-9-]+)\.xima-typo3-content-planner\.ddev\.site$
+ RewriteRule ^(.*)$ /var/www/html/.test/%1/public/$1 [L]
+
+ RewriteCond %{HTTP:X-Forwarded-Proto} =https
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
+ RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
+ ErrorLog /dev/stdout
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+ Alias "/phpstatus" "/var/www/phpstatus.php"
+
+
+
+ ServerName sub.xima-typo3-content-planner.ddev.site
+ ServerAlias *.xima-typo3-content-planner.ddev.site
+ DocumentRoot /var/www/html/.test
+
+ AllowOverride All
+ Allow from All
+
+
+ RewriteEngine On
+ RewriteCond %{HTTP_HOST} ^([a-z0-9-]+)\.xima-typo3-content-planner\.ddev\.site$
+ RewriteRule ^(.*)$ /var/www/html/.test/%1/public/$1 [L]
+
+ RewriteCond %{HTTP:X-Forwarded-Proto} =https
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
+ RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
+ ErrorLog /dev/stdout
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+ Alias "/phpstatus" "/var/www/phpstatus.php"
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/certs/master.crt
+ SSLCertificateKeyFile /etc/ssl/certs/master.key
+
diff --git a/.ddev/apache/apache-site.conf b/.ddev/apache/apache-site.conf
new file mode 100644
index 0000000..d53c5d9
--- /dev/null
+++ b/.ddev/apache/apache-site.conf
@@ -0,0 +1,100 @@
+# ddev generic/default/php config for apache2
+
+#ddev-generated
+# If you want to take over this file and customize it, remove the line above
+# and ddev will respect it and won't overwrite the file.
+# See https://ddev.readthedocs.io/en/stable/users/extend/customization-extendibility/#custom-apache-configuration
+
+ RewriteEngine On
+ RewriteCond %{HTTP:X-Forwarded-Proto} =https
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
+ RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
+
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
+
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www/html/.test
+
+ AllowOverride All
+ Allow from All
+
+ # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
+ # error, crit, alert, emerg.
+ # It is also possible to configure the loglevel for particular
+ # modules, e.g.
+ #LogLevel info ssl:warn
+
+ ErrorLog /dev/stdout
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+ # For most configuration files from conf-available/, which are
+ # enabled or disabled at a global level, it is possible to
+ # include a line for only one particular virtual host. For example the
+ # following line enables the CGI configuration for this host only
+ # after it has been globally disabled with "a2disconf".
+ #Include conf-available/serve-cgi-bin.conf
+
+ # Increase allowed field size for large cookies header.
+ LimitRequestFieldSize 16380
+
+ # Simple ddev technique to get a phpstatus
+ Alias "/phpstatus" "/var/www/phpstatus.php"
+ Alias "/xhprof" "/var/xhprof/xhprof_html"
+
+ Options Indexes
+ AllowOverride None
+ Require all granted
+
+
+
+
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/certs/master.crt
+ SSLCertificateKeyFile /etc/ssl/certs/master.key
+
+ # Workaround from https://mail-archives.apache.org/mod_mbox/httpd-users/201403.mbox/%3C49404A24C7FAD94BB7B45E86A9305F6214D04652@MSGEXSV21103.ent.wfb.bank.corp%3E
+ # See also https://gist.github.com/nurtext/b6ac07ac7d8c372bc8eb
+
+ RewriteEngine On
+ RewriteCond %{HTTP:X-Forwarded-Proto} =https
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
+ RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
+
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
+
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www/html/.test
+
+ AllowOverride All
+ Allow from All
+
+ # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
+ # error, crit, alert, emerg.
+ # It is also possible to configure the loglevel for particular
+ # modules, e.g.
+ #LogLevel info ssl:warn
+
+ ErrorLog /dev/stdout
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+ # Increase allowed field size for large cookies header.
+ LimitRequestFieldSize 16380
+
+ # For most configuration files from conf-available/, which are
+ # enabled or disabled at a global level, it is possible to
+ # include a line for only one particular virtual host. For example the
+ # following line enables the CGI configuration for this host only
+ # after it has been globally disabled with "a2disconf".
+ #Include conf-available/serve-cgi-bin.conf
+ # Simple ddev technique to get a phpstatus
+ Alias "/phpstatus" "/var/www/phpstatus.php"
+ Alias "/xhprof" "/var/xhprof/xhprof_html"
+
+ Options Indexes
+ AllowOverride None
+ Require all granted
+
+
+
+# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
diff --git a/.ddev/commands/web/.install-11 b/.ddev/commands/web/.install-11
new file mode 100755
index 0000000..11bcb51
--- /dev/null
+++ b/.ddev/commands/web/.install-11
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+. .ddev/commands/web/.utils.sh
+
+VERSION=11
+
+rm -rf /var/www/html/.test/$VERSION/*
+
+message red "ToDo"
+exit 0
+
+intro_typo3 $VERSION
+install_start $VERSION
+export TYPO3_BIN="$BASE_PATH/vendor/bin/typo3cms"
+
+composer req typo3/cms-base-distribution:'^11.5' helhum/typo3-console:'^7.1' $PACKAGE_NAME:'*@dev' \
+ --no-progress -n -d /var/www/html/.test/$VERSION
+
+cd $BASE_PATH
+TYPO3_INSTALL_DB_DBNAME=$DATABASE
+$TYPO3_BIN install:setup -n --database-name $DATABASE
+setup_typo3
+$TYPO3_BIN configuration:set 'GFX/processor_path_lzw' '/usr/bin/'
+
+sed -i "/'deprecations'/,/^[[:space:]]*'disabled' => true,/s/'disabled' => true,/'disabled' => false,/" /var/www/html/.test/$VERSION/public/typo3conf/LocalConfiguration.php
+
+sed -i -e "s/base: ht\//base: \//g" /var/www/html/.test/$VERSION/config/sites/main/config.yaml
+sed -i -e 's/base: \/en\//base: \//g' /var/www/html/.test/$VERSION/config/sites/main/config.yaml
+
+update_typo3
diff --git a/.ddev/commands/web/.install-12 b/.ddev/commands/web/.install-12
new file mode 100755
index 0000000..8cbfd20
--- /dev/null
+++ b/.ddev/commands/web/.install-12
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+. .ddev/commands/web/.utils.sh
+
+VERSION=12
+
+rm -rf /var/www/html/.test/$VERSION/*
+intro_typo3 $VERSION
+install_start $VERSION
+
+composer req typo3/cms-base-distribution:'^12.4' helhum/typo3-console:'^8.1' $PACKAGE_NAME:'*@dev' test/sitepackage:'*@dev' \
+ --no-progress -n -d /var/www/html/.test/$VERSION
+
+cd $BASE_PATH
+TYPO3_INSTALL_DB_DBNAME=$DATABASE
+$TYPO3_BIN install:setup -n --database-name $DATABASE
+setup_typo3
+
+sed -i "/'deprecations'/,/^[[:space:]]*'disabled' => true,/s/'disabled' => true,/'disabled' => false,/" /var/www/html/.test/$VERSION/config/system/settings.php
+
+sed -i -e "s/base: ht\//base: \//g" /var/www/html/.test/$VERSION/config/sites/main/config.yaml
+sed -i -e 's/base: \/en\//base: \//g' /var/www/html/.test/$VERSION/config/sites/main/config.yaml
+
+import_data
+update_typo3
diff --git a/.ddev/commands/web/.install-13 b/.ddev/commands/web/.install-13
new file mode 100755
index 0000000..8e9902b
--- /dev/null
+++ b/.ddev/commands/web/.install-13
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+. .ddev/commands/web/.utils.sh
+
+VERSION=13
+
+rm -rf /var/www/html/.test/$VERSION/*
+intro_typo3 $VERSION
+install_start $VERSION
+
+composer req typo3/cms-base-distribution:'^13.4' helhum/typo3-console:'^8.2.1' $PACKAGE_NAME:'*@dev' test/sitepackage:'*@dev' \
+ --no-progress -n -d /var/www/html/.test/$VERSION
+
+cd $BASE_PATH
+TYPO3_INSTALL_DB_DBNAME=$DATABASE
+mysql -h db -u root -p"root" -e "CREATE DATABASE $DATABASE;"
+$TYPO3_BIN setup -n --dbname=$DATABASE --password=$TYPO3_DB_PASSWORD --create-site="https://${VERSION}.xima-typo3-frontend-edit.ddev.site" --admin-user-password=$TYPO3_SETUP_ADMIN_PASSWORD
+setup_typo3
+
+sed -i "/'deprecations'/,/^[[:space:]]*'disabled' => true,/s/'disabled' => true,/'disabled' => false,/" /var/www/html/.test/$VERSION/config/system/settings.php
+
+import_data
+update_typo3
diff --git a/.ddev/commands/web/.utils.sh b/.ddev/commands/web/.utils.sh
new file mode 100644
index 0000000..1d901ef
--- /dev/null
+++ b/.ddev/commands/web/.utils.sh
@@ -0,0 +1,165 @@
+#!/bin/bash
+
+function get_lowest_supported_typo3_versions() {
+ local TYPO3_VERSIONS_ARRAY=()
+ IFS=' ' read -r -a TYPO3_VERSIONS_ARRAY <<< "$TYPO3_VERSIONS"
+ if [ ${#TYPO3_VERSIONS_ARRAY[@]} -eq 0 ]; then
+ message red "Error! No supported TYPO3 versions found in environment variables."
+ exit 1
+ fi
+ printf "%s\n" "${TYPO3_VERSIONS_ARRAY[@]}" | sort -V | head -n 1
+}
+
+function get_supported_typo3_versions() {
+ if [ -z "${TYPO3_VERSIONS+x}" ]; then
+ message red "TYPO3_VERSIONS is unset. Please set it before running this function."
+ return 1
+ else
+ local TYPO3_VERSIONS_ARRAY=()
+ IFS=' ' read -r -a TYPO3_VERSIONS_ARRAY <<< "$TYPO3_VERSIONS"
+ if [ ${#TYPO3_VERSIONS_ARRAY[@]} -eq 0 ]; then
+ message red "Error! No supported TYPO3 versions found in environment variables."
+ return 1
+ fi
+ printf "%s\n" "${TYPO3_VERSIONS_ARRAY[@]}"
+ fi
+}
+
+function check_typo3_version() {
+ local TYPO3=$1
+ local SUPPORTED_TYPO3_VERSIONS=()
+ local found=0
+
+ if [ -z "$TYPO3" ]; then
+ message red "No TYPO3 version provided. Please set one of the supported TYPO3 versions as argument: $(get_supported_typo3_versions_comma_separated)"
+ exit 1
+ fi
+
+ while IFS= read -r line; do
+ SUPPORTED_TYPO3_VERSIONS+=("$line")
+ done < <(get_supported_typo3_versions)
+
+ for version in "${SUPPORTED_TYPO3_VERSIONS[@]}"; do
+ if [[ "$version" == "$TYPO3" ]]; then
+ found=1
+ break
+ fi
+ done
+
+ if [[ $found -eq 0 ]]; then
+ message red "TYPO3 version '$TYPO3' is not supported."
+ exit 1
+ fi
+
+ return 0
+}
+
+function intro_typo3() {
+ local version=$1
+ message magenta "-------------------------------------------------"
+ message magenta "|\t\t\t\t\t\t|"
+ message magenta "| \t\t TYPO3 $version \t\t|"
+ message magenta "|\t\t\t\t\t\t|"
+ message magenta "-------------------------------------------------"
+}
+
+function install_start() {
+ local version=$1
+ rm -rf /var/www/html/.test/$version/*
+ setup_environment $version
+ create_symlinks_main_extension
+ create_symlinks_additional_extensions
+ setup_composer
+}
+
+function setup_environment() {
+ local version=$1
+ BASE_PATH="/var/www/html/.test/$version"
+ rm -rf "$BASE_PATH"
+ mkdir -p "$BASE_PATH/packages/$EXTENSION_KEY"
+ chmod 775 -R $BASE_PATH
+ export DATABASE="database_$version"
+ export BASE_PATH
+ export VERSION="$version"
+ export TYPO3_BIN="$BASE_PATH/vendor/bin/typo3"
+ mysql -uroot -proot -e "DROP DATABASE IF EXISTS $DATABASE"
+}
+
+function create_symlinks_main_extension() {
+ local exclusions=(".*" "Documentation" "Documentation-GENERATED-temp" "var")
+ for item in ./*; do
+ local base_name=$(basename "$item")
+ for exclusion in "${exclusions[@]}"; do
+ if [[ $base_name == "$exclusion" ]]; then
+ continue 2
+ fi
+ done
+ ln -sr "$item" "$BASE_PATH/packages/$EXTENSION_KEY/$base_name"
+ done
+}
+
+function create_symlinks_additional_extensions() {
+ for dir in .ddev/test/packages/*/; do
+ ln -sr "$dir" "$BASE_PATH/packages/$(basename "$dir")"
+ done
+}
+
+function setup_composer() {
+ composer init --name="xima/typo3-$VERSION" --description="TYPO3 $VERSION" --no-interaction --working-dir "$BASE_PATH"
+ composer config extra.typo3/cms.web-dir public --working-dir "$BASE_PATH"
+ composer config repositories.packages path 'packages/*' --working-dir "$BASE_PATH"
+ composer config --no-interaction allow-plugins.typo3/cms-composer-installers true --working-dir "$BASE_PATH"
+ composer config --no-interaction allow-plugins.typo3/class-alias-loader true --working-dir "$BASE_PATH"
+}
+
+function setup_typo3() {
+ cd $BASE_PATH
+ export TYPO3_INSTALL_DB_DBNAME=$DATABASE
+ $TYPO3_BIN configuration:set 'BE/debug' 1
+ $TYPO3_BIN configuration:set 'FE/debug' 1
+ $TYPO3_BIN configuration:set 'SYS/devIPmask' '*'
+ $TYPO3_BIN configuration:set 'SYS/displayErrors' 1
+ $TYPO3_BIN configuration:set 'SYS/trustedHostsPattern' '.*.*'
+ $TYPO3_BIN configuration:set 'MAIL/transport' 'smtp'
+ $TYPO3_BIN configuration:set 'MAIL/transport_smtp_server' 'localhost:1025'
+ $TYPO3_BIN configuration:set 'GFX/processor' 'ImageMagick'
+ $TYPO3_BIN configuration:set 'GFX/processor_path' '/usr/bin/'
+}
+
+function update_typo3() {
+ $TYPO3_BIN database:updateschema
+ $TYPO3_BIN cache:flush
+}
+
+function import_data() {
+ $TYPO3_BIN database:import < /var/www/html/.ddev/test/data/dump.sql
+}
+
+message() {
+ local color=$1
+ local message=$2
+
+ case $color in
+ red)
+ echo -e "\033[31m$message\033[0m"
+ ;;
+ green)
+ echo -e "\033[32m$message\033[0m"
+ ;;
+ yellow)
+ echo -e "\033[33m$message\033[0m"
+ ;;
+ blue)
+ echo -e "\033[34m$message\033[0m"
+ ;;
+ magenta)
+ echo -e "\033[35m$message\033[0m"
+ ;;
+ cyan)
+ echo -e "\033[36m$message\033[0m"
+ ;;
+ *)
+ echo -e "$message"
+ ;;
+ esac
+}
diff --git a/.ddev/commands/web/11 b/.ddev/commands/web/11
new file mode 100755
index 0000000..fd03ae3
--- /dev/null
+++ b/.ddev/commands/web/11
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+## Description: Exec command for TYPO3 instance 11.
+## Usage: 11
+## Example: "ddev 11 composer du -o"
+
+. .ddev/commands/web/.utils.sh
+
+command=$@
+version=11
+
+TYPO3_PATH=".test/${version}"
+if [ -f "$TYPO3_PATH" ]; then
+ message magenta "[TYPO3 v${version}] ${command}"
+ cd $TYPO3_PATH
+ $command
+else
+ message red "TYPO3 binary not found for version ${version}"
+fi
+
diff --git a/.ddev/commands/web/12 b/.ddev/commands/web/12
new file mode 100755
index 0000000..ad5b993
--- /dev/null
+++ b/.ddev/commands/web/12
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+## Description: Exec command for TYPO3 instance 12.
+## Usage: 12
+## Example: "ddev 12 composer du -o"
+
+. .ddev/commands/web/.utils.sh
+
+command=$@
+version=12
+
+TYPO3_PATH=".test/${version}"
+if [ -f "$TYPO3_PATH" ]; then
+ message magenta "[TYPO3 v${version}] ${command}"
+ cd $TYPO3_PATH
+ $command
+else
+ message red "TYPO3 binary not found for version ${version}"
+fi
+
diff --git a/.ddev/commands/web/13 b/.ddev/commands/web/13
new file mode 100755
index 0000000..f762f89
--- /dev/null
+++ b/.ddev/commands/web/13
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+## Description: Exec command for TYPO3 instance 13.
+## Usage: 13
+## Example: "ddev 13 composer du -o"
+
+. .ddev/commands/web/.utils.sh
+
+command=$@
+version=13
+
+TYPO3_PATH=".test/${version}"
+if [ -d "$TYPO3_PATH" ]; then
+ message magenta "[TYPO3 v${version}] ${command}"
+ cd $TYPO3_PATH
+ $command
+else
+ message red "TYPO3 binary not found for version ${version}"
+fi
+
diff --git a/.ddev/commands/web/install b/.ddev/commands/web/install
new file mode 100755
index 0000000..fec0c08
--- /dev/null
+++ b/.ddev/commands/web/install
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+## Description: Install TYPO3 instances.
+## Usage: install
+## Example: "ddev install" or "ddev install 12"
+
+TYPO3=${1}
+
+. .ddev/commands/web/.utils.sh
+
+if [ "$TYPO3" == "all" ]; then
+ mapfile -t versions < <(get_supported_typo3_versions)
+ for version in "${versions[@]}"; do
+ .ddev/commands/web/.install-$version
+ done
+else
+ if [ -z "$TYPO3" ]; then
+ TYPO3=$(get_lowest_supported_typo3_versions)
+ else
+ if ! check_typo3_version "$TYPO3"; then
+ exit 1
+ fi
+ fi
+ ".ddev/commands/web/.install-$TYPO3"
+fi
diff --git a/.ddev/commands/web/typo3 b/.ddev/commands/web/typo3
new file mode 100755
index 0000000..429ad2e
--- /dev/null
+++ b/.ddev/commands/web/typo3
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+## Description: Exec TYPO3 command for all available TYPO3 integration instances or a selected TYPO3 instance.
+## Usage: typo3
+## Example: "ddev typo3 cache:flush" or "ddev typo3 database:schemaupdate" or "ddev typo3 11 cache:flush"
+
+. .ddev/commands/web/.utils.sh
+
+command=$1
+mapfile -t versions < <(get_supported_typo3_versions)
+
+if [[ "$command" =~ ^[0-9]+$ ]] && [[ " ${versions[@]} " =~ " ${command} " ]]; then
+ version=$command
+ command=$2
+ TYPO3_PATH=".test/${version}/vendor/bin/typo3"
+ if [ -f "$TYPO3_PATH" ]; then
+ message magenta "[TYPO3 v${version}] ${command}"
+ /usr/bin/php $TYPO3_PATH $command
+ else
+ message red "TYPO3 binary not found for version ${version}"
+ fi
+else
+ for version in "${versions[@]}"; do
+ TYPO3_PATH=".test/${version}/vendor/bin/typo3"
+ if [ -f "$TYPO3_PATH" ]; then
+ message magenta "[TYPO3 v${version}] ${command}"
+ /usr/bin/php $TYPO3_PATH $command
+ else
+ message red "TYPO3 binary not found for version ${version}"
+ fi
+ done
+fi
+
+
+
diff --git a/.ddev/config.yaml b/.ddev/config.yaml
index ecc26d6..aa16b58 100644
--- a/.ddev/config.yaml
+++ b/.ddev/config.yaml
@@ -1,41 +1,26 @@
name: xima-typo3-content-planner
-type: typo3
-docroot: public
+type: php
+docroot: .test
php_version: "8.2"
webserver_type: apache-fpm
router_http_port: "80"
router_https_port: "443"
xdebug_enabled: false
-additional_hostnames: []
+additional_hostnames:
+ - 11.xima-typo3-content-planner
+ - 12.xima-typo3-content-planner
+ - 13.xima-typo3-content-planner
additional_fqdns: []
database:
type: mariadb
version: "10.4"
webimage_extra_packages: [libxml2-utils]
use_dns_when_possible: true
-composer_version: "2"
-web_environment:
- - TYPO3_CONTEXT=Development/Local
- - TYPO3_INSTALL_DB_DRIVER=mysqli
- - TYPO3_INSTALL_DB_USER=db
- - TYPO3_INSTALL_DB_PASSWORD=db
- - TYPO3_INSTALL_DB_HOST=db
- - TYPO3_INSTALL_DB_PORT=3306
- - TYPO3_INSTALL_DB_UNIX_SOCKET=
- - TYPO3_INSTALL_DB_USE_EXISTING=1
- - TYPO3_INSTALL_DB_DBNAME=db
- - TYPO3_INSTALL_ADMIN_USER=admin
- - TYPO3_INSTALL_ADMIN_PASSWORD=Password1!
- - TYPO3_INSTALL_SITE_NAME=Frontend Edit
- - TYPO3_INSTALL_SITE_SETUP_TYPE=no
- - TYPO3_INSTALL_SITE_BASE_URL=
- - TYPO3_INSTALL_WEB_SERVER_CONFIG=apache
-nodejs_version: "16"
corepack_enable: false
hooks:
post-start:
- exec: composer install --ignore-platform-reqs --no-scripts
- - exec: if [ ! -f /var/www/html/config/system/settings.php ]; then vendor/bin/typo3 install:setup --force && vendor/bin/typo3 configuration:set SYS/trustedHostsPattern ".*"; fi
+ - exec: mkdir -p /var/www/html/.test/ && cp /var/www/html/.ddev/templates/* /var/www/html/.test/
# Key features of DDEV's config.yaml:
diff --git a/.ddev/docker-compose.web.yaml b/.ddev/docker-compose.web.yaml
new file mode 100644
index 0000000..dfa022d
--- /dev/null
+++ b/.ddev/docker-compose.web.yaml
@@ -0,0 +1,31 @@
+services:
+ web:
+ environment:
+ - EXTENSION_KEY=xima_typo3_content_planner
+ - EXTENSION_NAME=xima-typo3-content-planner
+ - PACKAGE_NAME=xima/xima-typo3-content-planner
+ - TYPO3_VERSIONS=11 12 13
+
+ # TYPO3 v11 and v12 config
+ - TYPO3_INSTALL_DB_DRIVER=mysqli
+ - TYPO3_INSTALL_DB_USER=root
+ - TYPO3_INSTALL_DB_PASSWORD=root
+ - TYPO3_INSTALL_DB_HOST=db
+ - TYPO3_INSTALL_DB_UNIX_SOCKET=
+ - TYPO3_INSTALL_DB_USE_EXISTING=0
+ - TYPO3_INSTALL_ADMIN_USER=admin
+ - TYPO3_INSTALL_ADMIN_PASSWORD=Password1!
+ - TYPO3_INSTALL_SITE_NAME=EXT:xima-typo3-content-planner Dev Environment
+ - TYPO3_INSTALL_SITE_SETUP_TYPE=site
+ - TYPO3_INSTALL_WEB_SERVER_CONFIG=apache
+
+ # TYPO3 v13 config
+ - TYPO3_DB_DRIVER=mysqli
+ - TYPO3_DB_USERNAME=root
+ - TYPO3_DB_PASSWORD=root
+ - TYPO3_DB_HOST=db
+ - TYPO3_SETUP_ADMIN_EMAIL=admin@example.com
+ - TYPO3_SETUP_ADMIN_USERNAME=admin
+ - TYPO3_SETUP_ADMIN_PASSWORD=Password1!
+ - TYPO3_PROJECT_NAME=EXT:xima-typo3-content-planner Dev Environment
+ - TYPO3_SERVER_TYPE=apache
diff --git a/.ddev/templates/index.php b/.ddev/templates/index.php
new file mode 100644
index 0000000..d4d6347
--- /dev/null
+++ b/.ddev/templates/index.php
@@ -0,0 +1,90 @@
+
+
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
', '0', '0', '0', '0', '0', '0', '0', '2', '0', '0', '0', 'default', '0', '', '', NULL, NULL, '0', '', '', '0', '0', '', '1', '0', NULL, '0', '', '', '', '0', '0', NULL, '', '', NULL, '124', '0', '0', '0', '0', NULL, '0', '0', '0', '0', '0'),
+ ('2', '', '1', '1736359378', '1736359378', '0', '0', '0', '0', '', '512', '0', '0', '0', '0', '0', X'', '0', '0', '0', '0', 'bullets', 'Features', '', 'First point\r\nSecond point\r\nThird point', '0', '0', '0', '0', '0', '0', '0', '2', '0', '0', '0', 'default', '0', '', '', NULL, NULL, '0', '', '', '0', '0', '', '1', '0', NULL, '0', '', '', '', '0', '0', NULL, '', '', NULL, '124', '0', '0', '0', '0', NULL, '0', '0', '0', '0', '0');
+
+# sys_category
+
+INSERT INTO `sys_category` (`uid`, `pid`, `tstamp`, `crdate`, `deleted`, `hidden`, `starttime`, `endtime`, `sorting`, `description`, `sys_language_uid`, `l10n_parent`, `l10n_state`, `l10n_diffsource`, `t3ver_oid`, `t3ver_wsid`, `t3ver_state`, `t3ver_stage`, `title`, `items`, `parent`, `tx_ximatypo3contentplanner_status`, `tx_ximatypo3contentplanner_assignee`, `tx_ximatypo3contentplanner_comments`)
+VALUES
+ ('1', '6', '1736359306', '1736359306', '0', '0', '0', '0', '256', '', '0', '0', '0', X'', '0', '0', '0', '0', 'Important', '0', '0', '0', '0', '0'),
+ ('2', '6', '1736359322', '1736359322', '0', '0', '0', '0', '512', '', '0', '0', '0', X'', '0', '0', '0', '0', 'Seasonal', '0', '0', '0', '0', '0'),
+ ('3', '6', '1736359338', '1736359338', '0', '0', '0', '0', '768', '', '0', '0', '0', X'', '0', '0', '0', '0', 'Sales', '0', '0', '0', '0', '0');
diff --git a/.ddev/test/packages/sitepackage/Classes/EventListener/PrepareStatusSelectionListener.php b/.ddev/test/packages/sitepackage/Classes/EventListener/PrepareStatusSelectionListener.php
new file mode 100644
index 0000000..af28f8e
--- /dev/null
+++ b/.ddev/test/packages/sitepackage/Classes/EventListener/PrepareStatusSelectionListener.php
@@ -0,0 +1,31 @@
+getSelection();
+
+ if ($event->getCurrentStatus() && $event->getCurrentStatus()->getTitle() === 'Needs review') {
+ $targetStatus = $this->statusRepository->findOneByTitle('Pending');
+
+ if ($targetStatus) {
+ unset($selection[$targetStatus->getUid()]);
+ }
+ }
+
+ $event->setSelection($selection);
+ }
+}
diff --git a/.ddev/test/packages/sitepackage/Configuration/Services.yaml b/.ddev/test/packages/sitepackage/Configuration/Services.yaml
new file mode 100644
index 0000000..cb1fea6
--- /dev/null
+++ b/.ddev/test/packages/sitepackage/Configuration/Services.yaml
@@ -0,0 +1,14 @@
+services:
+ _defaults:
+ autowire: true
+ autoconfigure: true
+ public: false
+
+ Test\Sitepackage\:
+ resource: '../Classes/*'
+ exclude: '../Classes/Domain/Model/*'
+
+ Test\Sitepackage\EventListener\PrepareStatusSelectionListener:
+ tags:
+ - name: event.listener
+ identifier: 'xima-typo3-content-planner/prepare-status-selection'
\ No newline at end of file
diff --git a/.ddev/test/packages/sitepackage/Configuration/TCA/Overrides/sys_category.php b/.ddev/test/packages/sitepackage/Configuration/TCA/Overrides/sys_category.php
new file mode 100644
index 0000000..bf01200
--- /dev/null
+++ b/.ddev/test/packages/sitepackage/Configuration/TCA/Overrides/sys_category.php
@@ -0,0 +1,7 @@
+table === 'pages' || in_array($this->table, $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY]['registerAdditionalRecordTables']);
+ return ExtensionUtility::isRegisteredRecordTable($this->table) && $this->identifier;
}
public function getPriority(): int
@@ -40,6 +52,8 @@ protected function getAdditionalAttributes(string|int $itemName): array
return [
'data-callback-module' => '@xima/ximatypo3contentplanner/context-menu-actions',
'data-status' => $itemName,
+ 'data-uri' => UrlHelper::getContentStatusPropertiesEditUrl($this->table, (int)$this->identifier, false),
+ 'data-new-comment-uri' => UrlHelper::getNewCommentUrl($this->table, (int)$this->identifier),
];
}
@@ -48,23 +62,71 @@ public function addItems(array $items): array
if (!VisibilityUtility::checkContentStatusVisibility()) {
return $items;
}
+ /** @var PageRenderer $pageRenderer */
+ $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
+ $pageRenderer->loadJavaScriptModule('@xima/ximatypo3contentplanner/new-comment-modal.js');
+ $pageRenderer->loadJavaScriptModule('@xima/ximatypo3contentplanner/comments-modal.js');
+ $pageRenderer->addInlineLanguageLabelFile('EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf');
$this->initDisabledItems();
+ $itemsToAdd = [];
foreach ($this->statusRepository->findAll() as $statusItem) {
- $this->itemsConfiguration['wrap']['childItems'][$statusItem->getUid()] = [
+ $itemsToAdd[$statusItem->getUid()] = [
'label' => $statusItem->getTitle(),
'iconIdentifier' => $statusItem->getColoredIcon(),
'callbackAction' => 'change',
];
}
- $this->itemsConfiguration['wrap']['childItems']['divider'] = ['type' => 'divider'];
+ $itemsToAdd['divider'] = ['type' => 'divider'];
- $this->itemsConfiguration['wrap']['childItems']['reset'] = [
+ $itemsToAdd['reset'] = [
'label' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_be.xlf:reset',
'iconIdentifier' => 'actions-close',
'callbackAction' => 'reset',
];
+ $record = null;
+ if (ExtensionUtility::isFeatureEnabled(Configuration::FEATURE_EXTEND_CONTEXT_MENU)) {
+ $record = $this->recordRepository->findByUid($this->table, (int)$this->identifier);
+ if ($record) {
+ $itemsToAdd['divider2'] = ['type' => 'divider'];
+
+ // remove current status from list
+ if (in_array($record['tx_ximatypo3contentplanner_status'], array_keys($itemsToAdd), true)) {
+ unset($itemsToAdd[$record['tx_ximatypo3contentplanner_status']]);
+ }
+
+ // remove reset if status is already null
+ if ($record['tx_ximatypo3contentplanner_status'] === null) {
+ unset($itemsToAdd['reset']);
+ }
+
+ // assignee
+ if ($record['tx_ximatypo3contentplanner_assignee']) {
+ $username = $this->backendUserRepository->getUsernameByUid($record['tx_ximatypo3contentplanner_assignee']);
+ $itemsToAdd['assignee'] = [
+ 'label' => $username,
+ 'iconIdentifier' => 'actions-user',
+ 'callbackAction' => 'load',
+ ];
+ }
+
+ // comments
+ if ($record['tx_ximatypo3contentplanner_status'] !== null) {
+ $itemsToAdd['comments'] = [
+ 'label' => $this->getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_be.xlf:comments') . ($record['tx_ximatypo3contentplanner_comments'] ? ' (' . $record['tx_ximatypo3contentplanner_comments'] . ')' : ''),
+ 'iconIdentifier' => 'actions-message',
+ 'callbackAction' => 'comments',
+ ];
+ }
+ }
+ }
+
+ $this->statusSelectionManager->prepareStatusSelection($this, $this->table, (int)$this->identifier, $itemsToAdd, $record ? $record['tx_ximatypo3contentplanner_status'] : null);
+ foreach ($itemsToAdd as $itemKey => $itemToAdd) {
+ $this->itemsConfiguration['wrap']['childItems'][$itemKey] = $itemToAdd;
+ }
+
$localItems = $this->prepareItems($this->itemsConfiguration);
if (isset($items['info'])) {
@@ -86,4 +148,9 @@ protected function canRender(string|int $itemName, string $type): bool
}
return true;
}
+
+ protected function getLanguageService(): LanguageService
+ {
+ return $GLOBALS['LANG'];
+ }
}
diff --git a/Classes/Backend/ToolbarItems/UpdateItem.php b/Classes/Backend/ToolbarItems/UpdateItem.php
deleted file mode 100644
index d466aa0..0000000
--- a/Classes/Backend/ToolbarItems/UpdateItem.php
+++ /dev/null
@@ -1,116 +0,0 @@
-setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:' . Configuration::EXT_KEY
- . '/Resources/Private/Templates/Backend/ToolbarItems/UpdateItem.html'));
- return $view->assignMultiple([
- 'count' => count($this->getRelevantUpdates()),
- ])->render();
- }
-
- /**
- * TRUE if this toolbar item has a collapsible drop down
- *
- * @return bool
- */
- public function hasDropDown(): bool
- {
- return true;
- }
-
- /**
- * Render "drop down" part of this toolbar
- *
- * @return string Drop down HTML
- */
- public function getDropDown(): string
- {
- $view = GeneralUtility::makeInstance(StandaloneView::class);
- $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:' . Configuration::EXT_KEY
- . '/Resources/Private/Templates/Backend/ToolbarItems/UpdateItemDropDown.html'));
- $view->setPartialRootPaths([
- GeneralUtility::getFileAbsFileName('EXT:' . Configuration::EXT_KEY . '/Resources/Private/Partials/'),
- ]);
- return $view->assignMultiple([
- 'data' => $this->getRelevantUpdates(),
- ])->render();
- }
-
- /**
- * Returns an array with additional attributes added to containing handle($request);
+ private function addStatusHintToContentElement(int $pid): string
+ {
+ $styling = [];
+ $records = $this->recordRepository->findByPid('tt_content', (int)$pid);
+
+ foreach ($records as $record) {
+ $status = $this->statusRepository->findByUid($record['tx_ximatypo3contentplanner_status']);
+ if (!$status) {
+ continue;
+ }
+ $statusColor = Configuration\Colors::get($status->getColor());
+ $styling[] = '.t3-page-ce[data-uid="' . $record['uid'] . '"]:before { content: "";display:block;box-shadow:var(--pagemodule-element-box-shadow);padding:.5em;border-left: 5px solid ' . $statusColor . ';border-radius: 5px 5px 0 0;background-color:' . $statusColor . '; }';
+ }
+
+ return '';
}
}
diff --git a/Classes/Utility/ContentUtility.php b/Classes/Utility/ContentUtility.php
index 121fc45..a5f4531 100644
--- a/Classes/Utility/ContentUtility.php
+++ b/Classes/Utility/ContentUtility.php
@@ -5,11 +5,11 @@
namespace Xima\XimaTypo3ContentPlanner\Utility;
use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
-use Xima\XimaTypo3ContentPlanner\Domain\Model\Dto\CommentItem;
use Xima\XimaTypo3ContentPlanner\Domain\Model\Status;
+use Xima\XimaTypo3ContentPlanner\Domain\Repository\BackendUserRepository;
+use Xima\XimaTypo3ContentPlanner\Domain\Repository\CommentRepository;
use Xima\XimaTypo3ContentPlanner\Domain\Repository\StatusRepository;
class ContentUtility
@@ -23,208 +23,63 @@ public static function getStatus(?int $statusId): ?Status
return $statusRepository->findByUid($statusId);
}
- public static function getPage(int $pageId): array|bool
+ public static function getStatusByTitle(?string $title): ?Status
{
- $pageRepository = GeneralUtility::makeInstance(PageRepository::class);
- return $pageRepository->getPage($pageId);
- }
-
- public static function getAssignedPages(): array|bool
- {
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
-
- return $queryBuilder
- ->select('*')
- ->from('pages')
- ->where(
- $queryBuilder->expr()->eq('tx_ximatypo3contentplanner_assignee', $queryBuilder->createNamedParameter($GLOBALS['BE_USER']->user['uid'], \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
- )
- ->executeQuery()->fetchAllAssociative();
- }
-
- public static function getRecordsByFilter(?string $search = null, ?int $status = null, ?int $assignee = null, ?string $type = null, int $maxResults = 20): array|bool
- {
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
-
- $additionalWhere = ' AND deleted = 0';
- $additionalParams = [
- 'limit' => $maxResults,
- ];
-
- $defaultSelects = [
- 'uid',
- 'pid',
- 'tstamp',
- 'tx_ximatypo3contentplanner_status',
- 'tx_ximatypo3contentplanner_assignee',
- 'tx_ximatypo3contentplanner_comments',
- ];
-
- if ($search) {
- $additionalWhere .= ' AND (title LIKE :search OR uid = :uid)';
- $additionalParams['search'] = '%' . $search . '%';
- $additionalParams['uid'] = $search;
- }
- if ($status) {
- $additionalWhere .= ' AND tx_ximatypo3contentplanner_status = :status';
- $additionalParams['status'] = $status;
- }
- if ($assignee) {
- $additionalWhere .= ' AND tx_ximatypo3contentplanner_assignee = :assignee';
- $additionalParams['assignee'] = $assignee;
- }
- $sqlArray = [];
- foreach (ExtensionUtility::getRecordTables() as $table) {
- if ($type && $type !== $table) {
- continue;
- }
-
- $titleField = $GLOBALS['TCA'][$table]['ctrl']['label'];
- if ($table === 'pages') {
- $selects = array_merge($defaultSelects, [$titleField . ' as title, "' . $table . '" as tablename', 'perms_userid', 'perms_groupid', 'perms_user', 'perms_group', 'perms_everybody']);
- } else {
- $selects = array_merge($defaultSelects, [$titleField . ' as title, "' . $table . '" as tablename', '0 as perms_userid', '0 as perms_groupid', '0 as perms_user', '0 as perms_group', '0 as perms_everybody']);
- }
-
- $sqlArray[] = '(SELECT ' . implode(',', $selects) . ' FROM ' . $table . ' WHERE tx_ximatypo3contentplanner_status IS NOT NULL AND tx_ximatypo3contentplanner_status != 0' . $additionalWhere . ')';
- }
- $sql = implode(' UNION ', $sqlArray) . ' ORDER BY tstamp DESC LIMIT :limit';
-
- $statement = $queryBuilder->getConnection()->executeQuery($sql, $additionalParams);
- $results = $statement->fetchAllAssociative();
-
- foreach ($results as $key => $record) {
- if (!PermissionUtility::checkAccessForRecord($record['tablename'], $record)) {
- unset($results[$key]);
- }
+ if (!$title) {
+ return null;
}
- return $results;
+ $statusRepository = GeneralUtility::makeInstance(StatusRepository::class);
+ return $statusRepository->findByTitle($title);
}
- public static function getComments(int $id, string $table): array
+ public static function getPage(int $pageId): array|bool
{
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_ximatypo3contentplanner_comment');
-
- $comments = $queryBuilder
- ->select('*')
- ->from('tx_ximatypo3contentplanner_comment')
- ->where(
- $queryBuilder->expr()->eq('foreign_uid', $queryBuilder->createNamedParameter($id, \TYPO3\CMS\Core\Database\Connection::PARAM_INT)),
- $queryBuilder->expr()->eq('foreign_table', $queryBuilder->createNamedParameter($table, \TYPO3\CMS\Core\Database\Connection::PARAM_STR)),
- $queryBuilder->expr()->eq('deleted', 0)
- )
- ->orderBy('tstamp', 'DESC')
- ->executeQuery()->fetchAllAssociative();
-
- $items = [];
- foreach ($comments as $result) {
- try {
- $items[] = CommentItem::create($result);
- } catch (\Exception $e) {
- }
- }
-
- return $items;
+ $pageRepository = GeneralUtility::makeInstance(PageRepository::class);
+ return $pageRepository->getPage($pageId);
}
+ /**
+ * @Deprecated
+ */
public static function getComment(int $id): array|bool
{
if (!$id) {
return false;
}
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_ximatypo3contentplanner_comment');
-
- return $queryBuilder
- ->select('*')
- ->from('tx_ximatypo3contentplanner_comment')
- ->where(
- $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($id, \TYPO3\CMS\Core\Database\Connection::PARAM_INT)),
- $queryBuilder->expr()->eq('deleted', 0)
- )
- ->executeQuery()->fetchAssociative();
+ $commentRepository = GeneralUtility::makeInstance(CommentRepository::class);
+ return $commentRepository->findByUid($id);
}
+ /**
+ * @Deprecated
+ */
public static function getBackendUserById(?int $userId): array|bool
{
if (!$userId) {
return false;
}
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users');
-
- return $queryBuilder
- ->select('*')
- ->from('be_users')
- ->where(
- $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($userId, \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
- )
- ->executeQuery()->fetchAssociative();
+ $backendUserRepository = GeneralUtility::makeInstance(BackendUserRepository::class);
+ return $backendUserRepository->findByUid($userId);
}
+ /**
+ * @Deprecated
+ */
public static function getBackendUsernameById(?int $userId): string
{
if (!$userId) {
return '';
}
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users');
-
- $userRecord = $queryBuilder
- ->select('username', 'realName')
- ->from('be_users')
- ->where(
- $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($userId, \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
- )
- ->executeQuery()->fetchAssociative();
-
- if ($userRecord) {
- $user = $userRecord['username'];
- if ($userRecord['realName']) {
- $user = $userRecord['realName'] . ' (' . $user . ')';
- }
- return htmlspecialchars($user, ENT_QUOTES, 'UTF-8');
- }
-
- return '';
- }
-
- public static function getBackendUsers(): array
- {
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users');
-
- $query = $queryBuilder
- ->select('uid', 'username')
- ->from('be_users')
- ->orderBy('username', 'ASC');
-
- return $query->executeQuery()
- ->fetchAllAssociative();
- }
-
- public static function getExtensionRecords(string $table, ?int $pid = null): array
- {
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
-
- $query = $queryBuilder
- ->select('uid', $GLOBALS['TCA'][$table]['ctrl']['label'] . ' as "title"', 'tx_ximatypo3contentplanner_status', 'tx_ximatypo3contentplanner_assignee', 'tx_ximatypo3contentplanner_comments')
- ->from($table)
- ->andWhere(
- $queryBuilder->expr()->isNotNull('tx_ximatypo3contentplanner_status'),
- $queryBuilder->expr()->eq('deleted', 0)
- )
- ->orderBy('tstamp', 'DESC');
-
- if ($pid) {
- $query->andWhere(
- $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pid, \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
- );
- }
-
- return $query->executeQuery()
- ->fetchAllAssociative();
+ $backendUserRepository = GeneralUtility::makeInstance(BackendUserRepository::class);
+ return $backendUserRepository->getUsernameByUid($userId);
}
+ /**
+ * @Deprecated
+ */
public static function getExtensionRecord(?string $table, ?int $uid): array|null
{
if (!$table && !$uid) {
@@ -232,17 +87,4 @@ public static function getExtensionRecord(?string $table, ?int $uid): array|null
}
return BackendUtility::getRecord($table, $uid);
}
-
- public static function clearStatusOfExtensionRecords(string $table, int $status): void
- {
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
-
- $queryBuilder
- ->update($table)
- ->set('tx_ximatypo3contentplanner_status', null)
- ->where(
- $queryBuilder->expr()->eq('tx_ximatypo3contentplanner_status', $status)
- )
- ->executeQuery();
- }
}
diff --git a/Classes/Utility/DiffUtility.php b/Classes/Utility/DiffUtility.php
index d6420a2..8e15b98 100644
--- a/Classes/Utility/DiffUtility.php
+++ b/Classes/Utility/DiffUtility.php
@@ -13,64 +13,60 @@ class DiffUtility
public static function timeAgo(int $timestamp): string
{
$now = new DateTime();
- new DateTime();
- $storedTime = new DateTime();
- $storedTime->setTimestamp($timestamp);
+ $storedTime = (new DateTime())->setTimestamp($timestamp);
$interval = $now->diff($storedTime);
- if ($interval->y > 0) {
- return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.' . ($interval->y == 1 ? 'year' : 'years')), $interval->y);
- }
- if ($interval->m > 0) {
- return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.' . ($interval->m == 1 ? 'month' : 'months')), $interval->m);
- }
- if ($interval->d > 0) {
- return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.' . ($interval->d == 1 ? 'day' : 'days')), $interval->d);
- }
- if ($interval->h > 0) {
- return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.' . ($interval->h == 1 ? 'hour' : 'hours')), $interval->h);
- }
- if ($interval->i > 0) {
- return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.' . ($interval->i == 1 ? 'minute' : 'minutes')), $interval->i);
+ $timeUnits = [
+ 'y' => 'year',
+ 'm' => 'month',
+ 'd' => 'day',
+ 'h' => 'hour',
+ 'i' => 'minute',
+ 's' => 'second',
+ ];
+
+ foreach ($timeUnits as $unit => $label) {
+ if ($interval->$unit > 0) {
+ $key = $interval->$unit == 1 ? $label : $label . 's';
+ return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.' . $key), $interval->$unit);
+ }
}
- return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.' . ($interval->s == 1 ? 'second' : 'seconds')), $interval->s);
+
+ return sprintf(self::getLanguageService()->sL('LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang.xlf:timeAgo.seconds'), $interval->s);
}
public static function checkRecordDiff(array $data, int $actiontype): string|bool
{
- $old = $data['oldRecord'];
- $new = $data['newRecord'];
$diff = [];
- foreach ($old as $key => $value) {
- if ($key !== 'l10n_diffsource') {
- $oldValue = $value;
- $newValue = $new[$key];
- if ($oldValue !== $newValue) {
- $diffValue = self::makeRecordDiffReadable($key, $actiontype, $oldValue, $newValue);
- if ($diffValue) {
- $diff[] = $diffValue;
- }
+ foreach ($data['oldRecord'] as $key => $oldValue) {
+ if ($key === 'l10n_diffsource') {
+ continue;
+ }
+
+ $newValue = $data['newRecord'][$key];
+ if ($oldValue !== $newValue) {
+ $diffValue = self::makeRecordDiffReadable($key, $actiontype, $oldValue, $newValue);
+ if ($diffValue) {
+ $diff[] = $diffValue;
}
}
}
- return empty($diff) ? false : implode('
', $diff);
+
+ return $diff ? implode('
', $diff) : false;
}
private static function makeRecordDiffReadable(string $field, int $actiontype, string|int|null $old, string|int|null $new): string|bool
{
- // set value
- if (($old === null || $old === '' || $old === 0) && ($new === null || $new === '' || $new === 0)) {
+ if (empty($old) && empty($new)) {
return false;
}
- if ($old === null || $old === '') {
+ if (empty($old)) {
return sprintf(self::getLanguageService()->sL('LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang_be.xlf:history.record.' . $actiontype . '.set.' . $field), self::preparePageAttributeValue($field, $new));
}
- // reset value
- if ($new === null || $new === '') {
+ if (empty($new)) {
return sprintf(self::getLanguageService()->sL('LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang_be.xlf:history.record.' . $actiontype . '.unset.' . $field), self::preparePageAttributeValue($field, $old));
}
- // change value
if ($old !== $new) {
return sprintf(self::getLanguageService()->sL('LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang_be.xlf:history.record.' . $actiontype . '.change.' . $field), self::preparePageAttributeValue($field, $old), self::preparePageAttributeValue($field, $new));
}
diff --git a/Classes/Utility/ExtensionUtility.php b/Classes/Utility/ExtensionUtility.php
index 8cdb086..cd46ec0 100644
--- a/Classes/Utility/ExtensionUtility.php
+++ b/Classes/Utility/ExtensionUtility.php
@@ -4,7 +4,11 @@
namespace Xima\XimaTypo3ContentPlanner\Utility;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\PathUtility;
use Xima\XimaTypo3ContentPlanner\Configuration;
class ExtensionUtility
@@ -36,7 +40,7 @@ public static function addContentPlannerTabToTCA(string $table): void
'label' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_db.xlf:pages.tx_ximatypo3contentplanner_comments',
'config' => [
'foreign_field' => 'foreign_uid',
- 'foreign_sortby' => 'sorting',
+ 'foreign_sortby' => 'crdate',
'foreign_table' => 'tx_ximatypo3contentplanner_comment',
'foreign_table_field' => 'foreign_table',
'type' => 'inline',
@@ -92,4 +96,33 @@ public static function isRegisteredRecordTable(string $table): bool
{
return in_array($table, self::getRecordTables());
}
+
+ public static function isFeatureEnabled(string $feature): bool
+ {
+ $configuration = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get(Configuration::EXT_KEY);
+ return array_key_exists($feature, $configuration) && $configuration[$feature];
+ }
+
+ public static function getTitleField(string $table): string
+ {
+ return $GLOBALS['TCA'][$table]['ctrl']['label'];
+ }
+
+ public static function getTitle(string $key, array|bool|null $record): string
+ {
+ return $record ? (array_key_exists($key, $record) ? $record[$key] : BackendUtility::getNoRecordTitle()) : BackendUtility::getNoRecordTitle();
+ }
+
+ public static function getCssTag(string $cssFileLocation, array $attributes): string
+ {
+ return sprintf(
+ '
',
+ GeneralUtility::implodeAttributes([
+ ...$attributes,
+ 'rel' => 'stylesheet',
+ 'media' => 'all',
+ 'href' => PathUtility::getPublicResourceWebPath($cssFileLocation),
+ ], true)
+ );
+ }
}
diff --git a/Classes/Utility/IconHelper.php b/Classes/Utility/IconHelper.php
new file mode 100644
index 0000000..aeaf999
--- /dev/null
+++ b/Classes/Utility/IconHelper.php
@@ -0,0 +1,59 @@
+getIcon($identifier, $size);
+ return $icon->render();
+ }
+
+ public static function getIconByStatusUid(int $uid, bool $render = false): string
+ {
+ $status = ContentUtility::getStatus($uid);
+ return self::getIconByStatus($status, $render);
+ }
+
+ public static function getIconByStatus(?Status $status, bool $render = false, string $size = Icon::SIZE_SMALL): string
+ {
+ $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+ $icon = $iconFactory->getIcon($status ? $status->getColoredIcon() : 'flag-gray', $size);
+ return $render ? $icon->render() : $icon->getIdentifier();
+ }
+
+ public static function getIconByRecord(string $table, array|bool $record, bool $render = false, string $size = Icon::SIZE_SMALL): string
+ {
+ if (!$record) {
+ return '';
+ }
+ $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+ $icon = $iconFactory->getIconForRecord($table, $record, $size);
+ return $render ? $icon->render() : $icon->getIdentifier();
+ }
+
+ public static function getAvatarByUserId(int $userId, int $size = 15): string
+ {
+ $user = ContentUtility::getBackendUserById($userId);
+ return self::getAvatarByUser($user, $size);
+ }
+
+ public static function getAvatarByUser(array|bool $user, int $size = 15): string
+ {
+ if (!$user) {
+ return '';
+ }
+ $avatar = GeneralUtility::makeInstance(Avatar::class);
+ return $avatar->render($user, $size, true);
+ }
+}
diff --git a/Classes/Utility/PermissionUtility.php b/Classes/Utility/PermissionUtility.php
index 37df693..1e862f7 100644
--- a/Classes/Utility/PermissionUtility.php
+++ b/Classes/Utility/PermissionUtility.php
@@ -10,7 +10,7 @@
class PermissionUtility
{
- public static function checkAccessForRecord(string $tablename, $record): bool
+ public static function checkAccessForRecord(string $table, $record): bool
{
$backendUser = $GLOBALS['BE_USER'];
if ($backendUser->user === null) {
@@ -24,14 +24,14 @@ public static function checkAccessForRecord(string $tablename, $record): bool
}
/* @var $backendUser \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */
- if ($tablename === 'pages' && !BackendUtility::readPageAccess(
+ if ($table === 'pages' && !BackendUtility::readPageAccess(
$record['uid'],
$GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW)
)) {
return false;
}
- if (!$backendUser->check('tables_select', $tablename) || !BackendUtility::readPageAccess(
+ if (!$backendUser->check('tables_select', $table) || !BackendUtility::readPageAccess(
$record['pid'],
$GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW)
)) {
diff --git a/Classes/Utility/StatusRegistry.php b/Classes/Utility/StatusRegistry.php
index 4b46189..ae96c84 100644
--- a/Classes/Utility/StatusRegistry.php
+++ b/Classes/Utility/StatusRegistry.php
@@ -25,7 +25,7 @@ public function getStatus(array &$config): void
public function getStatusIcons(array &$config): void
{
- foreach (Configuration::STATUS_ICONS as $icon) {
+ foreach (Configuration\Icons::STATUS_ICONS as $icon) {
$config['items'][] = [
$icon,
$icon,
@@ -36,7 +36,7 @@ public function getStatusIcons(array &$config): void
public function getStatusColors(array &$config): void
{
- foreach (Configuration::STATUS_COLORS as $color) {
+ foreach (Configuration\Colors::STATUS_COLORS as $color) {
$config['items'][] = [
$color,
$color,
diff --git a/Classes/Utility/UrlHelper.php b/Classes/Utility/UrlHelper.php
new file mode 100644
index 0000000..87e6927
--- /dev/null
+++ b/Classes/Utility/UrlHelper.php
@@ -0,0 +1,68 @@
+ [$table => [$uid => 'edit']],
+ 'returnUrl' => $generateReturnUrl ? $request->getAttribute('normalizedParams')->getRequestUri() : null,
+ 'columnsOnly' => 'tx_ximatypo3contentplanner_status,tx_ximatypo3contentplanner_assignee,tx_ximatypo3contentplanner_comments',
+ ];
+ return (string)$uriBuilder->buildUriFromRoute('record_edit', $params);
+ }
+
+ public static function getNewCommentUrl(string $table, int $uid): string
+ {
+ $request = $GLOBALS['TYPO3_REQUEST'];
+ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+ $pid = $uid;
+ if ($table !== 'pages') {
+ $record = ContentUtility::getExtensionRecord($table, $uid);
+ $pid = (int)$record['pid'];
+ }
+
+ $params = [
+ 'edit' => ['tx_ximatypo3contentplanner_comment' => [$pid => 'new']],
+ 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
+ 'defVals' => ['tx_ximatypo3contentplanner_comment' => ['foreign_table' => $table, 'foreign_uid' => $pid]],
+ ];
+ return (string)$uriBuilder->buildUriFromRoute('record_edit', $params);
+ }
+
+ public static function getRecordLink(string $table, int $uid): string
+ {
+ return match ($table) {
+ 'pages' => (string)GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute('web_layout', ['id' => $uid]),
+ default => (string)GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute('record_edit', ['edit' => [$table => [$uid => 'edit']]]),
+ };
+ }
+
+ public static function isRelevantWebLayoutRequest(ServerRequestInterface $request): bool
+ {
+ return $request->getAttribute('applicationType') === SystemEnvironmentBuilder::REQUESTTYPE_BE
+ && $request->getAttribute('module') !== null
+ && $request->getAttribute('module')->getIdentifier() === 'web_layout'
+ && in_array('tt_content', $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY]['registerAdditionalRecordTables']);
+ }
+
+ public static function isRelevantRecordEditRequest(ServerRequestInterface $request): bool
+ {
+ return $request->getAttribute('applicationType') === SystemEnvironmentBuilder::REQUESTTYPE_BE
+ && ExtensionUtility::isFeatureEnabled(Configuration::FEATURE_RECORD_EDIT_HEADER_INFO)
+ && array_key_exists('edit', $request->getQueryParams())
+ && (array_key_first($request->getQueryParams()['edit']) === 'pages' || in_array(array_key_first($request->getQueryParams()['edit']), $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][Configuration::EXT_KEY]['registerAdditionalRecordTables']));
+ }
+}
diff --git a/Classes/ViewHelpers/RandomNumberViewHelper.php b/Classes/ViewHelpers/RandomNumberViewHelper.php
index b1c1fed..aef6de2 100644
--- a/Classes/ViewHelpers/RandomNumberViewHelper.php
+++ b/Classes/ViewHelpers/RandomNumberViewHelper.php
@@ -31,6 +31,9 @@ public function initializeArguments(): void
);
}
+ /**
+ * @throws \Random\RandomException
+ */
public function render()
{
return random_int($this->arguments['min'], $this->arguments['max']);
diff --git a/Classes/ViewHelpers/StatusColorViewHelper.php b/Classes/ViewHelpers/StatusColorViewHelper.php
new file mode 100644
index 0000000..22e4fff
--- /dev/null
+++ b/Classes/ViewHelpers/StatusColorViewHelper.php
@@ -0,0 +1,51 @@
+registerArgument(
+ 'statusId',
+ 'integer',
+ '',
+ true
+ );
+ $this->registerArgument(
+ 'colorName',
+ 'boolean',
+ '',
+ false,
+ true
+ );
+ }
+
+ public function render()
+ {
+ $status = $this->statusRepository->findByUid($this->arguments['statusId']);
+
+ if (!$status) {
+ return '';
+ }
+ if ($this->arguments['colorName']) {
+ return $status->getColor();
+ }
+ return Configuration\Colors::get($status->getColor());
+ }
+}
diff --git a/Classes/Widgets/ContentNotesWidget.php b/Classes/Widgets/ContentNotesWidget.php
deleted file mode 100644
index 28bd8ed..0000000
--- a/Classes/Widgets/ContentNotesWidget.php
+++ /dev/null
@@ -1,22 +0,0 @@
-render(
- 'EXT:xima_typo3_content_planner/Resources/Private/Templates/Backend/Widgets/ContentNotes.html',
- [
- 'configuration' => $this->configuration,
- 'records' => $this->dataProvider->getItems(),
- 'options' => $this->options,
- 'buttons' => $GLOBALS['BE_USER']->check('tables_modify', 'tx_ximatypo3contentplanner_note') ? $this->buttons : null,
- 'icon' => 'content-thumbtack',
- ]
- );
- }
-}
diff --git a/Classes/Widgets/Provider/ContentNotesDataProvider.php b/Classes/Widgets/Provider/ContentNotesDataProvider.php
deleted file mode 100644
index d7fbcb1..0000000
--- a/Classes/Widgets/Provider/ContentNotesDataProvider.php
+++ /dev/null
@@ -1,34 +0,0 @@
-getQueryBuilderForTable('tx_ximatypo3contentplanner_note');
-
- $results = $queryBuilder
- ->select(
- 'uid',
- 'tstamp',
- 'title',
- 'content'
- )
- ->from('tx_ximatypo3contentplanner_note')
-
- ->orderBy('tstamp', 'DESC')
- ->executeQuery()
- ->fetchAllAssociative();
- return $results ?: [];
- }
-}
diff --git a/Classes/Widgets/Provider/ContentStatusDataProvider.php b/Classes/Widgets/Provider/ContentStatusDataProvider.php
index 20b9911..2a62a5a 100644
--- a/Classes/Widgets/Provider/ContentStatusDataProvider.php
+++ b/Classes/Widgets/Provider/ContentStatusDataProvider.php
@@ -6,12 +6,12 @@
use TYPO3\CMS\Dashboard\Widgets\ListDataProviderInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
+use Xima\XimaTypo3ContentPlanner\Domain\Repository\BackendUserRepository;
use Xima\XimaTypo3ContentPlanner\Domain\Repository\StatusRepository;
-use Xima\XimaTypo3ContentPlanner\Utility\ContentUtility;
class ContentStatusDataProvider implements ListDataProviderInterface
{
- public function __construct(protected readonly StatusRepository $statusRepository)
+ public function __construct(private readonly StatusRepository $statusRepository, private readonly BackendUserRepository $backendUserRepository)
{
}
@@ -30,6 +30,6 @@ public function getStatus(): QueryResultInterface|array
public function getUsers(): array
{
- return ContentUtility::getBackendUsers();
+ return $this->backendUserRepository->findAll();
}
}
diff --git a/Classes/Widgets/Provider/ContentUpdateDataProvider.php b/Classes/Widgets/Provider/ContentUpdateDataProvider.php
index 5c168ca..d5e865e 100644
--- a/Classes/Widgets/Provider/ContentUpdateDataProvider.php
+++ b/Classes/Widgets/Provider/ContentUpdateDataProvider.php
@@ -9,7 +9,6 @@
use TYPO3\CMS\Dashboard\Widgets\ListDataProviderInterface;
use Xima\XimaTypo3ContentPlanner\Configuration;
use Xima\XimaTypo3ContentPlanner\Domain\Model\Dto\HistoryItem;
-use Xima\XimaTypo3ContentPlanner\Utility\ContentUtility;
class ContentUpdateDataProvider implements ListDataProviderInterface
{
@@ -21,7 +20,7 @@ public function getItems(): array
return $this->fetchUpdateData(maxItems: 15);
}
- public function fetchUpdateData(bool $relevanteUpdatesForCurrentUser = false, ?int $beUser = null, ?int $tstamp = null, ?int $maxItems = null, bool $cliContext = false): array
+ public function fetchUpdateData(?int $beUser = null, ?int $tstamp = null, ?int $maxItems = null): array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_history');
@@ -52,14 +51,6 @@ public function fetchUpdateData(bool $relevanteUpdatesForCurrentUser = false, ?i
$query->setMaxResults($maxItems*2);
}
- // Filter for relevant history entries, which are not created by the current user
- if ($relevanteUpdatesForCurrentUser) {
- $query
- ->andWhere('h.userid != :userid')
- ->andWhere('p.tx_ximatypo3contentplanner_assignee = :userid')
- ->setParameter('userid', $beUser ?: $GLOBALS['BE_USER']->user['uid']);
- }
-
if ($tstamp) {
$query->andWhere('h.tstamp > :tstamp')
->setParameter('tstamp', $tstamp);
@@ -71,21 +62,11 @@ public function fetchUpdateData(bool $relevanteUpdatesForCurrentUser = false, ?i
foreach ($results as $result) {
try {
- $items[] = HistoryItem::create($result, $cliContext);
+ $items[] = HistoryItem::create($result);
} catch (\Exception $e) {
}
}
- if ($relevanteUpdatesForCurrentUser) {
- $additionalItems = $this->getRecentRelevantCommentsForUser($beUser);
- $items = array_merge($items, $additionalItems);
-
- // sort by tstamp
- usort($items, function ($a, $b) {
- return $b->data['tstamp'] <=> $a->data['tstamp'];
- });
- }
-
foreach ($items as $key => $item) {
if ($item->getHistoryData() === '') {
unset($items[$key]);
@@ -98,50 +79,4 @@ public function fetchUpdateData(bool $relevanteUpdatesForCurrentUser = false, ?i
return $items;
}
-
- /*
- * It's a workaround to fetch all comments and afterwards filter them by assigned pages, because this information is serialized and cannot be filtered within the query
- */
- private function getRecentRelevantCommentsForUser(?int $beUser = null): array
- {
- $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_history');
-
- $query = $queryBuilder
- ->select(
- 'h.uid',
- 'h.tstamp as tstamp',
- 'h.recuid as recuid',
- 'h.userid as userid',
- 'h.actiontype as actiontype',
- 'h.tablename as tablename',
- 'h.history_data as history_data',
- 'b.username as username',
- )
- ->from('sys_history', 'h')
- ->leftJoin('h', 'be_users', 'b', 'h.userid = b.uid')
- ->andWhere('h.userid != :userid')
- ->andWhere('h.tablename = "tx_ximatypo3contentplanner_comment"')
- ->orderBy('h.tstamp', 'DESC')
- ->setParameter('userid', $beUser ?: $GLOBALS['BE_USER']->user['uid']);
-
- $assignedPages = ContentUtility::getAssignedPages();
- // only get uids from assigned pages
- $uids = array_map(function ($page) {
- return $page['uid'];
- }, $assignedPages);
-
- $items = [];
- $results = $query->executeQuery()
- ->fetchAllAssociative();
-
- foreach ($results as $result) {
- try {
- if (!is_null($result['history_data']) && in_array(json_decode($result['history_data'], true)['pid'], $uids)) {
- $items[] = HistoryItem::create($result);
- }
- } catch (\Exception $e) {
- }
- }
- return $items;
- }
}
diff --git a/Classes/Widgets/Provider/CreateNoteButtonProvider.php b/Classes/Widgets/Provider/CreateNoteButtonProvider.php
deleted file mode 100644
index 3c356a7..0000000
--- a/Classes/Widgets/Provider/CreateNoteButtonProvider.php
+++ /dev/null
@@ -1,43 +0,0 @@
-title;
- }
-
- public function getLink(): string
- {
- $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
- $params = [
- 'edit' => ['tx_ximatypo3contentplanner_note' => [0 => 'new']],
- 'returnUrl' => (string)$uriBuilder->buildUriFromRoute('dashboard'),
- ];
-
- return (string)$uriBuilder->buildUriFromRoute('record_edit', $params);
- }
-
- public function getTarget(): string
- {
- return $this->target;
- }
-
- public function getElementAttributes(): array
- {
- return [];
- }
-}
diff --git a/Classes/Widgets/Provider/ListNoteButtonProvider.php b/Classes/Widgets/Provider/ListNoteButtonProvider.php
deleted file mode 100644
index 156d7a9..0000000
--- a/Classes/Widgets/Provider/ListNoteButtonProvider.php
+++ /dev/null
@@ -1,44 +0,0 @@
-title;
- }
-
- public function getLink(): string
- {
- $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
- $params = [
- 'id' => 0,
- 'table' => 'tx_ximatypo3contentplanner_note',
- 'returnUrl' => (string)$uriBuilder->buildUriFromRoute('dashboard'),
- ];
-
- return (string)$uriBuilder->buildUriFromRoute('web_list', $params);
- }
-
- public function getTarget(): string
- {
- return $this->target;
- }
-
- public function getElementAttributes(): array
- {
- return [];
- }
-}
diff --git a/Classes/Widgets/Provider/StatusOverviewDataProvider.php b/Classes/Widgets/Provider/StatusOverviewDataProvider.php
index 19e7d26..5495cd3 100644
--- a/Classes/Widgets/Provider/StatusOverviewDataProvider.php
+++ b/Classes/Widgets/Provider/StatusOverviewDataProvider.php
@@ -7,12 +7,12 @@
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Dashboard\Widgets\ChartDataProviderInterface;
use Xima\XimaTypo3ContentPlanner\Configuration;
+use Xima\XimaTypo3ContentPlanner\Domain\Repository\RecordRepository;
use Xima\XimaTypo3ContentPlanner\Domain\Repository\StatusRepository;
-use Xima\XimaTypo3ContentPlanner\Utility\ContentUtility;
class StatusOverviewDataProvider implements ChartDataProviderInterface
{
- public function __construct(protected StatusRepository $statusRepository)
+ public function __construct(private readonly StatusRepository $statusRepository, private readonly RecordRepository $recordRepository)
{
}
@@ -37,7 +37,7 @@ public function getChartData(): array
public function countPageStatus(int $status = null): int
{
- return count(ContentUtility::getRecordsByFilter(null, $status));
+ return count($this->recordRepository->findAllByFilter(status: $status));
}
protected function calculateStatusCounts(): void
@@ -45,7 +45,7 @@ protected function calculateStatusCounts(): void
foreach ($this->statusRepository->findAll() as $status) {
$this->labels[] = $status->getTitle();
$this->data[] = $this->countPageStatus($status->getUid());
- $this->colors[] = Configuration::STATUS_COLOR_CODES[$status->getColor()];
+ $this->colors[] = Configuration\Colors::get($status->getColor());
}
}
diff --git a/Configuration/Backend/DashboardPresets.php b/Configuration/Backend/DashboardPresets.php
index 92a8a13..090efc3 100644
--- a/Configuration/Backend/DashboardPresets.php
+++ b/Configuration/Backend/DashboardPresets.php
@@ -5,7 +5,7 @@
'title' => 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:dashboard.contentPlanner',
'description' => 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:dashboard.contentPlanner.description',
'iconIdentifier' => 'flag-gray',
- 'defaultWidgets' => ['contentPlanner-notes', 'contentPlanner-overview', 'contentPlanner-current', 'contentPlanner-update', 'contentPlanner-status', 'contentPlanner-comment'],
+ 'defaultWidgets' => ['contentPlanner-overview', 'contentPlanner-update', 'contentPlanner-current', 'contentPlanner-comment', 'contentPlanner-status'],
'showInWizard' => true,
],
];
diff --git a/Configuration/Icons.php b/Configuration/Icons.php
index 60d838e..f8f07ad 100644
--- a/Configuration/Icons.php
+++ b/Configuration/Icons.php
@@ -3,165 +3,432 @@
declare(strict_types=1);
use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider;
+use TYPO3\CMS\Core\Imaging\IconProvider\SvgSpriteIconProvider;
use Xima\XimaTypo3ContentPlanner\Configuration;
return [
+ 'actions-flag-edit' => [
+ 'provider' => SvgIconProvider::class,
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/actions-flag-edit.svg',
+ ],
// flag
'flag-black' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-black.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-black.svg',
],
'flag-white' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-white.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-white',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-white.svg',
],
'flag-toolbar' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-toolbar.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-toolbar',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-toolbar.svg',
],
'flag-blue' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-blue.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-blue.svg',
],
'flag-gray' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-gray.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-gray.svg',
],
'flag-green' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-green.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-green.svg',
],
'flag-red' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-red.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-red.svg',
],
'flag-yellow' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/flag-yellow.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-yellow.svg',
+ ],
+ 'flag-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-purple.svg',
+ ],
+ 'flag-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/flags.svg#flag-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/flags/flag-orange.svg',
],
// star
'star-black' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/star-black.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-black.svg',
],
'star-blue' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/star-blue.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-blue.svg',
],
'star-gray' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/star-gray.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-gray.svg',
],
'star-green' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/star-green.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-green.svg',
],
'star-red' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/star-red.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-red.svg',
],
'star-yellow' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/star-yellow.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-yellow.svg',
+ ],
+ 'star-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-purple.svg',
+ ],
+ 'star-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/stars.svg#star-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/stars/star-orange.svg',
],
// tag
'tag-black' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/tag-black.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-black.svg',
],
'tag-blue' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/tag-blue.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-blue.svg',
],
'tag-gray' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/tag-gray.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-gray.svg',
],
'tag-green' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/tag-green.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-green.svg',
],
'tag-red' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/tag-red.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-red.svg',
],
'tag-yellow' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/tag-yellow.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-yellow.svg',
+ ],
+ 'tag-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-purple.svg',
+ ],
+ 'tag-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/tags.svg#tag-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/tags/tag-orange.svg',
],
// info
'info-black' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/info-black.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-black.svg',
],
'info-blue' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/info-blue.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-blue.svg',
],
'info-gray' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/info-gray.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-gray.svg',
],
'info-green' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/info-green.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-green.svg',
],
'info-red' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/info-red.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-red.svg',
],
'info-yellow' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/info-yellow.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-yellow.svg',
+ ],
+ 'info-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-purple.svg',
+ ],
+ 'info-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/infos.svg#info-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/infos/info-orange.svg',
],
// heart
'heart-black' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/heart-black.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-black.svg',
],
'heart-blue' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/heart-blue.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-blue.svg',
],
'heart-gray' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/heart-gray.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-gray.svg',
],
'heart-green' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/heart-green.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-green.svg',
],
'heart-red' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/heart-red.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-red.svg',
],
'heart-yellow' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/heart-yellow.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-yellow.svg',
+ ],
+ 'heart-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-purple.svg',
+ ],
+ 'heart-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/hearts.svg#heart-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/hearts/heart-orange.svg',
+ ],
+ // certificates
+ 'certificate-black' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-black.svg',
+ ],
+ 'certificate-blue' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-blue.svg',
+ ],
+ 'certificate-gray' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-gray.svg',
+ ],
+ 'certificate-green' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-green.svg',
+ ],
+ 'certificate-red' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-red.svg',
+ ],
+ 'certificate-yellow' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-yellow.svg',
+ ],
+ 'certificate-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-purple.svg',
+ ],
+ 'certificate-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/certificates.svg#certificate-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/certificates/certificate-orange.svg',
+ ],
+ // exclamation
+ 'exclamation-black' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-black.svg',
+ ],
+ 'exclamation-blue' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-blue.svg',
+ ],
+ 'exclamation-gray' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-gray.svg',
+ ],
+ 'exclamation-green' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-green.svg',
+ ],
+ 'exclamation-red' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-red.svg',
+ ],
+ 'exclamation-yellow' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-yellow.svg',
+ ],
+ 'exclamation-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-purple.svg',
+ ],
+ 'exclamation-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/exclamations.svg#exclamation-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/exclamations/exclamation-orange.svg',
+ ],
+ // rocket
+ 'rocket-black' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-black.svg',
+ ],
+ 'rocket-blue' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-blue.svg',
+ ],
+ 'rocket-gray' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-gray.svg',
+ ],
+ 'rocket-green' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-green.svg',
+ ],
+ 'rocket-red' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-red.svg',
+ ],
+ 'rocket-yellow' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-yellow.svg',
+ ],
+ 'rocket-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-purple.svg',
+ ],
+ 'rocket-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/rockets.svg#rocket-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/rockets/rocket-orange.svg',
+ ],
+ // thumbtack
+ 'thumbtack-black' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-black.svg',
+ ],
+ 'thumbtack-blue' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-blue.svg',
+ ],
+ 'thumbtack-gray' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-gray.svg',
+ ],
+ 'thumbtack-green' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-green.svg',
+ ],
+ 'thumbtack-red' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-red.svg',
+ ],
+ 'thumbtack-yellow' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-yellow.svg',
+ ],
+ 'thumbtack-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-purple.svg',
+ ],
+ 'thumbtack-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/thumbtacks.svg#thumbtack-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/thumbtacks/thumbtack-orange.svg',
],
// color
'color-black' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/color-black.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-black',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-black.svg',
],
'color-blue' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/color-blue.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-blue',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-blue.svg',
],
'color-gray' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/color-gray.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-gray',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-gray.svg',
],
'color-green' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/color-green.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-green',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-green.svg',
],
'color-red' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/color-red.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-red',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-red.svg',
],
'color-yellow' => [
- 'provider' => SvgIconProvider::class,
- 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/color-yellow.svg',
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-yellow',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-yellow.svg',
+ ],
+ 'color-purple' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-purple',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-purple.svg',
+ ],
+ 'color-orange' => [
+ 'provider' => SvgSpriteIconProvider::class,
+ 'sprite' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/sprites/colors.svg#color-orange',
+ 'source' => 'EXT:' . Configuration::EXT_KEY . '/Resources/Public/Icons/svgs/colors/color-orange.svg',
],
];
diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml
index 8043c1c..f7ef18c 100644
--- a/Configuration/Services.yaml
+++ b/Configuration/Services.yaml
@@ -8,14 +8,20 @@ services:
resource: '../Classes/*'
exclude: '../Classes/Domain/Model/*'
- cache.ximatypo3contentplanner_toolbarcache:
+ cache.ximatypo3contentplanner_statuscache:
class: TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
factory: [ '@TYPO3\CMS\Core\Cache\CacheManager', 'getCache' ]
- arguments: [ 'ximatypo3contentplanner_toolbarcache' ]
+ arguments: [ 'ximatypo3contentplanner_statuscache' ]
- Xima\XimaTypo3ContentPlanner\Backend\ToolbarItems\UpdateItem:
+ Xima\XimaTypo3ContentPlanner\Domain\Repository\StatusRepository:
arguments:
- $cache: '@cache.ximatypo3contentplanner_toolbarcache'
+ $cache: '@cache.ximatypo3contentplanner_statuscache'
+
+ Xima\XimaTypo3ContentPlanner\Hooks\DataHandlerHook:
+ public: true
+ arguments:
+ $cache: '@cache.ximatypo3contentplanner_statuscache'
+ $statusChangeManager: '@Xima\XimaTypo3ContentPlanner\Manager\StatusChangeManager'
Xima\XimaTypo3ContentPlanner\EventListener\DrawBackendHeaderListener:
tags:
@@ -42,12 +48,6 @@ services:
- name: event.listener
identifier: 'xima-typo3-content-planner/backend/modify-record-list-record-actions'
- Xima\XimaTypo3ContentPlanner\Command\NotifyUpdateCommand:
- tags:
- - name: console.command
- command: 'content-planner:notifiy-update'
- description: 'A command to notify users about relevant updates in the content planner.'
-
Xima\XimaTypo3ContentPlanner\Command\BulkUpdateCommand:
tags:
- name: console.command
@@ -102,8 +102,8 @@ services:
title: 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:widgets.contentPlanner.comment.title'
description: 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:widgets.contentPlanner.comment.description'
iconIdentifier: 'content-message'
- height: 'large'
- width: 'medium'
+ height: 'medium'
+ width: 'small'
dashboard.widget.ContentStatus-overview:
class: 'TYPO3\CMS\Dashboard\Widgets\DoughnutChartWidget'
@@ -120,30 +120,6 @@ services:
iconIdentifier: 'content-widget-chart-pie'
height: 'medium'
- Xima\XimaTypo3ContentPlanner\Widgets\Provider\CreateNoteButtonProvider:
- arguments:
- $title: 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:widgets.contentPlanner.notes.button.create'
-
- Xima\XimaTypo3ContentPlanner\Widgets\Provider\ListNoteButtonProvider:
- arguments:
- $title: 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:widgets.contentPlanner.notes.button.list'
-
- dashboard.widget.ContentStatus-notes:
- class: 'Xima\XimaTypo3ContentPlanner\Widgets\ContentNotesWidget'
- arguments:
- $dataProvider: '@Xima\XimaTypo3ContentPlanner\Widgets\Provider\ContentNotesDataProvider'
- $buttons:
- - '@Xima\XimaTypo3ContentPlanner\Widgets\Provider\CreateNoteButtonProvider'
- - '@Xima\XimaTypo3ContentPlanner\Widgets\Provider\ListNoteButtonProvider'
- tags:
- - name: dashboard.widget
- identifier: 'contentPlanner-notes'
- groupNames: 'contentPlanner'
- title: 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:widgets.contentPlanner.notes.title'
- description: 'LLL:EXT:xima_typo3_content_planner/Resources/Private/Language/locallang.xlf:widgets.contentPlanner.notes.description'
- iconIdentifier: 'content-thumbtack'
- height: 'medium'
-
dashboard.widget.ContentStatus-update:
class: 'Xima\XimaTypo3ContentPlanner\Widgets\ContentUpdateWidget'
arguments:
diff --git a/Configuration/TCA/Overrides/be_users.php b/Configuration/TCA/Overrides/be_users.php
index dff27df..0775ef6 100644
--- a/Configuration/TCA/Overrides/be_users.php
+++ b/Configuration/TCA/Overrides/be_users.php
@@ -21,23 +21,9 @@
],
],
],
- 'tx_ximatypo3contentplanner_subscribe' => [
- 'exclude' => 1,
- 'label' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_db.xlf:be_users.tx_ximatypo3contentplanner_subscribe',
- 'description' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_db.xlf:be_users.tx_ximatypo3contentplanner_subscribe.description',
- 'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
- 'items' => [
- ['label' => 'Never', 'value' => ''],
- ['label' => 'Daily', 'value' => 'daily'],
- ['label' => 'Weekly', 'value' => 'weekly'],
- ],
- ],
- ],
];
$GLOBALS['TCA']['pages']['palettes']['tx_ximatypo3contentplanner'] = [
- 'showitem' => 'tx_ximatypo3contentplanner_hide, tx_ximatypo3contentplanner_subscribe',
+ 'showitem' => 'tx_ximatypo3contentplanner_hide',
];
ExtensionManagementUtility::addTCAcolumns('be_users', $temporaryColumns);
diff --git a/Configuration/TCA/tx_ximatypo3contentplanner_comment.php b/Configuration/TCA/tx_ximatypo3contentplanner_comment.php
index 0484acc..72a7857 100644
--- a/Configuration/TCA/tx_ximatypo3contentplanner_comment.php
+++ b/Configuration/TCA/tx_ximatypo3contentplanner_comment.php
@@ -16,6 +16,7 @@
'typeicon_classes' => [
'default' => 'content-message',
],
+ 'default_sortby' => 'crdate',
'searchFields' => 'title,text',
'hideTable' => true,
'security' => [
@@ -35,11 +36,6 @@
'type' => 'check',
],
],
- 'sorting' => [
- 'config' => [
- 'type' => 'passthrough',
- ],
- ],
'content' => [
'exclude' => 1,
'label' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_db.xlf:tx_ximatypo3contentplanner_comment.content',
diff --git a/Configuration/TCA/tx_ximatypo3contentplanner_note.php b/Configuration/TCA/tx_ximatypo3contentplanner_note.php
deleted file mode 100644
index 29232a3..0000000
--- a/Configuration/TCA/tx_ximatypo3contentplanner_note.php
+++ /dev/null
@@ -1,58 +0,0 @@
- [
- 'title' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_be.xlf:note',
- 'label' => 'title',
- 'tstamp' => 'tstamp',
- 'crdate' => 'crdate',
- 'adminOnly' => true,
- 'rootLevel' => 1,
- 'delete' => 'deleted',
- 'enablecolumns' => [
- 'disabled' => 'hidden',
- ],
- 'default_sortby' => 'crdate DESC',
- 'typeicon_classes' => [
- 'default' => 'mimetypes-x-sys_news',
- ],
- 'searchFields' => 'title,content',
- ],
- 'types' => [
- '0' => [
- 'showitem' => 'title,content',
- ],
- ],
- 'columns' => [
- 'hidden' => [
- 'exclude' => 1,
- 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.hidden',
- 'config' => [
- 'type' => 'check',
- ],
- ],
- 'title' => [
- 'exclude' => 1,
- 'label' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_db.xlf:tx_ximatypo3contentplanner_note.title',
- 'config' => [
- 'type' => 'input',
- 'eval' => 'trim',
- 'required' => true,
- ],
- ],
- 'content' => [
- 'exclude' => 1,
- 'label' => 'LLL:EXT:' . Configuration::EXT_KEY . '/Resources/Private/Language/locallang_db.xlf:tx_ximatypo3contentplanner_note.text',
- 'config' => [
- 'enableRichtext' => true,
- 'type' => 'text',
- 'eval' => 'trim',
- 'cols' => 48,
- 'rows' => 5,
- 'required' => true,
- ],
- ],
- ],
-];
diff --git a/Documentation/Images/categories.png b/Documentation/Images/categories.png
new file mode 100644
index 0000000..4f43114
Binary files /dev/null and b/Documentation/Images/categories.png differ
diff --git a/Documentation/Images/dashboard.png b/Documentation/Images/dashboard.png
index 0b9a22c..7dd011b 100644
Binary files a/Documentation/Images/dashboard.png and b/Documentation/Images/dashboard.png differ
diff --git a/Documentation/Images/page.png b/Documentation/Images/page.png
index 834bf59..4a044df 100644
Binary files a/Documentation/Images/page.png and b/Documentation/Images/page.png differ
diff --git a/Documentation/Images/screencast.gif b/Documentation/Images/screencast.gif
new file mode 100644
index 0000000..1e0de16
Binary files /dev/null and b/Documentation/Images/screencast.gif differ
diff --git a/Documentation/Images/tt_content.png b/Documentation/Images/tt_content.png
new file mode 100644
index 0000000..015ef59
Binary files /dev/null and b/Documentation/Images/tt_content.png differ
diff --git a/README.md b/README.md
index c5dc59d..d43f998 100644
--- a/README.md
+++ b/README.md
@@ -50,14 +50,14 @@ Download the zip file from [TYPO3 extension repository (TER)](https://extensions
### Status
-By default they are four different default status available:
+By default, they are four different default status available:
- *Pending*: The page is not yet ready for editing.
- *In progress*: The page is currently being edited.
- *Needs review*: The page is ready for review.
- *Completed*: The page is ready to be published.
-> **Hint**: The status are content generated on the root page. Add/remove/adjust them to fit your needs.
+> **Hint**: The status are content generated on the root page. Add/remove/adjust them to fit your needs regarding custom title, predefined color and icon.
Change the page status easily:
@@ -65,13 +65,17 @@ Change the page status easily:
- In the page tree context menu
- In the page backend header
+### Assignee and comments
+
Assign a user to the page to distribute the content work. >our own assignment is highlighted in the dashboard.
> **Hint**: By default the auto assignee feature is enabled. The assignee is automatically set to the current user when the status is changed from stateless to a new state.
-Add some helpful comments within the page to support the content work.
+Configure the auto assignee feature and more in the __extension settings__.
+
+Use the comment feature to add some helpful message within the records to support the content work.
-![Screencast](./Documentation/Images/screencast-content-planner.gif)
+![Screencast](./Documentation/Images/screencast.gif)
### Dashboard
@@ -83,13 +87,27 @@ Add custom notes to the dashboard to influence the content planning.
## Configuration
-Feature toggles are available, see `ext_localconf.php` for configuration options.
+Feature toggles are available in the __extension settings__.
+
+### User settings
The content planner abilities are part of a **custom permission** and needed to be granted to the dedicated user group/s (except admins).
Every user can easily disable the content planner features in the user settings to avoid colour overload.
-## Additional record tables
+## Command
+
+Use the bulk update command to process multiple entities at once. See help for more information regarding the specific usage.
+
+```bash
+vendor/bin/typo3 content-planner:bulk-update --help
+```
+
+## Extend
+
+### Additional record tables
+
+![Categories](./Documentation/Images/categories.png)
If you want to extend the content planner to other record tables (e.g. news), follow the steps below:
@@ -116,6 +134,25 @@ CREATE TABLE tx_news_domain_model_news
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['xima_typo3_content_planner']['registerAdditionalRecordTables'][] = 'tx_news_domain_model_news';
```
+> **Hint**: The extension also support the content status functionality for content elements as well.
+
+![Content](./Documentation/Images/tt_content.png)
+
+### Events
+
+This extension provides several events to hook into the content planner functionality.
+
+- [StatusChangeEvent](Classes/Event/StatusChangeEvent.php)
+- [PrepareStatusSelectionEvent.php](Classes/Event/PrepareStatusSelectionEvent.php)
+
+## Development
+
+Use the following ddev command to easily install all support TYPO3 versions.
+
+```bash
+ddev install all
+```
+
## License
This project is licensed
diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf
new file mode 100644
index 0000000..497611e
--- /dev/null
+++ b/Resources/Private/Language/de.locallang.xlf
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+ Content Planner
+
+
+
+ Übersichtsdashboard für Inhaltsstatusinformationen
+
+
+
+ Content Planner
+
+
+
+ Status
+
+
+
+ Alle Datensätze mit Inhaltsstatus anzeigen
+
+
+
+ Aktueller Zuständigkeit
+
+
+
+ Alle Datensätze mit Ihrer Zuweisung anzeigen
+
+
+
+ Übersicht
+
+
+
+ Ein Diagramm mit der Verteilung des Inhaltsstatus anzeigen
+
+
+
+
+
+ Neueste Updates
+
+
+
+ Die neuesten Updates hinsichtlich Inhaltsstatusänderungen anzeigen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ vor %s Jahren
+
+
+
+ vor %s Jahr
+
+
+
+ vor %s Monaten
+
+
+
+ vor %s Monat
+
+
+
+ vor %s Tagen
+
+
+
+ vor %s Tag
+
+
+
+ vor %s Stunden
+
+
+
+ vor %s Stunde
+
+
+
+ vor %s Minuten
+
+
+
+ vor %s Minute
+
+
+
+ vor %s Sekunden
+
+
+
+ vor %s Sekunde
+
+
+
+
diff --git a/Resources/Private/Language/de.locallang_be.xlf b/Resources/Private/Language/de.locallang_be.xlf
new file mode 100644
index 0000000..fe118a2
--- /dev/null
+++ b/Resources/Private/Language/de.locallang_be.xlf
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ Inhaltsstatus
+
+
+
+ Ausstehend
+
+
+
+ In Bearbeitung
+
+
+
+ Benötigt Überprüfung
+
+
+
+ Abgeschlossen
+
+
+
+ Status zurücksetzen
+
+
+
+
+
+ Aktueller Zuständiger
+
+
+
+ Speichern und Schließen
+
+
+
+
+ Status wurde auf %s gesetzt]]>
+
+
+
+ Status wurde von %s entfernt]]>
+
+
+
+ Status wurde von %s zu %s geändert]]>
+
+
+
+ Zuständigkeit wurde auf %s gesetzt]]>
+
+
+
+ Zuständigkeit wurde von %s entfernt]]>
+
+
+
+ Zuständigkeit wurde von %s zu %s geändert]]>
+
+
+
+
+
+
+
diff --git a/Resources/Private/Language/de.locallang_db.xlf b/Resources/Private/Language/de.locallang_db.xlf
new file mode 100644
index 0000000..ce1f0ae
--- /dev/null
+++ b/Resources/Private/Language/de.locallang_db.xlf
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+ Status
+
+
+
+
+ Zuständigkeit
+
+
+
+
+
+ Content Planner ausblenden
+
+
+
+ Deaktivieren Sie die Anzeige von Content Planner Statusinformationen und Farben im TYPO3-Backend
+
+
+
+ Titel
+
+
+
+ Symbol
+
+
+
+ Farbe
+
+
+
+ Content Planner
+
+
+
+ Inhaltsstatus
+
+
+
+ Erlauben Sie die Verwendung des Inhaltsstatus innerhalb von Datensätzen
+
+
+
+ Content Planner
+
+
+
+
diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf
index 3e2db05..892018f 100644
--- a/Resources/Private/Language/locallang.xlf
+++ b/Resources/Private/Language/locallang.xlf
@@ -13,43 +13,31 @@
Content Planner
- Content Planner Status
+ Status
- Display all pages with content status
+ Display all records with content status
- Content Planner Current Assignee
+ Current Assignee
- Display all pages with your assignment
+ Display all records with your assignment
- Content Planner Overview
+ Overview
Display a donut chart with the distribution of content status
-
- Content Planner Notes
-
-
- Display the content status notes
-
-
- New
-
-
- List
-
- Content Planner Recent Updates
+ Recent Updates
Display the recent updates according to content status changes
@@ -88,9 +76,15 @@
Change note
+
+
diff --git a/Resources/Private/Language/locallang_be.xlf b/Resources/Private/Language/locallang_be.xlf
index 8eee0dd..8c56893 100644
--- a/Resources/Private/Language/locallang_be.xlf
+++ b/Resources/Private/Language/locallang_be.xlf
@@ -24,8 +24,14 @@
-
- Content Planner Note
+
+
+ Current Assignee
+
+
+ Save and Close
diff --git a/Resources/Private/Language/locallang_db.xlf b/Resources/Private/Language/locallang_db.xlf
index 27620ce..ddb2b58 100644
--- a/Resources/Private/Language/locallang_db.xlf
+++ b/Resources/Private/Language/locallang_db.xlf
@@ -24,18 +24,6 @@
Disable the display of content planner status information and color within the TYPO3 backend
-
- Subscribe for updates
-
-
- Subscribe to e-mail notification for content planner updates
-
-
- Title
-
-
- Text
-
Title
diff --git a/Resources/Private/Partials/Empty.html b/Resources/Private/Partials/Empty.html
index d130bfb..a7ee532 100644
--- a/Resources/Private/Partials/Empty.html
+++ b/Resources/Private/Partials/Empty.html
@@ -5,3 +5,17 @@
EXT:xima_typo3_content_planner/Resources/Public/Icons/icon-relax-{xcp:randomNumber(min: 1,max: 5)}.svg
+
+
diff --git a/Resources/Private/Templates/Backend/Header/HeaderInfo.html b/Resources/Private/Templates/Backend/Header/HeaderInfo.html
new file mode 100644
index 0000000..d75cb89
--- /dev/null
+++ b/Resources/Private/Templates/Backend/Header/HeaderInfo.html
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/Resources/Private/Templates/Backend/PageHeader/PageHeaderInfo.html b/Resources/Private/Templates/Backend/PageHeader/PageHeaderInfo.html
deleted file mode 100644
index d0f452b..0000000
--- a/Resources/Private/Templates/Backend/PageHeader/PageHeaderInfo.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
diff --git a/Resources/Private/Templates/Backend/ToolbarItems/UpdateItem.html b/Resources/Private/Templates/Backend/ToolbarItems/UpdateItem.html
deleted file mode 100644
index e157763..0000000
--- a/Resources/Private/Templates/Backend/ToolbarItems/UpdateItem.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-Content Planner Relevant Updates
-
- {count}
-
diff --git a/Resources/Private/Templates/Backend/ToolbarItems/UpdateItemDropDown.html b/Resources/Private/Templates/Backend/ToolbarItems/UpdateItemDropDown.html
deleted file mode 100644
index 346733a..0000000
--- a/Resources/Private/Templates/Backend/ToolbarItems/UpdateItemDropDown.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
- Content Planner: Relevant Updates
-
-Find recent updates on content, you're currently assigned to.
-
-
-
-
-
-
-
- {record.historyData -> f:format.raw()}
-
- by
-
-
-
- {record.user}
-
- {record.timeAgo}
-
-
-
-
-
-
-
-
- {f:if(condition: record.pageTitle, then: '{record.pageTitle -> f:format.raw()}',
- else: '[{f:translate(key:
- \'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title\')}]')}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Resources/Private/Templates/Backend/Widgets/ContentCommentList.html b/Resources/Private/Templates/Backend/Widgets/ContentCommentList.html
index 5250cc2..4e4c4f5 100644
--- a/Resources/Private/Templates/Backend/Widgets/ContentCommentList.html
+++ b/Resources/Private/Templates/Backend/Widgets/ContentCommentList.html
@@ -11,26 +11,29 @@
-
-
-
Content Planner Update
-Find recent updates on content, you may have probably missed.
--
-
-
-
- -
-
-
- {record.changeTypeIcon -> f:format.raw()}
-
-
- {record.historyData -> f:format.raw()}
-
- by
-
-
- {record.user}
-
- {record.timeAgo}
-
- {record.statusIcon -> f:format.raw()}
- {record.recordIcon -> f:format.raw()}
- {record.title}
-
-
-
-
-
-
-
-
-
- --