8000 Merge branch '2.3' · symfony/symfony@c3728d2 · GitHub
[go: up one dir, main page]

Skip to content

Commit c3728d2

Browse files
committed
Merge branch '2.3'
* 2.3: fixes RequestDataCollector bug, visible when used on Drupal8 [Console] fixed exception rendering when nested styles [Console] added some more information about OutputFormatter::replaceStyle() [Console] fixed the formatter for single-char tags [Console] Escape exception message during the rendering of an exception [DomCrawler] fixed HTML5 form attribute handling Making tests pass on mac os x without this change tests would fail under mac os x at least in 10.8.2 [BrowserKit] Fixed the handling of parameters when redirecting [Process] Properly close pipes after a Process::stop call fixed bytes conversion when used on 32-bits systems Typo fix HttpFoundation RequestTest - Fixed indentation and removed comments HttpFoundation Request test for #8619 LICENSE files moved to meta folders added missing method in the UPGRADE file for 2.2 (closes #8941) [Form] Fixed: "required" attribute is not added to <select> tag if no empty value [Translation] Removed an unneeded return annotation. [DomCrawler] Added missing docblocks and removed unneeded return annotation. Conflicts: src/Symfony/Component/Process/Tests/AbstractProcessTest.php
2 parents 77d7906 + d182503 commit c3728d2

File tree

32 files changed

+286
-92
lines changed

32 files changed

+286
-92
lines changed

