Merge branch '3.4'

* 3.4:
  [DI] Handle container.autowiring.strict_mode to opt-out from legacy autowiring
  [2.8] Fix some docblocks
  Escape trailing \ in QuestionHelper autocompletion
  [FrameworkBundle][Serializer] Remove outdated condition
  Add "doctrine/annotations" to top-level composer.json
  Fix phpdoc inconsistencies, simplify no-op sprintf.
  Remove inapplicable phpdoc comment
  nit: Fix phpdoc inconsistency and unreachable statement
  [DI] Register default env var provided types
  Fix phpdoc and unnecessary sprintf
  [FrameworkBundle][Workflow] Fix deprectation when checking workflow.registry service in dump command
  [Security] Fix BC layer for AbstractGuardAuthenticator subclasses
  Prefer line formatter on missing cli dumper
  [DI] Enhance service locator error message
This commit is contained in:
Nicolas Grekas 2017-10-24 14:50:36 +02:00
commit a13befe38e
21 changed files with 91 additions and 33 deletions

View File

@ -84,6 +84,7 @@
},
"require-dev": {
"cache/integration-tests": "dev-master",
"doctrine/annotations": "~1.0",
"doctrine/cache": "~1.6",
"doctrine/data-fixtures": "1.0.*",
"doctrine/dbal": "~2.4",

View File

@ -11,6 +11,7 @@
namespace Symfony\Bridge\Monolog\Handler;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter;
@ -20,6 +21,7 @@ use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\VarDumper\Dumper\CliDumper;
/**
* Writes logs to the console output depending on its verbosity setting.
@ -162,6 +164,9 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe
*/
protected function getDefaultFormatter()
{
if (!class_exists(CliDumper::class)) {
return new LineFormatter();
}
if (!$this->output) {
return new ConsoleFormatter();
}

View File

@ -85,7 +85,7 @@ class WorkflowExtension extends AbstractExtension
* Returns marked places.
*
* @param object $subject A subject
* @param string $placesNameOnly If true, returns only places name. If false returns the raw representation
* @param bool $placesNameOnly If true, returns only places name. If false returns the raw representation
* @param string $name A workflow name
*
* @return string[]|int[]

View File

@ -413,9 +413,6 @@ class TextDescriptor extends Descriptor
$this->writeText($this->formatCallable($callable), $options);
}
/**
* @param array $array
*/
private function renderEventListenerTable(EventDispatcherInterface $eventDispatcher, $event, array $eventListeners, SymfonyStyle $io)
{
$tableHeaders = array('Order', 'Callable', 'Priority');

View File

@ -476,9 +476,7 @@ class FrameworkExtension extends Extension
private function registerWorkflowConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
if (!$config['enabled']) {
if (!class_exists(Workflow\Workflow::class)) {
$container->removeDefinition(WorkflowDumpCommand::class);
}
$container->removeDefinition(WorkflowDumpCommand::class);
return;
}

View File

@ -11,8 +11,6 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
@ -20,10 +18,6 @@ class SerializerTest extends WebTestCase
{
public function testDeserializeArrayOfObject()
{
if (!class_exists(DataUriNormalizer::class)) {
$this->markTestSkipped('This test is only applicable when using the Symfony Serializer Component version 3.1 or superior.');
}
static::bootKernel(array('test_case' => 'Serializer'));
$container = static::$kernel->getContainer();

View File

@ -12,11 +12,12 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Question\ChoiceQuestion;
@ -283,7 +284,7 @@ class QuestionHelper extends Helper
// Save cursor position
$output->write("\0337");
// Write highlighted text
$output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
$output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $i)).'</hl>');
// Restore cursor position
$output->write("\0338");
}

View File

@ -48,7 +48,7 @@ class Table
/**
* Number of columns cache.
*
* @var array
* @var int
*/
private $numberOfColumns;

View File

