N°8834 - Add compatibility with PHP 8.4 (#819)

* N°8834 - Add compatibility with PHP 8.4

* Rollback of scssphp/scssphp version upgrade due to compilation error
This commit is contained in:
Lenaick
2026-02-26 10:36:32 +01:00
committed by GitHub
parent d4821b7edc
commit fc967c06ce
961 changed files with 12298 additions and 7130 deletions

View File

@@ -45,7 +45,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
* @param string|null $charset The default character encoding to use for non-UTF8 strings
* @param int $flags A bit field of static::DUMP_* constants to fine tune dumps representation
*/
public function __construct($output = null, string $charset = null, int $flags = 0)
public function __construct($output = null, ?string $charset = null, int $flags = 0)
{
$this->flags = $flags;
$this->setCharset($charset ?: \ini_get('php.output_encoding') ?: \ini_get('default_charset') ?: 'UTF-8');
@@ -188,17 +188,48 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
return $s;
}
if (!\function_exists('iconv')) {
throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');
if (\function_exists('iconv')) {
if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) {
return $c;
}
if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) {
return $c;
}
}
if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) {
return $c;
}
if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) {
return $c;
$s .= $s;
$len = \strlen($s);
$mapCp1252 = false;
for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
if ($s[$i] < "\x80") {
$s[$j] = $s[$i];
} elseif ($s[$i] < "\xC0") {
$s[$j] = "\xC2";
$s[++$j] = $s[$i];
if ($s[$i] < "\xA0") {
$mapCp1252 = true;
}
} else {
$s[$j] = "\xC3";
$s[++$j] = \chr(\ord($s[$i]) - 64);
}
}
return iconv('CP850', 'UTF-8', $s);
$s = substr($s, 0, $j);
if (!$mapCp1252) {
return $s;
}
return strtr($s, [
"\xC2\x80" => '€', "\xC2\x82" => '', "\xC2\x83" => 'ƒ', "\xC2\x84" => '„',
"\xC2\x85" => '…', "\xC2\x86" => '†', "\xC2\x87" => '‡', "\xC2\x88" => 'ˆ',
"\xC2\x89" => '‰', "\xC2\x8A" => 'Š', "\xC2\x8B" => '', "\xC2\x8C" => 'Œ',
"\xC2\x8D" => 'Ž', "\xC2\x91" => '', "\xC2\x92" => '', "\xC2\x93" => '“',
"\xC2\x94" => '”', "\xC2\x95" => '•', "\xC2\x96" => '', "\xC2\x97" => '—',
"\xC2\x98" => '˜', "\xC2\x99" => '™', "\xC2\x9A" => 'š', "\xC2\x9B" => '',
"\xC2\x9C" => 'œ', "\xC2\x9E" => 'ž',
]);
}
}

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\VarDumper\Dumper;
use Symfony\Component\ErrorHandler\ErrorRenderer\FileLinkFormatter;
use Symfony\Component\VarDumper\Cloner\Cursor;
use Symfony\Component\VarDumper\Cloner\Stub;
@@ -63,7 +64,7 @@ class CliDumper extends AbstractDumper
private bool $handlesHrefGracefully;
public function __construct($output = null, string $charset = null, int $flags = 0)
public function __construct($output = null, ?string $charset = null, int $flags = 0)
{
parent::__construct($output, $charset, $flags);
@@ -82,7 +83,7 @@ class CliDumper extends AbstractDumper
]);
}
$this->displayOptions['fileLinkFormat'] = \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l';
$this->displayOptions['fileLinkFormat'] = class_exists(FileLinkFormatter::class) ? new FileLinkFormatter() : (\ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l');
}
/**
@@ -482,7 +483,7 @@ class CliDumper extends AbstractDumper
$s = $startCchr;
$c = $c[$i = 0];
do {
$s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i]));
$s .= $map[$c[$i]] ?? \sprintf('\x%02X', \ord($c[$i]));
} while (isset($c[++$i]));
return $s.$endCchr;
@@ -577,8 +578,12 @@ class CliDumper extends AbstractDumper
*/
protected function dumpLine(int $depth, bool $endOfValue = false)
{
if (null === $this->colors) {
$this->colors = $this->supportsColors();
}
if ($this->colors) {
$this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line);
$this->line = \sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line);
}
parent::dumpLine($depth);
}
@@ -616,23 +621,34 @@ class CliDumper extends AbstractDumper
}
// Follow https://no-color.org/
if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
if ('' !== (($_SERVER['NO_COLOR'] ?? getenv('NO_COLOR'))[0] ?? '')) {
return false;
}
if ('Hyper' === getenv('TERM_PROGRAM')) {
// Detect msysgit/mingw and assume this is a tty because detection
// does not work correctly, see https://github.com/composer/composer/issues/9690
if (!@stream_isatty($stream) && !\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) {
return false;
}
if ('\\' === \DIRECTORY_SEPARATOR && @sapi_windows_vt100_support($stream)) {
return true;
}
if (\DIRECTORY_SEPARATOR === '\\') {
return (\function_exists('sapi_windows_vt100_support')
&& @sapi_windows_vt100_support($stream))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
if ('Hyper' === getenv('TERM_PROGRAM')
|| false !== getenv('COLORTERM')
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
) {
return true;
}
return stream_isatty($stream);
if ('dumb' === $term = (string) getenv('TERM')) {
return false;
}
// See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157
return preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term);
}
/**
@@ -650,7 +666,7 @@ class CliDumper extends AbstractDumper
|| 'Hyper' === getenv('TERM_PROGRAM');
if (!$result) {
$version = sprintf(
$version = \sprintf(
'%s.%s.%s',
PHP_WINDOWS_VERSION_MAJOR,
PHP_WINDOWS_VERSION_MINOR,

View File

@@ -26,7 +26,7 @@ final class CliContextProvider implements ContextProviderInterface
return [
'command_line' => $commandLine = implode(' ', $_SERVER['argv'] ?? []),
'identifier' => hash('crc32b', $commandLine.$_SERVER['REQUEST_TIME_FLOAT']),
'identifier' => hash('xxh128', $commandLine.'@'.$_SERVER['REQUEST_TIME_FLOAT']),
];
}
}

View File

@@ -45,7 +45,7 @@ final class RequestContextProvider implements ContextProviderInterface
'uri' => $request->getUri(),
'method' => $request->getMethod(),
'controller' => $controller ? $this->cloner->cloneVar($controller) : $controller,
'identifier' => spl_object_hash($request),
'identifier' => hash('xxh128', spl_object_id($request).'@'.$_SERVER['REQUEST_TIME_FLOAT']),
];
}
}

View File

@@ -31,7 +31,7 @@ final class SourceContextProvider implements ContextProviderInterface
private ?string $projectDir;
private FileLinkFormatter|LegacyFileLinkFormatter|null $fileLinkFormatter;
public function __construct(string $charset = null, string $projectDir = null, FileLinkFormatter|LegacyFileLinkFormatter $fileLinkFormatter = null, int $limit = 9)
public function __construct(?string $charset = null, ?string $projectDir = null, FileLinkFormatter|LegacyFileLinkFormatter|null $fileLinkFormatter = null, int $limit = 9)
{
$this->charset = $charset;
$this->projectDir = $projectDir;

View File

@@ -75,7 +75,7 @@ class HtmlDumper extends CliDumper
];
private array $extraDisplayOptions = [];
public function __construct($output = null, string $charset = null, int $flags = 0)
public function __construct($output = null, ?string $charset = null, int $flags = 0)
{
AbstractDumper::__construct($output, $charset, $flags);
$this->dumpId = 'sf-dump-'.mt_rand();
@@ -98,7 +98,7 @@ class HtmlDumper extends CliDumper
public function setTheme(string $themeName)
{
if (!isset(static::$themes[$themeName])) {
throw new \InvalidArgumentException(sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class));
throw new \InvalidArgumentException(\sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class));
}
$this->setStyles(static::$themes[$themeName]);
@@ -663,7 +663,7 @@ pre.sf-dump:after {
height: 0;
clear: both;
}
pre.sf-dump span {
pre.sf-dump .sf-dump-ellipsization {
display: inline-flex;
}
pre.sf-dump a {
@@ -681,16 +681,12 @@ pre.sf-dump img {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAHUlEQVQY02O8zAABilCaiQEN0EeA8QuUcX9g3QEAAjcC5piyhyEAAAAASUVORK5CYII=) #D3D3D3;
}
pre.sf-dump .sf-dump-ellipsis {
display: inline-block;
overflow: visible;
text-overflow: ellipsis;
max-width: 5em;
white-space: nowrap;
overflow: hidden;
vertical-align: top;
}
pre.sf-dump .sf-dump-ellipsis+.sf-dump-ellipsis {
max-width: none;
pre.sf-dump .sf-dump-ellipsis-tail {
flex-shrink: 0;
}
pre.sf-dump code {
display:inline;
@@ -796,7 +792,7 @@ EOHTML
$this->line .= $cursor->depth >= $this->displayOptions['maxDepth'] ? ' <samp class=sf-dump-compact>' : ' <samp class=sf-dump-expanded>';
$this->endValue($cursor);
$this->line .= $this->indentPad;
$this->line .= sprintf('<img src="data:%s;base64,%s" /></samp>', $cursor->attr['content-type'], base64_encode($cursor->attr['img-data']));
$this->line .= \sprintf('<img src="data:%s;base64,%s" /></samp>', $cursor->attr['content-type'], base64_encode($cursor->attr['img-data']));
$this->endValue($cursor);
} else {
parent::dumpString($cursor, $str, $bin, $cut);
@@ -827,7 +823,7 @@ EOHTML
$r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2;
$r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex;
$this->line .= sprintf(' id=%s-ref%s', $this->dumpId, $r);
$this->line .= \sprintf(' id=%s-ref%s', $this->dumpId, $r);
}
$this->line .= $eol;
$this->dumpLine($cursor->depth);
@@ -856,73 +852,82 @@ EOHTML
if ('ref' === $style) {
if (empty($attr['count'])) {
return sprintf('<a class=sf-dump-ref>%s</a>', $v);
return \sprintf('<a class=sf-dump-ref>%s</a>', $v);
}
$r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1);
return sprintf('<a class=sf-dump-ref href=#%s-ref%s title="%d occurrences">%s</a>', $this->dumpId, $r, 1 + $attr['count'], $v);
return \sprintf('<a class=sf-dump-ref href=#%s-ref%s title="%d occurrences">%s</a>', $this->dumpId, $r, 1 + $attr['count'], $v);
}
$dumpClasses = ['sf-dump-'.$style];
$dumpTitle = '';
if ('const' === $style && isset($attr['value'])) {
$style .= sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
$dumpTitle = esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value']));
} elseif ('public' === $style) {
$style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
$dumpTitle = empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property';
} elseif ('str' === $style && 1 < $attr['length']) {
$style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
$dumpTitle = \sprintf('%d%s characters', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
} elseif ('note' === $style && 0 < ($attr['depth'] ?? 0) && false !== $c = strrpos($value, '\\')) {
$style .= ' title=""';
$attr += [
'ellipsis' => \strlen($value) - $c,
'ellipsis-type' => 'note',
'ellipsis-tail' => 1,
];
} elseif ('protected' === $style) {
$style .= ' title="Protected property"';
$dumpTitle = 'Protected property';
} elseif ('meta' === $style && isset($attr['title'])) {
$style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title'])));
$dumpTitle = esc($this->utf8Encode($attr['title']));
} elseif ('private' === $style) {
$style .= sprintf(' title="Private property defined in class:&#10;`%s`"', esc($this->utf8Encode($attr['class'])));
$dumpTitle = \sprintf('Private property defined in class:&#10;`%s`', esc($this->utf8Encode($attr['class'])));
}
if (isset($attr['ellipsis'])) {
$class = 'sf-dump-ellipsis';
$dumpClasses[] = 'sf-dump-ellipsization';
$ellipsisClass = 'sf-dump-ellipsis';
if (isset($attr['ellipsis-type'])) {
$class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']);
$ellipsisClass .= ' sf-dump-ellipsis-'.$attr['ellipsis-type'];
}
$label = esc(substr($value, -$attr['ellipsis']));
$style = str_replace(' title="', " title=\"$v\n", $style);
$v = sprintf('<span class=%s>%s</span>', $class, substr($v, 0, -\strlen($label)));
$dumpTitle = $v."\n".$dumpTitle;
$v = \sprintf('<span class="%s">%s</span>', $ellipsisClass, substr($v, 0, -\strlen($label)));
if (!empty($attr['ellipsis-tail'])) {
$tail = \strlen(esc(substr($value, -$attr['ellipsis'], $attr['ellipsis-tail'])));
$v .= sprintf('<span class=%s>%s</span>%s', $class, substr($label, 0, $tail), substr($label, $tail));
$v .= \sprintf('<span class="%s">%s</span><span class="sf-dump-ellipsis-tail">%s</span>', $ellipsisClass, substr($label, 0, $tail), substr($label, $tail));
} else {
$v .= $label;
$v .= \sprintf('<span class="sf-dump-ellipsis-tail">%s</span>', $label);
}
}
$map = static::$controlCharsMap;
$v = "<span class=sf-dump-{$style}>".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) {
$s = $b = '<span class="sf-dump-default';
$c = $c[$i = 0];
if ($ns = "\r" === $c[$i] || "\n" === $c[$i]) {
$s .= ' sf-dump-ns';
}
$s .= '">';
do {
if (("\r" === $c[$i] || "\n" === $c[$i]) !== $ns) {
$s .= '</span>'.$b;
if ($ns = !$ns) {
$s .= ' sf-dump-ns';
}
$s .= '">';
$v = \sprintf(
'<span class=%s%s%1$s%s>%s</span>',
1 === \count($dumpClasses) ? '' : '"',
implode(' ', $dumpClasses),
$dumpTitle ? ' title="'.$dumpTitle.'"' : '',
preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) {
$s = $b = '<span class="sf-dump-default';
$c = $c[$i = 0];
if ($ns = "\r" === $c[$i] || "\n" === $c[$i]) {
$s .= ' sf-dump-ns';
}
$s .= '">';
do {
if (("\r" === $c[$i] || "\n" === $c[$i]) !== $ns) {
$s .= '</span>'.$b;
if ($ns = !$ns) {
$s .= ' sf-dump-ns';
}
$s .= '">';
}
$s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i]));
} while (isset($c[++$i]));
$s .= $map[$c[$i]] ?? \sprintf('\x%02X', \ord($c[$i]));
} while (isset($c[++$i]));
return $s.'</span>';
}, $v).'</span>';
return $s.'</span>';
}, $v)
);
if (!($attr['binary'] ?? false)) {
$v = preg_replace_callback(static::$unicodeCharsRx, function ($c) {
@@ -938,10 +943,10 @@ EOHTML
$v .= '^';
}
$target = isset($attr['file']) ? '' : ' target="_blank"';
$v = sprintf('<a href="%s"%s rel="noopener noreferrer">%s</a>', esc($this->utf8Encode($attr['href'])), $target, $v);
$v = \sprintf('<a href="%s"%s rel="noopener noreferrer">%s</a>', esc($this->utf8Encode($attr['href'])), $target, $v);
}
if (isset($attr['lang'])) {
$v = sprintf('<code class="%s">%s</code>', esc($attr['lang']), $v);
$v = \sprintf('<code class="%s">%s</code>', esc($attr['lang']), $v);
}
if ('label' === $style) {
$v .= ' ';
@@ -956,7 +961,7 @@ EOHTML
protected function dumpLine(int $depth, bool $endOfValue = false)
{
if (-1 === $this->lastDepth) {
$this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line;
$this->line = \sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line;
}
if ($this->headerIsDumped !== ($this->outputStream ?? $this->lineDumper)) {
$this->line = $this->getDumpHeader().$this->line;
@@ -968,7 +973,7 @@ EOHTML
$args[] = json_encode($this->extraDisplayOptions, \JSON_FORCE_OBJECT);
}
// Replace is for BC
$this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args));
$this->line .= \sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args));
}
$this->lastDepth = $depth;

View File

@@ -30,7 +30,7 @@ class ServerDumper implements DataDumperInterface
* @param DataDumperInterface|null $wrappedDumper A wrapped instance used whenever we failed contacting the server
* @param ContextProviderInterface[] $contextProviders Context providers indexed by context name
*/
public function __construct(string $host, DataDumperInterface $wrappedDumper = null, array $contextProviders = [])
public function __construct(string $host, ?DataDumperInterface $wrappedDumper = null, array $contextProviders = [])
{
$this->connection = new Connection($host, $contextProviders);
$this->wrappedDumper = $wrappedDumper;