Merge branch '4.4'

* 4.4:
  Update GitHub PR template
  [DI] fix related to preloading
  [HttpKernel] fix compat with legacy DebugClassLoader
  [WebProfilerBundle] Assign automatic colors to custom Stopwatch categories
  [DI] use dirname() when possible
  Simplify usage of dirname()
  Remove Google references when not needed
  Simplify usage of dirname()
  don't dump a scalar tag value on its own line
  Remove Google references when not needed
  [DI] fix Preloader
  [HttpClient] fix calling the buffer-enabling callback
  [HttpClient] fix php notice on push
  do not perform string operations on null
  Require exact match when reading from stdin with a dash
This commit is contained in:
Nicolas Grekas 2019-09-10 19:00:13 +02:00
commit 70963e390b
83 changed files with 292 additions and 313 deletions

View File

@ -3,20 +3,19 @@
| Branch? | 4.4 for features / 3.4 or 4.3 for bug fixes <!-- see below -->
| Bug fix? | yes/no
| New feature? | yes/no <!-- please update src/**/CHANGELOG.md files -->
| BC breaks? | no <!-- see https://symfony.com/bc -->
| Deprecations? | yes/no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass? | yes <!-- please add some, will be required by reviewers -->
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| Tickets | Fix #... <!-- prefix each issue number with "Fix #", if any -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/roadmap):
- Always add tests and ensure they pass.
- Never break backward compatibility (see https://symfony.com/bc).
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too).
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch 4.4.
- Legacy code removals go to the master branch.
-->

View File

