Merge branch '2.8'
* 2.8: (65 commits) [VarDumper] Fix tests for HHVM Update DateTimeToArrayTransformer.php Mock microtime() and time() in transient tests Azerbaijani language pluralization rule Move HHVM tests out of the allowed failures Fix merge [2.6] Towards 100% HHVM compat [Security/Http] Fix test [Stopwatch] Fix test Minor fixes [Validator] Added missing error codes and turned codes into UUIDs Towards 100% HHVM compat Warmup twig templates in non-standard paths (closes #12507) [Bridge/PhpUnit] Enforce a consistent locale Fix param order of assertEquals (expected, actual) in test for Finder\Glob Fix choice translation domain for expanded choice widget unify default AccessDeniedExeption message trigger event with right user (add test) [Security] Initialize SwitchUserEvent::targetUser on attemptExitUser fixed CS ... Conflicts: UPGRADE-2.8.md src/Symfony/Bridge/ProxyManager/composer.json src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php src/Symfony/Bundle/FrameworkBundle/Resources/config/old_assets.xml src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_1.xml src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.json src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.md src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.txt src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/legacy_synchronized_service_definition_2.xml src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/config.yml src/Symfony/Bundle/SecurityBundle/composer.json src/Symfony/Component/Debug/ErrorHandler.php src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php src/Symfony/Component/DependencyInjection/Definition.php src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/legacy-container9.php src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/legacy-services9.dot src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy-services6.xml src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy-services9.xml src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy-services6.yml src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy-services9.yml src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php src/Symfony/Component/Form/ResolvedFormType.php src/Symfony/Component/Form/Tests/CompoundFormTest.php src/Symfony/Component/Process/Tests/AbstractProcessTest.php src/Symfony/Component/VarDumper/Tests/CliDumperTest.php src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php
This commit is contained in:
commit
d994a748dc
|
@ -20,7 +20,6 @@ matrix:
|
|||
- php: hhvm
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
- php: hhvm
|
||||
fast_finish: true
|
||||
|
||||
services: mongodb
|
||||
|
|
|
@ -50,30 +50,7 @@ class DbalLogger implements SQLLogger
|
|||
}
|
||||
|
||||
if (is_array($params)) {
|
||||
foreach ($params as $index => $param) {
|
||||
if (!is_string($params[$index])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// non utf-8 strings break json encoding
|
||||
if (!preg_match('//u', $params[$index])) {
|
||||
$params[$index] = self::BINARY_DATA_VALUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
// detect if the too long string must be shorten
|
||||
if (function_exists('mb_strlen')) {
|
||||
if (self::MAX_STRING_LENGTH < mb_strlen($params[$index], 'UTF-8')) {
|
||||
$params[$index] = mb_substr($params[$index], 0, self::MAX_STRING_LENGTH - 6, 'UTF-8').' [...]';
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (self::MAX_STRING_LENGTH < strlen($params[$index])) {
|
||||
$params[$index] = substr($params[$index], 0, self::MAX_STRING_LENGTH - 6).' [...]';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$params = $this->normalizeParams($params);
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
|
@ -101,4 +78,40 @@ class DbalLogger implements SQLLogger
|
|||
{
|
||||
$this->logger->debug($message, $params);
|
||||
}
|
||||
|
||||
private function normalizeParams(array $params)
|
||||
{
|
||||
foreach ($params as $index => $param) {
|
||||
// normalize recursively
|
||||
if (is_array($param)) {
|
||||
$params[$index] = $this->normalizeParams($param);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_string($params[$index])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// non utf-8 strings break json encoding
|
||||
if (!preg_match('//u', $params[$index])) {
|
||||
$params[$index] = self::BINARY_DATA_VALUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
// detect if the too long string must be shorten
|
||||
if (function_exists('mb_strlen')) {
|
||||
if (self::MAX_STRING_LENGTH < mb_strlen($params[$index], 'UTF-8')) {
|
||||
$params[$index] = mb_substr($params[$index], 0, self::MAX_STRING_LENGTH - 6, 'UTF-8').' [...]';
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (self::MAX_STRING_LENGTH < strlen($params[$index])) {
|
||||
$params[$index] = substr($params[$index], 0, self::MAX_STRING_LENGTH - 6).' [...]';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,37 @@ class DbalLoggerTest extends \PHPUnit_Framework_TestCase
|
|||
));
|
||||
}
|
||||
|
||||
public function testLogNonUtf8Array()
|
||||
{
|
||||
$logger = $this->getMock('Psr\\Log\\LoggerInterface');
|
||||
|
||||
$dbalLogger = $this
|
||||
->getMockBuilder('Symfony\\Bridge\\Doctrine\\Logger\\DbalLogger')
|
||||
->setConstructorArgs(array($logger, null))
|
||||
->setMethods(array('log'))
|
||||
->getMock()
|
||||
;
|
||||
|
||||
$dbalLogger
|
||||
->expects($this->once())
|
||||
->method('log')
|
||||
->with('SQL', array(
|
||||
'utf8' => 'foo',
|
||||
array(
|
||||
'nonutf8' => DbalLogger::BINARY_DATA_VALUE,
|
||||
)
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
$dbalLogger->startQuery('SQL', array(
|
||||
'utf8' => 'foo',
|
||||
array(
|
||||
'nonutf8' => "\x7F\xFF",
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
public function testLogLongString()
|
||||
{
|
||||
$logger = $this->getMock('Psr\\Log\\LoggerInterface');
|
||||
|
|
|
@ -82,7 +82,7 @@ class UniqueEntityValidator extends ConstraintValidator
|
|||
$criteria = array();
|
||||
foreach ($fields as $fieldName) {
|
||||
if (!$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) {
|
||||
throw new ConstraintDefinitionException(sprintf("The field '%s' is not mapped by Doctrine, so it cannot be validated for uniqueness.", $fieldName));
|
||||
throw new ConstraintDefinitionException(sprintf('The field "%s" is not mapped by Doctrine, so it cannot be validated for uniqueness.', $fieldName));
|
||||
}
|
||||
|
||||
$criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity);
|
||||
|
|
|
@ -21,10 +21,10 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
|||
*/
|
||||
class WebProcessor extends BaseWebProcessor
|
||||
{
|
||||
public function __construct()
|
||||
public function __construct(array $extraFields = null)
|
||||
{
|
||||
// Pass an empty array as the default null value would access $_SERVER
|
||||
parent::__construct(array());
|
||||
parent::__construct(array(), $extraFields);
|
||||
}
|
||||
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
|
|
|
@ -18,6 +18,42 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testUsesRequestServerData()
|
||||
{
|
||||
list($event, $server) = $this->createRequestEvent();
|
||||
|
||||
$processor = new WebProcessor();
|
||||
$processor->onKernelRequest($event);
|
||||
$record = $processor($this->getRecord());
|
||||
|
||||
$this->assertCount(5, $record['extra']);
|
||||
$this->assertEquals($server['REQUEST_URI'], $record['extra']['url']);
|
||||
$this->assertEquals($server['REMOTE_ADDR'], $record['extra']['ip']);
|
||||
$this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']);
|
||||
$this->assertEquals($server['SERVER_NAME'], $record['extra']['server']);
|
||||
$this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
|
||||
}
|
||||
|
||||
public function testCanBeConstructedWithExtraFields()
|
||||
{
|
||||
if (!$this->isExtraFieldsSupported()) {
|
||||
$this->markTestSkipped('WebProcessor of the installed Monolog version does not support $extraFields parameter');
|
||||
}
|
||||
|
||||
list($event, $server) = $this->createRequestEvent();
|
||||
|
||||
$processor = new WebProcessor(array('url', 'referrer'));
|
||||
$processor->onKernelRequest($event);
|
||||
$record = $processor($this->getRecord());
|
||||
|
||||
$this->assertCount(2, $record['extra']);
|
||||
$this->assertEquals($server['REQUEST_URI'], $record['extra']['url']);
|
||||
$this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function createRequestEvent()
|
||||
{
|
||||
$server = array(
|
||||
'REQUEST_URI' => 'A',
|
||||
|
@ -40,15 +76,7 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
|||
->method('getRequest')
|
||||
->will($this->returnValue($request));
|
||||
|
||||
$processor = new WebProcessor();
|
||||
$processor->onKernelRequest($event);
|
||||
$record = $processor($this->getRecord());
|
||||
|
||||
$this->assertEquals($server['REQUEST_URI'], $record['extra']['url']);
|
||||
$this->assertEquals($server['REMOTE_ADDR'], $record['extra']['ip']);
|
||||
$this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']);
|
||||
$this->assertEquals($server['SERVER_NAME'], $record['extra']['server']);
|
||||
$this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
|
||||
return array($event, $server);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +85,7 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
|||
*
|
||||
* @return array Record
|
||||
*/
|
||||
protected function getRecord($level = Logger::WARNING, $message = 'test')
|
||||
private function getRecord($level = Logger::WARNING, $message = 'test')
|
||||
{
|
||||
return array(
|
||||
'message' => $message,
|
||||
|
@ -69,4 +97,17 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
|||
'extra' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
private function isExtraFieldsSupported()
|
||||
{
|
||||
$monologWebProcessorClass = new \ReflectionClass('Monolog\Processor\WebProcessor');
|
||||
|
||||
foreach ($monologWebProcessorClass->getConstructor()->getParameters() as $parameter) {
|
||||
if ('extraFields' === $parameter->getName()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ Provides utilities for PHPUnit, especially user deprecation notices management.
|
|||
It comes with the following features:
|
||||
|
||||
* disable the garbage collector;
|
||||
* enforce a consistent `C` locale;
|
||||
* auto-register `class_exists` to load Doctrine annotations;
|
||||
* print a user deprecation notices summary at the end of the test suite.
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ if (!defined('PHPUNIT_COMPOSER_INSTALL') && !class_exists('PHPUnit_TextUI_Comman
|
|||
// https://bugs.php.net/bug.php?id=53976
|
||||
gc_disable();
|
||||
|
||||
// Enforce a consistent locale
|
||||
setlocale(LC_ALL, 'C');
|
||||
|
||||
if (class_exists('Doctrine\Common\Annotations\AnnotationRegistry')) {
|
||||
AnnotationRegistry::registerLoader('class_exists');
|
||||
}
|
||||
|
|
|
@ -68,9 +68,9 @@ class ProxyDumper implements DumperInterface
|
|||
{
|
||||
$instantiation = 'return';
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
|
||||
if ($definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) {
|
||||
$instantiation .= " \$this->services['$id'] =";
|
||||
} elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
} elseif ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
|
||||
$instantiation .= " \$this->services['$id'] = \$this->scopedServices['$scope']['$id'] =";
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
{%- for child in form %}
|
||||
{{- form_widget(child, {
|
||||
parent_label_class: label_attr.class|default(''),
|
||||
translation_domain: choice_translation_domain,
|
||||
}) -}}
|
||||
{% endfor -%}
|
||||
</div>
|
||||
|
@ -106,6 +107,7 @@
|
|||
{%- for child in form %}
|
||||
{{- form_widget(child, {
|
||||
parent_label_class: label_attr.class|default(''),
|
||||
translation_domain: choice_translation_domain,
|
||||
}) -}}
|
||||
{% endfor -%}
|
||||
</div>
|
||||
|
@ -156,7 +158,7 @@
|
|||
{%- endblock radio_label %}
|
||||
|
||||
{% block checkbox_radio_label %}
|
||||
{# Do no display the label if widget is not defined in order to prevent double label rendering #}
|
||||
{# Do not display the label if widget is not defined in order to prevent double label rendering #}
|
||||
{% if widget is defined %}
|
||||
{% if required %}
|
||||
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
|
||||
|
@ -169,7 +171,7 @@
|
|||
{% endif %}
|
||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
||||
{{- widget|raw -}}
|
||||
{{- label is not sameas(false) ? label|trans({}, translation_domain) -}}
|
||||
{{- label is not sameas(false) ? (translation_domain is sameas(false) ? label : label|trans({}, translation_domain)) -}}
|
||||
</label>
|
||||
{% endif %}
|
||||
{% endblock checkbox_radio_label %}
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<div {{ block('widget_container_attributes') }}>
|
||||
{%- for child in form %}
|
||||
{{- form_widget(child) -}}
|
||||
{{- form_label(child) -}}
|
||||
{{- form_label(child, null, {translation_domain: choice_translation_domain}) -}}
|
||||
{% endfor -%}
|
||||
</div>
|
||||
{%- endblock choice_widget_expanded -%}
|
||||
|
@ -57,7 +57,7 @@
|
|||
{%- endif -%}
|
||||
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
|
||||
{%- if placeholder is not none -%}
|
||||
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ placeholder|trans({}, translation_domain) }}</option>
|
||||
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ placeholder != '' ? placeholder|trans({}, translation_domain) }}</option>
|
||||
{%- endif -%}
|
||||
{%- if preferred_choices|length > 0 -%}
|
||||
{% set options = preferred_choices %}
|
||||
|
@ -225,7 +225,7 @@
|
|||
{% set label = name|humanize %}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
|
||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ translation_domain is sameas(false) ? label : label|trans({}, translation_domain) }}</label>
|
||||
{%- endif -%}
|
||||
{%- endblock form_label -%}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ class ServerStartCommand extends ServerCommand
|
|||
new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'),
|
||||
new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root', null),
|
||||
new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'),
|
||||
new InputOption('force', 'f', InputOption::VALUE_NONE, 'Force web server startup'),
|
||||
))
|
||||
->setName('server:start')
|
||||
->setDescription('Starts PHP built-in web server in the background')
|
||||
|
@ -110,8 +111,9 @@ EOF
|
|||
$address = $address.':'.$input->getOption('port');
|
||||
}
|
||||
|
||||
if ($this->isOtherServerProcessRunning($address)) {
|
||||
if (!$input->getOption('force') && $this->isOtherServerProcessRunning($address)) {
|
||||
$output->writeln(sprintf('<error>A process is already listening on http://%s.</error>', $address));
|
||||
$output->writeln(sprintf('<error>Use the --force option if the server process terminated unexpectedly to start a new web server process.</error>'));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -100,106 +100,103 @@ EOF
|
|||
$kernel = $this->getContainer()->get('kernel');
|
||||
|
||||
// Define Root Path to App folder
|
||||
$rootPaths = array($kernel->getRootDir());
|
||||
$transPaths = array($kernel->getRootDir().'/Resources/');
|
||||
|
||||
// Override with provided Bundle info
|
||||
if (null !== $input->getArgument('bundle')) {
|
||||
try {
|
||||
$rootPaths = array($kernel->getBundle($input->getArgument('bundle'))->getPath());
|
||||
$bundle = $kernel->getBundle($input->getArgument('bundle'));
|
||||
$transPaths = array(
|
||||
$bundle->getPath().'/Resources/',
|
||||
sprintf('%s/Resources/%s/', $kernel->getRootDir(), $bundle->getName()),
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// such a bundle does not exist, so treat the argument as path
|
||||
$rootPaths = array($input->getArgument('bundle'));
|
||||
$transPaths = array($input->getArgument('bundle').'/Resources/');
|
||||
|
||||
if (!is_dir($rootPaths[0])) {
|
||||
throw new \InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.</error>', $rootPaths[0]));
|
||||
if (!is_dir($transPaths[0])) {
|
||||
throw new \InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0]));
|
||||
}
|
||||
}
|
||||
} elseif ($input->getOption('all')) {
|
||||
foreach ($kernel->getBundles() as $bundle) {
|
||||
$rootPaths[] = $bundle->getPath();
|
||||
$transPaths[] = $bundle->getPath().'/Resources/';
|
||||
$transPaths[] = sprintf('%s/Resources/%s/', $kernel->getRootDir(), $bundle->getName());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($rootPaths as $rootPath) {
|
||||
// get bundle directory
|
||||
$translationsPath = $rootPath.'/Resources/translations';
|
||||
// Extract used messages
|
||||
$extractedCatalogue = $this->extractMessages($locale, $transPaths);
|
||||
|
||||
$output->writeln(sprintf('Translations in <info>%s</info>', $translationsPath));
|
||||
// Load defined messages
|
||||
$currentCatalogue = $this->loadCurrentMessages($locale, $transPaths, $loader);
|
||||
|
||||
// Extract used messages
|
||||
$extractedCatalogue = $this->extractMessages($locale, $rootPath);
|
||||
// Merge defined and extracted messages to get all message ids
|
||||
$mergeOperation = new MergeOperation($extractedCatalogue, $currentCatalogue);
|
||||
$allMessages = $mergeOperation->getResult()->all($domain);
|
||||
if (null !== $domain) {
|
||||
$allMessages = array($domain => $allMessages);
|
||||
}
|
||||
|
||||
// Load defined messages
|
||||
$currentCatalogue = $this->loadCurrentMessages($locale, $translationsPath, $loader);
|
||||
// No defined or extracted messages
|
||||
if (empty($allMessages) || null !== $domain && empty($allMessages[$domain])) {
|
||||
$outputMessage = sprintf('No defined or extracted messages for locale "%s"', $locale);
|
||||
|
||||
// Merge defined and extracted messages to get all message ids
|
||||
$mergeOperation = new MergeOperation($extractedCatalogue, $currentCatalogue);
|
||||
$allMessages = $mergeOperation->getResult()->all($domain);
|
||||
if (null !== $domain) {
|
||||
$allMessages = array($domain => $allMessages);
|
||||
$outputMessage .= sprintf(' and domain "%s"', $domain);
|
||||
}
|
||||
|
||||
// No defined or extracted messages
|
||||
if (empty($allMessages) || null !== $domain && empty($allMessages[$domain])) {
|
||||
$outputMessage = sprintf('<info>No defined or extracted messages for locale "%s"</info>', $locale);
|
||||
$output->warning($outputMessage);
|
||||
|
||||
if (null !== $domain) {
|
||||
$outputMessage .= sprintf(' <info>and domain "%s"</info>', $domain);
|
||||
}
|
||||
|
||||
$output->writeln($outputMessage);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load the fallback catalogues
|
||||
$fallbackCatalogues = $this->loadFallbackCatalogues($locale, $translationsPath, $loader);
|
||||
|
||||
// Display header line
|
||||
$headers = array('State', 'Domain', 'Id', sprintf('Message Preview (%s)', $locale));
|
||||
foreach ($fallbackCatalogues as $fallbackCatalogue) {
|
||||
$headers[] = sprintf('Fallback Message Preview (%s)', $fallbackCatalogue->getLocale());
|
||||
}
|
||||
|
||||
// Iterate all message ids and determine their state
|
||||
$rows = array();
|
||||
foreach ($allMessages as $domain => $messages) {
|
||||
foreach (array_keys($messages) as $messageId) {
|
||||
$value = $currentCatalogue->get($messageId, $domain);
|
||||
$states = array();
|
||||
|
||||
if ($extractedCatalogue->defines($messageId, $domain)) {
|
||||
if (!$currentCatalogue->defines($messageId, $domain)) {
|
||||
$states[] = self::MESSAGE_MISSING;
|
||||
}
|
||||
} elseif ($currentCatalogue->defines($messageId, $domain)) {
|
||||
$states[] = self::MESSAGE_UNUSED;
|
||||
}
|
||||
|
||||
if (!in_array(self::MESSAGE_UNUSED, $states) && true === $input->getOption('only-unused')
|
||||
|| !in_array(self::MESSAGE_MISSING, $states) && true === $input->getOption('only-missing')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($fallbackCatalogues as $fallbackCatalogue) {
|
||||
if ($fallbackCatalogue->defines($messageId, $domain) && $value === $fallbackCatalogue->get($messageId, $domain)) {
|
||||
$states[] = self::MESSAGE_EQUALS_FALLBACK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$row = array($this->formatStates($states), $domain, $this->formatId($messageId), $this->sanitizeString($value));
|
||||
foreach ($fallbackCatalogues as $fallbackCatalogue) {
|
||||
$row[] = $this->sanitizeString($fallbackCatalogue->get($messageId, $domain));
|
||||
}
|
||||
|
||||
$rows[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$output->table($headers, $rows);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the fallback catalogues
|
||||
$fallbackCatalogues = $this->loadFallbackCatalogues($locale, $transPaths, $loader);
|
||||
|
||||
// Display header line
|
||||
$headers = array('State', 'Domain', 'Id', sprintf('Message Preview (%s)', $locale));
|
||||
foreach ($fallbackCatalogues as $fallbackCatalogue) {
|
||||
$headers[] = sprintf('Fallback Message Preview (%s)', $fallbackCatalogue->getLocale());
|
||||
}
|
||||
$rows = array();
|
||||
// Iterate all message ids and determine their state
|
||||
foreach ($allMessages as $domain => $messages) {
|
||||
foreach (array_keys($messages) as $messageId) {
|
||||
$value = $currentCatalogue->get($messageId, $domain);
|
||||
$states = array();
|
||||
|
||||
if ($extractedCatalogue->defines($messageId, $domain)) {
|
||||
if (!$currentCatalogue->defines($messageId, $domain)) {
|
||||
$states[] = self::MESSAGE_MISSING;
|
||||
}
|
||||
} elseif ($currentCatalogue->defines($messageId, $domain)) {
|
||||
$states[] = self::MESSAGE_UNUSED;
|
||||
}
|
||||
|
||||
if (!in_array(self::MESSAGE_UNUSED, $states) && true === $input->getOption('only-unused')
|
||||
|| !in_array(self::MESSAGE_MISSING, $states) && true === $input->getOption('only-missing')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($fallbackCatalogues as $fallbackCatalogue) {
|
||||
if ($fallbackCatalogue->defines($messageId, $domain) && $value === $fallbackCatalogue->get($messageId, $domain)) {
|
||||
$states[] = self::MESSAGE_EQUALS_FALLBACK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$row = array($this->formatStates($states), $domain, $this->formatId($messageId), $this->sanitizeString($value));
|
||||
foreach ($fallbackCatalogues as $fallbackCatalogue) {
|
||||
$row[] = $this->sanitizeString($fallbackCatalogue->get($messageId, $domain));
|
||||
}
|
||||
|
||||
$rows[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$output->table($headers, $rows);
|
||||
}
|
||||
|
||||
private function formatState($state)
|
||||
|
@ -251,15 +248,18 @@ EOF
|
|||
|
||||
/**
|
||||
* @param string $locale
|
||||
* @param string $rootPath
|
||||
* @param array $transPaths
|
||||
*
|
||||
* @return MessageCatalogue
|
||||
*/
|
||||
private function extractMessages($locale, $rootPath)
|
||||
private function extractMessages($locale, $transPaths)
|
||||
{
|
||||
$extractedCatalogue = new MessageCatalogue($locale);
|
||||
if (is_dir($rootPath.'/Resources/views')) {
|
||||
$this->getContainer()->get('translation.extractor')->extract($rootPath.'/Resources/views', $extractedCatalogue);
|
||||
foreach ($transPaths as $path) {
|
||||
$path = $path.'views';
|
||||
if (is_dir($path)) {
|
||||
$this->getContainer()->get('translation.extractor')->extract($path, $extractedCatalogue);
|
||||
}
|
||||
}
|
||||
|
||||
return $extractedCatalogue;
|
||||
|
@ -267,16 +267,19 @@ EOF
|
|||
|
||||
/**
|
||||
* @param string $locale
|
||||
* @param string $translationsPath
|
||||
* @param array $transPaths
|
||||
* @param TranslationLoader $loader
|
||||
*
|
||||
* @return MessageCatalogue
|
||||
*/
|
||||
private function loadCurrentMessages($locale, $translationsPath, TranslationLoader $loader)
|
||||
private function loadCurrentMessages($locale, $transPaths, TranslationLoader $loader)
|
||||
{
|
||||
$currentCatalogue = new MessageCatalogue($locale);
|
||||
if (is_dir($translationsPath)) {
|
||||
$loader->loadMessages($translationsPath, $currentCatalogue);
|
||||
foreach ($transPaths as $path) {
|
||||
$path = $path.'translations';
|
||||
if (is_dir($path)) {
|
||||
$loader->loadMessages($path, $currentCatalogue);
|
||||
}
|
||||
}
|
||||
|
||||
return $currentCatalogue;
|
||||
|
@ -284,12 +287,12 @@ EOF
|
|||
|
||||
/**
|
||||
* @param string $locale
|
||||
* @param string $translationsPath
|
||||
* @param array $transPaths
|
||||
* @param TranslationLoader $loader
|
||||
*
|
||||
* @return MessageCatalogue[]
|
||||
*/
|
||||
private function loadFallbackCatalogues($locale, $translationsPath, TranslationLoader $loader)
|
||||
private function loadFallbackCatalogues($locale, $transPaths, TranslationLoader $loader)
|
||||
{
|
||||
$fallbackCatalogues = array();
|
||||
$translator = $this->getContainer()->get('translator');
|
||||
|
@ -300,7 +303,12 @@ EOF
|
|||
}
|
||||
|
||||
$fallbackCatalogue = new MessageCatalogue($fallbackLocale);
|
||||
$loader->loadMessages($translationsPath, $fallbackCatalogue);
|
||||
foreach ($transPaths as $path) {
|
||||
$path = $path.'translations';
|
||||
if (is_dir($path)) {
|
||||
$loader->loadMessages($path, $fallbackCatalogue);
|
||||
}
|
||||
}
|
||||
$fallbackCatalogues[] = $fallbackCatalogue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,8 @@ EOF
|
|||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output = new SymfonyStyle($input, $output);
|
||||
$kernel = $this->getContainer()->get('kernel');
|
||||
|
||||
// check presence of force or dump-message
|
||||
if ($input->getOption('force') !== true && $input->getOption('dump-messages') !== true) {
|
||||
$output->error('You must choose one of --force or --dump-messages');
|
||||
|
@ -87,30 +89,30 @@ EOF
|
|||
$kernel = $this->getContainer()->get('kernel');
|
||||
|
||||
// Define Root Path to App folder
|
||||
$rootPath = $kernel->getRootDir();
|
||||
$transPaths = array($kernel->getRootDir().'/Resources/');
|
||||
$currentName = 'app folder';
|
||||
|
||||
// Override with provided Bundle info
|
||||
if (null !== $input->getArgument('bundle')) {
|
||||
try {
|
||||
$foundBundle = $kernel->getBundle($input->getArgument('bundle'));
|
||||
$rootPath = $foundBundle->getPath();
|
||||
$transPaths = array(
|
||||
$foundBundle->getPath().'/Resources/',
|
||||
sprintf('%s/Resources/%s/', $kernel->getRootDir(), $foundBundle->getName()),
|
||||
);
|
||||
$currentName = $foundBundle->getName();
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// such a bundle does not exist, so treat the argument as path
|
||||
$rootPath = $input->getArgument('bundle');
|
||||
$currentName = $rootPath;
|
||||
$transPaths = array($input->getArgument('bundle').'/Resources/');
|
||||
$currentName = $transPaths[0];
|
||||
|
||||
if (!is_dir($rootPath)) {
|
||||
throw new \InvalidArgumentException(sprintf('<error>"%s" is neither an enabled bundle nor a directory.</error>', $rootPath));
|
||||
if (!is_dir($transPaths[0])) {
|
||||
throw new \InvalidArgumentException(sprintf('<error>"%s" is neither an enabled bundle nor a directory.</error>', $transPaths[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$output->title('Symfony translation update command');
|
||||
|
||||
// get bundle directory
|
||||
$translationsPath = $rootPath.'/Resources/translations';
|
||||
$output->text(sprintf('Generating "<info>%s</info>" translation files for "<info>%s</info>"', $input->getArgument('locale'), $currentName));
|
||||
|
||||
// load any messages from templates
|
||||
|
@ -118,13 +120,23 @@ EOF
|
|||
$output->text('Parsing templates');
|
||||
$extractor = $this->getContainer()->get('translation.extractor');
|
||||
$extractor->setPrefix($input->getOption('prefix'));
|
||||
$extractor->extract($rootPath.'/Resources/views/', $extractedCatalogue);
|
||||
foreach ($transPaths as $path) {
|
||||
$path = $path.'views';
|
||||
if (is_dir($path)) {
|
||||
$extractor->extract($path, $extractedCatalogue);
|
||||
}
|
||||
}
|
||||
|
||||
// load any existing messages from the translation files
|
||||
$currentCatalogue = new MessageCatalogue($input->getArgument('locale'));
|
||||
$output->text('Loading translation files');
|
||||
$loader = $this->getContainer()->get('translation.loader');
|
||||
$loader->loadMessages($translationsPath, $currentCatalogue);
|
||||
foreach ($transPaths as $path) {
|
||||
$path = $path.'translations';
|
||||
if (is_dir($path)) {
|
||||
$loader->loadMessages($path, $currentCatalogue);
|
||||
}
|
||||
}
|
||||
|
||||
// process catalogues
|
||||
$operation = $input->getOption('clean')
|
||||
|
@ -150,7 +162,7 @@ EOF
|
|||
array_map(function ($id) {
|
||||
return sprintf('<fg=green>%s</>', $id);
|
||||
}, $newKeys),
|
||||
array_map(function($id) {
|
||||
array_map(function ($id) {
|
||||
return sprintf('<fg=red>%s</>', $id);
|
||||
}, array_keys($operation->getObsoleteMessages($domain)))
|
||||
));
|
||||
|
@ -168,7 +180,18 @@ EOF
|
|||
// save the files
|
||||
if ($input->getOption('force') === true) {
|
||||
$output->text('Writing files');
|
||||
$writer->writeTranslations($operation->getResult(), $input->getOption('output-format'), array('path' => $translationsPath, 'default_locale' => $this->getContainer()->getParameter('kernel.default_locale')));
|
||||
|
||||
$bundleTransPath = false;
|
||||
foreach ($transPaths as $path) {
|
||||
$path = $path.'translations';
|
||||
if (is_dir($path)) {
|
||||
$bundleTransPath = $path;
|
||||
}
|
||||
}
|
||||
|
||||
if ($bundleTransPath) {
|
||||
$writer->writeTranslations($operation->getResult(), $input->getOption('output-format'), array('path' => $bundleTransPath, 'default_locale' => $this->getContainer()->getParameter('kernel.default_locale')));
|
||||
}
|
||||
}
|
||||
|
||||
$output->newLine();
|
||||
|
|
|
@ -210,12 +210,16 @@ class JsonDescriptor extends Descriptor
|
|||
{
|
||||
$data = array(
|
||||
'class' => (string) $definition->getClass(),
|
||||
'scope' => $definition->getScope(),
|
||||
'scope' => $definition->getScope(false),
|
||||
'public' => $definition->isPublic(),
|
||||
'synthetic' => $definition->isSynthetic(),
|
||||
'lazy' => $definition->isLazy(),
|
||||
);
|
||||
|
||||
if (method_exists($definition, 'isShared')) {
|
||||
$data['shared'] = $definition->isShared();
|
||||
}
|
||||
|
||||
$data['abstract'] = $definition->isAbstract();
|
||||
$data['file'] = $definition->getFile();
|
||||
|
||||
|
|
|
@ -176,12 +176,16 @@ class MarkdownDescriptor extends Descriptor
|
|||
protected function describeContainerDefinition(Definition $definition, array $options = array())
|
||||
{
|
||||
$output = '- Class: `'.$definition->getClass().'`'
|
||||
."\n".'- Scope: `'.$definition->getScope().'`'
|
||||
."\n".'- Scope: `'.$definition->getScope(false).'`'
|
||||
."\n".'- Public: '.($definition->isPublic() ? 'yes' : 'no')
|
||||
."\n".'- Synthetic: '.($definition->isSynthetic() ? 'yes' : 'no')
|
||||
."\n".'- Lazy: '.($definition->isLazy() ? 'yes' : 'no')
|
||||
;
|
||||
|
||||
if (method_exists($definition, 'isShared')) {
|
||||
$output .= "\n".'- Shared: '.($definition->isShared() ? 'yes' : 'no');
|
||||
}
|
||||
|
||||
$output .= "\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no');
|
||||
|
||||
if ($definition->getFile()) {
|
||||
|
|
|
@ -170,7 +170,7 @@ class TextDescriptor extends Descriptor
|
|||
$serviceIds = isset($options['tag']) && $options['tag'] ? array_keys($builder->findTaggedServiceIds($options['tag'])) : $builder->getServiceIds();
|
||||
$maxTags = array();
|
||||
|
||||
foreach ($serviceIds as $key => $serviceId) {
|
||||
foreach ($serviceIds as $key => $serviceId) {
|
||||
$definition = $this->resolveServiceDefinition($builder, $serviceId);
|
||||
if ($definition instanceof Definition) {
|
||||
// filter out private services unless shown explicitly
|
||||
|
@ -256,10 +256,13 @@ class TextDescriptor extends Descriptor
|
|||
$description[] = '<comment>Tags</comment> -';
|
||||
}
|
||||
|
||||
$description[] = sprintf('<comment>Scope</comment> %s', $definition->getScope());
|
||||
$description[] = sprintf('<comment>Scope</comment> %s', $definition->getScope(false));
|
||||
$description[] = sprintf('<comment>Public</comment> %s', $definition->isPublic() ? 'yes' : 'no');
|
||||
$description[] = sprintf('<comment>Synthetic</comment> %s', $definition->isSynthetic() ? 'yes' : 'no');
|
||||
$description[] = sprintf('<comment>Lazy</comment> %s', $definition->isLazy() ? 'yes' : 'no');
|
||||
if (method_exists($definition, 'isShared')) {
|
||||
$description[] = sprintf('<comment>Shared</comment> %s', $definition->isShared() ? 'yes' : 'no');
|
||||
}
|
||||
$description[] = sprintf('<comment>Abstract</comment> %s', $definition->isAbstract() ? 'yes' : 'no');
|
||||
|
||||
if ($definition->getFile()) {
|
||||
|
|
|
@ -346,10 +346,13 @@ class XmlDescriptor extends Descriptor
|
|||
}
|
||||
}
|
||||
|
||||
$serviceXML->setAttribute('scope', $definition->getScope());
|
||||
$serviceXML->setAttribute('scope', $definition->getScope(false));
|
||||
$serviceXML->setAttribute('public', $definition->isPublic() ? 'true' : 'false');
|
||||
$serviceXML->setAttribute('synthetic', $definition->isSynthetic() ? 'true' : 'false');
|
||||
$serviceXML->setAttribute('lazy', $definition->isLazy() ? 'true' : 'false');
|
||||
if (method_exists($definition, 'isShared')) {
|
||||
$serviceXML->setAttribute('shared', $definition->isShared() ? 'true' : 'false');
|
||||
}
|
||||
$serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false');
|
||||
$serviceXML->setAttribute('file', $definition->getFile());
|
||||
|
||||
|
|
|
@ -119,9 +119,9 @@ abstract class Controller extends ContainerAware
|
|||
* @param mixed $attributes The attributes
|
||||
* @param mixed $object The object
|
||||
*
|
||||
* @throws \LogicException
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
protected function isGranted($attributes, $object = null)
|
||||
{
|
||||
|
@ -231,7 +231,7 @@ abstract class Controller extends ContainerAware
|
|||
*
|
||||
* @return AccessDeniedException
|
||||
*/
|
||||
protected function createAccessDeniedException($message = 'Access Denied', \Exception $previous = null)
|
||||
protected function createAccessDeniedException($message = 'Access Denied.', \Exception $previous = null)
|
||||
{
|
||||
return new AccessDeniedException($message, $previous);
|
||||
}
|
||||
|
|
|
@ -444,7 +444,7 @@ class FrameworkExtension extends Extension
|
|||
/**
|
||||
* Loads the request configuration.
|
||||
*
|
||||
* @param array $config A session configuration array
|
||||
* @param array $config A request configuration array
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
* @param XmlFileLoader $loader An XmlFileLoader instance
|
||||
*/
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<services>
|
||||
<service id="templating.asset.path_package" class="Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage" abstract="true">
|
||||
<argument type="expression">service('request_stack').getMasterRequest()</argument>
|
||||
<argument /> <!-- version -->
|
||||
<argument /> <!-- version format -->
|
||||
</service>
|
||||
|
||||
<service id="templating.asset.url_package" class="Symfony\Component\Templating\Asset\UrlPackage" abstract="true">
|
||||
<argument /> <!-- base urls -->
|
||||
<argument /> <!-- version -->
|
||||
<argument /> <!-- version format -->
|
||||
</service>
|
||||
|
||||
<service id="templating.asset.request_aware_package" class="Symfony\Component\Templating\Asset\PackageInterface" abstract="true">
|
||||
<factory service="templating.asset.package_factory" method="getPackage" />
|
||||
<argument type="expression">service('request_stack').getMasterRequest()</argument>
|
||||
<argument /> <!-- HTTP id -->
|
||||
<argument /> <!-- SSL id -->
|
||||
</service>
|
||||
|
||||
<service id="templating.asset.package_factory" class="Symfony\Bundle\FrameworkBundle\Templating\Asset\PackageFactory">
|
||||
<argument type="service" id="service_container" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
|
@ -9,16 +9,16 @@
|
|||
</parameters>
|
||||
|
||||
<services>
|
||||
<service id="test.client" class="Symfony\Bundle\FrameworkBundle\Client" scope="prototype">
|
||||
<service id="test.client" class="Symfony\Bundle\FrameworkBundle\Client" shared="false">
|
||||
<argument type="service" id="kernel" />
|
||||
<argument>%test.client.parameters%</argument>
|
||||
<argument type="service" id="test.client.history" />
|
||||
<argument type="service" id="test.client.cookiejar" />
|
||||
</service>
|
||||
|
||||
<service id="test.client.history" class="Symfony\Component\BrowserKit\History" scope="prototype" />
|
||||
<service id="test.client.history" class="Symfony\Component\BrowserKit\History" shared="false" />
|
||||
|
||||
<service id="test.client.cookiejar" class="Symfony\Component\BrowserKit\CookieJar" scope="prototype" />
|
||||
<service id="test.client.cookiejar" class="Symfony\Component\BrowserKit\CookieJar" shared="false" />
|
||||
|
||||
<service id="test.session.listener" class="Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener">
|
||||
<argument type="service" id="service_container" />
|
||||
|
|
|
@ -32,6 +32,16 @@
|
|||
<argument>%validator.mapping.cache.prefix%</argument>
|
||||
</service>
|
||||
|
||||
<service id="validator.mapping.cache.doctrine.apc" class="Symfony\Component\Validator\Mapping\Cache\DoctrineCache" public="false">
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Common\Cache\ApcCache">
|
||||
<call method="setNamespace">
|
||||
<argument>%validator.mapping.cache.prefix%</argument>
|
||||
</call>
|
||||
</service>
|
||||
</argument>
|
||||
</service>
|
||||
|
||||
<service id="validator.validator_factory" class="Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory" public="false">
|
||||
<argument type="service" id="service_container" />
|
||||
<argument type="collection" />
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
)) ?>
|
||||
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
|
||||
>
|
||||
<?php if (null !== $placeholder): ?><option value=""<?php if ($required and empty($value) && "0" !== $value): ?> selected="selected"<?php endif?>><?php echo $view->escape($view['translator']->trans($placeholder, array(), $translation_domain)) ?></option><?php endif; ?>
|
||||
<?php if (null !== $placeholder): ?><option value=""<?php if ($required and empty($value) && '0' !== $value): ?> selected="selected"<?php endif?>><?php echo '' != $placeholder ? $view->escape($view['translator']->trans($placeholder, array(), $translation_domain)) : '' ?></option><?php endif; ?>
|
||||
<?php if (count($preferred_choices) > 0): ?>
|
||||
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?>
|
||||
<?php if (count($choices) > 0 && null !== $separator): ?>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php foreach ($form as $child): ?>
|
||||
<?php echo $view['form']->widget($child) ?>
|
||||
<?php echo $view['form']->label($child) ?>
|
||||
<?php echo $view['form']->label($child, null, array('translation_domain' => $choice_translation_domain)) ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
<?php if (!$label) { $label = isset($label_format)
|
||||
? strtr($label_format, array('%name%' => $name, '%id%' => $id))
|
||||
: $view['form']->humanize($name); } ?>
|
||||
<label <?php foreach ($label_attr as $k => $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?>><?php echo $view->escape($view['translator']->trans($label, array(), $translation_domain)) ?></label>
|
||||
<label <?php foreach ($label_attr as $k => $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?>><?php echo $view->escape(false !== $translation_domain ? $view['translator']->trans($label, array(), $translation_domain) : $label) ?></label>
|
||||
<?php endif ?>
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
|
|||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
@ -515,14 +515,14 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||
return $container;
|
||||
}
|
||||
|
||||
private function assertPathPackage(ContainerBuilder $container, Definition $package, $basePath, $version, $format)
|
||||
private function assertPathPackage(ContainerBuilder $container, DefinitionDecorator $package, $basePath, $version, $format)
|
||||
{
|
||||
$this->assertEquals('assets.path_package', $package->getParent());
|
||||
$this->assertEquals($basePath, $package->getArgument(0));
|
||||
$this->assertVersionStrategy($container, $package->getArgument(1), $version, $format);
|
||||
}
|
||||
|
||||
private function assertUrlPackage(ContainerBuilder $container, Definition $package, $baseUrls, $version, $format)
|
||||
private function assertUrlPackage(ContainerBuilder $container, DefinitionDecorator $package, $baseUrls, $version, $format)
|
||||
{
|
||||
$this->assertEquals('assets.url_package', $package->getParent());
|
||||
$this->assertEquals($baseUrls, $package->getArgument(0));
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"public": true,
|
||||
"synthetic": false,
|
||||
"lazy": true,
|
||||
"shared": true,
|
||||
"abstract": true,
|
||||
"file": null,
|
||||
"factory_class": "Full\\Qualified\\FactoryClass",
|
||||
|
|
|
@ -12,6 +12,7 @@ definition_1
|
|||
- Public: yes
|
||||
- Synthetic: no
|
||||
- Lazy: yes
|
||||
- Shared: yes
|
||||
- Abstract: yes
|
||||
- Factory Class: `Full\Qualified\FactoryClass`
|
||||
- Factory Method: `get`
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<container>
|
||||
<alias id="alias_1" service="service_1" public="true"/>
|
||||
<alias id="alias_2" service="service_2" public="false"/>
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" scope="container" public="true" synthetic="false" lazy="true" abstract="true" file="">
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" scope="container" public="true" synthetic="false" lazy="true" shared="true" abstract="true" file="">
|
||||
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||
</definition>
|
||||
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerBuilder"/>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"public": true,
|
||||
"synthetic": false,
|
||||
"lazy": true,
|
||||
"shared": true,
|
||||
"abstract": true,
|
||||
"file": null,
|
||||
"factory_class": "Full\\Qualified\\FactoryClass",
|
||||
|
@ -20,6 +21,7 @@
|
|||
"public": false,
|
||||
"synthetic": true,
|
||||
"lazy": false,
|
||||
"shared": true,
|
||||
"abstract": false,
|
||||
"file": "\/path\/to\/file",
|
||||
"factory_service": "factory.service",
|
||||
|
|
|
@ -12,6 +12,7 @@ definition_1
|
|||
- Public: yes
|
||||
- Synthetic: no
|
||||
- Lazy: yes
|
||||
- Shared: yes
|
||||
- Abstract: yes
|
||||
- Factory Class: `Full\Qualified\FactoryClass`
|
||||
- Factory Method: `get`
|
||||
|
@ -24,6 +25,7 @@ definition_2
|
|||
- Public: no
|
||||
- Synthetic: yes
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
<container>
|
||||
<alias id="alias_1" service="service_1" public="true"/>
|
||||
<alias id="alias_2" service="service_2" public="false"/>
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" scope="container" public="true" synthetic="false" lazy="true" abstract="true" file="">
|
||||
<definition id="definition_1" class="Full\Qualified\Class1" scope="container" public="true" synthetic="false" lazy="true" shared="true" abstract="true" file="">
|
||||
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||
</definition>
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
<tags>
|
||||
<tag name="tag1">
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"public": false,
|
||||
"synthetic": true,
|
||||
"lazy": false,
|
||||
"shared": true,
|
||||
"abstract": false,
|
||||
"file": "\/path\/to\/file",
|
||||
"factory_service": "factory.service",
|
||||
|
|
|
@ -12,6 +12,7 @@ definition_2
|
|||
- Public: no
|
||||
- Synthetic: yes
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container>
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
<tags>
|
||||
<tag name="tag1">
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"public": false,
|
||||
"synthetic": true,
|
||||
"lazy": false,
|
||||
"shared": true,
|
||||
"abstract": false,
|
||||
"file": "\/path\/to\/file",
|
||||
"factory_service": "factory.service",
|
||||
|
@ -19,6 +20,7 @@
|
|||
"public": false,
|
||||
"synthetic": true,
|
||||
"lazy": false,
|
||||
"shared": true,
|
||||
"abstract": false,
|
||||
"file": "\/path\/to\/file",
|
||||
"factory_service": "factory.service",
|
||||
|
|
|
@ -12,6 +12,7 @@ definition_2
|
|||
- Public: no
|
||||
- Synthetic: yes
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
|
@ -29,6 +30,7 @@ definition_2
|
|||
- Public: no
|
||||
- Synthetic: yes
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container>
|
||||
<tag name="tag1">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
</definition>
|
||||
</tag>
|
||||
<tag name="tag2">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" abstract="false" file="/path/to/file">
|
||||
<definition id="definition_2" class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
</definition>
|
||||
</tag>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"public": true,
|
||||
"synthetic": false,
|
||||
"lazy": true,
|
||||
"shared": true,
|
||||
"abstract": true,
|
||||
"file": null,
|
||||
"factory_class": "Full\\Qualified\\FactoryClass",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
- Public: yes
|
||||
- Synthetic: no
|
||||
- Lazy: yes
|
||||
- Shared: yes
|
||||
- Abstract: yes
|
||||
- Factory Class: `Full\Qualified\FactoryClass`
|
||||
- Factory Method: `get`
|
|
@ -5,6 +5,7 @@
|
|||
<comment>Public</comment> yes
|
||||
<comment>Synthetic</comment> no
|
||||
<comment>Lazy</comment> yes
|
||||
<comment>Shared</comment> yes
|
||||
<comment>Abstract</comment> yes
|
||||
<comment>Factory Class</comment> Full\Qualified\FactoryClass
|
||||
<comment>Factory Method</comment> get
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definition class="Full\Qualified\Class1" scope="container" public="true" synthetic="false" lazy="true" abstract="true" file="">
|
||||
<definition class="Full\Qualified\Class1" scope="container" public="true" synthetic="false" lazy="true" shared="true" abstract="true" file="">
|
||||
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||
</definition>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"public": false,
|
||||
"synthetic": true,
|
||||
"lazy": false,
|
||||
"shared": true,
|
||||
"abstract": false,
|
||||
"file": "\/path\/to\/file",
|
||||
"factory_service": "factory.service",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
- Public: no
|
||||
- Synthetic: yes
|
||||
- Lazy: no
|
||||
- Shared: yes
|
||||
- Abstract: no
|
||||
- File: `/path/to/file`
|
||||
- Factory Service: `factory.service`
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<comment>Public</comment> no
|
||||
<comment>Synthetic</comment> yes
|
||||
<comment>Lazy</comment> no
|
||||
<comment>Shared</comment> yes
|
||||
<comment>Abstract</comment> no
|
||||
<comment>Required File</comment> /path/to/file
|
||||
<comment>Factory Service</comment> factory.service
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definition class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" abstract="false" file="/path/to/file">
|
||||
<definition class="Full\Qualified\Class2" scope="container" public="false" synthetic="true" lazy="false" shared="true" abstract="false" file="/path/to/file">
|
||||
<factory service="factory.service" method="get"/>
|
||||
<tags>
|
||||
<tag name="tag1">
|
||||
|
|
|
@ -4,7 +4,8 @@ imports:
|
|||
services:
|
||||
csrf_form_login.form.type:
|
||||
class: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Form\UserLoginFormType
|
||||
arguments: [ @request_stack ]
|
||||
arguments:
|
||||
- @request_stack
|
||||
tags:
|
||||
- { name: form.type, alias: user_login }
|
||||
|
||||
|
|
|
@ -11,9 +11,11 @@
|
|||
|
||||
namespace Symfony\Bundle\TwigBundle\CacheWarmer;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinderInterface;
|
||||
use Symfony\Component\Templating\TemplateReference;
|
||||
|
||||
/**
|
||||
* Generates the Twig cache for all templates.
|
||||
|
@ -27,14 +29,16 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
|||
{
|
||||
protected $container;
|
||||
protected $finder;
|
||||
private $paths;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ContainerInterface $container The dependency injection container
|
||||
* @param TemplateFinderInterface $finder The template paths cache warmer
|
||||
* @param array $paths Additional twig paths to warm
|
||||
*/
|
||||
public function __construct(ContainerInterface $container, TemplateFinderInterface $finder)
|
||||
public function __construct(ContainerInterface $container, TemplateFinderInterface $finder, array $paths = array())
|
||||
{
|
||||
// We don't inject the Twig environment directly as it depends on the
|
||||
// template locator (via the loader) which might be a cached one.
|
||||
|
@ -42,6 +46,7 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
|||
// has been warmed up
|
||||
$this->container = $container;
|
||||
$this->finder = $finder;
|
||||
$this->paths = $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,7 +58,13 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
|||
{
|
||||
$twig = $this->container->get('twig');
|
||||
|
||||
foreach ($this->finder->findAllTemplates() as $template) {
|
||||
$templates = $this->finder->findAllTemplates();
|
||||
|
||||
foreach ($this->paths as $path => $namespace) {
|
||||
$templates = array_merge($templates, $this->findTemplatesInFolder($namespace, $path));
|
||||
}
|
||||
|
||||
foreach ($templates as $template) {
|
||||
if ('twig' !== $template->get('engine')) {
|
||||
continue;
|
||||
}
|
||||
|
@ -75,4 +86,32 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find templates in the given directory.
|
||||
*
|
||||
* @param string $namespace The namespace for these templates
|
||||
* @param string $dir The folder where to look for templates
|
||||
*
|
||||
* @return array An array of templates of type TemplateReferenceInterface
|
||||
*/
|
||||
private function findTemplatesInFolder($namespace, $dir)
|
||||
{
|
||||
if (!is_dir($dir)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$templates = array();
|
||||
$finder = new Finder();
|
||||
|
||||
foreach ($finder->files()->followLinks()->in($dir) as $file) {
|
||||
$name = $file->getRelativePathname();
|
||||
$templates[] = new TemplateReference(
|
||||
$namespace ? sprintf('@%s/%s', $namespace, $name) : $name,
|
||||
'twig'
|
||||
);
|
||||
}
|
||||
|
||||
return $templates;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,8 @@ class TwigExtension extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
$container->getDefinition('twig.cache_warmer')->replaceArgument(2, $config['paths']);
|
||||
|
||||
// register bundles as Twig namespaces
|
||||
foreach ($container->getParameter('kernel.bundles') as $bundle => $class) {
|
||||
$dir = $container->getParameter('kernel.root_dir').'/Resources/'.$bundle.'/views';
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<service id="twig.cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer" public="false">
|
||||
<argument type="service" id="service_container" />
|
||||
<argument type="service" id="templating.finder" />
|
||||
<argument type="collection" /> <!-- Twig paths -->
|
||||
</service>
|
||||
|
||||
<service id="twig.loader.native_filesystem" class="Twig_Loader_Filesystem" public="false">
|
||||
|
|
|
@ -18,7 +18,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
use Symfony\Component\DependencyInjection\Scope;
|
||||
|
||||
class WebProfilerExtensionTest extends TestCase
|
||||
{
|
||||
|
@ -49,8 +48,6 @@ class WebProfilerExtensionTest extends TestCase
|
|||
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
|
||||
|
||||
$this->container = new ContainerBuilder();
|
||||
$this->container->addScope(new Scope('request'));
|
||||
$this->container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request');
|
||||
$this->container->register('router', $this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'));
|
||||
$this->container->register('twig', 'Twig_Environment');
|
||||
$this->container->setParameter('kernel.bundles', array());
|
||||
|
@ -125,7 +122,6 @@ class WebProfilerExtensionTest extends TestCase
|
|||
eval('?>'.$dumper->dump(array('class' => $class)));
|
||||
|
||||
$container = new $class();
|
||||
$container->enterScope('request');
|
||||
$container->set('kernel', $this->kernel);
|
||||
|
||||
return $container;
|
||||
|
|
|
@ -77,7 +77,7 @@ class Cookie
|
|||
if (null !== $expires) {
|
||||
$timestampAsDateTime = \DateTime::createFromFormat('U', $expires);
|
||||
if (false === $timestampAsDateTime) {
|
||||
throw new \UnexpectedValueException(sprintf('The cookie expiration time "%s" is not valid.'), $expires);
|
||||
throw new \UnexpectedValueException(sprintf('The cookie expiration time "%s" is not valid.', $expires));
|
||||
}
|
||||
|
||||
$this->expires = $timestampAsDateTime->getTimestamp();
|
||||
|
|
|
@ -22,7 +22,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
public function prepare_workspace()
|
||||
{
|
||||
$this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().rand(0, 1000);
|
||||
$this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().mt_rand(0, 1000);
|
||||
mkdir($this->workspace, 0777, true);
|
||||
$this->workspace = realpath($this->workspace);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
|||
protected $addIfNotSet = false;
|
||||
protected $performDeepMerging = true;
|
||||
protected $ignoreExtraKeys = false;
|
||||
protected $removeExtraKeys = true;
|
||||
protected $normalizeKeys = true;
|
||||
|
||||
public function setNormalizeKeys($normalizeKeys)
|
||||
|
@ -140,10 +141,12 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
|||
* Whether extra keys should just be ignore without an exception.
|
||||
*
|
||||
* @param bool $boolean To allow extra keys
|
||||
* @param bool $remove To remove extra keys
|
||||
*/
|
||||
public function setIgnoreExtraKeys($boolean)
|
||||
public function setIgnoreExtraKeys($boolean, $remove = true)
|
||||
{
|
||||
$this->ignoreExtraKeys = (bool) $boolean;
|
||||
$this->removeExtraKeys = $this->ignoreExtraKeys && $remove;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,6 +303,9 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
|||
if (isset($this->children[$name])) {
|
||||
$normalized[$name] = $this->children[$name]->normalize($val);
|
||||
unset($value[$name]);
|
||||
} elseif (false === $this->removeExtraKeys) {
|
||||
$normalized[$name] = $val;
|
||||
unset($value[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
|||
{
|
||||
protected $performDeepMerging = true;
|
||||
protected $ignoreExtraKeys = false;
|
||||
protected $removeExtraKeys = true;
|
||||
protected $children = array();
|
||||
protected $prototype;
|
||||
protected $atLeastOne = false;
|
||||
|
@ -284,11 +285,14 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
|||
* you want to send an entire configuration array through a special
|
||||
* tree that processes only part of the array.
|
||||
*
|
||||
* @param bool $remove Whether to remove the extra keys
|
||||
*
|
||||
* @return ArrayNodeDefinition
|
||||
*/
|
||||
public function ignoreExtraKeys()
|
||||
public function ignoreExtraKeys($remove = true)
|
||||
{
|
||||
$this->ignoreExtraKeys = true;
|
||||
$this->removeExtraKeys = $remove;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -393,7 +397,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
|||
$node->addEquivalentValue(false, $this->falseEquivalent);
|
||||
$node->setPerformDeepMerging($this->performDeepMerging);
|
||||
$node->setRequired($this->required);
|
||||
$node->setIgnoreExtraKeys($this->ignoreExtraKeys);
|
||||
$node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
|
||||
$node->setNormalizeKeys($this->normalizeKeys);
|
||||
|
||||
if (null !== $this->normalization) {
|
||||
|
|
|
@ -50,6 +50,21 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue(true, 'No exception was thrown when setIgnoreExtraKeys is true');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that extra keys are not removed when
|
||||
* ignoreExtraKeys second option is set to false.
|
||||
*
|
||||
* Related to testExceptionThrownOnUnrecognizedChild
|
||||
*/
|
||||
public function testIgnoreExtraKeysNotRemoved()
|
||||
{
|
||||
$node = new ArrayNode('roo');
|
||||
$node->setIgnoreExtraKeys(true, false);
|
||||
|
||||
$data = array('foo' => 'bar');
|
||||
$this->assertSame($data, $node->normalize($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPreNormalizationTests
|
||||
*/
|
||||
|
|
|
@ -69,7 +69,7 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
|
||||
$this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');
|
||||
|
||||
$resource = new DirectoryResource('/____foo/foobar'.rand(1, 999999));
|
||||
$resource = new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999));
|
||||
$this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed');
|
||||
$this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated');
|
||||
|
||||
$resource = new FileResource('/____foo/foobar'.rand(1, 999999));
|
||||
$resource = new FileResource('/____foo/foobar'.mt_rand(1, 999999));
|
||||
$this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist');
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class TextDescriptor extends Descriptor
|
|||
$totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
|
||||
$spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
|
||||
|
||||
$this->writeText(sprintf(" <info>%s</info>%s%s%s",
|
||||
$this->writeText(sprintf(' <info>%s</info>%s%s%s',
|
||||
$argument->getName(),
|
||||
str_repeat(' ', $spacingWidth),
|
||||
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
||||
|
@ -77,7 +77,7 @@ class TextDescriptor extends Descriptor
|
|||
|
||||
$spacingWidth = $totalWidth - strlen($synopsis) + 2;
|
||||
|
||||
$this->writeText(sprintf(" <info>%s</info>%s%s%s%s",
|
||||
$this->writeText(sprintf(' <info>%s</info>%s%s%s%s',
|
||||
$synopsis,
|
||||
str_repeat(' ', $spacingWidth),
|
||||
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
||||
|
@ -207,7 +207,7 @@ class TextDescriptor extends Descriptor
|
|||
foreach ($namespace['commands'] as $name) {
|
||||
$this->writeText("\n");
|
||||
$spacingWidth = $width - strlen($name);
|
||||
$this->writeText(sprintf(" <info>%s</info>%s%s", $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
|
||||
$this->writeText(sprintf(' <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,8 @@ class TextDescriptor extends Descriptor
|
|||
{
|
||||
$totalWidth = 0;
|
||||
foreach ($options as $option) {
|
||||
$nameLength = 4 + strlen($option->getName()) + 2; // - + shortcut + , + whitespace + name + --
|
||||
// "-" + shortcut + ", --" + name
|
||||
$nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + strlen($option->getName());
|
||||
|
||||
if ($option->acceptValue()) {
|
||||
$valueLength = 1 + strlen($option->getName()); // = + value
|
||||
|
|
|
@ -205,24 +205,26 @@ class Table
|
|||
public function render()
|
||||
{
|
||||
$this->calculateNumberOfColumns();
|
||||
$this->rows = $this->buildTableRows($this->rows);
|
||||
$this->headers = $this->buildTableRows($this->headers);
|
||||
$rows = $this->buildTableRows($this->rows);
|
||||
$headers = $this->buildTableRows($this->headers);
|
||||
|
||||
$this->calculateColumnsWidth(array_merge($headers, $rows));
|
||||
|
||||
$this->renderRowSeparator();
|
||||
if (!empty($this->headers)) {
|
||||
foreach ($this->headers as $header) {
|
||||
if (!empty($headers)) {
|
||||
foreach ($headers as $header) {
|
||||
$this->renderRow($header, $this->style->getCellHeaderFormat());
|
||||
$this->renderRowSeparator();
|
||||
}
|
||||
}
|
||||
foreach ($this->rows as $row) {
|
||||
foreach ($rows as $row) {
|
||||
if ($row instanceof TableSeparator) {
|
||||
$this->renderRowSeparator();
|
||||
} else {
|
||||
$this->renderRow($row, $this->style->getCellRowFormat());
|
||||
}
|
||||
}
|
||||
if (!empty($this->rows)) {
|
||||
if (!empty($rows)) {
|
||||
$this->renderRowSeparator();
|
||||
}
|
||||
|
||||
|
@ -246,7 +248,7 @@ class Table
|
|||
|
||||
$markup = $this->style->getCrossingChar();
|
||||
for ($column = 0; $column < $count; $column++) {
|
||||
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->getColumnWidth($column)).$this->style->getCrossingChar();
|
||||
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar();
|
||||
}
|
||||
|
||||
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
|
||||
|
@ -292,11 +294,11 @@ class Table
|
|||
private function renderCell(array $row, $column, $cellFormat)
|
||||
{
|
||||
$cell = isset($row[$column]) ? $row[$column] : '';
|
||||
$width = $this->getColumnWidth($column);
|
||||
$width = $this->columnWidths[$column];
|
||||
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
|
||||
// add the width of the following columns(numbers of colspan).
|
||||
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
|
||||
$width += $this->getColumnSeparatorWidth() + $this->getColumnWidth($nextColumn);
|
||||
$width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -509,21 +511,20 @@ class Table
|
|||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getColumnWidth($column)
|
||||
private function calculateColumnsWidth($rows)
|
||||
{
|
||||
if (isset($this->columnWidths[$column])) {
|
||||
return $this->columnWidths[$column];
|
||||
}
|
||||
for ($column = 0; $column < $this->numberOfColumns; $column++) {
|
||||
$lengths = array();
|
||||
foreach ($rows as $row) {
|
||||
if ($row instanceof TableSeparator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (array_merge($this->headers, $this->rows) as $row) {
|
||||
if ($row instanceof TableSeparator) {
|
||||
continue;
|
||||
$lengths[] = $this->getCellWidth($row, $column);
|
||||
}
|
||||
|
||||
$lengths[] = $this->getCellWidth($row, $column);
|
||||
$this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
|
||||
}
|
||||
|
||||
return $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -221,7 +221,7 @@ class ArgvInput extends Input
|
|||
}
|
||||
|
||||
if (null !== $value && !$option->acceptValue()) {
|
||||
throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name, $value));
|
||||
throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
|
||||
}
|
||||
|
||||
if (null === $value && $option->acceptValue() && count($this->parsed)) {
|
||||
|
|
|
@ -30,6 +30,9 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
|||
*/
|
||||
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
||||
{
|
||||
/**
|
||||
* @var StreamOutput
|
||||
*/
|
||||
private $stderr;
|
||||
|
||||
/**
|
||||
|
@ -43,14 +46,12 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
|||
*/
|
||||
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
|
||||
{
|
||||
$outputStream = 'php://stdout';
|
||||
if (!$this->hasStdoutSupport()) {
|
||||
$outputStream = 'php://output';
|
||||
}
|
||||
$outputStream = $this->hasStdoutSupport() ? 'php://stdout' : 'php://output';
|
||||
$errorStream = $this->hasStderrSupport() ? 'php://stderr' : 'php://output';
|
||||
|
||||
parent::__construct(fopen($outputStream, 'w'), $verbosity, $decorated, $formatter);
|
||||
|
||||
$this->stderr = new StreamOutput(fopen('php://stderr', 'w'), $verbosity, $decorated, $this->getFormatter());
|
||||
$this->stderr = new StreamOutput(fopen($errorStream, 'w'), $verbosity, $decorated, $this->getFormatter());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,14 +101,32 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
|||
* Returns true if current environment supports writing console output to
|
||||
* STDOUT.
|
||||
*
|
||||
* IBM iSeries (OS400) exhibits character-encoding issues when writing to
|
||||
* STDOUT and doesn't properly convert ASCII to EBCDIC, resulting in garbage
|
||||
* output.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasStdoutSupport()
|
||||
{
|
||||
return ('OS400' != php_uname('s'));
|
||||
return false === $this->isRunningOS400();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if current environment supports writing console output to
|
||||
* STDERR.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasStderrSupport()
|
||||
{
|
||||
return false === $this->isRunningOS400();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current executing environment is IBM iSeries (OS400), which
|
||||
* doesn't properly convert character-encodings between ASCII to EBCDIC.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isRunningOS400()
|
||||
{
|
||||
return 'OS400' === php_uname('s');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class ObjectsProvider
|
|||
'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'),
|
||||
'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
|
||||
'input_option_5' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, "multiline\noption description"),
|
||||
'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"name":"--option_name","shortcut":"-o|-O","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"option with multiple shortcuts","default":null}
|
|
@ -0,0 +1,9 @@
|
|||
**option_name:**
|
||||
|
||||
* Name: `--option_name`
|
||||
* Shortcut: `-o|-O`
|
||||
* Accept value: yes
|
||||
* Is value required: yes
|
||||
* Is multiple: no
|
||||
* Description: option with multiple shortcuts
|
||||
* Default: `NULL`
|
|
@ -0,0 +1 @@
|
|||
<info>-o|O, --option_name=OPTION_NAME</info> option with multiple shortcuts
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<option name="--option_name" shortcut="-o" shortcuts="-o|-O" accept_value="1" is_value_required="1" is_multiple="0">
|
||||
<description>option with multiple shortcuts</description>
|
||||
<defaults/>
|
||||
</option>
|
|
@ -427,7 +427,7 @@ TABLE
|
|||
array('ISBN', 'Author'),
|
||||
array(
|
||||
array(
|
||||
new TableCell("9971-5-0210-0", array('rowspan' => 3, 'colspan' => 1)),
|
||||
new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)),
|
||||
'Dante Alighieri',
|
||||
),
|
||||
array(new TableSeparator()),
|
||||
|
@ -554,6 +554,33 @@ TABLE;
|
|||
$this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works');
|
||||
}
|
||||
|
||||
public function testRenderMultiCalls()
|
||||
{
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
$table->setRows(array(
|
||||
array(new TableCell('foo', array('colspan' => 2))),
|
||||
));
|
||||
$table->render();
|
||||
$table->render();
|
||||
$table->render();
|
||||
|
||||
$expected =
|
||||
<<<TABLE
|
||||
+---+--+
|
||||
| foo |
|
||||
+---+--+
|
||||
+---+--+
|
||||
| foo |
|
||||
+---+--+
|
||||
+---+--+
|
||||
| foo |
|
||||
+---+--+
|
||||
|
||||
TABLE;
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
protected function getOutputStream()
|
||||
{
|
||||
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
|
||||
|
|
|
@ -95,6 +95,7 @@ class ErrorHandler
|
|||
private static $reservedMemory;
|
||||
private static $stackedErrors = array();
|
||||
private static $stackedErrorLevels = array();
|
||||
private static $toStringException = null;
|
||||
|
||||
/**
|
||||
* Registers the error handler.
|
||||
|
@ -351,13 +352,56 @@ class ErrorHandler
|
|||
}
|
||||
|
||||
if ($throw) {
|
||||
if (($this->scopedErrors & $type) && class_exists(ContextErrorException::class)) {
|
||||
// Checking for class existence is a work around for https://bugs.php.net/42098
|
||||
if (null !== self::$toStringException) {
|
||||
$throw = self::$toStringException;
|
||||
self::$toStringException = null;
|
||||
} elseif (($this->scopedErrors & $type) && class_exists(ContextErrorException::class)) {
|
||||
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
|
||||
} else {
|
||||
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
|
||||
}
|
||||
|
||||
if (E_USER_ERROR & $type) {
|
||||
$backtrace = $backtrace ?: $throw->getTrace();
|
||||
|
||||
for ($i = 1; isset($backtrace[$i]); ++$i) {
|
||||
if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function'])
|
||||
&& '__toString' === $backtrace[$i]['function']
|
||||
&& '->' === $backtrace[$i]['type']
|
||||
&& !isset($backtrace[$i - 1]['class'])
|
||||
&& ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])
|
||||
) {
|
||||
// Here, we know trigger_error() has been called from __toString().
|
||||
// HHVM is fine with throwing from __toString() but PHP triggers a fatal error instead.
|
||||
// A small convention allows working around the limitation:
|
||||
// given a caught $e exception in __toString(), quitting the method with
|
||||
// `return trigger_error($e, E_USER_ERROR);` allows this error handler
|
||||
// to make $e get through the __toString() barrier.
|
||||
|
||||
foreach ($context as $e) {
|
||||
if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) {
|
||||
if (1 === $i) {
|
||||
// On HHVM
|
||||
$throw = $e;
|
||||
break;
|
||||
}
|
||||
self::$toStringException = $e;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 < $i) {
|
||||
// On PHP (not on HHVM), display the original error message instead of the default one.
|
||||
$this->handleException($throw);
|
||||
|
||||
// Stop the process by giving back the error to the native handler.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw $throw;
|
||||
}
|
||||
|
||||
|
|
|
@ -266,6 +266,33 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
}
|
||||
|
||||
public function testHandleUserError()
|
||||
{
|
||||
try {
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->throwAt(0, true);
|
||||
|
||||
$e = null;
|
||||
$x = new \Exception('Foo');
|
||||
|
||||
try {
|
||||
$f = new Fixtures\ToStringThrower($x);
|
||||
$f .= ''; // Trigger $f->__toString()
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
$this->assertSame($x, $e);
|
||||
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testHandleException()
|
||||
{
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Symfony\Component\Debug\Tests\Fixtures;
|
||||
|
||||
class ToStringThrower
|
||||
{
|
||||
private $exception;
|
||||
|
||||
public function __construct(\Exception $e)
|
||||
{
|
||||
$this->exception = $e;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
throw $this->exception;
|
||||
} catch (\Exception $e) {
|
||||
// Using user_error() here is on purpose so we do not forget
|
||||
// that this alias also should work alongside with trigger_error().
|
||||
return user_error($e, E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ CHANGELOG
|
|||
-----
|
||||
|
||||
* allowed specifying a directory to recursively load all configuration files it contains
|
||||
* deprecated the concept of scopes
|
||||
* added `Definition::setShared()` and `Definition::isShared()`
|
||||
|
||||
2.7.0
|
||||
-----
|
||||
|
|
|
@ -25,6 +25,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
|||
* - non synthetic, non abstract services always have a class set
|
||||
* - synthetic services are always public
|
||||
* - synthetic services are always of non-prototype scope
|
||||
* - shared services are always of non-prototype scope
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
|
@ -46,10 +47,15 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
|
|||
}
|
||||
|
||||
// synthetic service has non-prototype scope
|
||||
if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
|
||||
throw new RuntimeException(sprintf('A synthetic service ("%s") cannot be of scope "prototype".', $id));
|
||||
}
|
||||
|
||||
// shared service has non-prototype scope
|
||||
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
|
||||
throw new RuntimeException(sprintf('A shared service ("%s") cannot be of scope "prototype".', $id));
|
||||
}
|
||||
|
||||
// non-synthetic, non-abstract service has class
|
||||
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
|
||||
if ($definition->getFactory()) {
|
||||
|
|
|
@ -46,10 +46,10 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
{
|
||||
$this->container = $container;
|
||||
|
||||
$children = $this->container->getScopeChildren();
|
||||
$children = $this->container->getScopeChildren(false);
|
||||
$ancestors = array();
|
||||
|
||||
$scopes = $this->container->getScopes();
|
||||
$scopes = $this->container->getScopes(false);
|
||||
foreach ($scopes as $name => $parent) {
|
||||
$ancestors[$name] = array($parent);
|
||||
|
||||
|
@ -65,7 +65,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
|
||||
$this->currentId = $id;
|
||||
$this->currentDefinition = $definition;
|
||||
$this->currentScope = $scope = $definition->getScope();
|
||||
$this->currentScope = $scope = $definition->getScope(false);
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER === $scope) {
|
||||
$this->currentScopeChildren = array_keys($scopes);
|
||||
|
@ -125,7 +125,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$reference->isStrict()) {
|
||||
if (!$reference->isStrict(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
return;
|
||||
}
|
||||
|
||||
if ($this->currentScope === $scope = $definition->getScope()) {
|
||||
if ($this->currentScope === $scope = $definition->getScope(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,27 +48,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
$this->graph = $this->compiler->getServiceReferenceGraph();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$this->currentId = $id;
|
||||
|
||||
$definition->setArguments(
|
||||
$this->inlineArguments($container, $definition->getArguments())
|
||||
);
|
||||
|
||||
$definition->setMethodCalls(
|
||||
$this->inlineArguments($container, $definition->getMethodCalls())
|
||||
);
|
||||
|
||||
$definition->setProperties(
|
||||
$this->inlineArguments($container, $definition->getProperties())
|
||||
);
|
||||
|
||||
$configurator = $this->inlineArguments($container, array($definition->getConfigurator()));
|
||||
$definition->setConfigurator($configurator[0]);
|
||||
|
||||
$factory = $this->inlineArguments($container, array($definition->getFactory()));
|
||||
$definition->setFactory($factory[0]);
|
||||
}
|
||||
$container->setDefinitions($this->inlineArguments($container, $container->getDefinitions(), true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,12 +56,16 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param array $arguments An array of arguments
|
||||
* @param bool $isRoot If we are processing the root definitions or not
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function inlineArguments(ContainerBuilder $container, array $arguments)
|
||||
private function inlineArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if ($isRoot) {
|
||||
$this->currentId = $k;
|
||||
}
|
||||
if (is_array($argument)) {
|
||||
$arguments[$k] = $this->inlineArguments($container, $argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
|
@ -92,7 +76,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
||||
$this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
|
||||
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) {
|
||||
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false)) {
|
||||
$arguments[$k] = $definition;
|
||||
} else {
|
||||
$arguments[$k] = clone $definition;
|
||||
|
@ -102,6 +86,12 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
$argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
|
||||
$argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
|
||||
$argument->setProperties($this->inlineArguments($container, $argument->getProperties()));
|
||||
|
||||
$configurator = $this->inlineArguments($container, array($argument->getConfigurator()));
|
||||
$argument->setConfigurator($configurator[0]);
|
||||
|
||||
$factory = $this->inlineArguments($container, array($argument->getFactory()));
|
||||
$argument->setFactory($factory[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +109,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
*/
|
||||
private function isInlineableDefinition(ContainerBuilder $container, $id, Definition $definition)
|
||||
{
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
if (!$definition->isShared() || ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -148,6 +138,6 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
return $container->getDefinition(reset($ids))->getScope() === $definition->getScope();
|
||||
return $container->getDefinition(reset($ids))->getScope(false) === $definition->getScope(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,13 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
|||
* merged Definition instance.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
private $currentId;
|
||||
|
||||
/**
|
||||
* Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
|
||||
|
@ -35,44 +36,80 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
// yes, we are specifically fetching the definition from the
|
||||
// container to ensure we are not operating on stale data
|
||||
$definition = $container->getDefinition($id);
|
||||
if (!$definition instanceof DefinitionDecorator || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
$container->setDefinitions($this->resolveArguments($container, $container->getDefinitions(), true));
|
||||
}
|
||||
|
||||
$this->resolveDefinition($id, $definition);
|
||||
/**
|
||||
* Resolves definition decorator arguments.
|
||||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param array $arguments An array of arguments
|
||||
* @param bool $isRoot If we are processing the root definitions or not
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function resolveArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if ($isRoot) {
|
||||
// yes, we are specifically fetching the definition from the
|
||||
// container to ensure we are not operating on stale data
|
||||
$arguments[$k] = $argument = $container->getDefinition($k);
|
||||
$this->currentId = $k;
|
||||
}
|
||||
if (is_array($argument)) {
|
||||
$arguments[$k] = $this->resolveArguments($container, $argument);
|
||||
} elseif ($argument instanceof Definition) {
|
||||
if ($argument instanceof DefinitionDecorator) {
|
||||
$arguments[$k] = $argument = $this->resolveDefinition($container, $argument);
|
||||
if ($isRoot) {
|
||||
$container->setDefinition($k, $argument);
|
||||
}
|
||||
}
|
||||
$argument->setArguments($this->resolveArguments($container, $argument->getArguments()));
|
||||
$argument->setMethodCalls($this->resolveArguments($container, $argument->getMethodCalls()));
|
||||
$argument->setProperties($this->resolveArguments($container, $argument->getProperties()));
|
||||
|
||||
$configurator = $this->resolveArguments($container, array($argument->getConfigurator()));
|
||||
$argument->setConfigurator($configurator[0]);
|
||||
|
||||
$factory = $this->resolveArguments($container, array($argument->getFactory()));
|
||||
$argument->setFactory($factory[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the definition.
|
||||
*
|
||||
* @param string $id The definition identifier
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param DefinitionDecorator $definition
|
||||
*
|
||||
* @return Definition
|
||||
*
|
||||
* @throws \RuntimeException When the definition is invalid
|
||||
*/
|
||||
private function resolveDefinition($id, DefinitionDecorator $definition)
|
||||
private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
|
||||
{
|
||||
if (!$this->container->hasDefinition($parent = $definition->getParent())) {
|
||||
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $id));
|
||||
if (!$container->hasDefinition($parent = $definition->getParent())) {
|
||||
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $this->currentId));
|
||||
}
|
||||
|
||||
$parentDef = $this->container->getDefinition($parent);
|
||||
$parentDef = $container->getDefinition($parent);
|
||||
if ($parentDef instanceof DefinitionDecorator) {
|
||||
$parentDef = $this->resolveDefinition($parent, $parentDef);
|
||||
$id = $this->currentId;
|
||||
$this->currentId = $parent;
|
||||
$parentDef = $this->resolveDefinition($container, $parentDef);
|
||||
$container->setDefinition($parent, $parentDef);
|
||||
$this->currentId = $id;
|
||||
}
|
||||
|
||||
$this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $id, $parent));
|
||||
$this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $this->currentId, $parent));
|
||||
$def = new Definition();
|
||||
|
||||
// merge in parent definition
|
||||
|
@ -107,6 +144,14 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
if (isset($changes['lazy'])) {
|
||||
$def->setLazy($definition->isLazy());
|
||||
}
|
||||
if (isset($changes['decorated_service'])) {
|
||||
$decoratedService = $definition->getDecoratedService();
|
||||
if (null === $decoratedService) {
|
||||
$def->setDecoratedService($decoratedService);
|
||||
} else {
|
||||
$def->setDecoratedService($decoratedService[0], $decoratedService[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// merge arguments
|
||||
foreach ($definition->getArguments() as $k => $v) {
|
||||
|
@ -135,12 +180,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
|
||||
// these attributes are always taken from the child
|
||||
$def->setAbstract($definition->isAbstract());
|
||||
$def->setScope($definition->getScope());
|
||||
$def->setScope($definition->getScope(false), false);
|
||||
$def->setTags($definition->getTags());
|
||||
|
||||
// set new definition on container
|
||||
$this->container->setDefinition($id, $def);
|
||||
|
||||
return $def;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
|||
$defId = $this->getDefinitionId($id = (string) $argument);
|
||||
|
||||
if ($defId !== $id) {
|
||||
$arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict());
|
||||
$arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,6 +180,8 @@ class Container implements IntrospectableContainerInterface
|
|||
* Setting a service to null resets the service: has() returns false and get()
|
||||
* behaves in the same way as if the service was never created.
|
||||
*
|
||||
* Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope of the service
|
||||
|
@ -191,6 +193,10 @@ class Container implements IntrospectableContainerInterface
|
|||
*/
|
||||
public function set($id, $service, $scope = self::SCOPE_CONTAINER)
|
||||
{
|
||||
if (!in_array($scope, array('container', 'request')) || ('request' === $scope && 'request' !== $id)) {
|
||||
@trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (self::SCOPE_PROTOTYPE === $scope) {
|
||||
throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id));
|
||||
}
|
||||
|
@ -389,9 +395,15 @@ class Container implements IntrospectableContainerInterface
|
|||
* @throws InvalidArgumentException When the scope does not exist
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function enterScope($name)
|
||||
{
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!isset($this->scopes[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name));
|
||||
}
|
||||
|
@ -437,9 +449,15 @@ class Container implements IntrospectableContainerInterface
|
|||
* @throws InvalidArgumentException if the scope is not active
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function leaveScope($name)
|
||||
{
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!isset($this->scopedServices[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
|
||||
}
|
||||
|
@ -484,12 +502,17 @@ class Container implements IntrospectableContainerInterface
|
|||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function addScope(ScopeInterface $scope)
|
||||
{
|
||||
$name = $scope->getName();
|
||||
$parentScope = $scope->getParentName();
|
||||
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
|
||||
}
|
||||
|
@ -518,9 +541,15 @@ class Container implements IntrospectableContainerInterface
|
|||
* @return bool
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function hasScope($name)
|
||||
{
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return isset($this->scopes[$name]);
|
||||
}
|
||||
|
||||
|
@ -534,9 +563,13 @@ class Container implements IntrospectableContainerInterface
|
|||
* @return bool
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function isScopeActive($name)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
return isset($this->scopedServices[$name]);
|
||||
}
|
||||
|
||||
|
|
|
@ -358,9 +358,15 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
* @return array An array of scopes
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function getScopes()
|
||||
public function getScopes($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->scopes;
|
||||
}
|
||||
|
||||
|
@ -370,15 +376,23 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
* @return array An array of scope children.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function getScopeChildren()
|
||||
public function getScopeChildren($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->scopeChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
* Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope
|
||||
|
@ -1126,7 +1140,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||
*/
|
||||
private function shareService(Definition $definition, $service, $id)
|
||||
{
|
||||
if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
if ($definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
|
||||
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
|
||||
throw new InactiveScopeException($id, $scope);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ interface ContainerInterface
|
|||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
* Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope of the service
|
||||
|
@ -110,6 +112,8 @@ interface ContainerInterface
|
|||
* @param string $name
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function enterScope($name);
|
||||
|
||||
|
@ -119,6 +123,8 @@ interface ContainerInterface
|
|||
* @param string $name
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function leaveScope($name);
|
||||
|
||||
|
@ -128,6 +134,8 @@ interface ContainerInterface
|
|||
* @param ScopeInterface $scope
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function addScope(ScopeInterface $scope);
|
||||
|
||||
|
@ -139,6 +147,8 @@ interface ContainerInterface
|
|||
* @return bool
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function hasScope($name);
|
||||
|
||||
|
@ -152,6 +162,8 @@ interface ContainerInterface
|
|||
* @return bool
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function isScopeActive($name);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class Definition
|
|||
private $class;
|
||||
private $file;
|
||||
private $factory;
|
||||
private $shared = true;
|
||||
private $scope = ContainerInterface::SCOPE_CONTAINER;
|
||||
private $properties = array();
|
||||
private $calls = array();
|
||||
|
@ -484,6 +485,34 @@ class Definition
|
|||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the service must be shared or not.
|
||||
*
|
||||
* @param bool $shared Whether the service must be shared or not
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setShared($shared)
|
||||
{
|
||||
$this->shared = (bool) $shared;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this service is shared.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isShared()
|
||||
{
|
||||
return $this->shared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scope of the service.
|
||||
*
|
||||
|
@ -492,9 +521,19 @@ class Definition
|
|||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function setScope($scope)
|
||||
public function setScope($scope, $triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $scope) {
|
||||
$this->setShared(false);
|
||||
}
|
||||
|
||||
$this->scope = $scope;
|
||||
|
||||
return $this;
|
||||
|
@ -506,9 +545,15 @@ class Definition
|
|||
* @return string
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function getScope()
|
||||
public function getScope($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,16 @@ class DefinitionDecorator extends Definition
|
|||
return parent::setLazy($boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDecoratedService($id, $renamedId = null)
|
||||
{
|
||||
$this->changes['decorated_service'] = true;
|
||||
|
||||
return parent::setDecoratedService($id, $renamedId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
|
|
|
@ -173,7 +173,7 @@ class GraphvizDumper extends Dumper
|
|||
} catch (ParameterNotFoundException $e) {
|
||||
}
|
||||
|
||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $className), 'attributes' => array_merge($this->options['node.definition'], array('style' => ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope() ? 'filled' : 'dotted')));
|
||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $className), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false) ? 'filled' : 'dotted')));
|
||||
$container->setDefinition($id, new Definition('stdClass'));
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ class GraphvizDumper extends Dumper
|
|||
$container->setDefinitions($this->container->getDefinitions());
|
||||
$container->setAliases($this->container->getAliases());
|
||||
$container->setResources($this->container->getResources());
|
||||
foreach ($this->container->getScopes() as $scope => $parentScope) {
|
||||
foreach ($this->container->getScopes(false) as $scope => $parentScope) {
|
||||
$container->addScope(new Scope($scope, $parentScope));
|
||||
}
|
||||
foreach ($this->container->getExtensions() as $extension) {
|
||||
|
|
|
@ -377,9 +377,9 @@ class PhpDumper extends Dumper
|
|||
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
|
||||
$instantiation = '';
|
||||
|
||||
if (!$isProxyCandidate && ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
|
||||
if (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) {
|
||||
$instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance');
|
||||
} elseif (!$isProxyCandidate && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
} elseif (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
|
||||
$instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance');
|
||||
} elseif (!$simple) {
|
||||
$instantiation = '$instance';
|
||||
|
@ -569,7 +569,7 @@ class PhpDumper extends Dumper
|
|||
}
|
||||
}
|
||||
|
||||
$scope = $definition->getScope();
|
||||
$scope = $definition->getScope(false);
|
||||
if (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) {
|
||||
if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
|
||||
$return[] = '';
|
||||
|
@ -580,7 +580,7 @@ class PhpDumper extends Dumper
|
|||
$return = implode("\n * ", $return);
|
||||
|
||||
$doc = '';
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
|
||||
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
|
||||
$doc .= <<<EOF
|
||||
|
||||
*
|
||||
|
@ -832,10 +832,10 @@ EOF;
|
|||
|
||||
EOF;
|
||||
|
||||
if (count($scopes = $this->container->getScopes()) > 0) {
|
||||
if (count($scopes = $this->container->getScopes(false)) > 0) {
|
||||
$code .= "\n";
|
||||
$code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n";
|
||||
$code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n";
|
||||
$code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren(false)).";\n";
|
||||
}
|
||||
|
||||
$code .= $this->addMethodMap();
|
||||
|
@ -879,9 +879,9 @@ EOF;
|
|||
EOF;
|
||||
|
||||
$code .= "\n";
|
||||
if (count($scopes = $this->container->getScopes()) > 0) {
|
||||
if (count($scopes = $this->container->getScopes(false)) > 0) {
|
||||
$code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n";
|
||||
$code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n";
|
||||
$code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren(false)).";\n";
|
||||
} else {
|
||||
$code .= " \$this->scopes = array();\n";
|
||||
$code .= " \$this->scopeChildren = array();\n";
|
||||
|
@ -1273,11 +1273,6 @@ EOF;
|
|||
foreach ($value->getArguments() as $argument) {
|
||||
$arguments[] = $this->dumpValue($argument);
|
||||
}
|
||||
$class = $this->dumpValue($value->getClass());
|
||||
|
||||
if (false !== strpos($class, '$')) {
|
||||
throw new RuntimeException('Cannot dump definitions which have a variable class name.');
|
||||
}
|
||||
|
||||
if (null !== $value->getFactory()) {
|
||||
$factory = $value->getFactory();
|
||||
|
@ -1303,7 +1298,16 @@ EOF;
|
|||
throw new RuntimeException('Cannot dump definition because of invalid factory');
|
||||
}
|
||||
|
||||
return sprintf("new \\%s(%s)", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
|
||||
$class = $value->getClass();
|
||||
if (null === $class) {
|
||||
throw new RuntimeException('Cannot dump definitions which have no class nor factory.');
|
||||
}
|
||||
$class = $this->dumpValue($class);
|
||||
if (false !== strpos($class, '$')) {
|
||||
throw new RuntimeException('Cannot dump definitions which have a variable class name.');
|
||||
}
|
||||
|
||||
return sprintf('new \\%s(%s)', substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
|
||||
} elseif ($value instanceof Variable) {
|
||||
return '$'.$value;
|
||||
} elseif ($value instanceof Reference) {
|
||||
|
|
|
@ -117,7 +117,10 @@ class XmlDumper extends Dumper
|
|||
if ($definition->getClass()) {
|
||||
$service->setAttribute('class', $definition->getClass());
|
||||
}
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
|
||||
if (!$definition->isShared()) {
|
||||
$service->setAttribute('shared', 'false');
|
||||
}
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
|
||||
$service->setAttribute('scope', $scope);
|
||||
}
|
||||
if (!$definition->isPublic()) {
|
||||
|
@ -271,7 +274,7 @@ class XmlDumper extends Dumper
|
|||
} elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
|
||||
$element->setAttribute('on-invalid', 'ignore');
|
||||
}
|
||||
if (!$value->isStrict()) {
|
||||
if (!$value->isStrict(false)) {
|
||||
$element->setAttribute('strict', 'false');
|
||||
}
|
||||
} elseif ($value instanceof Definition) {
|
||||
|
|
|
@ -112,7 +112,11 @@ class YamlDumper extends Dumper
|
|||
$code .= sprintf(" calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12));
|
||||
}
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
|
||||
if (!$definition->isShared()) {
|
||||
$code .= " shared: false\n";
|
||||
}
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
|
||||
$code .= sprintf(" scope: %s\n", $scope);
|
||||
}
|
||||
|
||||
|
@ -196,7 +200,7 @@ class YamlDumper extends Dumper
|
|||
}
|
||||
|
||||
/**
|
||||
* Dumps callable to YAML format
|
||||
* Dumps callable to YAML format.
|
||||
*
|
||||
* @param callable $callable
|
||||
*
|
||||
|
|
|
@ -148,11 +148,8 @@ class XmlFileLoader extends FileLoader
|
|||
$definition = new Definition();
|
||||
}
|
||||
|
||||
foreach (array('class', 'scope', 'public', 'synthetic', 'lazy', 'abstract') as $key) {
|
||||
foreach (array('class', 'shared', 'public', 'synthetic', 'lazy', 'abstract') as $key) {
|
||||
if ($value = $service->getAttribute($key)) {
|
||||
if (in_array($key, array('factory-class', 'factory-method', 'factory-service'))) {
|
||||
@trigger_error(sprintf('The "%s" attribute in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use the "factory" element instead.', $key, $file), E_USER_DEPRECATED);
|
||||
}
|
||||
$method = 'set'.str_replace('-', '', $key);
|
||||
$definition->$method(XmlUtils::phpize($value));
|
||||
}
|
||||
|
|
|
@ -163,8 +163,15 @@ class YamlFileLoader extends FileLoader
|
|||
$definition->setClass($service['class']);
|
||||
}
|
||||
|
||||
if (isset($service['shared'])) {
|
||||
$definition->setShared($service['shared']);
|
||||
}
|
||||
|
||||
if (isset($service['scope'])) {
|
||||
$definition->setScope($service['scope']);
|
||||
if ('request' !== $id) {
|
||||
@trigger_error(sprintf('The "scope" key of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED);
|
||||
}
|
||||
$definition->setScope($service['scope'], false);
|
||||
}
|
||||
|
||||
if (isset($service['synthetic'])) {
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
</xsd:choice>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="class" type="xsd:string" />
|
||||
<xsd:attribute name="shared" type="boolean" />
|
||||
<xsd:attribute name="scope" type="xsd:string" />
|
||||
<xsd:attribute name="public" type="boolean" />
|
||||
<xsd:attribute name="synthetic" type="boolean" />
|
||||
|
|
|
@ -27,6 +27,8 @@ class Reference
|
|||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Note: The $strict parameter is deprecated since version 2.8 and will be removed in 3.0.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param int $invalidBehavior The behavior when the service does not exist
|
||||
* @param bool $strict Sets how this reference is validated
|
||||
|
@ -64,9 +66,15 @@ class Reference
|
|||
* Returns true when this Reference is strict.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function isStrict()
|
||||
public function isStrict($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->strict;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace Symfony\Component\DependencyInjection;
|
|||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
class Scope implements ScopeInterface
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace Symfony\Component\DependencyInjection;
|
|||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
interface ScopeInterface
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessDetectsSyntheticPrototypeDefinitions()
|
||||
{
|
||||
|
@ -39,6 +40,18 @@ class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessDetectsSharedPrototypeDefinitions()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('a')->setShared(true)->setScope(ContainerInterface::SCOPE_PROTOTYPE);
|
||||
|
||||
$this->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
*/
|
||||
|
|
|
@ -19,6 +19,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|||
|
||||
class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessIgnoresScopeWideningIfNonStrictReference()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -30,6 +33,7 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessDetectsScopeWidening()
|
||||
{
|
||||
|
@ -40,6 +44,9 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessIgnoresCrossScopeHierarchyReferenceIfNotStrict()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -54,6 +61,7 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessDetectsCrossScopeHierarchyReference()
|
||||
{
|
||||
|
|
|
@ -41,6 +41,29 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]);
|
||||
}
|
||||
|
||||
public function testProcessDoesNotInlinesWhenAliasedServiceIsShared()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('foo')
|
||||
->setPublic(false)
|
||||
;
|
||||
$container->setAlias('moo', 'foo');
|
||||
|
||||
$container
|
||||
->register('service')
|
||||
->setArguments(array($ref = new Reference('foo')))
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$arguments = $container->getDefinition('service')->getArguments();
|
||||
$this->assertSame($ref, $arguments[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessDoesNotInlineWhenAliasedServiceIsNotOfPrototypeScope()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -61,6 +84,38 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame($ref, $arguments[0]);
|
||||
}
|
||||
|
||||
public function testProcessDoesInlineNonSharedService()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container
|
||||
->register('foo')
|
||||
->setShared(false)
|
||||
;
|
||||
$container
|
||||
->register('bar')
|
||||
->setPublic(false)
|
||||
->setShared(false)
|
||||
;
|
||||
$container->setAlias('moo', 'bar');
|
||||
|
||||
$container
|
||||
->register('service')
|
||||
->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$arguments = $container->getDefinition('service')->getArguments();
|
||||
$this->assertEquals($container->getDefinition('foo'), $arguments[0]);
|
||||
$this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
|
||||
$this->assertSame($ref, $arguments[1]);
|
||||
$this->assertEquals($container->getDefinition('bar'), $arguments[2]);
|
||||
$this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessDoesInlineServiceOfPrototypeScope()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -188,6 +243,9 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame($ref, $args[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessInlinesOnlyIfSameScope()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
|
|
@ -79,6 +79,9 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse($def->isAbstract());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testProcessDoesNotCopyScope()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -117,6 +120,25 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(array(), $def->getTags());
|
||||
}
|
||||
|
||||
public function testProcessDoesNotCopyDecoratedService()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container
|
||||
->register('parent')
|
||||
->setDecoratedService('foo')
|
||||
;
|
||||
|
||||
$container
|
||||
->setDefinition('child', new DefinitionDecorator('parent'))
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$def = $container->getDefinition('child');
|
||||
$this->assertNull($def->getDecoratedService());
|
||||
}
|
||||
|
||||
public function testProcessHandlesMultipleInheritance()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -173,6 +195,55 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($container->getDefinition('child1')->isLazy());
|
||||
}
|
||||
|
||||
public function testDeepDefinitionsResolving()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('parent', 'parentClass');
|
||||
$container->register('sibling', 'siblingClass')
|
||||
->setConfigurator(new DefinitionDecorator('parent'), 'foo')
|
||||
->setFactory(array(new DefinitionDecorator('parent'), 'foo'))
|
||||
->addArgument(new DefinitionDecorator('parent'))
|
||||
->setProperty('prop', new DefinitionDecorator('parent'))
|
||||
->addMethodCall('meth', array(new DefinitionDecorator('parent')))
|
||||
;
|
||||
|
||||
$this->process($container);
|
||||
|
||||
$configurator = $container->getDefinition('sibling')->getConfigurator();
|
||||
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($configurator));
|
||||
$this->assertSame('parentClass', $configurator->getClass());
|
||||
|
||||
$factory = $container->getDefinition('sibling')->getFactory();
|
||||
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($factory[0]));
|
||||
$this->assertSame('parentClass', $factory[0]->getClass());
|
||||
|
||||
$argument = $container->getDefinition('sibling')->getArgument(0);
|
||||
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($argument));
|
||||
$this->assertSame('parentClass', $argument->getClass());
|
||||
|
||||
$properties = $container->getDefinition('sibling')->getProperties();
|
||||
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($properties['prop']));
|
||||
$this->assertSame('parentClass', $properties['prop']->getClass());
|
||||
|
||||
$methodCalls = $container->getDefinition('sibling')->getMethodCalls();
|
||||
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($methodCalls[0][1][0]));
|
||||
$this->assertSame('parentClass', $methodCalls[0][1][0]->getClass());
|
||||
}
|
||||
|
||||
public function testSetDecoratedServiceOnServiceHasParent()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('parent', 'stdClass');
|
||||
|
||||
$container->setDefinition('child1', new DefinitionDecorator('parent'))
|
||||
->setDecoratedService('foo', 'foo_inner')
|
||||
;
|
||||
|
||||
$this->assertEquals(array('foo', 'foo_inner'), $container->getDefinition('child1')->getDecoratedService());
|
||||
}
|
||||
|
||||
protected function process(ContainerBuilder $container)
|
||||
{
|
||||
$pass = new ResolveDefinitionTemplatesPass();
|
||||
|
|
|
@ -61,6 +61,9 @@ class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals(array(), $def->getProperties());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testStrictFlagIsPreserved()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
|
|
@ -117,10 +117,21 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('Circular reference detected for service "baz", path: "baz".', $e->getMessage(), '->get() throws a LogicException if the service has a circular reference to itself');
|
||||
}
|
||||
|
||||
$builder->register('foobar', 'stdClass')->setScope('container');
|
||||
$this->assertTrue($builder->get('bar') === $builder->get('bar'), '->get() always returns the same instance if the service is shared');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::setShared
|
||||
*/
|
||||
public function testNonSharedServicesReturnsDifferentInstances()
|
||||
{
|
||||
$builder = new ContainerBuilder();
|
||||
$builder->register('bar', 'stdClass')->setShared(false);
|
||||
|
||||
$this->assertNotSame($builder->get('bar'), $builder->get('bar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Symfony\Component\DependencyInjection\ContainerBuilder::get
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
|
@ -143,6 +154,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGetReturnsNullOnInactiveScope()
|
||||
{
|
||||
|
@ -154,6 +166,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGetReturnsNullOnInactiveScopeWhenServiceIsCreatedByAMethod()
|
||||
{
|
||||
|
|
|
@ -171,6 +171,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testSetDoesNotAllowPrototypeScope()
|
||||
{
|
||||
|
@ -180,6 +181,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testSetDoesNotAllowInactiveScope()
|
||||
{
|
||||
|
@ -188,6 +190,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$c->set('foo', new \stdClass(), 'foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testSetAlsoSetsScopedService()
|
||||
{
|
||||
$c = new Container();
|
||||
|
@ -264,6 +269,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @covers Symfony\Component\DependencyInjection\Container::get
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGetReturnsNullOnInactiveScope()
|
||||
{
|
||||
|
@ -302,6 +308,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($sc->initialized('alias'), '->initialized() returns true for alias if aliased service is initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testEnterLeaveCurrentScope()
|
||||
{
|
||||
$container = new ProjectServiceContainer();
|
||||
|
@ -327,6 +336,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame($scopedFoo1, $scopedFoo3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testEnterLeaveScopeWithChildScopes()
|
||||
{
|
||||
$container = new Container();
|
||||
|
@ -357,6 +369,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse($container->has('a'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testEnterScopeRecursivelyWithInactiveChildScopes()
|
||||
{
|
||||
$container = new Container();
|
||||
|
@ -398,6 +413,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($container->has('a'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testEnterChildScopeRecursively()
|
||||
{
|
||||
$container = new Container();
|
||||
|
@ -435,6 +453,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testEnterScopeNotAdded()
|
||||
{
|
||||
|
@ -444,6 +463,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testEnterScopeDoesNotAllowInactiveParentScope()
|
||||
{
|
||||
|
@ -453,6 +473,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$container->enterScope('bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testLeaveScopeNotActive()
|
||||
{
|
||||
$container = new Container();
|
||||
|
@ -477,7 +500,8 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @dataProvider getBuiltInScopes
|
||||
* @dataProvider getLegacyBuiltInScopes
|
||||
* @group legacy
|
||||
*/
|
||||
public function testAddScopeDoesNotAllowBuiltInScopes($scope)
|
||||
{
|
||||
|
@ -487,6 +511,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testAddScopeDoesNotAllowExistingScope()
|
||||
{
|
||||
|
@ -497,7 +522,8 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @dataProvider getInvalidParentScopes
|
||||
* @dataProvider getLegacyInvalidParentScopes
|
||||
* @group legacy
|
||||
*/
|
||||
public function testAddScopeDoesNotAllowInvalidParentScope($scope)
|
||||
{
|
||||
|
@ -505,6 +531,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$c->addScope(new Scope('foo', $scope));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testAddScope()
|
||||
{
|
||||
$c = new Container();
|
||||
|
@ -520,6 +549,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame(array('foo' => array('bar', 'baz'), 'bar' => array('baz'), 'baz' => array()), $this->getField($c, 'scopeChildren'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testHasScope()
|
||||
{
|
||||
$c = new Container();
|
||||
|
@ -568,6 +600,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testIsScopeActive()
|
||||
{
|
||||
$c = new Container();
|
||||
|
@ -584,7 +619,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse($c->isScopeActive('foo'));
|
||||
}
|
||||
|
||||
public function getInvalidParentScopes()
|
||||
public function getLegacyInvalidParentScopes()
|
||||
{
|
||||
return array(
|
||||
array(ContainerInterface::SCOPE_PROTOTYPE),
|
||||
|
@ -592,7 +627,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||
);
|
||||
}
|
||||
|
||||
public function getBuiltInScopes()
|
||||
public function getLegacyBuiltInScopes()
|
||||
{
|
||||
return array(
|
||||
array(ContainerInterface::SCOPE_CONTAINER),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue