Skip to content

Commit

Permalink
Merge branch '4.2'
Browse files Browse the repository at this point in the history
* 4.2:
  [Routing] fix trailing slash redirections involving a trailing var
  [EventDispatcher] Revers event tracing order
  [Security] Prefer clone over unserialize(serialize()) for user refreshment
  [Console] OutputFormatter: move strtolower to createStyleFromString
  Adjust tests to work in the armhf architecture. Fixes #29281.
  Vietnamese translations improvement
  [Form] Fixed FormErrorIterator class phpdoc
  Renamed test controller from Controller to TestController so it doesn't show up in the IDE autocomplete.
  Don't use he in docs when its not needed
  EventSubscriberInterface isn't a man
  Fix undefined variable in cache ArrayTrait
  fixed public directory of web server and assets install when configured in composer.json
  • Loading branch information
nicolas-grekas committed Dec 17, 2018
2 parents f2590d1 + 8a60907 commit 75eebcf
Show file tree
Hide file tree
Showing 37 changed files with 1,380 additions and 1,297 deletions.
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
Expand Down Expand Up @@ -56,7 +57,7 @@ protected function configure()
{
$this
->setDefinition(array(
new InputArgument('target', InputArgument::OPTIONAL, 'The target directory', 'public'),
new InputArgument('target', InputArgument::OPTIONAL, 'The target directory', null),
))
->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it')
->addOption('relative', null, InputOption::VALUE_NONE, 'Make relative symlinks')
Expand Down Expand Up @@ -94,6 +95,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
$kernel = $this->getApplication()->getKernel();
$targetArg = rtrim($input->getArgument('target'), '/');

if (!$targetArg) {
$targetArg = $this->getPublicDirectory($this->getContainer());
}

if (!is_dir($targetArg)) {
$targetArg = $kernel->getProjectDir().'/'.$targetArg;

Expand Down Expand Up @@ -250,4 +255,27 @@ private function hardCopy(string $originDir, string $targetDir): string

return self::METHOD_COPY;
}

private function getPublicDirectory(ContainerInterface $container)
{
$defaultPublicDir = 'public';

if (!$container->hasParameter('kernel.project_dir')) {
return $defaultPublicDir;
}

$composerFilePath = $container->getParameter('kernel.project_dir').'/composer.json';

if (!file_exists($composerFilePath)) {
return $defaultPublicDir;
}

$composerConfig = json_decode(file_get_contents($composerFilePath), true);

if (isset($composerConfig['extra']['public-dir'])) {
return $composerConfig['extra']['public-dir'];
}

return $defaultPublicDir;
}
}
Expand Up @@ -27,8 +27,31 @@ public function load(array $configs, ContainerBuilder $container)
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('webserver.xml');

$publicDirectory = $this->getPublicDirectory($container);
$container->getDefinition('web_server.command.server_run')->replaceArgument(0, $publicDirectory);
$container->getDefinition('web_server.command.server_start')->replaceArgument(0, $publicDirectory);

if (!class_exists(ConsoleFormatter::class)) {
$container->removeDefinition('web_server.command.server_log');
}
}

private function getPublicDirectory(ContainerBuilder $container)
{
$kernelProjectDir = $container->getParameter('kernel.project_dir');
$publicDir = 'public';
$composerFilePath = $kernelProjectDir.'/composer.json';

if (!file_exists($composerFilePath)) {
return $kernelProjectDir.'/'.$publicDir;
}

$composerConfig = json_decode(file_get_contents($composerFilePath), true);

if (isset($composerConfig['extra']['public-dir'])) {
$publicDir = $composerConfig['extra']['public-dir'];
}

return $kernelProjectDir.'/'.$publicDir;
}
}
Expand Up @@ -21,8 +21,17 @@ class WebServerExtensionTest extends TestCase
public function testLoad()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.project_dir', __DIR__);
(new WebServerExtension())->load(array(), $container);

$this->assertSame(
__DIR__.'/test',
$container->getDefinition('web_server.command.server_run')->getArgument(0)
);
$this->assertSame(
__DIR__.'/test',
$container->getDefinition('web_server.command.server_start')->getArgument(0)
);
$this->assertTrue($container->hasDefinition('web_server.command.server_run'));
$this->assertTrue($container->hasDefinition('web_server.command.server_start'));
$this->assertTrue($container->hasDefinition('web_server.command.server_stop'));
Expand Down
@@ -0,0 +1,6 @@
{
"name": "test-composer.json",
"extra": {
"public-dir": "test"
}
}
2 changes: 1 addition & 1 deletion src/Symfony/Component/Cache/Adapter/ArrayAdapter.php
Expand Up @@ -124,7 +124,7 @@ public function save(CacheItemInterface $item)