@ -21,6 +21,7 @@ return PhpCsFixer\Config::create()
'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'namespaced', 'strict' => true],
// Part of future @Symfony ruleset in PHP-CS-Fixer To be removed from the config file once upgrading
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
'combine_nested_dirname' => true,
])
->setRiskyAllowed(true)
->setFinder(

View File

@ -267,7 +267,7 @@ class Deprecation
foreach (get_declared_classes() as $class) {
if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$v = \dirname(\dirname($r->getFileName()));
$v = \dirname($r->getFileName(), 2);
if (file_exists($v.'/composer/installed.json')) {
self::$vendors[] = $v;
$loader = require $v.'/autoload.php';

View File

@ -78,11 +78,11 @@ EOF
$io = new SymfonyStyle($input, $output);
$filenames = $input->getArgument('filename');
if ('-' === ($filenames[0] ?? '')) {
if (['-'] === $filenames) {
return $this->display($input, $output, $io, [$this->validate($this->getStdin(), uniqid('sf_', true))]);
}
if (0 === \count($filenames)) {
if (!$filenames) {
$loader = $this->twig->getLoader();
if ($loader instanceof FilesystemLoader) {
$paths = [];

View File

@ -2559,7 +2559,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
public function testUrlWithDefaultProtocol()
{
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
$url = 'http://www.example.com?foo1=bar1&foo2=bar2';
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']);
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
@ -2567,7 +2567,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
[@type="text"]
[@name="name"]
[@class="my&class form-control"]
[@value="http://www.google.com?foo1=bar1&foo2=bar2"]
[@value="http://www.example.com?foo1=bar1&foo2=bar2"]
[@inputmode="url"]
'
);
@ -2575,7 +2575,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
public function testUrlWithoutDefaultProtocol()
{
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
$url = 'http://www.example.com?foo1=bar1&foo2=bar2';
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]);
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
@ -2583,7 +2583,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
[@type="url"]
[@name="name"]
[@class="my&class form-control"]
[@value="http://www.google.com?foo1=bar1&foo2=bar2"]
[@value="http://www.example.com?foo1=bar1&foo2=bar2"]
'
);
}

View File

@ -1020,7 +1020,7 @@ class FrameworkExtension extends Extension
if (class_exists('Symfony\Component\Security\Core\Exception\AuthenticationException')) {
$r = new \ReflectionClass('Symfony\Component\Security\Core\Exception\AuthenticationException');
$dirs[] = $transPaths[] = \dirname(\dirname($r->getFileName())).'/Resources/translations';
$dirs[] = $transPaths[] = \dirname($r->getFileName(), 2).'/Resources/translations';
}
$defaultDir = $container->getParameterBag()->resolveValue($config['default_path']);
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {

View File

@ -169,7 +169,7 @@ class KernelBrowser extends HttpKernelBrowser
foreach (get_declared_classes() as $class) {
if (0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$file = \dirname(\dirname($r->getFileName())).'/autoload.php';
$file = \dirname($r->getFileName(), 2).'/autoload.php';
if (file_exists($file)) {
$requires .= 'require_once '.var_export($file, true).";\n";
}

View File

@ -64,7 +64,7 @@ class CacheClearCommandTest extends TestCase
// check that app kernel file present in meta file of container's cache
$containerClass = $this->kernel->getContainer()->getParameter('kernel.container_class');
$containerRef = new \ReflectionClass($containerClass);
$containerFile = \dirname(\dirname($containerRef->getFileName())).'/'.$containerClass.'.php';
$containerFile = \dirname($containerRef->getFileName(), 2).'/'.$containerClass.'.php';
$containerMetaFile = $containerFile.'.meta';
$kernelRef = new \ReflectionObject($this->kernel);
$kernelFile = $kernelRef->getFileName();

View File

@ -43,7 +43,7 @@ class ExtensionPass implements CompilerPassInterface
$container->getDefinition('twig.extension.form')->addTag('twig.extension');
$reflClass = new \ReflectionClass('Symfony\Bridge\Twig\Extension\FormExtension');
$coreThemePath = \dirname(\dirname($reflClass->getFileName())).'/Resources/views/Form';
$coreThemePath = \dirname($reflClass->getFileName(), 2).'/Resources/views/Form';
$container->getDefinition('twig.loader.native_filesystem')->addMethodCall('addPath', [$coreThemePath]);
$paths = $container->getDefinition('twig.template_iterator')->getArgument(1);

View File

@ -1,15 +1,3 @@
/* Variables */
.sf-profiler-timeline {
--color-default: #777;
--color-section: #999;
--color-event-listener: #00B8F5;
--color-template: #66CC00;
--color-doctrine: #FF6633;
--color-messenger-middleware: #BDB81E;
--color-controller-argument-value-resolver: #8c5de6;
}
/* Legend */
.sf-profiler-timeline .legends .timeline-category {
@ -31,14 +19,6 @@
display: inline-block;
}
.sf-profiler-timeline .legends .{{ classnames.default|raw }} { border-color: var(--color-default); }
.sf-profiler-timeline .legends .{{ classnames.section|raw }} { border-color: var(--color-section); }
.sf-profiler-timeline .legends .{{ classnames.event_listener|raw }} { border-color: var(--color-event-listener); }
.sf-profiler-timeline .legends .{{ classnames.template|raw }} { border-color: var(--color-template); }
.sf-profiler-timeline .legends .{{ classnames.doctrine|raw }} { border-color: var(--color-doctrine); }
.sf-profiler-timeline .legends .{{ classnames['messenger.middleware']|raw }} { border-color: var(--color-messenger-middleware); }
.sf-profiler-timeline .legends .{{ classnames['controller.argument_value_resolver']|raw }} { border-color: var(--color-controller-argument-value-resolver); }
.timeline-graph {
margin: 1em 0;
width: 100%;
@ -82,24 +62,3 @@
.timeline-graph .timeline-period {
stroke-width: 0;
}
.timeline-graph .{{ classnames.default|raw }} .timeline-period {
fill: var(--color-default);
}
.timeline-graph .{{ classnames.section|raw }} .timeline-period {
fill: var(--color-section);
}
.timeline-graph .{{ classnames.event_listener|raw }} .timeline-period {
fill: var(--color-event-listener);
}
.timeline-graph .{{ classnames.template|raw }} .timeline-period {
fill: var(--color-template);
}
.timeline-graph .{{ classnames.doctrine|raw }} .timeline-period {
fill: var(--color-doctrine);
}
.timeline-graph .{{ classnames['messenger.middleware']|raw }} .timeline-period {
fill: var(--color-messenger-middleware);
}
.timeline-graph .{{ classnames['controller.argument_value_resolver']|raw }} .timeline-period {
fill: var(--color-controller-argument-value-resolver);
}

View File

@ -2,16 +2,6 @@
{% import _self as helper %}
{% set classnames = {
'default': 'timeline-category-default',
'section': 'timeline-category-section',
'event_listener': 'timeline-category-event-listener',
'template': 'timeline-category-template',
'doctrine': 'timeline-category-doctrine',
'messenger.middleware': 'timeline-category-messenger-middleware',
'controller.argument_value_resolver': 'timeline-category-controller-argument-value-resolver',
} %}
{% block toolbar %}
{% set has_time_events = collector.events|length > 0 %}
{% set total_time = has_time_events ? '%.0f'|format(collector.duration) : 'n/a' %}
@ -128,7 +118,7 @@
</h3>
{% endif %}
{{ helper.display_timeline(token, classnames, collector.events, collector.events.__section__.origin) }}
{{ helper.display_timeline(token, collector.events, collector.events.__section__.origin) }}
{% if profile.children|length %}
<p class="help">Note: sections with a striped background correspond to sub-requests.</p>
@ -142,7 +132,7 @@
<small>{{ events.__section__.duration }} ms</small>
</h4>
{{ helper.display_timeline(child.token, classnames, events, collector.events.__section__.origin) }}
{{ helper.display_timeline(child.token, events, collector.events.__section__.origin) }}
{% endfor %}
{% endif %}
@ -154,7 +144,7 @@
</defs>
</svg>
<style type="text/css">
{% include '@WebProfiler/Collector/time.css.twig' with classnames %}
{% include '@WebProfiler/Collector/time.css.twig' %}
</style>
<script>
{% include '@WebProfiler/Collector/time.js' %}
@ -202,16 +192,19 @@
{% endautoescape %}
{% endmacro %}
{% macro display_timeline(token, classnames, events, origin) %}
{% macro display_timeline(token, events, origin) %}
{% import _self as helper %}
<div class="sf-profiler-timeline">
<div id="legend-{{ token }}" class="legends"></div>
<svg id="timeline-{{ token }}" class="timeline-graph"></svg>
<script>{% autoescape 'js' %}
window.addEventListener('load', function onLoad() {
const theme = new Theme();
new TimelineEngine(
theme,
new SvgRenderer(document.getElementById('timeline-{{ token }}')),
new Legend(document.getElementById('legend-{{ token }}'), {{ classnames|json_encode|raw }}),
new Legend(document.getElementById('legend-{{ token }}'), theme),
document.getElementById('threshold'),
{{ helper.dump_request_data(token, events, origin) }}
);

View File

@ -2,6 +2,7 @@
class TimelineEngine {
/**
* @param {Theme} theme
* @param {Renderer} renderer
* @param {Legend} legend
* @param {Element} threshold
@ -9,7 +10,8 @@ class TimelineEngine {
* @param {Number} eventHeight
* @param {Number} horizontalMargin
*/
constructor(renderer, legend, threshold, request, eventHeight = 36, horizontalMargin = 10) {
constructor(theme, renderer, legend, threshold, request, eventHeight = 36, horizontalMargin = 10) {
this.theme = theme;
this.renderer = renderer;
this.legend = legend;
this.threshold = threshold;
@ -81,7 +83,7 @@ class TimelineEngine {
const lines = periods.map(period => this.createPeriod(period, category));
const label = this.createLabel(this.getShortName(name), duration, memory, periods[0]);
const title = this.renderer.createTitle(name);
const group = this.renderer.group([title, border, label].concat(lines), this.legend.getClassname(event.category));
const group = this.renderer.group([title, border, label].concat(lines), this.theme.getCategoryColor(event.category));
event.elements = Object.assign(event.elements || {}, { group, label, border });
@ -100,7 +102,7 @@ class TimelineEngine {
}
createPeriod(period, category) {
const timeline = this.renderer.createPath(null, 'timeline-period');
const timeline = this.renderer.createPath(null, 'timeline-period', this.theme.getCategoryColor(category));
period.draw = category === 'section' ? this.renderer.setSectionLine : this.renderer.setPeriodLine;
period.elements = Object.assign(period.elements || {}, { timeline });
@ -213,14 +215,14 @@ class TimelineEngine {
}
class Legend {
constructor(element, classnames) {
constructor(element, theme) {
this.element = element;
this.classnames = classnames;
this.theme = theme;
this.toggle = this.toggle.bind(this);
this.createCategory = this.createCategory.bind(this);
this.categories = Array.from(Object.keys(classnames)).map(this.createCategory);
this.categories = Array.from(this.theme.getDefaultCategories()).map(this.createCategory);
}
add(category) {
@ -229,8 +231,8 @@ class Legend {
createCategory(category) {
const element = document.createElement('button');
element.className = `timeline-category ${this.getClassname(category)} active`;
element.className = `timeline-category active`;
element.style.borderColor = this.theme.getCategoryColor(category);
element.innerText = category;
element.value = category;
element.type = 'button';
@ -390,13 +392,17 @@ class SvgRenderer {
return element;
}
createPath(path = null, className = null) {
createPath(path = null, className = null, color = null) {
const element = this.create('path', className);
if (path) {
element.setAttribute('d', path);
}
if (color) {
element.setAttribute('fill', color);
}
return element;
}
@ -410,3 +416,55 @@ class SvgRenderer {
return element;
}
}
class Theme {
constructor(element) {
this.reservedCategoryColors = {
'default': '#777',
'section': '#999',
'event_listener': '#00b8f5',
'template': '#66cc00',
'doctrine': '#ff6633',
'messenger_middleware': '#bdb81e',
'controller.argument_value_resolver': '#8c5de6',
};
this.customCategoryColors = [
'#dbab09', // dark yellow
'#ea4aaa', // pink
'#964b00', // brown
'#22863a', // dark green
'#0366d6', // dark blue
'#17a2b8', // teal
];
this.getCategoryColor = this.getCategoryColor.bind(this);
this.getDefaultCategories = this.getDefaultCategories.bind(this);
}
getDefaultCategories() {
return Object.keys(this.reservedCategoryColors);
}
getCategoryColor(category) {
return this.reservedCategoryColors[category] || this.getRandomColor(category);
}
getRandomColor(category) {
// instead of pure randomness, colors are assigned deterministically based on the
// category name, to ensure that each custom category always displays the same color
return this.customCategoryColors[this.hash(category) % this.customCategoryColors.length];
}
// copied from https://github.com/darkskyapp/string-hash
hash(string) {
var hash = 5381;
var i = string.length;
while(i) {
hash = (hash * 33) ^ string.charCodeAt(--i);
}
return hash >>> 0;
}
}

View File

@ -47,10 +47,10 @@ class CookieTest extends TestCase
return [
['foo=bar; path=/'],
['foo=bar; path=/foo'],
['foo=bar; domain=google.com; path=/'],
['foo=bar; domain=example.com; path=/'],
['foo=bar; domain=example.com; path=/; secure', 'https://example.com/'],
['foo=bar; path=/; httponly'],
['foo=bar; domain=google.com; path=/foo; secure; httponly', 'https://google.com/'],
['foo=bar; domain=example.com; path=/foo; secure; httponly', 'https://example.com/'],
['foo=bar=baz; path=/'],
['foo=bar%3Dbaz; path=/'],
];

View File

@ -60,7 +60,7 @@ class ComposerResource implements SelfCheckingResourceInterface
foreach (get_declared_classes() as $class) {
if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$v = \dirname(\dirname($r->getFileName()));
$v = \dirname($r->getFileName(), 2);
if (file_exists($v.'/composer/installed.json')) {
self::$runtimeVendors[$v] = @filemtime($v.'/composer/installed.json');
}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\DependencyInjection\Dumper;
use Composer\Autoload\ClassLoader;
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
@ -37,6 +39,7 @@ use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator;
use Symfony\Component\DependencyInjection\TypedReference;
use Symfony\Component\DependencyInjection\Variable;
use Symfony\Component\ErrorHandler\DebugClassLoader;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpKernel\Kernel;
@ -297,8 +300,11 @@ EOF;
$namespaceLine = $this->namespace ? "\nnamespace {$this->namespace};\n" : '';
$time = $options['build_time'];
$id = hash('crc32', $hash.$time);
$this->asFiles = false;
if ($preload && null !== $autoloadFile = $this->getAutoloadFile()) {
$autoloadFile = substr($this->export($autoloadFile), 2, -1);
if ($preload) {
$code[$options['class'].'.preload.php'] = <<<EOF
<?php
@ -307,7 +313,7 @@ EOF;
use Symfony\Component\DependencyInjection\Dumper\Preloader;
require dirname(__DIR__, 3).'/vendor/autoload.php';
require $autoloadFile;
require __DIR__.'/Container{$hash}/{$options['class']}.php';
\$classes = [];
@ -515,7 +521,6 @@ EOF;
if ($this->inlineFactories) {
$this->inlinedRequires[$file] = true;
}
$file = preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file);
$code .= sprintf("include_once %s;\n", $file);
}
@ -557,7 +562,6 @@ EOF;
}
foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) {
$file = preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file);
$code .= sprintf(" include_once %s;\n", $file);
}
}
@ -566,7 +570,6 @@ EOF;
if ($file = $def->getFile()) {
$file = $this->dumpValue($file);
$file = '(' === $file[0] ? substr($file, 1, -1) : $file;
$file = preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file);
$code .= sprintf(" include_once %s;\n", $file);
}
}
@ -1080,27 +1083,21 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class $class extends $baseClass
{
private \$parameters = [];
private \$targetDirs = [];
public function __construct()
{
EOF;
if (null !== $this->targetDirRegex) {
$dir = $this->asFiles ? '$this->targetDirs[0] = \\dirname($containerDir)' : '__DIR__';
$code .= <<<EOF
\$dir = {$dir};
for (\$i = 1; \$i <= {$this->targetDirMaxMatches}; ++\$i) {
\$this->targetDirs[\$i] = \$dir = \\dirname(\$dir);
}
EOF;
}
if ($this->asFiles) {
$code = str_replace('$parameters', "\$buildParameters;\n private \$containerDir;\n private \$parameters", $code);
$code = str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code);
$code .= " \$this->buildParameters = \$buildParameters;\n";
$code .= " \$this->containerDir = \$containerDir;\n";
if (null !== $this->targetDirRegex) {
$code = str_replace('$parameters', "\$targetDir;\n private \$parameters", $code);
$code .= ' $this->targetDir = \\dirname($containerDir);'."\n";
}
}
if (Container::class !== $this->baseClass) {
@ -1354,12 +1351,11 @@ EOF;
foreach ($lineage as $file) {
if (!isset($this->inlinedRequires[$file])) {
$this->inlinedRequires[$file] = true;
$file = preg_replace('#^\\$this->targetDirs\[(\d++)\]#', sprintf('\dirname(__DIR__, %d + $1)', $this->asFiles), $file);
$code .= sprintf("\n include_once %s;", $file);
}
}
return $code ? sprintf("\n \$this->privates['service_container'] = static function () {%s\n };\n", $code) : '';
return $code ? sprintf("\n \$this->privates['service_container'] = function () {%s\n };\n", $code) : '';
}
private function addDefaultParametersMethod(): string
@ -1378,7 +1374,7 @@ EOF;
$export = $this->exportParameters([$value]);
$export = explode('0 => ', substr(rtrim($export, " ]\n"), 2, -1), 2);
if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $export[1])) {
if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDir\.'')/", $export[1])) {
$dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]);
} else {
$php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]);
@ -1778,7 +1774,7 @@ EOF;
return $dumpedValue;
}
if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $dumpedValue)) {
if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDir\.'')/", $dumpedValue)) {
return sprintf('$this->parameters[%s]', $this->doExport($name));
}
}
@ -1979,8 +1975,10 @@ EOF;
$dirname = $this->asFiles ? '$this->containerDir' : '__DIR__';
$offset = 1 + $this->targetDirMaxMatches - \count($matches);
if ($this->asFiles || 0 < $offset) {
$dirname = sprintf('$this->targetDirs[%d]', $offset);
if (0 < $offset) {
$dirname = sprintf('\dirname(__DIR__, %d)', $offset + (int) $this->asFiles);
} elseif ($this->asFiles) {
$dirname = "\$this->targetDir.''"; // empty string concatenation on purpose
}
if ($prefix || $suffix) {
@ -2029,4 +2027,37 @@ EOF;
return $export;
}
private function getAutoloadFile(): ?string
{
if (null === $this->targetDirRegex) {
return null;
}
foreach (spl_autoload_functions() as $autoloader) {
if (!\is_array($autoloader)) {
continue;
}
if ($autoloader[0] instanceof DebugClassLoader || $autoloader[0] instanceof LegacyDebugClassLoader) {
$autoloader = $autoloader[0]->getClassLoader();
}
if (!\is_array($autoloader) || !$autoloader[0] instanceof ClassLoader || !$autoloader[0]->findFile(__CLASS__)) {
continue;
}
foreach (get_declared_classes() as $class) {
if (0 === strpos($class, 'ComposerAutoloaderInit') && $class::getLoader() === $autoloader[0]) {
$file = \dirname((new \ReflectionClass($class))->getFileName(), 2).'/autoload.php';
if (preg_match($this->targetDirRegex.'A', $file)) {
return $file;
}
}
}
}
return null;
}
}

View File

@ -38,8 +38,7 @@ class Preloader
$prev = $classes;
foreach ($classes as $c) {
if (!isset($preloaded[$c])) {
$preloaded[$c] = true;
self::doPreload($c);
self::doPreload($c, $preloaded);
}
}
$classes = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
@ -49,12 +48,14 @@ class Preloader
}
}
private static function doPreload(string $class)
private static function doPreload(string $class, array &$preloaded)
{
if (\in_array($class, ['self', 'static', 'parent'], true)) {
if (isset($preloaded[$class]) || \in_array($class, ['self', 'static', 'parent'], true)) {
return;
}
$preloaded[$class] = true;
try {
$r = new \ReflectionClass($class);
@ -68,7 +69,7 @@ class Preloader
if (\PHP_VERSION_ID >= 70400) {
foreach ($r->getProperties() as $p) {
if (($t = $p->getType()) && !$t->isBuiltin()) {
self::doPreload($t->getName());
self::doPreload($t->getName(), $preloaded);
}
}
}
@ -79,17 +80,17 @@ class Preloader
$c = $p->getDefaultValueConstantName();
if ($i = strpos($c, '::')) {
self::doPreload(substr($c, 0, $i));
self::doPreload(substr($c, 0, $i), $preloaded);
}
}
if (($t = $p->getType()) && !$t->isBuiltin()) {
self::doPreload($t->getName());
self::doPreload($t->getName(), $preloaded);
}
}
if (($t = $m->getReturnType()) && !$t->isBuiltin()) {
self::doPreload($t->getName());
self::doPreload($t->getName(), $preloaded);
}
}
} catch (\ReflectionException $e) {

View File

@ -14,6 +14,10 @@ namespace Symfony\Component\DependencyInjection;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
if (!class_exists(BaseExpressionLanguage::class)) {
throw new \ReflectionException(BaseExpressionLanguage::class.' not found.');
}
/**
* Adds some function to the default ExpressionLanguage.
*

View File

@ -107,7 +107,7 @@ class PhpDumperTest extends TestCase
$container->setParameter('foo', 'wiz'.\dirname(__DIR__));
$container->setParameter('bar', __DIR__);
$container->setParameter('baz', '%bar%/PhpDumperTest.php');
$container->setParameter('buz', \dirname(\dirname(__DIR__)));
$container->setParameter('buz', \dirname(__DIR__, 2));
$container->compile();
$dumper = new PhpDumper($container);

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Aliases_Deprecation extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -20,7 +20,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\ConstructorWithoutArgumentsContainer
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -20,7 +20,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\ConstructorWithMandatoryArgumentsContainer
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -20,7 +20,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\ConstructorWithOptionalArgumentsContainer
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -20,7 +20,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container\NoConstructorContainer
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -20,7 +20,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Container extends \Symfony\Component\DependencyInjection\Dump\AbstractContainer
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,14 +18,9 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{
$dir = __DIR__;
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
@ -61,7 +56,7 @@ class ProjectServiceContainer extends Container
*/
protected function getTestService()
{
return $this->services['test'] = new \stdClass(('wiz'.$this->targetDirs[1]), [('wiz'.$this->targetDirs[1]) => ($this->targetDirs[2].'/')]);
return $this->services['test'] = new \stdClass(('wiz'.\dirname(__DIR__, 1)), [('wiz'.\dirname(__DIR__, 1)) => (\dirname(__DIR__, 2).'/')]);
}
public function getParameter(string $name)
@ -99,29 +94,21 @@ class ProjectServiceContainer extends Container
return $this->parameterBag;
}
private $loadedDynamicParameters = [
'foo' => false,
'buz' => false,
];
private $loadedDynamicParameters = [];
private $dynamicParameters = [];
private function getDynamicParameter(string $name)
{
switch ($name) {
case 'foo': $value = ('wiz'.$this->targetDirs[1]); break;
case 'buz': $value = $this->targetDirs[2]; break;
default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
}
$this->loadedDynamicParameters[$name] = true;
return $this->dynamicParameters[$name] = $value;
throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
}
protected function getDefaultParameters(): array
{
return [
'foo' => ('wiz'.\dirname(__DIR__, 1)),
'bar' => __DIR__,
'baz' => (__DIR__.'/PhpDumperTest.php'),
'buz' => \dirname(__DIR__, 2),
];
}
}

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,14 +18,9 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{
$dir = __DIR__;
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
@ -115,7 +110,6 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
'baz' => false,
'json' => false,
'db_dsn' => false,
'env(json_file)' => false,
];
private $dynamicParameters = [];
@ -126,7 +120,6 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
case 'baz': $value = $this->getEnv('int:Baz'); break;
case 'json': $value = $this->getEnv('json:file:json_file'); break;
case 'db_dsn': $value = $this->getEnv('resolve:DB'); break;
case 'env(json_file)': $value = ($this->targetDirs[1].'/array.json'); break;
default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
}
$this->loadedDynamicParameters[$name] = true;
@ -140,6 +133,7 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
'project_dir' => '/foo/bar',
'env(FOO)' => 'foo',
'env(DB)' => 'sqlite://%project_dir%/var/data.db',
'env(json_file)' => (\dirname(__DIR__, 1).'/array.json'),
];
}
}

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -265,7 +265,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the public 'method_call1' shared service.
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo.php';
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
$this->services['method_call1'] = $instance = new \Bar\FooClass();
@ -300,7 +300,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the public 'non_shared_foo' service.
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo.php';
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
$this->factories['non_shared_foo'] = function () {
return new \Bar\FooClass();
@ -374,17 +374,14 @@ class ProjectServiceContainer extends Container
{
private $buildParameters;
private $containerDir;
private $targetDir;
private $parameters = [];
private $targetDirs = [];
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
{
$dir = $this->targetDirs[0] = \dirname($containerDir);
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->buildParameters = $buildParameters;
$this->containerDir = $containerDir;
$this->targetDir = \dirname($containerDir);
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -40,17 +40,14 @@ class ProjectServiceContainer extends Container
{
private $buildParameters;
private $containerDir;
private $targetDir;
private $parameters = [];
private $targetDirs = [];
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
{
$dir = $this->targetDirs[0] = \dirname($containerDir);
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->buildParameters = $buildParameters;
$this->containerDir = $containerDir;
$this->targetDir = \dirname($containerDir);
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
@ -90,8 +87,8 @@ class ProjectServiceContainer extends Container
'decorated' => 'decorator_service_with_name',
];
$this->privates['service_container'] = static function () {
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo.php';
$this->privates['service_container'] = function () {
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
};
}
@ -287,7 +284,7 @@ class ProjectServiceContainer extends Container
*/
protected function getFoo_BazService()
{
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/classes.php';
include_once $this->targetDir.''.'/Fixtures/includes/classes.php';
$this->services['foo.baz'] = $instance = \BazClass::getInstance();
@ -331,7 +328,7 @@ class ProjectServiceContainer extends Container
*/
protected function getLazyContextService()
{
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/classes.php';
include_once $this->targetDir.''.'/Fixtures/includes/classes.php';
return $this->services['lazy_context'] = new \LazyContext(new RewindableGenerator(function () {
yield 'k1' => ($this->services['foo.baz'] ?? $this->getFoo_BazService());
@ -348,7 +345,7 @@ class ProjectServiceContainer extends Container
*/
protected function getLazyContextIgnoreInvalidRefService()
{
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/classes.php';
include_once $this->targetDir.''.'/Fixtures/includes/classes.php';
return $this->services['lazy_context_ignore_invalid_ref'] = new \LazyContext(new RewindableGenerator(function () {
yield 0 => ($this->services['foo.baz'] ?? $this->getFoo_BazService());
@ -364,7 +361,7 @@ class ProjectServiceContainer extends Container
*/
protected function getMethodCall1Service()
{
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo.php';
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
$this->services['method_call1'] = $instance = new \Bar\FooClass();
@ -399,7 +396,7 @@ class ProjectServiceContainer extends Container
*/
protected function getNonSharedFooService()
{
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo.php';
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
return new \Bar\FooClass();
}

View File

@ -30,17 +30,14 @@ class ProjectServiceContainer extends Container
{
private $buildParameters;
private $containerDir;
private $targetDir;
private $parameters = [];
private $targetDirs = [];
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
{
$dir = $this->targetDirs[0] = \dirname($containerDir);
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->buildParameters = $buildParameters;
$this->containerDir = $containerDir;
$this->targetDir = \dirname($containerDir);
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
@ -92,7 +89,7 @@ class ProjectServiceContainer extends Container
});
}
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo_lazy.php';
include_once $this->targetDir.''.'/Fixtures/includes/foo_lazy.php';
return new \Bar\FooClass(new \Bar\FooLazyClass());
}
@ -159,7 +156,7 @@ class ProjectServiceContainer extends Container
];
}
}
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo.php';
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
class FooClass_%s extends \Bar\FooClass implements \ProxyManager\Proxy\VirtualProxyInterface
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,14 +18,9 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{
$dir = __DIR__;
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
@ -63,7 +58,7 @@ class ProjectServiceContainer extends Container
{
$this->services['bar'] = $instance = new \BarClass();
$instance->setBaz($this->parameters['array_1'], $this->getParameter('array_2'), '%array_1%', $this->parameters['array_1']);
$instance->setBaz($this->parameters['array_1'], $this->parameters['array_2'], '%array_1%', $this->parameters['array_1']);
return $instance;
}
@ -103,22 +98,12 @@ class ProjectServiceContainer extends Container
return $this->parameterBag;
}
private $loadedDynamicParameters = [
'array_2' => false,
];
private $loadedDynamicParameters = [];
private $dynamicParameters = [];
private function getDynamicParameter(string $name)
{
switch ($name) {
case 'array_2': $value = [
0 => ($this->targetDirs[2].'/Dumper'),
]; break;
default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
}
$this->loadedDynamicParameters[$name] = true;
return $this->dynamicParameters[$name] = $value;
throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
}
protected function getDefaultParameters(): array
@ -127,6 +112,9 @@ class ProjectServiceContainer extends Container
'array_1' => [
0 => 123,
],
'array_2' => [
0 => (\dirname(__DIR__, 2).'/Dumper'),
],
];
}
}

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Base64Parameters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_CsvParameters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Deep_Graph extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_DefaultParameters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Errored_Definition extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,14 +18,9 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{
$dir = __DIR__;
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
@ -37,11 +32,11 @@ class ProjectServiceContainer extends Container
$this->aliases = [];
$this->privates['service_container'] = static function () {
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/I1.php';
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/P1.php';
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/T1.php';
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/C1.php';
$this->privates['service_container'] = function () {
include_once \dirname(__DIR__, 1).'/includes/HotPath/I1.php';
include_once \dirname(__DIR__, 1).'/includes/HotPath/P1.php';
include_once \dirname(__DIR__, 1).'/includes/HotPath/T1.php';
include_once \dirname(__DIR__, 1).'/includes/HotPath/C1.php';
};
}
@ -91,8 +86,8 @@ class ProjectServiceContainer extends Container
*/
protected function getC2Service()
{
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/C2.php';
include_once \dirname(__DIR__, 0 + 1).'/includes/HotPath/C3.php';
include_once \dirname(__DIR__, 1).'/includes/HotPath/C2.php';
include_once \dirname(__DIR__, 1).'/includes/HotPath/C3.php';
return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3());
}

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Inline_Self_Ref extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_JsonParameters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -15,7 +15,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the public 'non_shared_foo' service.
include_once \dirname(__DIR__, 1 + 0).'/Fixtures/includes/foo_lazy.php';
include_once $this->targetDir.''.'/Fixtures/includes/foo_lazy.php';
$this->factories['non_shared_foo'] = function ($lazyLoad = true) {
return new \Bar\FooLazyClass();
@ -46,17 +46,14 @@ class ProjectServiceContainer extends Container
{
private $buildParameters;
private $containerDir;
private $targetDir;
private $parameters = [];
private $targetDirs = [];
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
{
$dir = $this->targetDirs[0] = \dirname($containerDir);
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = \dirname($dir);
}
$this->buildParameters = $buildParameters;
$this->containerDir = $containerDir;
$this->targetDir = \dirname($containerDir);
$this->services = $this->privates = [];
$this->fileMap = [
'non_shared_foo' => 'getNonSharedFooService.php',

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_QueryStringParameters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container
{
private $parameters = [];
private $targetDirs = [];
private $getService;
public function __construct()

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Service_Locator_Argument extends Container
{
private $parameters = [];
private $targetDirs = [];
private $getService;
public function __construct()

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
private $getService;
public function __construct()

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProjectServiceContainer extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Uninitialized_Reference extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_Unsupported_Characters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Test_UrlParameters extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Symfony_DI_PhpDumper_Service_Wither extends Container
{
private $parameters = [];
private $targetDirs = [];
public function __construct()
{

View File

@ -32,7 +32,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
}
if ($function[0] instanceof ComposerClassLoader) {
$function[0]->add('Symfony_Component_ErrorHandler_Tests_Fixtures', \dirname(\dirname(\dirname(\dirname(\dirname(__DIR__))))));
$function[0]->add('Symfony_Component_ErrorHandler_Tests_Fixtures', \dirname(__DIR__, 5));
break;
}
}

View File

@ -2289,14 +2289,14 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
public function testUrlWithDefaultProtocol()
{
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
$url = 'http://www.example.com?foo1=bar1&foo2=bar2';
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => 'http']);
$this->assertWidgetMatchesXpath($form->createView(), [],
'/input
[@type="text"]
[@name="name"]
[@value="http://www.google.com?foo1=bar1&foo2=bar2"]
[@value="http://www.example.com?foo1=bar1&foo2=bar2"]
[@inputmode="url"]
'
);
@ -2304,14 +2304,14 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
public function testUrlWithoutDefaultProtocol()
{
$url = 'http://www.google.com?foo1=bar1&foo2=bar2';
$url = 'http://www.example.com?foo1=bar1&foo2=bar2';
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\UrlType', $url, ['default_protocol' => null]);
$this->assertWidgetMatchesXpath($form->createView(), [],
'/input
[@type="url"]
[@name="name"]
[@value="http://www.google.com?foo1=bar1&foo2=bar2"]
[@value="http://www.example.com?foo1=bar1&foo2=bar2"]
'
);
}

View File

@ -29,15 +29,15 @@ class TranslationFilesTest extends TestCase
{
return array_map(
function ($filePath) { return (array) $filePath; },
glob(\dirname(\dirname(__DIR__)).'/Resources/translations/*.xlf')
glob(\dirname(__DIR__, 2).'/Resources/translations/*.xlf')
);
}
public function testNorwegianAlias()
{
$this->assertFileEquals(
\dirname(\dirname(__DIR__)).'/Resources/translations/validators.nb.xlf',
\dirname(\dirname(__DIR__)).'/Resources/translations/validators.no.xlf',
\dirname(__DIR__, 2).'/Resources/translations/validators.nb.xlf',
\dirname(__DIR__, 2).'/Resources/translations/validators.no.xlf',
'The NO locale should be an alias for the NB variant of the Norwegian language.'
);
}

View File

@ -506,7 +506,9 @@ trait HttpClientTrait
private static function shouldBuffer(array $headers): bool
{
$contentType = $headers['content-type'][0] ?? null;
if (null === $contentType = $headers['content-type'][0] ?? null) {
return false;
}
if (false !== $i = strpos($contentType, ';')) {
$contentType = substr($contentType, 0, $i);

View File

@ -64,14 +64,26 @@ final class CurlResponse implements ResponseInterface
}
if (null === $content = &$this->content) {
$content = true === $options['buffer'] ? fopen('php://temp', 'w+') : null;
$content = null === $options || true === $options['buffer'] ? fopen('php://temp', 'w+') : null;
} else {
// Move the pushed response to the activity list
if (ftell($content)) {
rewind($content);
$multi->handlesActivity[$id][] = stream_get_contents($content);
$buffer = $options['buffer'];
if ('headers' !== curl_getinfo($ch, CURLINFO_PRIVATE)) {
if ($options['buffer'] instanceof \Closure) {
[$content, $buffer] = [null, $content];
[$content, $buffer] = [$buffer, (bool) $options['buffer']($headers)];
}
if (ftell($content)) {
rewind($content);
$multi->handlesActivity[$id][] = stream_get_contents($content);
}
}
if (true !== $buffer) {
$content = null;
}
$content = true === $options['buffer'] ? $content : null;
}
curl_setopt($ch, CURLOPT_HEADERFUNCTION, static function ($ch, string $data) use (&$info, &$headers, $options, $multi, $id, &$location, $resolveRedirect, $logger, &$content): int {
@ -349,11 +361,11 @@ final class CurlResponse implements ResponseInterface
return 0;
}
if ($options['buffer'] instanceof \Closure && !$content && $options['buffer']($headers)) {
curl_setopt($ch, CURLOPT_PRIVATE, 'content');
if (!$content && $options['buffer'] instanceof \Closure && $options['buffer']($headers)) {
$content = fopen('php://temp', 'w+');
}
curl_setopt($ch, CURLOPT_PRIVATE, 'content');
} elseif (null !== $info['redirect_url'] && $logger) {
$logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url']));
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\HttpKernel\DependencyInjection;
use Composer\Autoload\ClassLoader;
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\ErrorHandler\DebugClassLoader;
@ -90,7 +91,7 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface
continue;
}
if ($function[0] instanceof DebugClassLoader) {
if ($function[0] instanceof DebugClassLoader || $function[0] instanceof LegacyDebugClassLoader) {
$function = $function[0]->getClassLoader();
}

View File

@ -34,10 +34,7 @@ class HttpKernelBrowser extends AbstractBrowser
private $catchExceptions = true;
/**
* @param HttpKernelInterface $kernel An HttpKernel instance
* @param array $server The server parameters (equivalent of $_SERVER)
* @param History $history A History instance to store the browser history
* @param CookieJar $cookieJar A CookieJar instance to store the cookies
* @param array $server The server parameters (equivalent of $_SERVER)
*/
public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null)
{
@ -88,7 +85,7 @@ class HttpKernelBrowser extends AbstractBrowser
foreach (get_declared_classes() as $class) {
if (0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$file = \dirname(\dirname($r->getFileName())).'/autoload.php';
$file = \dirname($r->getFileName(), 2).'/autoload.php';
if (file_exists($file)) {
$requires .= 'require_once '.var_export($file, true).";\n";
}

View File

@ -16,6 +16,7 @@ use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\Loader\DelegatingLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -463,7 +464,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
}
// Remove frames added by DebugClassLoader.
for ($i = \count($backtrace) - 2; 0 < $i; --$i) {
if (DebugClassLoader::class === ($backtrace[$i]['class'] ?? null)) {
if (\in_array($backtrace[$i]['class'] ?? null, [DebugClassLoader::class, LegacyDebugClassLoader::class], true)) {
$backtrace = [$backtrace[$i + 1]];
break;
}

View File

@ -39,8 +39,8 @@ class HttpKernelBrowserTest extends TestCase
$this->assertEquals('Request: /', $client->getResponse()->getContent(), '->doRequest() uses the request handler to make the request');
$this->assertEquals('www.example.com', $client->getRequest()->getHost(), '->doRequest() uses the request handler to make the request');
$client->request('GET', 'http://www.example.com/?parameter=http://google.com');
$this->assertEquals('http://www.example.com/?parameter='.urlencode('http://google.com'), $client->getRequest()->getUri(), '->doRequest() uses the request handler to make the request');
$client->request('GET', 'http://www.example.com/?parameter=http://example.com');
$this->assertEquals('http://www.example.com/?parameter='.urlencode('http://example.com'), $client->getRequest()->getUri(), '->doRequest() uses the request handler to make the request');
}
public function testGetScript()

View File

@ -29,15 +29,15 @@ class TranslationFilesTest extends TestCase
{
return array_map(
function ($filePath) { return (array) $filePath; },
glob(\dirname(\dirname(__DIR__)).'/Resources/translations/*.xlf')
glob(\dirname(__DIR__, 2).'/Resources/translations/*.xlf')
);
}
public function testNorwegianAlias()
{
$this->assertFileEquals(
\dirname(\dirname(__DIR__)).'/Resources/translations/security.nb.xlf',
\dirname(\dirname(__DIR__)).'/Resources/translations/security.no.xlf',
\dirname(__DIR__, 2).'/Resources/translations/security.nb.xlf',
\dirname(__DIR__, 2).'/Resources/translations/security.no.xlf',
'The NO locale should be an alias for the NB variant of the Norwegian language.'
);
}

View File

@ -84,11 +84,11 @@ EOF
$this->format = $input->getOption('format');
$this->displayCorrectFiles = $output->isVerbose();
if ('-' === ($filenames[0] ?? '')) {
if (['-'] === $filenames) {
return $this->display($io, [$this->validate($this->getStdin())]);
}
if (0 === \count($filenames)) {
if (!$filenames) {
throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
}

View File

@ -87,7 +87,7 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
public function getValidRelativeUrls()
{
return [
['//google.com'],
['//example.com'],
['//symfony.fake/blog/'],
['//symfony.com/search?type=&q=url+validator'],
];
@ -97,11 +97,11 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
{
return [
['http://a.pl'],
['http://www.google.com'],
['http://www.google.com.'],
['http://www.google.museum'],
['https://google.com/'],
['https://google.com:80/'],
['http://www.example.com'],
['http://www.example.com.'],
['http://www.example.museum'],
['https://example.com/'],
['https://example.com:80/'],
['http://www.example.coop/'],
['http://www.test-example.com/'],
['http://www.symfony.com/'],
@ -162,11 +162,11 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
public function getValidUrlsWithWhitespaces()
{
return [
["\x20http://www.google.com"],
["\x09\x09http://www.google.com."],
["\x20http://www.example.com"],
["\x09\x09http://www.example.com."],
["http://symfony.fake/blog/\x0A"],
["http://symfony.com/search?type=&q=url+validator\x0D\x0D"],
["\x00https://google.com:80\x00"],
["\x00https://example.com:80\x00"],
["\x0B\x0Bhttp://username:password@symfony.com\x0B\x0B"],
];
}
@ -210,10 +210,10 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
public function getInvalidRelativeUrls()
{
return [
['/google.com'],
['//goog_le.com'],
['//google.com::aa'],
['//google.com:aa'],
['/example.com'],
['//examp_le.com'],
['//example.com::aa'],
['//example.com:aa'],
['//127.0.0.1:aa/'],
['//[::1'],
['//hello.☎/'],
@ -231,15 +231,15 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
public function getInvalidUrls()
{
return [
['google.com'],
['://google.com'],
['http ://google.com'],
['http:/google.com'],
['http://goog_le.com'],
['http://google.com::aa'],
['http://google.com:aa'],
['ftp://google.fr'],
['faked://google.fr'],
['example.com'],
['://example.com'],
['http ://example.com'],
['http:/example.com'],
['http://examp_le.com'],
['http://example.com::aa'],
['http://example.com:aa'],
['ftp://example.fr'],
['faked://example.fr'],
['http://127.0.0.1:aa/'],
['ftp://[::1]/'],
['http://[::1'],
@ -272,7 +272,7 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
public function getValidCustomUrls()
{
return [
['ftp://google.com'],
['ftp://example.com'],
['file://127.0.0.1'],
['git://[::1]/'],
];

View File

@ -29,15 +29,15 @@ class TranslationFilesTest extends TestCase
{
return array_map(
function ($filePath) { return (array) $filePath; },
glob(\dirname(\dirname(__DIR__)).'/Resources/translations/*.xlf')
glob(\dirname(__DIR__, 2).'/Resources/translations/*.xlf')
);
}
public function testNorwegianAlias()
{
$this->assertFileEquals(
\dirname(\dirname(__DIR__)).'/Resources/translations/validators.nb.xlf',
\dirname(\dirname(__DIR__)).'/Resources/translations/validators.no.xlf',
\dirname(__DIR__, 2).'/Resources/translations/validators.nb.xlf',
\dirname(__DIR__, 2).'/Resources/translations/validators.no.xlf',
'The NO locale should be an alias for the NB variant of the Norwegian language.'
);
}

View File

@ -71,7 +71,7 @@ class LinkStub extends ConstStub
foreach (get_declared_classes() as $class) {
if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$v = \dirname(\dirname($r->getFileName()));
$v = \dirname($r->getFileName(), 2);
if (file_exists($v.'/composer/installed.json')) {
self::$vendorRoots[] = $v.\DIRECTORY_SEPARATOR;
}

View File

@ -50,12 +50,12 @@ SplFileInfo {
%A}
EOTXT
],
['https://google.com/about', <<<'EOTXT'
['https://example.com/about', <<<'EOTXT'
SplFileInfo {
%Apath: "https://google.com"
%Apath: "https://example.com"
filename: "about"
basename: "about"
pathname: "https://google.com/about"
pathname: "https://example.com/about"
extension: ""
realPath: false
%A}

View File

@ -87,11 +87,11 @@ EOF
$this->displayCorrectFiles = $output->isVerbose();
$flags = $input->getOption('parse-tags') ? Yaml::PARSE_CUSTOM_TAGS : 0;
if ('-' === ($filenames[0] ?? '')) {
if (['-'] === $filenames) {
return $this->display($io, [$this->validate($this->getStdin(), $flags)]);
}
if (0 === \count($filenames)) {
if (!$filenames) {
throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
}

View File

@ -80,15 +80,11 @@ class Dumper
if ($value instanceof TaggedValue) {
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());
if ($inline - 1 <= 0) {
if ($inline - 1 <= 0 || null === $value->getValue() || is_scalar($value->getValue())) {
$output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n";
} else {
$output .= "\n";
$output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags);
if (is_scalar($value->getValue())) {
$output .= "\n";
}
}
continue;

View File

@ -466,10 +466,21 @@ YAML;
'user2' => new TaggedValue('user', 'john'),
];
$expected = <<<YAML
user1: !user
jane
user2: !user
john
user1: !user jane
user2: !user john
YAML;
$this->assertSame($expected, $this->dumper->dump($data, 2));
}
public function testDumpingNotInlinedNullTaggedValue()
{
$data = [
'foo' => new TaggedValue('bar', null),
];
$expected = <<<YAML
foo: !bar null
YAML;