<?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>Kamil Adryjanek - blog programisty</title>
	<atom:link href="http://www.kamiladryjanek.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kamiladryjanek.com</link>
	<description>Blog programisty PHP, Python. Projektowanie - programowanie serwisów internetowych, rozwiązania dedykowane, aplikacje e-commerce. Django, Symfony, Zend, jQuery, Magento.</description>
	<lastBuildDate>Wed, 16 Nov 2011 06:29:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Symfony2: get controller / action name in Twig template</title>
		<link>http://www.kamiladryjanek.com/2011/11/symfony2-get-controller-action-name-in-twig-template/</link>
		<comments>http://www.kamiladryjanek.com/2011/11/symfony2-get-controller-action-name-in-twig-template/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 01:04:46 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony2]]></category>
		<category><![CDATA[Twig]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=133</guid>
		<description><![CDATA[In one of my templates i needed a simple way to get controller / action name to generate some dynamic urls. Symfony2 does not offer any Twig helper function to display current controller / action name. The easiest way that i have found so far is to create Twig extension. In our default bundle we [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kamiladryjanek.com/wp-content/uploads/2011/11/twig.png" alt="" title="twig" width="160" height="110" class="alignleft size-full wp-image-138" /> In one of my templates i needed a simple way to get controller / action name to generate some dynamic urls. Symfony2 does not offer any Twig helper function to display current controller / action name. </p>
<p>The easiest way that i have found so far is to create Twig extension. In our default bundle we need to create folder Twig/Extension for example Acme/PageBundle/Twig/Extension and place there our Twig extension class:<span id="more-133"></span></p>
<pre class="brush: php; title: ; notranslate">

&lt;?php
// src/Acme/PageBundle/Twig/Extension/AcmePageExtension.php

namespace Acme\PageBundle\Twig\Extension;

use Symfony\Component\HttpFoundation\Request;

class AcmePageExtension extends \Twig_Extension
{
	protected $request;
	/**
	 *
	 * @var \Twig_Environment
	 */
	protected $environment;

	public function __construct(Request $request)
	{
		$this-&gt;request = $request;
	}

	public function initRuntime(\Twig_Environment $environment)
	{
		$this-&gt;environment = $environment;
	}

	public function getFunctions()
	{
		return array(
	            'get_controller_name' =&gt; new \Twig_Function_Method($this, 'getControllerName'),
	            'get_action_name' =&gt; new \Twig_Function_Method($this, 'getActionName'),
		);
	}

	/**
	 * Get current controller name
	 */
	public function getControllerName()
	{
		$pattern = &quot;#Controller\\\([a-zA-Z]*)Controller#&quot;;
		$matches = array();
		preg_match($pattern, $this-&gt;request-&gt;get('_controller'), $matches);

		return strtolower($matches[1]);
	}

	/**
	 * Get current action name
	 */
	public function getActionName()
	{
		$pattern = &quot;#::([a-zA-Z]*)Action#&quot;;
		$matches = array();
		preg_match($pattern, $this-&gt;request-&gt;get('_controller'), $matches);

		return $matches[1];
	}

	public function getName()
	{
		return 'acme_page';
	}
}
</pre>
<p>Next step is to register this service:</p>
<pre class="brush: xml; title: ; notranslate">
// src/Acme/PageBundle/Resources/config/services.yml
    request:
        class:        Symfony\Component\HttpFoundation\Reques

    acme.twig.extension:
        class: Acme\PageBundle\Twig\Extension\AcmePageExtension
        arguments:  [@request]
        tags:
            - { name: 'twig.extension' }
</pre>
<p>and then in twig templates we can simply call:</p>
<pre class="brush: xml; title: ; notranslate">

Controller name: {{ get_controller_name() }}
Action name: {{ get_action_name() }}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2011/11/symfony2-get-controller-action-name-in-twig-template/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Symfony2 &#8211; pierwsze wrażenia</title>
		<link>http://www.kamiladryjanek.com/2011/11/symfony2-pierwsze-wrazenia/</link>
		<comments>http://www.kamiladryjanek.com/2011/11/symfony2-pierwsze-wrazenia/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 23:14:28 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony2]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=112</guid>
		<description><![CDATA[Od jakiegoś czasu starałem się znaleźć odpowiedni moment / trochę wolnego czasu na zapoznanie się z najnowszą wersją frameworka Symfony. Jako, że wiele osób zastanawia się / rozważa migrację swoich dotychczasowych projektów, bądź też rozpoczęcie nowych na Symfony2 postanowiłem przedstawić moje subiektywne obiektywne zdanie na temat możliwości Symfony2. Ogromną zaletą Symfony2 jest w pełni przepisany [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kamiladryjanek.com/wp-content/uploads/2011/10/symfony_logo.gif" alt="" title="symfony_logo" width="100" height="100" class="alignleft size-full wp-image-104" /> Od jakiegoś czasu starałem się znaleźć odpowiedni moment / trochę wolnego czasu na zapoznanie się z najnowszą wersją frameworka Symfony. Jako, że wiele osób zastanawia się / rozważa migrację swoich dotychczasowych projektów, bądź też rozpoczęcie nowych na Symfony2 postanowiłem przedstawić moje subiektywne <del datetime="2011-11-07T06:10:15+00:00">obiektywne</del> zdanie na temat możliwości Symfony2.<br />
<span id="more-112"></span></p>
<p>Ogromną zaletą Symfony2 jest w pełni przepisany silnik frameworka, który w pełni wykorzystuje możliwości PHP 5.3. Przestrzenie nazw nie tylko rozwiązuje problem konfliktów i długich nazw ale także sprawiają, że ładowanie potrzebnych klas jest teraz znacznie prostsze. </p>
<p><strong>Instalacja</strong><br />
Do ściągnięcia dostępna jest gotowa paczka zawierająca wszystkie biblioteki niezbędne do rozpoczęcia pracy. Osobiście polecam instalację framewokra z Gita (najwygodniej pod Linuxem, chociaż jest też ciekawa wersja pod <a href="http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.7.1-preview20111027.exe&#038;can=2&#038;q=" title="Git dla Windows" target="_blank">Windowsa</a> dla zainteresowanych). Dzięki temu wszelkie aktualizacje zewnętrznych bibliotek, czy tez bibliotek frameworka sprowadzają się do aktualizacji plików deps i deps.lock, a następnie wywołania z wiersza poleceń komendy: </p>
<pre class="brush: php; title: ; notranslate">
php bin/vendors update
</pre>
<p><strong>Bundles</strong><br />
Symfony2 to przede wszystkim ogromne zmiany w architekturze i organizacji kodu aplikacji. Każda aplikacja składa się teraz z pakietów: bundles &#8211; coś na wzór modułu z symfony 1.X, z tym że każdy bundle jest teraz dużo bardziej niezależny: posiada odrębną logikę, konfigurację, klasy Entity czy usługi. <a href="http://www.kamiladryjanek.com/wp-content/uploads/2011/11/post_list.png.jpg"><img src="http://www.kamiladryjanek.com/wp-content/uploads/2011/11/post_list.png.jpg" alt="" title="Sonata Admin" width="640" height="452" class="aligncenter size-full wp-image-119" /></a> Dzięki temu nowy mechanizm rozszerzeń Symfony2 jest w całości oparty o bundles &#8211; w sieci można znaleźć wiele ciekawie napisanych rozszerzeń: rozbudowany panel administracyjny wzorowany na Django (SonataAdmin) + szereg rozszerzeń, biblioteka do manipulacji/modyfikacji obrazków inspirowana Pythonowym PILem  (Imagine), Goutte, biblioteka do budowania scenariuszy, które są następnie wykorzystywane do testowania funkcjonalności (Behat + Mink). </p>
<p><strong>Formularze</strong><br />
Początkowo bardzo toporne &#8211; brakuje dobrej dokumentacji. Stworzenie formularza rejestracji, dodanie walidacji (dodanie zależności między polami) stanowi nie lada wyzwanie. Nie podoba mi się przeniesienie walidacji do klasy yml/xml &#8211; tak jakbyśmy wracali do symfony 1.0. Na szczęście są annotacje, które można wykorzystać zarówno w klasach Entity, jak i Models. UWAGA na problem z eAcceleratorem &#8211; straciłem kilka dobrych godzin przez problem z obcinaniem komentarzy na serwerze produkcyjnym. eAccelerator nie współpracuje poprawnie z nowymi bibliotekami: Symfony2, Doctrine2, Zend Framework, PHP Unit, &#8230; . Niestety po kilku godzinach pracy z formularzami miałem odczucie jakby cały mechanizm był teraz znacznie bardziej skomplikowany i trudny do opanowania.</p>
<p><strong>Doctrine2</strong><br />
Nowa wersja Doctrine niesie ze sobą szereg udogodnień &#8211; zwłaszcza jeśli chodzi o wydajność działania biblioteki. Z biblioteki zostały usunięte magiczne metody setterów i getterów. </p>
<pre class="brush: php; title: ; notranslate">
    $user= new User();
    $user-&gt;setName('Kamil Adryjanek');

    $em = $this-&gt;getDoctrine()-&gt;getEntityManager();
    $em-&gt;persist($user);
    $em-&gt;flush();
</pre>
<p>Usprawniono model cachowania danych.<br />
Z Core usunięte zostały funkcjonalności behaviours, które zostały przeniesione do zewnętrznych bibliotek.<br />
Niestety miałem okazję trafić na kilka problemów, które dość znacząco utrudniają pracę, np: </p>
<pre class="brush: php; title: ; notranslate">
php app\console doctrine:generate:entities
</pre>
<p>dla klas dziedziczących po innych Entity, powoduje wygenerowanie prywatnych atrybutów klasy w klasie pochodnej &#8211; problem jak narazie nie jest rozwiązany.<br />
Warto też wspomnieć o ciekawym mechanizmie aktualizacji schema bazy danych, który porównuje strukturę bazy danych i aktualny stan naszych klas Entity. Dzięki skrypt temu wywołuje tylko te zapytania, które są naprawdę niezbędne.</p>
<p><strong>Twig</strong><br />
Jest to wg mnie jedna najciekawszych i najlepszych zmian w nowej wersji Symfony. Dziedziczenie szablonów, definiowalne makra, szereg rozszerzeń i wbudowanych funkcji to tylko niektóre z funkcjonalności Twiga. Twig jest rewelacyjny, daje ogromne możliwości, a zarazem jest bardzo prosty w użyciu. Początkowo może sprawiać problemy webmasterom przyzwyczajonym do czystego PHP, jednak trud włożony w poznanie w Twig powinien zaprocentować w przyszłości. Odsyłam do dokumentacji projektu, bo dokumentacja na stronie symfony.com pozwala na zapoznanie się tylko z podstawowymie elementami składni.</p>
<pre class="brush: php; title: ; notranslate">
&lt;h1&gt;Użytkownicy&lt;/h1&gt;
&lt;ul&gt;
    {% for user in users if user.active %}
        &lt;li&gt;{{ user.username|e }}&lt;/li&gt;
    {% endfor %}
&lt;/ul&gt;
</pre>
<p><strong>Inne problemy</strong><br />
Muszę wspomnieć o bardzo dziwnym (myślę, że to najlepsze określenie) mechanizmie logowania, który sprowadza się do konfiguracji szeregu predefiniowanych opcji. Nie mamy pełnej kontroli nad tym co się dzieje z danymi, które są wysyłane przez formularz logowania, albo przynajmniej mi nie udało się znaleźć sposobu. Możemy ustawić success_handler i failure_handler, ale to nie daje pełnej kontroli nad sesją i uprawnieniami użytkownika. Rozwiązanie na chwilę obecną wydaje mi się być trochę przekombinowane. </p>
<p><strong>Co dalej?</strong><br />
W Symfony2 koduje się szybko i sprawnie, wszelkie błędy okresu dojrzewania nowej wersji frameworka są eliminowane na bieżąco. To czego wg mnie brakuje w tym momencie to duża liczba przykładów wykorzystania nowych mechanizmów frameworka. Dokumentacja jest bardzo dobra ale momentami brakuje w niej podstawowych informacji &#8211; m.in. na temat wykorzystania nowego systemu formularzy (jeden rozdział nie wyczerpuje tematu). Warto zapoznać się z kodem niektórych rozszerzeń Symfony2 i standardami kodowania jakie przyjęli programiści. Po cichu liczę na to, że autorzy pokuszą się z końcem roku na wydanie nowej wersji Advent Calendar, która zademonstruje pełnię możliwości Symfony2, a tym samym przekona użytkowników że warto wykorzystać framework w następnym projekcie. Myślę, że to znakomity moment na migrację do PHP 5.3 i Symfony2.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2011/11/symfony2-pierwsze-wrazenia/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Symfony 1.4 &#8211; sfImageFileValidator &#8211; validate image dimensions</title>
		<link>http://www.kamiladryjanek.com/2011/10/symfony-1-4-sfimagefilevalidator-validate-image-dimensions/</link>
		<comments>http://www.kamiladryjanek.com/2011/10/symfony-1-4-sfimagefilevalidator-validate-image-dimensions/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 19:43:10 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[snippet]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=100</guid>
		<description><![CDATA[Default symfony 1.4 file validator can validate only some basic file attributes. Sometimes we need more, for example we want to prevent small images from being uploaded. Code below presents my custom sfImageFileValidator which allows you to apply some dimensions constraints to image file validation, e.g. max_height or max_width. How to use this code?]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kamiladryjanek.com/wp-content/uploads/2011/10/symfony.png" alt="" title="symfony" width="200" height="54" class="alignleft size-full wp-image-109" style="margin-top: 8px;" /> Default symfony 1.4 file validator can validate only some basic file attributes. Sometimes we need more, for example we want to prevent small images from being uploaded. Code below presents my custom sfImageFileValidator which allows you to apply some dimensions constraints to image file validation, e.g. max_height or max_width.</p>
<p><span id="more-100"></span></p>
<pre class="brush: php; title: ; notranslate">

&lt;?php

/**
 * sfImageFileValidator allows you to apply constraints to image file upload, it extend the sfFileValidator functions.
 *
 * @author     Kamil Adryjanek &lt;kamil.adryjanek@gmail.com&gt;
 */
class sfImageFileValidator extends sfValidatorFile
{
    /**
     * Configures the current validator.
     *
     * Available options:
     *
     *  * max_height:             The maximum file height in pixels
     *  * min_height:             The minimum file height in pixels
     *  * max_width:              The maximum file width in pixels
     *  * min_width:              The minimum file width in pixels
     *
     * Available error codes:
     *
     *  * max_height
     *  * min_height
     *  * max_width
     *  * min_width
     *
     * @param array $options   An array of options
     * @param array $messages  An array of error messages
     *
     * @see sfValidatorBase
     */
    public function configure($options = array(), $messages = array())
    {
        parent::configure($options, $messages);

        $this-&gt;addOption('max_height');
        $this-&gt;addOption('min_height');
        $this-&gt;addOption('max_width');
        $this-&gt;addOption('min_width');

        $this-&gt;addMessage('max_height', 'File is too high (maximum is %max_height% pixels, %height% given).');
        $this-&gt;addMessage('min_height', 'File is too short (minimum is %min_height% pixels, %height% given).');
        $this-&gt;addMessage('max_width', 'File is too wide (maximum is %max_width% pixels, %width% given).');
        $this-&gt;addMessage('min_width', 'File is too thin (minimum is %min_width% pixels, %width% given).');
    }

    /**
     * This validator always returns a sfValidatedFile object.
     *
     * The input value must be an array with the following keys:
     *
     *  * tmp_name: The absolute temporary path to the file
     *  * name:     The original file name (optional)
     *  * type:     The file content type (optional)
     *  * error:    The error code (optional)
     *  * size:     The file size in bytes (optional)
     *
     * @see sfValidatorBase
     */
    protected function doClean($value)
    {
        if (!is_array($value) || !isset($value['tmp_name'])) {
            throw new sfValidatorError($this, 'invalid', array('value' =&gt; (string) $value));
        }

        // get image dimensions
        list($width, $height) = getimagesize($value['tmp_name']);

        // check file height
        if ($this-&gt;hasOption('max_height') &amp;&amp; $this-&gt;getOption('max_height') &lt; (int) $height) {
            throw new sfValidatorError($this, 'max_height', array('max_height' =&gt; $this-&gt;getOption('max_height'), 'height' =&gt; (int) $height));
        }

        if ($this-&gt;hasOption('min_height') &amp;&amp; $this-&gt;getOption('min_height') &gt; (int) $height) {
            throw new sfValidatorError($this, 'min_height', array('min_height' =&gt; $this-&gt;getOption('min_height'), 'height' =&gt; (int) $height));
        }

        // check file width
        if ($this-&gt;hasOption('max_width') &amp;&amp; $this-&gt;getOption('max_width') &lt; (int) $width) {
            throw new sfValidatorError($this, 'max_width', array('max_width' =&gt; $this-&gt;getOption('max_width'), 'width' =&gt; (int) $width));
        }

        if ($this-&gt;hasOption('min_width') &amp;&amp; $this-&gt;getOption('min_width') &gt; (int) $width) {
            throw new sfValidatorError($this, 'min_width', array('min_width' =&gt; $this-&gt;getOption('min_width'), 'width' =&gt; (int) $width));
        }

        // check other options
        return parent::doClean($value);
    }
}
?&gt;
</pre>
<p>How to use this code?</p>
<pre class="brush: php; title: ; notranslate">

&lt;?php

class PhotoForm extends sfForm
{
    public function configure()
    {

        //...

        $this-&gt;widgetSchema['photo'] = new sfWidgetFormInputFileEditable(array(
            'label' =&gt; 'User photo',
            'file_src' =&gt; '/uploads/photos/'.$this-&gt;getObject()-&gt;getPhoto(),
            'is_image' =&gt; true,
            'edit_mode' =&gt; !$this-&gt;isNew(),
            'template' =&gt; '&lt;div&gt;%file%&lt;br /&gt;%input%&lt;br /&gt;%delete% %delete_label%&lt;/div&gt;',
        ));

        $this-&gt;validatorSchema['photo'] = new sfImageFileValidator(array(
                'required'        =&gt; true,
                'mime_types'    =&gt; array('image/jpeg', 'image/png', 'image/gif', 'image/pjpeg'),
                'max_size'        =&gt; '1048576',
                'min_height'    =&gt; '640',
                'min_width'        =&gt; '480',
                'path'            =&gt; sfConfig::get('sf_upload_dir').'/photos',
            ), array(
                'required'        =&gt; &quot;Photo is required!&quot;,
                'min_height'    =&gt; &quot;Custom message for height vaidation.&quot;,
                'min_width'        =&gt; &quot;File is too thin (minimum is %min_width% pixels, %width% given).&quot;
        ));

        $this-&gt;validatorSchema['photo_delete'] = new sfValidatorPass();

        //…

    }
}

?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2011/10/symfony-1-4-sfimagefilevalidator-validate-image-dimensions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Krótko o książce: &#8222;Symfony w przykładach&#8221;</title>
		<link>http://www.kamiladryjanek.com/2011/03/krotko-o-ksiazce-symfony-w-przykladach/</link>
		<comments>http://www.kamiladryjanek.com/2011/03/krotko-o-ksiazce-symfony-w-przykladach/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 21:11:25 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=81</guid>
		<description><![CDATA[W odpowiedzi na liczne pytania, poniżej chciałbym w kilku zdaniach przedstawić moją subiektywną opinię na temat najnowszej Polskiej książki dotyczącej Symfony Framework. Prezentowana książka wg rankingów Helion, jest obecnie jedną z najlepiej sprzedających się pozycji &#8211; numer 2 na liście bestsellerów. Na samym początku chciałbym zaznaczyć, że z dość dużym dystansem podchodzę do tego typu [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.kamiladryjanek.com/wp-content/uploads/2011/03/symfony-w-przykladach.jpg"><img class="alignleft alignnone size-medium wp-image-82" style="border: 1px solid black; margin: 5px 10px 5px 5px; float: left;" title="Symfony w przykładach" src="http://www.kamiladryjanek.com/wp-content/uploads/2011/03/symfony-w-przykladach-209x300.jpg" alt="" width="120" height="156" /></a>W odpowiedzi na liczne pytania, poniżej chciałbym w kilku zdaniach przedstawić moją subiektywną opinię na temat najnowszej Polskiej książki dotyczącej Symfony Framework. Prezentowana książka wg rankingów Helion, jest obecnie jedną z najlepiej sprzedających się pozycji &#8211; numer 2 na liście bestsellerów.<br />
Na samym początku chciałbym zaznaczyć, że z dość dużym dystansem podchodzę do tego typu pozycji &#8211; książki i materiały udostępniane na stronie projektu powinny w zupełności wystarczyć na początku przygody z Symfony.<br />
<span id="more-81"></span></p>
<p><strong>Plusy</strong></p>
<p>- jedna z dwóch Polskich książek na temat programowania w Symfony;</p>
<p>- Symfony 1.4 &#8211; niektórzy odbiorą to za minus, biorąc pod uwagę premierę Symfony2 zaplanowaną na koniec marca 2011. Jednakże prawda jest taka, że większość nowych projektów oparta jest o sf 1.4 i firmy nie szybko przestawią się na nową wersję frameworka;</p>
<p>- dobre wprowadzenie dla początkujących programistów Symfony &#8211; autor niemal za rękę prowadzi poprzez konfigurację środowiska, tworzenie projektu/aplikacji/modułów i implementację poszczególnych funkcjonalności. Ponadto opisuje takie zagadnienia jak: generowanie admina, i18n, pracę z bazą danych, https;</p>
<p>- autor opisuje sposoby publikacji aplikacji na hostingu;</p>
<p><strong>Minusy</strong></p>
<p>- niedopuszczalne jest dla mnie stosowanie Polskich nazw dla zmiennych i metod funkcji &#8211; zupełnym nieporozumieniem jest dodawanie &#8222;s&#8221; dla liczby mnogiej lub też &#8222;_id&#8221; do Polskich nazw zmiennych:</p>
<pre class="brush: php; title: ; notranslate">
// polskie nazwy metod
public function executeJaszczurka(sfWebRequest $request)
// liczba monga - piosenkas?
$this-&gt;Piosenkas = PiosenkaPeer::doSelect(new Criteria());
// pole w bazie danych - piosenka_id?
$this-&gt;Piosenka = PiosenkaPeer::retrieveByPk($request-&gt;getParameter('piosenka_id'));
// rezultat polskich nazw kolumn
$this-&gt;Zadanie-&gt;getOdpowiedz();
</pre>
<p>Co z konwencjami nazewnictwa i dobrymi praktykami?</p>
<p>- Propel &#8211; trudno bezpośrenio przyjąć to za minus,  jednakże Symfony oficjalnie wspiera Doctrine, a Propel traktują jedynie jako dodatek. Symfony 2.0 ma w pełni wykorzystywać możliwości Doctrine 2.0 &#8211; nie ma jeszcze oficjalnych planów co do Propela; Doctrine</p>
<p><strong>Podsumowanie</strong></p>
<p>Książka jest ciekawa ale  można ją polecić co najwyżej początkującym &#8211; zdecydowanie odradzam tę pozycję osobom, które miały już wcześniej przyjemność programowania w Symfony. Gdyby nie konwencje nazewnictwa stosowane w &#8222;Symfony w przykładach&#8221;, możnaby ją smiało rekomendować jako wstęp do sf1.4 &#8211; jednakże angielskojęzycznej dokumentacji Symfony napewno nie zastąpi.</p>
<p>Osoby, które chciałby poznać możliwości framework na bardziej zaawansowanych przykładach, odsyłam do lektury Jobeeta.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2011/03/krotko-o-ksiazce-symfony-w-przykladach/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Zend framework &#8211; Zend_Validate_Db_Unique draft</title>
		<link>http://www.kamiladryjanek.com/2011/01/zend-framework-zend_validate_db_unique-draft/</link>
		<comments>http://www.kamiladryjanek.com/2011/01/zend-framework-zend_validate_db_unique-draft/#comments</comments>
		<pubDate>Sun, 30 Jan 2011 20:45:21 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[Zend_Form]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=80</guid>
		<description><![CDATA[Zend framework has a lot of o really nice features. Lately i had an opportunity to work with Zend_Form (also with its validation system) and Zend_Db (my most hated component of ZF). Playing with DB i needed a simple way to check if new item (record) is unique. Unfortunately i haven&#8217;t found Zend_Validate_Db_Unique component There [...]]]></description>
			<content:encoded><![CDATA[<p>Zend framework has a lot of o really nice features. Lately i had an opportunity to work with Zend_Form (also with its validation system) and Zend_Db (my most hated component of ZF). Playing with DB i needed a simple way to check if new item (record) is unique. Unfortunately i haven&#8217;t found Zend_Validate_Db_Unique component <img src='http://www.kamiladryjanek.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  There is Zend_Validate_Db_NoRecordExists/RecordExists but it only checks if record exists/not exists in db. The code below is my proposal for new validation component:</p>
<pre class="brush: php; title: ; notranslate">

/**
 * @see Zend_Validate_Db_Abstract
 */
require_once 'Zend/Validate/Db/Abstract.php';

/**
 * Confirms a record is unique in a table.
 *
 * @uses       Zend_Validate_Db_Abstract
 */
class Zend_Validate_Db_Unique extends Zend_Validate_Db_Abstract
{
    /**
     * @var Zend_DB_Table_Row
     */
    protected $_row = null;

	public function __construct($table, $field, Zend_DB_Table_Row $row, Zend_Db_Adapter_Abstract $adapter = null)
    {
        parent::__construct($table, $field, null, $adapter);

        $this-&gt;_row   = $row;

        $this-&gt;setMessage(&quot;A record matching %value% already exists.&quot;, self::ERROR_RECORD_FOUND);
    }  

    public function isValid($value)
    {
        $valid = true;
        $this-&gt;_setValue($value);

		$result = $this-&gt;_query($value);

		if (!$result || $this-&gt;isUpdate()) {

			return true;
		}

		$this-&gt;_error(self::ERROR_RECORD_FOUND);

        return false;
    }

  protected function isUpdate()
  {
      if (!isset($this-&gt;_row[$this-&gt;_field]) || $this-&gt;_row[$this-&gt;_field] != $this-&gt;_value)
      {
        return false;
      }

    return true;
  }
}
</pre>
<p><span id="more-80"></span><br />
Is important to note that as a one parameter i&#8217;m passing Zend_DB_Table_Row $row &#8211; to check if currently we are editing it. This compoment is inspired by sfValidatorDoctrineUnique from Symfony package.</p>
<p>For this implementation we also need something like Zend_Form_Db which will also store current database record. Draft:</p>
<pre class="brush: php; title: ; notranslate">

class Zend_Form_Db extends Zend_Form
{

	/**
	 * Db row
	 *
	 * @var Zend_DB_Table_Row
	 */
	protected $_row = null;

	/**
     * Constructor
     *
     * @param mixed $options
     * @return void
     */
    public function __construct(Zend_DB_Table_Row $row, $options = null)
    {
        parent::__construct($options);

        $this-&gt;_row = $row;
    }
}
</pre>
<p>This solved my problem.</p>
<p><div class="note"><div class="notetip">In my opinion the best way is not to use Zend_Db <img src='http://www.kamiladryjanek.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  and replace it with Doctrine ORM. Then we can simply create Zend_Form_Doctrine and Zend_Validate_Doctrine_Unique.</div></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2011/01/zend-framework-zend_validate_db_unique-draft/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Symfony 1.4 and SSL &#8211; playing with symfony filters</title>
		<link>http://www.kamiladryjanek.com/2010/12/symfony-14-and-ssl-playing-with-symfony-filters/</link>
		<comments>http://www.kamiladryjanek.com/2010/12/symfony-14-and-ssl-playing-with-symfony-filters/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 01:18:37 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=78</guid>
		<description><![CDATA[Building last application i needed SSL protection for some of my modules and actions. What I wanted to achieve was to choose some actions and redirect non-https requests to https (and https to non-https). I found a plugin: sfSslRequirementPlugin, it&#8217;s for sf 1.0/1.1 and it does not really meet my needs. Yes, i know that [...]]]></description>
			<content:encoded><![CDATA[<p>Building last application i needed SSL protection for some of my modules and actions. What I wanted to achieve was to choose some actions and redirect non-https requests to https (and https to non-https).<br />
I found a plugin: <a href="http://www.symfony-project.org/plugins/sfSslRequirementPlugin" rel="nofollow" target="_blank">sfSslRequirementPlugin</a>, it&#8217;s for sf 1.0/1.1 and it does not really meet my needs. Yes, i know that i can fix it to work with sf 1.4 but that&#8217;s not a point.</p>
<p>Then in the documentation i found simple ssl filter example:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

class sfSecureFilter extends sfFilter
{
  public function execute($filterChain)
  {
    $context = $this-&gt;getContext();
    $request = $context-&gt;getRequest();

    if (!$request-&gt;isSecure())
    {
      $secure_url = str_replace('http', 'https', $request-&gt;getUri());

      return $context-&gt;getController()-&gt;redirect($secure_url);
      // We don't continue the filter chain
    }
    else
    {
      // The request is already secure, so we can continue
      $filterChain-&gt;execute();
    }
  }
}
</pre>
<p><span id="more-78"></span><br />
I really like the idea of describing the authentication and authorization rules in security.yml file (is_secure option) and filters. So i decided to add another option: &#8222;is_ssl&#8221; for module-action restrictio. It shoud works on the same rules as sfBasicSecurityFilter.</p>
<p><div class="note"><div class="notehelp"><br />
The default application configuration can be overridden for a module by creating a security.yml file in the config/ directory of the module. The main keys are action names without the execute prefix (index for the executeIndex method for instance).</p>
<p>To determine if an action is secure or not, symfony looks for the information in the following order:<br />
 * a configuration for the specific action in the module configuration file if it exists;<br />
 * a configuration for the whole module in the module configuration file if it exists (under the all key);<br />
 * the default application configuration (under the default key).<br />
</div></div></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

class MySecureFilter extends sfFilter
{
  public function execute($filterChain) {

    $context = $this-&gt;getContext();
    $request = $context-&gt;getRequest();

    $moduleName = $request-&gt;getParameter('module');
    $actionName = $request-&gt;getParameter('action');

    if ($context-&gt;getController()-&gt;actionExists($moduleName, $actionName)) {

	    $action = $context-&gt;getController()-&gt;getAction(
	    	$moduleName,
	    	$actionName
	    );

	    if ($action-&gt;getSecurityValue('is_ssl', false) &amp;&amp; !$request-&gt;isSecure()) {

	    	$secure_url = str_replace('http', 'https', $request-&gt;getUri());

			return $context-&gt;getController()-&gt;redirect($secure_url);

	    } else if (!$action-&gt;getSecurityValue('is_ssl', false) &amp;&amp; $request-&gt;isSecure()) {

	    	$not_secure_url = str_replace('https', 'http', $request-&gt;getUri());

			return $context-&gt;getController()-&gt;redirect($not_secure_url);
	    }
    }

    $filterChain-&gt;execute();
  }
}
</pre>
<p>This simple filter redirects all actions that has option &#8216;is_ssl&#8217; = true to https requests and https requests (with is_ssl = false) to non-https.</p>
<p>To enable this filter for example for our frontend application we need to set this filter in filters.yml &#8211; apps/frontend/config/filters.yml:</p>
<pre class="brush: xml; title: ; notranslate">

rendering: ~
security:  ~

secure:
  class: MySecureFilter

cache:     ~
execution: ~
</pre>
<p>Enable ssl for module/action (default module) &#8211; apps/frontend/modules/default/config/security.yml:</p>
<pre class="brush: xml; title: ; notranslate">

# for the whole module
all:
  is_ssl: true

# just one action
login:
  is_ssl: true
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2010/12/symfony-14-and-ssl-playing-with-symfony-filters/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Symfony &#8211; how to set up default database encoding?</title>
		<link>http://www.kamiladryjanek.com/2010/06/symfony-how-to-set-up-default-database-encoding/</link>
		<comments>http://www.kamiladryjanek.com/2010/06/symfony-how-to-set-up-default-database-encoding/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 13:13:31 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=74</guid>
		<description><![CDATA[Maybe it&#8217;s nothing special and difficult but i remember the day (some time go) when i had a problem with setting up default database encoding in my application. I recently received some questions about it so i decided to post this here and help some of you. My solutions (maybe there is some better way [...]]]></description>
			<content:encoded><![CDATA[<p>Maybe it&#8217;s nothing special and difficult but i remember the day (some time go)  when i had a problem with setting up default database encoding in my application. I recently received some questions about it so i decided to post this here and help some of you.</p>
<p><span id="more-74"></span></p>
<p>My solutions (maybe there is some better way to do this):</p>
<pre class="brush: xml; title: ; notranslate">

all:
  doctrine:
    class: sfDoctrineDatabase   # or sfPropelDatabase
    param:
      dsn:      mysql:host=host_name;dbname=database_name
      username: default_user
      password: pass
      encoding: utf8
      attributes: { default_table_collate: utf8_unicode_ci, default_table_charset: utf8 }
</pre>
<p>[edit]<br />
If we also want to set prefix for our tables we need to set &#8222;tblname_format&#8221; attribute. We can set similar option for indexes and sequences name format:</p>
<pre class="brush: xml; title: ; notranslate">

all:
  doctrine:
    class: sfDoctrineDatabase   # or sfPropelDatabase
    param:
      dsn:      mysql:host=host_name;dbname=database_name
      username: default_user
      password: pass
      encoding: utf8
      attributes:
        default_table_collate: utf8_unicode_ci,
        default_table_charset: utf8
        tblname_format: prefix_%s
        idxname_format: %s_idx
        seqname_format: %s_seq
</pre>
<p>And that&#8217;s really all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2010/06/symfony-how-to-set-up-default-database-encoding/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Advanced data filtering with Symfony 1.4 and ExtJS 3.2 [english]</title>
		<link>http://www.kamiladryjanek.com/2010/06/advanced-data-filtering-with-symfony-14-and-extjs-32-english/</link>
		<comments>http://www.kamiladryjanek.com/2010/06/advanced-data-filtering-with-symfony-14-and-extjs-32-english/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 15:26:33 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[Ext JS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=63</guid>
		<description><![CDATA[After a couple of weeks I finally found some time to write about Symfony and ExtJS. This time i want to show how to put together to work Symfony 1.4, ExtJS 3.2 and Grid Filter Plugin &#8211; for me it&#8217;s the one of most powerfull filtering solutions i have ever seen. Since my last entry [...]]]></description>
			<content:encoded><![CDATA[<p>After a couple of weeks I finally found some time to write about Symfony and ExtJS. This time i want to show how to put together to work Symfony 1.4, ExtJS 3.2 and Grid Filter Plugin &#8211; for me it&#8217;s the one of most powerfull filtering solutions i have ever seen.<br />
Since my last entry about displaying data in ExtJS Grid Panel i have updated Ext library to 3.2 version &#8211; they have added some nice features (more information you can find in <a href="http://www.extjs.com/products/js/CHANGES_ext-3.1.0.html">changelog 3.1</a> and <a href="http://www.extjs.com/products/js/CHANGES_ext-3.2.0.html">changelog 3.2</a>) and changed some ExtJs components (more details you will find later).</p>
<p><span id="more-63"></span></p>
<p><strong>Configuration and project setup</strong></p>
<p>Information about how to setup new Symfony project and configure it to work well with ExtJS &#8211; you can find in this <a href="http://www.kamiladryjanek.com/2009/12/13/symfony-14-and-extjs-displaying-data-in-gridpanel-english">entry</a> &#8211; i&#8217;m not gonna repeat all steps again. Notice that you should download latest ExtJS version: 3.2 and set up view.yml file to attach neccessary files. You should also load sample data &#8211; we need it for our example.</p>
<p>After setting up the environment we can start coding. </p>
<p><div class="note"><div class="notehelp">In this example i will use a little bit diffrent type of configuration of ExtJS components &#8211; this is because next time i would like to show how to add funcionality of creating and updating new records. </div></div></p>
<p><strong>ExtJS components</strong></p>
<p>This time i&#8217;m going to put all JavaScript code in separate files &#8211; it is really good practice for building bigger ExtJS applications than in this example. First i will create grid.js file and put there grid component class and other configuration &#8211; i will create my own custom component class: App.country.Grid which inherits from Ext.grid.GridPanel &#8211; it&#8217;s not really needed now but it will save us time next time. Commnets should help you understand the concept:</p>
<pre class="brush: jscript; title: ; notranslate">

// Typical data Store automatically configured with a Ext.data.JsonReader.
var store = new Ext.data.JsonStore({
	// store configs
	url: 'default/list',  // url for retreiving data
    autoLoad: true,
    // reader configs
    totalProperty: 'total',
    successProperty: 'success',  // response status name
    idProperty: 'id',
    root: 'data',
    fields: ['id', 'name', 'description', 'population', 'created_at']
});

// Columns configuration
var columns =  [
    {header: &quot;ID&quot;, width: 50, fixed: true, sortable: true, dataIndex: 'id'},
    {header: &quot;Country&quot;, width: 50, sortable: true, dataIndex: 'name' },
    {header: &quot;Description&quot;, width: 100, sortable: true, dataIndex: 'description' },
    {header: &quot;Population&quot;, width: 50, sortable: true, dataIndex: 'population' },
    {header: &quot;Created at&quot;, width: 150, fixed:true, sortable: true, dataIndex: 'created_at' }
];

Ext.ns('App', 'App.country');
// my custom grid component
App.country.Grid = Ext.extend(Ext.grid.GridPanel, {

    initComponent : function() {

        // typical viewConfig
        this.viewConfig = {
            forceFit: true,
            emptyText: 'No data found.'
        };

        App.country.Grid.superclass.initComponent.call(this);
    }
});
</pre>
<p>I think this code do not need additional explanations.</p>
<p>Next step is to create main app.js file &#8211; place where i&#8217;m going to put my components logic (components initialization)  &#8211; nothing special so far &#8211; simple retrieving data and displaying it in grid. In this example i will place grid into simple window component &#8211; for better usability- it&#8217;s another good example of using ExtJS components. Code responsible for that:</p>
<pre class="brush: jscript; title: ; notranslate">

// when document is ready
Ext.onReady(function() {

	Ext.QuickTips.init();

	// create my custom grid component
    var grid = new App.country.Grid({

        store: store,  // data store for grid
        columns : columns,  //columns configuration
        plugins: [filters],  // additional plugin - Grid Filter Plugin
        bbar: new Ext.PagingToolbar({  //bottom bar configuration
    		pageSize: 15,   // records per page
    		store: store,
    		displayInfo: true
    	})
    });

    // simple window for grid
    var win = new Ext.Window({
        title: 'Advanced data filtering with Grid Filter Plugin',
        height: 410,
        width: 800,
        layout: 'fit',
        items: grid  // just one item
    });

    win.show();  // display window with grid

});
</pre>
<p><strong>On the server side</strong></p>
<p>There is one more thing to get it to work &#8211; we need PHP code on the server side. We can use code from the latest <a href="http://www.kamiladryjanek.com/2009/12/13/symfony-14-and-extjs-displaying-data-in-gridpanel-english">entry </a>or use the following:</p>
<pre class="brush: php; title: ; notranslate">

  public function executeList(sfWebRequest $request) {

  	 # data retrieved from the request
	$limit = $request-&gt;getParameter('limit', 15);
	$page = ($request-&gt;getParameter('start', 0)/$limit)+1;
	$dir = $request-&gt;getParameter('dir', 'ASC');
	$column = strtolower($request-&gt;getParameter('sort', 'name'));

	 # create query object
	$query = Doctrine_Query::create()
		-&gt;from('Country c');

	 # conditions for sorting
	if (Doctrine::getTable('Country')-&gt;hasColumn($column)) {

		$query-&gt;orderBy(sprintf('c.%s %s', Doctrine::getTable('Country')-&gt;getFieldName($column), $dir));
	}

	# object responsible for paging
	$pager = new sfDoctrinePager('Country', $limit);

	$pager-&gt;setQuery($query);
	$pager-&gt;setPage($page);
	$pager-&gt;init();

	$result = array();

	 # format result array
	foreach($pager-&gt;getResults() as $country) {

		$result[] = $country-&gt;toArray();
	}

	# formatted data are returned to the grid
	return $this-&gt;renderText(json_encode(array(
		'success'	=&gt; true,
		'total'		=&gt; $pager-&gt;getNbResults(),
		'data'		=&gt; $result
	)));
  }
</pre>
<p>Calling default action of our application we should achieved the following:</p>
<p><a href='http://www.kamiladryjanek.com/wp-content/uploads/2010/06/ext1.png'><img src="http://www.kamiladryjanek.com/wp-content/uploads/2010/06/ext1.png" alt="" title="Simple window with grid" width="500" height="245" class="aligncenter size-full wp-image-72" /></a></p>
<p><strong>Grid Filter plugin</strong></p>
<p>Next step is to apply Grid Filter plugin to our example.</p>
<p><div class="note"><div class="notetip">Since ExtJS 3.1 Grid filter plugin has been included in ExtJS package, so it&#8217;s not necessary to download any additional code.</div></div></p>
<p>I just only copied Filter plugin folder from Ext/examples/ux to Ext/ux for better code organisation. To add all neccessary JS and CSS files we need to edit view.yml file &#8211; final version should looks similar to this:</p>
<pre class="brush: xml; title: ; notranslate">

  stylesheets:
    - ../js/ext-3.2.0/resources/css/ext-all.css
    - ../js/ext-3.2.0/ux/gridfilters/css/GridFilters.css
    - ../js/ext-3.2.0/ux/gridfilters/css/RangeMenu.css

  javascripts:
    - ext-3.2.0/adapter/ext/ext-base-debug.js
    - ext-3.2.0/ext-all-debug.js
    - ext-3.2.0/ux/gridfilters/menu/RangeMenu.js
    - ext-3.2.0/ux/gridfilters/menu/ListMenu.js
    - ext-3.2.0/ux/gridfilters/GridFilters.js
    - ext-3.2.0/ux/gridfilters/filter/Filter.js
    - ext-3.2.0/ux/gridfilters/filter/StringFilter.js
    - ext-3.2.0/ux/gridfilters/filter/DateFilter.js
    - ext-3.2.0/ux/gridfilters/filter/ListFilter.js
    - ext-3.2.0/ux/gridfilters/filter/NumericFilter.js
    - ext-3.2.0/ux/gridfilters/filter/BooleanFilter.js
    - grid.js
    - app.js
</pre>
<p>Now we can configure filter component:</p>
<pre class="brush: jscript; title: ; notranslate">

var filters = new Ext.ux.grid.GridFilters({
    local: false,   // enable remote filtering
    filters: [{
        type: 'numeric',  // filter type
        dataIndex: 'id'    // column name
    }, {
        type: 'string',
        dataIndex: 'name'
    }, {
        type: 'string',
        dataIndex: 'description'
    }, {
    	type: 'numeric',
        dataIndex: 'population'
    }, {
        type: 'date',
        dataIndex: 'created_at'
    }]
}); 
</pre>
<p>And enable it in grid:</p>
<pre class="brush: jscript; title: ; notranslate">

    var grid = new App.country.Grid({

        store: store,  // data store for grid
        columns : columns,  //columns configuration
        plugins: [filters],  // additional plugin - Grid Filter Plugin
        bbar: new Ext.PagingToolbar({  //bottom bar configuration
    		pageSize: 15,   // records per page
    		store: store,
    		displayInfo: true
    	})
    });
</pre>
<p>So filter component could work properly we need to write additional PHP code responsible for filtering data. Using symfony and Doctrine Query Language it is really easy. The fallowing code of action.class.php presents complete code:</p>
<pre class="brush: php; title: ; notranslate">

  public function executeList(sfWebRequest $request) {

  	 # data retrieved from the request
	$limit = $request-&gt;getParameter('limit', 15);
	$page = ($request-&gt;getParameter('start', 0)/$limit)+1;
	$dir = $request-&gt;getParameter('dir', 'ASC');
	$column = strtolower($request-&gt;getParameter('sort', 'name'));

	 # create query object
	$query = Doctrine_Query::create()
		-&gt;from('Country c');

	 # conditions for sorting
	if (Doctrine::getTable('Country')-&gt;hasColumn($column)) {

		$query-&gt;orderBy(sprintf('c.%s %s', Doctrine::getTable('Country')-&gt;getFieldName($column), $dir));
	}

	 # code resposible for filtering data
	foreach($request-&gt;getParameter('filter') as $filter) {

		 # comparison condition
		if (isset($filter['data']['comparison'])) {

			switch($filter['data']['comparison']) {

				case 'eq':

					$comparison = '=';
					break;

				case 'lt':

					$comparison = '&lt;';
					break;

				case 'gt':

					$comparison = '&gt;';
					break;
			}
		}

		 # switch 5 filter types
		switch($filter['data']['type']) {

			case 'boolean':

				$query-&gt;addWhere(sprintf('c.%s = ?', $filter['field']), $filter['data']['value']);

				break;

			case 'string':

				$query-&gt;addWhere(sprintf('c.%s LIKE ?', $filter['field']), '%'.$filter['data']['value'].'%');

				break;

			case 'numeric':

				$query-&gt;addWhere(sprintf('c.%s %s ?', $filter['field'], $comparison), $filter['data']['value']);

				break;

			case 'list':

				$query-&gt;whereIn(sprintf('c.%s', $filter['field']), explode(',', $filter['data']['value'])); 

				break;

			case 'date':

				$query-&gt;addWhere(sprintf('c.%s %s ?', $filter['field'], $comparison), date('Y-m-d', strtotime($filter['data']['value'])));

				break;

			default:

				break;
		}
	}

	# object responsible for paging
	$pager = new sfDoctrinePager('Country', $limit);

	$pager-&gt;setQuery($query);
	$pager-&gt;setPage($page);
	$pager-&gt;init();

	$result = array();

	 # format result array
	foreach($pager-&gt;getResults() as $country) {

		$result[] = $country-&gt;toArray();
	}

	# formatted data are returned to the grid
	return $this-&gt;renderText(json_encode(array(
		'success'	=&gt; true,
		'total'		=&gt; $pager-&gt;getNbResults(),
		'data'		=&gt; $result
	)));
  }

}
</pre>
<p>Thats all. As a result we should get: </p>
<p><a href='http://www.kamiladryjanek.com/wp-content/uploads/2010/06/ext2.png'><img src="http://www.kamiladryjanek.com/wp-content/uploads/2010/06/ext2.png" alt="" title="Sample Grid with Filter plugin" width="500" height="246" class="aligncenter size-full wp-image-73" /></a></p>
<p>Enyoj!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2010/06/advanced-data-filtering-with-symfony-14-and-extjs-32-english/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Symfony and jQuery: sfWidgetFormJQueryMultiSelect ver 0.1</title>
		<link>http://www.kamiladryjanek.com/2010/02/symfony-and-jquery-sfwidgetformjquerymultiselect-ver-01/</link>
		<comments>http://www.kamiladryjanek.com/2010/02/symfony-and-jquery-sfwidgetformjquerymultiselect-ver-01/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 19:07:38 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[Ext JS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[sfForm]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=70</guid>
		<description><![CDATA[Recently i created nice and simple Symfony widget: sfWidgetFormJQueryMultiSelect. It&#8217;s really simple in use and implementation. I have used code written recently by Eric Hynds: jQuery MultiSelect Plugin w/ ThemeRoller Support and standard sfWidgetFormChoice. As a result, i received sfWidgetFormJQueryMultiSelect. How to use it Include into your application neccessary JavaScripts (jQuery 1.4+ and jQuery UI [...]]]></description>
			<content:encoded><![CDATA[<p>Recently i created nice and simple Symfony widget: sfWidgetFormJQueryMultiSelect. It&#8217;s really simple in use and implementation. I have used code written recently by Eric Hynds: <a title="jQuery Multiselect" rel="external nofollow" href="http://www.erichynds.com/jquery/jquery-multiselect-plugin-with-themeroller-support/" target="_blank">jQuery MultiSelect Plugin w/ ThemeRoller Support</a> and standard sfWidgetFormChoice.</p>
<p><span id="more-70"></span><br />
As a result, i received sfWidgetFormJQueryMultiSelect.</p>
<pre class="brush: php; title: ; notranslate">

&lt;?php

/**
* sfWidgetFormJQueryMultiSelect represents a multi choice select widget.
*
* @package    symfony
* @subpackage widget
* @author     Kamil Adryjanek &lt;kamil.adryjanek@gmail.com&gt;

*/
class sfWidgetFormJQueryMultiSelect extends sfWidgetFormChoice
  {
    /**
    * Constructor.
    *
    * Available options:
    *
    *  * choices:          An array of possible choices (required)
    *  * renderer_class:   The class to use instead of the default ones
    *  * renderer_options: The options to pass to the renderer constructor
    *  * renderer:         A renderer widget (overrides the expanded and renderer_options options)
    *                      The choices option must be: new sfCallable($thisWidgetInstance, 'getChoices')
    * @param array $options     An array of options
    * @param array $attributes  An array of default HTML attributes
    *
    * @see sfWidgetFormChoiceBase
    */

    protected function configure($options = array(), $attributes = array())
    {
        $this-&gt;addOption('config', '{}');

        parent::configure($options, $attributes);

        $this-&gt;setOption('multiple', true);
        $this-&gt;setOption('expanded', true);
    }

    /**
    * @param  string $name        The element name
    * @param  string $value       The value selected in this widget
    * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
    * @param  array  $errors      An array of errors for the field
    *
    * @return string An HTML tag string
    *
    * @see sfWidgetForm
    */
    public function render($name, $value = null, $attributes = array(), $errors = array())
    {
        return parent::render($name, $value, $attributes, $errors).
        sprintf(&lt;&lt;&lt;EOF
            &lt;script type=&quot;text/javascript&quot;&gt;
                jQuery(document).ready(function() {
                    jQuery(&quot;#%s&quot;).multiselect(
                        %s
                    );
                });

            &lt;/script&gt;
        EOF,
        $this-&gt;generateId($name),
        $this-&gt;getOption('config')
    );
  }
}
</pre>
<p><strong>How to use it</strong><br />
Include into your application neccessary JavaScripts (jQuery 1.4+ and jQuery UI required) and stylesheets: (for example view.yml):</p>
<pre class="brush: xml; title: ; notranslate">

stylesheets:    [main.css, ui-lightness/jquery-ui-1.7.2.custom.css, jquery.multiselect.css]

javascripts:    [jquery.js, jquery-ui.js, jquery.multiselect.js]
</pre>
<p>Then we need to create simple form and set our widgets:</p>
<pre class="brush: php; title: ; notranslate">

&lt;?php

class SimpleForm extends sfForm {

    public function configure() {

        $userChoices = array('John', 'Michael', 'Tom', 'Peter');

        $this-&gt;setWidgets(array(
            'users'	=&gt; new sfWidgetFormJQueryMultiSelect(array(
                'choices'	=&gt; $userChoices
            ));
        ));

        $this-&gt;setValidators(array(
            'users'	=&gt; new sfValidatorChoice(array(
                'choices'	=&gt; array_keys($userChoices)
            ))
    ));
  }
}
</pre>
<p><strong>How does it work (look)</strong><br />
Form should now look similar to that:</p>
<p><a href="http://www.kamiladryjanek.com/wp-content/uploads/2010/02/multi1.png"><img class="alignnone size-full wp-image-71" title="multi1" src="http://www.kamiladryjanek.com/wp-content/uploads/2010/02/multi1.png" alt="MultiSelect Widget" width="500" height="243" /></a></p>
<p>Widget should work with Symfony 1.2.X &#8211; 1.4.X.</p>
<p>More information about jquery.multiselect plugin can be found <a title="jQuery Multiselect" rel="external nofollow" href="http://www.erichynds.com/jquery/jquery-multiselect-plugin-with-themeroller-support/" target="_blank">on this page</a>.</p>
<p>In the near future I would like to create Symfony widget and put there some of my custom widgets (for example sfWidgetFormJQueryDateTime).</p>
<p>Enjoy</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2010/02/symfony-and-jquery-sfwidgetformjquerymultiselect-ver-01/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>ExtJS and simple JavaScirpt Internationalization (i18n)</title>
		<link>http://www.kamiladryjanek.com/2010/01/extjs-ans-simple-javascirpt-internationalization-i18n/</link>
		<comments>http://www.kamiladryjanek.com/2010/01/extjs-ans-simple-javascirpt-internationalization-i18n/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 18:39:55 +0000</pubDate>
		<dc:creator>Kamil Adryjanek</dc:creator>
				<category><![CDATA[Ext JS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.kamiladryjanek.com/?p=67</guid>
		<description><![CDATA[Lastely, building quite big Symfony and Ext.js application i was looking for simple way to make my application internationalized. I haven&#8217;t found any good solutions that would suits my needs. I found this on extjs forum: &#8216;The simplest way, perhaps, is to extract hardcoded strings to locale files. Then your framework just have to load [...]]]></description>
			<content:encoded><![CDATA[<p>Lastely, building quite big Symfony and Ext.js application i was looking for simple way to make my application internationalized. I haven&#8217;t found any good solutions that would suits my needs. I found this on extjs forum: &#8216;The simplest way, perhaps, is to extract hardcoded strings to locale files. Then your framework just have to load the selected language file together with YUI-ext.&#8221; I didn&#8217;t like that idea, i think it would be good for building some custom components but not for internationalize the whole application. I needed something quicker and less complicated.<br />
Than, i thought that i can write my own simple i18n mechanism &#8211; maybe there is better way (files can be generated on the server side), but this work for sure.<br />
<span id="more-67"></span><br />
I simple wrote custom JavaScript function __(string) and put it into one of my .js files:</p>
<pre class="brush: jscript; title: ; notranslate">

function __(string) {

	 if (typeof(i18n)!='undefined' &amp;amp;&amp;amp; i18n[string]) {

		return i18n[string];
	}

	return string;
}
</pre>
<p>Then i attached another JavaScript file with translations object (before including __() function), for example we can call this file &#8222;pl_PL.js&#8221; and put there code:</p>
<pre class="brush: jscript; title: ; notranslate">

var i18n = {
	'Country.'							: 'Kraj',
	'Description'						: 'Opis',
	'Population'						: 'Populacja',
	'Created at'						: 'Data utworzenia',
	'Symfony 1.2 and Ext.js example'	: 'Przykład wykorzystania Symfony 1.2 i Ext.js '
}
</pre>
<p>In our ExtJS components (or any other JavaScript code) we just simple call (example code from latest entry):</p>
<pre class="brush: jscript; title: ; notranslate">

	//columns structure
	var columns = [
		{id:'name',header: __('Country'), width: 160, sortable: true, dataIndex: 'name'},
		{header: __('Description'), width: 160, sortable: false, dataIndex: 'description'},
		{header: __('Population'), width: 160, sortable: true, dataIndex: 'population'},
		{header: __('Created at'), width: 100, sortable: true, dataIndex: 'created_at'}
	];

	// gridPanel object
	var grid = new Ext.grid.GridPanel({
		title: __('Symfony 1.2 and Ext.js example'),
		loadMask: true,   // mask panel when data is loading
		store: store,
		columns: columns,
		autoExpandColumn: 'name',
		height: 400,
		width: 600,
		renderTo: 'grid-example'  // DOM element
	});

});
</pre>
<p>For me it&#8217;s simple, powerfull and really usefull. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kamiladryjanek.com/2010/01/extjs-ans-simple-javascirpt-internationalization-i18n/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