return true;
}
if ($this->storeSerialized && null === $value = $this->freeze($value)) {
if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
return false;
}
if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) {
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Cache/Simple/ArrayCache.php
Expand Up @@ -129,7 +129,7 @@ public function setMultiple($values, $ttl = null)
$expiry = 0 < $ttl ? microtime(true) + $ttl : PHP_INT_MAX;

foreach ($valuesArray as $key => $value) {
if ($this->storeSerialized && null === $value = $this->freeze($value)) {
if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
return false;
}
$this->values[$key] = $value;
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Cache/Traits/ArrayTrait.php
Expand Up @@ -113,7 +113,7 @@ private function generateItems(array $keys, $now, $f)
}
}

private function freeze($value)
private function freeze($value, $key)
{
if (null === $value) {
return 'N;';
Expand Down
9 changes: 5 additions & 4 deletions src/Symfony/Component/Console/Formatter/OutputFormatter.php
Expand Up @@ -166,7 +166,7 @@ public function formatAndWrap(string $message, int $width)
if (!$open && !$tag) {
// </>
$this->styleStack->pop();
} elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
} elseif (false === $style = $this->createStyleFromString($tag)) {
$output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength);
} elseif ($open) {
$this->styleStack->push($style);
Expand Down Expand Up @@ -210,15 +210,16 @@ private function createStyleFromString(string $string)
$style = new OutputFormatterStyle();
foreach ($matches as $match) {
array_shift($match);
$match[0] = strtolower($match[0]);

if ('fg' == $match[0]) {
$style->setForeground($match[1]);
$style->setForeground(strtolower($match[1]));
} elseif ('bg' == $match[0]) {
$style->setBackground($match[1]);
$style->setBackground(strtolower($match[1]));
} elseif ('href' === $match[0]) {
$style->setHref($match[1]);
} elseif ('options' === $match[0]) {
preg_match_all('([^,;]+)', $match[1], $options);
preg_match_all('([^,;]+)', strtolower($match[1]), $options);
$options = array_shift($options);
foreach ($options as $option) {
$style->setOption($option);
Expand Down
Expand Up @@ -29,7 +29,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
protected $logger;
protected $stopwatch;

private $called;
private $callStack;
private $dispatcher;
private $wrappedListeners;
private $orphanedEvents;
Expand All @@ -39,7 +39,6 @@ public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $sto
$this->dispatcher = $dispatcher;
$this->stopwatch = $stopwatch;
$this->logger = $logger;
$this->called = array();
$this->wrappedListeners = array();
$this->orphanedEvents = array();
}
Expand Down Expand Up @@ -125,6 +124,10 @@ public function hasListeners($eventName = null)
*/
public function dispatch($eventName, Event $event = null)
{
if (null === $this->callStack) {
$this->callStack = new \SplObjectStorage();
}

if (null === $event) {
$event = new Event();
}
Expand Down Expand Up @@ -160,11 +163,15 @@ public function dispatch($eventName, Event $event = null)
*/
public function getCalledListeners()
{
if (null === $this->callStack) {
return array();
}

$called = array();
foreach ($this->called as $eventName => $listeners) {
foreach ($listeners as $listener) {
$called[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
}
foreach ($this->callStack as $listener) {
list($eventName) = $this->callStack->getInfo();

$called[] = $listener->getInfo($eventName);
}

return $called;
Expand All @@ -190,9 +197,9 @@ public function getNotCalledListeners()
foreach ($allListeners as $eventName => $listeners) {
foreach ($listeners as $listener) {
$called = false;
if (isset($this->called[$eventName])) {
foreach ($this->called[$eventName] as $l) {
if ($l->getWrappedListener() === $listener) {
if (null !== $this->callStack) {
foreach ($this->callStack as $calledListener) {
if ($calledListener->getWrappedListener() === $listener) {
$called = true;

break;
Expand All @@ -204,12 +211,12 @@ public function getNotCalledListeners()
if (!$listener instanceof WrappedListener) {
$listener = new WrappedListener($listener, null, $this->stopwatch, $this);
}
$notCalled[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
$notCalled[] = $listener->getInfo($eventName);
}
}
}

uasort($notCalled, array($this, 'sortListenersByPriority'));
uasort($notCalled, array($this, 'sortNotCalledListeners'));

return $notCalled;
}
Expand All @@ -221,7 +228,7 @@ public function getOrphanedEvents(): array

public function reset()
{
$this->called = array();
$this->callStack = array();
$this->orphanedEvents = array();
}

Expand Down Expand Up @@ -272,6 +279,7 @@ private function preProcess($eventName)
$this->wrappedListeners[$eventName][] = $wrappedListener;
$this->dispatcher->removeListener($eventName, $listener);
$this->dispatcher->addListener($eventName, $wrappedListener, $priority);
$this->callStack->attach($wrappedListener, array($eventName));
}
}

Expand Down Expand Up @@ -300,8 +308,8 @@ private function postProcess($eventName)
if (!isset($this->called[$eventName])) {
$this->called[$eventName] = new \SplObjectStorage();
}

$this->called[$eventName]->attach($listener);
} else {
$this->callStack->detach($listener);
}

if (null !== $this->logger && $skipped) {
Expand All @@ -318,8 +326,12 @@ private function postProcess($eventName)
}
}

private function sortListenersByPriority($a, $b)
private function sortNotCalledListeners(array $a, array $b)
{
if (0 !== $cmp = strcmp($a['event'], $b['event'])) {
return $cmp;
}

if (\is_int($a['priority']) && !\is_int($b['priority'])) {
return 1;
}
Expand Down
Expand Up @@ -46,7 +46,7 @@ public function addListener($eventName, $listener, $priority = 0);
/**
* Adds an event subscriber.
*
* The subscriber is asked for all the events he is
* The subscriber is asked for all the events it is
* interested in and added as a listener for these events.
*/
public function addSubscriber(EventSubscriberInterface $subscriber);
Expand Down
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Component\EventDispatcher;

/**
* An EventSubscriber knows himself what events he is interested in.
* An EventSubscriber knows itself what events it is interested in.
* If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes
* {@link getSubscribedEvents} and registers the subscriber as a listener for all
* returned events.
Expand Down
Expand Up @@ -110,17 +110,17 @@ public function testGetCalledListeners()
$tdispatcher->addListener('foo', function () {}, 5);

$listeners = $tdispatcher->getNotCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertArrayHasKey('stub', $listeners[0]);
unset($listeners[0]['stub']);
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);

$tdispatcher->dispatch('foo');

$listeners = $tdispatcher->getCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertArrayHasKey('stub', $listeners[0]);
unset($listeners[0]['stub']);
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
}

Expand All @@ -133,10 +133,10 @@ public function testClearCalledListeners()
$tdispatcher->reset();

$listeners = $tdispatcher->getNotCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertArrayHasKey('stub', $listeners[0]);
unset($listeners[0]['stub']);
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
}

public function testGetCalledListenersNested()
Expand Down
Expand Up @@ -378,7 +378,7 @@ private function addSubForm(FormBuilderInterface $builder, string $name, ChoiceV
if ($options['multiple']) {
$choiceType = __NAMESPACE__.'\CheckboxType';
// The user can check 0 or more checkboxes. If required
// is true, he is required to check all of them.
// is true, they are required to check all of them.
$choiceOpts['required'] = false;
} else {
$choiceType = __NAMESPACE__.'\RadioType';
Expand Down
7 changes: 3 additions & 4 deletions src/Symfony/Component/Form/FormErrorIterator.php
Expand Up @@ -19,10 +19,9 @@
/**
* Iterates over the errors of a form.
*
* Optionally, this class supports recursive iteration. In order to iterate
* recursively, set the constructor argument $deep to true. Now each element
* returned by the iterator is either an instance of {@link FormError} or of
* {@link FormErrorIterator}, in case the errors belong to a sub-form.
* This class supports recursive iteration. In order to iterate recursively,
* pass a structure of {@link FormError} and {@link FormErrorIterator} objects
* to the $errors constructor argument.
*
* You can also wrap the iterator into a {@link \RecursiveIteratorIterator} to
* flatten the recursive structure into a flat list of errors.
Expand Down

0 comments on commit 75eebcf

Please sign in to comment.