@ -153,6 +153,46 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
}
public function testAutocompleteWithTrailingBackslash()
{
if (!$this->hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
}
$inputStream = $this->getInputStream('E');
$dialog = new QuestionHelper();
$dialog->setInputStream($inputStream);
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);
$question = new Question('');
$expectedCompletion = 'ExampleNamespace\\';
$question->setAutocompleterValues(array($expectedCompletion));
$output = $this->createOutputInterface();
$dialog->ask($this->createInputInterfaceMock(), $output, $question);
$outputStream = $output->getStream();
rewind($outputStream);
$actualOutput = stream_get_contents($outputStream);
// Shell control (esc) sequences are not so important: we only care that
// <hl> tag is interpreted correctly and replaced
$irrelevantEscSequences = array(
"\0337" => '', // Save cursor position
"\0338" => '', // Restore cursor position
"\033[K" => '', // Clear line from cursor till the end
);
$importantActualOutput = strtr($actualOutput, $irrelevantEscSequences);
// Remove colors (e.g. "\033[30m", "\033[31;41m")
$importantActualOutput = preg_replace('/\033\[\d+(;\d+)?m/', '', $importantActualOutput);
$this->assertEquals($expectedCompletion, $importantActualOutput);
}
public function testAskHiddenResponse()
{
if ('\\' === DIRECTORY_SEPARATOR) {

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\EnvVarProcessor;
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
@ -45,10 +46,16 @@ class RegisterEnvVarProcessorsPass implements CompilerPassInterface
}
}
if ($processors) {
if ($bag instanceof EnvPlaceholderParameterBag) {
$bag->setProvidedTypes($types);
if ($bag instanceof EnvPlaceholderParameterBag) {
foreach (EnvVarProcessor::getProvidedTypes() as $prefix => $type) {
if (!isset($types[$prefix])) {
$types[$prefix] = self::validateProvidedTypes($type, EnvVarProcessor::class);
}
}
$bag->setProvidedTypes($types);
}
if ($processors) {
$container->register('container.env_var_processors_locator', ServiceLocator::class)
->setPublic(true)
->setArguments(array($processors))

View File

@ -78,6 +78,9 @@ final class ServiceLocatorTagPass extends AbstractRecursivePass
public static function register(ContainerBuilder $container, array $refMap)
{
foreach ($refMap as $id => $ref) {
if (!$ref instanceof Reference) {
throw new InvalidArgumentException(sprintf('Invalid service locator definition: only services can be referenced, "%s" found for key "%s". Inject parameter values using constructors instead.', is_object($ref) ? get_class($ref) : gettype($ref), $id));
}
$refMap[$id] = new ServiceClosureArgument($ref);
}
ksort($refMap);

View File

@ -40,7 +40,7 @@ class DefaultsConfigurator extends AbstractServiceConfigurator
final public function tag($name, array $attributes = array())
{
if (!is_string($name) || '' === $name) {
throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string.'));
throw new InvalidArgumentException('The tag name in "_defaults" must be a non-empty string.');
}
foreach ($attributes as $attribute => $value) {

View File

@ -28,7 +28,20 @@ class RegisterEnvVarProcessorsPassTest extends TestCase
$this->assertTrue($container->has('container.env_var_processors_locator'));
$this->assertInstanceof(SimpleProcessor::class, $container->get('container.env_var_processors_locator')->get('foo'));
$this->assertSame(array('foo' => array('string')), $container->getParameterBag()->getProvidedTypes());
$expected = array(
'foo' => array('string'),
'base64' => array('string'),
'bool' => array('bool'),
'const' => array('bool', 'int', 'float', 'string', 'array'),
'file' => array('string'),
'float' => array('float'),
'int' => array('int'),
'json' => array('array'),
'resolve' => array('string'),
'string' => array('string'),
);
$this->assertSame($expected, $container->getParameterBag()->getProvidedTypes());
}
public function testNoProcessor()

View File

@ -132,7 +132,7 @@ class ControllerResolver implements ControllerResolverInterface
}
if (2 !== count($callable)) {
return sprintf('Invalid format for controller, expected array(controller, method) or controller::method.');
return 'Invalid format for controller, expected array(controller, method) or controller::method.';
}
list($controller, $method) = $callable;

View File

@ -42,7 +42,7 @@ class CollectionConfigurator
* Adds a route.
*
* @param string $name
* @param string $value
* @param string $path
*
* @return RouteConfigurator
*/

View File

@ -38,9 +38,6 @@ class RouteCollectionBuilder
private $methods;
private $resources = array();
/**
* @param LoaderInterface $loader
*/
public function __construct(LoaderInterface $loader = null)
{
$this->loader = $loader;

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Guard\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
@ -110,7 +111,7 @@ class GuardAuthenticationListener implements ListenerInterface
$credentials = $guardAuthenticator->getCredentials($request);
if (null === $credentials) {
throw new \UnexpectedValueException(sprintf('The return value of "%s::getCredentials()" must not be null. Return false from "%s::supports()" instead.', get_class($guardAuthenticator), get_class($guardAuthenticator)));
throw new \UnexpectedValueException(sprintf('The return value of "%1$s::getCredentials()" must not be null. Return false from "%1$s::supports()" instead.', get_class($guardAuthenticator)));
}
// create a token with the unique key, so that the provider knows which authenticator to use

View File

@ -46,9 +46,6 @@ class GuardAuthenticatorHandler
/**
* Authenticates the given token in the system.
*
* @param TokenInterface $token
* @param Request $request
*/
public function authenticateWithToken(TokenInterface $token, Request $request)
{

View File

@ -110,7 +110,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
*
* @return string[]
*/
protected function getAttributes($object, $format = null, array $context)
protected function getAttributes($object, $format, array $context)
{
$class = get_class($object);
$key = $class.'-'.$context['cache_key'];

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Serializer\Tests\Encoder;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\Encoder\ChainEncoder;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Encoder\NormalizationAwareInterface;
class ChainEncoderTest extends TestCase
@ -123,10 +124,14 @@ class ChainNormalizationAwareEncoder extends ChainEncoder implements Normalizati
{
}
class NormalizationAwareEncoder implements NormalizationAwareInterface
class NormalizationAwareEncoder implements EncoderInterface, NormalizationAwareInterface
{
public function supportsEncoding($format)
{
return true;
}
public function encode($data, $format, array $context = array())
{
}
}

View File

@ -71,7 +71,6 @@ class PluralizationRules
case 'vi':
case 'zh':
return 0;
break;
case 'af':
case 'bn':