UPGRADE-2.2.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,9 @@
482482
}
483483
```
484484

485-
* The method `ExecutionContext::addViolationAtSubPath()` was deprecated and
486-
will be removed in Symfony 2.3. You should use `addViolationAt()` instead.
485+
* The methods `ExecutionContext::addViolationAtSubPath()` and
486+
`ExecutionContext::addViolationAtPath()` were deprecated and will be
487+
removed in Symfony 2.3. You should use `addViolationAt()` instead.
487488

488489
Before:
489490

src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767

6868
{% block choice_widget_collapsed %}
6969
{% spaceless %}
70+
{% if required and empty_value is none and not empty_value_in_choices %}
71+
{% set required = false %}
72+
{% endif %}
7073
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
7174
{% if empty_value is not none %}
7275
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>

src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<select
2-
<?php echo $view['form']->block($form, 'widget_attributes') ?>
2+
<?php echo $view['form']->block($form, 'widget_attributes', array(
3+
'required' => $required && (null !== $empty_value || $empty_value_in_choices)
4+
)) ?>
35
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
46
>
57
<?php if (null !== $empty_value): ?><option value=""<?php if ($required and empty($value) && "0" !== $value): ?> selected="selected"<?php endif?>><?php echo $view->escape($view['translator']->trans($empty_value, array(), $translation_domain)) ?></option><?php endif; ?>

src/Symfony/Component/BrowserKit/Client.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,12 +504,19 @@ public function followRedirect()
504504
$content = $request->getContent();
505505
}
506506

507+
if ('get' === strtolower($method)) {
508+
// Don't forward parameters for GET request as it should reach the redirection URI
509+
$parameters = array();
510+
} else {
511+
$parameters = $request->getParameters();
512+
}
513+
507514
$server = $request->getServer();
508515
unset($server['HTTP_IF_NONE_MATCH'], $server['HTTP_IF_MODIFIED_SINCE']);
509516

510517
$this->isMainRequest = false;
511518

512-
$response = $this->request($method, $this->redirect, $request->getParameters(), $files, $server, $content);
519+
$response = $this->request($method, $this->redirect, $parameters, $files, $server, $content);
513520

514521
$this->isMainRequest = true;
515522

src/Symfony/Component/BrowserKit/Tests/ClientTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,10 @@ public function testFollowRedirectWithMaxRedirects()
357357
$this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() follows a redirect if any');
358358

359359
$client->setNextResponse(new Response('', 302, array('Location' => 'http://www.example.com/redirected')));
360-
$client->request('POST', 'http://www.example.com/foo/foobar');
360+
$client->request('POST', 'http://www.example.com/foo/foobar', array('name' => 'bar'));
361361

362362
$this->assertEquals('get', $client->getRequest()->getMethod(), '->followRedirect() uses a get for 302');
363+
$this->assertEquals(array(), $client->getRequest()->getParameters(), '->followRedirect() does not submit parameters when changing the method');
363364
}
364365

365366
public function testFollowRedirectWithCookies()

src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ public function testSerializeUnserialize()
5353
{
5454
$unserialized = unserialize(serialize($this->resource));
5555

56-
$this->assertSame($this->file, $this->resource->getResource());
56+
$this->assertSame(realpath($this->file), $this->resource->getResource());
5757
}
5858
}

src/Symfony/Component/Console/Application.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -685,29 +685,29 @@ public function renderException($e, $output)
685685
$title = sprintf(' [%s] ', get_class($e));
686686
$len = $strlen($title);
687687
$width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
688+
$formatter = $output->getFormatter();
688689
$lines = array();
689690
foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
690691
foreach (str_split($line, $width - 4) as $line) {
691-
$lines[] = sprintf(' %s ', $line);
692-
$len = max($strlen($line) + 4, $len);
692+
// pre-format lines to get the right string length
693+
$lineLength = $strlen(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
694+
$lines[] = array($line, $lineLength);
695+
696+
$len = max($lineLength, $len);
693697
}
694698
}
695699

696-
$messages = array(str_repeat(' ', $len), $title.str_repeat(' ', max(0, $len - $strlen($title))));
697-
700+
$messages = array('', '');
701+
$messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
702+
$messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $strlen($title)))));
698703
foreach ($lines as $line) {
699-
$messages[] = $line.str_repeat(' ', $len - $strlen($line));
704+
$messages[] = $formatter->format(sprintf('<error> %s %s</error>', $line[0], str_repeat(' ', $len - $line[1])));
700705
}
706+
$messages[] = $emptyLine;
707+
$messages[] = '';
708+
$messages[] = '';
701709

702-
$messages[] = str_repeat(' ', $len);
703-
704-
$output->writeln("");
705-
$output->writeln("");
706-
foreach ($messages as $message) {
707-
$output->writeln('<error>'.$message.'</error>');
708-
}
709-
$output->writeln("");
710-
$output->writeln("");
710+
$output->writeln($messages, OutputInterface::OUTPUT_RAW);
711711

712712
if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
713713
$output->writeln('<comment>Exception trace:</comment>');

src/Symfony/Component/Console/Formatter/OutputFormatter.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class OutputFormatter implements OutputFormatterInterface
2323
/**
2424
* The pattern to phrase the format.
2525
*/
26-
const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]+)?>((?: [^<\\\\]+ | (?!<(?:/?[a-z]|/>)). | .(?<=\\\\<) )*)#isx';
26+
const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]*)?>((?: [^<\\\\]+ | (?!<(?:/?[a-z]|/>)). | .(?<=\\\\<) )*)#isx';
2727

2828
private $decorated;
2929
private $styles = array();
@@ -163,6 +163,8 @@ public function getStyleStack()
163163
/**
164164
* Replaces style of the output.
165165
*
166+
* All escaped tags and tags that reference unknown styles are kept as is.
167+
*
166168
* @param array $match
167169
*
168170
* @return string The replaced style

src/Symfony/Component/Console/Tests/ApplicationTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@ public function testRenderException()
481481
$tester->run(array('command' => 'foo3:bar'), array('decorated' => false));
482482
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
483483

484+
$tester->run(array('command' => 'foo3:bar'), array('decorated' => true));
485+
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
486+
484487
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
485488
$application->setAutoExit(false);
486489
$application->expects($this->any())

src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ protected function configure()
1717
protected function execute(InputInterface $input, OutputInterface $output)
1818
{
1919
try {
20-
throw new \Exception("First exception");
20+
try {
21+
throw new \Exception("First exception <p>this is html</p>");
22+
} catch (\Exception $e) {
23+
throw new \Exception("Second exception <comment>comment</comment>", 0, $e);
24+
}
2125
} catch (\Exception $e) {
22-
throw new \Exception("Second exception", 0, $e);
26+
throw new \Exception("Third exception <fg=blue;bg=red>comment</>", 0, $e);
2327
}
2428
}
2529
}

src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt

Lines changed: 16 additions & 10000 amp; 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11

22

3-
4-
[Exception]
5-
Second exception
6-
3+
4+
[Exception]
5+
Third exception comment
6+
77

88

99

1010

11-
12-
[Exception]
13-
First exception
14-
11+
12+
[Exception]
13+
Second exception comment
14+
15+
16+
17+
18+
19+
20+
[Exception]
21+
First exception <p>this is html</p>
22+
1523

1624

1725
foo3:bar
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
3+
 
4+
 [Exception] 
5+
 Third exception comment 
6+
 
7+
8+
9+
10+
11+
 
12+
 [Exception] 
13+
 Second exception comment 
14+
 
15+
16+
17+
18+
19+
 
20+
 [Exception] 
21+
 First exception <p>this is html</p> 
22+
 
23+
24+
25+
foo3:bar
26+
27+

src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ public function testNewStyle()
113113
$this->assertEquals($style, $formatter->getStyle('test'));
114114
$this->assertNotEquals($style, $formatter->getStyle('info'));
115115

116-
$this->assertEquals("\033[34;47msome custom msg\033[0m", $formatter->format('<test>some custom msg</test>'));
116+
$style = new OutputFormatterStyle('blue', 'white');
117+
$formatter->setStyle('b', $style);
118+
119+
$this->assertEquals("\033[34;47msome \033[0m\033[34;47mcustom\033[0m\033[34;47m msg\033[0m", $formatter->format('<test>some <b>custom</b> msg</test>'));
117120
}
118121

119122
public function testRedefineStyle()
@@ -137,7 +140,7 @@ public function testInlineStyle()
137140
public function testNonStyleTag()
138141
{
139142
$formatter = new OutputFormatter(true);
140-
$this->assertEquals("\033[32msome \033[0m\033[32m<tag> styled\033[0m", $formatter->format('<info>some <tag> styled</info>'));
143+
$this->assertEquals("\033[32msome \033[0m\033[32m<tag> styled \033[0m\033[32m<p>single-char tag\033[0m\033[32m</p>\033[0m", $formatter->format('<info>some <tag> styled <p>single-char tag</p></info>'));
141144
}
142145

143146
public function testNotDecoratedFormatter()

src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* PhpFileLoader loads service definitions from a PHP file.
1818
*
1919
* The PHP file is required and the $container variable can be
20-
* used form the file to change the container.
20+
* used within the file to change the container.
2121
*
2222
* @author Fabien Potencier <fabien@symfony.com>
2323
*/

src/Symfony/Component/DomCrawler/Crawler.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ public function add($node)
8888
*
8989
* @param string $content A string to parse as HTML/XML
9090
* @param null|string $type The content type of the string
91-
*
92-
* @return null|void
9391
*/
9492
public function addContent($content, $type = null)
9593
{
@@ -749,6 +747,11 @@ public static function xpathLiteral($s)
749747
return sprintf("concat(%s)", implode($parts, ', '));
750748
}
751749

750+
/**
751+
* @param integer $position
752+
*
753+
* @return \DOMElement|null
754+
*/
752755
protected function getNode($position)
753756
{
754757
foreach ($this as $i => $node) {
@@ -762,6 +765,12 @@ protected function getNode($position)
762765
// @codeCoverageIgnoreEnd
763766
}
764767

768+
/**
769+
* @param \DOMElement $node
770+
* @param string $siblingDir
771+
*
772+
* @return array
773+
*/
765774
protected function sibling($node, $siblingDir = 'nextSibling')
766775
{
767776
$nodes = array();

src/Symfony/Component/DomCrawler/Form.php

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -367,46 +367,59 @@ protected function setNode(\DOMNode $node)
367367
$this->node = $node;
368368
}
369369

370+
/**
371+
* Adds form elements related to this form.
372+
*
373+
* Creates an internal copy of the submitted 'button' element and
374+
* the form node or the entire document depending on whether we need
375+
* to find non-descendant elements through HTML5 'form' attribute.
376+
*/
370377
private function initialize()
371378
{
372379
$this->fields = new FormFieldRegistry();
373380

374381
$document = new \DOMDocument('1.0', 'UTF-8');
375-
$node = $document->importNode($this->node, true);
376-
$button = $document->importNode($this->button, true);
377-
$root = $document->appendChild($document->createElement('_root'));
378-
$root->appendChild($node);
379-
$root->appendChild($button);
380382
$xpath = new \DOMXPath($document);
383+
$root = $document->appendChild($document->createElement('_root'));
381384

382-
// add descendant elements to the form
383-
$fieldNodes = $xpath->query('descendant::input | descendant::button | descendant::textarea | descendant::select', $root);
384-
foreach ($fieldNodes as $node) {
385-
$this->addField($node, $button);
385+
// add submitted button if it has a valid name
386+
if ($this->button->hasAttribute('name') && $this->button->getAttribute('name')) {
387+
$this->set(new Field\InputFormField($document->importNode($this->button, true)));
386388
}
387389

388-
// find form elements corresponding to the current form by the HTML5 form attribute
390+
// find form elements corresponding to the current form
389391
if ($this->node->hasAttribute('id')) {
392+
// traverse through the whole document
393+
$node = $document->importNode($this->node->ownerDocument->documentElement, true);
394+
$root->appendChild($node);
395+
396+
// corresponding elements are either descendants or have a matching HTML5 form attribute
390397
$formId = Crawler::xpathLiteral($this->node->getAttribute('id'));
391-
$xpath = new \DOMXPath($this->node->ownerDocument);
392-
$fieldNodes = $xpath->query(sprintf('descendant::input[@form=%s] | descendant::button[@form=%s] | descendant::textarea[@form=%s] | descendant::select[@form=%s]', $formId, $formId, $formId, $formId));
398+
$fieldNodes = $xpath->query(sprintf('descendant::input[@form=%s] | descendant::button[@form=%s] | descendant::textarea[@form=%s] | descendant::select[@form=%s] | //form[@id=%s]/input[not(@form)] | //form[@id=%s]/button[not(@form)] | //form[@id=%s]/textarea[not(@form)] | //form[@id=%s]/select[not(@form)]', $formId, $formId, $formId, $formId, $formId, $formId, $formId, $formId), $root);
393399
foreach ($fieldNodes as $node) {
394-
$this->addField($node, $button);
400+
$this->addField($node);
401+
}
402+
} else {
403+
// parent form has no id, add descendant elements only
404+
$node = $document->importNode($this->node, true);
405+
$root->appendChild($node);
406+
407+
// descendant elements with form attribute are not part of this form
408+
$fieldNodes = $xpath->query('descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)]', $root);
409+
foreach ($fieldNodes as $node) {
410+
$this->addField($node);
395411
}
396412
}
397413
}
398414

399-
private function addField(\DOMNode $node, \DOMNode $button)
415+
private function addField(\DOMNode $node)
400416
{
401417
if (!$node->hasAttribute('name') || !$node->getAttribute('name')) {
402418
return;
403419
}
404420

405421
$nodeName = $node->nodeName;
406-
407-
if ($node === $button) {
408-
$this->set(new Field\InputFormField($node));
409-
} elseif ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) {
422+
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) {
410423
$this->set(new Field\ChoiceFormField($node));
411424
} elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) {
412425
if ($this->has($node->getAttribute('name'))) {

0 commit comments

Comments
 (0)
0