Compare commits
29
Commits
5e39e39b90
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49547ecda3 | ||
|
|
eb096bd8b5 | ||
|
|
b3541b21fb | ||
|
|
93ed5c6962 | ||
|
|
942724fdd1 | ||
|
|
e52f7dcff8 | ||
|
|
30e531497d | ||
|
|
2cb37e760a | ||
|
|
3ff3251419 | ||
|
|
abcd39107b | ||
|
|
599e3c7ee2 | ||
|
|
6ff308015a | ||
|
|
6e0479bf22 | ||
|
|
fb8fddf669 | ||
|
|
f745c7b683 | ||
|
|
9b3550ec40 | ||
|
|
d9943619f6 | ||
|
|
e33b57c9f1 | ||
|
|
dc594efee1 | ||
|
|
432d8da350 | ||
|
|
5b338eeab6 | ||
|
|
05ceae5100 | ||
|
|
f005272242 | ||
|
|
7d856d1031 | ||
|
|
f9e94231a7 | ||
|
|
0a3e8f59cb | ||
|
|
a01d1ba0c5 | ||
|
|
6828e49663 | ||
|
|
46001a02ed |
+79
-42
@@ -1,9 +1,8 @@
|
|||||||
|
name: ep-reisen
|
||||||
type: typo3
|
type: typo3
|
||||||
docroot: public
|
docroot: public
|
||||||
php_version: "7.4"
|
php_version: "7.4"
|
||||||
webserver_type: nginx-fpm
|
webserver_type: nginx-fpm
|
||||||
router_http_port: "80"
|
|
||||||
router_https_port: "443"
|
|
||||||
xdebug_enabled: false
|
xdebug_enabled: false
|
||||||
additional_hostnames:
|
additional_hostnames:
|
||||||
- ep-events
|
- ep-events
|
||||||
@@ -16,36 +15,58 @@ additional_hostnames:
|
|||||||
additional_fqdns: []
|
additional_fqdns: []
|
||||||
database:
|
database:
|
||||||
type: mariadb
|
type: mariadb
|
||||||
version: "10.2"
|
version: "11.4"
|
||||||
|
hooks:
|
||||||
|
post-start:
|
||||||
|
- exec: .ddev/claude-code/install.sh
|
||||||
|
- exec: .ddev/codex-cli/install.sh
|
||||||
|
webimage_extra_packages: [ripgrep, bubblewrap, socat]
|
||||||
use_dns_when_possible: true
|
use_dns_when_possible: true
|
||||||
timezone: Europe/Berlin
|
timezone: Europe/Berlin
|
||||||
composer_version: "2"
|
composer_version: "2"
|
||||||
web_environment:
|
web_environment:
|
||||||
- TYPO3_CONTEXT=Development
|
- TYPO3_CONTEXT=Development
|
||||||
nodejs_version: "18"
|
nodejs_version: "24"
|
||||||
|
corepack_enable: false
|
||||||
|
omit_containers: [ddev-ssh-agent]
|
||||||
|
|
||||||
# Key features of DDEV's config.yaml:
|
# Key features of DDEV's config.yaml:
|
||||||
|
|
||||||
# name: <projectname> # Name of the project, automatically provides
|
# name: <projectname> # Name of the project, automatically provides
|
||||||
# http://projectname.ddev.site and https://projectname.ddev.site
|
# http://projectname.ddev.site and https://projectname.ddev.site
|
||||||
|
# If the name is omitted, the project will take the name of the enclosing directory,
|
||||||
|
# which is useful if you want to have a copy of the project side by side with this one.
|
||||||
|
|
||||||
# type: <projecttype> # drupal6/7/8, backdrop, typo3, wordpress, php
|
# type: <projecttype> # asterios, backdrop, cakephp, codeigniter, craftcms, drupal, drupal6, drupal7, drupal8, drupal9, drupal10, drupal11, drupal12, generic, joomla, laravel, magento, magento2, maho, modx, php, shopware6, silverstripe, symfony, typo3, wordpress, wp-bedrock
|
||||||
|
# See https://docs.ddev.com/en/stable/users/quickstart/ for more
|
||||||
|
# information on the different project types
|
||||||
|
|
||||||
# docroot: <relative_path> # Relative path to the directory containing index.php.
|
# docroot: <relative_path> # Relative path to the directory containing index.php.
|
||||||
|
|
||||||
# php_version: "8.1" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2", "8.3"
|
# php_version: "8.4" # PHP version to use, "5.6" through "8.5"
|
||||||
|
|
||||||
# You can explicitly specify the webimage but this
|
# You can explicitly specify the webimage but this
|
||||||
# is not recommended, as the images are often closely tied to DDEV's' behavior,
|
# is not recommended, as the images are often closely tied to DDEV's behavior,
|
||||||
# so this can break upgrades.
|
# so this can break upgrades.
|
||||||
|
|
||||||
# webimage: <docker_image> # nginx/php docker image.
|
# webimage: <docker_image>
|
||||||
|
# It’s unusual to change this option, and we don’t recommend it without Docker experience and a good reason.
|
||||||
|
# Typically, this means additions to the existing web image using a .ddev/web-build/Dockerfile.*
|
||||||
|
|
||||||
# database:
|
# database:
|
||||||
# type: <dbtype> # mysql, mariadb, postgres
|
# type: <dbtype> # mysql, mariadb, postgres
|
||||||
# version: <version> # database version, like "10.4" or "8.0"
|
# version: <version> # database version, like "10.11" or "8.0"
|
||||||
# MariaDB versions can be 5.5-10.8 and 10.11, MySQL versions can be 5.5-8.0
|
# MariaDB versions can be 5.5-10.8, 10.11, 11.4, 11.8, 12.3
|
||||||
# PostgreSQL versions can be 9-16.
|
# MySQL versions can be 5.5-8.0, 8.4, 9.7
|
||||||
|
# PostgreSQL versions can be 9-18
|
||||||
|
|
||||||
|
# You can explicitly specify the dbimage but this
|
||||||
|
# is not recommended, as the images are often closely tied to DDEV's behavior,
|
||||||
|
# so this can break upgrades.
|
||||||
|
|
||||||
|
# dbimage: <docker_image>
|
||||||
|
# It’s unusual to change this option, and we don’t recommend it without Docker experience and a good reason.
|
||||||
|
# Typically, this means additions to the existing db image using a .ddev/db-build/Dockerfile.*
|
||||||
|
|
||||||
# router_http_port: <port> # Port to be used for http (defaults to global configuration, usually 80)
|
# router_http_port: <port> # Port to be used for http (defaults to global configuration, usually 80)
|
||||||
# router_https_port: <port> # Port for https (defaults to global configuration, usually 443)
|
# router_https_port: <port> # Port for https (defaults to global configuration, usually 443)
|
||||||
@@ -55,14 +76,24 @@ nodejs_version: "18"
|
|||||||
# "ddev xdebug" to enable Xdebug and "ddev xdebug off" to disable it work better,
|
# "ddev xdebug" to enable Xdebug and "ddev xdebug off" to disable it work better,
|
||||||
# as leaving Xdebug enabled all the time is a big performance hit.
|
# as leaving Xdebug enabled all the time is a big performance hit.
|
||||||
|
|
||||||
# xhprof_enabled: false # Set to true to enable Xhprof and "ddev start" or "ddev restart"
|
# xhgui_http_port: "8143"
|
||||||
# Note that for most people the commands
|
# xhgui_https_port: "8142"
|
||||||
# "ddev xhprof" to enable Xhprof and "ddev xhprof off" to disable it work better,
|
# The XHGui ports can be changed from the default 8143 and 8142
|
||||||
# as leaving Xhprof enabled all the time is a big performance hit.
|
# Very rarely used
|
||||||
|
|
||||||
# webserver_type: nginx-fpm, apache-fpm, or nginx-gunicorn
|
# host_xhgui_port: "8142"
|
||||||
|
# Can be used to change the host binding port of the XHGui
|
||||||
|
# application. Rarely used; only when port conflict and
|
||||||
|
# bind_all_ports is used (normally with router disabled)
|
||||||
|
|
||||||
|
# xhprof_mode: [prepend|xhgui|global]
|
||||||
|
# Default is "xhgui"
|
||||||
|
|
||||||
|
# webserver_type: nginx-fpm, apache-fpm, generic
|
||||||
|
|
||||||
# timezone: Europe/Berlin
|
# timezone: Europe/Berlin
|
||||||
|
# If timezone is unset, DDEV will attempt to derive it from the host system timezone
|
||||||
|
# using the $TZ environment variable or the /etc/localtime symlink.
|
||||||
# This is the timezone used in the containers and by PHP;
|
# This is the timezone used in the containers and by PHP;
|
||||||
# it can be set to any valid timezone,
|
# it can be set to any valid timezone,
|
||||||
# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
@@ -74,22 +105,27 @@ nodejs_version: "18"
|
|||||||
# commands are executed.
|
# commands are executed.
|
||||||
|
|
||||||
# composer_version: "2"
|
# composer_version: "2"
|
||||||
# You can set it to "" or "2" (default) for Composer v2 or "1" for Composer v1
|
# You can set it to "" or "2" (default) for Composer v2
|
||||||
# to use the latest major version available at the time your container is built.
|
# to use the latest major version available at the time your container is built.
|
||||||
# It is also possible to use each other Composer version channel. This includes:
|
# It is also possible to use any other Composer version channel. This includes:
|
||||||
# - 2.2 (latest Composer LTS version)
|
# - 2.2 (latest Composer LTS version)
|
||||||
# - stable
|
# - stable
|
||||||
# - preview
|
# - preview
|
||||||
# - snapshot
|
# - snapshot
|
||||||
# Alternatively, an explicit Composer version may be specified, for example "2.2.18".
|
# Alternatively, an explicit Composer version may be specified, for example "2.2.18".
|
||||||
# To reinstall Composer after the image was built, run "ddev debug refresh".
|
# To reinstall Composer after the image was built, run "ddev utility rebuild".
|
||||||
|
|
||||||
# nodejs_version: "18"
|
# nodejs_root: <relative_path>
|
||||||
# change from the default system Node.js version to another supported version, like 16, 18, 20.
|
# Relative path to the directory containing the Node.js version file from the
|
||||||
# Note that you can use 'ddev nvm' or nvm inside the web container to provide nearly any
|
# project root. Only used with "nodejs_version: auto" or "nodejs_version: engine".
|
||||||
# Node.js version, including v6, etc.
|
|
||||||
# You only need to configure this if you are not using nvm and you want to use a major
|
# nodejs_version: "24"
|
||||||
# version that is not the default.
|
# change from the default system Node.js version to any other version.
|
||||||
|
# See https://docs.ddev.com/en/stable/users/configuration/config/#nodejs_version for more information
|
||||||
|
# and https://www.npmjs.com/package/n#specifying-nodejs-versions for the full documentation.
|
||||||
|
|
||||||
|
# corepack_enable: false
|
||||||
|
# Change to 'true' to 'corepack enable' and gain access to latest versions of yarn/pnpm
|
||||||
|
|
||||||
# additional_hostnames:
|
# additional_hostnames:
|
||||||
# - somename
|
# - somename
|
||||||
@@ -119,7 +155,7 @@ nodejs_version: "18"
|
|||||||
|
|
||||||
# ddev_version_constraint: ""
|
# ddev_version_constraint: ""
|
||||||
# Example:
|
# Example:
|
||||||
# ddev_version_constraint: ">= 1.22.4"
|
# ddev_version_constraint: ">= 1.24.8"
|
||||||
# This will enforce that the running ddev version is within this constraint.
|
# This will enforce that the running ddev version is within this constraint.
|
||||||
# See https://github.com/Masterminds/semver#checking-version-constraints for
|
# See https://github.com/Masterminds/semver#checking-version-constraints for
|
||||||
# supported constraint formats
|
# supported constraint formats
|
||||||
@@ -146,10 +182,8 @@ nodejs_version: "18"
|
|||||||
# - "global": uses the value from the global config.
|
# - "global": uses the value from the global config.
|
||||||
# - "none": disables performance optimization for this project.
|
# - "none": disables performance optimization for this project.
|
||||||
# - "mutagen": enables Mutagen for this project.
|
# - "mutagen": enables Mutagen for this project.
|
||||||
# - "nfs": enables NFS for this project.
|
|
||||||
#
|
#
|
||||||
# See https://ddev.readthedocs.io/en/latest/users/install/performance/#nfs
|
# See https://docs.ddev.com/en/stable/users/install/performance/#mutagen
|
||||||
# See https://ddev.readthedocs.io/en/latest/users/install/performance/#mutagen
|
|
||||||
|
|
||||||
# fail_on_hook_fail: False
|
# fail_on_hook_fail: False
|
||||||
# Decide whether 'ddev start' should be interrupted by a failing hook
|
# Decide whether 'ddev start' should be interrupted by a failing hook
|
||||||
@@ -178,10 +212,10 @@ nodejs_version: "18"
|
|||||||
# The mailpit port is not normally bound on the host at all, instead being routed
|
# The mailpit port is not normally bound on the host at all, instead being routed
|
||||||
# through ddev-router, but it can be bound directly to localhost if specified here.
|
# through ddev-router, but it can be bound directly to localhost if specified here.
|
||||||
|
|
||||||
# webimage_extra_packages: [php7.4-tidy, php-bcmath]
|
# webimage_extra_packages: ['php${DDEV_PHP_VERSION}-tidy', 'php${DDEV_PHP_VERSION}-yac']
|
||||||
# Extra Debian packages that are needed in the webimage can be added here
|
# Extra Debian packages that are needed in the webimage can be added here
|
||||||
|
|
||||||
# dbimage_extra_packages: [telnet,netcat]
|
# dbimage_extra_packages: [netcat, telnet, sudo]
|
||||||
# Extra Debian packages that are needed in the dbimage can be added here
|
# Extra Debian packages that are needed in the dbimage can be added here
|
||||||
|
|
||||||
# use_dns_when_possible: true
|
# use_dns_when_possible: true
|
||||||
@@ -193,22 +227,25 @@ nodejs_version: "18"
|
|||||||
# project_tld: ddev.site
|
# project_tld: ddev.site
|
||||||
# The top-level domain used for project URLs
|
# The top-level domain used for project URLs
|
||||||
# The default "ddev.site" allows DNS lookup via a wildcard
|
# The default "ddev.site" allows DNS lookup via a wildcard
|
||||||
# If you prefer you can change this to "ddev.local" to preserve
|
|
||||||
# pre-v1.9 behavior.
|
|
||||||
|
|
||||||
# ngrok_args: --basic-auth username:pass1234
|
# share_default_provider: ngrok
|
||||||
# Provide extra flags to the "ngrok http" command, see
|
# The default share provider to use for "ddev share"
|
||||||
# https://ngrok.com/docs/ngrok-agent/config or run "ngrok http -h"
|
# Defaults to global configuration, usually "ngrok"
|
||||||
|
# Can be "ngrok" or "cloudflared" or the name of a custom provider from .ddev/share-providers/
|
||||||
|
|
||||||
|
# share_provider_args: --basic-auth username:pass1234
|
||||||
|
# Provide extra flags to the share provider script
|
||||||
|
# See https://docs.ddev.com/en/stable/users/configuration/config/#share_provider_args
|
||||||
|
|
||||||
# disable_settings_management: false
|
# disable_settings_management: false
|
||||||
# If true, DDEV will not create CMS-specific settings files like
|
# If true, DDEV will not create CMS-specific settings files like
|
||||||
# Drupal's settings.php/settings.ddev.php or TYPO3's AdditionalConfiguration.php
|
# Drupal's settings.php/settings.ddev.php or TYPO3's additional.php
|
||||||
# In this case the user must provide all such settings.
|
# In this case the user must provide all such settings.
|
||||||
|
|
||||||
# You can inject environment variables into the web container with:
|
# You can inject environment variables into the web container with:
|
||||||
# web_environment:
|
# web_environment:
|
||||||
# - SOMEENV=somevalue
|
# - SOMEENV=somevalue
|
||||||
# - SOMEOTHERENV=someothervalue
|
# - SOMEOTHERENV=someothervalue
|
||||||
|
|
||||||
# no_project_mount: false
|
# no_project_mount: false
|
||||||
# (Experimental) If true, DDEV will not mount the project into the web container;
|
# (Experimental) If true, DDEV will not mount the project into the web container;
|
||||||
@@ -260,7 +297,7 @@ nodejs_version: "18"
|
|||||||
# override_config: false
|
# override_config: false
|
||||||
# By default, config.*.yaml files are *merged* into the configuration
|
# By default, config.*.yaml files are *merged* into the configuration
|
||||||
# But this means that some things can't be overridden
|
# But this means that some things can't be overridden
|
||||||
# For example, if you have 'use_dns_when_possible: true'' you can't override it with a merge
|
# For example, if you have 'use_dns_when_possible: true' you can't override it with a merge
|
||||||
# and you can't erase existing hooks or all environment variables.
|
# and you can't erase existing hooks or all environment variables.
|
||||||
# However, with "override_config: true" in a particular config.*.yaml file,
|
# However, with "override_config: true" in a particular config.*.yaml file,
|
||||||
# 'use_dns_when_possible: false' can override the existing values, and
|
# 'use_dns_when_possible: false' can override the existing values, and
|
||||||
@@ -270,13 +307,13 @@ nodejs_version: "18"
|
|||||||
# web_environment: []
|
# web_environment: []
|
||||||
# or
|
# or
|
||||||
# additional_hostnames: []
|
# additional_hostnames: []
|
||||||
# can have their intended affect. 'override_config' affects only behavior of the
|
# can have their intended effect. 'override_config' affects only behavior of the
|
||||||
# config.*.yaml file it exists in.
|
# config.*.yaml file it exists in.
|
||||||
|
|
||||||
# Many DDEV commands can be extended to run tasks before or after the
|
# Many DDEV commands can be extended to run tasks before or after the
|
||||||
# DDEV command is executed, for example "post-start", "post-import-db",
|
# DDEV command is executed, for example "post-start", "post-import-db",
|
||||||
# "pre-composer", "post-composer"
|
# "pre-composer", "post-composer"
|
||||||
# See https://ddev.readthedocs.io/en/stable/users/extend/custom-commands/ for more
|
# See https://docs.ddev.com/en/stable/users/extend/custom-commands/ for more
|
||||||
# information on the commands that can be extended and the tasks you can define
|
# information on the commands that can be extended and the tasks you can define
|
||||||
# for them. Example:
|
# for them. Example:
|
||||||
#hooks:
|
#hooks:
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
# http://download.redis.io/redis-stable/redis.conf
|
# http://download.redis.io/redis-stable/redis.conf
|
||||||
# http://download.redis.io/redis-stable/sentinel.conf
|
# http://download.redis.io/redis-stable/sentinel.conf
|
||||||
|
|
||||||
maxmemory 2048mb
|
maxmemory 128mb
|
||||||
maxmemory-policy allkeys-lfu
|
maxmemory-policy allkeys-lru
|
||||||
|
|
||||||
# to disable Redis persistence, remove ddev-generated from this file,
|
# to disable Redis persistence, remove ddev-generated from this file,
|
||||||
# and uncomment the two lines below:
|
# and uncomment the two lines below:
|
||||||
|
|||||||
-3284
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -15,6 +15,7 @@
|
|||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-libxml": "*",
|
"ext-libxml": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
"ext-redis": "*",
|
||||||
"ext-simplexml": "*",
|
"ext-simplexml": "*",
|
||||||
"b13/container": "^1.3",
|
"b13/container": "^1.3",
|
||||||
"blueways/bw-captcha": "^3.1",
|
"blueways/bw-captcha": "^3.1",
|
||||||
@@ -97,7 +98,7 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"sort-packages": true,
|
"sort-packages": true,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "7.4.13"
|
"php": "7.4.33"
|
||||||
},
|
},
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
"typo3/cms-composer-installers": true,
|
"typo3/cms-composer-installers": true,
|
||||||
|
|||||||
Generated
+37
-35
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "e3a433b77a2142f116e57b54c4172ffa",
|
"content-hash": "38fb94ebf504e8413d37c94f929e4b47",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "b13/container",
|
"name": "b13/container",
|
||||||
@@ -1817,21 +1817,22 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "league/oauth2-client",
|
"name": "league/oauth2-client",
|
||||||
"version": "2.9.0",
|
"version": "2.9.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/thephpleague/oauth2-client.git",
|
"url": "https://github.com/thephpleague/oauth2-client.git",
|
||||||
"reference": "26e8c5da4f3d78cede7021e09b1330a0fc093d5e"
|
"reference": "8cedfef9d01a8d1fd2ecfabb41734b17592c4b71"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/26e8c5da4f3d78cede7021e09b1330a0fc093d5e",
|
"url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/8cedfef9d01a8d1fd2ecfabb41734b17592c4b71",
|
||||||
"reference": "26e8c5da4f3d78cede7021e09b1330a0fc093d5e",
|
"reference": "8cedfef9d01a8d1fd2ecfabb41734b17592c4b71",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"guzzlehttp/guzzle": "^6.5.8 || ^7.4.5",
|
"guzzlehttp/guzzle": "^6.5.8 || ^7.8.2 || ^8.0",
|
||||||
|
"guzzlehttp/psr7": "^1.9.1 || ^2.6.3 || ^3.0",
|
||||||
"php": "^7.1 || >=8.0.0 <8.6.0"
|
"php": "^7.1 || >=8.0.0 <8.6.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@@ -1876,9 +1877,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/thephpleague/oauth2-client/issues",
|
"issues": "https://github.com/thephpleague/oauth2-client/issues",
|
||||||
"source": "https://github.com/thephpleague/oauth2-client/tree/2.9.0"
|
"source": "https://github.com/thephpleague/oauth2-client/tree/2.9.1"
|
||||||
},
|
},
|
||||||
"time": "2025-11-25T22:17:17+00:00"
|
"time": "2026-09-16T13:14:31+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "league/period",
|
"name": "league/period",
|
||||||
@@ -2121,24 +2122,24 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "masterminds/html5",
|
"name": "masterminds/html5",
|
||||||
"version": "2.10.1",
|
"version": "2.11.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Masterminds/html5-php.git",
|
"url": "https://github.com/Masterminds/html5-php.git",
|
||||||
"reference": "fd5018f6815fff903946d0564977b44ce8010e29"
|
"reference": "a1e7a2f88ee13635d86fc61cfbdf2306a76ddfc7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fd5018f6815fff903946d0564977b44ce8010e29",
|
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/a1e7a2f88ee13635d86fc61cfbdf2306a76ddfc7",
|
||||||
"reference": "fd5018f6815fff903946d0564977b44ce8010e29",
|
"reference": "a1e7a2f88ee13635d86fc61cfbdf2306a76ddfc7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
"php": ">=5.3.0"
|
"php": ">=7.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9 || ^10"
|
"phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
@@ -2182,9 +2183,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||||
"source": "https://github.com/Masterminds/html5-php/tree/2.10.1"
|
"source": "https://github.com/Masterminds/html5-php/tree/2.11.0"
|
||||||
},
|
},
|
||||||
"time": "2026-06-23T18:43:15+00:00"
|
"time": "2026-08-18T06:18:41+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
@@ -2641,16 +2642,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpdoc-parser",
|
"name": "phpstan/phpdoc-parser",
|
||||||
"version": "2.3.3",
|
"version": "2.3.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||||
"reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3"
|
"reference": "148cefffaf0233e4c08cc13db8a195a56dd6dfe9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fb19eedd2bb67ff8cf7a5502ad329e701d6398a3",
|
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/148cefffaf0233e4c08cc13db8a195a56dd6dfe9",
|
||||||
"reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3",
|
"reference": "148cefffaf0233e4c08cc13db8a195a56dd6dfe9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2682,9 +2683,9 @@
|
|||||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.3"
|
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.5"
|
||||||
},
|
},
|
||||||
"time": "2026-07-08T07:01:06+00:00"
|
"time": "2026-08-31T16:05:28+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/cache",
|
"name": "psr/cache",
|
||||||
@@ -5110,16 +5111,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-idn",
|
"name": "symfony/polyfill-intl-idn",
|
||||||
"version": "v1.38.1",
|
"version": "v1.42.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||||
"reference": "dc21118016c039a66235cf93d96b435ffb282412"
|
"reference": "51b5ff5ba85452b31ec6f55490b08148612339d9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412",
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/51b5ff5ba85452b31ec6f55490b08148612339d9",
|
||||||
"reference": "dc21118016c039a66235cf93d96b435ffb282412",
|
"reference": "51b5ff5ba85452b31ec6f55490b08148612339d9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -5173,7 +5174,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1"
|
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.42.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -5193,20 +5194,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-05-25T15:22:23+00:00"
|
"time": "2026-08-24T10:51:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-normalizer",
|
"name": "symfony/polyfill-intl-normalizer",
|
||||||
"version": "v1.38.0",
|
"version": "v1.42.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||||
"reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b"
|
"reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b",
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/aa20edea75bd9c48cfecc8360922e5a6e5c44502",
|
||||||
"reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b",
|
"reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -5258,7 +5259,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0"
|
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.42.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -5278,7 +5279,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-05-25T13:48:31+00:00"
|
"time": "2026-08-07T06:33:24+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
@@ -9647,11 +9648,12 @@
|
|||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-libxml": "*",
|
"ext-libxml": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
"ext-redis": "*",
|
||||||
"ext-simplexml": "*"
|
"ext-simplexml": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": {},
|
||||||
"platform-overrides": {
|
"platform-overrides": {
|
||||||
"php": "7.4.13"
|
"php": "7.4.33"
|
||||||
},
|
},
|
||||||
"plugin-api-version": "2.9.0"
|
"plugin-api-version": "2.9.0"
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-12
@@ -63,41 +63,39 @@ host('prod')
|
|||||||
->setForwardAgent(true)
|
->setForwardAgent(true)
|
||||||
->setSshMultiplexing(true)
|
->setSshMultiplexing(true)
|
||||||
->setDeployPath('/usr/home/eptypo3/public_html/{{application}}')
|
->setDeployPath('/usr/home/eptypo3/public_html/{{application}}')
|
||||||
->set('buspronet_path', '/usr/home/eptypo3/public_html/kuschick/buspronet/buspronet')
|
|
||||||
->set('bin/php', '/usr/bin/php74')
|
->set('bin/php', '/usr/bin/php74')
|
||||||
->set('http_user', 'eptypo3')
|
->set('http_user', 'eptypo3')
|
||||||
->set('writable_mode', 'chmod')
|
->set('writable_mode', 'chmod')
|
||||||
->set('bin/composer', '/usr/bin/composer')
|
|
||||||
->set('composer_options', '--prefer-dist --no-progress --no-interaction --optimize-autoloader')
|
|
||||||
->set('rsync_src', __DIR__)
|
->set('rsync_src', __DIR__)
|
||||||
->set('rsync', $rsyncOptions)
|
->set('rsync', $rsyncOptions)
|
||||||
->set('cachetool_args', '--web=SymfonyHttpClient --web-path={{current_path}}/public/ --web-url=https://www.ep-reisen.de')
|
->set('cachetool_args', '--web=SymfonyHttpClient --web-path={{current_path}}/{{typo3_webroot}}/ --web-url=https://www.ep-reisen.de')
|
||||||
;
|
;
|
||||||
|
|
||||||
task('deploy', [
|
task('deploy', [
|
||||||
'deploy:info',
|
'deploy:info',
|
||||||
|
// Build locally first, so a failing build aborts before the server is touched at all.
|
||||||
|
'deploy:assets:build',
|
||||||
'deploy:setup',
|
'deploy:setup',
|
||||||
'deploy:lock',
|
'deploy:lock',
|
||||||
'deploy:release',
|
'deploy:release',
|
||||||
'deploy:assets:build',
|
|
||||||
'rsync',
|
'rsync',
|
||||||
'deploy:shared',
|
'deploy:shared',
|
||||||
'deploy:writable',
|
'deploy:writable',
|
||||||
|
// The schema has to exist before the new code starts serving traffic.
|
||||||
'typo3:database:migrate',
|
'typo3:database:migrate',
|
||||||
'typo3:language:update',
|
'typo3:language:update',
|
||||||
|
// deploy:publish == deploy:symlink, deploy:unlock, deploy:cleanup, deploy:success
|
||||||
'deploy:publish',
|
'deploy:publish',
|
||||||
'cachetool:clear:opcache',
|
|
||||||
'typo3:cache:flush',
|
|
||||||
'deploy:buspronet:symlink',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
task('deploy:buspronet:symlink', function () {
|
// Caches belong to the release that goes live, so they are cleared after the symlink flip. Hooking
|
||||||
run('ln -s {{buspronet_path}} {{release_or_current_path}}/public/buchung');
|
// into deploy:symlink rather than appending to the list above keeps them inside deploy:publish, ahead
|
||||||
});
|
// of deploy:unlock and deploy:success - a failing cache task must not follow a declared success.
|
||||||
|
after('deploy:symlink', 'cachetool:clear:opcache');
|
||||||
|
after('deploy:symlink', 'typo3:cache:flush');
|
||||||
|
|
||||||
task ('deploy:assets:build', function () {
|
task ('deploy:assets:build', function () {
|
||||||
runLocally('ddev exec npm ci');
|
runLocally('ddev exec npm ci');
|
||||||
runLocally('ddev exec npm rebuild node-sass');
|
|
||||||
runLocally('ddev exec npm run build');
|
runLocally('ddev exec npm run build');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Generated
+1415
-1608
File diff suppressed because it is too large
Load Diff
+9
-23
@@ -1,62 +1,48 @@
|
|||||||
{
|
{
|
||||||
"name": "eptheme",
|
"name": "eptheme",
|
||||||
"description": "EP Reisen TYPO3 website package",
|
|
||||||
"version": "3.0.0",
|
|
||||||
"author": "Björn Fromme, [email protected]",
|
|
||||||
"license": "proprietary",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "./node_modules/.bin/encore dev --watch",
|
"dev": "./node_modules/.bin/encore dev --watch",
|
||||||
"build": "NODE_ENV=production ./node_modules/.bin/encore production"
|
"build": "NODE_ENV=production ./node_modules/.bin/encore production"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16"
|
"node": ">=20.19.0"
|
||||||
},
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"defaults"
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hotwired/stimulus": "^3.2.1",
|
"@hotwired/stimulus": "^3.2.1",
|
||||||
"@hotwired/stimulus-webpack-helpers": "^1.0.1",
|
"@hotwired/stimulus-webpack-helpers": "^1.0.1",
|
||||||
"@iframe-resizer/parent": "^5.3.2",
|
"@iframe-resizer/parent": "^5.3.2",
|
||||||
"@splidejs/splide": "^2.4.21",
|
"@splidejs/splide": "^2.4.21",
|
||||||
"axios": "^1.6.2",
|
|
||||||
"cooltipz-css": "^1.6.8",
|
"cooltipz-css": "^1.6.8",
|
||||||
"dayjs": "^1.10.6",
|
"dayjs": "^1.10.6",
|
||||||
"es6-slide-up-down": "^1.0.0",
|
|
||||||
"flatpickr": "^4.6.9",
|
"flatpickr": "^4.6.9",
|
||||||
"glightbox": "^3.0.9",
|
"glightbox": "^3.0.9",
|
||||||
"htmx.org": "^1.9.12",
|
"htmx.org": "^1.9.12",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"lazysizes": "^5.3.2",
|
|
||||||
"leaflet": "^1.7.1",
|
"leaflet": "^1.7.1",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"picturefill": "^3.0.3",
|
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
"sticky-js": "^1.3.0",
|
"sticky-js": "^1.3.0",
|
||||||
"stimulus-use": "^0.52.0",
|
"stimulus-use": "^0.52.0",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-router": "^3.5.2",
|
"vue-session": "^1.0.0"
|
||||||
"vue-session": "^1.0.0",
|
|
||||||
"vuex": "^3.6.2",
|
|
||||||
"whatwg-fetch": "^3.6.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-object-rest-spread": "^7.16.0",
|
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
||||||
"@babel/preset-env": "^7.16.0",
|
"@babel/preset-env": "^7.16.0",
|
||||||
"@symfony/webpack-encore": "^2.1.0",
|
"@symfony/webpack-encore": "^4.7.0",
|
||||||
"@tailwindcss/aspect-ratio": "^0.4.0",
|
"@tailwindcss/aspect-ratio": "^0.4.0",
|
||||||
"@tailwindcss/forms": "^0.5.2",
|
"@tailwindcss/forms": "^0.5.2",
|
||||||
"autoprefixer": "^10.4.8",
|
"autoprefixer": "^10.4.8",
|
||||||
"core-js": "^3.22.5",
|
|
||||||
"document-register-element": "^1.14.10",
|
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"postcss": "^8.4.16",
|
"postcss": "^8.4.16",
|
||||||
"postcss-loader": "^6.2.1",
|
"postcss-loader": "^8.2.1",
|
||||||
"sass": "^1.53.0",
|
"sass": "^1.53.0",
|
||||||
"sass-loader": "^12.6.0",
|
"sass-loader": "^14.2.1",
|
||||||
"sass-mq": "^6.0.0",
|
"sass-mq": "^7.0.1",
|
||||||
"smoothscroll-polyfill": "^0.4.4",
|
|
||||||
"tailwindcss": "^3.1.8",
|
"tailwindcss": "^3.1.8",
|
||||||
"tailwindcss-alt": "^3.0.0",
|
"tailwindcss-alt": "^3.0.0",
|
||||||
"vue-custom-element": "^3.3.0",
|
|
||||||
"vue-loader": "^15.11.1",
|
"vue-loader": "^15.11.1",
|
||||||
"vue-template-compiler": "^2.6.14"
|
"vue-template-compiler": "^2.6.14"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,24 +47,49 @@ if (getenv('IS_DDEV_PROJECT') == 'true') {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_pages'] = [
|
// Fail fast instead of blocking indefinitely when redis is unreachable.
|
||||||
|
$redisOptions['connectionTimeout'] = 2;
|
||||||
|
|
||||||
|
// Note: the cache identifiers must stay unprefixed ('pages', not 'cache_pages'). These
|
||||||
|
// assignments replace the definitions from LocalConfiguration.php wholesale, so 'groups'
|
||||||
|
// and the compression/lifetime options have to be repeated here.
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['pages'] = [
|
||||||
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||||
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||||
'options' => $redisOptions + ['database' => 0],
|
'options' => $redisOptions + [
|
||||||
|
'database' => 0,
|
||||||
|
'compression' => true,
|
||||||
|
],
|
||||||
|
'groups' => ['pages'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_hash'] = [
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['hash'] = [
|
||||||
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||||
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||||
'options' => $redisOptions + ['database' => 1],
|
'options' => $redisOptions + [
|
||||||
|
'database' => 1,
|
||||||
|
],
|
||||||
|
'groups' => ['pages'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_rootline'] = [
|
// Own database: RedisBackend::flush() issues FLUSHDB and the keys carry no per-cache
|
||||||
|
// prefix, so two caches sharing a database flush each other.
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['rootline'] = [
|
||||||
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||||
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||||
'options' => $redisOptions + ['database' => 1],
|
'options' => $redisOptions + [
|
||||||
|
'database' => 2,
|
||||||
|
'compression' => true,
|
||||||
|
'defaultLifetime' => 2592000,
|
||||||
|
],
|
||||||
|
'groups' => ['pages'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Assets are served through the bunny.net CDN, which gzip/brotli-compresses at the edge.
|
||||||
|
// Pre-gzipped .gzip twins are served with Content-Encoding: gzip and cannot be processed
|
||||||
|
// by the CDN, so stop generating them. mod_deflate still compresses direct origin hits.
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] = 0;
|
||||||
|
|
||||||
// suppress php deprecation warnings flooding typo3 logs
|
// suppress php deprecation warnings flooding typo3 logs
|
||||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'] =
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'] =
|
||||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'] & ~E_DEPRECATED & ~E_USER_DEPRECATED;
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'] & ~E_DEPRECATED & ~E_USER_DEPRECATED;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -53,6 +54,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -50,6 +51,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -51,6 +52,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -52,6 +53,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -64,6 +65,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -449,6 +451,7 @@ return [
|
|||||||
'label' => 'Ansprechpartner',
|
'label' => 'Ansprechpartner',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epevents_domain_model_contact',
|
'foreign_table' => 'tx_epevents_domain_model_contact',
|
||||||
'foreign_table_where' => 'AND 1=1 order by name',
|
'foreign_table_where' => 'AND 1=1 order by name',
|
||||||
@@ -461,6 +464,7 @@ return [
|
|||||||
'label' => 'Unterkunft',
|
'label' => 'Unterkunft',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epevents_domain_model_hotel',
|
'foreign_table' => 'tx_epevents_domain_model_hotel',
|
||||||
'foreign_table_where' => 'AND 1=1 order by name',
|
'foreign_table_where' => 'AND 1=1 order by name',
|
||||||
@@ -473,6 +477,7 @@ return [
|
|||||||
'label' => 'Location',
|
'label' => 'Location',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epevents_domain_model_location',
|
'foreign_table' => 'tx_epevents_domain_model_location',
|
||||||
'foreign_table_where' => 'AND 1=1 order by name',
|
'foreign_table_where' => 'AND 1=1 order by name',
|
||||||
|
|||||||
+2
@@ -35,6 +35,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -49,6 +50,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+4
-2
@@ -38,6 +38,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -52,12 +53,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epevents_domain_model_offer',
|
'foreign_table' => 'tx_epevents_domain_model_traveltype',
|
||||||
'foreign_table_where' => 'AND tx_epevents_domain_model_offer.pid=###CURRENT_PID### AND tx_epevents_domain_model_offer.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epevents_domain_model_traveltype.pid=###CURRENT_PID### AND tx_epevents_domain_model_traveltype.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ import Vue from 'vue'
|
|||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
import VueSession from 'vue-session'
|
import VueSession from 'vue-session'
|
||||||
|
|
||||||
import 'lazysizes';
|
|
||||||
import 'lazysizes/plugins/attrchange/ls.attrchange';
|
|
||||||
|
|
||||||
const slick = require('slick-carousel');
|
const slick = require('slick-carousel');
|
||||||
const Sticky = require('sticky-js');
|
const Sticky = require('sticky-js');
|
||||||
const $window = $(window);
|
const $window = $(window);
|
||||||
|
|||||||
+17
-10
@@ -38,9 +38,9 @@
|
|||||||
<div class="card card--no-form offerlist-item__card">
|
<div class="card card--no-form offerlist-item__card">
|
||||||
<div class="card__inner">
|
<div class="card__inner">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(max-width: 512px)" :data-srcset="offer.teaserImageMobile + ' 500w'"/>
|
<source media="(max-width: 512px)" :srcset="offer.teaserImageMobile"/>
|
||||||
<img class="card__image scale lazyload" data-sizes="auto"
|
<img class="card__image scale"
|
||||||
:data-src="offer.teaserImage" alt="">
|
:src="offer.teaserImage" alt="" loading="lazy">
|
||||||
</picture>
|
</picture>
|
||||||
<div class="card__caption">
|
<div class="card__caption">
|
||||||
<span class="card__subtitle" v-html="offer.name"></span>
|
<span class="card__subtitle" v-html="offer.name"></span>
|
||||||
@@ -55,7 +55,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -82,13 +81,21 @@
|
|||||||
load() {
|
load() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
sessionStorage.setItem('filterSettings', JSON.stringify(this.filterSettings));
|
sessionStorage.setItem('filterSettings', JSON.stringify(this.filterSettings));
|
||||||
axios({
|
fetch(this.endpointUri, {
|
||||||
url: this.endpointUri,
|
method: 'POST',
|
||||||
method: 'post',
|
credentials: 'same-origin',
|
||||||
data: $.param({'tx_epevents_ajax[filterSettings]': this.filterSettings})
|
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
|
||||||
|
body: $.param({'tx_epevents_ajax[filterSettings]': this.filterSettings})
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
this.offers = response.data.offers;
|
// fetch only rejects on network errors, so surface HTTP errors here
|
||||||
this.filterOptions = response.data.filterOptions;
|
// to keep the previous behaviour of falling through to .catch()
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}).then(data => {
|
||||||
|
this.offers = data.offers;
|
||||||
|
this.filterOptions = data.filterOptions;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
@@ -27,15 +30,15 @@
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 130%;
|
line-height: 130%;
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge__outline {
|
.badge__outline {
|
||||||
@include sectionFills(0.15);
|
@include mixins.sectionFills(0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge__inner {
|
.badge__inner {
|
||||||
@include sectionFills();
|
@include mixins.sectionFills();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@use "mixins";
|
||||||
|
|
||||||
.banner {
|
.banner {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
@@ -8,7 +10,7 @@
|
|||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
padding: 48px 0;
|
padding: 48px 0;
|
||||||
color: white;
|
color: white;
|
||||||
@include sectionBackgrounds(0.8);
|
@include mixins.sectionBackgrounds(0.8);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
@use "fonts";
|
||||||
|
@use "mixins";
|
||||||
|
@use "variables";
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: $font-main, Sans-Serif;
|
font-family: fonts.$font-main, Sans-Serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,13 +47,13 @@ html {
|
|||||||
height: auto;
|
height: auto;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.navtoggle__icon {
|
.navtoggle__icon {
|
||||||
fill: $color-font-main;
|
fill: colors.$color-font-main;
|
||||||
transition: all 0.25s ease-in-out;
|
transition: all 0.25s ease-in-out;
|
||||||
|
|
||||||
.mobilenav--open & {
|
.mobilenav--open & {
|
||||||
@@ -62,7 +68,7 @@ html {
|
|||||||
right: 2%;
|
right: 2%;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,12 +82,12 @@ a {
|
|||||||
&.anchor {
|
&.anchor {
|
||||||
display: block;
|
display: block;
|
||||||
height: 0;
|
height: 0;
|
||||||
padding-top: $header-height-mobile;
|
padding-top: variables.$header-height-mobile;
|
||||||
margin-top: -$header-height-mobile;
|
margin-top: -(variables.$header-height-mobile);
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding-top: $header-height-desktop;
|
padding-top: variables.$header-height-desktop;
|
||||||
margin-top: -$header-height-desktop;
|
margin-top: -(variables.$header-height-desktop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +132,7 @@ ul {
|
|||||||
left: 0;
|
left: 0;
|
||||||
content: "\25CF";
|
content: "\25CF";
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@include sectionColoursFromParent();
|
@include mixins.sectionColoursFromParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,8 +150,8 @@ p {
|
|||||||
hr {
|
hr {
|
||||||
max-width: 25%;
|
max-width: 25%;
|
||||||
margin: 32px auto 32px 0;
|
margin: 32px auto 32px 0;
|
||||||
color: $color-ruler;
|
color: colors.$color-ruler;
|
||||||
background-color: $color-ruler;
|
background-color: colors.$color-ruler;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
@@ -161,7 +167,7 @@ h3,
|
|||||||
}
|
}
|
||||||
|
|
||||||
.headline {
|
.headline {
|
||||||
@include sectionColoursFromParent();
|
@include mixins.sectionColoursFromParent();
|
||||||
|
|
||||||
&--icon {
|
&--icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -186,7 +192,7 @@ h1,
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
padding-bottom: 18px;
|
padding-bottom: 18px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
}
|
}
|
||||||
@@ -200,11 +206,11 @@ h1,
|
|||||||
display: block;
|
display: block;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 120%;
|
line-height: 120%;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@include sectionColoursFromParent();
|
@include mixins.sectionColoursFromParent();
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +227,7 @@ h2,
|
|||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
}
|
}
|
||||||
@@ -231,7 +237,7 @@ h3 {
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
@@ -243,7 +249,7 @@ h3 {
|
|||||||
height: auto;
|
height: auto;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
|
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
width: 96px;
|
width: 96px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@@ -13,7 +16,7 @@
|
|||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: $color-brand-secondary;
|
background-color: colors.$color-brand-secondary;
|
||||||
border: none;
|
border: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@@ -23,18 +26,18 @@
|
|||||||
|
|
||||||
.box__content {
|
.box__content {
|
||||||
padding: 32px 16px;
|
padding: 32px 16px;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box__form {
|
.box__form {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
fill: $color-brand-primary;
|
fill: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--top {
|
&--top {
|
||||||
@@ -52,7 +55,7 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
|
|
||||||
@@ -66,7 +69,7 @@
|
|||||||
.box__nav {
|
.box__nav {
|
||||||
margin-top: -32px;
|
margin-top: -32px;
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box__nav__item {
|
.box__nav__item {
|
||||||
@@ -78,7 +81,7 @@
|
|||||||
|
|
||||||
&--active,
|
&--active,
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $color-brand-light;
|
background-color: colors.$color-brand-light;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.brands {
|
.brands {
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
border-top: 1px solid $color-divider;
|
border-top: 1px solid colors.$color-divider;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -9,7 +12,7 @@
|
|||||||
.brands__item {
|
.brands__item {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
$mq-breakpoints: (
|
@use "variables";
|
||||||
mobile: $viewport-width-mobile,
|
|
||||||
tablet: $viewport-width-tablet,
|
|
||||||
desktop: $viewport-width-desktop
|
|
||||||
);
|
|
||||||
|
|
||||||
@import "~sass-mq";
|
@forward "sass-mq" with (
|
||||||
|
$breakpoints: (
|
||||||
|
mobile: variables.$viewport-width-mobile,
|
||||||
|
tablet: variables.$viewport-width-tablet,
|
||||||
|
desktop: variables.$viewport-width-desktop
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -5,7 +9,7 @@
|
|||||||
|
|
||||||
&--default {
|
&--default {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
}
|
}
|
||||||
@@ -13,7 +17,7 @@
|
|||||||
&--page-header {
|
&--page-header {
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 186px;
|
min-width: 186px;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding: 0 32px 0 24px;
|
padding: 0 32px 0 24px;
|
||||||
@@ -26,14 +30,14 @@
|
|||||||
display: block;
|
display: block;
|
||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
@include sectionBackgroundsFromParent();
|
@include mixins.sectionBackgroundsFromParent();
|
||||||
color: white;
|
color: white;
|
||||||
line-height: 48px;
|
line-height: 48px;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
box-shadow: 8px 8px 8px rgba(black, 0.2);
|
box-shadow: 8px 8px 8px rgba(black, 0.2);
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
@@ -43,7 +47,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,7 +60,7 @@
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: white;
|
background: white;
|
||||||
color: $color-font-main;
|
color: colors.$color-font-main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +69,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&--icon {
|
&--icon {
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
&:not(.card--no-form) {
|
&:not(.card--no-form) {
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
}
|
}
|
||||||
@@ -20,12 +23,12 @@
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
color: white;
|
color: white;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@include sectionBackgrounds(0.75);
|
@include mixins.sectionBackgrounds(0.75);
|
||||||
transition: background-color 0.25s ease-in-out;
|
transition: background-color 0.25s ease-in-out;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
.card:hover & {
|
.card:hover & {
|
||||||
@include sectionBackgrounds();
|
@include mixins.sectionBackgrounds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,7 +36,7 @@
|
|||||||
.card__form {
|
.card__form {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
display: block;
|
display: block;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.25s ease-in-out;
|
transition: opacity 0.25s ease-in-out;
|
||||||
@@ -50,7 +53,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
polygon {
|
polygon {
|
||||||
@include sectionFills();
|
@include mixins.sectionFills();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
|
@use "colors";
|
||||||
|
@use "mixins";
|
||||||
|
@use "variables";
|
||||||
|
|
||||||
.carousel {
|
.carousel {
|
||||||
|
|
||||||
&--background {
|
&--background {
|
||||||
background-color: $color-background;
|
background-color: colors.$color-background;
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include sectionBackgrounds(0.25);
|
@include mixins.sectionBackgrounds(0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel__outer {
|
.carousel__outer {
|
||||||
@include container($viewport-width-max);
|
@include mixins.container(variables.$viewport-width-max);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel__inner {
|
.carousel__inner {
|
||||||
@include container($content-width-max);
|
@include mixins.container(variables.$content-width-max);
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel__item {
|
.carousel__item {
|
||||||
@@ -36,7 +40,7 @@
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
|
|
||||||
fill: white;
|
fill: white;
|
||||||
@include sectionColoursFromParent;
|
@include mixins.sectionColoursFromParent;
|
||||||
|
|
||||||
&--prev {
|
&--prev {
|
||||||
left: -5px;
|
left: -5px;
|
||||||
@@ -59,7 +63,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.testimonials & {
|
.testimonials & {
|
||||||
fill: $color-brand-primary;
|
fill: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
@use "sass:color";
|
||||||
|
|
||||||
//$color-brand-primary: #0084d4;
|
//$color-brand-primary: #0084d4;
|
||||||
$color-brand-primary: #19a0d2;
|
$color-brand-primary: #19a0d2;
|
||||||
$color-brand-secondary: #1e314b;
|
$color-brand-secondary: #1e314b;
|
||||||
$color-brand-light: #8CCFE8;
|
$color-brand-light: #8CCFE8;
|
||||||
$color-background: lighten(#dbdee2, 5%);
|
$color-background: color.adjust(#dbdee2, $lightness: 5%);
|
||||||
|
|
||||||
$color-font-main: #1e314b;
|
$color-font-main: #1e314b;
|
||||||
$color-divider: rgba($color-background, 0.8);
|
$color-divider: rgba($color-background, 0.8);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.configurator {
|
.configurator {
|
||||||
background: url(../images/bg_configurator.jpg) no-repeat top left;
|
background: url(../images/bg_configurator.jpg) no-repeat top left;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
@@ -39,7 +42,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: rgba($color-brand-secondary, 0.85);
|
background-color: rgba(colors.$color-brand-secondary, 0.85);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +54,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,11 +86,11 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,12 +101,12 @@
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
@@ -113,11 +116,11 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 70%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,11 +134,11 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,13 +154,13 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
font-family: "fontello";
|
font-family: "fontello";
|
||||||
|
|
||||||
&.closed {
|
&.closed {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: '\e800';
|
content: '\e800';
|
||||||
@@ -204,7 +207,7 @@
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|
||||||
.active & {
|
.active & {
|
||||||
@@ -212,7 +215,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
|
|
||||||
.active & {
|
.active & {
|
||||||
@@ -240,10 +243,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.selected &:after {
|
.selected &:after {
|
||||||
background-color: rgba($color-brand-secondary, 0.75);
|
background-color: rgba(colors.$color-brand-secondary, 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
&:hover:after {
|
&:hover:after {
|
||||||
content: "";
|
content: "";
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -251,7 +254,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
background-color: rgba($color-brand-primary, 0.5);
|
background-color: rgba(colors.$color-brand-primary, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,12 +263,12 @@
|
|||||||
background-position: center 32px;
|
background-position: center 32px;
|
||||||
background-size: 96px;
|
background-size: 96px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
background-position: center 16px;
|
background-position: center 16px;
|
||||||
background-size: 128px;
|
background-size: 128px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
background-position: center 8px;
|
background-position: center 8px;
|
||||||
background-size: 96px;
|
background-size: 96px;
|
||||||
}
|
}
|
||||||
@@ -382,7 +385,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,7 +394,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 66.6666%;
|
width: 66.6666%;
|
||||||
padding-right: 32px;
|
padding-right: 32px;
|
||||||
}
|
}
|
||||||
@@ -401,7 +404,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 33.3333%;
|
width: 33.3333%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -456,7 +459,7 @@
|
|||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
font-family: 'fontello';
|
font-family: 'fontello';
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// .headline* live in _base.scss; @extend needs that module loaded explicitly.
|
||||||
|
@use "base";
|
||||||
|
|
||||||
.cookiefirst {
|
.cookiefirst {
|
||||||
h2 {
|
h2 {
|
||||||
@extend .headline;
|
@extend .headline;
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.form {
|
.form {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
&:not(&--horizontal) {
|
&:not(&--horizontal) {
|
||||||
max-width: 75%;
|
max-width: 75%;
|
||||||
}
|
}
|
||||||
@@ -16,7 +20,7 @@
|
|||||||
|
|
||||||
&--horizontal {
|
&--horizontal {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -42,7 +46,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background-color: $color-brand-light;
|
background-color: colors.$color-brand-light;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
@@ -50,7 +54,7 @@
|
|||||||
&--mobile {
|
&--mobile {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +62,7 @@
|
|||||||
&--tablet {
|
&--tablet {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: tablet, $until: desktop) {
|
@include breakpoints.mq($from: tablet, $until: desktop) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +70,7 @@
|
|||||||
&--desktop {
|
&--desktop {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +83,7 @@
|
|||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 33.3333%;
|
width: 33.3333%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,20 +92,20 @@
|
|||||||
.form__item__error {
|
.form__item__error {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
color: $color-formerror;
|
color: colors.$color-formerror;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form__field {
|
.form__field {
|
||||||
@include nooutline;
|
@include mixins.nooutline;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: $color-brand-light;
|
background-color: colors.$color-brand-light;
|
||||||
|
|
||||||
.form--box & {
|
.form--box & {
|
||||||
background-color: $color-brand-light;
|
background-color: colors.$color-brand-light;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,10 +118,10 @@
|
|||||||
display: block;
|
display: block;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,7 +131,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.has-errors & {
|
.has-errors & {
|
||||||
border: 1px solid $color-formerror;
|
border: 1px solid colors.$color-formerror;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +162,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: $color-brand-secondary;
|
background-color: colors.$color-brand-secondary;
|
||||||
border: none;
|
border: none;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -166,7 +170,7 @@
|
|||||||
padding: 8px 32px;
|
padding: 8px 32px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: auto;
|
width: auto;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
@@ -189,10 +193,10 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: rgba($color-divider, 0.75);
|
background-color: rgba(colors.$color-divider, 0.75);
|
||||||
|
|
||||||
.form--box & {
|
.form--box & {
|
||||||
background-color: rgba($color-brand-primary, 0.75);
|
background-color: rgba(colors.$color-brand-primary, 0.75);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.helpernav {
|
.helpernav {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -24,7 +27,7 @@
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
padding: 16px 32px;
|
padding: 16px 32px;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.helpernav__item {
|
.helpernav__item {
|
||||||
@@ -32,7 +35,7 @@
|
|||||||
&:hover:not(.helpernav__item--disabled) {
|
&:hover:not(.helpernav__item--disabled) {
|
||||||
|
|
||||||
& > .helpernav__link {
|
& > .helpernav__link {
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .helpernav__subnav {
|
& > .helpernav__subnav {
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
@use "mixins";
|
||||||
|
@use "variables";
|
||||||
|
|
||||||
.herounit {
|
.herounit {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: $viewport-width-max;
|
max-width: variables.$viewport-width-max;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
&--indent {
|
&--indent {
|
||||||
max-width: $content-width-max - 16px;
|
max-width: variables.$content-width-max - 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,22 +21,22 @@
|
|||||||
|
|
||||||
height: 240px;
|
height: 240px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
height: 384px;
|
height: 384px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
height: 420px;
|
height: 420px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.herounit--large & {
|
.herounit--large & {
|
||||||
height: 300px;
|
height: 300px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
height: 480px;
|
height: 480px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
height: 700px;
|
height: 700px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +44,7 @@
|
|||||||
.herounit--indent & {
|
.herounit--indent & {
|
||||||
height: 320px;
|
height: 320px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
height: 480px;
|
height: 480px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +53,7 @@
|
|||||||
.herounit__mask {
|
.herounit__mask {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -67,9 +72,9 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
background-color: rgba($color-brand-secondary, 0.2);
|
background-color: rgba(colors.$color-brand-secondary, 0.2);
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding: 64px 16px 0 96px;
|
padding: 64px 16px 0 96px;
|
||||||
max-width: 45%;
|
max-width: 45%;
|
||||||
@@ -83,7 +88,7 @@
|
|||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
line-height: 95%;
|
line-height: 95%;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,10 +106,10 @@
|
|||||||
span {
|
span {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
font-size: 56px;
|
font-size: 56px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +125,7 @@
|
|||||||
color: white;
|
color: white;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,12 +133,12 @@
|
|||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
padding-bottom: 96px;
|
padding-bottom: 96px;
|
||||||
}
|
}
|
||||||
@@ -146,7 +151,7 @@
|
|||||||
line-height: 120%;
|
line-height: 120%;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +159,7 @@
|
|||||||
.herounit__icon {
|
.herounit__icon {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
@@ -173,11 +178,11 @@
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
top: 85%;
|
top: 85%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
@@ -190,34 +195,34 @@
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > polygon {
|
& > polygon {
|
||||||
fill: $color-brand-primary;
|
fill: colors.$color-brand-primary;
|
||||||
@include sectionFills();
|
@include mixins.sectionFills();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#gradient__from {
|
#gradient__from {
|
||||||
stop-color: $color-brand-secondary;
|
stop-color: colors.$color-brand-secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gradient__to {
|
#gradient__to {
|
||||||
.section-default & {
|
.section-default & {
|
||||||
stop-color: $color-brand-primary;
|
stop-color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
.section-incentives & {
|
.section-incentives & {
|
||||||
stop-color: $color-incentives;
|
stop-color: colors.$color-incentives;
|
||||||
}
|
}
|
||||||
.section-teambuilding & {
|
.section-teambuilding & {
|
||||||
stop-color: $color-teambuilding;
|
stop-color: colors.$color-teambuilding;
|
||||||
}
|
}
|
||||||
.secolor-meeting & {
|
.secolor-meeting & {
|
||||||
stop-color: $color-meetings;
|
stop-color: colors.$color-meetings;
|
||||||
}
|
}
|
||||||
.secolor-events & {
|
.secolor-events & {
|
||||||
stop-color: $color-events;
|
stop-color: colors.$color-events;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.iconbar {
|
.iconbar {
|
||||||
@apply hidden lg:block fixed z-100 top-[30vh] right-0 overflow-hidden;
|
@apply hidden lg:block fixed z-100 top-[30vh] right-0 overflow-hidden;
|
||||||
}
|
}
|
||||||
.iconbar {
|
.iconbar {
|
||||||
display: none;
|
display: none;
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -20,7 +23,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: $color-brand-light;
|
background-color: colors.$color-brand-light;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@@ -30,7 +33,7 @@
|
|||||||
|
|
||||||
.iconbar__icon {
|
.iconbar__icon {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.iconnav {
|
.iconnav {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -21,7 +24,7 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,5 +39,5 @@
|
|||||||
.iconnav__label {
|
.iconnav__label {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@include sectionColours();
|
@include mixins.sectionColours();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
main {
|
main {
|
||||||
padding-top: 96px;
|
padding-top: 96px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding-top: 140px;
|
padding-top: 140px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +13,7 @@ main {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
@include clearfix();
|
@include mixins.clearfix();
|
||||||
|
|
||||||
&.nopad {
|
&.nopad {
|
||||||
&--bottom {
|
&--bottom {
|
||||||
@@ -23,18 +26,18 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content__title {
|
.content__title {
|
||||||
@include container();
|
@include mixins.container();
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__inner {
|
.content__inner {
|
||||||
@include container();
|
@include mixins.container();
|
||||||
|
|
||||||
.content--has-sidebar & {
|
.content--has-sidebar & {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,40 +48,40 @@ main {
|
|||||||
padding: 0 0 32px;
|
padding: 0 0 32px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__plain {
|
.content__plain {
|
||||||
@include clearfix();
|
@include mixins.clearfix();
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding-right: 96px;
|
padding-right: 96px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__background {
|
.content__background {
|
||||||
@include clearfix();
|
@include mixins.clearfix();
|
||||||
@include sectionBackgrounds(0.15);
|
@include mixins.sectionBackgrounds(0.15);
|
||||||
padding: 24px 48px 24px 32px;
|
padding: 24px 48px 24px 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__float {
|
.content__float {
|
||||||
@include clearfix();
|
@include mixins.clearfix();
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__sidebar {
|
.content__sidebar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 32px 0;
|
padding: 32px 0;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
flex: 0 0 320px;
|
flex: 0 0 320px;
|
||||||
padding: 0 0 0 32px;
|
padding: 0 0 0 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__form {
|
.content__form {
|
||||||
@include sectionFills(0.15);
|
@include mixins.sectionFills(0.15);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -93,7 +96,7 @@ main {
|
|||||||
|
|
||||||
.desktop-only {
|
.desktop-only {
|
||||||
display: none;
|
display: none;
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
@use "sass:math";
|
@use "sass:math";
|
||||||
|
@use "variables" as *;
|
||||||
|
@use "colors" as *;
|
||||||
|
|
||||||
@mixin clearfix {
|
@mixin clearfix {
|
||||||
&::after {
|
&::after {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.mobilenav {
|
.mobilenav {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
@@ -7,10 +10,10 @@
|
|||||||
height: 0;
|
height: 0;
|
||||||
padding-top: 96px;
|
padding-top: 96px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: rgba($color-brand-secondary, 0.9);
|
background: rgba(colors.$color-brand-secondary, 0.9);
|
||||||
transition: height 0.25s ease-in-out;
|
transition: height 0.25s ease-in-out;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
|
||||||
.news-entry {
|
.news-entry {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
@@ -13,7 +15,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,7 +24,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +41,7 @@
|
|||||||
.news-entry__teaser {
|
.news-entry__teaser {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
padding-left: 24px;
|
padding-left: 24px;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
|
||||||
.offerlist {
|
.offerlist {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -13,7 +15,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.offerlist__teasers {
|
.offerlist__teasers {
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
@@ -24,13 +26,13 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
display: block;
|
display: block;
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 33.3333%;
|
width: 33.3333%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,30 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
@use "mixins";
|
||||||
|
@use "variables";
|
||||||
|
|
||||||
.page-footer {
|
.page-footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(to right, $color-brand-secondary, $color-brand-primary);
|
background: linear-gradient(to right, colors.$color-brand-secondary, colors.$color-brand-primary);
|
||||||
color: white;
|
color: white;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
|
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
padding-top: 48px;
|
padding-top: 48px;
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-footer__inner {
|
.page-footer__inner {
|
||||||
@include container($content-width-max);
|
@include mixins.container(variables.$content-width-max);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-bottom: 1px solid white;
|
border-bottom: 1px solid white;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,14 +38,14 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--hide-mobile {
|
&--hide-mobile {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,14 +65,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page-footer__bottom {
|
.page-footer__bottom {
|
||||||
@include container($content-width-max);
|
@include mixins.container(variables.$content-width-max);
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
@@ -76,7 +81,7 @@
|
|||||||
.page-footer__bottom__column {
|
.page-footer__bottom__column {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 33.3333%;
|
width: 33.3333%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +91,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +111,7 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +120,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
@@ -138,7 +143,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -5,28 +9,28 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
background: white;
|
background: white;
|
||||||
box-shadow: 0 2px 2px rgba($color-background, 0.5);
|
box-shadow: 0 2px 2px rgba(colors.$color-background, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header__bar {
|
.page-header__bar {
|
||||||
background: linear-gradient(to right, $color-brand-primary 50%, $color-brand-secondary);
|
background: linear-gradient(to right, colors.$color-brand-primary 50%, colors.$color-brand-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header__bar__main {
|
.page-header__bar__main {
|
||||||
@include container();
|
@include mixins.container();
|
||||||
color: white;
|
color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header__bar__search {
|
.page-header__bar__search {
|
||||||
display: none;
|
display: none;
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
@@ -37,7 +41,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
@@ -53,14 +57,14 @@
|
|||||||
.page-header__bar__divider {
|
.page-header__bar__divider {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 12px 8px;
|
padding: 12px 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header__main {
|
.page-header__main {
|
||||||
@include container();
|
@include mixins.container();
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
display: -ms-flexbox;
|
display: -ms-flexbox;
|
||||||
@@ -68,11 +72,11 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
-ms-flex-align: center;
|
-ms-flex-align: center;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding: 32px 16px 24px;
|
padding: 32px 16px 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
-ms-flex-align: end;
|
-ms-flex-align: end;
|
||||||
@@ -98,7 +102,7 @@
|
|||||||
.page-header__sitenav {
|
.page-header__sitenav {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +110,7 @@
|
|||||||
.page-header__button {
|
.page-header__button {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
@@ -128,6 +132,6 @@
|
|||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
& > polygon {
|
& > polygon {
|
||||||
fill: $color-brand-primary;
|
fill: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@use "colors";
|
||||||
|
|
||||||
.paginator {
|
.paginator {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -10,7 +12,7 @@
|
|||||||
|
|
||||||
.paginator__item {
|
.paginator__item {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -19,8 +21,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&--current {
|
&--current {
|
||||||
border: 1px solid $color-brand-primary;
|
border: 1px solid colors.$color-brand-primary;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,27 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.searchresult {}
|
.searchresult {}
|
||||||
|
|
||||||
.searchresult__info {
|
.searchresult__info {
|
||||||
@include container();
|
@include mixins.container();
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchresult-item {
|
.searchresult-item {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
display: block;
|
display: block;
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchresult-item__card {
|
.searchresult-item__card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
width: 240px;
|
width: 240px;
|
||||||
}
|
}
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 33.3333%;
|
width: 33.3333%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,8 +30,8 @@
|
|||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
color: white;
|
color: white;
|
||||||
@include sectionBackgrounds();
|
@include mixins.sectionBackgrounds();
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.sitenav {
|
.sitenav {
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
padding-right: 64px;
|
padding-right: 64px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +28,7 @@
|
|||||||
&--active,
|
&--active,
|
||||||
&:hover {
|
&:hover {
|
||||||
border-bottom: 3px solid;
|
border-bottom: 3px solid;
|
||||||
@include sectionColours();
|
@include mixins.sectionColours();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
|
||||||
.slider {}
|
.slider {}
|
||||||
|
|
||||||
.slider__arrow {
|
.slider__arrow {
|
||||||
@@ -38,7 +40,7 @@
|
|||||||
top: 30%;
|
top: 30%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.statement {
|
.statement {
|
||||||
@include container();
|
@include mixins.container();
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statement__inner {
|
.statement__inner {
|
||||||
@include sectionBackgrounds();
|
@include mixins.sectionBackgrounds();
|
||||||
box-shadow: 0 5px 10px rgba(black, 0.2);
|
box-shadow: 0 5px 10px rgba(black, 0.2);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 48px;
|
padding-top: 48px;
|
||||||
@@ -18,7 +21,7 @@
|
|||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
line-height: 105%;
|
line-height: 105%;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.team {
|
.team {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -12,11 +15,11 @@
|
|||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
padding: 0 16px 64px;
|
padding: 0 16px 64px;
|
||||||
|
|
||||||
@include mq($until: desktop) {
|
@include breakpoints.mq($until: desktop) {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
@@ -57,10 +60,10 @@
|
|||||||
|
|
||||||
.team__position {
|
.team__position {
|
||||||
display: block;
|
display: block;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.team__contact__link {
|
.team__contact__link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.teasers {
|
.teasers {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@include sectionBackgrounds(0.15);
|
@include mixins.sectionBackgrounds(0.15);
|
||||||
margin: 0 -16px 0;
|
margin: 0 -16px 0;
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,15 +22,15 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($until: tablet) {
|
@include breakpoints.mq($until: tablet) {
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 33.3333%;
|
width: 33.3333%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,12 +43,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.teaser__caption {
|
.teaser__caption {
|
||||||
@include sectionBackgroundsFromParent();
|
@include mixins.sectionBackgroundsFromParent();
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.teaser__form {
|
.teaser__form {
|
||||||
@include sectionFills();
|
@include mixins.sectionFills();
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
.testimonial {
|
.testimonial {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 32px;
|
padding: 0 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
border-right: 1px solid $color-divider;
|
border-right: 1px solid colors.$color-divider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: desktop) {
|
@include breakpoints.mq($from: desktop) {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
@use "breakpoints";
|
||||||
|
@use "colors";
|
||||||
|
@use "mixins";
|
||||||
|
|
||||||
.tiles {
|
.tiles {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
@@ -15,7 +19,7 @@
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
@@ -26,12 +30,12 @@
|
|||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
|
||||||
@include mq($from: mobile) {
|
@include breakpoints.mq($from: mobile) {
|
||||||
min-height: 250px;
|
min-height: 250px;
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding: 32px 32px 0;
|
padding: 32px 32px 0;
|
||||||
min-height: 375px;
|
min-height: 375px;
|
||||||
}
|
}
|
||||||
@@ -42,33 +46,33 @@
|
|||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
width: 70%;
|
width: 70%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile__caption__inner {
|
.tile__caption__inner {
|
||||||
@include sectionBackgrounds(0.75);
|
@include mixins.sectionBackgrounds(0.75);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 24px 0;
|
padding: 24px 0;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
padding: 32px 0;
|
padding: 32px 0;
|
||||||
|
|
||||||
.tile:hover .section-incentives & {
|
.tile:hover .section-incentives & {
|
||||||
background-color: $color-incentives;
|
background-color: colors.$color-incentives;
|
||||||
}
|
}
|
||||||
.tile:hover .section-teambuilding & {
|
.tile:hover .section-teambuilding & {
|
||||||
background-color: $color-teambuilding;
|
background-color: colors.$color-teambuilding;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile:hover .section-meetings & {
|
.tile:hover .section-meetings & {
|
||||||
background-color: $color-meetings;
|
background-color: colors.$color-meetings;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile:hover .section-events & {
|
.tile:hover .section-events & {
|
||||||
background-color: $color-events;
|
background-color: colors.$color-events;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +81,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
padding: 16px 32px 0;
|
padding: 16px 32px 0;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
.tile:hover & {
|
.tile:hover & {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -91,10 +95,10 @@
|
|||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
|
|
||||||
polygon {
|
polygon {
|
||||||
@include sectionFills();
|
@include mixins.sectionFills();
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
.tile:hover & {
|
.tile:hover & {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -114,7 +118,7 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
min-height: 54px;
|
min-height: 54px;
|
||||||
|
|
||||||
@include mq($from: tablet) {
|
@include breakpoints.mq($from: tablet) {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
@use "mixins";
|
||||||
|
|
||||||
.video {
|
.video {
|
||||||
@include container();
|
@include mixins.container();
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
@import "variables";
|
@use "variables";
|
||||||
@import "mixins";
|
@use "mixins";
|
||||||
@import "breakpoints";
|
@use "breakpoints";
|
||||||
|
|
||||||
@import "colors";
|
@use "colors";
|
||||||
@import "fonts";
|
@use "fonts";
|
||||||
|
|
||||||
@import "base";
|
@use "base";
|
||||||
@import "buttons";
|
@use "buttons";
|
||||||
@import "page-header";
|
@use "page-header";
|
||||||
@import "page-footer";
|
@use "page-footer";
|
||||||
@import "layout";
|
@use "layout";
|
||||||
@import "sitenav";
|
@use "sitenav";
|
||||||
@import "helpernav";
|
@use "helpernav";
|
||||||
@import "mobilenav";
|
@use "mobilenav";
|
||||||
@import "herounit";
|
@use "herounit";
|
||||||
@import "carousel";
|
@use "carousel";
|
||||||
@import "slider";
|
@use "slider";
|
||||||
@import "configurator";
|
@use "configurator";
|
||||||
@import "statement";
|
@use "statement";
|
||||||
@import "testimonial";
|
@use "testimonial";
|
||||||
@import "brands";
|
@use "brands";
|
||||||
@import "iconbar";
|
@use "iconbar";
|
||||||
@import "tiles";
|
@use "tiles";
|
||||||
@import "card";
|
@use "card";
|
||||||
@import "box";
|
@use "box";
|
||||||
@import "banner";
|
@use "banner";
|
||||||
@import "iconnav";
|
@use "iconnav";
|
||||||
@import "forms";
|
@use "forms";
|
||||||
@import "teasers";
|
@use "teasers";
|
||||||
@import "badge";
|
@use "badge";
|
||||||
@import "team";
|
@use "team";
|
||||||
@import "search";
|
@use "search";
|
||||||
@import "offerlist";
|
@use "offerlist";
|
||||||
@import "paginator";
|
@use "paginator";
|
||||||
@import "news";
|
@use "news";
|
||||||
@import "datepicker";
|
@use "datepicker";
|
||||||
@import "cookiefirst";
|
@use "cookiefirst";
|
||||||
@import "video";
|
@use "video";
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
@import "mixins";
|
@use "mixins";
|
||||||
@import "colors";
|
@use "colors";
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Cairo';
|
font-family: 'Cairo';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url('../fonts/cairo-v2-latin-ext_latin-regular.eot'); /* IE9 Compat Modes */
|
|
||||||
src: local('Cairo'), local('Cairo-Regular'),
|
src: local('Cairo'), local('Cairo-Regular'),
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
url('../fonts/cairo-v2-latin-ext_latin-regular.woff2') format('woff2'),
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
url('../fonts/cairo-v2-latin-ext_latin-regular.woff') format('woff');
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-regular.woff') format('woff'), /* Modern Browsers */
|
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-regular.svg#Cairo') format('svg'); /* Legacy iOS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
@@ -20,13 +16,9 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url('../fonts/cairo-v2-latin-ext_latin-700.eot'); /* IE9 Compat Modes */
|
|
||||||
src: local('Cairo Bold'), local('Cairo-Bold'),
|
src: local('Cairo Bold'), local('Cairo-Bold'),
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
url('../fonts/cairo-v2-latin-ext_latin-700.woff2') format('woff2'),
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-700.woff2') format('woff2'), /* Super Modern Browsers */
|
url('../fonts/cairo-v2-latin-ext_latin-700.woff') format('woff');
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-700.woff') format('woff'), /* Modern Browsers */
|
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
|
|
||||||
url('../fonts/cairo-v2-latin-ext_latin-700.svg#Cairo') format('svg'); /* Legacy iOS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$font-main: 'Cairo';
|
$font-main: 'Cairo';
|
||||||
@@ -34,12 +26,8 @@ $font-main: 'Cairo';
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'fontello';
|
font-family: 'fontello';
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url('../fonts/fontello.eot?39986861');
|
src: url('../fonts/fontello.woff2?39986861') format('woff2'),
|
||||||
src: url('../fonts/fontello.eot?39986861#iefix') format('embedded-opentype'),
|
url('../fonts/fontello.woff?39986861') format('woff');
|
||||||
url('../fonts/fontello.woff2?39986861') format('woff2'),
|
|
||||||
url('../fonts/fontello.woff?39986861') format('woff'),
|
|
||||||
url('../fonts/fontello.ttf?39986861') format('truetype'),
|
|
||||||
url('../fonts/fontello.svg?39986861#fontello') format('svg');
|
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@@ -123,7 +111,7 @@ ul {
|
|||||||
left: 0;
|
left: 0;
|
||||||
content: "\25CF";
|
content: "\25CF";
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@include sectionColoursFromParent();
|
@include mixins.sectionColoursFromParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,8 +129,8 @@ p {
|
|||||||
hr {
|
hr {
|
||||||
max-width: 25%;
|
max-width: 25%;
|
||||||
margin: 32px auto 32px 0;
|
margin: 32px auto 32px 0;
|
||||||
color: $color-ruler;
|
color: colors.$color-ruler;
|
||||||
background-color: $color-ruler;
|
background-color: colors.$color-ruler;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
@@ -158,7 +146,7 @@ h3,
|
|||||||
}
|
}
|
||||||
|
|
||||||
.headline {
|
.headline {
|
||||||
@include sectionColoursFromParent();
|
@include mixins.sectionColoursFromParent();
|
||||||
|
|
||||||
&--icon {
|
&--icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -192,9 +180,9 @@ h1,
|
|||||||
display: block;
|
display: block;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 120%;
|
line-height: 120%;
|
||||||
color: $color-brand-primary;
|
color: colors.$color-brand-primary;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@include sectionColoursFromParent();
|
@include mixins.sectionColoursFromParent();
|
||||||
|
|
||||||
&--box {
|
&--box {
|
||||||
color: white;
|
color: white;
|
||||||
@@ -229,7 +217,7 @@ h3 {
|
|||||||
|
|
||||||
&--default {
|
&--default {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
}
|
}
|
||||||
@@ -237,7 +225,7 @@ h3 {
|
|||||||
&--page-header {
|
&--page-header {
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 186px;
|
min-width: 186px;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding: 0 32px 0 24px;
|
padding: 0 32px 0 24px;
|
||||||
@@ -250,8 +238,8 @@ h3 {
|
|||||||
display: block;
|
display: block;
|
||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
@include sectionBackgroundsFromParent();
|
@include mixins.sectionBackgroundsFromParent();
|
||||||
color: white;
|
color: white;
|
||||||
line-height: 48px;
|
line-height: 48px;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -271,7 +259,7 @@ h3 {
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: white;
|
background: white;
|
||||||
color: $color-font-main;
|
color: colors.$color-font-main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +268,7 @@ h3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&--icon {
|
&--icon {
|
||||||
background-color: $color-brand-primary;
|
background-color: colors.$color-brand-primary;
|
||||||
color: white;
|
color: white;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
|||||||
@@ -87,12 +87,16 @@ class SearchController extends ActionController
|
|||||||
|
|
||||||
public function initializeSearchresultAction()
|
public function initializeSearchresultAction()
|
||||||
{
|
{
|
||||||
// Process encoded filtersettings from static search result
|
// Process encoded filtersettings from static search result.
|
||||||
|
// Explicit filter settings win: they carry the visitor's current selection,
|
||||||
|
// whereas a stale 'f' riding along on a link would silently replace it.
|
||||||
$encodedFilterSettings = GeneralUtility::_GET('f');
|
$encodedFilterSettings = GeneralUtility::_GET('f');
|
||||||
if ($encodedFilterSettings) {
|
if ($encodedFilterSettings && !$this->request->hasArgument('filterSettings')) {
|
||||||
$filterSettingsEncoder = new FilterSettingsEncoder();
|
$filterSettingsEncoder = new FilterSettingsEncoder();
|
||||||
$filterSettings = $filterSettingsEncoder->decode($encodedFilterSettings);
|
$filterSettings = $filterSettingsEncoder->decode($encodedFilterSettings);
|
||||||
$this->request->setArgument('filterSettings', $filterSettings);
|
if (count($filterSettings) > 0) {
|
||||||
|
$this->request->setArgument('filterSettings', $filterSettings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'], true);
|
$forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'], true);
|
||||||
$this->processFilterSettingsArgument($forcedConceptUids);
|
$this->processFilterSettingsArgument($forcedConceptUids);
|
||||||
|
|||||||
@@ -30,12 +30,17 @@ namespace EP\EpProducts\Domain\Model;
|
|||||||
class Room
|
class Room
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const ROOM_TYPE_UNCLASSIFIED = 0;
|
||||||
const ROOM_TYPE_FOR_ONE = 1;
|
const ROOM_TYPE_FOR_ONE = 1;
|
||||||
const ROOM_TYPE_FOR_TWO = 2;
|
const ROOM_TYPE_FOR_TWO = 2;
|
||||||
const ROOM_TYPE_FOR_THREE = 3;
|
const ROOM_TYPE_FOR_THREE = 3;
|
||||||
const ROOM_TYPE_FOR_FOUR = 4;
|
const ROOM_TYPE_FOR_FOUR = 4;
|
||||||
const ROOM_TYPE_WITH_OTHERS = 5;
|
const ROOM_TYPE_FOR_FIVE = 5;
|
||||||
const ROOM_TYPE_OTHER = 6;
|
const ROOM_TYPE_FOR_SIX = 6;
|
||||||
|
const ROOM_TYPE_FOR_SEVEN = 7;
|
||||||
|
const ROOM_TYPE_FOR_EIGHT = 8;
|
||||||
|
const ROOM_TYPE_FOR_NINE_PLUS = 9;
|
||||||
|
const ROOM_TYPE_WITH_OTHERS = 10;
|
||||||
|
|
||||||
const ROOM_STATUS_AVAILABLE = 1;
|
const ROOM_STATUS_AVAILABLE = 1;
|
||||||
const ROOM_STATUS_ON_REQUEST = 2;
|
const ROOM_STATUS_ON_REQUEST = 2;
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace EP\EpProducts\Domain\Model;
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
*
|
|
||||||
* Copyright notice
|
|
||||||
*
|
|
||||||
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
|
|
||||||
*
|
|
||||||
* All rights reserved
|
|
||||||
*
|
|
||||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
|
||||||
* free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* The GNU General Public License can be found at
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html.
|
|
||||||
*
|
|
||||||
* This script is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
class RoomMapping extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $code = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
protected $type = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getCode()
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $code
|
|
||||||
*/
|
|
||||||
public function setCode($code)
|
|
||||||
{
|
|
||||||
$this->code = $code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getType()
|
|
||||||
{
|
|
||||||
return $this->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $type
|
|
||||||
*/
|
|
||||||
public function setType($type)
|
|
||||||
{
|
|
||||||
$this->type = $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -76,9 +76,11 @@ class ProductRepository extends AbstractRepository
|
|||||||
'date.services_included as servicesIncluded', 'date.skipass_included as skiPassIncluded',
|
'date.services_included as servicesIncluded', 'date.skipass_included as skiPassIncluded',
|
||||||
'date.bus_available as busAvailable', 'date.new as new',
|
'date.bus_available as busAvailable', 'date.new as new',
|
||||||
'date.min_price as minPrice', 'date.nights as nights', 'date.available as available',
|
'date.min_price as minPrice', 'date.nights as nights', 'date.available as available',
|
||||||
'date.pseudo_price as pseudoPrice', 'date.hide_booking_button as hideBookingButton',
|
'date.pseudo_price as pseudoPrice', 'date.hide_booking_button as hideBookingButton'
|
||||||
'room.type as roomType'
|
|
||||||
)
|
)
|
||||||
|
// The GROUP BY below collapses many room rows per group; an arbitrary
|
||||||
|
// room.type would hide most types from the filter facet.
|
||||||
|
->addSelectLiteral('GROUP_CONCAT(DISTINCT room.type) as roomTypes')
|
||||||
->from('tx_epproducts_domain_model_date', 'date')
|
->from('tx_epproducts_domain_model_date', 'date')
|
||||||
->leftJoin('date', 'tx_epproducts_domain_model_concept', 'con', 'date.concept = con.uid')
|
->leftJoin('date', 'tx_epproducts_domain_model_concept', 'con', 'date.concept = con.uid')
|
||||||
->leftJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid')
|
->leftJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid')
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace EP\EpProducts\Domain\Repository;
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
*
|
|
||||||
* Copyright notice
|
|
||||||
*
|
|
||||||
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
|
|
||||||
*
|
|
||||||
* All rights reserved
|
|
||||||
*
|
|
||||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
|
||||||
* free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* The GNU General Public License can be found at
|
|
||||||
* http://www.gnu.org/copyleft/gpl.html.
|
|
||||||
*
|
|
||||||
* This script is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
class RoomMappingRepository extends AbstractRepository
|
|
||||||
{}
|
|
||||||
@@ -49,8 +49,22 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
*/
|
*/
|
||||||
private const ACCESS_TOKEN_DEFAULT_TTL = 300;
|
private const ACCESS_TOKEN_DEFAULT_TTL = 300;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status codes that mean the token was rejected rather than the request being wrong.
|
||||||
|
*/
|
||||||
|
private const UNAUTHORIZED_STATUS_CODES = [Response::HTTP_UNAUTHORIZED, Response::HTTP_FORBIDDEN];
|
||||||
|
|
||||||
private static ?AccessToken $accessToken = null;
|
private static ?AccessToken $accessToken = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared on purpose. Symfony's CurlHttpClient keeps its connection pool and TLS session
|
||||||
|
* cache in a CurlClientState owned by the instance, so building a client per call throws
|
||||||
|
* both away and forces a fresh DNS lookup, TCP connect and TLS handshake every time -
|
||||||
|
* TravelinfoController alone makes two calls per page render. The bearer token is passed
|
||||||
|
* per request rather than as a client default so one instance can outlive one token.
|
||||||
|
*/
|
||||||
|
private static ?HttpClientInterface $httpClient = null;
|
||||||
|
|
||||||
private ?FrontendInterface $cache = null;
|
private ?FrontendInterface $cache = null;
|
||||||
|
|
||||||
private ?array $configuration = null;
|
private ?array $configuration = null;
|
||||||
@@ -100,7 +114,25 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
'json' => $addressData,
|
'json' => $addressData,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertStatusCode($response, [Response::HTTP_OK, Response::HTTP_CREATED, Response::HTTP_ACCEPTED, Response::HTTP_NO_CONTENT], 'POST', 'contactform');
|
// A conflict means the address is already registered, which is the normal answer to a
|
||||||
|
// resubmitted contact form and not worth reporting.
|
||||||
|
$this->assertStatusCode($response, [Response::HTTP_OK, Response::HTTP_CREATED, Response::HTTP_ACCEPTED, Response::HTTP_NO_CONTENT, Response::HTTP_CONFLICT], 'POST', 'contactform');
|
||||||
|
$this->drainResponse($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
public function submitApplication(array $applicationData): void
|
||||||
|
{
|
||||||
|
$response = $this->request('POST', 'applications', [
|
||||||
|
'json' => $applicationData,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// A conflict means the submission is already known, which is the normal answer to a
|
||||||
|
// double-clicked submit button and not worth reporting.
|
||||||
|
$this->assertStatusCode($response, [Response::HTTP_OK, Response::HTTP_CREATED, Response::HTTP_ACCEPTED, Response::HTTP_NO_CONTENT, Response::HTTP_CONFLICT], 'POST', 'applications');
|
||||||
|
$this->drainResponse($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,6 +215,30 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
*/
|
*/
|
||||||
private function request(string $method, string $uri, array $options = []): ResponseInterface
|
private function request(string $method, string $uri, array $options = []): ResponseInterface
|
||||||
{
|
{
|
||||||
|
$response = $this->sendRequest($method, $uri, $options);
|
||||||
|
|
||||||
|
if (false === in_array($this->readStatusCode($response, $method, $uri), self::UNAUTHORIZED_STATUS_CODES, true)) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The token outlives a single PHP request, so one the API has stopped accepting - after
|
||||||
|
// a MyEP restart or a revoked client - would keep failing every call for the rest of its
|
||||||
|
// cached lifetime unless it is actively discarded here.
|
||||||
|
$this->logWarning(sprintf('MyEP API rejected the cached access token for %s %s, re-authenticating once', $method, $uri));
|
||||||
|
$this->discardAccessToken();
|
||||||
|
|
||||||
|
return $this->sendRequest($method, $uri, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
private function sendRequest(string $method, string $uri, array $options): ResponseInterface
|
||||||
|
{
|
||||||
|
// Resolved here rather than baked into the client's default options so that the shared
|
||||||
|
// client survives a token change, and so the retry above picks up the fresh token.
|
||||||
|
$options['auth_bearer'] = $this->getAccessToken($this->getConfiguration())->getToken();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $this->getHttpClient()->request($method, $uri, $options);
|
return $this->getHttpClient()->request($method, $uri, $options);
|
||||||
} catch (TransportExceptionInterface $e) {
|
} catch (TransportExceptionInterface $e) {
|
||||||
@@ -199,13 +255,7 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
*/
|
*/
|
||||||
private function assertStatusCode(ResponseInterface $response, array $expectedStatusCodes, string $method, string $uri): void
|
private function assertStatusCode(ResponseInterface $response, array $expectedStatusCodes, string $method, string $uri): void
|
||||||
{
|
{
|
||||||
try {
|
$statusCode = $this->readStatusCode($response, $method, $uri);
|
||||||
$statusCode = $response->getStatusCode();
|
|
||||||
} catch (TransportExceptionInterface $e) {
|
|
||||||
$message = sprintf('MyEP API transport error while reading status for %s %s: %s', $method, $uri, $e->getMessage());
|
|
||||||
$this->logError($message, ['exception' => $e]);
|
|
||||||
throw new ApiException($message, 0, $e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (true === in_array($statusCode, $expectedStatusCodes, true)) {
|
if (true === in_array($statusCode, $expectedStatusCodes, true)) {
|
||||||
return;
|
return;
|
||||||
@@ -217,6 +267,39 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
throw new ApiException($message, $statusCode);
|
throw new ApiException($message, $statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reading the status completes the transfer, so this is also what turns the lazy response
|
||||||
|
* returned by the client into a finished request. Symfony keeps the status on the response,
|
||||||
|
* so calling this twice costs nothing.
|
||||||
|
*
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
private function readStatusCode(ResponseInterface $response, string $method, string $uri): int
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $response->getStatusCode();
|
||||||
|
} catch (TransportExceptionInterface $e) {
|
||||||
|
$message = sprintf('MyEP API transport error while reading status for %s %s: %s', $method, $uri, $e->getMessage());
|
||||||
|
$this->logError($message, ['exception' => $e]);
|
||||||
|
throw new ApiException($message, 0, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and discards a body nobody else is going to look at. Destroying an unconsumed
|
||||||
|
* response cancels the transfer, which closes the connection instead of returning it to
|
||||||
|
* the pool, so the next call would have to handshake again.
|
||||||
|
*/
|
||||||
|
private function drainResponse(ResponseInterface $response): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$response->getContent(false);
|
||||||
|
} catch (TransportExceptionInterface $e) {
|
||||||
|
// The status has already been asserted, so a failure here costs nothing but the
|
||||||
|
// connection reuse this method exists for.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ApiException
|
* @throws ApiException
|
||||||
*/
|
*/
|
||||||
@@ -237,13 +320,13 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
|
|
||||||
private function getHttpClient(): HttpClientInterface
|
private function getHttpClient(): HttpClientInterface
|
||||||
{
|
{
|
||||||
|
if (null !== static::$httpClient) {
|
||||||
|
return static::$httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
$config = $this->getConfiguration();
|
$config = $this->getConfiguration();
|
||||||
|
|
||||||
static::$accessToken = $this->getAccessToken($config);
|
$options = [];
|
||||||
|
|
||||||
$options = [
|
|
||||||
'auth_bearer' => static::$accessToken->getToken(),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Without these the client falls back to PHP's default_socket_timeout (commonly 60s),
|
// Without these the client falls back to PHP's default_socket_timeout (commonly 60s),
|
||||||
// so a stalled API pins a PHP worker for a minute per request. The defaults live in
|
// so a stalled API pins a PHP worker for a minute per request. The defaults live in
|
||||||
@@ -261,7 +344,7 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
$options['max_duration'] = $maxDuration;
|
$options['max_duration'] = $maxDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HttpClient::createForBaseUri($config['myEpApiBaseUrl'], $options);
|
return static::$httpClient = HttpClient::createForBaseUri($config['myEpApiBaseUrl'], $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,7 +379,7 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
*/
|
*/
|
||||||
private function getAccessToken(array $config): AccessToken
|
private function getAccessToken(array $config): AccessToken
|
||||||
{
|
{
|
||||||
if (null !== static::$accessToken && false === static::$accessToken->hasExpired()) {
|
if (true === $this->isTokenUsable(static::$accessToken)) {
|
||||||
return static::$accessToken;
|
return static::$accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +388,7 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
$cachedToken = $this->getCache()->get(self::ACCESS_TOKEN_CACHE_IDENTIFIER);
|
$cachedToken = $this->getCache()->get(self::ACCESS_TOKEN_CACHE_IDENTIFIER);
|
||||||
if (is_array($cachedToken) && isset($cachedToken['access_token'])) {
|
if (is_array($cachedToken) && isset($cachedToken['access_token'])) {
|
||||||
$token = new AccessToken($cachedToken);
|
$token = new AccessToken($cachedToken);
|
||||||
if (false === $token->hasExpired()) {
|
if (true === $this->isTokenUsable($token)) {
|
||||||
static::$accessToken = $token;
|
static::$accessToken = $token;
|
||||||
|
|
||||||
return static::$accessToken;
|
return static::$accessToken;
|
||||||
@@ -313,7 +396,7 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
static::$accessToken = $this->getProvider($config)->getAccessToken('client_credentials');
|
static::$accessToken = $this->normalizeToken($this->getProvider($config)->getAccessToken('client_credentials'));
|
||||||
$this->cacheAccessToken(static::$accessToken);
|
$this->cacheAccessToken(static::$accessToken);
|
||||||
} catch (IdentityProviderException $e) {
|
} catch (IdentityProviderException $e) {
|
||||||
$message = sprintf('MyEP OAuth token request failed: %s', $e->getMessage());
|
$message = sprintf('MyEP OAuth token request failed: %s', $e->getMessage());
|
||||||
@@ -332,16 +415,53 @@ class ApiClient implements LoggerAwareInterface
|
|||||||
return static::$accessToken;
|
return static::$accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function cacheAccessToken(AccessToken $token): void
|
/**
|
||||||
|
* AccessToken::hasExpired() throws for a token that reports no expiry, so it cannot be used
|
||||||
|
* as the check - a token without one is simply treated as unusable and replaced. The same
|
||||||
|
* margin as the cache lifetime is applied on read as well, so a token cannot lapse between
|
||||||
|
* this check and the API call that uses it, whichever node wrote the cache entry.
|
||||||
|
*/
|
||||||
|
private function isTokenUsable(?AccessToken $token): bool
|
||||||
{
|
{
|
||||||
|
if (null === $token) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$expires = $token->getExpires();
|
$expires = $token->getExpires();
|
||||||
|
|
||||||
if (null === $expires) {
|
if (null === $expires) {
|
||||||
$lifetime = self::ACCESS_TOKEN_DEFAULT_TTL;
|
return false;
|
||||||
} else {
|
|
||||||
$lifetime = $expires - time() - self::ACCESS_TOKEN_EXPIRY_MARGIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $expires - self::ACCESS_TOKEN_EXPIRY_MARGIN > time();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A token that reports no expiry cannot be validated on read - isTokenUsable() rejects it
|
||||||
|
* and AccessToken::hasExpired() throws for it - so it is given the fallback lifetime here,
|
||||||
|
* once, and the rest of the class can treat every token the same way.
|
||||||
|
*/
|
||||||
|
private function normalizeToken(AccessToken $token): AccessToken
|
||||||
|
{
|
||||||
|
if (null !== $token->getExpires()) {
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AccessToken($token->jsonSerialize() + ['expires_in' => self::ACCESS_TOKEN_DEFAULT_TTL]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function discardAccessToken(): void
|
||||||
|
{
|
||||||
|
static::$accessToken = null;
|
||||||
|
$this->getCache()->remove(self::ACCESS_TOKEN_CACHE_IDENTIFIER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function cacheAccessToken(AccessToken $token): void
|
||||||
|
{
|
||||||
|
// normalizeToken() has already given a token without a reported expiry the fallback
|
||||||
|
// lifetime, so there is always a real expiry to subtract the margin from here.
|
||||||
|
$lifetime = $token->getExpires() - time() - self::ACCESS_TOKEN_EXPIRY_MARGIN;
|
||||||
|
|
||||||
if ($lifetime <= 0) {
|
if ($lifetime <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,11 +60,6 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
*/
|
*/
|
||||||
protected $pid = 0;
|
protected $pid = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $roomMappings = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@@ -90,6 +85,11 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
*/
|
*/
|
||||||
protected $importSourceFactory;
|
protected $importSourceFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var RoomTypeResolver
|
||||||
|
*/
|
||||||
|
protected $roomTypeResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@@ -101,15 +101,18 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
* @param ConfigurationManagerInterface $configurationManager
|
* @param ConfigurationManagerInterface $configurationManager
|
||||||
* @param CacheService $cacheService
|
* @param CacheService $cacheService
|
||||||
* @param ProductImportSourceFactory $importSourceFactory
|
* @param ProductImportSourceFactory $importSourceFactory
|
||||||
|
* @param RoomTypeResolver $roomTypeResolver
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ConfigurationManagerInterface $configurationManager,
|
ConfigurationManagerInterface $configurationManager,
|
||||||
CacheService $cacheService,
|
CacheService $cacheService,
|
||||||
ProductImportSourceFactory $importSourceFactory
|
ProductImportSourceFactory $importSourceFactory,
|
||||||
|
RoomTypeResolver $roomTypeResolver
|
||||||
) {
|
) {
|
||||||
$this->configurationManager = $configurationManager;
|
$this->configurationManager = $configurationManager;
|
||||||
$this->cacheService = $cacheService;
|
$this->cacheService = $cacheService;
|
||||||
$this->importSourceFactory = $importSourceFactory;
|
$this->importSourceFactory = $importSourceFactory;
|
||||||
|
$this->roomTypeResolver = $roomTypeResolver;
|
||||||
|
|
||||||
$settings = GeneralUtility::removeDotsFromTS(
|
$settings = GeneralUtility::removeDotsFromTS(
|
||||||
$this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT)
|
$this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT)
|
||||||
@@ -130,7 +133,6 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
public function import($path): int
|
public function import($path): int
|
||||||
{
|
{
|
||||||
$this->db = $this->getDbConnection();
|
$this->db = $this->getDbConnection();
|
||||||
$this->getRoomMappings();
|
|
||||||
$this->getHotelMappings();
|
$this->getHotelMappings();
|
||||||
$this->importPickups($path);
|
$this->importPickups($path);
|
||||||
$this->createTempTables();
|
$this->createTempTables();
|
||||||
@@ -594,13 +596,9 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$roomTypeKey = mb_strtolower($code);
|
$label = (string) $roomXml->attributes()['zimmertext'];
|
||||||
if (array_key_exists($roomTypeKey, $this->roomMappings)) {
|
$roomMinPax = (int) $roomXml->attributes()['MinPax'];
|
||||||
$roomType = $this->roomMappings[$roomTypeKey];
|
$pax = (int) $roomXml->attributes()['MaxPax'];
|
||||||
} else {
|
|
||||||
$this->logger->warning('room type not found', ['code' => $code]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$available = (int) $roomXml->attributes()['verfuegbar'];
|
$available = (int) $roomXml->attributes()['verfuegbar'];
|
||||||
$price = (int) $roomXml->attributes()['preis'];
|
$price = (int) $roomXml->attributes()['preis'];
|
||||||
@@ -610,12 +608,23 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pax = (int) $roomXml->attributes()['MinPax'];
|
$roomType = $this->roomTypeResolver->resolve($code, $label, $pax, $roomMinPax);
|
||||||
if (0 === $minPax || $pax < $minPax) {
|
|
||||||
$minPax = $pax;
|
if ($pax < 1 && $roomMinPax < 1) {
|
||||||
|
$this->logger->warning('room without occupancy', ['code' => $code, 'zimmertext' => $label]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->roomTypeResolver->needsReview($code, $label, $pax)) {
|
||||||
|
$this->logger->warning(
|
||||||
|
'single-occupancy room without single-use marker',
|
||||||
|
['code' => $code, 'zimmertext' => $label]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 === $minPax || $roomMinPax < $minPax) {
|
||||||
|
$minPax = $roomMinPax;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pax = (int) $roomXml->attributes()['MaxPax'];
|
|
||||||
$availableTotal += $available * $pax;
|
$availableTotal += $available * $pax;
|
||||||
|
|
||||||
// Determine lowest price of available rooms
|
// Determine lowest price of available rooms
|
||||||
@@ -648,7 +657,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
'bus_pro_id' => (int) $roomXml->attributes()['idbuspro_zimmer'],
|
'bus_pro_id' => (int) $roomXml->attributes()['idbuspro_zimmer'],
|
||||||
'code' => $code,
|
'code' => $code,
|
||||||
'type' => $roomType,
|
'type' => $roomType,
|
||||||
'name' => (string) $roomXml->attributes()['zimmertext'],
|
'name' => $label,
|
||||||
'pax' => $pax,
|
'pax' => $pax,
|
||||||
'nights' => (int) $roomXml->attributes()['naechte'],
|
'nights' => (int) $roomXml->attributes()['naechte'],
|
||||||
'price' => $price,
|
'price' => $price,
|
||||||
@@ -791,16 +800,6 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getRoomMappings(): void
|
|
||||||
{
|
|
||||||
$sql = 'SELECT code, type FROM tx_epproducts_domain_model_roommapping WHERE deleted = 0 AND hidden = 0';
|
|
||||||
$roomMappings = $this->db->fetchAllAssociative($sql);
|
|
||||||
foreach ($roomMappings as $mapping) {
|
|
||||||
$key = trim(mb_strtolower($mapping['code']));
|
|
||||||
$this->roomMappings[$key] = $mapping['type'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getHotelMappings(): void
|
protected function getHotelMappings(): void
|
||||||
{
|
{
|
||||||
$sql = '
|
$sql = '
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace EP\EpProducts\Service;
|
namespace EP\EpProducts\Service;
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\Dto\FilterOptions;
|
use EP\EpProducts\Domain\Model\Dto\FilterOptions;
|
||||||
|
use EP\EpProducts\Domain\Model\Room;
|
||||||
use EP\EpProducts\Domain\Model\SearchResult;
|
use EP\EpProducts\Domain\Model\SearchResult;
|
||||||
use Symfony\Component\OptionsResolver\Options;
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
@@ -212,6 +213,12 @@ class FilterService implements SingletonInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($item['rooms'] as $roomType) {
|
foreach ($item['rooms'] as $roomType) {
|
||||||
|
// Type 0 is not a room (Baby) and must never become a filter option:
|
||||||
|
// it has no label, so it would render as an empty checkbox and leave
|
||||||
|
// a hole in the option list.
|
||||||
|
if ((int) $roomType === Room::ROOM_TYPE_UNCLASSIFIED) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!\in_array($roomType, $roomTypes, false)) {
|
if (!\in_array($roomType, $roomTypes, false)) {
|
||||||
$roomTypes[] = $roomType;
|
$roomTypes[] = $roomType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,11 +76,28 @@ class FilterSettingsEncoder
|
|||||||
return implode('|', $encoded);
|
return implode('|', $encoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes an encoded filter settings string.
|
||||||
|
*
|
||||||
|
* The format is strictly positional, so a string whose field count does not
|
||||||
|
* match the mapping cannot be interpreted: every field after a missing one
|
||||||
|
* would be read into the wrong setting. Such input is rejected outright
|
||||||
|
* rather than silently producing a shifted - and therefore wrong - result.
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
* @return array the decoded settings, or an empty array if $data is malformed
|
||||||
|
*/
|
||||||
public function decode(string $data): array
|
public function decode(string $data): array
|
||||||
{
|
{
|
||||||
$decoded = [];
|
$mapping = $this->getMapping();
|
||||||
$values = explode('|', $data);
|
$values = explode('|', $data);
|
||||||
foreach ($this->getMapping() as $index => $property)
|
|
||||||
|
if (count($values) !== count($mapping)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$decoded = [];
|
||||||
|
foreach ($mapping as $index => $property)
|
||||||
{
|
{
|
||||||
[$name, $type] = $property;
|
[$name, $type] = $property;
|
||||||
$value = $values[$index];
|
$value = $values[$index];
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpProducts\Service;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
|
||||||
|
*
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||||
|
* free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The GNU General Public License can be found at
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
*
|
||||||
|
* This script is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
use EP\EpProducts\Domain\Model\Room;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derives the room type from the data each <preis> element carries.
|
||||||
|
*
|
||||||
|
* Replaces the former tx_epproducts_domain_model_roommapping lookup: zimmercode is
|
||||||
|
* neither unique per room nor a function of room type, so a code-keyed table cannot
|
||||||
|
* classify this data. MaxPax is the advertised occupancy and is present on every row.
|
||||||
|
*/
|
||||||
|
class RoomTypeResolver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Phrases in zimmertext that mark a bed shared with other customers.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
const LABEL_PATTERNS_WITH_OTHERS = [
|
||||||
|
'bett im',
|
||||||
|
'mit ander',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Phrases in zimmertext that mark a deliberate single use of a larger room.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
const LABEL_PATTERNS_SINGLE_USE = [
|
||||||
|
'einzel',
|
||||||
|
'1 person',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $code zimmercode
|
||||||
|
* @param string $label zimmertext
|
||||||
|
* @param int $maxPax MaxPax
|
||||||
|
* @param int $minPax MinPax
|
||||||
|
* @return int one of the Room::ROOM_TYPE_* constants
|
||||||
|
*/
|
||||||
|
public function resolve(string $code, string $label, int $maxPax, int $minPax): int
|
||||||
|
{
|
||||||
|
// Not a room: "Babypreis für 0-2 Jährige". Kept in the date record for its
|
||||||
|
// price and availability, but hidden from the filter.
|
||||||
|
if ($code === DateImportService::CODE_BABYROOM) {
|
||||||
|
return Room::ROOM_TYPE_UNCLASSIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->matchesAny($label, static::LABEL_PATTERNS_WITH_OTHERS)) {
|
||||||
|
return Room::ROOM_TYPE_WITH_OTHERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pax = $maxPax > 0 ? $maxPax : $minPax;
|
||||||
|
|
||||||
|
if ($pax >= 1) {
|
||||||
|
// Type numbering is chosen so that type === pax for pax 1-8.
|
||||||
|
return $pax >= 9 ? Room::ROOM_TYPE_FOR_NINE_PLUS : $pax;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No usable occupancy - should never happen on current data, the caller logs it.
|
||||||
|
return Room::ROOM_TYPE_WITH_OTHERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tripwire for an under-matching label pattern: a row classified as a single room
|
||||||
|
* whose label carries no single-use marker is most likely a shared bed phrased in
|
||||||
|
* a way LABEL_PATTERNS_WITH_OTHERS does not yet cover.
|
||||||
|
*
|
||||||
|
* @param string $code zimmercode
|
||||||
|
* @param string $label zimmertext
|
||||||
|
* @param int $maxPax MaxPax
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function needsReview(string $code, string $label, int $maxPax): bool
|
||||||
|
{
|
||||||
|
if ($this->resolve($code, $label, $maxPax, $maxPax) !== Room::ROOM_TYPE_FOR_ONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($maxPax !== 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !$this->matchesAny($label, static::LABEL_PATTERNS_SINGLE_USE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $label
|
||||||
|
* @param array $patterns
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function matchesAny(string $label, array $patterns): bool
|
||||||
|
{
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
if (mb_strpos(mb_strtolower($label), mb_strtolower($pattern)) !== false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ use EP\EpProducts\Domain\Model\SearchResult;
|
|||||||
use EP\EpProducts\Domain\Repository\ProductRepository;
|
use EP\EpProducts\Domain\Repository\ProductRepository;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use TYPO3\CMS\Core\SingletonInterface;
|
use TYPO3\CMS\Core\SingletonInterface;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
class SearchResultService implements SingletonInterface
|
class SearchResultService implements SingletonInterface
|
||||||
{
|
{
|
||||||
@@ -216,8 +217,10 @@ class SearchResultService implements SingletonInterface
|
|||||||
$item['filterMetadata']['boardTypes'][] = $boardType;
|
$item['filterMetadata']['boardTypes'][] = $boardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($row['roomType']) && !\in_array($row['roomType'], $item['rooms'], false)) {
|
foreach (GeneralUtility::trimExplode(',', (string) ($row['roomTypes'] ?? ''), true) as $roomType) {
|
||||||
$item['rooms'][] = $row['roomType'];
|
if (!\in_array($roomType, $item['rooms'], false)) {
|
||||||
|
$item['rooms'][] = $roomType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!\in_array($row['nights'], $item['nights'], false)) {
|
if (!\in_array($row['nights'], $item['nights'], false)) {
|
||||||
|
|||||||
@@ -33,7 +33,10 @@ use EP\EpProducts\Domain\Repository\RegionRepository;
|
|||||||
use EP\EpProducts\Domain\Repository\SnowreportRepository;
|
use EP\EpProducts\Domain\Repository\SnowreportRepository;
|
||||||
use EP\EpProducts\Domain\Repository\WebcamRepository;
|
use EP\EpProducts\Domain\Repository\WebcamRepository;
|
||||||
use EP\EpProducts\Utility\SettingsUtility;
|
use EP\EpProducts\Utility\SettingsUtility;
|
||||||
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||||
|
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||||
|
use TYPO3\CMS\Core\Http\RequestFactory;
|
||||||
use TYPO3\CMS\Core\SingletonInterface;
|
use TYPO3\CMS\Core\SingletonInterface;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface;
|
use TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface;
|
||||||
@@ -44,14 +47,34 @@ class SnowreportImportService implements SingletonInterface
|
|||||||
const XML_FILE_URL = 'https://www.skiresort-service.com/xml-feed/';
|
const XML_FILE_URL = 'https://www.skiresort-service.com/xml-feed/';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* Connection and read timeout for the feed download, in seconds. A healthy response to this
|
||||||
|
* endpoint arrives in well under a second, so the ceiling is kept low enough that an outage on
|
||||||
|
* the vendor side fails visibly instead of stalling the scheduler task or the backend request.
|
||||||
*/
|
*/
|
||||||
protected static $validSnowreportUids = [];
|
const HTTP_CONNECT_TIMEOUT = 5;
|
||||||
|
const HTTP_TIMEOUT = 30;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected static $validWebcamUids = [];
|
protected $validSnowreportUids = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $validWebcamUids = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Existing records keyed by vendor_uid, preloaded once per import to avoid a query per record.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $snowreportIndex = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $webcamIndex = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
|
* @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
|
||||||
@@ -91,27 +114,62 @@ class SnowreportImportService implements SingletonInterface
|
|||||||
$this->regionRepository = $regionRepository;
|
$this->regionRepository = $regionRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TYPE_INT = 'int';
|
||||||
|
const TYPE_STRING = 'string';
|
||||||
|
const TYPE_BOOL = 'bool';
|
||||||
|
const TYPE_DATE = 'date';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Declared schema of the vendor feed: XML element name => target column and its type.
|
||||||
|
*
|
||||||
|
* XML carries no type information - every element is a string - so the type of each field is
|
||||||
|
* declared here rather than guessed from the value. Values are converted strictly according to
|
||||||
|
* this table; anything unexpected is logged and falls back to the type's empty value instead of
|
||||||
|
* silently changing type.
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected static $map = [
|
protected static $map = [
|
||||||
'region_id' => 'vendor_uid',
|
'region_id' => ['column' => 'vendor_uid', 'type' => self::TYPE_INT],
|
||||||
'region_name' => 'region_name',
|
'region_name' => ['column' => 'region_name', 'type' => self::TYPE_STRING],
|
||||||
'region_offen' => 'opened',
|
'region_offen' => ['column' => 'opened', 'type' => self::TYPE_BOOL],
|
||||||
'gletschergebiet' => 'glacier',
|
'gletschergebiet' => ['column' => 'glacier', 'type' => self::TYPE_BOOL],
|
||||||
'schneehoehe_berg' => 'snow_level_mountain',
|
'schneehoehe_berg' => ['column' => 'snow_level_mountain', 'type' => self::TYPE_INT],
|
||||||
'schneehoehe_tal' => 'snow_level_valley',
|
'schneehoehe_tal' => ['column' => 'snow_level_valley', 'type' => self::TYPE_INT],
|
||||||
'schneequalitaet' => 'snow_quality',
|
'schneequalitaet' => ['column' => 'snow_quality', 'type' => self::TYPE_STRING],
|
||||||
'letzter_schneefall' => 'last_snowfall',
|
'letzter_schneefall' => ['column' => 'last_snowfall', 'type' => self::TYPE_DATE],
|
||||||
'lifte_gesamt' => 'lifts_total',
|
'lifte_gesamt' => ['column' => 'lifts_total', 'type' => self::TYPE_INT],
|
||||||
'offene_lifte' => 'lifts_opened',
|
'offene_lifte' => ['column' => 'lifts_opened', 'type' => self::TYPE_INT],
|
||||||
'letzte_aktualisierung' => 'last_update',
|
'letzte_aktualisierung' => ['column' => 'last_update', 'type' => self::TYPE_DATE],
|
||||||
'hoehemax' => 'height_max',
|
'hoehemax' => ['column' => 'height_max', 'type' => self::TYPE_INT],
|
||||||
'hoehemin' => 'height_min',
|
'hoehemin' => ['column' => 'height_min', 'type' => self::TYPE_INT],
|
||||||
'datum_saisonstart' => 'season_start',
|
'datum_saisonstart' => ['column' => 'season_start', 'type' => self::TYPE_DATE],
|
||||||
'datum_saisonende' => 'season_end',
|
'datum_saisonende' => ['column' => 'season_end', 'type' => self::TYPE_DATE],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepted boolean representations, lowercased.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $booleanMap = [
|
||||||
|
'true' => true,
|
||||||
|
'1' => true,
|
||||||
|
'ja' => true,
|
||||||
|
'yes' => true,
|
||||||
|
'false' => false,
|
||||||
|
'0' => false,
|
||||||
|
'nein' => false,
|
||||||
|
'no' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distinct conversion problems encountered during the current import.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $conversionWarnings = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
@@ -119,39 +177,41 @@ class SnowreportImportService implements SingletonInterface
|
|||||||
{
|
{
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$file = GeneralUtility::getFileAbsFileName(self::XML_FILE_PATH);
|
$file = GeneralUtility::getFileAbsFileName(self::XML_FILE_PATH);
|
||||||
$xmlContent = file_get_contents($file);
|
|
||||||
$xmlData = simplexml_load_string($xmlContent);
|
if (!is_file($file)) {
|
||||||
|
$this->writelog(sprintf('Snowreport XML import failed: file "%s" does not exist.', $file));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$xmlData = $this->parseReportsXml((string) file_get_contents($file));
|
||||||
|
} catch (\RuntimeException $e) {
|
||||||
|
$this->writelog(sprintf('Snowreport XML import failed: %s', $e->getMessage()));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->resetImportState();
|
||||||
|
$this->buildIndexes();
|
||||||
|
|
||||||
$snowReportStoragePid = $this->getStoragePid();
|
$snowReportStoragePid = $this->getStoragePid();
|
||||||
|
|
||||||
foreach ($xmlData->schneemeldung as $reportXml)
|
foreach ($xmlData->schneemeldung as $reportXml)
|
||||||
{
|
{
|
||||||
$vendorUid = (int) $reportXml->region_id;
|
$vendorUid = (int) $reportXml->region_id;
|
||||||
$result = $this->snowreportRepository->findByVendorUid($vendorUid);
|
$snowreport = $this->getSnowreport($vendorUid);
|
||||||
if ($result->count() === 0) {
|
|
||||||
$snowreport = new Snowreport();
|
|
||||||
$this->snowreportRepository->add($snowreport);
|
|
||||||
} else {
|
|
||||||
$snowreport = $result->getFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
$row = [];
|
$row = [];
|
||||||
foreach (static::$map as $key => $column)
|
foreach (static::$map as $key => $field)
|
||||||
{
|
{
|
||||||
$valueRaw = trim($reportXml->{$key});
|
if (!isset($reportXml->{$key})) {
|
||||||
|
$this->addConversionWarning(sprintf('Element <%s> missing in feed.', $key));
|
||||||
if ($valueRaw === 'true') {
|
$row[$field['column']] = $this->getEmptyValue($field['type']);
|
||||||
$value = true;
|
continue;
|
||||||
} elseif ($valueRaw === 'false') {
|
|
||||||
$value = false;
|
|
||||||
} elseif (preg_match('/^\d{4}\-\d{2}\-\d{2}$/', $valueRaw)) {
|
|
||||||
$date = new \DateTime($valueRaw);
|
|
||||||
$value = $date->getTimestamp();
|
|
||||||
} else {
|
|
||||||
$value = (string) $valueRaw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$row[$column] = $value;
|
$row[$field['column']] = $this->convertValue((string) $reportXml->{$key}, $field['type'], $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
$snowreport->setPid($snowReportStoragePid);
|
$snowreport->setPid($snowReportStoragePid);
|
||||||
@@ -175,23 +235,24 @@ class SnowreportImportService implements SingletonInterface
|
|||||||
$this->importWebcamData($reportXml->webcam, $snowreport);
|
$this->importWebcamData($reportXml->webcam, $snowreport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($snowreport->_isNew()) {
|
// New objects are already registered via add(); only managed ones need update().
|
||||||
$this->persistenceManager->persistAll();
|
if (!$snowreport->_isNew()) {
|
||||||
} else {
|
|
||||||
$this->snowreportRepository->update($snowreport);
|
$this->snowreportRepository->update($snowreport);
|
||||||
}
|
}
|
||||||
|
|
||||||
static::$validSnowreportUids[] = $vendorUid;
|
$this->validSnowreportUids[] = $vendorUid;
|
||||||
|
|
||||||
$count++;
|
$count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->persistenceManager->persistAll();
|
$this->persistenceManager->persistAll();
|
||||||
|
|
||||||
$this->cleanupData('tx_epproducts_domain_model_webcam', static::$validWebcamUids);
|
$this->cleanupData('tx_epproducts_domain_model_webcam', $this->validWebcamUids);
|
||||||
$this->cleanupData('tx_epproducts_domain_model_snowreport', static::$validSnowreportUids);
|
$this->cleanupData('tx_epproducts_domain_model_snowreport', $this->validSnowreportUids);
|
||||||
|
$this->updateWebcamCounters();
|
||||||
|
|
||||||
$GLOBALS['BE_USER']->writelog(4, 0, 0, 0, sprintf('Snowreport XML import successful (%d records).', $count), []);
|
$this->logConversionWarnings();
|
||||||
|
$this->writelog(sprintf('Snowreport XML import successful (%d records).', $count));
|
||||||
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
@@ -205,40 +266,52 @@ class SnowreportImportService implements SingletonInterface
|
|||||||
$snowReportStoragePid = $this->getStoragePid();
|
$snowReportStoragePid = $this->getStoragePid();
|
||||||
foreach ($xml->children() as $item)
|
foreach ($xml->children() as $item)
|
||||||
{
|
{
|
||||||
$include = (string) $item->aktuell === 'true';
|
$include = $this->convertValue((string) $item->aktuell, self::TYPE_BOOL, 'aktuell');
|
||||||
$available = (string) $item->verf === 'true';
|
$available = $this->convertValue((string) $item->verf, self::TYPE_BOOL, 'verf');
|
||||||
$vendorUid = (int) $item->uid;
|
$vendorUid = (int) $item->uid;
|
||||||
$result = $this->webcamRepository->findByVendorUid($vendorUid);
|
|
||||||
// Skip invalid cams
|
$webcam = isset($this->webcamIndex[$vendorUid]) ? $this->webcamIndex[$vendorUid] : null;
|
||||||
if ($include === false && $result->count() === 0) {
|
|
||||||
|
// Skip cams that are neither current nor already known
|
||||||
|
if (null === $webcam && false === $include) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new cam if not in db yet
|
// Add new cam if not in db yet
|
||||||
if ($result->count() === 0) {
|
if (null === $webcam) {
|
||||||
$webcam = new Webcam();
|
$webcam = new Webcam();
|
||||||
$webcam->setVendorUid($vendorUid);
|
$webcam->setVendorUid($vendorUid);
|
||||||
$webcam->setPid($snowReportStoragePid);
|
$webcam->setPid($snowReportStoragePid);
|
||||||
$webcam->setUrl((string) $item->url);
|
|
||||||
$webcam->setName((string) $item->dt);
|
|
||||||
$webcam->setAvailable($available);
|
|
||||||
$this->webcamRepository->add($webcam);
|
$this->webcamRepository->add($webcam);
|
||||||
|
$this->webcamIndex[$vendorUid] = $webcam;
|
||||||
$snowreport->addWebcam($webcam);
|
$snowreport->addWebcam($webcam);
|
||||||
} else {
|
|
||||||
// Update cam in db and set availability
|
|
||||||
$webcam = $result->getFirst();
|
|
||||||
$webcam->setUrl((string) $item->url);
|
|
||||||
$webcam->setName((string) $item->dt);
|
|
||||||
$webcam->setAvailable($available && $include);
|
|
||||||
}
|
}
|
||||||
static::$validWebcamUids[] = $vendorUid;
|
|
||||||
|
$webcam->setUrl((string) $item->url);
|
||||||
|
$webcam->setName((string) $item->dt);
|
||||||
|
$webcam->setAvailable($available && $include);
|
||||||
|
|
||||||
|
$this->validWebcamUids[] = $vendorUid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags records that are no longer contained in the feed as deleted.
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @param array $validUids
|
||||||
|
* @return int Number of records flagged
|
||||||
|
*/
|
||||||
public function cleanupData($table, array $validUids)
|
public function cleanupData($table, array $validUids)
|
||||||
{
|
{
|
||||||
/** @var ConnectionPool $connectionPool */
|
/** @var ConnectionPool $connectionPool */
|
||||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||||
$qb = $connectionPool->getQueryBuilderForTable($table);
|
$qb = $connectionPool->getQueryBuilderForTable($table);
|
||||||
|
// Hidden records are still managed by the import, only deleted ones are out of scope.
|
||||||
|
$qb->getRestrictions()
|
||||||
|
->removeAll()
|
||||||
|
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
|
||||||
|
;
|
||||||
$result = $qb
|
$result = $qb
|
||||||
->select('vendor_uid')
|
->select('vendor_uid')
|
||||||
->from($table)
|
->from($table)
|
||||||
@@ -250,36 +323,293 @@ class SnowreportImportService implements SingletonInterface
|
|||||||
return (int)$row['vendor_uid'];
|
return (int)$row['vendor_uid'];
|
||||||
}, $result);
|
}, $result);
|
||||||
|
|
||||||
$obsoleteUids = array_diff($currentUids, $validUids);
|
$obsoleteUids = array_values(array_diff($currentUids, $validUids));
|
||||||
if (0 === count($obsoleteUids)) {
|
if (0 === count($obsoleteUids)) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb = $connectionPool->getQueryBuilderForTable($table);
|
$qb = $connectionPool->getQueryBuilderForTable($table);
|
||||||
$qb
|
|
||||||
->delete($table)
|
return (int) $qb
|
||||||
->where($qb->expr()->in('vendor_uid', $obsoleteUids))
|
->update($table)
|
||||||
|
->set('deleted', 1)
|
||||||
|
->set('tstamp', isset($GLOBALS['EXEC_TIME']) ? $GLOBALS['EXEC_TIME'] : time())
|
||||||
|
->where(
|
||||||
|
$qb->expr()->in(
|
||||||
|
'vendor_uid',
|
||||||
|
$qb->createNamedParameter($obsoleteUids, Connection::PARAM_INT_ARRAY)
|
||||||
|
)
|
||||||
|
)
|
||||||
->execute()
|
->execute()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculates the inline child counter on the snowreport records. Webcams are flagged as deleted
|
||||||
|
* with plain SQL, which bypasses the counter Extbase maintains for the relation.
|
||||||
|
*/
|
||||||
|
protected function updateWebcamCounters()
|
||||||
|
{
|
||||||
|
$connection = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||||
|
->getConnectionForTable('tx_epproducts_domain_model_snowreport');
|
||||||
|
|
||||||
|
$connection->executeStatement(
|
||||||
|
'UPDATE tx_epproducts_domain_model_snowreport s SET s.webcams = ('
|
||||||
|
. ' SELECT COUNT(*) FROM tx_epproducts_domain_model_webcam w'
|
||||||
|
. ' WHERE w.snowreport = s.uid AND w.deleted = 0'
|
||||||
|
. ')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the feed and replaces the local file only if the response is a usable XML document.
|
||||||
|
* The existing file is left untouched on any failure.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function downloadReportsXml()
|
public function downloadReportsXml()
|
||||||
{
|
{
|
||||||
$path = GeneralUtility::getFileAbsFileName(self::XML_FILE_PATH);
|
$path = GeneralUtility::getFileAbsFileName(self::XML_FILE_PATH);
|
||||||
$backupPath = $path . '.bak';
|
|
||||||
|
|
||||||
@copy($path, $backupPath);
|
try {
|
||||||
@unlink($path);
|
$xmlContent = $this->fetchReportsXml();
|
||||||
|
$this->parseReportsXml($xmlContent);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->writelog(sprintf(
|
||||||
|
'Snowreport XML download failed (%s). Keeping existing file.',
|
||||||
|
$e->getMessage()
|
||||||
|
));
|
||||||
|
|
||||||
$url = self::XML_FILE_URL;
|
return false;
|
||||||
exec("wget -O {$path} {$url}", $output, $return);
|
}
|
||||||
if (!$return) {
|
|
||||||
@unlink($backupPath);
|
// Write to a temporary file first and move it into place, so the feed is either the old or the
|
||||||
|
// new document, never a partially written one.
|
||||||
|
$temporaryPath = $path . '.tmp';
|
||||||
|
if (false === file_put_contents($temporaryPath, $xmlContent) || !rename($temporaryPath, $path)) {
|
||||||
|
@unlink($temporaryPath);
|
||||||
|
$this->writelog(sprintf('Snowreport XML could not be written to "%s".', $path));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
protected function fetchReportsXml()
|
||||||
|
{
|
||||||
|
/** @var RequestFactory $requestFactory */
|
||||||
|
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
|
||||||
|
|
||||||
|
$response = $requestFactory->request(self::XML_FILE_URL, 'GET', [
|
||||||
|
'connect_timeout' => self::HTTP_CONNECT_TIMEOUT,
|
||||||
|
'timeout' => self::HTTP_TIMEOUT,
|
||||||
|
'headers' => [
|
||||||
|
'Accept' => 'application/xml, text/xml',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (200 !== $response->getStatusCode()) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
sprintf('unexpected status code %d', $response->getStatusCode()),
|
||||||
|
1758000001
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) $response->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the feed and rejects documents that are unusable. Without this an empty or truncated
|
||||||
|
* response would be imported as an empty feed, and the cleanup would flag every record as deleted.
|
||||||
|
*
|
||||||
|
* @param string $xmlContent
|
||||||
|
* @return \SimpleXMLElement
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
protected function parseReportsXml($xmlContent)
|
||||||
|
{
|
||||||
|
if ('' === trim($xmlContent)) {
|
||||||
|
throw new \RuntimeException('response is empty', 1758000002);
|
||||||
|
}
|
||||||
|
|
||||||
|
$useInternalErrors = libxml_use_internal_errors(true);
|
||||||
|
libxml_clear_errors();
|
||||||
|
$xmlData = simplexml_load_string($xmlContent);
|
||||||
|
$errors = libxml_get_errors();
|
||||||
|
libxml_clear_errors();
|
||||||
|
libxml_use_internal_errors($useInternalErrors);
|
||||||
|
|
||||||
|
if (false === $xmlData) {
|
||||||
|
$message = count($errors) > 0 ? trim($errors[0]->message) : 'unknown error';
|
||||||
|
throw new \RuntimeException(sprintf('response is not valid XML (%s)', $message), 1758000003);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 === $xmlData->schneemeldung->count()) {
|
||||||
|
throw new \RuntimeException('response contains no <schneemeldung> elements', 1758000004);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $xmlData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads existing records once, keyed by vendor_uid. Replaces a repository lookup per feed record.
|
||||||
|
*/
|
||||||
|
protected function buildIndexes()
|
||||||
|
{
|
||||||
|
$this->snowreportIndex = [];
|
||||||
|
foreach ($this->snowreportRepository->findAll() as $snowreport) {
|
||||||
|
$this->snowreportIndex[(int) $snowreport->getVendorUid()] = $snowreport;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->webcamIndex = [];
|
||||||
|
foreach ($this->webcamRepository->findAll() as $webcam) {
|
||||||
|
$this->webcamIndex[(int) $webcam->getVendorUid()] = $webcam;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $vendorUid
|
||||||
|
* @return Snowreport
|
||||||
|
*/
|
||||||
|
protected function getSnowreport($vendorUid)
|
||||||
|
{
|
||||||
|
if (isset($this->snowreportIndex[$vendorUid])) {
|
||||||
|
return $this->snowreportIndex[$vendorUid];
|
||||||
|
}
|
||||||
|
|
||||||
|
$snowreport = new Snowreport();
|
||||||
|
$snowreport->setVendorUid($vendorUid);
|
||||||
|
$this->snowreportRepository->add($snowreport);
|
||||||
|
$this->snowreportIndex[$vendorUid] = $snowreport;
|
||||||
|
|
||||||
|
return $snowreport;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The service is a singleton, so per-import state must not survive into the next run.
|
||||||
|
*/
|
||||||
|
protected function resetImportState()
|
||||||
|
{
|
||||||
|
$this->validSnowreportUids = [];
|
||||||
|
$this->validWebcamUids = [];
|
||||||
|
$this->conversionWarnings = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a raw XML string to the declared type of the field.
|
||||||
|
*
|
||||||
|
* @param string $raw
|
||||||
|
* @param string $type
|
||||||
|
* @param string $key XML element name, for logging
|
||||||
|
* @return int|string|bool
|
||||||
|
*/
|
||||||
|
protected function convertValue($raw, $type, $key)
|
||||||
|
{
|
||||||
|
$raw = trim($raw);
|
||||||
|
|
||||||
|
// The feed delivers empty elements for data that is not available yet (snow levels out of
|
||||||
|
// season, for example). That is expected, not an error.
|
||||||
|
if ($raw === '') {
|
||||||
|
return $this->getEmptyValue($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case self::TYPE_STRING:
|
||||||
|
return $raw;
|
||||||
|
|
||||||
|
case self::TYPE_INT:
|
||||||
|
if (!preg_match('/^-?\d+$/', $raw)) {
|
||||||
|
$this->addConversionWarning(sprintf('<%s> expected an integer, got "%s".', $key, $raw));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) $raw;
|
||||||
|
|
||||||
|
case self::TYPE_BOOL:
|
||||||
|
$normalized = strtolower($raw);
|
||||||
|
if (!array_key_exists($normalized, static::$booleanMap)) {
|
||||||
|
$this->addConversionWarning(sprintf('<%s> expected a boolean, got "%s".', $key, $raw));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$booleanMap[$normalized];
|
||||||
|
|
||||||
|
case self::TYPE_DATE:
|
||||||
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}([ T]\d{2}:\d{2}(:\d{2})?)?$/', $raw)) {
|
||||||
|
$this->addConversionWarning(sprintf('<%s> expected a date, got "%s".', $key, $raw));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = new \DateTime($raw);
|
||||||
|
|
||||||
|
return $date->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \InvalidArgumentException(sprintf('Unknown field type "%s" declared for <%s>.', $type, $key), 1758000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $type
|
||||||
|
* @return int|string|bool
|
||||||
|
*/
|
||||||
|
protected function getEmptyValue($type)
|
||||||
|
{
|
||||||
|
if ($type === self::TYPE_STRING) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if ($type === self::TYPE_BOOL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $message
|
||||||
|
*/
|
||||||
|
protected function addConversionWarning($message)
|
||||||
|
{
|
||||||
|
// Keyed to keep one entry per distinct problem instead of one per record.
|
||||||
|
$this->conversionWarnings[$message] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a single summary entry to the log if the feed contained unexpected values.
|
||||||
|
*/
|
||||||
|
protected function logConversionWarnings()
|
||||||
|
{
|
||||||
|
if (0 === count($this->conversionWarnings)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$GLOBALS['BE_USER']->writelog(4, 0, 0, 0, 'Snowreport XML download failed. Keeping existing file.', []);
|
$messages = array_keys($this->conversionWarnings);
|
||||||
@rename($backupPath, $path);
|
$this->writelog(sprintf(
|
||||||
|
'Snowreport XML import: %d unexpected value(s) in feed: %s',
|
||||||
|
count($messages),
|
||||||
|
implode(' | ', array_slice($messages, 0, 10))
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->conversionWarnings = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scheduler task and the backend module provide a backend user, the CLI command does not.
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*/
|
||||||
|
protected function writelog($message)
|
||||||
|
{
|
||||||
|
if (isset($GLOBALS['BE_USER']) && is_object($GLOBALS['BE_USER'])) {
|
||||||
|
$GLOBALS['BE_USER']->writelog(4, 0, 0, 0, $message, []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStoragePid()
|
public function getStoragePid()
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,7 @@ return [
|
|||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_badge',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_badge',
|
||||||
'default_sortby' => 'ORDER BY title',
|
'default_sortby' => 'ORDER BY title',
|
||||||
'label' => 'title',
|
'label' => 'title',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -18,7 +19,7 @@ return [
|
|||||||
'starttime' => 'starttime',
|
'starttime' => 'starttime',
|
||||||
'endtime' => 'endtime',
|
'endtime' => 'endtime',
|
||||||
],
|
],
|
||||||
'searchFields' => 'headline,subline',
|
'searchFields' => 'title,subtitle',
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
@@ -35,6 +36,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -49,6 +51,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ return [
|
|||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_city',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_city',
|
||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'label' => 'name_internal',
|
'label' => 'name_internal',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -40,6 +41,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -54,6 +56,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -405,6 +408,7 @@ return [
|
|||||||
'label' => 'Land',
|
'label' => 'Land',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_country',
|
'foreign_table' => 'tx_epproducts_domain_model_country',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
@@ -416,6 +420,7 @@ return [
|
|||||||
'label' => 'Gebiet',
|
'label' => 'Gebiet',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_region',
|
'foreign_table' => 'tx_epproducts_domain_model_region',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
@@ -427,6 +432,7 @@ return [
|
|||||||
'label' => 'Officetipp',
|
'label' => 'Officetipp',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
||||||
'items' => [
|
'items' => [
|
||||||
|
|||||||
+3
@@ -5,6 +5,7 @@ return [
|
|||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'sortby' => 'sorting',
|
'sortby' => 'sorting',
|
||||||
'label' => 'name',
|
'label' => 'name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -43,6 +44,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -57,6 +59,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+4
-1
@@ -20,7 +20,7 @@ return [
|
|||||||
'starttime' => 'starttime',
|
'starttime' => 'starttime',
|
||||||
'endtime' => 'endtime',
|
'endtime' => 'endtime',
|
||||||
],
|
],
|
||||||
'searchFields' => 'code',
|
'searchFields' => 'room_code,room_label',
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
@@ -34,6 +34,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -48,6 +49,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -145,6 +147,7 @@ return [
|
|||||||
'label' => 'Unterkunft',
|
'label' => 'Unterkunft',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_hotel',
|
'foreign_table' => 'tx_epproducts_domain_model_hotel',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
|
|||||||
+5
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_country',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_country',
|
||||||
'label' => 'name_internal',
|
'label' => 'name_internal',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY name_internal',
|
'default_sortby' => 'ORDER BY name_internal',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -42,6 +43,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -56,6 +58,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -387,6 +390,7 @@ return [
|
|||||||
'label' => 'Officetipp',
|
'label' => 'Officetipp',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
||||||
'items' => [
|
'items' => [
|
||||||
@@ -401,6 +405,7 @@ return [
|
|||||||
'label' => 'Gebiet für Schneehöhen',
|
'label' => 'Gebiet für Schneehöhen',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'items' => [
|
'items' => [
|
||||||
['Keine Zuordnung', 0]
|
['Keine Zuordnung', 0]
|
||||||
],
|
],
|
||||||
|
|||||||
+53
@@ -38,6 +38,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -52,6 +53,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -142,6 +144,57 @@ return [
|
|||||||
'type' => 'passthrough',
|
'type' => 'passthrough',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
// Denormalized columns written by DateImportService, which rebuilds this table
|
||||||
|
// wholesale. They are TEXT NOT NULL, and MySQL cannot default that, so without a
|
||||||
|
// TCA entry DataHandler omits them and every INSERT fails under STRICT_TRANS_TABLES.
|
||||||
|
'product_keywords' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'product_teaser' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'concept_popup_text' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'country_keywords' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'region_keywords' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'city_keywords' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'hotel_keywords' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'hotel_teaser' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
'bus_pro_id' => [
|
'bus_pro_id' => [
|
||||||
'exclude' => false,
|
'exclude' => false,
|
||||||
'label' => 'BusPro ID',
|
'label' => 'BusPro ID',
|
||||||
|
|||||||
+4
-1
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_fact',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_fact',
|
||||||
'label' => 'label',
|
'label' => 'label',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY label',
|
'default_sortby' => 'ORDER BY label',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -18,7 +19,7 @@ return [
|
|||||||
'starttime' => 'starttime',
|
'starttime' => 'starttime',
|
||||||
'endtime' => 'endtime',
|
'endtime' => 'endtime',
|
||||||
],
|
],
|
||||||
'searchFields' => 'name,tags,',
|
'searchFields' => 'name,label,keywords',
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
@@ -34,6 +35,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -48,6 +50,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_faq',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_faq',
|
||||||
'label' => 'label',
|
'label' => 'label',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -35,6 +36,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -49,6 +51,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+2
@@ -5,6 +5,7 @@ return [
|
|||||||
'default_sortby' => 'ORDER BY price',
|
'default_sortby' => 'ORDER BY price',
|
||||||
'sortby' => 'sorting',
|
'sortby' => 'sorting',
|
||||||
'label' => 'title',
|
'label' => 'title',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -52,6 +53,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+1
@@ -55,6 +55,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+2
@@ -5,6 +5,7 @@ return [
|
|||||||
'default_sortby' => 'ORDER BY price',
|
'default_sortby' => 'ORDER BY price',
|
||||||
'sortby' => 'sorting',
|
'sortby' => 'sorting',
|
||||||
'label' => 'title',
|
'label' => 'title',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -53,6 +54,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+6
@@ -4,6 +4,7 @@ return [
|
|||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_hotel',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_hotel',
|
||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'label' => 'name',
|
'label' => 'name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'label_userFunc' => \EP\EpProducts\Service\LabelService::class . '->getHotelLabel',
|
'label_userFunc' => \EP\EpProducts\Service\LabelService::class . '->getHotelLabel',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -51,6 +52,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -65,6 +67,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -488,6 +491,7 @@ return [
|
|||||||
'label' => 'Land',
|
'label' => 'Land',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_country',
|
'foreign_table' => 'tx_epproducts_domain_model_country',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
@@ -499,6 +503,7 @@ return [
|
|||||||
'label' => 'Gebiet',
|
'label' => 'Gebiet',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_region',
|
'foreign_table' => 'tx_epproducts_domain_model_region',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
@@ -510,6 +515,7 @@ return [
|
|||||||
'label' => 'Ort',
|
'label' => 'Ort',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_city',
|
'foreign_table' => 'tx_epproducts_domain_model_city',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
|
|||||||
+4
-2
@@ -49,12 +49,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_infobox',
|
'foreign_table' => 'tx_epproducts_domain_model_hotel_mapping',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_infobox.pid=###CURRENT_PID### AND tx_epproducts_domain_model_infobox.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_hotel_mapping.pid=###CURRENT_PID### AND tx_epproducts_domain_model_hotel_mapping.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
@@ -114,6 +115,7 @@ return [
|
|||||||
'label' => 'Produkt',
|
'label' => 'Produkt',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_product',
|
'foreign_table' => 'tx_epproducts_domain_model_product',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
|
|||||||
+3
-1
@@ -4,6 +4,7 @@ return [
|
|||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_infobox',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_infobox',
|
||||||
'default_sortby' => 'ORDER BY title',
|
'default_sortby' => 'ORDER BY title',
|
||||||
'label' => 'title',
|
'label' => 'title',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -18,7 +19,7 @@ return [
|
|||||||
'starttime' => 'starttime',
|
'starttime' => 'starttime',
|
||||||
'endtime' => 'endtime',
|
'endtime' => 'endtime',
|
||||||
],
|
],
|
||||||
'searchFields' => 'name',
|
'searchFields' => 'title,text',
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
@@ -51,6 +52,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+5
-2
@@ -4,6 +4,7 @@ return [
|
|||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_journey',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_journey',
|
||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'label' => 'name',
|
'label' => 'name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -33,6 +34,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -47,12 +49,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_city',
|
'foreign_table' => 'tx_epproducts_domain_model_journey',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_city.pid=###CURRENT_PID### AND tx_epproducts_domain_model_city.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_journey.pid=###CURRENT_PID### AND tx_epproducts_domain_model_journey.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
|
|||||||
+3
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_matchcode',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_matchcode',
|
||||||
'label' => 'code',
|
'label' => 'code',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -34,6 +35,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -48,6 +50,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+5
-1
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_officetip',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_officetip',
|
||||||
'label' => 'label',
|
'label' => 'label',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'label_userFunc' => \EP\EpProducts\Service\LabelService::class . '->getOfficetipLabel',
|
'label_userFunc' => \EP\EpProducts\Service\LabelService::class . '->getOfficetipLabel',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -18,7 +19,7 @@ return [
|
|||||||
'starttime' => 'starttime',
|
'starttime' => 'starttime',
|
||||||
'endtime' => 'endtime',
|
'endtime' => 'endtime',
|
||||||
],
|
],
|
||||||
'searchFields' => 'text,author,product,',
|
'searchFields' => 'label,text,author',
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
@@ -34,6 +35,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -48,6 +50,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -133,6 +136,7 @@ return [
|
|||||||
'label' => 'Autor',
|
'label' => 'Autor',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_teammember',
|
'foreign_table' => 'tx_epproducts_domain_model_teammember',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
|
|||||||
+13
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_product',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_product',
|
||||||
'label' => 'name_internal',
|
'label' => 'name_internal',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'label_userFunc' => \EP\EpProducts\Service\LabelService::class . '->getProductLabel',
|
'label_userFunc' => \EP\EpProducts\Service\LabelService::class . '->getProductLabel',
|
||||||
'default_sortby' => 'ORDER BY name_internal',
|
'default_sortby' => 'ORDER BY name_internal',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
@@ -54,6 +55,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -68,6 +70,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -631,6 +634,7 @@ return [
|
|||||||
'label' => 'Konzept',
|
'label' => 'Konzept',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_concept',
|
'foreign_table' => 'tx_epproducts_domain_model_concept',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
||||||
@@ -643,6 +647,7 @@ return [
|
|||||||
'label' => 'Land',
|
'label' => 'Land',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_country',
|
'foreign_table' => 'tx_epproducts_domain_model_country',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
||||||
@@ -655,6 +660,7 @@ return [
|
|||||||
'label' => 'Gebiet',
|
'label' => 'Gebiet',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_region',
|
'foreign_table' => 'tx_epproducts_domain_model_region',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
||||||
@@ -667,6 +673,7 @@ return [
|
|||||||
'label' => 'Stadt/Ort',
|
'label' => 'Stadt/Ort',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_city',
|
'foreign_table' => 'tx_epproducts_domain_model_city',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
||||||
@@ -679,6 +686,7 @@ return [
|
|||||||
'label' => 'Anreise',
|
'label' => 'Anreise',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_journey',
|
'foreign_table' => 'tx_epproducts_domain_model_journey',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
||||||
@@ -735,6 +743,7 @@ return [
|
|||||||
'label' => 'Unterkunft für Belegungskalender',
|
'label' => 'Unterkunft für Belegungskalender',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_hotel',
|
'foreign_table' => 'tx_epproducts_domain_model_hotel',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY tx_epproducts_domain_model_hotel.name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY tx_epproducts_domain_model_hotel.name',
|
||||||
@@ -748,6 +757,7 @@ return [
|
|||||||
'label' => 'Officetipp',
|
'label' => 'Officetipp',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
||||||
'items' => [
|
'items' => [
|
||||||
@@ -787,6 +797,7 @@ return [
|
|||||||
'label' => 'Produkt',
|
'label' => 'Produkt',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_product',
|
'foreign_table' => 'tx_epproducts_domain_model_product',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_product.uid != ###THIS_UID### ORDER BY tx_epproducts_domain_model_product.name_internal',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_product.uid != ###THIS_UID### ORDER BY tx_epproducts_domain_model_product.name_internal',
|
||||||
@@ -858,6 +869,7 @@ return [
|
|||||||
'label' => 'Badge',
|
'label' => 'Badge',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_badge',
|
'foreign_table' => 'tx_epproducts_domain_model_badge',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_badge.deleted = 0 ORDER BY tx_epproducts_domain_model_badge.title',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_badge.deleted = 0 ORDER BY tx_epproducts_domain_model_badge.title',
|
||||||
@@ -873,6 +885,7 @@ return [
|
|||||||
'label' => 'Infobox nicht buchbar',
|
'label' => 'Infobox nicht buchbar',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_infobox',
|
'foreign_table' => 'tx_epproducts_domain_model_infobox',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_infobox.deleted = 0 ORDER BY tx_epproducts_domain_model_infobox.title',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_infobox.deleted = 0 ORDER BY tx_epproducts_domain_model_infobox.title',
|
||||||
|
|||||||
+7
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_region',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_region',
|
||||||
'label' => 'name_internal',
|
'label' => 'name_internal',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY name_internal',
|
'default_sortby' => 'ORDER BY name_internal',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -45,6 +46,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -59,6 +61,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
@@ -480,6 +483,7 @@ return [
|
|||||||
'label' => 'Land',
|
'label' => 'Land',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_country',
|
'foreign_table' => 'tx_epproducts_domain_model_country',
|
||||||
'minitems' => 1,
|
'minitems' => 1,
|
||||||
@@ -515,6 +519,7 @@ return [
|
|||||||
'label' => 'Officetip',
|
'label' => 'Officetip',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
'foreign_table' => 'tx_epproducts_domain_model_officetip',
|
||||||
'items' => [
|
'items' => [
|
||||||
@@ -529,6 +534,7 @@ return [
|
|||||||
'label' => 'Gebiet für Schneehöhen',
|
'label' => 'Gebiet für Schneehöhen',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['Keine Zuordnung', 0]
|
['Keine Zuordnung', 0]
|
||||||
@@ -544,6 +550,7 @@ return [
|
|||||||
'label' => 'Webcam',
|
'label' => 'Webcam',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'items' => [
|
'items' => [
|
||||||
['Keine Zuordnung', 0]
|
['Keine Zuordnung', 0]
|
||||||
],
|
],
|
||||||
|
|||||||
+3
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_reseller',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_reseller',
|
||||||
'label' => 'name',
|
'label' => 'name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -32,6 +33,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -46,6 +48,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
-141
@@ -1,141 +0,0 @@
|
|||||||
<?php
|
|
||||||
return [
|
|
||||||
'ctrl' => [
|
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_roommapping',
|
|
||||||
'label' => 'code',
|
|
||||||
'default_sortby' => 'ORDER BY code',
|
|
||||||
'tstamp' => 'tstamp',
|
|
||||||
'crdate' => 'crdate',
|
|
||||||
'cruser_id' => 'cruser_id',
|
|
||||||
'dividers2tabs' => true,
|
|
||||||
'versioningWS' => false,
|
|
||||||
'languageField' => 'sys_language_uid',
|
|
||||||
'transOrigPointerField' => 'l10n_parent',
|
|
||||||
'transOrigDiffSourceField' => 'l10n_diffsource',
|
|
||||||
'delete' => 'deleted',
|
|
||||||
'enablecolumns' => [
|
|
||||||
'disabled' => 'hidden',
|
|
||||||
'starttime' => 'starttime',
|
|
||||||
'endtime' => 'endtime',
|
|
||||||
],
|
|
||||||
'searchFields' => 'name,tags,',
|
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
|
||||||
],
|
|
||||||
'types' => [
|
|
||||||
'1' => ['showitem' => 'code, type'],
|
|
||||||
],
|
|
||||||
'palettes' => [
|
|
||||||
'1' => ['showitem' => ''],
|
|
||||||
],
|
|
||||||
'columns' => [
|
|
||||||
|
|
||||||
'sys_language_uid' => [
|
|
||||||
'exclude' => 0,
|
|
||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'select',
|
|
||||||
'renderType' => 'selectSingle',
|
|
||||||
'foreign_table' => 'sys_language',
|
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
|
||||||
'items' => [
|
|
||||||
['LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages', -1],
|
|
||||||
['LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.default_value', 0]
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'l10n_parent' => [
|
|
||||||
'displayCond' => 'FIELD:sys_language_uid:>:0',
|
|
||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'select',
|
|
||||||
'renderType' => 'selectSingle',
|
|
||||||
'items' => [
|
|
||||||
['', 0],
|
|
||||||
],
|
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_roommapping',
|
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_roommapping.pid=###CURRENT_PID### AND tx_epproducts_domain_model_roommapping.sys_language_uid IN (-1,0)',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'l10n_diffsource' => [
|
|
||||||
'config' => [
|
|
||||||
'type' => 'passthrough',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
|
|
||||||
't3ver_label' => [
|
|
||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.versionLabel',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'input',
|
|
||||||
'size' => 30,
|
|
||||||
'max' => 255,
|
|
||||||
]
|
|
||||||
],
|
|
||||||
|
|
||||||
'hidden' => [
|
|
||||||
'exclude' => 0,
|
|
||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.hidden',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'check',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'starttime' => [
|
|
||||||
'exclude' => 0,
|
|
||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.starttime',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'input',
|
|
||||||
'size' => 13,
|
|
||||||
'eval' => 'datetime',
|
|
||||||
'checkbox' => 0,
|
|
||||||
'default' => 0,
|
|
||||||
'behaviour' => [
|
|
||||||
'allowLanguageSynchronization' => true,
|
|
||||||
],
|
|
||||||
'renderType' => 'inputDateTime',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'endtime' => [
|
|
||||||
'exclude' => 0,
|
|
||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.endtime',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'input',
|
|
||||||
'size' => 13,
|
|
||||||
'eval' => 'datetime',
|
|
||||||
'checkbox' => 0,
|
|
||||||
'default' => 0,
|
|
||||||
'behaviour' => [
|
|
||||||
'allowLanguageSynchronization' => true,
|
|
||||||
],
|
|
||||||
'renderType' => 'inputDateTime',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
|
|
||||||
'code' => [
|
|
||||||
'exclude' => 0,
|
|
||||||
'label' => 'Code',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'input',
|
|
||||||
'size' => 30,
|
|
||||||
'eval' => 'trim'
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'type' => [
|
|
||||||
'exclude' => 0,
|
|
||||||
'label' => 'Typ',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'select',
|
|
||||||
'renderType' => 'selectSingle',
|
|
||||||
'items' => [
|
|
||||||
['Einzelzimmer', \EP\EpProducts\Domain\Model\Room::ROOM_TYPE_FOR_ONE],
|
|
||||||
['Doppelzimmer und Apartm. f. 2 Pers.', \EP\EpProducts\Domain\Model\Room::ROOM_TYPE_FOR_TWO],
|
|
||||||
['Zimmer und Apartm. f. 3 Pers.', \EP\EpProducts\Domain\Model\Room::ROOM_TYPE_FOR_THREE],
|
|
||||||
['Zimmer und Apartm. f. 4 Pers.', \EP\EpProducts\Domain\Model\Room::ROOM_TYPE_FOR_FOUR],
|
|
||||||
['Zimmer und Apartm. mit Anderen', \EP\EpProducts\Domain\Model\Room::ROOM_TYPE_WITH_OTHERS],
|
|
||||||
['weitere Zimmer und Apartments', \EP\EpProducts\Domain\Model\Room::ROOM_TYPE_OTHER],
|
|
||||||
],
|
|
||||||
'size' => 1,
|
|
||||||
'minItems' => 1,
|
|
||||||
'maxItems' => 1
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
+4
-1
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_snowreport',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_snowreport',
|
||||||
'label' => 'region_name',
|
'label' => 'region_name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY region_name',
|
'default_sortby' => 'ORDER BY region_name',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -18,7 +19,7 @@ return [
|
|||||||
'starttime' => 'starttime',
|
'starttime' => 'starttime',
|
||||||
'endtime' => 'endtime',
|
'endtime' => 'endtime',
|
||||||
],
|
],
|
||||||
'searchFields' => 'regionName,',
|
'searchFields' => 'region_name',
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
@@ -35,6 +36,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -49,6 +51,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+8
-2
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_staticsearchparams',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_staticsearchparams',
|
||||||
'label' => 'name',
|
'label' => 'name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -35,6 +36,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -49,12 +51,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_product',
|
'foreign_table' => 'tx_epproducts_domain_model_staticsearchparams',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_product.pid=###CURRENT_PID### AND tx_epproducts_domain_model_product.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_staticsearchparams.pid=###CURRENT_PID### AND tx_epproducts_domain_model_staticsearchparams.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
@@ -156,6 +159,7 @@ return [
|
|||||||
'label' => 'Land',
|
'label' => 'Land',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_country',
|
'foreign_table' => 'tx_epproducts_domain_model_country',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
||||||
@@ -171,6 +175,7 @@ return [
|
|||||||
'label' => 'Gebiet',
|
'label' => 'Gebiet',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_region',
|
'foreign_table' => 'tx_epproducts_domain_model_region',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY name',
|
||||||
@@ -186,6 +191,7 @@ return [
|
|||||||
'label' => 'Hotel',
|
'label' => 'Hotel',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_hotel',
|
'foreign_table' => 'tx_epproducts_domain_model_hotel',
|
||||||
'foreign_table_where' => 'AND 1=1 ORDER BY tx_epproducts_domain_model_hotel.name',
|
'foreign_table_where' => 'AND 1=1 ORDER BY tx_epproducts_domain_model_hotel.name',
|
||||||
|
|||||||
+3
@@ -4,6 +4,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_teammember',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_teammember',
|
||||||
'label' => 'name',
|
'label' => 'name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'sortby' => 'sorting',
|
'sortby' => 'sorting',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
@@ -39,6 +40,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -53,6 +55,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
|
|||||||
+6
-3
@@ -4,9 +4,11 @@ return [
|
|||||||
'title' => 'Reiseinformationen',
|
'title' => 'Reiseinformationen',
|
||||||
'default_sortby' => 'ORDER BY title',
|
'default_sortby' => 'ORDER BY title',
|
||||||
'label' => 'title',
|
'label' => 'title',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
|
'origUid' => 't3_origuid',
|
||||||
'dividers2tabs' => true,
|
'dividers2tabs' => true,
|
||||||
'versioningWS' => true,
|
'versioningWS' => true,
|
||||||
'languageField' => 'sys_language_uid',
|
'languageField' => 'sys_language_uid',
|
||||||
@@ -18,7 +20,7 @@ return [
|
|||||||
'starttime' => 'starttime',
|
'starttime' => 'starttime',
|
||||||
'endtime' => 'endtime',
|
'endtime' => 'endtime',
|
||||||
],
|
],
|
||||||
'searchFields' => 'name',
|
'searchFields' => 'title,travel_code',
|
||||||
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
@@ -55,12 +57,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_infobox',
|
'foreign_table' => 'tx_epproducts_domain_model_travelinfo',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_infobox.pid=###CURRENT_PID### AND tx_epproducts_domain_model_infobox.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_travelinfo.pid=###CURRENT_PID### AND tx_epproducts_domain_model_travelinfo.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
|
|||||||
+4
-2
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'Reiseinfo Link',
|
'title' => 'Reiseinfo Link',
|
||||||
'label' => 'title',
|
'label' => 'title',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
@@ -51,12 +52,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_faq',
|
'foreign_table' => 'tx_epproducts_domain_model_travelinfolink',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_faq.pid=###CURRENT_PID### AND tx_epproducts_domain_model_faq.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_travelinfolink.pid=###CURRENT_PID### AND tx_epproducts_domain_model_travelinfolink.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
|
|||||||
+5
-2
@@ -3,9 +3,11 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'Reiseinfo Teaser',
|
'title' => 'Reiseinfo Teaser',
|
||||||
'label' => 'title',
|
'label' => 'title',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
'cruser_id' => 'cruser_id',
|
'cruser_id' => 'cruser_id',
|
||||||
|
'origUid' => 't3_origuid',
|
||||||
'dividers2tabs' => true,
|
'dividers2tabs' => true,
|
||||||
'versioningWS' => true,
|
'versioningWS' => true,
|
||||||
'hideTable' => true,
|
'hideTable' => true,
|
||||||
@@ -51,12 +53,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_faq',
|
'foreign_table' => 'tx_epproducts_domain_model_travelinfoteaser',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_faq.pid=###CURRENT_PID### AND tx_epproducts_domain_model_faq.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_travelinfoteaser.pid=###CURRENT_PID### AND tx_epproducts_domain_model_travelinfoteaser.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
|
|||||||
+6
-2
@@ -3,6 +3,7 @@ return [
|
|||||||
'ctrl' => [
|
'ctrl' => [
|
||||||
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_webcam',
|
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_webcam',
|
||||||
'label' => 'name',
|
'label' => 'name',
|
||||||
|
'prependAtCopy' => '[COPY %s]',
|
||||||
'default_sortby' => 'ORDER BY name',
|
'default_sortby' => 'ORDER BY name',
|
||||||
'tstamp' => 'tstamp',
|
'tstamp' => 'tstamp',
|
||||||
'crdate' => 'crdate',
|
'crdate' => 'crdate',
|
||||||
@@ -33,6 +34,7 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'foreign_table' => 'sys_language',
|
'foreign_table' => 'sys_language',
|
||||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||||
@@ -47,12 +49,13 @@ return [
|
|||||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingle',
|
'renderType' => 'selectSingle',
|
||||||
'items' => [
|
'items' => [
|
||||||
['', 0],
|
['', 0],
|
||||||
],
|
],
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_snowreport',
|
'foreign_table' => 'tx_epproducts_domain_model_webcam',
|
||||||
'foreign_table_where' => 'AND tx_epproducts_domain_model_snowreport.pid=###CURRENT_PID### AND tx_epproducts_domain_model_snowreport.sys_language_uid IN (-1,0)',
|
'foreign_table_where' => 'AND tx_epproducts_domain_model_webcam.pid=###CURRENT_PID### AND tx_epproducts_domain_model_webcam.sys_language_uid IN (-1,0)',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'l10n_diffsource' => [
|
'l10n_diffsource' => [
|
||||||
@@ -152,6 +155,7 @@ return [
|
|||||||
'label' => 'Skigebiet',
|
'label' => 'Skigebiet',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'default' => 0,
|
||||||
'renderType' => 'selectSingleBox',
|
'renderType' => 'selectSingleBox',
|
||||||
'foreign_table' => 'tx_epproducts_domain_model_snowreport',
|
'foreign_table' => 'tx_epproducts_domain_model_snowreport',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -39,9 +39,6 @@
|
|||||||
<trans-unit id="tx_epproducts_domain_model_teammember">
|
<trans-unit id="tx_epproducts_domain_model_teammember">
|
||||||
<source>Mitarbeiter/Teamer</source>
|
<source>Mitarbeiter/Teamer</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="tx_epproducts_domain_model_roommapping">
|
|
||||||
<source>Zimmermapping</source>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="tx_epproducts_domain_model_journey">
|
<trans-unit id="tx_epproducts_domain_model_journey">
|
||||||
<source>Anreise</source>
|
<source>Anreise</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ CREATE TABLE tx_epproducts_domain_model_product
|
|||||||
external_link varchar(255) DEFAULT '' NOT NULL,
|
external_link varchar(255) DEFAULT '' NOT NULL,
|
||||||
tour_link varchar(255) DEFAULT '' NOT NULL,
|
tour_link varchar(255) DEFAULT '' NOT NULL,
|
||||||
path_segment varchar(255) DEFAULT '' NOT NULL,
|
path_segment varchar(255) DEFAULT '' NOT NULL,
|
||||||
description text NOT NULL,
|
|
||||||
teaser text NOT NULL,
|
teaser text NOT NULL,
|
||||||
teaser_long text NOT NULL,
|
teaser_long text NOT NULL,
|
||||||
header_title varchar(255) DEFAULT '' NOT NULL,
|
header_title varchar(255) DEFAULT '' NOT NULL,
|
||||||
@@ -495,47 +494,6 @@ CREATE TABLE tx_epproducts_domain_model_room
|
|||||||
KEY constraints (date, type)
|
KEY constraints (date, type)
|
||||||
);
|
);
|
||||||
|
|
||||||
#
|
|
||||||
# Table structure for table 'tx_epproducts_domain_model_roommapping'
|
|
||||||
#
|
|
||||||
CREATE TABLE tx_epproducts_domain_model_roommapping
|
|
||||||
(
|
|
||||||
|
|
||||||
uid int(11) NOT NULL auto_increment,
|
|
||||||
pid int(11) DEFAULT '0' NOT NULL,
|
|
||||||
|
|
||||||
code varchar(255) DEFAULT '' NOT NULL,
|
|
||||||
type int(11) DEFAULT '0' NOT NULL,
|
|
||||||
|
|
||||||
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
|
|
||||||
crdate int(11) unsigned DEFAULT '0' NOT NULL,
|
|
||||||
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
|
|
||||||
deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
|
||||||
hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
|
||||||
starttime int(11) unsigned DEFAULT '0' NOT NULL,
|
|
||||||
endtime int(11) unsigned DEFAULT '0' NOT NULL,
|
|
||||||
|
|
||||||
t3ver_oid int(11) DEFAULT '0' NOT NULL,
|
|
||||||
t3ver_id int(11) DEFAULT '0' NOT NULL,
|
|
||||||
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
|
|
||||||
t3ver_label varchar(255) DEFAULT '' NOT NULL,
|
|
||||||
t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
|
|
||||||
t3ver_stage int(11) DEFAULT '0' NOT NULL,
|
|
||||||
t3ver_count int(11) DEFAULT '0' NOT NULL,
|
|
||||||
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
|
|
||||||
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
|
|
||||||
|
|
||||||
sys_language_uid int(11) DEFAULT '0' NOT NULL,
|
|
||||||
l10n_parent int(11) DEFAULT '0' NOT NULL,
|
|
||||||
l10n_diffsource mediumblob,
|
|
||||||
|
|
||||||
PRIMARY KEY (uid),
|
|
||||||
KEY parent (pid),
|
|
||||||
KEY t3ver_oid (t3ver_oid, t3ver_wsid),
|
|
||||||
KEY language (l10n_parent, sys_language_uid)
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Table structure for table 'tx_epproducts_domain_model_concept'
|
# Table structure for table 'tx_epproducts_domain_model_concept'
|
||||||
#
|
#
|
||||||
@@ -1099,6 +1057,7 @@ CREATE TABLE tx_epproducts_domain_model_snowreport
|
|||||||
|
|
||||||
PRIMARY KEY (uid),
|
PRIMARY KEY (uid),
|
||||||
KEY parent (pid),
|
KEY parent (pid),
|
||||||
|
KEY vendor_uid (vendor_uid),
|
||||||
KEY t3ver_oid (t3ver_oid, t3ver_wsid),
|
KEY t3ver_oid (t3ver_oid, t3ver_wsid),
|
||||||
KEY language (l10n_parent, sys_language_uid)
|
KEY language (l10n_parent, sys_language_uid)
|
||||||
|
|
||||||
@@ -1143,6 +1102,7 @@ CREATE TABLE tx_epproducts_domain_model_webcam
|
|||||||
|
|
||||||
PRIMARY KEY (uid),
|
PRIMARY KEY (uid),
|
||||||
KEY parent (pid),
|
KEY parent (pid),
|
||||||
|
KEY vendor_uid (vendor_uid),
|
||||||
KEY t3ver_oid (t3ver_oid, t3ver_wsid),
|
KEY t3ver_oid (t3ver_oid, t3ver_wsid),
|
||||||
KEY language (l10n_parent, sys_language_uid)
|
KEY language (l10n_parent, sys_language_uid)
|
||||||
|
|
||||||
|
|||||||
@@ -4,25 +4,43 @@ namespace EP\EpTheme\Form;
|
|||||||
|
|
||||||
use TYPO3\CMS\Core\Log\LogManager;
|
use TYPO3\CMS\Core\Log\LogManager;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
|
||||||
use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
|
use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
|
||||||
|
|
||||||
abstract class AbstractMappedFinisher extends AbstractFinisher
|
abstract class AbstractMappedFinisher extends AbstractFinisher
|
||||||
{
|
{
|
||||||
protected function buildPayload(): array
|
/**
|
||||||
|
* Resolves the 'mapping' option into remote name => local form element identifier.
|
||||||
|
*/
|
||||||
|
protected function parseMapping(): array
|
||||||
{
|
{
|
||||||
$values = [];
|
$mappings = [];
|
||||||
$formValues = $this->finisherContext->getFormValues();
|
|
||||||
$mappingOption = (string)$this->parseOption('mapping');
|
$mappingOption = (string)$this->parseOption('mapping');
|
||||||
$mappings = GeneralUtility::trimExplode(',', $mappingOption, true);
|
|
||||||
|
|
||||||
foreach ($mappings as $mapping) {
|
foreach (GeneralUtility::trimExplode(',', $mappingOption, true) as $mapping) {
|
||||||
$parts = GeneralUtility::trimExplode(':', $mapping, true, 2);
|
$parts = GeneralUtility::trimExplode(':', $mapping, true, 2);
|
||||||
if (2 !== count($parts)) {
|
if (2 !== count($parts)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
[$remote, $local] = $parts;
|
[$remote, $local] = $parts;
|
||||||
if ('' === $remote || '' === $local || false === array_key_exists($local, $formValues)) {
|
if ('' === $remote || '' === $local) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mappings[$remote] = $local;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $mappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildPayload(): array
|
||||||
|
{
|
||||||
|
$values = [];
|
||||||
|
$formValues = $this->finisherContext->getFormValues();
|
||||||
|
|
||||||
|
foreach ($this->parseMapping() as $remote => $local) {
|
||||||
|
if (false === array_key_exists($local, $formValues)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +50,95 @@ abstract class AbstractMappedFinisher extends AbstractFinisher
|
|||||||
return $values;
|
return $values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every submitted value that the mapping does not already cover, keyed by the element label
|
||||||
|
* as the editor sees it in the form editor. Forms built in the backend use generated
|
||||||
|
* identifiers (text-1, singleselect-2, ...) that carry no meaning and cannot be renamed
|
||||||
|
* without breaking existing finisher options, so the label is the only stable description
|
||||||
|
* of what was asked.
|
||||||
|
*
|
||||||
|
* The label is taken from the form definition, not through TranslationService: a translated
|
||||||
|
* label would change the payload keys with the site language, and these keys are stored.
|
||||||
|
*/
|
||||||
|
protected function buildLabeledValues(): array
|
||||||
|
{
|
||||||
|
$formValues = $this->finisherContext->getFormValues();
|
||||||
|
$skip = array_merge(
|
||||||
|
array_values($this->parseMapping()),
|
||||||
|
GeneralUtility::trimExplode(',', (string)$this->parseOption('exclude'), true)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Keyed by identifier in form order, and contains only real form elements - iterating
|
||||||
|
// this instead of the form values keeps the collection in the order of the form and
|
||||||
|
// leaves out anything that is not an element the visitor filled in.
|
||||||
|
$elements = $this->finisherContext->getFormRuntime()->getFormDefinition()->getElements();
|
||||||
|
|
||||||
|
$collected = [];
|
||||||
|
foreach ($elements as $identifier => $element) {
|
||||||
|
if (true === in_array($identifier, $skip, true) || false === array_key_exists($identifier, $formValues)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $this->normalizeValue($formValues[$identifier], $identifier);
|
||||||
|
if (null === $value || '' === $value || [] === $value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$label = trim($element->getLabel());
|
||||||
|
if ('' === $label) {
|
||||||
|
$label = $identifier;
|
||||||
|
}
|
||||||
|
if (true === array_key_exists($label, $collected)) {
|
||||||
|
$label .= ' (' . $identifier . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
$collected[$label] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $collected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $value
|
||||||
|
*
|
||||||
|
* @return mixed null when the value has no JSON representation
|
||||||
|
*/
|
||||||
|
protected function normalizeValue($value, string $identifier)
|
||||||
|
{
|
||||||
|
if (true === is_array($value)) {
|
||||||
|
$normalized = [];
|
||||||
|
foreach ($value as $item) {
|
||||||
|
$item = $this->normalizeValue($item, $identifier);
|
||||||
|
if (null !== $item && '' !== $item) {
|
||||||
|
$normalized[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value instanceof \DateTimeInterface) {
|
||||||
|
return $value->format('Y-m-d');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value instanceof FileReference) {
|
||||||
|
$resource = $value->getOriginalResource();
|
||||||
|
|
||||||
|
return null !== $resource ? $resource->getName() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true === is_object($value)) {
|
||||||
|
$this->logWarning('Form value skipped while collecting labeled values: unsupported type.', [
|
||||||
|
'element' => $identifier,
|
||||||
|
'class' => get_class($value),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
protected function logWarning(string $message, array $context = []): void
|
protected function logWarning(string $message, array $context = []): void
|
||||||
{
|
{
|
||||||
GeneralUtility::makeInstance(LogManager::class)
|
GeneralUtility::makeInstance(LogManager::class)
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpTheme\Form;
|
||||||
|
|
||||||
|
use EP\EpProducts\MyEP\ApiClient;
|
||||||
|
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class ApplicationApiFinisher extends AbstractMappedFinisher
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ApiClient
|
||||||
|
*/
|
||||||
|
protected $apiClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ApiClient $apiClient
|
||||||
|
*/
|
||||||
|
public function injectApiClient(ApiClient $apiClient)
|
||||||
|
{
|
||||||
|
$this->apiClient = $apiClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function executeInternal()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$payload = $this->buildPayload();
|
||||||
|
if ([] === $payload) {
|
||||||
|
$this->logWarning('Application API finisher skipped: the mapping produced no values.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$formDefinition = $this->finisherContext->getFormRuntime()->getFormDefinition();
|
||||||
|
$formLabel = trim($formDefinition->getLabel());
|
||||||
|
|
||||||
|
$payload['form'] = $formDefinition->getIdentifier();
|
||||||
|
// The name the editor gave the form, so the receiving side can label a submission
|
||||||
|
// without keeping a list of identifiers. Taken from the definition rather than
|
||||||
|
// through TranslationService: a translated label would differ per site language.
|
||||||
|
$payload['formLabel'] = '' !== $formLabel ? $formLabel : $formDefinition->getIdentifier();
|
||||||
|
$payload['submittedAt'] = (new \DateTimeImmutable())->format(\DateTimeInterface::ATOM);
|
||||||
|
$payload = array_merge($payload, $this->resolvePageContext());
|
||||||
|
$payload['details'] = $this->buildLabeledValues();
|
||||||
|
|
||||||
|
$this->apiClient->submitApplication($payload);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$this->logWarning('Application API finisher request failed.', [
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The page the form was submitted from. The URL is generated through the site router in the
|
||||||
|
* visitor's language, the same way AddReferrerFinisher does it, so it is the page's canonical
|
||||||
|
* URL rather than the submit request with its form arguments attached.
|
||||||
|
*/
|
||||||
|
private function resolvePageContext(): array
|
||||||
|
{
|
||||||
|
if (false === isset($GLOBALS['TSFE']) || 0 === (int)$GLOBALS['TSFE']->id) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageUid = (int)$GLOBALS['TSFE']->id;
|
||||||
|
$context = ['pageUid' => $pageUid];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageUid);
|
||||||
|
$context['pageUrl'] = (string)$site->getRouter()->generateUri($pageUid, [
|
||||||
|
'_language' => $GLOBALS['TSFE']->getLanguage(),
|
||||||
|
]);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
// An unroutable page must not cost the submission, so the uid is sent without a URL.
|
||||||
|
$this->logWarning('Application API finisher could not resolve the page URL.', [
|
||||||
|
'pageUid' => $pageUid,
|
||||||
|
'exception' => $e,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $context;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace EP\EpTheme\ViewHelpers;
|
|
||||||
|
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
||||||
use TYPO3\CMS\Fluid\ViewHelpers\ImageViewHelper;
|
|
||||||
|
|
||||||
class LazyLoadImageViewHelper extends ImageViewHelper
|
|
||||||
{
|
|
||||||
public function initializeArguments()
|
|
||||||
{
|
|
||||||
parent::initializeArguments();
|
|
||||||
$this->registerArgument('loaderimg', 'string', '', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render(): string
|
|
||||||
{
|
|
||||||
parent::render();
|
|
||||||
|
|
||||||
$src = $this->tag->getAttribute('src');
|
|
||||||
$this->tag->removeAttribute('src');
|
|
||||||
$this->tag->addAttribute('data', ['src' => $src], false);
|
|
||||||
|
|
||||||
if (isset($this->arguments['loaderimg'])) {
|
|
||||||
$loaderImage = $this->imageService->getImage($this->arguments['loaderimg'], null, false);
|
|
||||||
$processingInstructions = [
|
|
||||||
'width' => $this->arguments['width'],
|
|
||||||
'height' => $this->arguments['height'],
|
|
||||||
'minWidth' => $this->arguments['minWidth'],
|
|
||||||
'minHeight' => $this->arguments['minHeight'],
|
|
||||||
'maxWidth' => $this->arguments['maxWidth'],
|
|
||||||
'maxHeight' => $this->arguments['maxHeight'],
|
|
||||||
];
|
|
||||||
$processedLoaderImage = $this->imageService->applyProcessingInstructions($loaderImage, $processingInstructions);
|
|
||||||
$loaderImageUri = $this->imageService->getImageUri($processedLoaderImage, $this->arguments['absolute']);
|
|
||||||
$this->tag->addAttribute('src', $loaderImageUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
$classes = $this->tag->getAttribute('class');
|
|
||||||
$classItems = GeneralUtility::trimExplode(' ', $classes, true);
|
|
||||||
$classItems[] = 'lazyload';
|
|
||||||
$classes = implode(' ', array_unique($classItems));
|
|
||||||
$this->tag->addAttribute('class', $classes);
|
|
||||||
// ensure a11y compliance
|
|
||||||
$this->tag->removeAttribute('title');
|
|
||||||
|
|
||||||
return $this->tag->render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user