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
|
- php: hhvm
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- php: nightly
|
- php: nightly
|
||||||
- php: hhvm
|
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
services: mongodb
|
services: mongodb
|
||||||
|
|
|
@ -50,30 +50,7 @@ class DbalLogger implements SQLLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($params)) {
|
if (is_array($params)) {
|
||||||
foreach ($params as $index => $param) {
|
$params = $this->normalizeParams($params);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
|
@ -101,4 +78,40 @@ class DbalLogger implements SQLLogger
|
||||||
{
|
{
|
||||||
$this->logger->debug($message, $params);
|
$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()
|
public function testLogLongString()
|
||||||
{
|
{
|
||||||
$logger = $this->getMock('Psr\\Log\\LoggerInterface');
|
$logger = $this->getMock('Psr\\Log\\LoggerInterface');
|
||||||
|
|
|
@ -82,7 +82,7 @@ class UniqueEntityValidator extends ConstraintValidator
|
||||||
$criteria = array();
|
$criteria = array();
|
||||||
foreach ($fields as $fieldName) {
|
foreach ($fields as $fieldName) {
|
||||||
if (!$class->hasField($fieldName) && !$class->hasAssociation($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);
|
$criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity);
|
||||||
|
|
|
@ -21,10 +21,10 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
*/
|
*/
|
||||||
class WebProcessor extends BaseWebProcessor
|
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
|
// Pass an empty array as the default null value would access $_SERVER
|
||||||
parent::__construct(array());
|
parent::__construct(array(), $extraFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onKernelRequest(GetResponseEvent $event)
|
public function onKernelRequest(GetResponseEvent $event)
|
||||||
|
|
|
@ -18,6 +18,42 @@ use Symfony\Component\HttpFoundation\Request;
|
||||||
class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testUsesRequestServerData()
|
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(
|
$server = array(
|
||||||
'REQUEST_URI' => 'A',
|
'REQUEST_URI' => 'A',
|
||||||
|
@ -40,15 +76,7 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
||||||
->method('getRequest')
|
->method('getRequest')
|
||||||
->will($this->returnValue($request));
|
->will($this->returnValue($request));
|
||||||
|
|
||||||
$processor = new WebProcessor();
|
return array($event, $server);
|
||||||
$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']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +85,7 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
||||||
*
|
*
|
||||||
* @return array Record
|
* @return array Record
|
||||||
*/
|
*/
|
||||||
protected function getRecord($level = Logger::WARNING, $message = 'test')
|
private function getRecord($level = Logger::WARNING, $message = 'test')
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'message' => $message,
|
'message' => $message,
|
||||||
|
@ -69,4 +97,17 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
|
||||||
'extra' => array(),
|
'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:
|
It comes with the following features:
|
||||||
|
|
||||||
* disable the garbage collector;
|
* disable the garbage collector;
|
||||||
|
* enforce a consistent `C` locale;
|
||||||
* auto-register `class_exists` to load Doctrine annotations;
|
* auto-register `class_exists` to load Doctrine annotations;
|
||||||
* print a user deprecation notices summary at the end of the test suite.
|
* 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
|
// https://bugs.php.net/bug.php?id=53976
|
||||||
gc_disable();
|
gc_disable();
|
||||||
|
|
||||||
|
// Enforce a consistent locale
|
||||||
|
setlocale(LC_ALL, 'C');
|
||||||
|
|
||||||
if (class_exists('Doctrine\Common\Annotations\AnnotationRegistry')) {
|
if (class_exists('Doctrine\Common\Annotations\AnnotationRegistry')) {
|
||||||
AnnotationRegistry::registerLoader('class_exists');
|
AnnotationRegistry::registerLoader('class_exists');
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,9 +68,9 @@ class ProxyDumper implements DumperInterface
|
||||||
{
|
{
|
||||||
$instantiation = 'return';
|
$instantiation = 'return';
|
||||||
|
|
||||||
if (ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
|
if ($definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) {
|
||||||
$instantiation .= " \$this->services['$id'] =";
|
$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'] =";
|
$instantiation .= " \$this->services['$id'] = \$this->scopedServices['$scope']['$id'] =";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@
|
||||||
{%- for child in form %}
|
{%- for child in form %}
|
||||||
{{- form_widget(child, {
|
{{- form_widget(child, {
|
||||||
parent_label_class: label_attr.class|default(''),
|
parent_label_class: label_attr.class|default(''),
|
||||||
|
translation_domain: choice_translation_domain,
|
||||||
}) -}}
|
}) -}}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
</div>
|
</div>
|
||||||
|
@ -106,6 +107,7 @@
|
||||||
{%- for child in form %}
|
{%- for child in form %}
|
||||||
{{- form_widget(child, {
|
{{- form_widget(child, {
|
||||||
parent_label_class: label_attr.class|default(''),
|
parent_label_class: label_attr.class|default(''),
|
||||||
|
translation_domain: choice_translation_domain,
|
||||||
}) -}}
|
}) -}}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
</div>
|
</div>
|
||||||
|
@ -156,7 +158,7 @@
|
||||||
{%- endblock radio_label %}
|
{%- endblock radio_label %}
|
||||||
|
|
||||||
{% block checkbox_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 widget is defined %}
|
||||||
{% if required %}
|
{% if required %}
|
||||||
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
|
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
|
||||||
|
@ -169,7 +171,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
||||||
{{- widget|raw -}}
|
{{- 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>
|
</label>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock checkbox_radio_label %}
|
{% endblock checkbox_radio_label %}
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
<div {{ block('widget_container_attributes') }}>
|
<div {{ block('widget_container_attributes') }}>
|
||||||
{%- for child in form %}
|
{%- for child in form %}
|
||||||
{{- form_widget(child) -}}
|
{{- form_widget(child) -}}
|
||||||
{{- form_label(child) -}}
|
{{- form_label(child, null, {translation_domain: choice_translation_domain}) -}}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
</div>
|
</div>
|
||||||
{%- endblock choice_widget_expanded -%}
|
{%- endblock choice_widget_expanded -%}
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
|
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
|
||||||
{%- if placeholder is not none -%}
|
{%- 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 -%}
|
{%- endif -%}
|
||||||
{%- if preferred_choices|length > 0 -%}
|
{%- if preferred_choices|length > 0 -%}
|
||||||
{% set options = preferred_choices %}
|
{% set options = preferred_choices %}
|
||||||
|
@ -225,7 +225,7 @@
|
||||||
{% set label = name|humanize %}
|
{% set label = name|humanize %}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- 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 -%}
|
{%- endif -%}
|
||||||
{%- endblock form_label -%}
|
{%- endblock form_label -%}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ class ServerStartCommand extends ServerCommand
|
||||||
new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'),
|
new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'),
|
||||||
new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root', null),
|
new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root', null),
|
||||||
new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'),
|
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')
|
->setName('server:start')
|
||||||
->setDescription('Starts PHP built-in web server in the background')
|
->setDescription('Starts PHP built-in web server in the background')
|
||||||
|
@ -110,8 +111,9 @@ EOF
|
||||||
$address = $address.':'.$input->getOption('port');
|
$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>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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,106 +100,103 @@ EOF
|
||||||
$kernel = $this->getContainer()->get('kernel');
|
$kernel = $this->getContainer()->get('kernel');
|
||||||
|
|
||||||
// Define Root Path to App folder
|
// Define Root Path to App folder
|
||||||
$rootPaths = array($kernel->getRootDir());
|
$transPaths = array($kernel->getRootDir().'/Resources/');
|
||||||
|
|
||||||
// Override with provided Bundle info
|
// Override with provided Bundle info
|
||||||
if (null !== $input->getArgument('bundle')) {
|
if (null !== $input->getArgument('bundle')) {
|
||||||
try {
|
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) {
|
} catch (\InvalidArgumentException $e) {
|
||||||
// such a bundle does not exist, so treat the argument as path
|
// 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])) {
|
if (!is_dir($transPaths[0])) {
|
||||||
throw new \InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.</error>', $rootPaths[0]));
|
throw new \InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif ($input->getOption('all')) {
|
} elseif ($input->getOption('all')) {
|
||||||
foreach ($kernel->getBundles() as $bundle) {
|
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) {
|
// Extract used messages
|
||||||
// get bundle directory
|
$extractedCatalogue = $this->extractMessages($locale, $transPaths);
|
||||||
$translationsPath = $rootPath.'/Resources/translations';
|
|
||||||
|
|
||||||
$output->writeln(sprintf('Translations in <info>%s</info>', $translationsPath));
|
// Load defined messages
|
||||||
|
$currentCatalogue = $this->loadCurrentMessages($locale, $transPaths, $loader);
|
||||||
|
|
||||||
// Extract used messages
|
// Merge defined and extracted messages to get all message ids
|
||||||
$extractedCatalogue = $this->extractMessages($locale, $rootPath);
|
$mergeOperation = new MergeOperation($extractedCatalogue, $currentCatalogue);
|
||||||
|
$allMessages = $mergeOperation->getResult()->all($domain);
|
||||||
|
if (null !== $domain) {
|
||||||
|
$allMessages = array($domain => $allMessages);
|
||||||
|
}
|
||||||
|
|
||||||
// Load defined messages
|
// No defined or extracted messages
|
||||||
$currentCatalogue = $this->loadCurrentMessages($locale, $translationsPath, $loader);
|
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) {
|
if (null !== $domain) {
|
||||||
$allMessages = array($domain => $allMessages);
|
$outputMessage .= sprintf(' and domain "%s"', $domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No defined or extracted messages
|
$output->warning($outputMessage);
|
||||||
if (empty($allMessages) || null !== $domain && empty($allMessages[$domain])) {
|
|
||||||
$outputMessage = sprintf('<info>No defined or extracted messages for locale "%s"</info>', $locale);
|
|
||||||
|
|
||||||
if (null !== $domain) {
|
return;
|
||||||
$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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
private function formatState($state)
|
||||||
|
@ -251,15 +248,18 @@ EOF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $locale
|
* @param string $locale
|
||||||
* @param string $rootPath
|
* @param array $transPaths
|
||||||
*
|
*
|
||||||
* @return MessageCatalogue
|
* @return MessageCatalogue
|
||||||
*/
|
*/
|
||||||
private function extractMessages($locale, $rootPath)
|
private function extractMessages($locale, $transPaths)
|
||||||
{
|
{
|
||||||
$extractedCatalogue = new MessageCatalogue($locale);
|
$extractedCatalogue = new MessageCatalogue($locale);
|
||||||
if (is_dir($rootPath.'/Resources/views')) {
|
foreach ($transPaths as $path) {
|
||||||
$this->getContainer()->get('translation.extractor')->extract($rootPath.'/Resources/views', $extractedCatalogue);
|
$path = $path.'views';
|
||||||
|
if (is_dir($path)) {
|
||||||
|
$this->getContainer()->get('translation.extractor')->extract($path, $extractedCatalogue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $extractedCatalogue;
|
return $extractedCatalogue;
|
||||||
|
@ -267,16 +267,19 @@ EOF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $locale
|
* @param string $locale
|
||||||
* @param string $translationsPath
|
* @param array $transPaths
|
||||||
* @param TranslationLoader $loader
|
* @param TranslationLoader $loader
|
||||||
*
|
*
|
||||||
* @return MessageCatalogue
|
* @return MessageCatalogue
|
||||||
*/
|
*/
|
||||||
private function loadCurrentMessages($locale, $translationsPath, TranslationLoader $loader)
|
private function loadCurrentMessages($locale, $transPaths, TranslationLoader $loader)
|
||||||
{
|
{
|
||||||
$currentCatalogue = new MessageCatalogue($locale);
|
$currentCatalogue = new MessageCatalogue($locale);
|
||||||
if (is_dir($translationsPath)) {
|
foreach ($transPaths as $path) {
|
||||||
$loader->loadMessages($translationsPath, $currentCatalogue);
|
$path = $path.'translations';
|
||||||
|
if (is_dir($path)) {
|
||||||
|
$loader->loadMessages($path, $currentCatalogue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $currentCatalogue;
|
return $currentCatalogue;
|
||||||
|
@ -284,12 +287,12 @@ EOF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $locale
|
* @param string $locale
|
||||||
* @param string $translationsPath
|
* @param array $transPaths
|
||||||
* @param TranslationLoader $loader
|
* @param TranslationLoader $loader
|
||||||
*
|
*
|
||||||
* @return MessageCatalogue[]
|
* @return MessageCatalogue[]
|
||||||
*/
|
*/
|
||||||
private function loadFallbackCatalogues($locale, $translationsPath, TranslationLoader $loader)
|
private function loadFallbackCatalogues($locale, $transPaths, TranslationLoader $loader)
|
||||||
{
|
{
|
||||||
$fallbackCatalogues = array();
|
$fallbackCatalogues = array();
|
||||||
$translator = $this->getContainer()->get('translator');
|
$translator = $this->getContainer()->get('translator');
|
||||||
|
@ -300,7 +303,12 @@ EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
$fallbackCatalogue = new MessageCatalogue($fallbackLocale);
|
$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;
|
$fallbackCatalogues[] = $fallbackCatalogue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ EOF
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$output = new SymfonyStyle($input, $output);
|
$output = new SymfonyStyle($input, $output);
|
||||||
|
$kernel = $this->getContainer()->get('kernel');
|
||||||
|
|
||||||
// check presence of force or dump-message
|
// check presence of force or dump-message
|
||||||
if ($input->getOption('force') !== true && $input->getOption('dump-messages') !== true) {
|
if ($input->getOption('force') !== true && $input->getOption('dump-messages') !== true) {
|
||||||
$output->error('You must choose one of --force or --dump-messages');
|
$output->error('You must choose one of --force or --dump-messages');
|
||||||
|
@ -87,30 +89,30 @@ EOF
|
||||||
$kernel = $this->getContainer()->get('kernel');
|
$kernel = $this->getContainer()->get('kernel');
|
||||||
|
|
||||||
// Define Root Path to App folder
|
// Define Root Path to App folder
|
||||||
$rootPath = $kernel->getRootDir();
|
$transPaths = array($kernel->getRootDir().'/Resources/');
|
||||||
$currentName = 'app folder';
|
$currentName = 'app folder';
|
||||||
|
|
||||||
// Override with provided Bundle info
|
// Override with provided Bundle info
|
||||||
if (null !== $input->getArgument('bundle')) {
|
if (null !== $input->getArgument('bundle')) {
|
||||||
try {
|
try {
|
||||||
$foundBundle = $kernel->getBundle($input->getArgument('bundle'));
|
$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();
|
$currentName = $foundBundle->getName();
|
||||||
} catch (\InvalidArgumentException $e) {
|
} catch (\InvalidArgumentException $e) {
|
||||||
// such a bundle does not exist, so treat the argument as path
|
// such a bundle does not exist, so treat the argument as path
|
||||||
$rootPath = $input->getArgument('bundle');
|
$transPaths = array($input->getArgument('bundle').'/Resources/');
|
||||||
$currentName = $rootPath;
|
$currentName = $transPaths[0];
|
||||||
|
|
||||||
if (!is_dir($rootPath)) {
|
if (!is_dir($transPaths[0])) {
|
||||||
throw new \InvalidArgumentException(sprintf('<error>"%s" is neither an enabled bundle nor a directory.</error>', $rootPath));
|
throw new \InvalidArgumentException(sprintf('<error>"%s" is neither an enabled bundle nor a directory.</error>', $transPaths[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$output->title('Symfony translation update command');
|
$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));
|
$output->text(sprintf('Generating "<info>%s</info>" translation files for "<info>%s</info>"', $input->getArgument('locale'), $currentName));
|
||||||
|
|
||||||
// load any messages from templates
|
// load any messages from templates
|
||||||
|
@ -118,13 +120,23 @@ EOF
|
||||||
$output->text('Parsing templates');
|
$output->text('Parsing templates');
|
||||||
$extractor = $this->getContainer()->get('translation.extractor');
|
$extractor = $this->getContainer()->get('translation.extractor');
|
||||||
$extractor->setPrefix($input->getOption('prefix'));
|
$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
|
// load any existing messages from the translation files
|
||||||
$currentCatalogue = new MessageCatalogue($input->getArgument('locale'));
|
$currentCatalogue = new MessageCatalogue($input->getArgument('locale'));
|
||||||
$output->text('Loading translation files');
|
$output->text('Loading translation files');
|
||||||
$loader = $this->getContainer()->get('translation.loader');
|
$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
|
// process catalogues
|
||||||
$operation = $input->getOption('clean')
|
$operation = $input->getOption('clean')
|
||||||
|
@ -150,7 +162,7 @@ EOF
|
||||||
array_map(function ($id) {
|
array_map(function ($id) {
|
||||||
return sprintf('<fg=green>%s</>', $id);
|
return sprintf('<fg=green>%s</>', $id);
|
||||||
}, $newKeys),
|
}, $newKeys),
|
||||||
array_map(function($id) {
|
array_map(function ($id) {
|
||||||
return sprintf('<fg=red>%s</>', $id);
|
return sprintf('<fg=red>%s</>', $id);
|
||||||
}, array_keys($operation->getObsoleteMessages($domain)))
|
}, array_keys($operation->getObsoleteMessages($domain)))
|
||||||
));
|
));
|
||||||
|
@ -168,7 +180,18 @@ EOF
|
||||||
// save the files
|
// save the files
|
||||||
if ($input->getOption('force') === true) {
|
if ($input->getOption('force') === true) {
|
||||||
$output->text('Writing files');
|
$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();
|
$output->newLine();
|
||||||
|
|
|
@ -210,12 +210,16 @@ class JsonDescriptor extends Descriptor
|
||||||
{
|
{
|
||||||
$data = array(
|
$data = array(
|
||||||
'class' => (string) $definition->getClass(),
|
'class' => (string) $definition->getClass(),
|
||||||
'scope' => $definition->getScope(),
|
'scope' => $definition->getScope(false),
|
||||||
'public' => $definition->isPublic(),
|
'public' => $definition->isPublic(),
|
||||||
'synthetic' => $definition->isSynthetic(),
|
'synthetic' => $definition->isSynthetic(),
|
||||||
'lazy' => $definition->isLazy(),
|
'lazy' => $definition->isLazy(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (method_exists($definition, 'isShared')) {
|
||||||
|
$data['shared'] = $definition->isShared();
|
||||||
|
}
|
||||||
|
|
||||||
$data['abstract'] = $definition->isAbstract();
|
$data['abstract'] = $definition->isAbstract();
|
||||||
$data['file'] = $definition->getFile();
|
$data['file'] = $definition->getFile();
|
||||||
|
|
||||||
|
|
|
@ -176,12 +176,16 @@ class MarkdownDescriptor extends Descriptor
|
||||||
protected function describeContainerDefinition(Definition $definition, array $options = array())
|
protected function describeContainerDefinition(Definition $definition, array $options = array())
|
||||||
{
|
{
|
||||||
$output = '- Class: `'.$definition->getClass().'`'
|
$output = '- Class: `'.$definition->getClass().'`'
|
||||||
."\n".'- Scope: `'.$definition->getScope().'`'
|
."\n".'- Scope: `'.$definition->getScope(false).'`'
|
||||||
."\n".'- Public: '.($definition->isPublic() ? 'yes' : 'no')
|
."\n".'- Public: '.($definition->isPublic() ? 'yes' : 'no')
|
||||||
."\n".'- Synthetic: '.($definition->isSynthetic() ? 'yes' : 'no')
|
."\n".'- Synthetic: '.($definition->isSynthetic() ? 'yes' : 'no')
|
||||||
."\n".'- Lazy: '.($definition->isLazy() ? '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');
|
$output .= "\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no');
|
||||||
|
|
||||||
if ($definition->getFile()) {
|
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();
|
$serviceIds = isset($options['tag']) && $options['tag'] ? array_keys($builder->findTaggedServiceIds($options['tag'])) : $builder->getServiceIds();
|
||||||
$maxTags = array();
|
$maxTags = array();
|
||||||
|
|
||||||
foreach ($serviceIds as $key => $serviceId) {
|
foreach ($serviceIds as $key => $serviceId) {
|
||||||
$definition = $this->resolveServiceDefinition($builder, $serviceId);
|
$definition = $this->resolveServiceDefinition($builder, $serviceId);
|
||||||
if ($definition instanceof Definition) {
|
if ($definition instanceof Definition) {
|
||||||
// filter out private services unless shown explicitly
|
// filter out private services unless shown explicitly
|
||||||
|
@ -256,10 +256,13 @@ class TextDescriptor extends Descriptor
|
||||||
$description[] = '<comment>Tags</comment> -';
|
$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>Public</comment> %s', $definition->isPublic() ? 'yes' : 'no');
|
||||||
$description[] = sprintf('<comment>Synthetic</comment> %s', $definition->isSynthetic() ? 'yes' : 'no');
|
$description[] = sprintf('<comment>Synthetic</comment> %s', $definition->isSynthetic() ? 'yes' : 'no');
|
||||||
$description[] = sprintf('<comment>Lazy</comment> %s', $definition->isLazy() ? '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');
|
$description[] = sprintf('<comment>Abstract</comment> %s', $definition->isAbstract() ? 'yes' : 'no');
|
||||||
|
|
||||||
if ($definition->getFile()) {
|
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('public', $definition->isPublic() ? 'true' : 'false');
|
||||||
$serviceXML->setAttribute('synthetic', $definition->isSynthetic() ? 'true' : 'false');
|
$serviceXML->setAttribute('synthetic', $definition->isSynthetic() ? 'true' : 'false');
|
||||||
$serviceXML->setAttribute('lazy', $definition->isLazy() ? '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('abstract', $definition->isAbstract() ? 'true' : 'false');
|
||||||
$serviceXML->setAttribute('file', $definition->getFile());
|
$serviceXML->setAttribute('file', $definition->getFile());
|
||||||
|
|
||||||
|
|
|
@ -119,9 +119,9 @@ abstract class Controller extends ContainerAware
|
||||||
* @param mixed $attributes The attributes
|
* @param mixed $attributes The attributes
|
||||||
* @param mixed $object The object
|
* @param mixed $object The object
|
||||||
*
|
*
|
||||||
* @throws \LogicException
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
|
*
|
||||||
|
* @throws \LogicException
|
||||||
*/
|
*/
|
||||||
protected function isGranted($attributes, $object = null)
|
protected function isGranted($attributes, $object = null)
|
||||||
{
|
{
|
||||||
|
@ -231,7 +231,7 @@ abstract class Controller extends ContainerAware
|
||||||
*
|
*
|
||||||
* @return AccessDeniedException
|
* @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);
|
return new AccessDeniedException($message, $previous);
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,7 +444,7 @@ class FrameworkExtension extends Extension
|
||||||
/**
|
/**
|
||||||
* Loads the request configuration.
|
* 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 ContainerBuilder $container A ContainerBuilder instance
|
||||||
* @param XmlFileLoader $loader An XmlFileLoader 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>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<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 type="service" id="kernel" />
|
||||||
<argument>%test.client.parameters%</argument>
|
<argument>%test.client.parameters%</argument>
|
||||||
<argument type="service" id="test.client.history" />
|
<argument type="service" id="test.client.history" />
|
||||||
<argument type="service" id="test.client.cookiejar" />
|
<argument type="service" id="test.client.cookiejar" />
|
||||||
</service>
|
</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">
|
<service id="test.session.listener" class="Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener">
|
||||||
<argument type="service" id="service_container" />
|
<argument type="service" id="service_container" />
|
||||||
|
|
|
@ -32,6 +32,16 @@
|
||||||
<argument>%validator.mapping.cache.prefix%</argument>
|
<argument>%validator.mapping.cache.prefix%</argument>
|
||||||
</service>
|
</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">
|
<service id="validator.validator_factory" class="Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory" public="false">
|
||||||
<argument type="service" id="service_container" />
|
<argument type="service" id="service_container" />
|
||||||
<argument type="collection" />
|
<argument type="collection" />
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
)) ?>
|
)) ?>
|
||||||
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
|
<?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 if (count($preferred_choices) > 0): ?>
|
||||||
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?>
|
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?>
|
||||||
<?php if (count($choices) > 0 && null !== $separator): ?>
|
<?php if (count($choices) > 0 && null !== $separator): ?>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||||
<?php foreach ($form as $child): ?>
|
<?php foreach ($form as $child): ?>
|
||||||
<?php echo $view['form']->widget($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 ?>
|
<?php endforeach ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
<?php if (!$label) { $label = isset($label_format)
|
<?php if (!$label) { $label = isset($label_format)
|
||||||
? strtr($label_format, array('%name%' => $name, '%id%' => $id))
|
? strtr($label_format, array('%name%' => $name, '%id%' => $id))
|
||||||
: $view['form']->humanize($name); } ?>
|
: $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 ?>
|
<?php endif ?>
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
|
||||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
|
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
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\Loader\ClosureLoader;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
@ -515,14 +515,14 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||||
return $container;
|
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('assets.path_package', $package->getParent());
|
||||||
$this->assertEquals($basePath, $package->getArgument(0));
|
$this->assertEquals($basePath, $package->getArgument(0));
|
||||||
$this->assertVersionStrategy($container, $package->getArgument(1), $version, $format);
|
$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('assets.url_package', $package->getParent());
|
||||||
$this->assertEquals($baseUrls, $package->getArgument(0));
|
$this->assertEquals($baseUrls, $package->getArgument(0));
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"public": true,
|
"public": true,
|
||||||
"synthetic": false,
|
"synthetic": false,
|
||||||
"lazy": true,
|
"lazy": true,
|
||||||
|
"shared": true,
|
||||||
"abstract": true,
|
"abstract": true,
|
||||||
"file": null,
|
"file": null,
|
||||||
"factory_class": "Full\\Qualified\\FactoryClass",
|
"factory_class": "Full\\Qualified\\FactoryClass",
|
||||||
|
|
|
@ -12,6 +12,7 @@ definition_1
|
||||||
- Public: yes
|
- Public: yes
|
||||||
- Synthetic: no
|
- Synthetic: no
|
||||||
- Lazy: yes
|
- Lazy: yes
|
||||||
|
- Shared: yes
|
||||||
- Abstract: yes
|
- Abstract: yes
|
||||||
- Factory Class: `Full\Qualified\FactoryClass`
|
- Factory Class: `Full\Qualified\FactoryClass`
|
||||||
- Factory Method: `get`
|
- Factory Method: `get`
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<container>
|
<container>
|
||||||
<alias id="alias_1" service="service_1" public="true"/>
|
<alias id="alias_1" service="service_1" public="true"/>
|
||||||
<alias id="alias_2" service="service_2" public="false"/>
|
<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"/>
|
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||||
</definition>
|
</definition>
|
||||||
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerBuilder"/>
|
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerBuilder"/>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"public": true,
|
"public": true,
|
||||||
"synthetic": false,
|
"synthetic": false,
|
||||||
"lazy": true,
|
"lazy": true,
|
||||||
|
"shared": true,
|
||||||
"abstract": true,
|
"abstract": true,
|
||||||
"file": null,
|
"file": null,
|
||||||
"factory_class": "Full\\Qualified\\FactoryClass",
|
"factory_class": "Full\\Qualified\\FactoryClass",
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
"public": false,
|
"public": false,
|
||||||
"synthetic": true,
|
"synthetic": true,
|
||||||
"lazy": false,
|
"lazy": false,
|
||||||
|
"shared": true,
|
||||||
"abstract": false,
|
"abstract": false,
|
||||||
"file": "\/path\/to\/file",
|
"file": "\/path\/to\/file",
|
||||||
"factory_service": "factory.service",
|
"factory_service": "factory.service",
|
||||||
|
|
|
@ -12,6 +12,7 @@ definition_1
|
||||||
- Public: yes
|
- Public: yes
|
||||||
- Synthetic: no
|
- Synthetic: no
|
||||||
- Lazy: yes
|
- Lazy: yes
|
||||||
|
- Shared: yes
|
||||||
- Abstract: yes
|
- Abstract: yes
|
||||||
- Factory Class: `Full\Qualified\FactoryClass`
|
- Factory Class: `Full\Qualified\FactoryClass`
|
||||||
- Factory Method: `get`
|
- Factory Method: `get`
|
||||||
|
@ -24,6 +25,7 @@ definition_2
|
||||||
- Public: no
|
- Public: no
|
||||||
- Synthetic: yes
|
- Synthetic: yes
|
||||||
- Lazy: no
|
- Lazy: no
|
||||||
|
- Shared: yes
|
||||||
- Abstract: no
|
- Abstract: no
|
||||||
- File: `/path/to/file`
|
- File: `/path/to/file`
|
||||||
- Factory Service: `factory.service`
|
- Factory Service: `factory.service`
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<container>
|
<container>
|
||||||
<alias id="alias_1" service="service_1" public="true"/>
|
<alias id="alias_1" service="service_1" public="true"/>
|
||||||
<alias id="alias_2" service="service_2" public="false"/>
|
<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"/>
|
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||||
</definition>
|
</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"/>
|
<factory service="factory.service" method="get"/>
|
||||||
<tags>
|
<tags>
|
||||||
<tag name="tag1">
|
<tag name="tag1">
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"public": false,
|
"public": false,
|
||||||
"synthetic": true,
|
"synthetic": true,
|
||||||
"lazy": false,
|
"lazy": false,
|
||||||
|
"shared": true,
|
||||||
"abstract": false,
|
"abstract": false,
|
||||||
"file": "\/path\/to\/file",
|
"file": "\/path\/to\/file",
|
||||||
"factory_service": "factory.service",
|
"factory_service": "factory.service",
|
||||||
|
|
|
@ -12,6 +12,7 @@ definition_2
|
||||||
- Public: no
|
- Public: no
|
||||||
- Synthetic: yes
|
- Synthetic: yes
|
||||||
- Lazy: no
|
- Lazy: no
|
||||||
|
- Shared: yes
|
||||||
- Abstract: no
|
- Abstract: no
|
||||||
- File: `/path/to/file`
|
- File: `/path/to/file`
|
||||||
- Factory Service: `factory.service`
|
- Factory Service: `factory.service`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<container>
|
<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"/>
|
<factory service="factory.service" method="get"/>
|
||||||
<tags>
|
<tags>
|
||||||
<tag name="tag1">
|
<tag name="tag1">
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"public": false,
|
"public": false,
|
||||||
"synthetic": true,
|
"synthetic": true,
|
||||||
"lazy": false,
|
"lazy": false,
|
||||||
|
"shared": true,
|
||||||
"abstract": false,
|
"abstract": false,
|
||||||
"file": "\/path\/to\/file",
|
"file": "\/path\/to\/file",
|
||||||
"factory_service": "factory.service",
|
"factory_service": "factory.service",
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
"public": false,
|
"public": false,
|
||||||
"synthetic": true,
|
"synthetic": true,
|
||||||
"lazy": false,
|
"lazy": false,
|
||||||
|
"shared": true,
|
||||||
"abstract": false,
|
"abstract": false,
|
||||||
"file": "\/path\/to\/file",
|
"file": "\/path\/to\/file",
|
||||||
"factory_service": "factory.service",
|
"factory_service": "factory.service",
|
||||||
|
|
|
@ -12,6 +12,7 @@ definition_2
|
||||||
- Public: no
|
- Public: no
|
||||||
- Synthetic: yes
|
- Synthetic: yes
|
||||||
- Lazy: no
|
- Lazy: no
|
||||||
|
- Shared: yes
|
||||||
- Abstract: no
|
- Abstract: no
|
||||||
- File: `/path/to/file`
|
- File: `/path/to/file`
|
||||||
- Factory Service: `factory.service`
|
- Factory Service: `factory.service`
|
||||||
|
@ -29,6 +30,7 @@ definition_2
|
||||||
- Public: no
|
- Public: no
|
||||||
- Synthetic: yes
|
- Synthetic: yes
|
||||||
- Lazy: no
|
- Lazy: no
|
||||||
|
- Shared: yes
|
||||||
- Abstract: no
|
- Abstract: no
|
||||||
- File: `/path/to/file`
|
- File: `/path/to/file`
|
||||||
- Factory Service: `factory.service`
|
- Factory Service: `factory.service`
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<container>
|
<container>
|
||||||
<tag name="tag1">
|
<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"/>
|
<factory service="factory.service" method="get"/>
|
||||||
</definition>
|
</definition>
|
||||||
</tag>
|
</tag>
|
||||||
<tag name="tag2">
|
<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"/>
|
<factory service="factory.service" method="get"/>
|
||||||
</definition>
|
</definition>
|
||||||
</tag>
|
</tag>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"public": true,
|
"public": true,
|
||||||
"synthetic": false,
|
"synthetic": false,
|
||||||
"lazy": true,
|
"lazy": true,
|
||||||
|
"shared": true,
|
||||||
"abstract": true,
|
"abstract": true,
|
||||||
"file": null,
|
"file": null,
|
||||||
"factory_class": "Full\\Qualified\\FactoryClass",
|
"factory_class": "Full\\Qualified\\FactoryClass",
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
- Public: yes
|
- Public: yes
|
||||||
- Synthetic: no
|
- Synthetic: no
|
||||||
- Lazy: yes
|
- Lazy: yes
|
||||||
|
- Shared: yes
|
||||||
- Abstract: yes
|
- Abstract: yes
|
||||||
- Factory Class: `Full\Qualified\FactoryClass`
|
- Factory Class: `Full\Qualified\FactoryClass`
|
||||||
- Factory Method: `get`
|
- Factory Method: `get`
|
|
@ -5,6 +5,7 @@
|
||||||
<comment>Public</comment> yes
|
<comment>Public</comment> yes
|
||||||
<comment>Synthetic</comment> no
|
<comment>Synthetic</comment> no
|
||||||
<comment>Lazy</comment> yes
|
<comment>Lazy</comment> yes
|
||||||
|
<comment>Shared</comment> yes
|
||||||
<comment>Abstract</comment> yes
|
<comment>Abstract</comment> yes
|
||||||
<comment>Factory Class</comment> Full\Qualified\FactoryClass
|
<comment>Factory Class</comment> Full\Qualified\FactoryClass
|
||||||
<comment>Factory Method</comment> get
|
<comment>Factory Method</comment> get
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"/>
|
<factory class="Full\Qualified\FactoryClass" method="get"/>
|
||||||
</definition>
|
</definition>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"public": false,
|
"public": false,
|
||||||
"synthetic": true,
|
"synthetic": true,
|
||||||
"lazy": false,
|
"lazy": false,
|
||||||
|
"shared": true,
|
||||||
"abstract": false,
|
"abstract": false,
|
||||||
"file": "\/path\/to\/file",
|
"file": "\/path\/to\/file",
|
||||||
"factory_service": "factory.service",
|
"factory_service": "factory.service",
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
- Public: no
|
- Public: no
|
||||||
- Synthetic: yes
|
- Synthetic: yes
|
||||||
- Lazy: no
|
- Lazy: no
|
||||||
|
- Shared: yes
|
||||||
- Abstract: no
|
- Abstract: no
|
||||||
- File: `/path/to/file`
|
- File: `/path/to/file`
|
||||||
- Factory Service: `factory.service`
|
- Factory Service: `factory.service`
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<comment>Public</comment> no
|
<comment>Public</comment> no
|
||||||
<comment>Synthetic</comment> yes
|
<comment>Synthetic</comment> yes
|
||||||
<comment>Lazy</comment> no
|
<comment>Lazy</comment> no
|
||||||
|
<comment>Shared</comment> yes
|
||||||
<comment>Abstract</comment> no
|
<comment>Abstract</comment> no
|
||||||
<comment>Required File</comment> /path/to/file
|
<comment>Required File</comment> /path/to/file
|
||||||
<comment>Factory Service</comment> factory.service
|
<comment>Factory Service</comment> factory.service
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"/>
|
<factory service="factory.service" method="get"/>
|
||||||
<tags>
|
<tags>
|
||||||
<tag name="tag1">
|
<tag name="tag1">
|
||||||
|
|
|
@ -4,7 +4,8 @@ imports:
|
||||||
services:
|
services:
|
||||||
csrf_form_login.form.type:
|
csrf_form_login.form.type:
|
||||||
class: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Form\UserLoginFormType
|
class: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Form\UserLoginFormType
|
||||||
arguments: [ @request_stack ]
|
arguments:
|
||||||
|
- @request_stack
|
||||||
tags:
|
tags:
|
||||||
- { name: form.type, alias: user_login }
|
- { name: form.type, alias: user_login }
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,11 @@
|
||||||
|
|
||||||
namespace Symfony\Bundle\TwigBundle\CacheWarmer;
|
namespace Symfony\Bundle\TwigBundle\CacheWarmer;
|
||||||
|
|
||||||
|
use Symfony\Component\Finder\Finder;
|
||||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinderInterface;
|
use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinderInterface;
|
||||||
|
use Symfony\Component\Templating\TemplateReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the Twig cache for all templates.
|
* Generates the Twig cache for all templates.
|
||||||
|
@ -27,14 +29,16 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
||||||
{
|
{
|
||||||
protected $container;
|
protected $container;
|
||||||
protected $finder;
|
protected $finder;
|
||||||
|
private $paths;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param ContainerInterface $container The dependency injection container
|
* @param ContainerInterface $container The dependency injection container
|
||||||
* @param TemplateFinderInterface $finder The template paths cache warmer
|
* @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
|
// We don't inject the Twig environment directly as it depends on the
|
||||||
// template locator (via the loader) which might be a cached one.
|
// template locator (via the loader) which might be a cached one.
|
||||||
|
@ -42,6 +46,7 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
||||||
// has been warmed up
|
// has been warmed up
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
$this->finder = $finder;
|
$this->finder = $finder;
|
||||||
|
$this->paths = $paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +58,13 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
||||||
{
|
{
|
||||||
$twig = $this->container->get('twig');
|
$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')) {
|
if ('twig' !== $template->get('engine')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -75,4 +86,32 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
|
||||||
{
|
{
|
||||||
return true;
|
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
|
// register bundles as Twig namespaces
|
||||||
foreach ($container->getParameter('kernel.bundles') as $bundle => $class) {
|
foreach ($container->getParameter('kernel.bundles') as $bundle => $class) {
|
||||||
$dir = $container->getParameter('kernel.root_dir').'/Resources/'.$bundle.'/views';
|
$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">
|
<service id="twig.cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer" public="false">
|
||||||
<argument type="service" id="service_container" />
|
<argument type="service" id="service_container" />
|
||||||
<argument type="service" id="templating.finder" />
|
<argument type="service" id="templating.finder" />
|
||||||
|
<argument type="collection" /> <!-- Twig paths -->
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="twig.loader.native_filesystem" class="Twig_Loader_Filesystem" public="false">
|
<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\Definition;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||||
use Symfony\Component\DependencyInjection\Scope;
|
|
||||||
|
|
||||||
class WebProfilerExtensionTest extends TestCase
|
class WebProfilerExtensionTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -49,8 +48,6 @@ class WebProfilerExtensionTest extends TestCase
|
||||||
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
|
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
|
||||||
|
|
||||||
$this->container = new ContainerBuilder();
|
$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('router', $this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'));
|
||||||
$this->container->register('twig', 'Twig_Environment');
|
$this->container->register('twig', 'Twig_Environment');
|
||||||
$this->container->setParameter('kernel.bundles', array());
|
$this->container->setParameter('kernel.bundles', array());
|
||||||
|
@ -125,7 +122,6 @@ class WebProfilerExtensionTest extends TestCase
|
||||||
eval('?>'.$dumper->dump(array('class' => $class)));
|
eval('?>'.$dumper->dump(array('class' => $class)));
|
||||||
|
|
||||||
$container = new $class();
|
$container = new $class();
|
||||||
$container->enterScope('request');
|
|
||||||
$container->set('kernel', $this->kernel);
|
$container->set('kernel', $this->kernel);
|
||||||
|
|
||||||
return $container;
|
return $container;
|
||||||
|
|
|
@ -77,7 +77,7 @@ class Cookie
|
||||||
if (null !== $expires) {
|
if (null !== $expires) {
|
||||||
$timestampAsDateTime = \DateTime::createFromFormat('U', $expires);
|
$timestampAsDateTime = \DateTime::createFromFormat('U', $expires);
|
||||||
if (false === $timestampAsDateTime) {
|
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();
|
$this->expires = $timestampAsDateTime->getTimestamp();
|
||||||
|
|
|
@ -22,7 +22,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function prepare_workspace()
|
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);
|
mkdir($this->workspace, 0777, true);
|
||||||
$this->workspace = realpath($this->workspace);
|
$this->workspace = realpath($this->workspace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||||
protected $addIfNotSet = false;
|
protected $addIfNotSet = false;
|
||||||
protected $performDeepMerging = true;
|
protected $performDeepMerging = true;
|
||||||
protected $ignoreExtraKeys = false;
|
protected $ignoreExtraKeys = false;
|
||||||
|
protected $removeExtraKeys = true;
|
||||||
protected $normalizeKeys = true;
|
protected $normalizeKeys = true;
|
||||||
|
|
||||||
public function setNormalizeKeys($normalizeKeys)
|
public function setNormalizeKeys($normalizeKeys)
|
||||||
|
@ -140,10 +141,12 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||||
* Whether extra keys should just be ignore without an exception.
|
* Whether extra keys should just be ignore without an exception.
|
||||||
*
|
*
|
||||||
* @param bool $boolean To allow extra keys
|
* @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->ignoreExtraKeys = (bool) $boolean;
|
||||||
|
$this->removeExtraKeys = $this->ignoreExtraKeys && $remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -300,6 +303,9 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
||||||
if (isset($this->children[$name])) {
|
if (isset($this->children[$name])) {
|
||||||
$normalized[$name] = $this->children[$name]->normalize($val);
|
$normalized[$name] = $this->children[$name]->normalize($val);
|
||||||
unset($value[$name]);
|
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 $performDeepMerging = true;
|
||||||
protected $ignoreExtraKeys = false;
|
protected $ignoreExtraKeys = false;
|
||||||
|
protected $removeExtraKeys = true;
|
||||||
protected $children = array();
|
protected $children = array();
|
||||||
protected $prototype;
|
protected $prototype;
|
||||||
protected $atLeastOne = false;
|
protected $atLeastOne = false;
|
||||||
|
@ -284,11 +285,14 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||||
* you want to send an entire configuration array through a special
|
* you want to send an entire configuration array through a special
|
||||||
* tree that processes only part of the array.
|
* tree that processes only part of the array.
|
||||||
*
|
*
|
||||||
|
* @param bool $remove Whether to remove the extra keys
|
||||||
|
*
|
||||||
* @return ArrayNodeDefinition
|
* @return ArrayNodeDefinition
|
||||||
*/
|
*/
|
||||||
public function ignoreExtraKeys()
|
public function ignoreExtraKeys($remove = true)
|
||||||
{
|
{
|
||||||
$this->ignoreExtraKeys = true;
|
$this->ignoreExtraKeys = true;
|
||||||
|
$this->removeExtraKeys = $remove;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -393,7 +397,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
||||||
$node->addEquivalentValue(false, $this->falseEquivalent);
|
$node->addEquivalentValue(false, $this->falseEquivalent);
|
||||||
$node->setPerformDeepMerging($this->performDeepMerging);
|
$node->setPerformDeepMerging($this->performDeepMerging);
|
||||||
$node->setRequired($this->required);
|
$node->setRequired($this->required);
|
||||||
$node->setIgnoreExtraKeys($this->ignoreExtraKeys);
|
$node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
|
||||||
$node->setNormalizeKeys($this->normalizeKeys);
|
$node->setNormalizeKeys($this->normalizeKeys);
|
||||||
|
|
||||||
if (null !== $this->normalization) {
|
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');
|
$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
|
* @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->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');
|
$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');
|
$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->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');
|
$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');
|
$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());
|
$totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
|
||||||
$spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
|
$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(),
|
$argument->getName(),
|
||||||
str_repeat(' ', $spacingWidth),
|
str_repeat(' ', $spacingWidth),
|
||||||
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
||||||
|
@ -77,7 +77,7 @@ class TextDescriptor extends Descriptor
|
||||||
|
|
||||||
$spacingWidth = $totalWidth - strlen($synopsis) + 2;
|
$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,
|
$synopsis,
|
||||||
str_repeat(' ', $spacingWidth),
|
str_repeat(' ', $spacingWidth),
|
||||||
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
||||||
|
@ -207,7 +207,7 @@ class TextDescriptor extends Descriptor
|
||||||
foreach ($namespace['commands'] as $name) {
|
foreach ($namespace['commands'] as $name) {
|
||||||
$this->writeText("\n");
|
$this->writeText("\n");
|
||||||
$spacingWidth = $width - strlen($name);
|
$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;
|
$totalWidth = 0;
|
||||||
foreach ($options as $option) {
|
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()) {
|
if ($option->acceptValue()) {
|
||||||
$valueLength = 1 + strlen($option->getName()); // = + value
|
$valueLength = 1 + strlen($option->getName()); // = + value
|
||||||
|
|
|
@ -205,24 +205,26 @@ class Table
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$this->calculateNumberOfColumns();
|
$this->calculateNumberOfColumns();
|
||||||
$this->rows = $this->buildTableRows($this->rows);
|
$rows = $this->buildTableRows($this->rows);
|
||||||
$this->headers = $this->buildTableRows($this->headers);
|
$headers = $this->buildTableRows($this->headers);
|
||||||
|
|
||||||
|
$this->calculateColumnsWidth(array_merge($headers, $rows));
|
||||||
|
|
||||||
$this->renderRowSeparator();
|
$this->renderRowSeparator();
|
||||||
if (!empty($this->headers)) {
|
if (!empty($headers)) {
|
||||||
foreach ($this->headers as $header) {
|
foreach ($headers as $header) {
|
||||||
$this->renderRow($header, $this->style->getCellHeaderFormat());
|
$this->renderRow($header, $this->style->getCellHeaderFormat());
|
||||||
$this->renderRowSeparator();
|
$this->renderRowSeparator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($this->rows as $row) {
|
foreach ($rows as $row) {
|
||||||
if ($row instanceof TableSeparator) {
|
if ($row instanceof TableSeparator) {
|
||||||
$this->renderRowSeparator();
|
$this->renderRowSeparator();
|
||||||
} else {
|
} else {
|
||||||
$this->renderRow($row, $this->style->getCellRowFormat());
|
$this->renderRow($row, $this->style->getCellRowFormat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty($this->rows)) {
|
if (!empty($rows)) {
|
||||||
$this->renderRowSeparator();
|
$this->renderRowSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +248,7 @@ class Table
|
||||||
|
|
||||||
$markup = $this->style->getCrossingChar();
|
$markup = $this->style->getCrossingChar();
|
||||||
for ($column = 0; $column < $count; $column++) {
|
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));
|
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
|
||||||
|
@ -292,11 +294,11 @@ class Table
|
||||||
private function renderCell(array $row, $column, $cellFormat)
|
private function renderCell(array $row, $column, $cellFormat)
|
||||||
{
|
{
|
||||||
$cell = isset($row[$column]) ? $row[$column] : '';
|
$cell = isset($row[$column]) ? $row[$column] : '';
|
||||||
$width = $this->getColumnWidth($column);
|
$width = $this->columnWidths[$column];
|
||||||
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
|
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
|
||||||
// add the width of the following columns(numbers of colspan).
|
// add the width of the following columns(numbers of colspan).
|
||||||
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
|
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
|
* @return int
|
||||||
*/
|
*/
|
||||||
private function getColumnWidth($column)
|
private function calculateColumnsWidth($rows)
|
||||||
{
|
{
|
||||||
if (isset($this->columnWidths[$column])) {
|
for ($column = 0; $column < $this->numberOfColumns; $column++) {
|
||||||
return $this->columnWidths[$column];
|
$lengths = array();
|
||||||
}
|
foreach ($rows as $row) {
|
||||||
|
if ($row instanceof TableSeparator) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (array_merge($this->headers, $this->rows) as $row) {
|
$lengths[] = $this->getCellWidth($row, $column);
|
||||||
if ($row instanceof TableSeparator) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$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()) {
|
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)) {
|
if (null === $value && $option->acceptValue() && count($this->parsed)) {
|
||||||
|
|
|
@ -30,6 +30,9 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||||
*/
|
*/
|
||||||
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var StreamOutput
|
||||||
|
*/
|
||||||
private $stderr;
|
private $stderr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,14 +46,12 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
||||||
*/
|
*/
|
||||||
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
|
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
|
||||||
{
|
{
|
||||||
$outputStream = 'php://stdout';
|
$outputStream = $this->hasStdoutSupport() ? 'php://stdout' : 'php://output';
|
||||||
if (!$this->hasStdoutSupport()) {
|
$errorStream = $this->hasStderrSupport() ? 'php://stderr' : 'php://output';
|
||||||
$outputStream = 'php://output';
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::__construct(fopen($outputStream, 'w'), $verbosity, $decorated, $formatter);
|
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
|
* Returns true if current environment supports writing console output to
|
||||||
* STDOUT.
|
* 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
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function hasStdoutSupport()
|
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_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_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_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('ISBN', 'Author'),
|
||||||
array(
|
array(
|
||||||
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',
|
'Dante Alighieri',
|
||||||
),
|
),
|
||||||
array(new TableSeparator()),
|
array(new TableSeparator()),
|
||||||
|
@ -554,6 +554,33 @@ TABLE;
|
||||||
$this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works');
|
$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()
|
protected function getOutputStream()
|
||||||
{
|
{
|
||||||
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
|
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
|
||||||
|
|
|
@ -95,6 +95,7 @@ class ErrorHandler
|
||||||
private static $reservedMemory;
|
private static $reservedMemory;
|
||||||
private static $stackedErrors = array();
|
private static $stackedErrors = array();
|
||||||
private static $stackedErrorLevels = array();
|
private static $stackedErrorLevels = array();
|
||||||
|
private static $toStringException = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the error handler.
|
* Registers the error handler.
|
||||||
|
@ -351,13 +352,56 @@ class ErrorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($throw) {
|
if ($throw) {
|
||||||
if (($this->scopedErrors & $type) && class_exists(ContextErrorException::class)) {
|
if (null !== self::$toStringException) {
|
||||||
// Checking for class existence is a work around for https://bugs.php.net/42098
|
$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);
|
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
|
||||||
} else {
|
} else {
|
||||||
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
|
$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;
|
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()
|
public function testHandleException()
|
||||||
{
|
{
|
||||||
try {
|
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
|
* 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
|
2.7.0
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -25,6 +25,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||||
* - non synthetic, non abstract services always have a class set
|
* - non synthetic, non abstract services always have a class set
|
||||||
* - synthetic services are always public
|
* - synthetic services are always public
|
||||||
* - synthetic services are always of non-prototype scope
|
* - synthetic services are always of non-prototype scope
|
||||||
|
* - shared services are always of non-prototype scope
|
||||||
*
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -46,10 +47,15 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// synthetic service has non-prototype scope
|
// 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));
|
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
|
// non-synthetic, non-abstract service has class
|
||||||
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
|
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
|
||||||
if ($definition->getFactory()) {
|
if ($definition->getFactory()) {
|
||||||
|
|
|
@ -46,10 +46,10 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
|
|
||||||
$children = $this->container->getScopeChildren();
|
$children = $this->container->getScopeChildren(false);
|
||||||
$ancestors = array();
|
$ancestors = array();
|
||||||
|
|
||||||
$scopes = $this->container->getScopes();
|
$scopes = $this->container->getScopes(false);
|
||||||
foreach ($scopes as $name => $parent) {
|
foreach ($scopes as $name => $parent) {
|
||||||
$ancestors[$name] = array($parent);
|
$ancestors[$name] = array($parent);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
||||||
|
|
||||||
$this->currentId = $id;
|
$this->currentId = $id;
|
||||||
$this->currentDefinition = $definition;
|
$this->currentDefinition = $definition;
|
||||||
$this->currentScope = $scope = $definition->getScope();
|
$this->currentScope = $scope = $definition->getScope(false);
|
||||||
|
|
||||||
if (ContainerInterface::SCOPE_CONTAINER === $scope) {
|
if (ContainerInterface::SCOPE_CONTAINER === $scope) {
|
||||||
$this->currentScopeChildren = array_keys($scopes);
|
$this->currentScopeChildren = array_keys($scopes);
|
||||||
|
@ -125,7 +125,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$reference->isStrict()) {
|
if (!$reference->isStrict(false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->currentScope === $scope = $definition->getScope()) {
|
if ($this->currentScope === $scope = $definition->getScope(false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,27 +48,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||||
$this->graph = $this->compiler->getServiceReferenceGraph();
|
$this->graph = $this->compiler->getServiceReferenceGraph();
|
||||||
|
|
||||||
foreach ($container->getDefinitions() as $id => $definition) {
|
$container->setDefinitions($this->inlineArguments($container, $container->getDefinitions(), true));
|
||||||
$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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,12 +56,16 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||||
*
|
*
|
||||||
* @param ContainerBuilder $container The ContainerBuilder
|
* @param ContainerBuilder $container The ContainerBuilder
|
||||||
* @param array $arguments An array of arguments
|
* @param array $arguments An array of arguments
|
||||||
|
* @param bool $isRoot If we are processing the root definitions or not
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function inlineArguments(ContainerBuilder $container, array $arguments)
|
private function inlineArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
|
||||||
{
|
{
|
||||||
foreach ($arguments as $k => $argument) {
|
foreach ($arguments as $k => $argument) {
|
||||||
|
if ($isRoot) {
|
||||||
|
$this->currentId = $k;
|
||||||
|
}
|
||||||
if (is_array($argument)) {
|
if (is_array($argument)) {
|
||||||
$arguments[$k] = $this->inlineArguments($container, $argument);
|
$arguments[$k] = $this->inlineArguments($container, $argument);
|
||||||
} elseif ($argument instanceof Reference) {
|
} elseif ($argument instanceof Reference) {
|
||||||
|
@ -92,7 +76,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||||
if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
||||||
$this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
|
$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;
|
$arguments[$k] = $definition;
|
||||||
} else {
|
} else {
|
||||||
$arguments[$k] = clone $definition;
|
$arguments[$k] = clone $definition;
|
||||||
|
@ -102,6 +86,12 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||||
$argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
|
$argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
|
||||||
$argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
|
$argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
|
||||||
$argument->setProperties($this->inlineArguments($container, $argument->getProperties()));
|
$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)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +138,6 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||||
return false;
|
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.
|
* merged Definition instance.
|
||||||
*
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
*/
|
*/
|
||||||
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||||
{
|
{
|
||||||
private $container;
|
|
||||||
private $compiler;
|
private $compiler;
|
||||||
private $formatter;
|
private $formatter;
|
||||||
|
private $currentId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
|
* 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)
|
public function process(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
|
||||||
$this->compiler = $container->getCompiler();
|
$this->compiler = $container->getCompiler();
|
||||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||||
|
|
||||||
foreach ($container->getDefinitions() as $id => $definition) {
|
$container->setDefinitions($this->resolveArguments($container, $container->getDefinitions(), true));
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
$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.
|
* Resolves the definition.
|
||||||
*
|
*
|
||||||
* @param string $id The definition identifier
|
* @param ContainerBuilder $container The ContainerBuilder
|
||||||
* @param DefinitionDecorator $definition
|
* @param DefinitionDecorator $definition
|
||||||
*
|
*
|
||||||
* @return Definition
|
* @return Definition
|
||||||
*
|
*
|
||||||
* @throws \RuntimeException When the definition is invalid
|
* @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())) {
|
if (!$container->hasDefinition($parent = $definition->getParent())) {
|
||||||
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $id));
|
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) {
|
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();
|
$def = new Definition();
|
||||||
|
|
||||||
// merge in parent definition
|
// merge in parent definition
|
||||||
|
@ -107,6 +144,14 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||||
if (isset($changes['lazy'])) {
|
if (isset($changes['lazy'])) {
|
||||||
$def->setLazy($definition->isLazy());
|
$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
|
// merge arguments
|
||||||
foreach ($definition->getArguments() as $k => $v) {
|
foreach ($definition->getArguments() as $k => $v) {
|
||||||
|
@ -135,12 +180,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||||
|
|
||||||
// these attributes are always taken from the child
|
// these attributes are always taken from the child
|
||||||
$def->setAbstract($definition->isAbstract());
|
$def->setAbstract($definition->isAbstract());
|
||||||
$def->setScope($definition->getScope());
|
$def->setScope($definition->getScope(false), false);
|
||||||
$def->setTags($definition->getTags());
|
$def->setTags($definition->getTags());
|
||||||
|
|
||||||
// set new definition on container
|
|
||||||
$this->container->setDefinition($id, $def);
|
|
||||||
|
|
||||||
return $def;
|
return $def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
||||||
$defId = $this->getDefinitionId($id = (string) $argument);
|
$defId = $this->getDefinitionId($id = (string) $argument);
|
||||||
|
|
||||||
if ($defId !== $id) {
|
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()
|
* 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.
|
* 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 string $id The service identifier
|
||||||
* @param object $service The service instance
|
* @param object $service The service instance
|
||||||
* @param string $scope The scope of the service
|
* @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)
|
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) {
|
if (self::SCOPE_PROTOTYPE === $scope) {
|
||||||
throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id));
|
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
|
* @throws InvalidArgumentException When the scope does not exist
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function enterScope($name)
|
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])) {
|
if (!isset($this->scopes[$name])) {
|
||||||
throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $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
|
* @throws InvalidArgumentException if the scope is not active
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function leaveScope($name)
|
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])) {
|
if (!isset($this->scopedServices[$name])) {
|
||||||
throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
|
throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
|
||||||
}
|
}
|
||||||
|
@ -484,12 +502,17 @@ class Container implements IntrospectableContainerInterface
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function addScope(ScopeInterface $scope)
|
public function addScope(ScopeInterface $scope)
|
||||||
{
|
{
|
||||||
$name = $scope->getName();
|
$name = $scope->getName();
|
||||||
$parentScope = $scope->getParentName();
|
$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) {
|
if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
|
||||||
throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
|
throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
|
||||||
}
|
}
|
||||||
|
@ -518,9 +541,15 @@ class Container implements IntrospectableContainerInterface
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function hasScope($name)
|
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]);
|
return isset($this->scopes[$name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,9 +563,13 @@ class Container implements IntrospectableContainerInterface
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function isScopeActive($name)
|
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]);
|
return isset($this->scopedServices[$name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -358,9 +358,15 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||||
* @return array An array of scopes
|
* @return array An array of scopes
|
||||||
*
|
*
|
||||||
* @api
|
* @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;
|
return $this->scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,15 +376,23 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||||
* @return array An array of scope children.
|
* @return array An array of scope children.
|
||||||
*
|
*
|
||||||
* @api
|
* @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;
|
return $this->scopeChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a service.
|
* 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 string $id The service identifier
|
||||||
* @param object $service The service instance
|
* @param object $service The service instance
|
||||||
* @param string $scope The scope
|
* @param string $scope The scope
|
||||||
|
@ -1126,7 +1140,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||||
*/
|
*/
|
||||||
private function shareService(Definition $definition, $service, $id)
|
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])) {
|
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
|
||||||
throw new InactiveScopeException($id, $scope);
|
throw new InactiveScopeException($id, $scope);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ interface ContainerInterface
|
||||||
/**
|
/**
|
||||||
* Sets a service.
|
* 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 string $id The service identifier
|
||||||
* @param object $service The service instance
|
* @param object $service The service instance
|
||||||
* @param string $scope The scope of the service
|
* @param string $scope The scope of the service
|
||||||
|
@ -110,6 +112,8 @@ interface ContainerInterface
|
||||||
* @param string $name
|
* @param string $name
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function enterScope($name);
|
public function enterScope($name);
|
||||||
|
|
||||||
|
@ -119,6 +123,8 @@ interface ContainerInterface
|
||||||
* @param string $name
|
* @param string $name
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function leaveScope($name);
|
public function leaveScope($name);
|
||||||
|
|
||||||
|
@ -128,6 +134,8 @@ interface ContainerInterface
|
||||||
* @param ScopeInterface $scope
|
* @param ScopeInterface $scope
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function addScope(ScopeInterface $scope);
|
public function addScope(ScopeInterface $scope);
|
||||||
|
|
||||||
|
@ -139,6 +147,8 @@ interface ContainerInterface
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function hasScope($name);
|
public function hasScope($name);
|
||||||
|
|
||||||
|
@ -152,6 +162,8 @@ interface ContainerInterface
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
public function isScopeActive($name);
|
public function isScopeActive($name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ class Definition
|
||||||
private $class;
|
private $class;
|
||||||
private $file;
|
private $file;
|
||||||
private $factory;
|
private $factory;
|
||||||
|
private $shared = true;
|
||||||
private $scope = ContainerInterface::SCOPE_CONTAINER;
|
private $scope = ContainerInterface::SCOPE_CONTAINER;
|
||||||
private $properties = array();
|
private $properties = array();
|
||||||
private $calls = array();
|
private $calls = array();
|
||||||
|
@ -484,6 +485,34 @@ class Definition
|
||||||
return $this->file;
|
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.
|
* Sets the scope of the service.
|
||||||
*
|
*
|
||||||
|
@ -492,9 +521,19 @@ class Definition
|
||||||
* @return Definition The current instance
|
* @return Definition The current instance
|
||||||
*
|
*
|
||||||
* @api
|
* @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;
|
$this->scope = $scope;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -506,9 +545,15 @@ class Definition
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
* @api
|
* @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;
|
return $this->scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,16 @@ class DefinitionDecorator extends Definition
|
||||||
return parent::setLazy($boolean);
|
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.
|
* Gets an argument to pass to the service constructor/factory method.
|
||||||
*
|
*
|
||||||
|
|
|
@ -173,7 +173,7 @@ class GraphvizDumper extends Dumper
|
||||||
} catch (ParameterNotFoundException $e) {
|
} 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'));
|
$container->setDefinition($id, new Definition('stdClass'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ class GraphvizDumper extends Dumper
|
||||||
$container->setDefinitions($this->container->getDefinitions());
|
$container->setDefinitions($this->container->getDefinitions());
|
||||||
$container->setAliases($this->container->getAliases());
|
$container->setAliases($this->container->getAliases());
|
||||||
$container->setResources($this->container->getResources());
|
$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));
|
$container->addScope(new Scope($scope, $parentScope));
|
||||||
}
|
}
|
||||||
foreach ($this->container->getExtensions() as $extension) {
|
foreach ($this->container->getExtensions() as $extension) {
|
||||||
|
|
|
@ -377,9 +377,9 @@ class PhpDumper extends Dumper
|
||||||
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
|
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
|
||||||
$instantiation = '';
|
$instantiation = '';
|
||||||
|
|
||||||
if (!$isProxyCandidate && ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
|
if (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) {
|
||||||
$instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance');
|
$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');
|
$instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance');
|
||||||
} elseif (!$simple) {
|
} elseif (!$simple) {
|
||||||
$instantiation = '$instance';
|
$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 (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) {
|
||||||
if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
|
if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
|
||||||
$return[] = '';
|
$return[] = '';
|
||||||
|
@ -580,7 +580,7 @@ class PhpDumper extends Dumper
|
||||||
$return = implode("\n * ", $return);
|
$return = implode("\n * ", $return);
|
||||||
|
|
||||||
$doc = '';
|
$doc = '';
|
||||||
if (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
|
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
|
||||||
$doc .= <<<EOF
|
$doc .= <<<EOF
|
||||||
|
|
||||||
*
|
*
|
||||||
|
@ -832,10 +832,10 @@ EOF;
|
||||||
|
|
||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
if (count($scopes = $this->container->getScopes()) > 0) {
|
if (count($scopes = $this->container->getScopes(false)) > 0) {
|
||||||
$code .= "\n";
|
$code .= "\n";
|
||||||
$code .= " \$this->scopes = ".$this->dumpValue($scopes).";\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();
|
$code .= $this->addMethodMap();
|
||||||
|
@ -879,9 +879,9 @@ EOF;
|
||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
$code .= "\n";
|
$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->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 {
|
} else {
|
||||||
$code .= " \$this->scopes = array();\n";
|
$code .= " \$this->scopes = array();\n";
|
||||||
$code .= " \$this->scopeChildren = array();\n";
|
$code .= " \$this->scopeChildren = array();\n";
|
||||||
|
@ -1273,11 +1273,6 @@ EOF;
|
||||||
foreach ($value->getArguments() as $argument) {
|
foreach ($value->getArguments() as $argument) {
|
||||||
$arguments[] = $this->dumpValue($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()) {
|
if (null !== $value->getFactory()) {
|
||||||
$factory = $value->getFactory();
|
$factory = $value->getFactory();
|
||||||
|
@ -1303,7 +1298,16 @@ EOF;
|
||||||
throw new RuntimeException('Cannot dump definition because of invalid factory');
|
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) {
|
} elseif ($value instanceof Variable) {
|
||||||
return '$'.$value;
|
return '$'.$value;
|
||||||
} elseif ($value instanceof Reference) {
|
} elseif ($value instanceof Reference) {
|
||||||
|
|
|
@ -117,7 +117,10 @@ class XmlDumper extends Dumper
|
||||||
if ($definition->getClass()) {
|
if ($definition->getClass()) {
|
||||||
$service->setAttribute('class', $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);
|
$service->setAttribute('scope', $scope);
|
||||||
}
|
}
|
||||||
if (!$definition->isPublic()) {
|
if (!$definition->isPublic()) {
|
||||||
|
@ -271,7 +274,7 @@ class XmlDumper extends Dumper
|
||||||
} elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
|
} elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
|
||||||
$element->setAttribute('on-invalid', 'ignore');
|
$element->setAttribute('on-invalid', 'ignore');
|
||||||
}
|
}
|
||||||
if (!$value->isStrict()) {
|
if (!$value->isStrict(false)) {
|
||||||
$element->setAttribute('strict', 'false');
|
$element->setAttribute('strict', 'false');
|
||||||
}
|
}
|
||||||
} elseif ($value instanceof Definition) {
|
} 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));
|
$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);
|
$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
|
* @param callable $callable
|
||||||
*
|
*
|
||||||
|
|
|
@ -148,11 +148,8 @@ class XmlFileLoader extends FileLoader
|
||||||
$definition = new Definition();
|
$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 ($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);
|
$method = 'set'.str_replace('-', '', $key);
|
||||||
$definition->$method(XmlUtils::phpize($value));
|
$definition->$method(XmlUtils::phpize($value));
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,8 +163,15 @@ class YamlFileLoader extends FileLoader
|
||||||
$definition->setClass($service['class']);
|
$definition->setClass($service['class']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($service['shared'])) {
|
||||||
|
$definition->setShared($service['shared']);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($service['scope'])) {
|
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'])) {
|
if (isset($service['synthetic'])) {
|
||||||
|
|
|
@ -87,6 +87,7 @@
|
||||||
</xsd:choice>
|
</xsd:choice>
|
||||||
<xsd:attribute name="id" type="xsd:string" />
|
<xsd:attribute name="id" type="xsd:string" />
|
||||||
<xsd:attribute name="class" 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="scope" type="xsd:string" />
|
||||||
<xsd:attribute name="public" type="boolean" />
|
<xsd:attribute name="public" type="boolean" />
|
||||||
<xsd:attribute name="synthetic" type="boolean" />
|
<xsd:attribute name="synthetic" type="boolean" />
|
||||||
|
|
|
@ -27,6 +27,8 @@ class Reference
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* 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 string $id The service identifier
|
||||||
* @param int $invalidBehavior The behavior when the service does not exist
|
* @param int $invalidBehavior The behavior when the service does not exist
|
||||||
* @param bool $strict Sets how this reference is validated
|
* @param bool $strict Sets how this reference is validated
|
||||||
|
@ -64,9 +66,15 @@ class Reference
|
||||||
* Returns true when this Reference is strict.
|
* Returns true when this Reference is strict.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @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;
|
return $this->strict;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ namespace Symfony\Component\DependencyInjection;
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
class Scope implements ScopeInterface
|
class Scope implements ScopeInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,8 @@ namespace Symfony\Component\DependencyInjection;
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.8, to be removed in 3.0.
|
||||||
*/
|
*/
|
||||||
interface ScopeInterface
|
interface ScopeInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,7 @@ class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testProcessDetectsSyntheticPrototypeDefinitions()
|
public function testProcessDetectsSyntheticPrototypeDefinitions()
|
||||||
{
|
{
|
||||||
|
@ -39,6 +40,18 @@ class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->process($container);
|
$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
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testProcessIgnoresScopeWideningIfNonStrictReference()
|
public function testProcessIgnoresScopeWideningIfNonStrictReference()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -30,6 +33,7 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \RuntimeException
|
* @expectedException \RuntimeException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testProcessDetectsScopeWidening()
|
public function testProcessDetectsScopeWidening()
|
||||||
{
|
{
|
||||||
|
@ -40,6 +44,9 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->process($container);
|
$this->process($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testProcessIgnoresCrossScopeHierarchyReferenceIfNotStrict()
|
public function testProcessIgnoresCrossScopeHierarchyReferenceIfNotStrict()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -54,6 +61,7 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \RuntimeException
|
* @expectedException \RuntimeException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testProcessDetectsCrossScopeHierarchyReference()
|
public function testProcessDetectsCrossScopeHierarchyReference()
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,29 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]);
|
$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()
|
public function testProcessDoesNotInlineWhenAliasedServiceIsNotOfPrototypeScope()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -61,6 +84,38 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertSame($ref, $arguments[0]);
|
$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()
|
public function testProcessDoesInlineServiceOfPrototypeScope()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -188,6 +243,9 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertSame($ref, $args[0]);
|
$this->assertSame($ref, $args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testProcessInlinesOnlyIfSameScope()
|
public function testProcessInlinesOnlyIfSameScope()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
|
|
@ -79,6 +79,9 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertFalse($def->isAbstract());
|
$this->assertFalse($def->isAbstract());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testProcessDoesNotCopyScope()
|
public function testProcessDoesNotCopyScope()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -117,6 +120,25 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals(array(), $def->getTags());
|
$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()
|
public function testProcessHandlesMultipleInheritance()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -173,6 +195,55 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertTrue($container->getDefinition('child1')->isLazy());
|
$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)
|
protected function process(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$pass = new ResolveDefinitionTemplatesPass();
|
$pass = new ResolveDefinitionTemplatesPass();
|
||||||
|
|
|
@ -61,6 +61,9 @@ class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals(array(), $def->getProperties());
|
$this->assertEquals(array(), $def->getProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testStrictFlagIsPreserved()
|
public function testStrictFlagIsPreserved()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$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');
|
$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');
|
$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
|
* @covers \Symfony\Component\DependencyInjection\ContainerBuilder::get
|
||||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||||
|
@ -143,6 +154,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
|
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testGetReturnsNullOnInactiveScope()
|
public function testGetReturnsNullOnInactiveScope()
|
||||||
{
|
{
|
||||||
|
@ -154,6 +166,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
|
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testGetReturnsNullOnInactiveScopeWhenServiceIsCreatedByAMethod()
|
public function testGetReturnsNullOnInactiveScopeWhenServiceIsCreatedByAMethod()
|
||||||
{
|
{
|
||||||
|
|
|
@ -171,6 +171,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \InvalidArgumentException
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testSetDoesNotAllowPrototypeScope()
|
public function testSetDoesNotAllowPrototypeScope()
|
||||||
{
|
{
|
||||||
|
@ -180,6 +181,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \RuntimeException
|
* @expectedException \RuntimeException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testSetDoesNotAllowInactiveScope()
|
public function testSetDoesNotAllowInactiveScope()
|
||||||
{
|
{
|
||||||
|
@ -188,6 +190,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$c->set('foo', new \stdClass(), 'foo');
|
$c->set('foo', new \stdClass(), 'foo');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testSetAlsoSetsScopedService()
|
public function testSetAlsoSetsScopedService()
|
||||||
{
|
{
|
||||||
$c = new Container();
|
$c = new Container();
|
||||||
|
@ -264,6 +269,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers Symfony\Component\DependencyInjection\Container::get
|
* @covers Symfony\Component\DependencyInjection\Container::get
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testGetReturnsNullOnInactiveScope()
|
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');
|
$this->assertTrue($sc->initialized('alias'), '->initialized() returns true for alias if aliased service is initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testEnterLeaveCurrentScope()
|
public function testEnterLeaveCurrentScope()
|
||||||
{
|
{
|
||||||
$container = new ProjectServiceContainer();
|
$container = new ProjectServiceContainer();
|
||||||
|
@ -327,6 +336,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertSame($scopedFoo1, $scopedFoo3);
|
$this->assertSame($scopedFoo1, $scopedFoo3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testEnterLeaveScopeWithChildScopes()
|
public function testEnterLeaveScopeWithChildScopes()
|
||||||
{
|
{
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
|
@ -357,6 +369,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertFalse($container->has('a'));
|
$this->assertFalse($container->has('a'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testEnterScopeRecursivelyWithInactiveChildScopes()
|
public function testEnterScopeRecursivelyWithInactiveChildScopes()
|
||||||
{
|
{
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
|
@ -398,6 +413,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertTrue($container->has('a'));
|
$this->assertTrue($container->has('a'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testEnterChildScopeRecursively()
|
public function testEnterChildScopeRecursively()
|
||||||
{
|
{
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
|
@ -435,6 +453,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \InvalidArgumentException
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testEnterScopeNotAdded()
|
public function testEnterScopeNotAdded()
|
||||||
{
|
{
|
||||||
|
@ -444,6 +463,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \RuntimeException
|
* @expectedException \RuntimeException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testEnterScopeDoesNotAllowInactiveParentScope()
|
public function testEnterScopeDoesNotAllowInactiveParentScope()
|
||||||
{
|
{
|
||||||
|
@ -453,6 +473,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$container->enterScope('bar');
|
$container->enterScope('bar');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testLeaveScopeNotActive()
|
public function testLeaveScopeNotActive()
|
||||||
{
|
{
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
|
@ -477,7 +500,8 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \InvalidArgumentException
|
* @expectedException \InvalidArgumentException
|
||||||
* @dataProvider getBuiltInScopes
|
* @dataProvider getLegacyBuiltInScopes
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testAddScopeDoesNotAllowBuiltInScopes($scope)
|
public function testAddScopeDoesNotAllowBuiltInScopes($scope)
|
||||||
{
|
{
|
||||||
|
@ -487,6 +511,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \InvalidArgumentException
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testAddScopeDoesNotAllowExistingScope()
|
public function testAddScopeDoesNotAllowExistingScope()
|
||||||
{
|
{
|
||||||
|
@ -497,7 +522,8 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \InvalidArgumentException
|
* @expectedException \InvalidArgumentException
|
||||||
* @dataProvider getInvalidParentScopes
|
* @dataProvider getLegacyInvalidParentScopes
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testAddScopeDoesNotAllowInvalidParentScope($scope)
|
public function testAddScopeDoesNotAllowInvalidParentScope($scope)
|
||||||
{
|
{
|
||||||
|
@ -505,6 +531,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$c->addScope(new Scope('foo', $scope));
|
$c->addScope(new Scope('foo', $scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testAddScope()
|
public function testAddScope()
|
||||||
{
|
{
|
||||||
$c = new Container();
|
$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'));
|
$this->assertSame(array('foo' => array('bar', 'baz'), 'bar' => array('baz'), 'baz' => array()), $this->getField($c, 'scopeChildren'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testHasScope()
|
public function testHasScope()
|
||||||
{
|
{
|
||||||
$c = new Container();
|
$c = new Container();
|
||||||
|
@ -568,6 +600,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
|
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testIsScopeActive()
|
public function testIsScopeActive()
|
||||||
{
|
{
|
||||||
$c = new Container();
|
$c = new Container();
|
||||||
|
@ -584,7 +619,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertFalse($c->isScopeActive('foo'));
|
$this->assertFalse($c->isScopeActive('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInvalidParentScopes()
|
public function getLegacyInvalidParentScopes()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
array(ContainerInterface::SCOPE_PROTOTYPE),
|
array(ContainerInterface::SCOPE_PROTOTYPE),
|
||||||
|
@ -592,7 +627,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBuiltInScopes()
|
public function getLegacyBuiltInScopes()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
array(ContainerInterface::SCOPE_CONTAINER),
|
array(ContainerInterface::SCOPE_CONTAINER),
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue