* weaverryan/exception_page_changes:
[FrameworkBundle] When there are multiple nested exceptions, this hides the stacktrace from all exceptions by default
[FrameworkBundle] Fixing small bug on exception page where the +/- icons didn't toggle correctly
* kriswallsmith/assetic/updates:
[AsseticBundle] added twig support for asset packages
[AsseticBundle] cleaned up php templating support
[FrameworkBundle] fixed interface and usage in RouterHelper
[AsseticBundle] fixed twig classes for api changes in assetic
* kriswallsmith/assetic/config-fixes:
[AsseticBundle] moved some parameter defaults to Configuration
[AsseticBundle] fixed definition of filter configs
This addresses the potential issue where a user doesn't realize that there are multiple exception messages because the
full stack trace of the first exception is displayed (pushing the others far far down the page). This hides the stacktrace
of all exceptions (when there are more than one) by default, making each exception message easily viewable.
* kadeer/master:
[DoctrineBundle] fixes issues with $this->container->get('form.context') when the value of default_connection key of doctrine.dbal is changed from default in config.yml
The parameter has been removed and the service moved to the XML file (for consistency).
The behavior is still the same as before as any non-public service
which is not referenced anywhere will be automatically removed by a
compiler pass.
I need to get the assets version to pass it to JavaScript. As there is
no obvious way to get it from a twig template actually, I think this
new `assets_version` function makes sense.
We a currently working on a project were a single requested URL typically
leads to some hundred controller calls. Using the dev controller got
incredibly slow since recent Symfony2 changes because for each controller
invocation a new entry gets added to the profiler storage (totalling over
100mb of data on each request in our case).
With the new configuration attribute "only-master-requests" it is possible
to limit the profiler storage to the master requests, keeping the profiler
usable for us.
* kriswallsmith/doctrine/test-fixes:
[FrameworkBundle] fixed shorter bundle name in test
[HttpKernel] updated tests for shorter bundle names
[DoctrineMongoDBBundle] updated tests with shorter bundle names
[DoctrineBundle] updated tests with shorter bundle names
* kriswallsmith/assetic/explicit-filter-config:
[AsseticBundle] added lessphp filter
[AsseticBundle] added config for image filters
[AsseticBundle] moved filters into individual config files which must be explicitly loaded
[AsseticBundle] removed configuration of default output strings
You must now explicitly load those filters you want to use in your app. Some filters have additional configuration options:
assetic:
filters:
cssrewrite: ~
yui_css: { jar: "/path/to/yuicompressor.jar" }
You can also register your own filters now by referencing a configuration file:
assetic:
filters:
my_filter:
resource: "%kernel.root_dir%/config/my_filter.xml"
foo: bar
This configuration would load the referenced configuration file and set the "assetic.filter.my_filter.foo" parameter to "bar"
* 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"
The rationale is that this is a very common task and we can't expect non-advanced users to have to remember what the fully-qualified
class name of the Exception is in order to use it.
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 background is that Chrome only displays the content returned on an error page if payload is at least 512 bytes.
Prior to this change, the 404 page was just a few bytes short, resulting in the Chrome error message instead of the
real one returned by Symfony (confusing for the user).
* schmittjoh/security:
changed condition nesting
[Security] ACL: AclVoter::vote only gets an ObjectIdentity if $object is not an instance of ObjectIdentityInterface
[SecurityBundle] fixed missing argument EventDisplatcher in RememberMe service
* stealth35/use_filesystemiterator:
simplify folders deletion
work with Traversable
added FilesystemIterator namespace
tab to spaces
use FilesytemIterator insteed opendir
Quote from HTTP (bis) spec (Part 2 - 5.1.1):
The Reason Phrase exists for the
sole purpose of providing a textual description associated with the
numeric status code, out of deference to earlier Internet application
protocols that were more frequently used with interactive text
clients. A client SHOULD ignore the content of the Reason Phrase.
* weaverryan/controller-cannot-find-exception:
[FrameworkBundle] Giving a more specific message when a Bundle:Controller:Action controller class cannot be found
It's a detail, but it hits usability. For normal bundles (those without children), we're able to actually print the namespace where we're looking for the Controller. For bundles with children, this would be a very verbose message, but we can at least print all of the bundles that we looked inside of.
Some question whether or not the base Controller should be included at all. I think it absolutely must be included because it's important for beginners and for rapid development of smaller features/applications (and rapid development is good for beginners).
So, assuming that we *do* like the base Controller, we should really use it to its fullest potential - making the lives of developers as easy as possible.
The formatter can be set for an handler. The argument is the id of a
service implementing Monolog\Formatter\FormatterInterface.
Processors can be set on the logger level or for a specific handler. It
can be either a callable service when the value starts with @ either a
callback.
* 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 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()
This is mirrored off of the messages used by git flow and serves to give the user some initial direction (and to avoid "forgetting" the setup steps).
I realize that I've hardcoded documentation URLs into this task, but I think the benefit outweighs the cost of needing to make sure these are always up-to-date.
* francisbesset/translation_fr:
[FrameworkBundle] Fixed latest typo in french validators translation
[FrameworkBundle] Fixed others typo in french validators translation
[FrameworkBundle] Fixed typo in french validators translation
[FrameworkBundle] Added french validators translation
This command uses a new container pass which dumps the ContainerBuilder into a cache file by serializing it. It's possible that we don't want this to run when kernel.debug = false, but I don't see the harm of generating the file and running the container:debug in, for example, the prod environment seems to make sense.
With the configuration class, this ultimately just won't be the right place for this (it'll likely just get out of date). If anything, it should be a link to the reference section of the docs (a la settings.yml for symfony1).
* stof/doctrine_simplify:
Removed the short syntax in DoctrineBundle
[DoctrineAbstractBundle] Removed obsolete code as the normalization is now done by the Configuration classes
[DoctrineMongoDBBundle] Removed the short syntax for the configuration
* schmittjoh/visibilityChanges:
[Security] renamed Twig function has_role to is_granted
[Security] some more visibility changes
[Security] added some more tests
[Security] fixed some left-overs
[Security] various changes, see below
[Security] Bugfix - Ensure that passwords is of string type. Function BasePasswordEncoder::comparePasswords haven't been working properly for numeric (plaintype) passwords.
* kriswallsmith/mongodb/pretty-queries:
[DoctrineMongoDBBundle] made queries in profiler look like mongodb js shell code
[DoctrineMongoDBBundle] fixed xml formatting
* vicb/profiler_log:
[WebProfilerBundle] Always use the default background color for counters
[WebProfilerBundle] The total number of log entries is not relevant, display only the number of errors when required
[WebProfilerBundle] Display the number of log entries together with the number of errors
* vicb/profiler_template:
[WebProfilerBundle] Remove dead code
[WebProfilerBundle] Better handling of queries with an empty result
[WebProfilerBundle] Improve the "token not found" page
[WebProfilerBundle] Always remember the query including the token
[WebProfilerBundle] Apply missing styles
* kriswallsmith/framework/optimize-debug-dispatcher:
[FrameworkBundle] optimized the debug event dispatcher to avoid instantiating every listener every time
* weaverryan/add_mongo_db_configuration:
[DoctrineMongoDBBundle] Adding is_bundle node and rearranging a few small things to match pull request 99 for the Doctrine Configuration class
[DoctrineMongoDBBundle] Removing left-over debug code.
[DoctrineMongoDBBundle] Adding a "full" config example in YAML.
[DoctrineMongoDBBundle] Changing root node name for consistency.
[DoctrineMongoDBBundle] Removing unused variable.
[DoctrineMongoDBBundle] Refactoring how the document_managers are loaded in the Extension and removing two unneeded DIC parameters.
[DoctrineMongoDBBundle] Removing the "default_connection" DI parameter, which was never used as a parameter. Now cleaning up connections creation in the DI extension class.
[DoctrineMongoDBBundle] Renaming extension method to overrideParameters(), which is truer to its name.
[DoctrineMongoDBBundle] Removing the "doctrine.odm.mongodb.metadata_cache_driver" parameter.
[DoctrineMongoDBBundle] Adding a test for the defaults of the Configuration class and updated a few default values.
[DoctrineMongoDBBundle] BC-break: This removes the excess "connections" and "document_managers" wrapper in XML. This was inconsistent and made normalization unnecesarily difficult.
[DoctrineMongoDBBundle] Initial use of the new Configuration class for DoctrineMongoDBExtension.
[DoctrineMongoDBExtension] Adding a large PHPDoc on the Extension::load() method discussing the available options.
[DoctrineMongoDBBundle] Fixing a test that was passing in the configs array without the wrapping array.
[DoctrineMongoDBBundle] Rewriting several getParameter() calls to use the parameter %wildcard% syntax instead. This is best-practice.
Also mae this function unset the options after their used. This prevents those values from being available later inside the options array and as parameters.
This information was set entirely in the DI extension options and then added as a parameter only to be later consumed by the DI extension class.
In other words, this should never have been a parameter, or at least it's never been used and treated like a parameter.
Previously:
<connections>
<connection ...>
<!-- .. -->
</connection>
<connection ...>
<!-- .. -->
</connection>
</connections>
Now:
<connection ...>
<!-- .. -->
</connection>
<connection ...>
<!-- .. -->
</connection>
I believe this is more semantically correct, and it removes code that had to worry about this extra format and normalize it.
* Seldaek/wdt:
[FrameworkBundle] Highlight error logs in red and not green
[FrameworkBundle] Fix alignment of <li> with the selected class and small opera glitch
[FrameworkBundle] Don't hide logs by default in exception pages
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.
* 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.
Doctrine's EventManager implementation has several advantages over the
EventDispatcher implementation of Symfony2. Therefore I suggest that we
use their implementation.
Advantages:
* Event Listeners are objects, not callbacks. These objects have handler
methods that have the same name as the event. This helps a lot when
reading the code and makes the code for adding an event listener shorter.
* You can create Event Subscribers, which are event listeners with an
additional getSubscribedEvents() method. The benefit here is that the
code that registers the subscriber doesn't need to know about its
implementation.
* All events are defined in static Events classes, so users of IDEs benefit
of code completion
* The communication between the dispatching class of an event and all
listeners is done through a subclass of EventArgs. This subclass can be
tailored to the type of event. A constructor, setters and getters can be
implemented that verify the validity of the data set into the object.
See examples below.
* Because each event type corresponds to an EventArgs implementation,
developers of event listeners can look up the available EventArgs methods
and benefit of code completion.
* EventArgs::stopPropagation() is more flexible and (IMO) clearer to use
than notifyUntil(). Also, it is a concept that is also used in other
event implementations
Before:
class EventListener
{
public function handle(EventInterface $event, $data) { ... }
}
$dispatcher->connect('core.request', array($listener, 'handle'));
$dispatcher->notify('core.request', new Event(...));
After (with listeners):
final class Events
{
const onCoreRequest = 'onCoreRequest';
}
class EventListener
{
public function onCoreRequest(RequestEventArgs $eventArgs) { ... }
}
$evm->addEventListener(Events::onCoreRequest, $listener);
$evm->dispatchEvent(Events::onCoreRequest, new RequestEventArgs(...));
After (with subscribers):
class EventSubscriber
{
public function onCoreRequest(RequestEventArgs $eventArgs) { ... }
public function getSubscribedEvents()
{
return Events::onCoreRequest;
}
}
$evm->addEventSubscriber($subscriber);
$evm->dispatchEvent(Events::onCoreRequest, new RequestEventArgs(...));
* kriswallsmith/assetic/test-coverage:
[AsseticBundle] progress migrating functional tests to unit tests
[AsseticBundle] changed type to use interface
[AsseticBundle] added a functional test group
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 }}
* kriswallsmith/assetic/watch:
[AsseticBundle] added error handling to --watch
[AsseticBundle] added a simple cache to --watch so it picks up where it left off last time
[AsseticBundle] added a --watch option to the assetic:dump command
* lsmith77/fixture_2_migration:
cosmetic tweak
initial steps to handling objects
A command to generate a migration from the sql queries executed when you load some data fixtures.
The Response is not available in the DIC anymore.
When you need to create a response, create an instance of
Symfony\Component\HttpFoundation\Response instead.
As a side effect, the Controller::createResponse() and Controller::redirect()
methods have been removed and can easily be replaced as follows:
return $this->createResponse('content', 200, array('foo' => 'bar'));
return new Response('content', 200, array('foo' => 'bar'));
return $this->redirect($url);
return Response::createRedirect($url);
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.
* dator/send_email_command:
Fix description
Add an example using the options in the help message
Fix CS
[SwiftMailer] Add the SendEmail Command (for the spool)
* weaverryan/config_definition_changes:
[SecurityBundle] Allowing the main Configuration tree to allow "factories" without a validation exception.
[SecurityBundle] Removing an old configuration key in a test - caught by the Configuration validation.
[SecurityBundle] Adding the ignoreExtraFields option to the factories tree so that there aren't validation errors on all the other unknown fields.
[Config] Adding an ignoreExtraKeys options, which allows you to let options simply be ignore without throwing a validation exception.
[Config] Reverting some meaningless changes that are no longer needed to minimize the true diff of the changes. Increasing the test precision.
[Config] Reverting the preventExtraKeys option. This is a revert of functionality that would have allowed "unnamed" children to be added to an array node.
[Config] Moving the removal of the key attribute on ArrayNode onto the setKeyAttribute() method per Johannes.
[Config] Renaming the key attribute removal property for consistency per Johannes' recommendation. Also fixing a PHPDoc typo per Stof.
[SwiftmailerBundle] Removing unnecessary "enabled" key in a test.
[FrameworkBundle] Removing the "namespace" key when it's defined in its own weird location in XML. This prevents that key, which we move in this same location, from looking like an invalid option during validation.
[Config] Renaming NodeBuilder::nodeBuilder() to NodeBuilder::builder() due to the fact that PHP can get confused when you have a __construct() method *and* a method that has the same name as the class (looks like two constructors to PHP).
[Config] Making the option to remove a key attribute optional.
[Config] Renaming the NodeBuilder::addNodeBuilder() to simply NodeBuilder::nodeBuilder() to be consistent with the other names: node(), arrayNode().
[Config] Making changes per the recent movement of the Config builder into the Config component.
[DependencyInjection] Renaming allowUnnamedChildren to preventExtraKeys. Also moved the place where validation of extra configs occurs.
[DependencyInjection] Being sure to remove XML-remapped singular options and key attribute options after processing.
[DependencyInjection] Adding a NodeBuilder::addNodeBuilder() method that helps achieve a fluid interface when a pre-built NodeBuilder needs to be added.
[DependencyInjection] Initial implementation of an allowUnnamedChildren method on NodeBuilder. Also added an "extra field" exception.
The main tree doesn't actually process the factories (that's done in an earlier step), so it doesn't actually need their real value. It does, however, need to *not* throw an exception when they're present. An alternative to this approach would be to call ignoreExtraKeys() on the root node of the main tree, but this would allow extra keys to be passed in at the root level, which I thought was a less-desirable solution.
Added config fixtures in each format to demonstrate the possible styles of all of the extension options. These should all be covered by the updated tests. Made XSD slightly more restrictive, with regards to the "type" attribute on globals. This is coupled with validation in the configuration class.
I double-checked with Stof - this is obviously unnecessary and there was no meaning behind including it. This caused the test to fail with the new validation.
Note that this commit removes the built-in support for MongoDB user providers.
This code can be moved back in once there is a stable release for MongoDB, but
for now you have to set-up that user provider just like you would set-up any
custom user provider:
security:
providers:
document_provider:
id: my.mongo.provider
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 allows for better conventions and better error messages if you
use the wrong configuration alias in a config file.
This is also the first step for a bigger refactoring of how the configuration
works (see next commits).
* Bundle::registerExtensions() method has been renamed to Bundle::build()
* The "main" DIC extension must be renamed to the new convention to be
automatically registered:
SensioBlogBundle -> DependencyInjection\SensioBlogExtension
* The main DIC extension alias must follow the convention:
sensio_blog for SensioBlogBundle
* If you have more than one extension for a bundle (which should really
never be the case), they must be registered manually by overriding the
build() method
* If you use YAML or PHP for your configuration, renamed the following
configuration entry points in your configs:
app -> framework
webprofiler -> web_profiler
doctrine_odm -> doctrine_mongo_db
* Added the --format parameter to the InitBundleCommand.php file
* Moved all the non-format-dependent files from Resources/skeleton/bundle to Resources/skeleton/bundle/generic
* Created Resources/skeleton/bundle/[php,yml,xml] subfolders containing the files config/routing.[xml,yml,php]
The custom error page is now disabled by default as this would throw an
exception if the /access_denied url does not match a route.
This commit also remove the old parameter for this url which is not used
anymore in the code.
Moved the default value to the Configuration class
* Remove redundant null/true equivalent array() values for array nodes
* Profiler matcher should not be deep merged; subsequent configs can simply overwrite its array
* Per lsmith's suggestion, change "isset(x) && x" to "!empty(x)"
* Templating engines node should be required, which is necessary to ensure requiresAtLeastOneElement() applies to its prototype children
In routing files, import statements allow an optional "type" option to hint the resources' type (e.g. for ambiguous file extensions). This adds the same type option to the FrameworkExtension config, which defines the main routing resource.
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.
Methods within FormExtension later type-hint this parameter as an array, but it's convenient to allow a single string to be passed from Twig if we ensure it's wrapped in an array.
Updated load data fixtures command in DoctrineMongoDBBundle to be identical to the one in DoctrineBundle
Created custom loader, that passes $container to all ContainerAware DataFixtures
This fixes some BC problems introduced in f9138d313b. Some top-level can now be simply enabled by providing true/null in PHP/YAML. Additionally, the Configuration\Builder allows options to be unset by providing "false" (helpful for overriding activation in a previous config file). All options supporting these behaviors can be found in the Configuration.php file (look for canBeUnset() and treatNull/TrueLike()).
Major changes:
* Removed "enabled" option for profiler config. Profiler is now enabled if its config is true, null or a map.
* Restore original config structure for validation namespaces. In PHP/YAML, namespaces are defined under annotations as an alternative to false (disabled) and true/null (enabled). For XML, annotation remains a boolean attribute for validation and a one or more optional namespace tags may appear within <app:validation />. During config normalization, namespace tags under validation will be moved to annotations to conform to the PHP/YAML structure (this occurs transparently to the user).
* Restore behavior for router/templating config sections being optional (as shown in changes to session/validation test fixtures). If either top-level section is unset in the configuration, neither feature will be enabled and the user will no longer receive exceptions due to missing a resource option (router) or engines (templating). Resource/engines will still be properly required if the respective feature is enabled.
* Remove unused router type option from XML config XSD. Type is only relevant for import statements, so this option is likely useless.
Additional small changes:
* Added isset()'s, since config options may be unset
* Wrap registerXxxConfiguration() calls in isset() checks
* Load translation.xml in configLoad(), since it's always required
* Default cache_warmer value (!kernel.debug) is determined via Configuration class
Things to be fixed:
* Configuration\Builder doesn't seem to respect isRequired() and requiresAtLeastOneElement() (or I haven't set it properly); this should replace the need for FrameworkExtension to throw exceptions for bad router/templating configs
* The config nodes for session options don't have the "pdo." prefix, as dots are not allowed in node names. To preserve BC for now, the "pdo." prefix is still allowed (and mandated by XSD) in configuration files. In the future, we may just want to do away with the "pdo." prefix.
* Translator has an "enabled" option. If there's no use case for setting "fallback" independently (when "enabled" is false), perhaps "enabled" should be removed entirely and translator should function like profiler currently does.
* Profiler matcher merging might need to be adjusted so multiple configs simply overwrite matcher instead of merging its array keys.
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.
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.
Restructured config format to make processing more straightforward. Important changes that might break existing configs:
* Added "enabled" option for translator (improves multi-format compat)
* Removed hash variation of validation annotations option (only boolean)
* Moved namespace option directly under validation (improves multi-format compat)
The new merge process depends on an internal array of all supported options and their default values, which is used for both validating the config schema and inferring how to merge options (as an added benefit, it helps make the extension self-documenting). Exceptions will now be thrown for merge errors resulting from unrecognized options or invalid types. Since incoming configurations are all merged atop the defaults, many isset() checks were removed. As a rule of thumb, we probably only want to ignore null values when an option would be used to set a parameter.
Also:
* Added missing attributes to symfony-1.0.xsd
* profiler: added only-exceptions attribute
* session: fix types and add pdo attributes
* Create FrameworkExtension tests with PHP/XML/YAML fixtures
* Use "%" syntax instead of calling getParameter() within FrameworkExtension
* Normalize config keys and arrays with helper methods for PHP/XML/YAML compatibility
Earlier changes:
* Remove nonexistent "DependencyInjection/Resources/" path from XmlFileLoaders
* Remove hasDefinition() checks, as register methods should only execute once
* Remove first-run logic from registerTranslatorConfiguration(), as it is only run once
* Removed apparently obsolete clearTags() calls on definitions for non-enabled features
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');
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();
A class in Symfony2 can be loaded by four different mechanisms:
* bootstrap.php: This file contains classes that are always required and
needed very early in the request handling;
* classes.php: This file contains classes that are always required and
managed by extensions via addClassesToCompile();
* MapFileClassLoader: This autoloader uses a map of class/file to load
classes (classes are managed by extensions via addClassesToAutoloadMap(),
and should contain often used classes);
* UniversalAutolaoder: This autoloader loads all other classes (it's the
slowest one).
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
}
Cache warmer will come in the next commits.
To warm up the cache on a production server, you can use
the cache:warmup command:
./app/console_prod cache:warmup
* 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.
You must now explicitly register the templating engine you want to use:
<app:templating>
<app:engine id="twig" />
</app:templating>
app.templating:
engines: ['twig']
Symfony2 comes with two such engines: 'twig', and 'php'.
This adds lazy loading for firewall configurations. This is useful when you have multiple firewalls, only the firewalls which are actually needed to process the Request are initialized. So, your event dispatcher is not as costly to initialize anymore.
It also implements re-using of RequestMatchers if all matching rules are the same, and exposes the remaining rules which are already implemented by the request matcher (host, ip, methods) in the access-control section
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" />
Let's take some examples to explain the change.
First, if you don't use any vendored bundles, this commit does not change anything.
So, let's say you use a FooBundle from Sensio. The files are stored under Bundle\Sensio\FooBundle.
And the Bundle class is Bundle\Sensio\FooBundle\SensioFooBundle.php.
Before the change, the bundle name ($bundle->getName()) would have returned 'FooBundle'.
Now it returns 'SensioFooBundle'.
Why does it matter? Well, it makes template names and controller names easier to read:
Before:
Template: Sensio\FooBundle:Bar:index.twig.html
Controller: Sensio\FooBundle:Bar:indexAction
After
Template: SensioFooBundle:Bar:index.twig.html
Controller: SensioFooBundle:Bar:indexAction
NB: Even if the change seems simple enough, the implementation is not. As finding
the namespace from the bundle class name is not trivial
NB2: If you don't follow the bundle name best practices, this will probably
leads to unexpected behaviors.
Before
bundle:section:template.format.renderer
After
bundle:section:template.renderer.format
Notice that both the renderer and the format are mandatory.
* 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
A global can now be a service or a string:
<twig:config debug="%kernel.debug%" strict-variables="%kernel.debug%">
<twig:global key="request" type="service" id="request" />
<twig:global key="PI">3.14</twig:global>
</twig:config>