Compare commits
2
Commits
8f421da599
...
8dad782603
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dad782603 | ||
|
|
0e6a65dfa0 |
@@ -0,0 +1,38 @@
|
|||||||
|
name: redis
|
||||||
|
repository: ddev/ddev-redis
|
||||||
|
version: v2.2.0
|
||||||
|
install_date: "2026-09-08T18:12:40+02:00"
|
||||||
|
project_files:
|
||||||
|
- docker-compose.redis.yaml
|
||||||
|
- redis/scripts/settings.ddev.redis.php
|
||||||
|
- redis/scripts/setup-drupal-settings.sh
|
||||||
|
- redis/scripts/setup-redis-optimized-config.sh
|
||||||
|
- redis/redis.conf
|
||||||
|
- redis/advanced.conf
|
||||||
|
- redis/append.conf
|
||||||
|
- redis/general.conf
|
||||||
|
- redis/io.conf
|
||||||
|
- redis/memory.conf
|
||||||
|
- redis/network.conf
|
||||||
|
- redis/security.conf
|
||||||
|
- redis/snapshots.conf
|
||||||
|
- commands/host/redis-backend
|
||||||
|
- commands/redis/redis-cli
|
||||||
|
- commands/redis/redis-flush
|
||||||
|
global_files: []
|
||||||
|
removal_actions:
|
||||||
|
- |
|
||||||
|
#ddev-description:Remove redis settings if applicable
|
||||||
|
files=(
|
||||||
|
"${DDEV_APPROOT}/${DDEV_DOCROOT}/sites/default/settings.ddev.redis.php"
|
||||||
|
"${DDEV_APPROOT}/.ddev/docker-compose.redis_extra.yaml"
|
||||||
|
)
|
||||||
|
for file in "${files[@]}"; do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
if grep -q '#ddev-generated' "$file"; then
|
||||||
|
rm -f "$file"
|
||||||
|
else
|
||||||
|
echo "Unwilling to remove '$file' because it does not have #ddev-generated in it; you can manually delete it if it is safe to delete."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
Executable
+124
@@ -0,0 +1,124 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#ddev-generated
|
||||||
|
|
||||||
|
## Description: Use a different key-value store for Redis
|
||||||
|
## Usage: redis-backend <image> [optimize]
|
||||||
|
## Example: ddev redis-backend redis-alpine optimize
|
||||||
|
|
||||||
|
REDIS_DOCKER_IMAGE=${1:-}
|
||||||
|
REDIS_CONFIG=${2:-}
|
||||||
|
NAME=$REDIS_DOCKER_IMAGE
|
||||||
|
|
||||||
|
function show_help() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: ddev redis-backend <image|alias> [optimize]
|
||||||
|
|
||||||
|
Choose from predefined aliases, or provide any Redis-compatible Docker image.
|
||||||
|
Note that not every Docker image can work right away, and you may need to override
|
||||||
|
the "command:" in the docker-compose.redis_extra.yaml file
|
||||||
|
|
||||||
|
Available aliases:
|
||||||
|
redis redis:7
|
||||||
|
redis-alpine redis:7-alpine
|
||||||
|
valkey valkey/valkey:8
|
||||||
|
valkey-alpine valkey/valkey:8-alpine
|
||||||
|
|
||||||
|
Custom backend:
|
||||||
|
You can specify any Docker image, e.g.:
|
||||||
|
ddev redis-backend redis:6
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
optimize Apply additional Redis configuration with resource limits
|
||||||
|
optimized Same as optimize
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
ddev redis-backend redis-alpine optimize
|
||||||
|
ddev redis-backend valkey
|
||||||
|
ddev redis-backend redis:7.2-alpine
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function optimize_config() {
|
||||||
|
[[ "$REDIS_CONFIG" != "optimized" && "$REDIS_CONFIG" != "optimize" ]] && return
|
||||||
|
ddev dotenv set .ddev/.env.redis --redis-optimized=true
|
||||||
|
}
|
||||||
|
|
||||||
|
function change_hostname() {
|
||||||
|
[[ "${REDIS_HOSTNAME:-}" == "" ]] && return
|
||||||
|
ddev dotenv set .ddev/.env.redis --redis-hostname="$REDIS_HOSTNAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
rm -f "$DDEV_APPROOT/.ddev/.env.redis"
|
||||||
|
rm -rf "$DDEV_APPROOT/.ddev/redis/"
|
||||||
|
rm -f "$DDEV_APPROOT/.ddev/docker-compose.redis.yaml" "$DDEV_APPROOT/.ddev/docker-compose.redis_extra.yaml"
|
||||||
|
|
||||||
|
redis_volume="ddev-$(ddev status -j | docker run -i --rm ddev/ddev-utilities jq -r '.raw.name')_redis"
|
||||||
|
if docker volume ls -q | grep -qw "$redis_volume"; then
|
||||||
|
ddev stop
|
||||||
|
docker volume rm "$redis_volume"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_docker_image() {
|
||||||
|
echo "Pulling ${REDIS_DOCKER_IMAGE}..."
|
||||||
|
if ! docker pull "$REDIS_DOCKER_IMAGE"; then
|
||||||
|
echo >&2 "❌ Unable to pull ${REDIS_DOCKER_IMAGE}"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function use_docker_image() {
|
||||||
|
[[ "$REDIS_DOCKER_IMAGE" != "redis:7" ]] && ddev dotenv set .ddev/.env.redis --redis-docker-image="$REDIS_DOCKER_IMAGE"
|
||||||
|
REPO=$(ddev add-on list --installed -j 2>/dev/null | docker run -i --rm ddev/ddev-utilities jq -r '.raw[] | select(.Name=="redis") | .Repository // empty' 2>/dev/null)
|
||||||
|
ddev add-on get "${REPO:-ddev/ddev-redis}"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$REDIS_DOCKER_IMAGE" in
|
||||||
|
redis)
|
||||||
|
NAME="Redis 7"
|
||||||
|
REDIS_DOCKER_IMAGE="redis:7"
|
||||||
|
;;
|
||||||
|
redis-alpine)
|
||||||
|
NAME="Redis 7 Alpine"
|
||||||
|
REDIS_DOCKER_IMAGE="redis:7-alpine"
|
||||||
|
;;
|
||||||
|
valkey)
|
||||||
|
NAME="Valkey 8"
|
||||||
|
REDIS_DOCKER_IMAGE="valkey/valkey:8"
|
||||||
|
REDIS_HOSTNAME="valkey"
|
||||||
|
;;
|
||||||
|
valkey-alpine)
|
||||||
|
NAME="Valkey 8 Alpine"
|
||||||
|
REDIS_DOCKER_IMAGE="valkey/valkey:8-alpine"
|
||||||
|
REDIS_HOSTNAME="valkey"
|
||||||
|
;;
|
||||||
|
""|--help|-h)
|
||||||
|
show_help
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
NAME="$REDIS_DOCKER_IMAGE"
|
||||||
|
# Allow unknown image, nothing to override
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
check_docker_image
|
||||||
|
cleanup
|
||||||
|
optimize_config
|
||||||
|
change_hostname
|
||||||
|
use_docker_image
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "✅ Redis backend: $REDIS_DOCKER_IMAGE"
|
||||||
|
if [[ "$REDIS_CONFIG" == "optimized" || "$REDIS_CONFIG" == "optimize" ]]; then
|
||||||
|
echo "⚙️ Redis config: optimized"
|
||||||
|
else
|
||||||
|
echo "⚙️ Redis config: default"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "📝 Commit the '.ddev' directory to version control"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "🔄 Redis config available after 'ddev restart'"
|
||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#ddev-generated
|
||||||
|
## Description: Run redis-cli inside the Redis container
|
||||||
|
## Usage: redis-cli [flags] [args]
|
||||||
|
## Example: "ddev redis-cli KEYS *" or "ddev redis-cli INFO" or "ddev redis-cli --version"
|
||||||
|
## Aliases: redis
|
||||||
|
|
||||||
|
if [ -f /etc/redis/conf/security.conf ]; then
|
||||||
|
redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" -a redis --no-auth-warning $@
|
||||||
|
else
|
||||||
|
redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" $@
|
||||||
|
fi
|
||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#ddev-generated
|
||||||
|
## Description: Flush all cache inside the Redis container
|
||||||
|
## Usage: redis-flush
|
||||||
|
## Example: "ddev redis-flush"
|
||||||
|
|
||||||
|
if [ -f /etc/redis/conf/security.conf ]; then
|
||||||
|
redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" -a redis --no-auth-warning FLUSHALL ASYNC
|
||||||
|
else
|
||||||
|
redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" FLUSHALL ASYNC
|
||||||
|
fi
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ddev-generated
|
||||||
|
services:
|
||||||
|
redis:
|
||||||
|
container_name: ddev-${DDEV_SITENAME}-redis
|
||||||
|
image: ${REDIS_DOCKER_IMAGE:-redis:7}
|
||||||
|
hostname: ${REDIS_HOSTNAME:-redis}
|
||||||
|
# These labels ensure this service is discoverable by ddev.
|
||||||
|
labels:
|
||||||
|
com.ddev.site-name: ${DDEV_SITENAME}
|
||||||
|
com.ddev.approot: ${DDEV_APPROOT}
|
||||||
|
restart: "no"
|
||||||
|
expose:
|
||||||
|
- 6379
|
||||||
|
volumes:
|
||||||
|
- ".:/mnt/ddev_config"
|
||||||
|
- "ddev-global-cache:/mnt/ddev-global-cache"
|
||||||
|
- "./redis:/etc/redis/conf"
|
||||||
|
- "redis:/data"
|
||||||
|
command: /etc/redis/conf/redis.conf
|
||||||
|
x-ddev:
|
||||||
|
describe-url-port: |
|
||||||
|
Backend: ${REDIS_DOCKER_IMAGE:-redis:7}
|
||||||
|
describe-info: |
|
||||||
|
Pass: <none>
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
redis:
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Redis configuration.
|
||||||
|
# #ddev-generated
|
||||||
|
# Example configuration files for reference:
|
||||||
|
# http://download.redis.io/redis-stable/redis.conf
|
||||||
|
# http://download.redis.io/redis-stable/sentinel.conf
|
||||||
|
|
||||||
|
maxmemory 2048mb
|
||||||
|
maxmemory-policy allkeys-lfu
|
||||||
|
|
||||||
|
# to disable Redis persistence, remove ddev-generated from this file,
|
||||||
|
# and uncomment the two lines below:
|
||||||
|
#appendonly no
|
||||||
|
#save ""
|
||||||
@@ -15,7 +15,6 @@ public/typo3conf/ext/*/
|
|||||||
public/typo3conf/ext/ep_events/Resources/Public/
|
public/typo3conf/ext/ep_events/Resources/Public/
|
||||||
public/typo3conf/ext/ep_theme/Resources/Public/
|
public/typo3conf/ext/ep_theme/Resources/Public/
|
||||||
public/typo3conf/LocalConfiguration.php
|
public/typo3conf/LocalConfiguration.php
|
||||||
public/typo3conf/AdditionalConfiguration.php
|
|
||||||
public/typo3conf/PackageStates.php
|
public/typo3conf/PackageStates.php
|
||||||
public/typo3conf/l10n
|
public/typo3conf/l10n
|
||||||
public/typo3temp
|
public/typo3temp
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"georgringer/news": "^8.5",
|
"georgringer/news": "^8.5",
|
||||||
"gridelementsteam/gridelements": "^10.0",
|
"gridelementsteam/gridelements": "^10.0",
|
||||||
"helhum/typo3-console": "^6.4",
|
"helhum/typo3-console": "^6.4",
|
||||||
|
"jweiland/replacer": "^2.1",
|
||||||
"kigkonsult/icalcreator": "^2.29",
|
"kigkonsult/icalcreator": "^2.29",
|
||||||
"league/csv": "^9.2",
|
"league/csv": "^9.2",
|
||||||
"league/oauth2-client": "^2.8",
|
"league/oauth2-client": "^2.8",
|
||||||
|
|||||||
Generated
+67
-1
@@ -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": "0842a6e9476f96ae559c7d2e900c3be2",
|
"content-hash": "e3a433b77a2142f116e57b54c4172ffa",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "b13/container",
|
"name": "b13/container",
|
||||||
@@ -1583,6 +1583,72 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-01-08T21:22:53+00:00"
|
"time": "2023-01-08T21:22:53+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "jweiland/replacer",
|
||||||
|
"version": "2.1.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/jweiland-net/replacer.git",
|
||||||
|
"reference": "feec487ea9c3573d1e8d80245dd9763352492357"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/jweiland-net/replacer/zipball/feec487ea9c3573d1e8d80245dd9763352492357",
|
||||||
|
"reference": "feec487ea9c3573d1e8d80245dd9763352492357",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"typo3/cms-core": "^9.5 || ^10.4 || ^11.0"
|
||||||
|
},
|
||||||
|
"replace": {
|
||||||
|
"typo3-ter/replacer": "self.version"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.0",
|
||||||
|
"nimut/testing-framework": "^6.0",
|
||||||
|
"phpspec/prophecy-phpunit": "^2.0",
|
||||||
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"roave/security-advisories": "dev-latest"
|
||||||
|
},
|
||||||
|
"type": "typo3-cms-extension",
|
||||||
|
"extra": {
|
||||||
|
"typo3/cms": {
|
||||||
|
"app-dir": ".build",
|
||||||
|
"web-dir": ".build/public",
|
||||||
|
"extension-key": "replacer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"JWeiland\\Replacer\\": "Classes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"GPL-2.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Pascal Rinker",
|
||||||
|
"email": "[email protected]",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Replaces string patterns from the page. You can use it to replace URLs for Content Delivery Network (CDN).",
|
||||||
|
"homepage": "http://www.jweiland.net",
|
||||||
|
"keywords": [
|
||||||
|
"TYPO3 CMS",
|
||||||
|
"jw",
|
||||||
|
"replacer",
|
||||||
|
"typo3"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"email": "[email protected]",
|
||||||
|
"issues": "https://github.com/jweiland-net/replacer/issues",
|
||||||
|
"source": "https://github.com/jweiland-net/replacer"
|
||||||
|
},
|
||||||
|
"time": "2022-06-02T09:29:20+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "kigkonsult/icalcreator",
|
"name": "kigkonsult/icalcreator",
|
||||||
"version": "v2.39.2",
|
"version": "v2.39.2",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ add('shared_dirs', [
|
|||||||
$rsyncOptions = [
|
$rsyncOptions = [
|
||||||
'exclude' => [
|
'exclude' => [
|
||||||
'.ddev',
|
'.ddev',
|
||||||
|
'.claude',
|
||||||
'.DS_Store',
|
'.DS_Store',
|
||||||
'.git',
|
'.git',
|
||||||
'.github',
|
'.github',
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$redisOptions = [
|
||||||
|
'hostname' => '/run/redis_eptypo3/redis.sock',
|
||||||
|
'port' => 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (getenv('IS_DDEV_PROJECT') == 'true') {
|
||||||
|
$redisOptions = [
|
||||||
|
'hostname' => 'redis',
|
||||||
|
'port' => 6379,
|
||||||
|
];
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS'] = array_replace_recursive(
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS'],
|
||||||
|
[
|
||||||
|
'DB' => [
|
||||||
|
'Connections' => [
|
||||||
|
'Default' => [
|
||||||
|
'dbname' => 'db',
|
||||||
|
'driver' => 'mysqli',
|
||||||
|
'host' => 'db',
|
||||||
|
'password' => 'db',
|
||||||
|
'port' => '3306',
|
||||||
|
'user' => 'db',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// This GFX configuration allows processing by installed ImageMagick 6
|
||||||
|
'GFX' => [
|
||||||
|
'processor' => 'ImageMagick',
|
||||||
|
'processor_path' => '/usr/bin/',
|
||||||
|
'processor_path_lzw' => '/usr/bin/',
|
||||||
|
],
|
||||||
|
// This mail configuration sends all emails to mailpit
|
||||||
|
'MAIL' => [
|
||||||
|
'transport' => 'smtp',
|
||||||
|
'transport_smtp_encrypt' => false,
|
||||||
|
'transport_smtp_server' => 'localhost:1025',
|
||||||
|
],
|
||||||
|
'SYS' => [
|
||||||
|
'trustedHostsPattern' => '.*.*',
|
||||||
|
'devIPmask' => '*',
|
||||||
|
'displayErrors' => 1,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_pages'] = [
|
||||||
|
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||||
|
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||||
|
'options' => $redisOptions + ['database' => 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_hash'] = [
|
||||||
|
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||||
|
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||||
|
'options' => $redisOptions + ['database' => 1],
|
||||||
|
];
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_rootline'] = [
|
||||||
|
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||||
|
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||||
|
'options' => $redisOptions + ['database' => 1],
|
||||||
|
];
|
||||||
|
|
||||||
|
// suppress php deprecation warnings flooding typo3 logs
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'] =
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'] & ~E_DEPRECATED & ~E_USER_DEPRECATED;
|
||||||
|
/*
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['BE']['cookieSameSite'] = 'lax';
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['oauth2_client'] = [
|
||||||
|
'providers' => [
|
||||||
|
'myep' => [
|
||||||
|
'label' => 'MyEP',
|
||||||
|
'iconIdentifier' => 'ep-logo',
|
||||||
|
'scopes' => [
|
||||||
|
\Waldhacker\Oauth2Client\Service\Oauth2ProviderManager::SCOPE_BACKEND,
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
'clientId' => '8df8f314ce17e8b716f86f9c24564746',
|
||||||
|
'clientSecret' => '7ff2532abc06f2b48438fc2e6e0278c8fdfb0e2de839889f4d5d17fd4a37cfffcca3bb19166331cc6ced462550611b33f08e9a3a993270d8c786a884c7fe935b',
|
||||||
|
'urlAuthorize' => 'https://myep-next-booking.ddev.site/authorize',
|
||||||
|
'urlAccessToken' => 'https://myep-next-booking.ddev.site/token',
|
||||||
|
'urlResourceOwnerDetails' => 'https://myep-next-booking.ddev.site/api/userinfo',
|
||||||
|
'scopes' => ['email', 'id', 'roles', 'profile'],
|
||||||
|
'scopeSeparator' => ' ',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
*/
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
config.tx_replacer {
|
||||||
|
enable_regex = 1
|
||||||
|
search {
|
||||||
|
10 = /"\/?(fileadmin|typo3temp|uploads)/
|
||||||
|
}
|
||||||
|
|
||||||
|
replace {
|
||||||
|
10 = "https://cdn.ep-reisen.de/$1
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user