diff --git a/.github/workflows/compatibility.yaml b/.github/workflows/compatibility.yaml index f2afb889..822da8e0 100644 --- a/.github/workflows/compatibility.yaml +++ b/.github/workflows/compatibility.yaml @@ -38,6 +38,14 @@ jobs: - name: Validate composer.json run: composer validate --strict + # Contao 4.13 pulls in spomky-labs/otphp ^10.0 transitively, and every + # available 10.x release carries a security advisory. Composer refuses to + # resolve advisory-affected packages by default, which breaks this + # dry-run resolvability check for a transitive constraint we don't control. + # Disable the advisory block for this ephemeral CI checkout only. + - name: Allow advisory-affected transitive dependencies + run: composer config --no-plugins policy.advisories.block false + - name: Check dependency resolution run: >- composer update --dry-run --no-progress --prefer-dist diff --git a/composer.json b/composer.json index 08694a95..71985cc8 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "symfony/serializer": "^5.4 || ^6.0 || ^7.0", "symfony/string": "^5.2 || ^6.0 || ^7.0", "symfony/validator": "^5.4 || ^6.0 || ^7.0", - "twig/twig": "^3.0" + "twig/twig": "^3.13" }, "require-dev": { "contao/test-case": "^4.0 || ^5.0", diff --git a/contao/templates/content_element/flare_listview.html.twig b/contao/templates/content_element/flare_listview.html.twig index 03dda1d2..a0793c3c 100644 --- a/contao/templates/content_element/flare_listview.html.twig +++ b/contao/templates/content_element/flare_listview.html.twig @@ -1,6 +1,8 @@ {# @var \HeimrichHannot\FlareBundle\Engine\Engine flare #} {% extends '@Contao/flare/_flare_base.html.twig' %} +{% set flare_css_classes = [flare_css_classes ?? '', 'flare-listview', 'content-flare-listview'] %} + {# @var \HeimrichHannot\FlareBundle\Engine\View\InteractiveView flare_list #} {% set flare_list = flare.createView %} diff --git a/contao/templates/content_element/flare_reader.html.twig b/contao/templates/content_element/flare_reader.html.twig index aad60f8d..1492af61 100644 --- a/contao/templates/content_element/flare_reader.html.twig +++ b/contao/templates/content_element/flare_reader.html.twig @@ -3,6 +3,8 @@ {# @var \Contao\Model model #} {% extends '@Contao/flare/_flare_base.html.twig' %} +{% set flare_css_classes = [flare_css_classes ?? '', 'flare-reader', 'content-flare-reader'] %} + {% block content %}
diff --git a/contao/templates/flare/_flare_base.html.twig b/contao/templates/flare/_flare_base.html.twig index f01b7d5b..f8b69ae5 100644 --- a/contao/templates/flare/_flare_base.html.twig +++ b/contao/templates/flare/_flare_base.html.twig @@ -1,4 +1,11 @@ -{% set html_class = ('flare-listview content-flare-listview block ' ~ element_css_classes|default(class|default('')) ~ ' ' ~ flare_css_classes|default('')) %} +{% types { + element_css_classes?: 'string', + class?: 'string', + flare_css_classes?: 'string|string[]', + html_class: 'string', + html_id?: 'string', +} %} +{% set html_class = flare_str.htmlJoinClasses('block', element_css_classes ?? class ?? '', flare_css_classes ?? '') %} {% set html_id = element_html_id|default(null) %}
{% block wrapper %} diff --git a/src/Util/Str.php b/src/Util/Str.php index 830b4901..2db295b2 100644 --- a/src/Util/Str.php +++ b/src/Util/Str.php @@ -139,7 +139,7 @@ public static function wrap(mixed $value): string public static function random(int $length = 10, ?string $chars = null): string { - $chars ??= '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $chars ??= self::CHARS_ALPHANUMERIC; $max = \mb_strlen($chars, '8bit') - 1; $rand = ''; @@ -294,4 +294,39 @@ public static function coalesce(string|callable|null ...$args): ?string return null; } + + public static function htmlListClasses(string|array|null ...$classes): array + { + if (!$classes) { + return []; + } + + $normalClasses = []; + $flatClasses = Arr::flatten($classes); + + foreach ($flatClasses as $class) + { + if ($class instanceof \Closure) { + $class = $class(); + } + + if (!$class) { + continue; + } + + if (!\is_scalar($class) && !$class instanceof \Stringable) { + continue; + } + + $split = \explode(' ', (string) $class); + \array_push($normalClasses, ...$split); + } + + return \array_values(\array_unique(\array_filter($normalClasses))); + } + + public static function htmlJoinClasses(string|array|null ...$classes): string + { + return \implode(' ', self::htmlListClasses(...$classes)); + } } \ No newline at end of file