Merge branch '4.4' into 5.0
* 4.4: fix unix root dir issue sync validator translation files with master [HttpFoundation] fix not sending Content-Type header for 204 responses [ErrorHandler] silence warning when zend.assertions=-1 fix anchor [Console] Handle zero row count in appendRow() for Table fix links to releases page (formerly known as "roadmap") [Console] Don't load same-namespace alternatives on exact match found
This commit is contained in:
commit
05f71d3fd5
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -11,7 +11,7 @@
|
|||||||
Replace this notice by a short README for your feature/bugfix. This will help people
|
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.
|
understand your PR and can be used as a start for the documentation.
|
||||||
|
|
||||||
Additionally (see https://symfony.com/roadmap):
|
Additionally (see https://symfony.com/releases):
|
||||||
- Always add tests and ensure they pass.
|
- Always add tests and ensure they pass.
|
||||||
- Never break backward compatibility (see https://symfony.com/bc).
|
- Never break backward compatibility (see https://symfony.com/bc).
|
||||||
- Bug fixes must be submitted against the lowest maintained branch where they apply
|
- Bug fixes must be submitted against the lowest maintained branch where they apply
|
||||||
|
@ -153,7 +153,7 @@
|
|||||||
<td class="font-normal">{{ collector.symfonyeom }}</td>
|
<td class="font-normal">{{ collector.symfonyeom }}</td>
|
||||||
<td class="font-normal">{{ collector.symfonyeol }}</td>
|
<td class="font-normal">{{ collector.symfonyeol }}</td>
|
||||||
<td class="font-normal">
|
<td class="font-normal">
|
||||||
<a href="https://symfony.com/roadmap?version={{ collector.symfonyminorversion }}#checker">View roadmap</a>
|
<a href="https://symfony.com/releases/{{ collector.symfonyminorversion }}#release-checker">View roadmap</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -647,7 +647,15 @@ class Application implements ResetInterface
|
|||||||
// filter out aliases for commands which are already on the list
|
// filter out aliases for commands which are already on the list
|
||||||
if (\count($commands) > 1) {
|
if (\count($commands) > 1) {
|
||||||
$commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
|
$commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
|
||||||
$commands = array_unique(array_filter($commands, function ($nameOrAlias) use (&$commandList, $commands, &$aliases) {
|
|
||||||
|
if (isset($commandList[$name])) {
|
||||||
|
return $this->get($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($commands as $k => $nameOrAlias) {
|
||||||
|
if ($nameOrAlias === $name) {
|
||||||
|
return $this->get($nameOrAlias);
|
||||||
|
}
|
||||||
if (!$commandList[$nameOrAlias] instanceof Command) {
|
if (!$commandList[$nameOrAlias] instanceof Command) {
|
||||||
$commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias);
|
$commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias);
|
||||||
}
|
}
|
||||||
@ -656,8 +664,14 @@ class Application implements ResetInterface
|
|||||||
|
|
||||||
$aliases[$nameOrAlias] = $commandName;
|
$aliases[$nameOrAlias] = $commandName;
|
||||||
|
|
||||||
return $commandName === $nameOrAlias || !\in_array($commandName, $commands);
|
if ($commandName === $nameOrAlias || !\in_array($commandName, $commands)) {
|
||||||
}));
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($commands[$k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$commands = array_unique($commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\count($commands) > 1) {
|
if (\count($commands) > 1) {
|
||||||
|
@ -589,7 +589,9 @@ class Table
|
|||||||
++$numberOfRows; // Add row for header separator
|
++$numberOfRows; // Add row for header separator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (\count($this->rows) > 0) {
|
||||||
++$numberOfRows; // Add row for footer separator
|
++$numberOfRows; // Add row for footer separator
|
||||||
|
}
|
||||||
|
|
||||||
return $numberOfRows;
|
return $numberOfRows;
|
||||||
}
|
}
|
||||||
|
@ -1692,6 +1692,31 @@ class ApplicationTest extends TestCase
|
|||||||
$this->assertArrayNotHasKey('disabled', $application->all());
|
$this->assertArrayNotHasKey('disabled', $application->all());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFindAlternativesDoesNotLoadSameNamespaceCommandsOnExactMatch()
|
||||||
|
{
|
||||||
|
$application = new Application();
|
||||||
|
$application->setAutoExit(false);
|
||||||
|
|
||||||
|
$loaded = [];
|
||||||
|
|
||||||
|
$application->setCommandLoader(new FactoryCommandLoader([
|
||||||
|
'foo:bar' => function () use (&$loaded) {
|
||||||
|
$loaded['foo:bar'] = true;
|
||||||
|
|
||||||
|
return (new Command('foo:bar'))->setCode(function () {});
|
||||||
|
},
|
||||||
|
'foo' => function () use (&$loaded) {
|
||||||
|
$loaded['foo'] = true;
|
||||||
|
|
||||||
|
return (new Command('foo'))->setCode(function () {});
|
||||||
|
},
|
||||||
|
]));
|
||||||
|
|
||||||
|
$application->run(new ArrayInput(['command' => 'foo']), new NullOutput());
|
||||||
|
|
||||||
|
$this->assertSame(['foo' => true], $loaded);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getDispatcher($skipCommand = false)
|
protected function getDispatcher($skipCommand = false)
|
||||||
{
|
{
|
||||||
$dispatcher = new EventDispatcher();
|
$dispatcher = new EventDispatcher();
|
||||||
|
@ -951,6 +951,38 @@ TABLE;
|
|||||||
$table->appendRow(['9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25']);
|
$table->appendRow(['9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSectionOutputHandlesZeroRowsAfterRender()
|
||||||
|
{
|
||||||
|
$sections = [];
|
||||||
|
$stream = $this->getOutputStream(true);
|
||||||
|
$output = new ConsoleSectionOutput($stream->getStream(), $sections, $stream->getVerbosity(), $stream->isDecorated(), new OutputFormatter());
|
||||||
|
$output->writeln('My Table');
|
||||||
|
$table = new Table($output);
|
||||||
|
$table
|
||||||
|
->setHeaders(['ISBN', 'Title', 'Author', 'Price'])
|
||||||
|
->setRows([]);
|
||||||
|
|
||||||
|
$table->render();
|
||||||
|
|
||||||
|
$table->appendRow(['9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25']);
|
||||||
|
|
||||||
|
$expected =
|
||||||
|
<<<TABLE
|
||||||
|
My Table
|
||||||
|
+------+-------+--------+-------+
|
||||||
|
|\033[32m ISBN \033[39m|\033[32m Title \033[39m|\033[32m Author \033[39m|\033[32m Price \033[39m|
|
||||||
|
+------+-------+--------+-------+
|
||||||
|
\x1b[3A\x1b[0J+---------------+----------------------+-----------------+--------+
|
||||||
|
|\033[32m ISBN \033[39m|\033[32m Title \033[39m|\033[32m Author \033[39m|\033[32m Price \033[39m|
|
||||||
|
+---------------+----------------------+-----------------+--------+
|
||||||
|
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
|
||||||
|
+---------------+----------------------+-----------------+--------+
|
||||||
|
|
||||||
|
TABLE;
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||||
|
}
|
||||||
|
|
||||||
public function testIsNotDefinedStyleException()
|
public function testIsNotDefinedStyleException()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\Console\Exception\InvalidArgumentException');
|
$this->expectException('Symfony\Component\Console\Exception\InvalidArgumentException');
|
||||||
|
@ -29,7 +29,7 @@ class Debug
|
|||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ini_set('zend.assertions', 1);
|
@ini_set('zend.assertions', 1);
|
||||||
ini_set('assert.active', 1);
|
ini_set('assert.active', 1);
|
||||||
ini_set('assert.warning', 0);
|
ini_set('assert.warning', 0);
|
||||||
ini_set('assert.exception', 1);
|
ini_set('assert.exception', 1);
|
||||||
|
@ -782,6 +782,10 @@ class Finder implements \IteratorAggregate, \Countable
|
|||||||
*/
|
*/
|
||||||
private function normalizeDir(string $dir): string
|
private function normalizeDir(string $dir): string
|
||||||
{
|
{
|
||||||
|
if ('/' === $dir) {
|
||||||
|
return $dir;
|
||||||
|
}
|
||||||
|
|
||||||
$dir = rtrim($dir, '/'.\DIRECTORY_SEPARATOR);
|
$dir = rtrim($dir, '/'.\DIRECTORY_SEPARATOR);
|
||||||
|
|
||||||
if (preg_match('#^(ssh2\.)?s?ftp://#', $dir)) {
|
if (preg_match('#^(ssh2\.)?s?ftp://#', $dir)) {
|
||||||
|
@ -70,7 +70,11 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
|
|||||||
}
|
}
|
||||||
$subPathname .= $this->getFilename();
|
$subPathname .= $this->getFilename();
|
||||||
|
|
||||||
return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname);
|
if ('/' !== $basePath = $this->rootPath) {
|
||||||
|
$basePath .= $this->directorySeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SplFileInfo($basePath.$subPathname, $this->subPath, $subPathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -258,10 +258,12 @@ class Response
|
|||||||
$this->setContent(null);
|
$this->setContent(null);
|
||||||
$headers->remove('Content-Type');
|
$headers->remove('Content-Type');
|
||||||
$headers->remove('Content-Length');
|
$headers->remove('Content-Length');
|
||||||
|
// prevent PHP from sending the Content-Type header based on default_mimetype
|
||||||
|
ini_set('default_mimetype', '');
|
||||||
} else {
|
} else {
|
||||||
// Content-type based on the Request
|
// Content-type based on the Request
|
||||||
if (!$headers->has('Content-Type')) {
|
if (!$headers->has('Content-Type')) {
|
||||||
$format = $request->getPreferredFormat();
|
$format = $request->getPreferredFormat(null);
|
||||||
if (null !== $format && $mimeType = $request->getMimeType($format)) {
|
if (null !== $format && $mimeType = $request->getMimeType($format)) {
|
||||||
$headers->set('Content-Type', $mimeType);
|
$headers->set('Content-Type', $mimeType);
|
||||||
}
|
}
|
||||||
|
@ -461,18 +461,10 @@ class ResponseTest extends ResponseTestCase
|
|||||||
|
|
||||||
public function testDefaultContentType()
|
public function testDefaultContentType()
|
||||||
{
|
{
|
||||||
$headerMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\ResponseHeaderBag')->setMethods(['set'])->getMock();
|
|
||||||
$headerMock->expects($this->at(0))
|
|
||||||
->method('set')
|
|
||||||
->with('Content-Type', 'text/html');
|
|
||||||
$headerMock->expects($this->at(1))
|
|
||||||
->method('set')
|
|
||||||
->with('Content-Type', 'text/html; charset=UTF-8');
|
|
||||||
|
|
||||||
$response = new Response('foo');
|
$response = new Response('foo');
|
||||||
$response->headers = $headerMock;
|
|
||||||
|
|
||||||
$response->prepare(new Request());
|
$response->prepare(new Request());
|
||||||
|
|
||||||
|
$this->assertSame('text/html; charset=UTF-8', $response->headers->get('Content-Type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testContentTypeCharset()
|
public function testContentTypeCharset()
|
||||||
|
@ -366,6 +366,10 @@
|
|||||||
<source>This value should be between {{ min }} and {{ max }}.</source>
|
<source>This value should be between {{ min }} and {{ max }}.</source>
|
||||||
<target>Dieser Wert sollte zwischen {{ min }} und {{ max }} sein.</target>
|
<target>Dieser Wert sollte zwischen {{ min }} und {{ max }} sein.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="95">
|
||||||
|
<source>This value is not a valid hostname.</source>
|
||||||
|
<target>Dieser Wert ist kein gültiger Hostname.</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -366,6 +366,10 @@
|
|||||||
<source>This value should be between {{ min }} and {{ max }}.</source>
|
<source>This value should be between {{ min }} and {{ max }}.</source>
|
||||||
<target>This value should be between {{ min }} and {{ max }}.</target>
|
<target>This value should be between {{ min }} and {{ max }}.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="95">
|
||||||
|
<source>This value is not a valid hostname.</source>
|
||||||
|
<target>This value is not a valid hostname.</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -366,6 +366,10 @@
|
|||||||
<source>This value should be between {{ min }} and {{ max }}.</source>
|
<source>This value should be between {{ min }} and {{ max }}.</source>
|
||||||
<target>Cette valeur doit être comprise entre {{ min }} et {{ max }}.</target>
|
<target>Cette valeur doit être comprise entre {{ min }} et {{ max }}.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="95">
|
||||||
|
<source>This value is not a valid hostname.</source>
|
||||||
|
<target>Cette valeur n'est pas un nom d'hôte valide.</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -366,6 +366,10 @@
|
|||||||
<source>This value should be between {{ min }} and {{ max }}.</source>
|
<source>This value should be between {{ min }} and {{ max }}.</source>
|
||||||
<target>Значение должно быть между {{ min }} и {{ max }}.</target>
|
<target>Значение должно быть между {{ min }} и {{ max }}.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="95">
|
||||||
|
<source>This value is not a valid hostname.</source>
|
||||||
|
<target>Значение не является корректным именем хоста.</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
Reference in New Issue
Block a user