Files
Twig/extra/html-extra/HtmlAttr/InlineStyle.php
T
Dylan Pulver c072ff85b3 Fix html_attr dropping style declarations whose value is zero
InlineStyle::getValue() skipped a declaration when empty($value) was true,
which also matches 0, 0.0 and '0'. Those are ordinary CSS values (opacity: 0,
z-index: 0, margin: 0, flex-grow: 0), so they were silently dropped, and a
style map containing only such declarations omitted the attribute entirely.

The sibling SeparatedTokenList::getValue() already uses an explicit
null/false test, so class token lists keep a 0 while style declarations did
not. The numeric-key branch of InlineStyle itself never consulted empty(),
so {style: ['opacity: 0']} printed while {style: {opacity: 0}} did not.
2026-09-03 20:24:11 +03:00

73 lines
2.0 KiB
PHP

<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Twig\Extra\Html\HtmlAttr;
use Twig\Error\RuntimeError;
/**
* @author Matthias Pigulla <mp@webfactory.de>
*/
final class InlineStyle implements MergeableInterface, AttributeValueInterface
{
private readonly array $value;
public function __construct(mixed $value)
{
if (!is_iterable($value)) {
throw new RuntimeError('InlineStyle can only be created from iterable values.');
}
$this->value = [...$value];
}
public function mergeInto(mixed $previous): mixed
{
if ($previous instanceof self) {
return new self([...$previous->value, ...$this->value]);
}
if (is_iterable($previous)) {
return new self([...$previous, ...$this->value]);
}
throw new RuntimeError('Attributes using InlineStyle can only be merged with iterables or other InlineStyle instances.');
}
public function appendFrom(mixed $newValue): mixed
{
if (!is_iterable($newValue)) {
throw new RuntimeError('Only iterable values can be appended to InlineStyle.');
}
return new self([...$this->value, ...$newValue]);
}
public function getValue(): ?string
{
$style = '';
foreach ($this->value as $name => $value) {
// `0`, `0.0` and `'0'` are valid CSS values, so only the values that carry
// no declaration at all are skipped here
if (null === $value || false === $value || true === $value || '' === $value || [] === $value) {
continue;
}
if (is_numeric($name)) {
$style .= trim($value, '; ').'; ';
} else {
$style .= $name.': '.$value.'; ';
}
}
return trim($style) ?: null;
}
}