* form: (291 commits)
[FrameworkBundle] updated method call
[Form] Removing excess option in the TimezoneType
[FrameworkBundle] Adding check for invalid form type for better exception message
[TwigBundle] Removing dbug text in form template
[Form] Removed obsolete code in TextType
[Form] fixed translations escaping
[Form] Adding a check that the choice_list option on the ChoiceType implements the ChoiceListInterface.
[Form] added support for groups in form validation (when using array data)
[Form] fixed error bubbling for choices when expanded is true
[Form] added a unit test
[Form] Removed obsolete view variables
[Form] Renamed ChoiceUtil to FormUtil and gave its methods more general names
[Form] Changed separator for Twig blocks from double underscore to single underscore to match the PHP template separator
[Form] Removed StripTagsListenerTest
[Form] Removed StripTagsListener. Its implementation is insufficient and needs to be replaced by a better one.
[Form] added a way to specify the form constraint when building the form (useful if you work with arrays instead of objects)
[Form] Added test for 'email' type and fixed a few bugs
[Form] Removed obsolete constraints from validation.xml
Revert "[Form] removed validation.xml file (not used anymore)"
Added html5 email input to the forms
...
* schmittjoh/referenceValidation:
[DependencyInjection] also check references of inlined services
[DependencyInjection] adds emulation of "exception-on-invalid-reference" behavior
* kriswallsmith/dic/method-renames:
added method renames to UPDATE
[DependencyInjection] renamed ContainerBuilder::remove() as removeDefinition() to be more consistent with other definition-related methods
[DependencyInjection] renamed Definition::setArgument() as replaceArgument() to be more specific
The _scheme requirement can be used to force routes to always match one given scheme
and to always be generated with the given scheme.
So, if _scheme is set to https, URL generation will force an absolute URL if the
current scheme is http. And if you request the URL with http, you will be redirected
to the https URL.
[Form] Fixed {get,set,has}Var references in templating php
[Form] Added getVars to FormView to ease usage in Twig. Also added some phpdoc and cleaned up the get method by adding a default value
[Form] Fix
[Form] Delete file generated by test
Based on dfb93b1bcebf1f34d3a880d00f36acb2bcca0f08:
[FORM] Fixed DateField Month Choices
The month choices were calculated using the current day of the month with
gmmktime rather than the 1st of the month. Additionally, this provides a
UTC timestamp which is passed to the formatter (IntlDateFormatter) which
converts the timestamp using the current timezone. This means that the UTC
timestamp for 1st March was being converted for my timezone (EST) and giving
a date of 28th February, leading to Feb appearing again in the popup form
instead of Mar.
* hason/logicalname:
[Templating] changed __toString method (synonym for getLogicalName method)
[Templating] fixed phpdoc a test
[FrameworkBundle] added getLogicalName() method to TemplateReference
[Templating] added method to return the template logical name, added test
* weaverryan/better_import_exception_and_bug_fix:
[Config] Improving the exception when a resource cannot be imported
[DependencyInjection] Fixing a bug where "ignore_errors" doesn't work in YAML and XML
Depending on the order of execution of Config\Definition\Builder tests (due to filesystem ordering), namespace conflicts can occur between real classes and fixtures loaded by the TreeBuilderTest.
* kriswallsmith/kernel/shorter-bundle-names:
updated codebase to use shorter bundle names
[HttpKernel] updated component to work with shorter bundle names
[HttpKernel] updated Bundle::getName() to validate bundle class name and rtrim "Bundle"
Controllers:
"BlogBundle:Post:show" is now "Blog:Post:show"
Templates:
"BlogBundle:Post:show.html.twig" is now "Blog:Post:show.html.twig"
Resources:
"@BlogBundle/Resources/config/blog.xml" is now "@Blog/Resources/config/blog.xml"
Doctrine:
"$em->find('BlogBundle:Post', $id)" is now "$em->find('Blog:Post', $id)"
The problem was that "data_class" was used in two places: FormBuilder::build() and PropertyPathMapper.
PropertyPathMapper was already constructed during FormType::buildForm(), so any data class changes made to the FormBuilder wouldn't affect the data class of the PropertyPathMapper anymore and so lead to an inconsistent state.
* kriswallsmith/framework/protocol-relative-base-urls:
[Templating] updated assets helper to leave protocol-relative URLs untouched
[FrameworkBundle] cleaned up test class
* l3l0/routing-tests:
[Routing] added tearDown with cleanup the file system tmp directory
[Routing] moved clean up the directory from tearDown to setUp. Removed setUpBeforeClass method
[Routing] modified place when we store temporary file
[Routing] modified unit test for PhpGeneratorDumper class
[Routing] add unit test for PhpGeneratorDumper class
[Routing] added more tests for UrlGenerator class
* subsven/master:
re-add filename based directory filter to the AnnotationDirectoryLoader, now restricting to *.php files and therefore disregarding e.g. SVN metadata files
revert adding filename based filter to the directory resource
Eleminate the need to manually clear the cache if a new controller file containing routing annotations is added - part II * add unit tests * introduce filename filter to DirectoryResource (to restrict change monitoring to a subset of files) * modify AnnotationDirectoryLoader.php to use filename filter set on Controller\.php$
* add unit tests
* introduce filename filter to DirectoryResource (to restrict change monitoring to a subset of files)
* modify AnnotationDirectoryLoader.php to use filename filter set on Controller\.php$
* vicb/cfg_rebase:
[Config] Ability to add and override node types without having to subclass NodeBuilder
[DoctrineBundle] Fix some typos
[SwiftMailerBundle] Fix a merge issue in the configuration
Tweak PHPDocs in the extension configuration files
[Config] Component refactoring
* The array returned by getListeners() now removes the listener hash as the key (as this is an implementation detail)
* The sort method now guarantees that a listener registered before another will stay in the same order even for the same priority (for BC)
* Made various optimizations
The onCore* events are fired at some pre-defined points during the
handling of a request. At this is more important than the fact
that you can change things from the event.
The Config component API have changed and the extension configuration files must be updated accordingly:
1. Array nodes must enclosed their children definition in ->children() ... ->end() calls:
Before:
$treeBuilder->root('zend', 'array')
->arrayNode('logger')
->scalarNode('priority')->defaultValue('INFO')->end()
->booleanNode('log_errors')->defaultFalse()->end()
->end();
After:
$treeBuilder->root('zend', 'array')
->children()
->arrayNode('logger')
->children()
->scalarNode('priority')->defaultValue('INFO')->end()
->booleanNode('log_errors')->defaultFalse()->end()
->end()
->end()
->end();
2. The 'builder' method (in NodeBuilder) has been dropped in favor of an 'append' method (in ArrayNodeDefinition)
Before:
$treeBuilder->root('doctrine', 'array')
->arrayNode('dbal')
->builder($this->getDbalConnectionsNode())
->end();
After:
$treeBuilder->root('doctrine', 'array')
->children()
->arrayNode('dbal')
->append($this->getDbalConnectionsNode())
->end()
->end();
3. The root of a TreeBuilder is now an NodeDefinition (and most probably an ArrayNodeDefinition):
Before:
$root = $treeBuilder->root('doctrine', 'array');
$this->addDbalSection($root);
public function addDbalSection(NodeBuilder $node)
{
...
}
After:
$root = $treeBuilder->root('doctrine', 'array');
$this->addDbalSection($root);
public function addDbalSection(ArrayNodeDefinition $node)
{
...
}
4. The NodeBuilder API has changed (this is seldom used):
Before:
$node = new NodeBuilder('connections', 'array');
After:
The recommended way is to use a tree builder:
$treeBuilder = new TreeBuilder();
$node = $treeBuilder->root('connections', 'array');
An other way would be:
$builder = new NodeBuilder();
$node = $builder->node('connections', 'array');
Some notes:
- Tree root nodes should most always be array nodes, so this as been made the default:
$treeBuilder->root('doctrine', 'array') is equivalent to $treeBuilder->root('doctrine')
- There could be more than one ->children() ... ->end() sections. This could help with the readability:
$treeBuilder->root('doctrine')
->children()
->scalarNode('default_connection')->end()
->end()
->fixXmlConfig('type')
->children()
->arrayNode('types')
....
->end()
->end()
* kriswallsmith/dic/false-circular-ref-fix:
[DependencyInjection] fixed false positive when detecting circular references if a service throws an exception during creation
* kriswallsmith/dic/lazy-replace-ext-params:
[DependencyInjection] added test for lazy param replacement
Removed replacement of parameter placeholders at load time since they're now replaced at compile time. Extensions should be written to expect parameter placeholders.
* opensky/hotfix/test_client:
[HttpKernel] added test for uri change
[HttpKernel] got rid of url transformation into uri, as parse_url doesn't work with uris
* Seldaek/file_field:
[HttpFoundation] Fixed test breaking on windows
[HttpFoundation] UploadedFile::getOriginalName is now overriding getName
[HttpFoundation] Minor optimization
[Form] Add exception for missing enctype attribute
* fixes a problem with security (/foo/bar and /foo///bar are not the same URL as far as security is concerned)
* this can still be done in your web server configuration or by adding a core.request listener
The only missing part is ContainerAwareEventManager::addEventSubscriberService(),
because I'm not sure how to find out the class name of a service in the DIC.
Also, inline documentation of this code needs to be finished once it is accepted.
* hhamon/cookie_path_fix:
[Security] renamed Cookie::isHttponly() to Cookie::isHttpOnly()
[HttpKernel] renamed Cookie::isHttponly() to Cookie::isHttpOnly()
[BrowserKit] renamed Cookie::isHttponly() to Cookie::isHttpOnly()
[HttpFoundation] fix cookie path default value to / and added some new unit tests to cover the class
* DuoSRX/code-coverage:
[HttpFoundation] Fixed a typo in response->setLastModified()
[HttpFoundation] Added some more tests on response
[HttpFoundation] Added some tests on Response
[HttpFoundation] Replace a duplicated test with a method in Response
Fixed code coverage generation when resources folder are deeper
* jakzal/FileLocatorTest:
[Config] Added missing tests to satisfy 100% test coverage of FileLocator. Made sure that every path returned with locate() is unique.
* digitalkaoz/httpkernel-debug:
[HttpKernel] added tests for debug stuff
[HttpKernel] reset handling if subject::handle throws an exception, otherwise it wouldnt be able to handle furthermore
* schmittjoh/security:
[Security] forward the entire access denied exception instead of only the message
[Security] changed defaults for MessageDigestEncoder
TICKET #9557: session isn't required when using http basic authentification mecanism for example
[Security] improved entropy to make collision attacks harder
[Security] added the 'key' attribute of RememberMeToken to serialized string to be stored in session
Fix the Acl schema generator script.
Added support for the full range of escaped values in double quoted
strings in chapter 5 of the YAML 1.1 and 1.2 specs. The escaping
and unescaping strategies were factored out into separate classes to
keep the logic isolated.
Added examples from the spec to the unit tests for all escaped values.
* kriswallsmith/dic/auto-ext-load:
[HttpKernel] added an subclass merge extension configuration compiler pass to ensure each bundle's "main" extension is loaded
[DependencyInjection] extensions should only load if called during configuration
You can now modify set or bound data by adding a filter for either of the following events:
* Filters::filterBoundDataFromClient
* Filters::filterBoundData
* Filters::filterSetData
Instead, hidden fields now override the "row" template to not include a label or errors.
The "rest" (former "hidden") helper has been adapted to output any fields that were not
rendered manually. It should usually be called at the end of a form.
Fields are not available in the templates anymore. Instead, all required information can be
accessed through view variables.
Example usage of helpers and variables in a form theme:
// use the label helper
{{ this.label('my label') }}
// use the label variable
{{ this.vars.label }}
{{ label }}
Example usage of helpers and variables in a normal template:
// use the label helper
{{ field.label('my label') }}
// use the label variable
{{ field.vars.label }}
* schmittjoh/security:
[Security] added method to retrieve the configured remember-me parameter
[Security] Copy token attributes when auth providers create a new token from another
* cristiangsp/Translation_FallbackLocale:
[Translation] Modified Translation unit test "testTransWithFallbackLocale"
[Translation] Fixed the addition of the fallbackLocale catalogue to the current locale catalogue.
[Translation] Added search to FallbackLocale Catalogue.
Now the test shows the behavior when is requested a translation to an undefined locale catalogue and, therefore, the fallbacklocale catalogue must be queried. The original test function only checks the step to reach the language catalog not to the fallbacklocale one (even the fallbacklocale isn't set). This test gives error in the current version of symfony/symfony.
PreAuthenticatedAuthenticationProvider and UserAuthenticationProvider tend to copy a token instead of modifying it during their authenticate() methods, which is probably a good idea if the token might be immutable. Ensure that the token's attributes get copied along with everything else.
According to ResponseHeaderBag::computeCacheControlValue(), a response with an ETag but no explicit Cache-Control header should have a sensible Cache-Control of "private, must-revalidate" set. According to Response::isCacheable(), a response that includes a private Cache-Controls is not considered cacheable. Therefore, in order for this test response to be cacheable and stored, it requires an explicit Cache-Control of public.
Without this patch, if you call __toString() on a Response,
the content-type auto-detection would never be trigerred
as __toString() changes the default content-type.
I had thought that this was unnecessary - when would you ever want to just let "extra" options fail silently?
But, the SecurityExtension takes advantage of this by creating two separate config trees. The first tree looks for just one particular value on the configuration array and ignores the rest. So, there *is* a use-case for allowing all extra fields to simply be ignored, though this should not be the norm.
We decided that this is not necessary and that it's leaving too many things wide open. Instead, in these cases where we have an array with unknown items, a prototype should be used.
Further functionality will need to be added later to allow you to specify a few nodes that you *do* know about under an array and then also specify a prototype to catch everything else.
This is *usually* what you want (and is defaulted this way). If you have an entry in an array *just* so it can become the key to that entry later, then you shouldn't normally still need it in the resulting array.
The importance of this comes in with validation. Since we're throwing an exception if you have any unrecognized options, the presence of the "key" field in the resulting array will cause issues when it's not needed.
This commit breaks functional tests in Symfony\Component\HttpKernel\HttpCache\HttpCacheTest.php. I tried to fix functional tests but I didn\'t manage to. For your information, the "try { } catch" block in the HttpKernel\HttpCache::lookup() method seems strange because I suspect line 274 to never leverage any exception...
How to upgrade?
For XML configuration files:
* All extensions should now use the config tag (this is just a convention as
the YAML configurations files do not use it anymore):
* The previous change means that the doctrine and security bundles now are
wrapped under a main "config" tag:
<doctrine:config>
<doctrine:orm />
<doctrine:dbal />
</doctrine:config>
<security:config>
<security:acl />
...
</security:config>
For YAML configuration files:
* The main keys have been renamed as follows:
* assetic:config -> assetic
* app:config -> framework
* webprofiler:config -> web_profiler
* doctrine_odm.mongodb -> doctrine_mongo_db
* doctrine:orm -> doctrine: { orm: ... }
* doctrine:dbal -> doctrine: { dbal: ... }
* security:config -> security
* security:acl -> security: { acl: ... }
* twig.config -> twig
* zend.config -> zend
This reverts commit f53080860a.
Revert "[Router] config fixes"
This reverts commit 51beecc6f2.
Revert "moved duplicated files to a new Config component"
This reverts commit a8ec9b27f0.
Rules are :
- If one of the ESI has validation cache strategy, the whole page will be
forced to validate.
- In none of the ESI has validation, the response will feature a Cache-Control
directive with s-maxage value equals to the smallest TTL of ESIs.
The merging is done in three steps:
1. Normalization:
=================
All passed config arrays will be transformed into the same structure
regardless of what format they come from.
2. Merging:
===========
This is the step when the actual merging is performed. Starting at the root
the configs will be passed along the tree until a node has no children, or
the merging of sub-paths of the current node has been specifically disabled.
Left-Side Right-Side Merge Result
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-nothing- array Right-Side will be taken.
scalar scalar Right-Side will be taken.
array false Right-Side will be taken if ->canBeUnset()
was called on the array node.
false array Right-Side will be taken.
array array Each value in the array will be passed to
the specific child node, or the prototype
node (whatever is present).
3. Finalization:
================
The normalized, and merged config will be passed through the config tree to
perform final validation on the submitted values, and set default values
where this has been requested.
You can influence this process in various ways, here is a list with some examples.
All of these methods must be called on the node on which they should be applied.
* isRequired(): Node must be present in at least one config file.
* requiresAtLeastOneElement(): PrototypeNode must have at least one element.
* treatNullLike($value): Replaces null with $value during normalization.
* treatTrueLike($value): Same as above just for true
* treatFalseLike($value): Same as above just for false
* defaultValue($value): Sets a default value for this node (only for scalars)
* addDefaultsIfNotSet(): Whether to add default values of an array which has not
been defined in any configuration file.
* disallowNewKeysInSubsequentConfigs(): All keys for this array must be defined
in one configuration file, subsequent
configurations may only overwrite these.
* fixXmlConfig($key, $plural = null): Transforms XML config into same structure
as YAML, and PHP configurations.
* useAttributeAsKey($name): Defines which XML attribute to use as array key.
* cannotBeOverwritten(): Declares a certain sub-path as non-overwritable. All
configuration for this path must be defined in the same
configuration file.
* cannotBeEmpty(): If value is set, it must be non-empty.
* canBeUnset(): If array values should be unset if false is specified.
Architecture:
=============
The configuration consists basically out of two different sets of classes.
1. Builder classes: These classes provide the fluent interface and
are used to construct the config tree.
2. Node classes: These classes contain the actual logic for normalization,
merging, and finalizing configurations.
After you have added all the metadata to your builders, the call to
->buildTree() will convert this metadata to actual node classes. Most of the
time, you will not have to interact with the config nodes directly, but will
delegate this to the Processor class which will call the respective methods
on the config node classes.
This commit removes CollectionToStringTransformer. Transformers should never change the state of the outside world, otherwise hard-to-track bugs might creap in.
This functionality needs to be implemented as a custom FieldType (see EntityChoiceField).
The implication is that set<Reference>() in the object of the parent form will not be called (and thus not has to be implemented/public).
If you want to suppress this behaviour, manually set "by_reference" to false.
Previously, the Definition class was used both for type inference and factory construction (if factoryService was absent). This is fine for cases where classes create instances of themselves (e.g. getInstance() or create()), but leads to ambiguity when we have a separate factory class.
Separated validation of data and form had serious drawbacks. When a form had nested form whose data was not connected to the data of the root form, this data would not be validated.
The new implementation validates the whole object graph at once. Class Form has a new method validateData(), that manually passes the data to the GraphWalker of the Validator and overrides the Default group with the groups set in the form.
This is mainly intended for complex configurations to ease the work you
have with normalizing different configuration formats (YAML, XML, and PHP).
First, you have to set-up a config tree:
$treeBuilder = new TreeBuilder();
$tree = $treeBuilder
->root('security_config', 'array')
->node('access_denied_url', 'scalar')->end()
->normalize('encoder')
->node('encoders', 'array')
->key('class')
->prototype('array')
->before()->ifString()->then(function($v) { return array('algorithm' => $v); })->end()
->node('algorithm', 'scalar')->end()
->node('encode_as_base64', 'scalar')->end()
->node('iterations', 'scalar')->end()
->end()
->end()
->end()
->buildTree()
;
This tree and the metadata attached to the different nodes is then used
to intelligently transform the passed config array:
$normalizedConfig = $tree->normalize($config);
With the form factory there was no reasonable way to implement instantiation of custom form classes. So the implementation was changed to let the classes instantiate themselves. A FormContext instance with default settings has to be passed to the creation method. This context is by default configured in the DI container.
$context = $this->get('form.context');
// or
$context = FormContext::buildDefault();
$form = MyFormClass::create($context, 'author');
If you want to circumvent this process, you can also create a form manually. Remember that the services stored in the default context won't be available then unless you pass them explicitely.
$form = new MyFormClass('author');
A form now always has to be bound, independent of whether the request is a POST request or not. The bind() method detects itself whether the request was a post request or not and reads its data accordingly. The "old" bind()/isBound() methods were renamed to submit()/isSubmitted().
$form = new Form('author');
$form->bind($request, $author);
if ($form->isValid()) {
// isValid() implies isSubmitted(), non-submitted forms can
// never be valid
// do something with author now
}
Alternatively, you can only bind global variables, if you don't have a request object.
$form->bindGlobals($author);
Note that the $author object is in both cases optional. You can also pass no object at all and read the data using $form->getData(), but then no validation will occur. You can also prefill the form with an object during instantiation.
$form = new Form('author', array('data' => $author));
$form->bind($request);
// etc.
The Request constructor no longer uses values from PHP's super globals. If you want a Request populated with these values you must use the new static method Request::fromGlobals().
Your front controllers (i.e. web/app.php, web/app_dev.php ...) will need to be updated:
// old
$kernel->handle(new Request())->send();
// new
$kernel->handle(Request::fromGlobals())->send();
The three notification methods do not return the Event instance anymore.
notify() does not return anything
notifyUntil() returns the returned value of the event that has processed the event
filter() returns the filtered value
Upgrading your listeners:
Listeners for notify() and filter() events: nothing to change
Listeners for notifyUntil() events:
Before:
$event->setReturnValue('foo');
return true;
After:
$event->setProcessed();
return 'foo';
If you notify events, the processing also need to be changed:
For filter() notifications: the filtered value is now available as
the returned value of the filter() method.
For notifyUntil() notifications:
Before:
$event = $dispatcher->notifyUntil($event);
if ($event->isProcessed()) {
$ret = $event->getReturnValue();
// do something with $ret
}
After:
$ret = $dispatcher->notifyUntil($event);
if ($event->isProcessed()) {
// do something with $ret
}
* Added empty_value option on CountryField, LanguageField, LocaleField, TimezoneField
* Added missing date_pattern to DateTimeField
* Made the currency option on MoneyField required.
* The register() method on all listeners has been removed
* Instead, the information is now put directly in the DIC tag
For instance, a listener on core.request had this method:
public function register(EventDispatcher $dispatcher, $priority = 0)
{
$dispatcher->connect('core.response', array($this, 'filter'), $priority);
}
And this tag in the DIC configuration:
<tag name="kernel.listener" />
Now, it only has the following configuration:
<tag name="kernel.listener" event="core.response" method="filter" priority="0" />
The event and method attributes are now mandatory.
Before I explain the changes, let's talk about the current state.
Before this patch, the registerBundleDirs() method returned an ordered (for
resource overloading) list of namespace prefixes and the path to their
location. Here are some problems with this approach:
* The paths set by this method and the paths configured for the autoloader
can be disconnected (leading to unexpected behaviors);
* A bundle outside these paths worked, but unexpected behavior can occur;
* Choosing a bundle namespace was limited to the registered namespace
prefixes, and their number should stay low enough (for performance reasons)
-- moreover the current Bundle\ and Application\ top namespaces does not
respect the standard rules for namespaces (first segment should be the
vendor name);
* Developers must understand the concept of "namespace prefixes" to
understand the overloading mechanism, which is one more thing to learn,
which is Symfony specific;
* Each time you want to get a resource that can be overloaded (a template for
instance), Symfony would have tried all namespace prefixes one after the
other until if finds a matching file. But that can be computed in advance
to reduce the overhead.
Another topic which was not really well addressed is how you can reference a
file/resource from a bundle (and take into account the possibility of
overloading). For instance, in the routing, you can import a file from a
bundle like this:
<import resource="FrameworkBundle/Resources/config/internal.xml" />
Again, this works only because we have a limited number of possible namespace
prefixes.
This patch addresses these problems and some more.
First, the registerBundleDirs() method has been removed. It means that you are
now free to use any namespace for your bundles. No need to have specific
prefixes anymore. You are also free to store them anywhere, in as many
directories as you want. You just need to be sure that they are autoloaded
correctly.
The bundle "name" is now always the short name of the bundle class (like
FrameworkBundle or SensioCasBundle). As the best practice is to prefix the
bundle name with the vendor name, it's up to the vendor to ensure that each
bundle name is unique. I insist that a bundle name must be unique. This was
the opposite before as two bundles with the same name was how Symfony2 found
inheritance.
A new getParent() method has been added to BundleInterface. It returns the
bundle name that the bundle overrides (this is optional of course). That way,
there is no ordering problem anymore as the inheritance tree is explicitely
defined by the bundle themselves.
So, with this system, we can easily have an inheritance tree like the
following:
FooBundle < MyFooBundle < MyCustomFooBundle
MyCustomFooBundle returns MyFooBundle for the getParent() method, and
MyFooBundle returns FooBundle.
If two bundles override the same bundle, an exception is thrown.
Based on the bundle name, you can now reference any resource with this
notation:
@FooBundle/Resources/config/routing.xml
@FooBundle/Controller/FooController.php
This notation is the input of the Kernel::locateResource() method, which
returns the location of the file (and of course it takes into account
overloading).
So, in the routing, you can now use the following:
<import resource="@FrameworkBundle/Resources/config/internal.xml" />
The template loading mechanism also use this method under the hood.
As a bonus, all the code that converts from internal notations to file names
(controller names: ControllerNameParser, template names: TemplateNameParser,
resource paths, ...) is now contained in several well-defined classes. The
same goes for the code that look for templates (TemplateLocator), routing
files (FileLocator), ...
As a side note, it is really easy to also support multiple-inheritance for a
bundle (for instance if a bundle returns an array of bundle names it extends).
However, this is not implemented in this patch as I'm not sure we want to
support that.
How to upgrade:
* Each bundle must now implement two new mandatory methods: getPath() and
getNamespace(), and optionally the getParent() method if the bundle extends
another one. Here is a common implementation for these methods:
/**
* {@inheritdoc}
*/
public function getParent()
{
return 'MyFrameworkBundle';
}
/**
* {@inheritdoc}
*/
public function getNamespace()
{
return __NAMESPACE__;
}
/**
* {@inheritdoc}
*/
public function getPath()
{
return strtr(__DIR__, '\\', '/');
}
* The registerBundleDirs() can be removed from your Kernel class;
* If your code relies on getBundleDirs() or the kernel.bundle_dirs parameter,
it should be upgraded to use the new interface (see Doctrine commands for
many example of such a change);
* When referencing a bundle, you must now always use its name (no more \ or /
in bundle names) -- this transition was already done for most things
before, and now applies to the routing as well;
* Imports in routing files must be changed:
Before: <import resource="Sensio/CasBundle/Resources/config/internal.xml" />
After: <import resource="@SensioCasBundle/Resources/config/internal.xml" />
Now that we have a compilation phase for the DIC, using tags after compilation
is not needed anymore.
Tags were introduced to allow several independant bundles to be able to
interact which each others (remember that each extension knows nothing about
the others).
But during the compilation phase, the container has been merged ans so, all
the information from all bundles are available. This is then the right place
to deal with tags. That way, less work is needed at runtime and the DIC class
in the cache is also much smaller.
For simple cases, it means that you need to process the tag in a compiler pass
and store the information you need in a DIC parameter (have a look at the
TranslatorPass for a very simple example).
So, the PHP dumper does not add tags to the dumped PHP class anymore (it does
not implements TaggedContainerInterface anymore). But tags are still available
on ContainerBuilder instances.
* better separation of concerns
* made TwigBundle independant of the PHP Engine from FrameworkBundle (WIP)
* removed one layer of abstraction in the Templating component (renderers)
* made it easier to create a new Engine for any templating library
* made engines lazy-loaded (PHP engine for instance is not started if you only use Twig)
* reduces memory footprint (if you only use one engine)
* reduces size of compiled classes.php cache file
* made the renderer argument of Storage ctor mandatory
* refactored the Engine class to avoid code duplication
* simplified the check for a template that extends another one but with a different renderer
- inline private services which are references multiple times, but where all references originate from the same definition
- bug fix for non-shared services which were considered shared within the scope in which they were inlined
The current `loadClass()` implementation tries to load a class from the first matching prefix then stops, producing false-negative results. This is especially evident in groups of related libraries, such as Doctrine:
Doctrine
Doctrine\Common
Doctrine\Common\DataFixtures
Doctrine\DBAL
Doctrine\DBAL\Migrations
Each of these libraries is submoduled into a different vendor directory. Depending on what order these libraries are added to a UniversalClassLoader instance, classes may or may not actually be loaded. This fix continues searching registered namespaces and prefixes if the first partial match is negative.
These helpers have been removed as they do not work as expected.
Among other things, the order is not the right one when using PHP
templates, and adding assets from an included template is not
possible when using Twig templates.
This should be replaced by integrating a third-party library that
manages assets: minification, compilation, packaging, ...
If the option is true, the password is never written into the input field's value. If it is false, it is only written into the input field's value after submitting a form with errors.
The default value for "always_empty" is true.
The semantics of property paths are now:
(1) if a property path is set, it is _always_ respected (relative to the object
of the parent field)
(2) if no property path is set, the object of the parent field is _always_ ignored
Fact (2) allows us to set data into fields that is updated independently of the parent
field (like CSRF tokens, subforms with different objects etc.)
What is missing now is support for subfields that pass the object of the parent field
through to their own subfields. This functionality would be needed for GoogleMapFields,
DateRangeFields etc., which are compositions of individual fields that update the
parent object of the FieldGroup.
There are several alternatives for the latter functionality that should be discussed
in a RFC.
Original explanation from pull request:
I'm Using symfony2 with URL Rewriting to 'hide' index.php.
On form authentication, symfony2 redirect to http://host:port/index.php/login_path instead of http://host:port/login_path. I do understand that, in my case, redirect is set into one of :
FormAuthenticationEntryPoint with getUriForPath()
FormAuthenticationListener with getUriForPath()
Security/Firewal/ExceptionListener with getUri()
This path modify getUri and getUriForPath to :
remove default port from URI
remove script name if not initially present
Currently, ambiguities only arise for PHP files, as PhpFileLoader and AnnotationFileLoader would both claim support. Future conflicts may occur if the XML, YAML, or PHP loaders were to receive Directory and Glob loaders (as annotations have).
Since the "type" parameter is optional, loader resolution will default to awarding resolution to the first loader to claim support. A previous hack in PhpFileLoader to avoid an AnnotationFileLoader conflict was removed, so that should be the only lost backwards compatibility with this patch. Unit tests were also created for the various loader classes, although only the supports() method is being tested.
This implementation was proposed on the symfony-dev mailing list in response to Fabien's RFC for custom loader notation: http://groups.google.com/group/symfony-devs/browse_thread/thread/3104c1a9e45799d2/20fbe393c1afe088
Previously, HttpKernel performed request-stashing. By moving this to the Kernel class, the request is now available immediately after the kernel becomes aware of it. If the kernel is allowed to boot lazily (during the first call to handle()), this also allows an actual master Request to be available during booting.
The old "request" service definition (with a bogus class name) can be replaced with a factory-aware definition that retrieves the request directly from the kernel.
The original HttpKernel class can be deleted, as it's request-stashing will be moved to the Kernel class. FrameworkBundle's list of compiled classes must also be modified to respect this change.
To keep language consistent, three methods were changed in InputOption:
* `InputOption::acceptParameter()` -> `InputOption::acceptValue()`
* `InputOption::isParameterRequired()` -> InputOption::isValueRequired()`
* `InputOption::isParameterOptional()` -> `InputOption::isValueOptional()`
The InputDefinition::asXml() method was also modified to update the `accept_value` and `is_value_required` attributes.
When an object has a "main" many relation with related "things" (objects,
parameters, ...), the method names are normalized:
* get()
* set()
* all()
* replace()
* remove()
* clear()
* isEmpty()
* add()
* register()
* count()
* keys()
The classes below follow this method naming convention:
* BrowserKit\CookieJar -> Cookie
* BrowserKit\History -> Request
* Console\Application -> Command
* Console\Application\Helper\HelperSet -> HelperInterface
* DependencyInjection\Container -> services
* DependencyInjection\ContainerBuilder -> services
* DependencyInjection\ParameterBag\ParameterBag -> parameters
* DependencyInjection\ParameterBag\FrozenParameterBag -> parameters
* DomCrawler\Form -> FormField
* EventDispatcher\Event -> parameters
* Form\FieldGroup -> Field
* HttpFoundation\HeaderBag -> headers
* HttpFoundation\ParameterBag -> parameters
* HttpFoundation\Session -> attributes
* HttpKernel\Profiler\Profiler -> DataCollectorInterface
* Routing\RouteCollection -> Route
* Security\Authentication\AuthenticationProviderManager -> AuthenticationProviderInterface
* Templating\Engine -> HelperInterface
* Translation\MessageCatalogue -> messages
The usage of these methods are only allowed when it is clear that there is a
main relation:
* a CookieJar has many Cookies;
* a Container has many services and many parameters (as services is the main
relation, we use the naming convention for this relation);
* a Console Input has many arguments and many options. There is no "main"
relation, and so the naming convention does not apply.
For many relations where the convention does not apply, the following methods
must be used instead (where XXX is the name of the related thing):
* get() -> getXXX()
* set() -> setXXX()
* all() -> getXXXs()
* replace() -> setXXXs()
* remove() -> removeXXX()
* clear() -> clearXXX()
* isEmpty() -> isEmptyXXX()
* add() -> addXXX()
* register() -> registerXXX()
* count() -> countXXX()
* keys()
* removed the __call() method in Container: it means that now, there is only
one way to get a service: via the get() method;
* removed the $shared variable in the dumped Container classes (we now use
the $services variable from the parent class directly -- this is where we
have a performance improvement);
* optimized the PHP Dumper output.
This is the case for instance when you pass a variable to a template like this:
new SafeDecorator($var);
and in the template, you pass it again to another embedded template:
$view->render('...', array('var' => $var);
The second time, $var will be escaped as the SafeDecorator wrapper will have been removed
by the escaper.
The PHP native cache limiter feature has been disabled as this is now managed
by the HeaderBag class directly instead (see below.)
The HeaderBag class uses the following rules to define a sensible and
convervative default value for the Response 'Cache-Control' header:
* If no cache header is defined ('Cache-Control', 'ETag', 'Last-Modified',
and 'Expires'), 'Cache-Control' is set to 'no-cache';
* If 'Cache-Control' is empty, its value is set to "private, max-age=0,
must-revalidate";
* But if at least one 'Cache-Control' directive is set, and no 'public' or
'private' directives have been explicitely added, Symfony2 adds the
'private' directive automatically (except when 's-maxage' is set.)
So, remember to explicitly add the 'public' directive to 'Cache-Control' when
you want shared caches to store your application resources:
// The Response is private by default
$response->setEtag($etag);
$response->setLastModified($date);
$response->setMaxAge(10);
// Change the Response to be public
$response->setPublic();
// Set cache settings in one call
$response->setCache(array(
'etag' => $etag,
'last_modified' => $date,
'max_age' => 10,
'public' => true,
));
The constraint "Valid" does not accept any options or groups anymore. As per
JSR303 1.0 final, section 3.5.1 "Object graph validation" (page 39),
properties annotated with valid should be cascaded independent of the current
group (i.e. always). Thus the group "*" is not necessary anymore and was
removed from the "Valid" constraint in the Form validation.xml.
This allows the translations to be deeply nested arrays that will be flattened, allowing for namespacing of translations easily.
The following:
'key' => array('key2' => array('key3' => 'value'))
Becomes:
'key.key2.key3' => 'value'
This isn't applied to Xliff since it does not make sense within the scope of the XLIFF standard
In the dumped PHP class, we must use get() and not get*Service() methods to get services.
That's because all calls must be managed by get(). From the outside, you can call
get*Service() because as they are protected, they are caught by the __call() method;
which is not the case obviously when it is used internally.
If not, if you override a service with set(), this won't work when a service
depends on this one (the default one will still be used).
Fields can now easier support different data types in their underlying object.
These datatypes can be normalized to a single datatype using a normalization
transformer. The normalized value can then be transformed to the user's
representation with the value transformer (better name required?).
This fixes a bug in UniversalClassLoader when attempting to autoload class names with leading slashes:
$namespacedClass = "\\Foo\\Bar";
$pearlikeClass = "\\Foo_Bar";
$namespaced = new $namespacedClass();
$pearlike = new $pearlikeClass();
`UniversalClassLoader::loadClass()` was unable to load PEAR-like classes with leading slashes because it found the slash and assumed that the requested class was namespaced. It was unable to load namespaced classes with leading slashes because it would look them up in the autoloader's registered namespaces, and was unable to match '\Foo' to 'Foo'. One (ugly) workaround for the namespaced classes was to register all namespaces twice:
$loader->registerNamespaces(array(
'Foo' => __DIR__ . '/lib',
'\Foo' => __DIR__ . '/lib',
));
But that's not very pretty, nor does it solve the bug with PEAR-like classes. Stripping the leading slash before trying to autoload allows UniversalClassLoader to load both namespaced and PEAR-like classes.