<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>symfony 2 | Nerdpress.org</title>
	<atom:link href="https://nerdpress.org/tag/symfony-2/feed/" rel="self" type="application/rss+xml" />
	<link>https://nerdpress.org</link>
	<description>...dev, tech problems and solutions.</description>
	<lastBuildDate>Mon, 29 Mar 2021 09:42:39 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>[Symfony 2] composer.json for a assumed-stable symfony 2 distribution</title>
		<link>https://nerdpress.org/2012/04/01/symfony-2-composer-json-for-a-assumed-stable-symfony-2-distribution/</link>
					<comments>https://nerdpress.org/2012/04/01/symfony-2-composer-json-for-a-assumed-stable-symfony-2-distribution/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 01 Apr 2012 12:18:54 +0000</pubDate>
				<category><![CDATA[Doctrine ORM]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Project Setup]]></category>
		<category><![CDATA[Silex]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Twig]]></category>
		<category><![CDATA[composer.phar]]></category>
		<category><![CDATA[dependency management]]></category>
		<category><![CDATA[packagist]]></category>
		<category><![CDATA[symfony 2]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=2118</guid>

					<description><![CDATA[<p>This small composer.json file is used in a project i am working on atm, feel free to use it at own risk. I will provide non-periodical updates and hopefully soon a full upgrade to symfony 2.1.x including doctrine orm 2.2.x. I still did not get the point regarding dependency resolution, so i simply &#8220;composed&#8221; the &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2012/04/01/symfony-2-composer-json-for-a-assumed-stable-symfony-2-distribution/" class="more-link">Continue reading<span class="screen-reader-text"> "[Symfony 2] composer.json for a assumed-stable symfony 2 distribution"</span></a></p>
The post <a href="https://nerdpress.org/2012/04/01/symfony-2-composer-json-for-a-assumed-stable-symfony-2-distribution/">[Symfony 2] composer.json for a assumed-stable symfony 2 distribution</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>This small composer.json file is used in a project i am working on atm, feel free to use it at own risk. I will provide non-periodical updates and hopefully soon a full upgrade to symfony 2.1.x including doctrine orm 2.2.x.</p>
<p>I still did not get the point regarding dependency resolution, so i simply &#8220;composed&#8221; the composer file by writing down my own requirements (&#8220;i want only the hottest, newest stuff!!&#8221;, then tracked down the error messages, removing them by explicetly writing down the missing dependencies by using the latest &#8220;dev-*&#8221; versions. After that i tried to run the project, which actually did not work, but selective downgrade of some of the bundles (framework, security-extra blahblah) finally did the job.<span id="more-2118"></span></p>
<p>Feel free to use it in your own projects:</p>
<pre class="brush: jscript; title: ; notranslate">
{
	&quot;require&quot; : {
              &quot;symfony/symfony&quot; : &quot;v2.0.12&quot;,
              &quot;doctrine/common&quot; : &quot;2.1.4&quot;,
              &quot;doctrine/orm&quot; : &quot;2.1.6&quot;,
              &quot;symfony/finder&quot; : &quot;v2.0.12&quot;,

              &quot;symfony/assetic-bundle&quot; : &quot;2.0-dev&quot;,
              &quot;twig/extensions&quot; : &quot;dev-master&quot;,
              &quot;jms/security-extra-bundle&quot; : &quot;1.1.0&quot;,
              &quot;sensio/framework-extra-bundle&quot; : &quot;2.0-dev&quot;,
              &quot;sensio/distribution-bundle&quot; : &quot;2.0-dev&quot;,
              &quot;sensio/generator-bundle&quot; : &quot;2.0-dev&quot;

 	},
        &quot;autoload&quot; : {
            &quot;psr-0&quot; : {
                &quot;Acme&quot; : &quot;src/&quot;,
            }
        }
}

</pre>
<p>Create a file named &#8220;composer.json&#8221; in your project&#8217;s root directory, then paste the above code into it and save it.</p>
<p>Now run</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -s http://getcomposer.org/installer | php
</pre>
<p>After that, download all dependencies by typing</p>
<pre class="brush: bash; title: ; notranslate">
$ php composer.phar install
</pre>
<p>The easiest way to create a full project including AcmeDemoBundle, AppKernel and the whole stuff is to download the symfony 2 standard distribution without vendors and calling the script from there. The only thing to do is to modify the path to autoload.php, which should point to vendor/.composer/autoload.php.</p>
<p>Now you are able to upgrade your project&#8217;s dependencies to the newest versions by simply modifying the composer.json file. Have fun!.</p>The post <a href="https://nerdpress.org/2012/04/01/symfony-2-composer-json-for-a-assumed-stable-symfony-2-distribution/">[Symfony 2] composer.json for a assumed-stable symfony 2 distribution</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2012/04/01/symfony-2-composer-json-for-a-assumed-stable-symfony-2-distribution/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>modulo in Twig</title>
		<link>https://nerdpress.org/2012/02/14/modulo-in-twig/</link>
					<comments>https://nerdpress.org/2012/02/14/modulo-in-twig/#comments</comments>
		
		<dc:creator><![CDATA[Ivo Bathke]]></dc:creator>
		<pubDate>Tue, 14 Feb 2012 16:05:48 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Twig]]></category>
		<category><![CDATA[symfony 2]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=2078</guid>

					<description><![CDATA[<p>Ever wondered how to use the modulo operator in twig, the template engine of symfony? Actually its like in PHP: {{ 11 % 7 }} As described here But i guess for most use cases modulus is used to check if a number is divisible by another number. Therefore Twig has the very conveniant divisible &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2012/02/14/modulo-in-twig/" class="more-link">Continue reading<span class="screen-reader-text"> "modulo in Twig"</span></a></p>
The post <a href="https://nerdpress.org/2012/02/14/modulo-in-twig/">modulo in Twig</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Ever wondered how to use the <strong>modulo</strong> operator in twig, the template engine of symfony?</p>
<p>Actually its like in PHP:</p>
<pre class="brush: php; title: ; notranslate">{{ 11 % 7 }}</pre>
<p>As described <a href="http://twig.sensiolabs.org/doc/templates.html#math">here</a></p>
<p>But i guess for most use cases <strong>modulus</strong> is used to check if a number is divisible by another number.<br />
Therefore Twig has the very conveniant <a href="http://twig.sensiolabs.org/doc/tests/divisibleby.html">divisible by</a> test function.</p>
<pre class="brush: php; title: ; notranslate">{% if loop.index is divisible by(3) %}</pre>
<p><span id="more-2078"></span><br />
Another modulo use case is to check odd and even rows in loops. There Twig has the built-in function <a href="http://twig.sensiolabs.org/doc/functions/cycle.html">cycle</a> to help you.</p>
<pre class="brush: php; title: ; notranslate">{{ cycle(&#x5B;'odd', 'even'], i) }}</pre>
<p>Once you know its so eeasy;)</p>The post <a href="https://nerdpress.org/2012/02/14/modulo-in-twig/">modulo in Twig</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2012/02/14/modulo-in-twig/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>[Symfony 2][Twig] &#8211; Enabling (native) Twig Extensions</title>
		<link>https://nerdpress.org/2011/10/19/symfony-2-twig-enabling-native-twig-extensions/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 19 Oct 2011 11:39:46 +0000</pubDate>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Project Setup]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[DIC]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[symfony 2]]></category>
		<category><![CDATA[Twig]]></category>
		<category><![CDATA[Twig Extension]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1899</guid>

					<description><![CDATA[<p>Twig Extensions is a tiny official repository for extensions to the Twig templating markup language, the default templating engine in each Symfony 2 (Standard Ed.) project. This short article shows how to purposeful enable them per-environment for your projects. The twig-extension repository is usually fetched by calling $ bin/vendor install into your project´s ./vendor directory &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2011/10/19/symfony-2-twig-enabling-native-twig-extensions/" class="more-link">Continue reading<span class="screen-reader-text"> "[Symfony 2][Twig] &#8211; Enabling (native) Twig Extensions"</span></a></p>
The post <a href="https://nerdpress.org/2011/10/19/symfony-2-twig-enabling-native-twig-extensions/">[Symfony 2][Twig] – Enabling (native) Twig Extensions</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p><a href="https://github.com/fabpot/Twig-extensions">Twig Extensions</a> is a tiny official repository for extensions to the <a href="http://twig.sensiolabs.org/">Twig templating markup language</a>, the default templating engine in each Symfony 2 (Standard Ed.) project. This short article shows how to purposeful enable them per-environment for your projects.</p>
<p><span id="more-1899"></span></p>
<p>The twig-extension repository is usually fetched by calling</p>
<pre class="brush: bash; title: ; notranslate">
$ bin/vendor install
</pre>
<p>into your project´s ./vendor directory (because it is part of the ./deps file of each symfony 2 standard edition).</p>
<p>After installing the required vendor files, register the namespace fallback in your autoload.php (if you use the one delivered with Symfony 2 Standard, this should already have been done for you):</p>
<pre class="brush: php; title: ; notranslate">
use Symfony\Component\ClassLoader\UniversalClassLoader;
use Doctrine\Common\Annotations\AnnotationRegistry;

$loader = new UniversalClassLoader();
$loader-&gt;registerNamespaces(array(
    'Symfony'          =&gt; array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
    // ...
));

$loader-&gt;registerPrefixes(array(
    'Twig_Extensions_' =&gt; __DIR__.'/../vendor/twig-extensions/lib',
    'Twig_'            =&gt; __DIR__.'/../vendor/twig/lib',
));
</pre>
<p>Remember that twig extensions are always registered as <a href="http://symfony.com/doc/2.0/book/service_container.html#tags-tags">tagged services</a>, but it is not always desirable to register a twig extension like e.g. the Debug-Extension as a regular service globally. We could do so by adding the service definition to the services.xml-file in one of our bundles. But due to the special purpose of the debug extension, we will choose a different, more &#8220;project-wide-configuration&#8221;-way.</p>
<p>Luckily, Symfony provides means to dynamically load services &#8220;on demand&#8221; and depending on the current <a href="http://symfony.com/doc/2.0/cookbook/configuration/environments.html">environment</a>.</p>
<p>Add the following lines to your app/config/config_dev.yml:</p>
<pre class="brush: python; title: ; notranslate">
services:
    debug.twig.extension:
        class: Twig_Extensions_Extension_Debug
        tags: &#x5B;{ name: 'twig.extension' }]
</pre>
<p>The &#8220;services&#8221;-configuration option may be utilized to register any class as a <a href="http://symfony.com/doc/2.0/book/service_container.html">DIC</a> managed <a href="http://symfony.com/doc/2.0/book/service_container.html#what-is-a-service">service</a>, for each project and independent from your bundle configuration (But remember that &#8220;regular&#8221; service definition configuration should usually happen in your bundle´s configuration files, otherwise you will not able to distribute your bundles because of missing or broken dependencies).</p>
<p>For twig extensions that should only be loaded for special purposes (like our DEBUG-function which is only needed in development environments), config_dev.yml is the perfect place to register them.</p>
<p>Note the &#8220;tags&#8221;-configuration which marks the service as a twig extension. Now, let´s create a demo twig-template and try the {% debug %} function:</p>
<pre class="brush: xml; title: ; notranslate">
{% extends &quot;NerdpressDemoBundle::layout.html.twig&quot; %}
{% debug %}
</pre>
<p>That will do. Open the page in your favorite webbrower (after defining a route, a controller and other stuff i won´t mention here) and admire the debug output. Note that the output will be much more nicer if you have had installed a native php debug extension like e.g. <a href="http://xdebug.org/">XDebug</a>.</p>The post <a href="https://nerdpress.org/2011/10/19/symfony-2-twig-enabling-native-twig-extensions/">[Symfony 2][Twig] – Enabling (native) Twig Extensions</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Symfony 2 &#8211; Set Default Locale On Form Login #2</title>
		<link>https://nerdpress.org/2011/10/13/symfony-2-set-default-locale-on-form-login-2/</link>
					<comments>https://nerdpress.org/2011/10/13/symfony-2-set-default-locale-on-form-login-2/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 13 Oct 2011 16:14:05 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Locale]]></category>
		<category><![CDATA[Request]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Session]]></category>
		<category><![CDATA[symfony 2]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1891</guid>

					<description><![CDATA[<p>A small update/correction out of sequence: A few weeks ago i described how to hook into the form login process in order to change the user session´s locale. In the meantime a non backwards compatible code modification has been introduced that outdated this article. From now on (Symfony 2.0.4) the locale and default locale settings &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2011/10/13/symfony-2-set-default-locale-on-form-login-2/" class="more-link">Continue reading<span class="screen-reader-text"> "Symfony 2 &#8211; Set Default Locale On Form Login #2"</span></a></p>
The post <a href="https://nerdpress.org/2011/10/13/symfony-2-set-default-locale-on-form-login-2/">Symfony 2 – Set Default Locale On Form Login #2</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>A small update/correction out of sequence:</p>
<p><a href="https://nerdpress.org/2011/08/14/symfony-2-security-bundle-set-user-locale-on-form-login/">A few weeks ago i described how to hook into the form login process in order to change the user session´s locale.</a></p>
<p>In the meantime a non backwards compatible code modification has been <a href="http://symfony.com/blog/a-week-of-symfony-249-3-9-october-2011">introduced</a> that outdated this article. From now on (Symfony 2.0.4) the locale and default locale settings are maintained within the request object (and not as used to be in the session).</p>
<p>So, here is a little update &#8211; under reserve &#8211; because the locale setting´s logic will probably <a href="https://github.com/symfony/symfony/commit/74bc699b270122b70b1de6ece47c726f5df8bd41">change again in the future</a>.</p>
<p><span id="more-1891"></span></p>
<p>At first, the new locale maintenance code by using a LocaleListener is <a href="https://github.com/symfony/symfony/issues/search?q=locale">still buggy</a>. Specially this issue breaks the whole thing atm: https://github.com/symfony/symfony/issues/2386</p>
<p>A quick workaround is to change the priority of the listener from 255 to let´s say 127. That forces the SessionListener to initialize the session right BEFORE the locale listener, so that $request->hasPreviousSession() has actually the chance to return TRUE.</p>
<p>Change Symfony\Component\HttpKernel\EventListener\LocaleListener, L. 69</p>
<pre class="brush: php; title: ; notranslate">
KernelEvents::REQUEST =&gt; array(array('onEarlyKernelRequest', 255), array('onKernelRequest', -1)),
</pre>
<p>to</p>
<pre class="brush: php; title: ; notranslate">
KernelEvents::REQUEST =&gt; array(array('onEarlyKernelRequest', 127), array('onKernelRequest', -1)),
</pre>
<p>Hopefully a patch will be available soon to fix the problem &#8211; source code modifications in this way are things YOU MUST NOT DO!</p>
<p>For now and demonstration purposes only, this will fit. After that, it´s easy to modify our <a href="https://nerdpress.org/2011/08/14/symfony-2-security-bundle-set-user-locale-on-form-login/">previously elaborated source code</a> to fit the new circumstances:</p>
<p>Change our listener from:</p>
<pre class="brush: php; title: ; notranslate">
class EventListener
{
    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $token = $event-&gt;getAuthenticationToken();
        $session = $event-&gt;getRequest()-&gt;getSession();
        $session-&gt;setLocale($token-&gt;getUser()-&gt;getLocale());
    }
}
</pre>
<p>into:</p>
<pre class="brush: php; title: ; notranslate">
class EventListener
{
    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $token = $event-&gt;getAuthenticationToken();
         
        $request = $event-&gt;getRequest();
        $session = $request-&gt;getSession();

        $locale = $token-&gt;getUser()-&gt;getLocale();
        $session-&gt;set('_locale', $locale);
        $request-&gt;setLocale($locale);
    }
}
</pre>
<p>I am still not sure if this is the best solution to the problem &#8211; hopefully the new implementation will be well documented in the future or changed in a way the produces less WTFs &#8230;</p>
<p>Any comments appreciated.</p>The post <a href="https://nerdpress.org/2011/10/13/symfony-2-set-default-locale-on-form-login-2/">Symfony 2 – Set Default Locale On Form Login #2</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2011/10/13/symfony-2-set-default-locale-on-form-login-2/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>[Symfony 2] Twig &#8211; Global Variables</title>
		<link>https://nerdpress.org/2011/09/12/symfony-2-twig-global-variables/</link>
					<comments>https://nerdpress.org/2011/09/12/symfony-2-twig-global-variables/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 12 Sep 2011 10:21:22 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Global Variables]]></category>
		<category><![CDATA[symfony 2]]></category>
		<category><![CDATA[Twig]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1647</guid>

					<description><![CDATA[<p>Schon mal gefragt, welche globalen Variablen in der Twig-Extension eines Symfony 2 (Standard Distri)-Projektes zur Verfügung stehen? Schaut man sich die Klasse GlobalVariables im Namespace Symfony\Bundle\FrameworkBundle\Templating an (diese Klasse ist Teil des Framework-Bundles, d.h., Gleiches gilt ebenfalls für PHP als Template-Maschine), wird einiges klarer. Weiter unten eine Liste der Assessoren, die die Klasse bereitstellt: Symfony\Component\Security\Core\SecurityContext&#124;void &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2011/09/12/symfony-2-twig-global-variables/" class="more-link">Continue reading<span class="screen-reader-text"> "[Symfony 2] Twig &#8211; Global Variables"</span></a></p>
The post <a href="https://nerdpress.org/2011/09/12/symfony-2-twig-global-variables/">[Symfony 2] Twig – Global Variables</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Schon mal gefragt, welche globalen Variablen in der Twig-Extension eines Symfony 2 (Standard Distri)-Projektes zur Verfügung stehen?<span id="more-1647"></span><br />
Schaut man sich die Klasse GlobalVariables im Namespace Symfony\Bundle\FrameworkBundle\Templating an (diese Klasse ist Teil des Framework-Bundles, d.h., Gleiches gilt ebenfalls für PHP als Template-Maschine), wird einiges klarer. Weiter unten eine Liste der Assessoren, die die Klasse bereitstellt:</p>
<pre class="brush: bash; title: ; notranslate">
    Symfony\Component\Security\Core\SecurityContext|void         getSecurity()
    Symfony\Component\Security\Core\User\(Advanced)UserInterface getUser()
    Symfony\Component\HttpFoundation\Request|void                getRequest()
    Symfony\Component\HttpFoundation\Session|void                getSession()
    string                                                       getEnvironment()
    bool                                                         getDebug()</pre>
<p>In Twig liegt der Container im &#8220;app&#8221;-Namespace, &#8220;Übersetzt&#8221; nach Twig heißt das ganze also:</p>
<pre class="brush: bash; title: ; notranslate">
    app.security
    app.user
    app.request
    app.session
    app.environment
    app.debug
</pre>
<p>Viel Spaß beim Templates-Bauen ;)</p>The post <a href="https://nerdpress.org/2011/09/12/symfony-2-twig-global-variables/">[Symfony 2] Twig – Global Variables</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2011/09/12/symfony-2-twig-global-variables/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>[Symfony 2] AsseticBundle, Less CSS &#038; YUI Compressor unter OSX installieren</title>
		<link>https://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/</link>
					<comments>https://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 25 Aug 2011 16:55:02 +0000</pubDate>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Assetic]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[less]]></category>
		<category><![CDATA[symfony 2]]></category>
		<category><![CDATA[Twig]]></category>
		<category><![CDATA[yui-compressor]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1600</guid>

					<description><![CDATA[<p>Less CSS und YUI-Compressor mit Assetic unter OSX installieren und innerhalb Symfony 2 konfigurieren.</p>
The post <a href="https://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/">[Symfony 2] AsseticBundle, Less CSS & YUI Compressor unter OSX installieren</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Das AsseticBundle ist ein Wrapper um <a href="https://github.com/kriswallsmith/assetic">Assetic</a>, ein geniales Tool, um statische Assets für Webprojekte zu verwalten. AsseticBundle ist extrem einfach zu verwenden, einfach die entsprechende Filter-Chain via yaml konfigurieren, um mehr muss man sich nicht kümmern. Natürlich allerdings müssen die zugrundeliegenden Abhängigkeiten im Vorfeld installiert sein. In unserem Falle benötigen wir den <a href="http://developer.yahoo.com/yui/compressor/">Yui-Compressor</a> als jar-File und <a href="http://lesscss.org/">Less CSS</a>. Less ist ein <a href="http://nodejs.org/">node.js</a> Modul, was bedingt, dass wir zuvor node.js installieren müssen.<br />
<span id="more-1600"></span></p>
<p>Also node.js via macports holen:</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo port install nodejs
</pre>
<p>Und den node.js-eigenen Package-Manager:</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo port install npm
</pre>
<p>Mit diesem installieren wir als nächsts less, und zwar &#8220;global&#8221; (via -g)-Flag (&#8220;global&#8221; bedeutet, dass das Modul unter $nodejs_lib_path/../node_modules abgelegt wird, ansonsten wird es im aktuellen Arbeitsverzeichnis unter ./node_modules installiert):</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo npm install -g less
</pre>
<p>Damit haben wir alles, um unsere less CSS Stylesheets kompilieren zu können.</p>
<p>Als nächstes holen wir uns den Yui-Kompressor, diesen habe ich mir einfach aus dem Netz gezogen und unter app/java/yuicompressor-2.4.6.jar abgelegt (Die Binary findet ihr unter <a href="http://developer.yahoo.com/yui/compressor/">http://developer.yahoo.com/yui/compressor/</a>).</p>
<p>Nun die Konfiguration:</p>
<p>app/config.yml:</p>
<pre class="brush: python; title: ; notranslate">
# Assetic Configuration
assetic:
    debug:          %kernel.debug%
    use_controller: false
    filters:
        cssrewrite: ~
        less:
          node: /opt/local/bin/node
          node_paths: &#x5B;/opt/local/lib/node, /opt/local/lib/node_modules]
        yui_css:
          jar: %kernel.root_dir%/java/yuicompressor-2.4.6.jar
</pre>
<p>Zu beachten sind die &#8220;node_paths&#8221;. Der node.js-Modulpfad muss explizit angegeben werden, sonst kann node.js die require()-Statements nicht auflösen (das sind sozusagen die node.js-&#8220;Classpaths&#8221;). /opt/local/lib/node zeigt auf Core-Module, in /opt/local/lib/node_modules liegt unser less.</p>
<p>Um den Yui-Kompressor zu aktivieren, reicht der simple Pfad zur .jar-Datei.</p>
<p>Nun müssen wir nur noch unser Twig-Layout anpassen:</p>
<p>src/Nerdpress/DemoBundle/Resources/views/layout.html.twig:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
        {% stylesheets
                '@NerdpressDemoBundle/Resources/public/css/main.css'
                '@NerdpressDemoBundle/Resources/public/css/layout.css'
        	filter='less,?yui_css'
                combine=true
        %}
          &lt;link rel=&quot;stylesheet&quot; href=&quot;{{ asset_url }}&quot; type=&quot;text/css&quot; media=&quot;all&quot; /&gt;
        {% endstylesheets %}
</pre>
<p>Das &#8220;?&#8221; vor dem Filter &#8220;yui_css&#8221; bedingt, dass die CSS-Compression nur angeschaltet wird, wenn der Debug-Parameter auf false steht. &#8220;Combine&#8221; bedeutet, dass alle CSS-Dateien in einer einzigen, großen Datei zusammengefügt werden, und &#8220;less&#8221; bedeutet letztlich, dass alle CSS-Dateien mittels less CSS precompiled werden.</p>
<p>That´s it. Die Seite im Browser öffnen und das Ergebnis bewundern. Viel Spaß! Symfony ist schon was feines&#8230;</p>The post <a href="https://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/">[Symfony 2] AsseticBundle, Less CSS & YUI Compressor unter OSX installieren</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2011/08/25/symfony-2-asseticbundle-less-css-yui-compressor-unter-osx-installieren/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>[Symfony 2] Security Bundle: Set User Locale on Form Login</title>
		<link>https://nerdpress.org/2011/08/14/symfony-2-security-bundle-set-user-locale-on-form-login/</link>
					<comments>https://nerdpress.org/2011/08/14/symfony-2-security-bundle-set-user-locale-on-form-login/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 14 Aug 2011 10:15:30 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Project Setup]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DIC]]></category>
		<category><![CDATA[EventListener]]></category>
		<category><![CDATA[SecurityBundle]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[symfony 2]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1574</guid>

					<description><![CDATA[<p>Anleitung, wie die User-Locale on Login unter anderem über den Symfony Event-Dispatcher zu setzen ist.</p>
The post <a href="https://nerdpress.org/2011/08/14/symfony-2-security-bundle-set-user-locale-on-form-login/">[Symfony 2] Security Bundle: Set User Locale on Form Login</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p><strong>[UPDATE]</strong><br />
A recent update to this article may be found here: <a href="https://nerdpress.org/2011/10/13/symfony-2-set-default-locale-on-form-login-2/">https://nerdpress.org/symfony-2-set-default-locale-on-form-login-2/</a></p>
<p>Das Security Bundle ist ein wenig magisch. Da muss man eine HTML-Form definieren, der Rest wird irgendwie konfiguriert (Namen der Post-Parameter wie &#8220;_username&#8221;, &#8220;_password&#8221; etc., den Redirect zum Referrer, Remember-Me Funktion und so weiter, das alles wird von der Firewall intern geregelt. Man muss nur eine Login-Route definieren, einen Stub-Controller + Action-Callable (der aber nie ausgeführt wird, weil die Firefall sich davorhängt), fertig.</p>
<p>Das ist angenehm einfach, solange man keine Fragen stellt. Aber wie führe ich zusätzliche Aktionen direkt nach erfolgtem Login aus, ohne Einfuss auf den Code des Security Bundles zu haben?</p>
<p><span id="more-1574"></span></p>
<p>Meist sucht man dazu einen Hook, Einstiegspunkt oder eine Konfigurationsvariable. In Symfony 2 sucht man natürlich Events, doch die Doku schweigt sich hierzu noch ein wenig aus, also wieder &#8216;rein in den Sourcecode. Irgendwo muss doch eine Möglichkeit zu finden sein, und tatsächlich, im AbstractAuthentificationListener werden wir fündig:</p>
<p>vendorsymfonysrcSymfonyComponentSecurityHttpFirewallAbstractAuthentificationListener.php</p>
<pre class="brush: php; title: ; notranslate">

namespace SymfonyComponentSecurityHttpFirewall;

//...

abstract class AbstractAuthenticationListener implements ListenerInterface
{
    // ...
    private function onSuccess(GetResponseEvent $event, Request $request, TokenInterface $token)
    {
        if (null !== $this-&gt;logger) {
            $this-&gt;logger-&gt;info(sprintf('User &quot;%s&quot; has been authenticated successfully', $token-&gt;getUsername()));
        }

        $this-&gt;securityContext-&gt;setToken($token);

        $session = $request-&gt;getSession();
        $session-&gt;remove(SecurityContextInterface::AUTHENTICATION_ERROR);
        $session-&gt;remove(SecurityContextInterface::LAST_USERNAME);

        if (null !== $this-&gt;dispatcher) {
            $loginEvent = new InteractiveLoginEvent($request, $token);
            $this-&gt;dispatcher-&gt;dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent);
        }

        if (null !== $this-&gt;successHandler) {
            $response = $this-&gt;successHandler-&gt;onAuthenticationSuccess($request, $token);
        } else {
            $response = $this-&gt;httpUtils-&gt;createRedirectResponse($request, $this-&gt;determineTargetUrl($request));
        }

        if (null !== $this-&gt;rememberMeServices) {
            $this-&gt;rememberMeServices-&gt;loginSuccess($request, $response, $token);
        }

        return $response;
    }
</pre>
<p>Die Klasse ist nur auszugsweise abgedruckt. Interessant sind die Zeilen 233 &amp; 238 im Original-Sourcecode.</p>
<p>Zeile 233 ff. benachrichtigt alle Eventlistener, die auf SecurityEvents::INTERACTIVE_LOGIN hören, wenn ein Event-Dispatcher vorhanden ist (im Falle der Symfony Standard Distribution kann man das voraussetzen).</p>
<p>Zeile 238 ist eine Sonderlocke, sozusagen ein &#8220;Security-Bundle-eigenes&#8221; Event. Man hat die Möglichkeit, in der jeweiligen Firewall-Einstellung für den Form-Login in der security.yml mit success_handler einen eigenen DIC-Service anzugeben, der SymfonyComponentSecurityHttpAuthenticationAuthenticationSuccessHandlerInterface implementiert.</p>
<p>Das sieht dann in etwa so aus:</p>
<pre class="brush: python; title: ; notranslate">
      secured_area:
            pattern:    ^/demo/secured/
            form_login:
                check_path: /demo/secured/login_check
                login_path: /demo/secured/login
                success_handler: dvlp_core.login_success_handler
</pre>
<p>Die Implementierung der Callback-Methode onAuthenticationSuccess(Request $request, TokenInterface $token) des Interfaces ist aber nicht ganz trivial, da als Rückgabewert eben eine Instanz von SymfonyComponentHttpFoundationResponse erwartet wird, die man dann selbsttätig konfigurieren muss (inkl. Rücksprung-Adresse, Referer-Logik und Auswertung der Benutzerkonfiguration). Daher lassen wir das erstmal sein und nutzen den Event-Dispatcher, um uns in den Login hineinzukrallen. Dazu definieren wir einen neuen Service in einem unserer Bundles und taggen ihn als Eventlistener:</p>
<p>Resourcesconfigservices.xml:</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;parameters&gt;
        &lt;parameter key=&quot;dvlp_core.event_listener.class&quot;&gt;DvlpCoreBundleEventListener&lt;/parameter&gt;
    &lt;/parameters&gt;
    &lt;service id=&quot;dvlp_core.event_listener&quot; class=&quot;%dvlp_core.event_listener.class%&quot;&gt;
        &lt;tag name=&quot;kernel.event_listener&quot; event=&quot;security.interactive_login&quot; method=&quot;onSecurityInteractiveLogin&quot; /&gt;
    &lt;/service&gt;
</pre>
<p>Dann implementieren wir den Listener. Dieser Listener soll die Session-Locale &#8220;on login&#8221; auf die Lokalisierungs-Einstellung des aktuellen (Datenbank-)-Users setzen.</p>
<p>DvlpCoreBundleEventListener.php:</p>
<pre class="brush: php; title: ; notranslate">
class EventListener
{
    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $token = $event-&gt;getAuthenticationToken();
        $session = $event-&gt;getRequest()-&gt;getSession();
        $session-&gt;setLocale($token-&gt;getUser()-&gt;getLocale());
    }
}
</pre>
<p>Das war´s auch schon. Events to the Rescue. Leider scheinen diese wirklich noch nicht allzu ausführlich dokumentiert zu sein, ich wäre froh, wenn mir jemand das Gegenteil aufzeigen kann!</p>
<p>Viel Spaß beim Ausprobieren.</p>The post <a href="https://nerdpress.org/2011/08/14/symfony-2-security-bundle-set-user-locale-on-form-login/">[Symfony 2] Security Bundle: Set User Locale on Form Login</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2011/08/14/symfony-2-security-bundle-set-user-locale-on-form-login/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>[Symfony 2] Security Bundle &#8211; Benutzer mit username oder email anmelden.</title>
		<link>https://nerdpress.org/2011/08/12/symfony-2-security-bundle-benutzer-mit-username-oder-email-anmelden/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 12 Aug 2011 13:04:36 +0000</pubDate>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Project Setup]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Doctrine 2]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SecurityBundle]]></category>
		<category><![CDATA[symfony 2]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1566</guid>

					<description><![CDATA[<p>Augenscheinlich unterstützt das Security-Modul in der Standard-Konfiguration nur die Authentifizierung via Benutzername und Password. Wie man sich mit einem Benutzernamen ODER der E-Mail-Adresse und einem Passwort authentifiziert, ist ein wenig versteckt. Das ist die Anleitung, wie es funktioniert.</p>
The post <a href="https://nerdpress.org/2011/08/12/symfony-2-security-bundle-benutzer-mit-username-oder-email-anmelden/">[Symfony 2] Security Bundle – Benutzer mit username oder email anmelden.</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Augenscheinlich unterstützt das Security-Module nur die Authentifizierung via Benutzername und Password. Wie man sich mit einem Benutzernamen ODER der E-Mail-Adresse und einem Password authentifiziert, ist ein wenig versteckt. So gehts:</p>
<p><span id="more-1566"></span></p>
<p>Schaut man sich den generischen EntityUserProvider an, so sieht man ab Zeile 46 sowas wie</p>
<pre class="brush: php; title: ; notranslate">
    /**
     * {@inheritdoc}
     */
    public function loadUserByUsername($username)
    {
        if (null !== $this-&gt;property) {
            $user = $this-&gt;repository-&gt;findOneBy(array($this-&gt;property =&gt; $username));
        } else {
            if (!$this-&gt;repository instanceof UserProviderInterface) {
                throw new InvalidArgumentException(sprintf('The Doctrine repository &quot;%s&quot; must implement UserProviderInterface.', get_class($this-&gt;repository)));
            }

            $user = $this-&gt;repository-&gt;loadUserByUsername($username);
        }

        if (null === $user) {
            throw new UsernameNotFoundException(sprintf('User &quot;%s&quot; not found.', $username));
        }

        return $user;
    }
</pre>
<p>Dieser Code besagt, dass nur dann, wenn die Konfigurationeinstellung &#8220;property&#8221; aus der security.yml entfernt wird (steht üblicherweise auf &#8220;username&#8221; und gibt das Datenbankattribut an, das eben den Benutzernamen hält), das entsprechende Doctrine-Entity &#8220;User&#8221; auch eine Repository-Class hat und diese darüber hinaus UserProviderInterface implementiert, man seine eigene loadUserByUsername()-Methode implementieren kann, die dann von der Firewall zur Identifizierung des Benutzer beim Login herangezogen wird (dieser Vorgang ist komplett intransparent, Symfony Magic).</p>
<p>Also aus seiner &#8220;alten&#8221; security.yml</p>
<pre class="brush: python; title: ; notranslate">
    providers:
        default:
            users:
                user:  { password: userpass, roles: &#x5B; 'ROLE_USER' ] }
                admin: { password: adminpass, roles: &#x5B; 'ROLE_ADMIN' ] }
            entity: { class: DvlpCoreBundleEntityUser, property: username }
</pre>
<p>sowas machen:</p>
<pre class="brush: python; title: ; notranslate">
     ...
            entity: { class: DvlpCoreBundleEntityUser }
</pre>
<p>Dann muss das zu User gehörtige UserRepository nur noch UserProviderInterface implementieren, bspw. so:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

namespace DvlpCoreBundleEntity;

use DoctrineORMEntityRepository;
use SymfonyComponentSecurityCoreUserUserProviderInterface;
use SymfonyComponentSecurityCoreUserUserInterface;

/**
 * UserRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class UserRepository extends EntityRepository implements UserProviderInterface
{
    /**
     * {@inheritdoc}
     */
    public function loadUserByUsername($username)
    {
        return $this-&gt;getEntityManager()
            -&gt;createQuery('SELECT u FROM DvlpCoreBundle:User u JOIN u.Profile p WHERE u.username = :username OR p.email = :username')
            -&gt;setParameters(array(
                'username' =&gt; $username
            ))
            -&gt;getOneOrNullResult();
    }

    /**
     * {@inheritDoc}
     */
    public function refreshUser(UserInterface $user)
    {
        return $this-&gt;loadUserByUsername($user-&gt;getUsername());
    }

    /**
     * {@inheritDoc}
     */
    public function supportsClass($class)
    {
        // NEVER CALLED ...
        return $class === 'DvlpCoreBundleEntityUser';
    }
}
}
</pre>
<p>Schon kann man als Benutzernamen entweder den Username oder die E-Mail-Adresse des Users angeben.</p>The post <a href="https://nerdpress.org/2011/08/12/symfony-2-security-bundle-benutzer-mit-username-oder-email-anmelden/">[Symfony 2] Security Bundle – Benutzer mit username oder email anmelden.</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Symfony 2 wird super. Oder &#8230;?</title>
		<link>https://nerdpress.org/2011/05/11/symfony-2-wird-super-oder/</link>
					<comments>https://nerdpress.org/2011/05/11/symfony-2-wird-super-oder/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Tue, 10 May 2011 22:09:30 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Doctrine ORM]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software engineering]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Design Pattern]]></category>
		<category><![CDATA[DIC]]></category>
		<category><![CDATA[IoC]]></category>
		<category><![CDATA[Software Architecture]]></category>
		<category><![CDATA[symfony 2]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1462</guid>

					<description><![CDATA[<p>Natürlich wird Symfony 2 super. Die Dokumentation ist wie gewohnt zum jetzigen, frühen Zeitpunkt genial, die Architektur durchdacht, die Entwickler-Community steckt sowieso alles in die Tasche, man sieht einfach: Da steckt eine Menge Arbeit, Hirnschmalz und Erfahrung hinter. Aber genug geschleimt ;) Mein Lieblingsthema ist ja zur Zeit der Dependency Injection Container. Und irgendwie stinkt &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2011/05/11/symfony-2-wird-super-oder/" class="more-link">Continue reading<span class="screen-reader-text"> "Symfony 2 wird super. Oder &#8230;?"</span></a></p>
The post <a href="https://nerdpress.org/2011/05/11/symfony-2-wird-super-oder/">Symfony 2 wird super. Oder …?</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Natürlich wird Symfony 2 super. Die Dokumentation ist wie gewohnt zum jetzigen, frühen Zeitpunkt genial, die Architektur durchdacht, die Entwickler-Community steckt sowieso alles in die Tasche, man sieht einfach: Da steckt eine Menge Arbeit, Hirnschmalz und Erfahrung hinter. Aber genug geschleimt ;) </p>
<p>Mein Lieblingsthema ist ja zur Zeit der Dependency Injection Container. Und irgendwie stinkt mir die ganze Container-Konfiguration noch gewaltig. Meine <a href="https://nerdpress.org/2010/09/26/dependency-injection-mit-php-5-3-runkit-erweiterung-und-doctrine-2-annotationen/">kläglichen Versuche</a>, selbst mal so was ähnliches wie eine brauchbare Autowiring-Implementierung herunterzubrechen, waren natürlich auch bzw. erst recht nicht der große Wurf &#8211; was vor allem daran lag, dass ich den Service Container und damit den ganzen Sinn und Zweck des Ganzen einfach mal wegrationalisiert hatte &#8211; Loose Coupling sieht natürlich anders aus, das sei den Kritikern zugestanden. Ich verteidige mich mal dadurch, dass ich eigentlich nur mal mit Mixins rumspielen wollte &#8211; da hab&#8217; ich wohl die eine oder andere Begrifflichkeit durcheinander geworfen. </p>
<p>Aber um mal zu des Pudels Kern zu kommen: Ist es wirklich so geil, mit kilometerlangen XML-Dateien, &#8216;ner Menge Initialisierungscode und ohne mit der heißgeliebten Code-Completion in der IDE meiner Wahl ein Paradigma zu kaufen, das im speziellen Anwendungskontext &#8211; nicht im Framework-Kontext &#8211; eher selten Anwendung findet? </p>
<p><span id="more-1462"></span></p>
<p>Es ist doch so: PHP bietet zwar mittlerweile eine vernünftige Reflection API, aber wenig (keine) Möglichkeiten, Code zur Compile- oder Runtime effizient zu injizieren (vorbei bspw. an der Sichtbarkeit, was für Property Injection aus meiner Sicht erforderlich wäre). Mit Handständen geht das mittels der Reflection API, noch fieser mit bspw. Runkit. </p>
<p>Somit ist &#8211; (natürlich nur aus meiner Sicht, was im Übrigen für den gesamten &#8220;Complaint&#8221; gilt &#8211; dabei wäre ich wirklich froh, berichtigt zu werden) jeder Versuch, die Konfiguration eines wie auch immer gearteten, auf PHP sitzenden, DIC mit Syntactic Sugar anzureichern, vergeblich. Und Syntactic Sugar ist dringend vonnöten, um das Zeug in der Praxis RAD-tauglich zu machen. Nehme ich PHP den RAD-Faktor, was bleibt denn dann noch übrig?</p>
<p>Symfony 2 behilft sich damit, einen DI-Container zu definieren und ihn als PHP-Code wegzucachen. Dieser hat dann Accessoren für alle definierten Services, Constructor-Injection ist durch Referenzierung in den Konfigurationsdateien möglich. Die Doku spricht zusätzlich von Setter- und Property-Injection, dazu konnte ich aber irgendwie keine dokumentierten Beispiele finden. Es gibt aber immerhin die Möglichkeit, Methoden in der Service-Klasse als Pre- oder Post-Initialization Interceptoren auszuführen.</p>
<p>Letztlich tut der Container, was er soll: Abhängigkeiten in beliebige Instanzen zu injizieren. Bei Bedarf auch gegen ein Interface, aber das ist letztlich aufgrund des Sprachentwurfs nur optional (Was impliziert, das man auf Kosten riesiger Flexibilität &#8211; die man nicht braucht &#8211; schnell mal riskiert, durch einen falsch konfigurierten DI-Container seine Anwendung kaputt zu machen).</p>
<p>Aber der Aufwand steht meiner Meinung nach noch in keinem Verhältnis zum Nutzen. Am Beispiel einer Controller Extension, die als Service definiert wird, möchte ich das mal demonstrieren. Die offizielle Symfony 2-Dokumentation sagt, dass</p>
<blockquote><p>To keep things simple, Symfony2 by defaults does not require that controllers be defined as services. Furthermore Symfony2 injects the entire service container into your controller.
</p></blockquote>
<p>Das ist immerhin schon einmal eine Information. Das Standardverhalten ist also, dass ich automagisch eine Controllerklasse habe, die den Container kennt (Wie? Magisch? Ich dachte, Symfony 2 hat die Magie zugunsten transparentem Code und ständiger Kontrolle über jeden Aspekt des Core-Frameworks aufgegeben?). Dadurch, dass er ein ContainerAware Interface implementiert, kennt er auch einen Shortcut auf </p>
<pre class="brush: php; title: ; notranslate">$this-&gt;container-&gt;get('serviceid')</pre>
<p>, nämlich </p>
<pre class="brush: php; title: ; notranslate">$this-&gt;get('serviceid');</pre>
<p>. Um Bspw. ein Doctrine-Entity zu persistieren, reichen &#8220;ein paar codezeilen&#8221;:</p>
<pre class="brush: php; title: ; notranslate">
     $em = $this-&gt;get('doctrine.orm.entity_manager');
     $em-&gt;???($myEntity);
</pre>
<p>Wie hieß die Methode da am Entity Manager jetzt nochmal? Das ist das erste Problem: Dadurch, dass alle Services anonym im Service Container herumdümpeln bzw. auf ihre Instanziierung warten, habe ich in meiner IDE keinerlei Code-Completion mehr. Um das wieder zu erreichen, muss ich entweder<br />
&#8211; einen Accessor schreiben (getEntityManager()) und diesen mittels PHP-Doc type-hinten (annotieren) oder<br />
&#8211; mindestens einen magischen Docblock davorsetzen, der genau *meiner* IDE die Möglichkeit gibt, den Variablentyp zu erraten (aber ggf. proprietär ist, d.h. in anderen IDEs nicht unbedingt funktionieren muss). Für die Netbeans IDE gibt es dafür bspw. das &#8220;<a href="http://blogs.oracle.com/netbeansphp/entry/defining_a_variable_type_in">vdoc</a>&#8220;-Feature.</p>
<p>Das ganze setzt natürlich voraus, dass ich *weiß*, welches Interface der Service doctrine.orm.entity_manager implementiert bzw wie die konkrete Klasse (samt Namespace) desselben heißt. Und vorher muss ich auch noch wissen, wie überhaupt der *Servicename* des Entity Managers lautet. </p>
<p>Bin ich also komplett Ahnungslos, rufe ich erstmal ein Terminal auf, tippe sowas wie</p>
<pre class="brush: jscript; title: ; notranslate">$ app/console container:debug --show-private</pre>
<p> ein und suche mir anschließend in der kilometerlangen Liste genau die Services zusammen, die ich brauche.</p>
<p>Dafür brauche ich als Framework-Newbie schonmal richtig tiefgehende Kenntnisse darüber, was ein DIC überhaupt ist, tut und zur Konfiguration erfordert.</p>
<p>Um also das, was &#8220;früher&#8221; ein </p>
<pre class="brush: php; title: ; notranslate">new Cart($color, $maxSpeed)-&gt;save()</pre>
<p> war, zu erreichen, muss ich nun erstmal ganz schön viel Sport treiben (dieses Beispiel nur exemplarisch, es steht außer Frage, dass die Doctrine 2-Architektur wirklich klasse ist. Das Manko aus meiner Sicht ist die Integration in Sf2, nicht der ORM-Layer an sich.)  </p>
<p>Möchte ich den Accessor der ContainerAware-Implementierung am Controller vermeiden und die Services &#8220;direkt&#8221; injizieren, muss ich ihn selbst als Service am DIC registrieren. Wie das funktioniert, würde den Rahmen sprengen, nur so viel: Der Aufwand steht aus meiner Sicht wieder in keinem Verhältnis zum Ergebnis. Allerdings habe ich damit den Vorteil, dass ich bspw. keine abstrakte Controllerklasse mehr zu erweitern habe &#8211; der Controller kann ein simples Popo sein. Dass es aber nicht zu simpel sein darf, zeigt bspw., das ich trotz alledem mindestens einen Constructor definieren muss, der eben alle benötigten Services aufnimmt und an Instanzvariablen bindet. Und das können einige sein &#8211; fängt an beim Templating, geht übers Formframework, ggf. den Entity-Manager, einen Mailer und was einem sonst noch so einfällt. Dabei wollten wir doch ab jetzt nur noch leichtgewichtige Controller haben?</p>
<p>Meiner Meinung nach liegt die Lösung der Malaise in zwei Alternativen: Man baut so lange Abstracts, die den ganzen Kram als Shortcuts bereitstellen (dann hätten wir bspw. wieder eine komplexe, abstrakte Kontrollerklasse, die mindestens alles kennt, was in Symfony 1 noch dem ApplicationContext gehörte) &#8211; womit wir unser Loose Coupling Pardigma wieder in den Schrank zu den übrigen Ideen stellen können, die im Nachgang irgendwie doch nicht funktionierten. Oder legt Autowiring drüber. </p>
<p>Flow 3 baut bspw. an einem DIC + Autowiring, der alle verwalteten Services durch eine Kombination der Analyse von Annotationen (also PHP-Doccomments) und Signaturen (Typehints) direkt an die erzeugten Instanzen bindet. Die Konfiguration scheint damit sehr viel leichtgewichtiger. </p>
<p>Grails (was so weit ich weiß auf der Spring IOC-Komponente sitzt) geht noch einen Schritt weiter und mappt Instanzvariablen durch reine Naming-Conventions: Wenn also eine Instanzvariable auf &#8220;Service&#8221; endet und es zur Eigenschaft &#8220;mailerService&#8221; einen passenden Service &#8220;mailer&#8221; gibt, wird dieser automagisch injiziert. Kein zusätzlicher Code noch Annotations vonnöten.</p>
<p>Ich wüsste aber nicht, wie man solche Features wirklich performanceneutral, effizient und stabil auf einer Plattform wie PHP aufsetzen könnte &#8211; dafür ist die Sprache einfach (noch) nicht weit genug. </p>
<p>Abschließend bleibt ein übler Nachgeschmack &#8211; und der Eindruck, dass man sich hier fatal an den XML-&#8220;Konfigurationswahnsinn&#8221; der entsprechenden Java-&#8220;Vorbilder&#8221; annähern möchte. Wo doch gerade in diesem Lager  intensiv daran gearbeitet wird, genau davon abzurücken und Konfigurationen eben durch Konventionen zu ersetzen.  </p>
<p>Was denkt ihr? Kann das ganze doch durch Routine punkten, sodass es durch ein wenig konkrete Projekterfahrung doch ganz leicht von der Hand geht? Wird der DIC im Tagesgeschäft schon intensiv benutzt, oder werden nur die Standardfunktionen des Frameworks verwendet und das Zeug &#8220;unter der Haube&#8221; doch lieber den Framework- und Bundle-Entwicklern überlassen? Ich bin wieder sehr gespannt auf Meinungen und Kritik&#8230;</p>The post <a href="https://nerdpress.org/2011/05/11/symfony-2-wird-super-oder/">Symfony 2 wird super. Oder …?</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2011/05/11/symfony-2-wird-super-oder/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Symfony 2 Standard Edition released</title>
		<link>https://nerdpress.org/2011/03/07/symfony-2-standard-edition-released/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 07 Mar 2011 17:20:38 +0000</pubDate>
				<category><![CDATA[Doctrine ORM]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software engineering]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[Doctrine 2]]></category>
		<category><![CDATA[Standard Edition]]></category>
		<category><![CDATA[symfony 2]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1401</guid>

					<description><![CDATA[<p>Ab heute, dem 7. 3. 2011, steht auf http://symfony.com die &#8220;Standard-Edition&#8221; der neuesten Version 2 des populären RAD-Frameworks zum Download bereit. Bereits am vergangenen Wochenende ging die neue Website des Projekts online. Symfony 2 wird als Sammlung loser gekoppelter Komponenten &#8211; sog. &#8220;Bundles&#8221; &#8211; in mehreren Ausgaben erhältlich sein. Zum jetzigen Zeitpunkt existiert bereits eine &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2011/03/07/symfony-2-standard-edition-released/" class="more-link">Continue reading<span class="screen-reader-text"> "Symfony 2 Standard Edition released"</span></a></p>
The post <a href="https://nerdpress.org/2011/03/07/symfony-2-standard-edition-released/">Symfony 2 Standard Edition released</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Ab heute, dem 7. 3. 2011, steht auf http://symfony.com die &#8220;Standard-Edition&#8221; der neuesten Version 2 des populären RAD-Frameworks zum Download bereit. Bereits am vergangenen Wochenende ging die neue Website des Projekts online.<br />
<span id="more-1401"></span><br />
Symfony 2 wird als Sammlung loser gekoppelter Komponenten &#8211; sog. &#8220;Bundles&#8221; &#8211; in mehreren Ausgaben erhältlich sein. Zum jetzigen Zeitpunkt existiert bereits eine Sandbox und eine davon abgeleitete &#8220;Standard-Edition&#8221;, die wie gewohnt ein festes Code-Verzeichnislayout vorgeben.</p>
<p>Als zukünftige Ausgaben denkbar sind ein Symfony2-basierendes CMF (Content Management Framework) oder eine auf die speziellen Befürfnisse von Online-Shops zugeschnittene Bundle-Sammlung.</p>
<p>Der Code ist noch nicht als stabil deklariert. Die bereits vorhandene und wie immer intensiv gepflegte Referenz-Dokumentation lädt bereits jetzt zum Reinschnuppern und Ausprobieren ein.  </p>The post <a href="https://nerdpress.org/2011/03/07/symfony-2-standard-edition-released/">Symfony 2 Standard Edition released</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
