This was imported from DoctrineBundle (see: doctrine/DoctrineBundle#23), since it can be used by other Doctrine bundles, too. It utilizes the ContainerAwareEventManager from f15dde6c59.
Commits
-------
e6e9b5a [Routing] Return the _route parameter from ApacheUrlMatcher
Discussion
----------
[Routing] Return the _route parameter from ApacheUrlMatcher
---------------------------------------------------------------------------
by fabpot at 2012-02-22T23:13:49Z
Can you squash your commits before I merge? Thanks.
---------------------------------------------------------------------------
by arnaud-lb at 2012-02-23T09:12:45Z
sure, done
Commits
-------
b269e27 [Config] Improve handling of PrototypedArrayNode defaults
4feba09 [Config] implements feedback
bc122bd [Config] Fix nested prototyped array nodes
675e5eb [Config] Take advantage of the new PrototypedArrayNode API in the core bundles
cba2c33 [Config] Improve error messages & extensibility
bca2b0e [Config] Improve PrototypedArrayNode default value management
Discussion
----------
[Config] Improve prototype nodes usability, error messages, extensibility
### First commit
*Before* (you should set multiple defalutValues)
```php
<?php
$root
->arrayNode('node')
->prototype('array')
// when the node is not set
->defaultValue(array('foo' => 'bar')
->children()
// when the key is not set
->scalarNode('foo')->defaultValue('bar')->end()
$root
->arrayNode('node')
->prototype('array')
// when the node is not set
->defaultValue(array('defaults' => array('foo1' => 'bar1', 'foo2' => 'bar2')
->children()
->arrayNode('bar')
// when the node is not set
->addDefautsIfNotSet()
// when some values are not set (node being set)
->scalarNode('foo1')->defaultValue('bar1')->end()
->scalarNode('foo2')->defaultValue('bar2')->end()
```
*after*
```php
<?php
$root
->arrayNode('node')
->addDefaultChildrenWhenNoneSet()
->prototype('array')
->children()
->scalarNode('foo')->defaultValue('bar')->end()
$root
->arrayNode('node')
->addDefaultChildrenWhenNoneSet()
->prototype('array')
->children()
->arrayNode('bar')
->scalarNode('foo1')->defaultValue('bar1')->end()
->scalarNode('foo2')->defaultValue('bar2')->end()
```
*more* (exclusive configs)
```php
<?php
$root
->arrayNode('node')
// Add a default node named 'defaults'
->addDefaultChildrenWhenNoneSet()
// Add a default node named 'foo'
->addDefaultChildrenWhenNoneSet('foo')
// Add two default nodes named 'foo', 'bar'
->addDefaultChildrenWhenNoneSet(array('foo', 'bar'))
// Add two default nodes
->addDefaultChildrenWhenNoneSet(2)
```
### Second commit
Improves error messages (print the path to the error) & extensibility.
@schmittjoh I would appreciate you feedback on both the commits. Do you think a boolean $throw switch on `getNode` would make sense (i.e. to prevent throwing excs in prod ?).
---------------------------------------------------------------------------
by schmittjoh at 2012-02-20T15:43:18Z
The error improvements seem uncontroversial.
I'm not so convinced by the other changes though. What if the prototype is a map and not a simple list?
---------------------------------------------------------------------------
by vicb at 2012-02-20T16:07:51Z
I think there's one caveat left in the code as it is now that I will fix (nested prototypes).
Could you please give me more details on the use case you are referring to ?
You do not have to use the new feature but It can be really helpful [here](https://github.com/symfony/symfony/pull/3225/files#L4R38) for example.
---------------------------------------------------------------------------
by schmittjoh at 2012-02-20T17:20:02Z
What I mean is something like this:
```php
->arrayNode("foo")
->useAttributeAsKey("name")
->prototype(/* ...
```
---------------------------------------------------------------------------
by vicb at 2012-02-20T17:28:01Z
What would be wrong then ? (that's the use case I link in my previous msg)
---------------------------------------------------------------------------
by schmittjoh at 2012-02-20T17:28:55Z
How would adding defaults look like?
---------------------------------------------------------------------------
by vicb at 2012-02-20T17:36:35Z
Check the "more" part of the PR message.
In the linked use case, it would add a "defaults" server using the default host / port / weight. In this case I do not care about the name but the values are important to help alias the equivalent configs. You can override the "defaults" name by using a parameter.
---------------------------------------------------------------------------
by vicb at 2012-02-20T17:47:27Z
```php
<?php
// [...]
->arrayNode('servers')
->addDefaultChildrenWhenNodeSet()
->useAttributeAsKey('name')
->prototype('array')
->children()
```
---------------------------------------------------------------------------
by schmittjoh at 2012-02-20T17:47:54Z
What I was thinking about is having two nodes with different default values. Right now, both nodes while having different keys would still have the same default values which does not make much sense to me. However, we can address this in another PR.
One thing that we should fix though is that we should require keys in case of a map, and forbid them in case of a list. It might make sense to split it into different methods. Like the following examples make no sense (but are possible atm):
```php
->arrayNode("foo")
->useAttributeAsKey("name")
->addDefaultChildrenIfNotSet(5)
->arrayNode("foo")
->addDefaultChildrenIfNotSet("foo")
->prototype("scalar")->end()
```
Another minor nitpick, please rename "when" to "if".
---------------------------------------------------------------------------
by vicb at 2012-02-20T18:03:19Z
@schmittjoh thank you for your feedback.
message-2:
* I think the first case is fine (children "1" to "5"). Sometimes you just don't care about the names so it should not be forbidden.
* I also think the second case is fine as you would write `foo: value` in your config file anyway.
Let me know your thoughts about the previous statements.
Agree to change when to if.
message-1:
Will change
---------------------------------------------------------------------------
by vicb at 2012-02-20T18:06:33Z
I think "IfNoneSet" is more accurate than "IfNotSet" ?
---------------------------------------------------------------------------
by schmittjoh at 2012-02-20T18:09:59Z
If you call "useAttributeAsKey" it automatically means that the keys are meaningful to you (otherwise there is no point in calling it). In such a case, keys should be explicitly given.
On the other hand, if you do not call it, then the keys are ignored/dropped by the Config component. So if you give a key, it is an obvious error that we should catch. The second case I linked would look like ``foo: [value]`` in contrast to ``foo: { foo: value }``.
---------------------------------------------------------------------------
by schmittjoh at 2012-02-20T18:14:44Z
I'm not feeling strongly about this, but "IfNotSet" is more consistent with
"addDefaultsIfNotSet" and basically reads as "if array node is not set, do
...". Your example would refer to the children and read as "if none
(children) have been defined, do ...".
On Mon, Feb 20, 2012 at 12:06 PM, Victor Berchet <
reply@reply.github.com
> wrote:
> I think "IfNoneSet" is more accurate than "IfNotSet" ?
>
> ---
> Reply to this email directly or view it on GitHub:
> https://github.com/symfony/symfony/pull/3403#issuecomment-4058579
>
---------------------------------------------------------------------------
by vicb at 2012-02-20T18:30:21Z
message-2:
* Agree on first point, will change
* You could specify the keys in your config file if the prototype is an array (you used a scalar). Should we implement a switch in the validation (i.e. array / not array) or just go with numeric / null arg as you suggest ?
message-1:
> Your example would refer to the children and read as "if none (children) have been defined, do ..."
QED
---------------------------------------------------------------------------
by vicb at 2012-02-20T22:11:05Z
@schmittjoh I have implemented your suggestions (other than the "NoneSet"). Let me know if you think this is ok. Thanks.
---------------------------------------------------------------------------
by schmittjoh at 2012-02-21T03:24:19Z
Looks good to me.
As an additional improvement we might consider to allow to prepopulate an prototyped with values. For example, in the FOSRestBundle there is a case where this could be used.
```php
->arrayNode('formats')
->prepopulateValues(array('application/json' => 'json', 'application/xhtml+xml' => 'xml'))
->useAttributeAsKey('name')
->prototype('scalar')->canBeUnset()->end()
```
This could be done in a separate PR however and is not strictly related to these improvements.
---------------------------------------------------------------------------
by vicb at 2012-02-21T07:51:59Z
@schmittjoh that would be a great addition but I think need some thinking (i.e. the name, `initialValues` ?, should we handle duplicates, how - in case we are not using attribue as key, ...) so let's make an other PR, I'd like this one to be merged asap as I need this for the Cache Bundle.
@fabpot ready
Commits
-------
fb2bb65 [HttpFoundation] Fix session.cache_limiter is not set correctly
Discussion
----------
[HttpFoundation] Fix session.cache_limiter is not set correctly
Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: -
Todo: -
Fixes a regression after the session refactoring where extra cache control http headers are sent.
This was previously handled by [calling session_cache_limiter(false) in NativeSessionStorage](https://github.com/symfony/symfony/blob/2.0/src/Symfony/Component/HttpFoundation/SessionStorage/NativeSessionStorage.php#L81)
---------------------------------------------------------------------------
by drak at 2012-02-21T12:23:48Z
@fabpot - this code can be merged imo.
Commits
-------
6fbd290 Improved unit tests for MemcacheSessionStorage
b4c5323 Added comma to array initializer, reverted permissions back to 644
3dd851a Use correct parameters
0e01418 Fix default if no serverpool is provided
2a65121 Fix several issues in MemccheSessionStorage which prevented it from being used correctly
Discussion
----------
Fix several issues in MemcacheSessionStorage
Apperently this could never have worked unless someone passed wrong arguments to the options.
---------------------------------------------------------------------------
by mazen at 2012-02-19T07:58:52Z
```
[marcel@development symfony]$ phpunit tests/Symfony/Tests/Component/HttpFoundation/Session/Storage/MemcacheSessionStorageTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.
Configuration read from /www/includes/vendor/symfony/phpunit.xml.dist
......
Time: 0 seconds, Memory: 3.75Mb
OK (6 tests, 11 assertions)
```
---------------------------------------------------------------------------
by lsmith77 at 2012-02-19T16:10:13Z
cc @drak
---------------------------------------------------------------------------
by drak at 2012-02-19T17:44:00Z
Looks like we could do with some tests for the constructor that also test the defaults and the internal properties. And also more extensively tests the mock to test the addServer behaviour.
---------------------------------------------------------------------------
by helmer at 2012-02-19T18:02:03Z
@mazen You've changed file permissions from 644->755 ..
---------------------------------------------------------------------------
by drak at 2012-02-21T12:25:11Z
@fabpot - with the extra tests added in 6fbd290 I believe this code is ready for merge.
Commits
-------
0a176eb [FrameworkBundle] Fix configuration errors
6745b28 [Config] Throw exceptions on invalid definition
fb27de0 [Config] cleanup
Discussion
----------
[Config] Cleanup, error detection, fixes
see #3357
---------------------------------------------------------------------------
by stloyd at 2012-02-15T10:56:00Z
@vicb As you added new exceptions, IMO you should add some tests to cover it.
---------------------------------------------------------------------------
by vicb at 2012-02-15T10:56:50Z
good point, I'll do.
---------------------------------------------------------------------------
by vicb at 2012-02-15T13:49:44Z
@stloyd that was a great idea, I realized I had miss a case. It has been added and should be covered by UT + fixes made.
I am done with the fixes, should be ready to merge.
And time to give the `PrototypedArrayNode` some more usability now.
Commits
-------
d077ede [HttpFoundation] Increase test coverage.
cbb3e69 [HttpFoundation] Increase test coverage.
Discussion
----------
[HttpFoundation] Increase session test coverage.
Bug fix: no
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: -
Todo: -
On the advice of @schmittjoh, this commit adds a LogoutException class for use by LogoutListener if the CSRF token is invalid.
The handling in the Security component's ExceptionListener is modeled after AccessDeniedException, which gets wrapped in an AccessDeniedHttpException in the absence of handler service or error page (I didn't think it was appropriate to re-use those for LogoutException).
This adds several new options to the logout listener, modeled after the form_login listener:
* csrf_parameter
* intention
* csrf_provider
The "csrf_parameter" and "intention" have default values if omitted. By default, "csrf_provider" is empty and CSRF validation is disabled in LogoutListener (preserving BC). If a service ID is given for "csrf_provider", CSRF validation will be enabled. Invalid tokens will result in an InvalidCsrfTokenException being thrown before any logout handlers are invoked.
Commits
-------
9d6eb82 [Routing] Fix a bug in the TraceableUrlMatcher
9fc8d28 [FrameworkBundle] Fix a bug in the RedirectableUrlMatcher
4fcf9ef [Routing] Small optimization in the UrlMatcher
abc2141 [Routing] Added a missing property declaration
d86e1eb [Routing] Remove a weird dependency
Discussion
----------
[Routing] Remove a dependency on a derived class, fixes, optim
Subset of #3296 which should be acceptable.
Travis is happy.
The side effect of removing the dependency is that the `UrlMatcher` does not throw an exception any more when the scheme does not match the required scheme. I think it is better because:
* it removes a dependency on a derived class,
* it was an undocumented "feature",
* other thrown excs are component specific while this one was raw SPL.
---------------------------------------------------------------------------
by vicb at 2012-02-09T14:43:02Z
let me know what should go in 2.0 as well.
Commits
-------
e5edf5a [Console] Fixed CS
8abf506 [Console] Added abbreviation into search for bad command / namespace
c6203bc [Console] Added namespace suggest on bad namespace name
117359a [Console] fixed CS according to PR comment
dd0d97e [Console] Added suggest on bad command name
Discussion
----------
[Console] Added suggest on bad command name
Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: -
Todo: namespace ?
Added something like in `git` : if user type a wrong command and if a close alternative exists, Command compenent will display a list of similar command(s).
Note : It does not work with namespace. If this PR will be merged, I could work on namespace.
see : https://github.com/fabpot/Twig/blob/master/lib/Twig/Environment.php#L1003
---------------------------------------------------------------------------
by fabpot at 2012-02-11T18:54:49Z
I think we need it to also work on namespace before merging. Is it possible?
---------------------------------------------------------------------------
by henrikbjorn at 2012-02-11T19:01:06Z
could maybe use similar_text ?
---------------------------------------------------------------------------
by lyrixx at 2012-02-11T19:01:55Z
Yes.
I will work on it asap
---------------------------------------------------------------------------
by lyrixx at 2012-02-11T20:06:43Z
I added code for namespace
@henrikbjorn I did the same logic as in twig.
---------------------------------------------------------------------------
by lyrixx at 2012-02-11T20:27:48Z
Note : Travis tests failed : http://travis-ci.org/#!/lyrixx/symfony/builds/663216
```before_script: Execution of 'php vendors.php' took longer than 600 seconds and was terminated.
Consider rewriting your stuff in AssemblyScript, we've heard it handles Web Scale™```
But tests are OK on my laptop
---------------------------------------------------------------------------
by stof at 2012-02-11T20:41:15Z
Well, it may be due to github issues during the setup of the vendors. There is some issues regularly because of the DDoS attack.
---------------------------------------------------------------------------
by lyrixx at 2012-02-11T20:58:07Z
Yes, i guessed it :-) that's why i notice it work on my laptop
---------------------------------------------------------------------------
by fabpot at 2012-02-11T23:11:08Z
This code won't work if you use abbreviations instead of the full namespace or command name.
---------------------------------------------------------------------------
by lyrixx at 2012-02-12T23:30:04Z
I added code to manage abbreviations. But I'm not sure what you are expecting. Can you try it and give me some feedback ?
P.S. : Travis failed again, but tests pass on my laptop.
Commits
-------
beb4fc0 [WIP][Locale] StubIntlDateFormatter::parse was throwing exception instead of returning Boolean false like intl implementation
b61dff7 fixed CS
Discussion
----------
[WIP][Locale] StubIntlDateFormatter::parse was throwing exception instead of returning Boolean false like intl implementation
Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: ![travis.ci](https://secure.travis-ci.org/eriksencosta/symfony.png?branch=ticket_2781)
Fixes the following tickets: #2781
Todo: A test fail in 32 bit environment, executed tests only with PHP 5.3.2 and ext-intl ICU 4.2 based
Failed test:
1) Symfony\Tests\Component\Locale\Stub\StubIntlDateFormatterTest::testFormatWithDefaultTimezoneIntl
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'1969-12-31 21:00:00'
+'1969-12-31 16:00:00'
Commits
-------
7474293 memcache profiler storage support added
Discussion
----------
[HttpKernel] [FrameworkBundle] Memcache(d) Profiler Storage added
Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: -
Todo: -
There are 2 memcache PHP extensions: Memcache and MemcacheD (with "D" at the end) - both are supported.
How to use Memcache Profiler Storage (Memcache php extension is used):
change (or add if there isn't) "dsn" in framework/profiler section in config_dev.yml
```
...
framework:
...
profiler:
...
dsn: memcache://127.0.0.1/11211
...
```
How to use Memcached Profiler Storage (MemcacheD php extension is used):
change "dsn" in framework/profiler section in config_dev.yml
```
...
framework:
...
profiler:
...
dsn: memcached://127.0.0.1/11211
...
```
Last changes:
- memcached support addedd
- optimized performance (serialization done in extension, index is created with ```append``` function)
- updated to last version of Profiler (find by method, avoid duplications)
- done squash on commits
---------------------------------------------------------------------------
by stloyd at 2011-12-01T23:36:02Z
You need to add check for index name size, AFAIK memcache will fail if key is longer than 250 characters.
Also please do an `squash` for all those commits.
---------------------------------------------------------------------------
by pulzarraider at 2011-12-02T00:15:28Z
@stloyd Thanks. I will add the check for key length.
I am just starting with git. Could you please add some tutorial about squash to a documentation page: http://symfony.com/doc/2.0/contributing/code/patches.html ? It will help me (and maybe some others) to do it correct way.
---------------------------------------------------------------------------
by stof at 2011-12-02T00:19:01Z
http://help.github.com/rebase/
---------------------------------------------------------------------------
by pulzarraider at 2011-12-03T18:56:11Z
Thanks @stof, rebase done.
---------------------------------------------------------------------------
by dlsniper at 2011-12-11T14:00:17Z
Hi,
Would it be possible to either use Memcached instead of Memcache or make it configurable to use either Memcache or Memcached?
I've did a little digging on the benefits of using Memcached over Memcache (like for example: http://stackoverflow.com/questions/1442411/using-memcache-vs-memcached-with-phphttp://devzone.zend.com/1869/zendcon-sessions-episode-040-memcached-the-better-memcache-interface/ ) and maybe this will also help in not having two extensions installed for people who are using Memcached already.
Regards.
---------------------------------------------------------------------------
by pulzarraider at 2011-12-11T16:15:58Z
@dlsniper thanks for great comment. I will add memcached support.
---------------------------------------------------------------------------
by stof at 2011-12-12T20:49:00Z
@pulzarraider what is the status of this PR ? Is it still a WIP ?
---------------------------------------------------------------------------
by pulzarraider at 2011-12-12T22:58:48Z
@stof Yes, it's still WIP. I'm working on a memcached (with D at the end) support. It will be finished in the next few days.
---------------------------------------------------------------------------
by dlsniper at 2011-12-15T12:51:52Z
@pulzarraider if I can help you with the PR let me know.
---------------------------------------------------------------------------
by pulzarraider at 2012-01-08T20:22:24Z
@dlsniper @stof I've finally added memcached support and done some optimizations. Memcache(d) profiler storage is now ready.
---------------------------------------------------------------------------
by dlsniper at 2012-01-08T22:12:29Z
I'm glad you finished this @pulzarraider
Thanks! for your hard work!
+1 for this PR
@stof, @fabpot is it good to go on master?
---------------------------------------------------------------------------
by pulzarraider at 2012-01-28T19:45:56Z
@stof, @fabpot ping
Commits
-------
3dd3d58 [EventListener] Fix an issue with sub-requests
71bf279 cleanup
acdb325 [StopWatch] Provide a cleaner API
acd1287 [Stopwatch] rename the section event to avoid collisions
eb540be [Profiler] Allow profiling the terminate event
4ccdc53 [HttpKernel] Cleanup of PdoProfilerStorage
814876f [HttpKernel] Tweak the code of the ProfilerListener
Discussion
----------
[Profiler] Allow profiling the terminate event
![Travis](https://secure.travis-ci.org/vicb/symfony.png?branch=profiler.terminate)
This PR is mainly about allowing to profile the terminate event (i.e. see it in the timeline panel)
There are some other tweaks.
---------------------------------------------------------------------------
by vicb at 2012-02-02T14:43:20Z
please don't merge for now. good question. bad answer.
---------------------------------------------------------------------------
by vicb at 2012-02-06T15:05:46Z
While first commits were focused on problem solving, the last brings a clean API with the ability to re-open an existing section in order to add events (re-setting event origins and merging them were just hacks).
Should be ready to be merged.
_Edit: Sorry, couldn't resist adding a private helper class again!_
---------------------------------------------------------------------------
by stof at 2012-02-06T18:30:09Z
@vicb you should stop adding such classes defined in the same file. Otherwise we will have to change the CS (and to stop telling we respect the PSR-0 standard)
---------------------------------------------------------------------------
by vicb at 2012-02-06T18:33:36Z
Once again PSR-0 is about autoloading which is exactly why I do not want in such cases. CS are an other matter and yes I think they should be changed to allow this (and I am going to submit a PR right now).
The only argument I could accept is whether this class should be private or not.
---------------------------------------------------------------------------
by vicb at 2012-02-06T19:57:06Z
Thanks for your valuable feedback @stof
---------------------------------------------------------------------------
by fabpot at 2012-02-11T20:53:03Z
Have you tested it on a project? Because it breaks my simple examples (where I have some sub-requests).
---------------------------------------------------------------------------
by vicb at 2012-02-12T09:47:23Z
my bad, should be ok now.
Commits
-------
cde34fd [Form] Throwing an AlreadyBoundException in `add`, `remove`, `setParent`, `bind` and `setData` if called on a bound form
Discussion
----------
[Form] Throwing an AlreadyBoundException in `add`, `remove`, `setParent`, `bind` and `setData` if called on a bound form
Bug fix: yes
Feature addition: no
Backwards compatibility break: **yes**
Symfony2 tests pass: yes
Fixes the following tickets: -
Todo: -
![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue3022)
The above mentioned methods now throw an exception because when invoked on a bound form they might cause strange side effects. You should rely on event listeners instead of modifying bound forms.
See also #3022
Commits
-------
cb6fdb1 [HttpFoundation] removed Session::close()
c59d880 Docblocks.
b8df162 Correct instanceof condition.
8a01dd5 renamed getFlashes() to getFlashBag() to avoid clashes
282d3ae updated CHANGELOG for 2.1
0f6c50a [HttpFoundation] added some method for a better BC
146a502 [FrameworkBundle] added some service aliases to avoid some BC breaks
93d81a1 [HttpFoundation] removed configuration for session storages in session.xml as we cannot provide a way to configure them (like before this PR anyway)
74ccf70 reverted 5b7ef11650 (Simplify session storage class names now we have a separate namespace for sessions)
91f4f8a [HttpFoundation] changed default flash bag to auto-expires to keep BC
0494250 removed unused use statements
7878a0a [HttpFoundation] renamed pop() to all() and getAll() to all()
0d2745f [HttpFoundation] Remove constants from FlashBagInterface
dad60ef [HttpFoundation] Add back get defaults and small clean-up.
5b7ef11 [HttpFoundation] Simplify session storage class names now we have a separate namespace for sessions.
27530cb [HttpFoundation] Moved session related classes to own sub-namespace.
4683915 [HttpFoundation] Free bags from session storage and move classes to their own namespaces.
d64939a [DoctrineBridge] Refactored driver for changed interface.
f9951a3 Fixed formatting.
398acc9 [HttpFoundation] Reworked flashes to maintain same behaviour as in Symfony 2.0
f98f9ae [HttpFoundation] Refactor for DRY code.
9dd4dbe Documentation, changelogs and coding standards.
1ed6ee3 [DoctribeBridge][SecurityBundle][WebProfiler] Refactor code for HttpFoundation changes.
7aaf024 [FrameworkBundle] Refactored code for changes to HttpFoundation component.
669bc96 [HttpFoundation] Added pure Memcache, Memcached and Null storage drivers.
e185c8d [HttpFoundation] Refactored component for session workflow.
85b5c43 [HttpFoundation] Added drivers for PHP native session save handlers, files, sqlite, memcache and memcached.
57ef984 [HttpFoundation] Added unit and functional testing session storage objects.
3a263dc [HttpFoundation] Introduced session storage base class and interfaces.
c969423 [HttpFoundation] Added FlashBagInterface and concrete implementation.
39288bc [HttpFoundation] Added AttributesInterface and AttributesBagInterface and concrete implementations.
Discussion
----------
[2.1][HttpFoundation] Refactor session handling and flash messages
Bug fix: yes
Feature addition: yes
Backwards compatibility break: yes
Symfony2 tests pass: yes
Fixes the following tickets: #2607, #2591, #2717, #2773
References the following tickets: #2592, #2543, #2541, #2510, #2714, #2684
Todo: -
__Introduction__
This extensive PR is a refactor with minimal BC breaks of the `[HttpFoundation]` component's session management which fixes several issues in the current implementation. This PR includes all necessary changes to other bundles and components is documented in the `CHANGELOG-2.1` and `UPGRADING-2.1`.
__Summary of Changes__
__Session:__
- Session object now implements `SessionInterface`
__Attributes:__
- Attributes now handled by `AttributeBagInterface`
- Added two AttributeBag implementations: `AttributeBag` replicates the current Symfony2 attributes behaviour, and the second, `NamespacedAttributeBag` introduces structured namespaced representation using '/' in the key. Both are BC. `FrameworkBundle` defaults to the old behaviour.
__Flash messages:__
- Flash messages now handled by `FlashBagInterface`
- Introduced `FlashBag` which changes the way flash messages expire, they now expire on use rather than automatically, useful for ESI.
- Introduced `AutoExpireFlashBag` (default) which replicates the old automatic expiry behaviour of flash messages.
__Session Storage:__
- Introduced a base object, `AbstractSessionStorage` for session storage drivers
- Introduced a `SessionSaveHandlerInterface` when using custom session save handlers
- Introduced a `NullSessionStorage` driver which allows for unsaved sessions
- Introduced new session storage drivers for Memcache and Memcached
- Introduced new session storage drivers for PHP's native SQLite, Memcache and Memcached support
__General:__
- Fixed bugs where session attributes are not saved and all cases where flash messages would get lost
- Wrote new tests, refactored related existing tests and increased test coverage extensively.
__Rationale/Details__
I'll explain more detail in the following sections.
__Unit Tests__
All unit and functional tests pass.
__Note on Functional Testing__
I've introduced `MockFileSessionStorage` which replaces `FilesystemSessionStorage` to emulate a PHP session for functional testing. Essentially the same methodology of functional testing has been maintained but without interrupting the other session storage drivers interaction with real PHP sessions. The service is now called `session.storage.mock_file`.
__Session Workflow__
PHP sessions follow a specific workflow which is not being followed by the current session management implementation and is responsible for some unpredictable bugs and behaviours.
Basically, PHP session workflow is as follows: `open`, `read`, `write`, `close`. In between these can occur, `destroy` and `garbage collection`. These actions are handled by `session save handlers` and one is always registered in all cases. By default, the `files` save handler (internally to PHP) is registered by PHP at the start of code execution.
PHP offers the possibility to change the save handler to another internal type, for example one provided by a PHP extension (think SQLite, Memcache etc), or you can register a user type and set your own handlers. However __in all cases__ PHP requires the handlers.
The handlers are called when the following things occur:
- `open` and `read` when `session_start()` or the session autostarts when PHP outputs some display
- `destroy` when `session_regenerate_id(true)` is called
- `write` and `close` when PHP shuts down or when `session_write_close()` is called
- `garbage collection` is called randomly according to configurable probability
The next very important aspect of this PR is that `$_SESSION` plays an important part in this workflow because the contents of the $_SESSION is populated __after__ the `read` handler returns the previously saved serialised session data. The `write` handler is sent the serialised `$_SESSION` contents for save. Please note the serialisation is a different format to `serialize()`.
For this reason, any session implementation cannot get rid of using `$_SESSION`.
I wrote more details on this issue [here](https://github.com/symfony/symfony/issues/2607#issuecomment-2858300)
In order to make writing session storage drivers simple, I created a light base class `AbstractSessionStorage` and the `SessionSaveHandlerInterface` which allows you to quickly write native and custom save handler drivers.
__Flash Messages [BC BREAK]__
Flash messages currently allow representation of a single message per `$name`. Fabien designed the original system so that `$name` was equivalent to flash message type. The current PR changes the fact that Flash messages expire explicitly when retrieved for display to the user as opposed to immediately on the next page load.
The last issue fixes potential cases when flash messages are lost due to an unexpected intervening page-load (an error for example). The API `get()` has a flag which allows you to override the `clear()` action.
__Flash message translation__
This PR does not cover translation of flash messages because messages should be translated before calling the flash message API. This is because flash messages are used to present messages to the user after a specific action, and in any case, immediately on the next page load. Since we know the locale of the request in every case we can translate the message before storing. Secondly, translation is simply a string manipulation. Translation API calls should always have the raw untranslated string present because it allows for extraction of translation catalogs. For a complete answer see my answer [here](https://github.com/symfony/symfony/pull/2543#issuecomment-2858707)
__Session attribute and structured namespacing__
__This has been implemented without changing the current default behaviour__ but details are below for the alternative:
Attributes are currently stored in a flat array which limits the potential of session attributes:
Here are some examples to see why this 'structured namespace' methodology is extremely convenient over using a flat system. Let's look at an example with csrf tokens. Let's say we have multiple csrftokens stored by form ID (allowing multiple forms on the page and tabbed browsing).
If we're using a flat system, you might have
'tokens' => array('a' => 'a6c1e0b6',
'b' => 'f4a7b1f3')
With a flat system when you get the key `tokens`, you will get back an array, so now you have to analyse the array. So if you simply want to add another token, you have to follow three steps: get the session attribute `tokens`, have to add to the array, and lastly set the entire array back to the session.
$tokens = $session->get('tokens');
$tokens['c'] = $value;
$session->set('tokens', $tokens);
Doable, but you can see it's pretty long winded.
With structured namespacing you can simply do:
$session->set('c', $value, '/tokens');
There are several ways to implement this, either with an additional `$namespace` argument, or by treating a character in the `$key` as a namespacer. `NamespacedAttributeBag` treats `/` as a namespacer so you can represent `user.tokens/a` for example. The namespace character is configurable in `NamespacedAttributeBag`.
---------------------------------------------------------------------------
by marijn at 2011-12-18T15:43:17Z
I haven't read the code yet but the description from this PR and your line of thought seem very well structured.
Seems like a big +1 for me.
---------------------------------------------------------------------------
by lsmith77 at 2011-12-19T16:01:19Z
@deviantintegral could you look over this to see if it really addresses everything you wanted with PR #2510 ?
---------------------------------------------------------------------------
by deviantintegral at 2011-12-24T20:12:03Z
I've read through the documentation and upgrade notes, and I can't see anything that's obviously missing from #2510. Being able to support multiple flashes per type is the most important, and the API looks reasonable to me. Drupal does support supressing repeat messages, but that can easily be implemented in our code unless there's a compelling case for it to be a part of Symfony.
I wonder if PHP memcache support is required in Symfony given the availability of memcached. I'm not familiar with how other parts of Symfony handle it, but there is often quite a bit of confusion between the two PHP extensions. It could be simpler to remove one, or add a bit of info describing or linking to why there are two nearly identical classes.
Is it possible to make one class inherit from the other (memcached is a child of memcache)?
---------------------------------------------------------------------------
by Fristi at 2011-12-24T20:29:46Z
Interesting, maybe add: session events as I did with the current impl: https://github.com/Fristi/SessionBundle
---------------------------------------------------------------------------
by drak at 2011-12-25T00:50:03Z
@deviantintegral - I agree about the confusion between memcache and memcached but actually, it is necessary to support both because `memcached` is not available everywhere. For example on Debian Lenny and RHEL/CentOS 5, only memcache is available by default. This would preclude a massive amount of shared hosting environments. Also, it is not possible to inherit one from the other, they are completely different drivers.
@Fristi - I also thought about the events, but they do not belong as part of the standalone component as this would create a coupling to the event dispatcher. The way you have done it, ie, in a bundle is the right way to achieve it.
---------------------------------------------------------------------------
by matheo at 2011-12-25T01:12:00Z
Impressive work, looks like a big improvement and deserves a big +1
---------------------------------------------------------------------------
by datiecher at 2011-12-26T11:57:12Z
Took some time to grok all the changes in this PR but all in all it is a keeper. Specially the new flash message API, it's really nicer to work with it then the previous one.
Nicely done @drak!
---------------------------------------------------------------------------
by lsmith77 at 2012-01-02T15:00:00Z
@fabpot did you have time to review this yet? with all the work @drak has done its important that he gets some feedback soon. its clear this PR breaks BC in ways we never wanted to allow. but i think this PR also clearly explains why its necessary none the less.
---------------------------------------------------------------------------
by drak at 2012-01-02T15:41:53Z
@fabpot - I have removed the WIP status from this PR now and rebased against the current master branch.
---------------------------------------------------------------------------
by Tobion at 2012-01-07T07:13:38Z
From what I read from the IRC chat logs, the main concern of @fabpot is whether we really need multiple flash messages per type. I'm in favor of this PR and just want to add one point to this discussion.
At the moment you can add multiple flash messages of different type/category/identifier. For example you can specify one error message and one info message after an operation. I think most agree that this can be usefull.
But then it makes semantically no sense that you currently cannot add 2 info messages. This approach feels a bit half-done.
So I think this PR eliminates this paradox.
---------------------------------------------------------------------------
by drak at 2012-01-07T09:11:07Z
For reference there is also a discussion started by @lsmith77 on the mailing list at https://groups.google.com/forum/#!topic/symfony-devs/cy4wokD0mQI
---------------------------------------------------------------------------
by dlsniper at 2012-01-07T16:02:15Z
@drak I could also add the next scenario that I currently have to live with, in addition to @lsmith77 ones.
I had this issue while working on our shopping cart implementation for a customer where the customer wanted to show the unavailability of the items as different lines in the 'flash-error' section of the cart. We had to set an array as the 'flash message' in order to display that information.
So in this case for example having the flash messages types as array would actually make more sense that sending an array to the flasher. Plus the the other issue we had was that we also wanted to add another error in the message but we had to do a check to see if the flash message is an array already or we need to make it an array.
I think it's better not to impose a limit of this sort and let the users be able to handle every scenario, even if some are rare, rather that forcing users to overcome limitations such as these.
I really hope this PR gets approved faster and thanks everyone for their hard work :)
---------------------------------------------------------------------------
by Tobion at 2012-01-07T21:01:07Z
@dlsniper I think you misinterpreted my point.
---------------------------------------------------------------------------
by dlsniper at 2012-01-07T21:04:04Z
@Tobion I'm sorry I did that, I'll edit the message asap. Seems no sleep in 26 hours can cause brain not to function as intended :)
---------------------------------------------------------------------------
by lsmith77 at 2012-02-01T14:38:52Z
FYI the drupal guys are liking this PR (including the flash changes):
http://drupal.org/node/335411
---------------------------------------------------------------------------
by drak at 2012-02-01T14:51:33Z
@lsmith77 Fabien asked me to remove the changes to the flash messages so that they are as before - i.e. only one flash per name/type /cc @fabpot
---------------------------------------------------------------------------
by fabpot at 2012-02-01T14:58:23Z
To be clear, I've asked to split this PR in two parts:
* one about the session refactoring (which is non-controversial and should be merged ASAP)
* this one with only the flash refactoring
---------------------------------------------------------------------------
by drak at 2012-02-02T11:29:26Z
@fabpot this is ready to be merged now. I will open a separate PR later today for the flash messages as a bucket.
---------------------------------------------------------------------------
by fabpot at 2012-02-02T11:34:39Z
I must have missed something, but I still see a lot of changes related to the flash messages.
---------------------------------------------------------------------------
by drak at 2012-02-02T11:39:10Z
When I spoke to you you said you wanted to make the commit with flash messages with one message per name/type rather than multiple. The old flash messages behaviour is 100% maintained in `AutoExpireFlashBag` which can be the default in the framework if you wish. The `FlashBag` implementation makes Symfony2 ESI compatible.
---------------------------------------------------------------------------
by stof at 2012-02-02T11:47:38Z
@drak splitting into 2 PRs means you should not refactor the flash messages in this one but in the dedicated one.
---------------------------------------------------------------------------
by drak at 2012-02-02T12:29:43Z
@stof Yes. I discussed with Fabien over chat there are basically no changes
to flashes in `FlashBag` and `AutoExpireFlashBag` maintains the exact
behaviour as before. The FlashBag just introduces ESI compatible flashes.
There is no way to refactor the sessions without moving the flash messages
to their own bag. The next PR will propose the changes to flashes that
allow multiple messages per name/type. I can size the PR down a little
more removing the new storage drivers and so on to make the PR smaller but
that's really as far as I can go. To be clear, while the API has changed a
little for flashes, the behaviour is the same.
Rename ArraySessionStorage to make it clear the session is a mock for testing purposes only.
Has BC class for ArraySessionStorage
Added sanity check when starting the session.
Fixed typos and incorrect php extension test method
session_module_name() also sets session.save_handler, so must use extension_loaded() to check if module exist
or not.
Respect autostart settings.
Session object now implements SessionInterface to make it more portable.
AbstractSessionStorage and SessionSaveHandlerInterface now makes implementation
of session storage drivers simple and easy to write for both custom save handlers
and native php save handlers and respect the PHP session workflow.
This commit outsources the flash message processing to it's own interface.
Overall flash messages now can have multiple flash types and each type can
store multiple messages. For convenience there are now four flash types
by default, INFO, NOTICE, WARNING and ERROR.
There are two concrete implementations: one preserving the old behaviour of
flash messages expiring exactly after one page load, regardless of being
displayed or not; and the other where flash messages persist until explicitly
popped.
This commit outsources session attribute storage to it's own class.
There are two concrete implementations, one with structured namespace storage and the other
without.
Commits
-------
ac59db7 cleanup
64ea95d [WebProfilerBundle] Add redirection info to the router panel
826bd23 [FrameworkBundle] fix phpDoc of ControllerResolver::createController()
e3cf37f [HttpFoundation] RedirectResponse: add the ability to retrieve the target URL, add unit tests
50c85ae [WebProfiler] Add info to the router panel
Discussion
----------
[WIP][Profiler] Routing
former #3206 part 3 (depends on part 1 - #3280)
The goal of this PR is to fix#3264 by adding redirection infos on the router panel.
Done:
* Add info on the target url / route
To do:
* Display an accurate URL matching process (when using the RedirectableUrlMatcher)
Commits
-------
22c8f80 [Form] Fixed issues mentioned in the PR comments
3b1b570 [Form] Fixed: The "date", "time" and "datetime" types can be initialized with \DateTime objects
88ef52d [Form] Improved FormType::getDefaultOptions() to see default options defined in parent types
b9facfc [Form] Removed undefined variables in exception constructor
Discussion
----------
[Form] Fixed: "date", "time" and "datetime" fields can be initialized with \DateTime objects
Bug fix: yes
Feature addition: yes
Backwards compatibility break: **yes**
Symfony2 tests pass: yes
Fixes the following tickets: #3288
Todo: -
![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue3288)
Fixed exception that was thrown when doing:
$builder->add('createdAt', 'date', array('data' => new \DateTime()));
On a side note, the options passed to `FieldType::getDefaultOptions` now always also contain the default options of any parent types. This is necessary if you want to be independent of how `getDefaultOptions` is implemented in the parent type and still rely on the already defined values.
As a result, `FieldType::getParent` doesn't see default options anymore. This shouldn't be a big problem, because this method only relies on options in few cases. If it does, options now need to be checked for existence with `isset` before being used (BC break).
---------------------------------------------------------------------------
by bschussek at 2012-02-09T16:14:46Z
@fabpot Ready to merge.
---------------------------------------------------------------------------
by bschussek at 2012-02-10T12:15:04Z
@fabpot Ready to merge
Commits
-------
da2447e [Form] Fixed MergeCollectionListener when used with a custom property path
b56502f0 [Form] Added getParent() to PropertyPath
7e5104e [Form] Fixed MergeCollectionListener for the case that the form's data is updated by the data mapper (as happening in CollectionType)
Discussion
----------
[Form] Fixed MergeCollectionListener for the case that the form's data is updated by the data mapper
Bug fix: yes
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #3293, #1499
Todo: -
![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue3293)
This fixes CollectionType to properly use adders and removers. Apart from that, adders and removers now work with custom property paths. PropertyPath was extended for a method `getParent`.
---------------------------------------------------------------------------
by bschussek at 2012-02-10T07:42:13Z
@fabpot Ready to merge.
Commits
-------
0a4519d [Form] Fixed duplicate errors on forms with "error_bubbling"=false
Discussion
----------
[Form] Fixed duplicate errors on forms with "error_bubbling"=false
Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #2308
Todo: -
![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue2308)
Commits
-------
411a0cc [Validator] Added GroupSequenceProvider to changelog
815c769 [Validator] Renamed getValidationGroups to getGroupSequence
d84a2e4 [Validator] Updated test expectations
9f2310b [Validator] Fixed typos, renamed hasGroupSequenceProvider
e0d2828 [Validator] GroupSequenceProvider tests improved, configuration changed
c3b04a3 [Validator] Changed GroupSequenceProvider implementation
6c4455f [Validator] Added GroupSequenceProvider
Discussion
----------
[Validator] Added GroupSequenceProvider
Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: ![](https://secure.travis-ci.org/blogsh/symfony.png?branch=dynamic_group_sequence)
As discussed in #3114 I implemented the "GroupSequenceProvider" pattern for the validator component. It allows the user to select certain validation groups based on the current state of an object. Here is an example:
/**
* @Assert\GroupSequenceProvider("UserGroupSequnceProvider")
*/
class User
{
/**
* @Assert\NotBlank(groups={"Premium"})
*/
public function getAddress();
public function hasPremiumSubscription();
}
class UserGroupSequenceProvider implements GroupSequenceProviderInterface
{
public function getValidationGroups($user)
{
if ($user->hasPremiumSubscription()) {
return array('User', 'Premium');
} else {
return array('User');
}
}
}
With this patch there are two mechanisms to define the group sequence now. Either you can use @GroupSequence to define a static order of validation groups or you can use @GroupSequenceProvider to create dynamic validation group arrays.
The ClassMetadata therefore has methods now which implement quite similar things. The question is whether it would make sense to interpret the static group sequence as a special case and create something like a DefaultGroupSequenceProvider or StaticGroupSequenceProvider which is assigned by default. This would cause a BC break inside the validator component.
---------------------------------------------------------------------------
by bschussek at 2012-01-28T13:39:54Z
I like the implementation, but I think we should differ a little bit from Java here.
1. `GroupSequenceProviderInterface` should be implemented by the domain classes themselves (`User`), not by a separate class.
2. As such, the parameter `$object` from `getValidationGroups($object)` can be removed
3. `ClassMetadata::setGroupSequenceProvider()` should accept a boolean to activate/deactivate this functionality. Also the check for the interface (does the underlying class implement it?) should be done here
Apart from that, special cases need to be treated:
* A definition of a group sequence and a group sequence provider in the same `ClassMetadata` should not be allowed. Either of them must not be set.
* Metadata loaders must take care of settings made by parent classes. If `Animal` is extended by `Dog`, `Animal` defines a group sequence (or group sequence provider) and `Dog` a group sequence provider (or group sequence), only the setting of `Dog` should apply
---------------------------------------------------------------------------
by blogsh at 2012-01-28T21:25:37Z
Changes of the latest commit:
- GroupSequenceProviderInterface has to be implemented by the domain class
- The annotation/configuration options let the user define whether the provider is activated or not (is this neccessary at all?)
- An error is thrown if the user wants to use static group sequences and the provider simultaneously
At the moment neither the static group sequence nor the provider is inherited from parent classes or interfaces. I don't know if it would make sense to enable this feature. There could be problems if a user wants to define a static group sequence in the parent class and a sequence provider in the child class.
---------------------------------------------------------------------------
by bschussek at 2012-01-30T13:07:04Z
> There could be problems if a user wants to define a static group sequence in the parent class and a sequence provider in the child class.
In this case, the setting in the child class should override the setting of the parent class.
But we can leave this open for now. As it seems, [this issue is unresolved in Hibernate as well](https://hibernate.onjira.com/browse/HV-467).
---------------------------------------------------------------------------
by blogsh at 2012-01-30T22:54:41Z
Okay, finally I managed to upload the latest commit. If you got a bunch of notifications or so I'm sorry, but I had to revert some accidental changes in the commit :(
I've rewritten the tests and have removed the "active" setting in the XML configuration.
---------------------------------------------------------------------------
by blogsh at 2012-02-02T15:24:01Z
Okay, typos are fixed now and `hasGroupSequenceProvider` has been renamed to `isGroupSequenceProvider`. I also had to adjust some tests after the rebase with master.
---------------------------------------------------------------------------
by bschussek at 2012-02-03T09:25:19Z
Looks good.
@fabpot 👍
---------------------------------------------------------------------------
by fabpot at 2012-02-03T09:46:52Z
Can you add a note in the CHANGELOG before I merge? Thanks.
---------------------------------------------------------------------------
by blogsh at 2012-02-09T12:31:27Z
@fabpot done
Commits
-------
ba3b321 [ClassLoader] Added a class map file generator utility
Discussion
----------
[ClassLoader] Added a class map file generator utility
Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #2407
---------------------------------------------------------------------------
by lsmith77 at 2011-11-30T19:33:52Z
@thesalla do you have time/interest to finish this up?
---------------------------------------------------------------------------
by thesalla at 2011-12-01T09:55:50Z
sure (will attempt at least), but no sooner than tomorrow
---------------------------------------------------------------------------
by stof at 2011-12-12T20:41:41Z
@thesalla @fabpot what is the state of this PR ?
---------------------------------------------------------------------------
by thesalla at 2011-12-17T19:36:58Z
If you don't have any other suggestions or ideas, I'd consider it finished.
---------------------------------------------------------------------------
by lsmith77 at 2012-01-24T09:27:12Z
ping
---------------------------------------------------------------------------
by fabpot at 2012-02-02T08:21:38Z
@thesalla: Can you rename the ClassMapDumper class to ClassMapGenerator and then squash your commit before the merge? Thanks.
---------------------------------------------------------------------------
by thesalla at 2012-02-04T12:55:48Z
@fabpot done.