Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu symfony Kanał ATOM (tag: symfony)

Autor wpisu: batman, dodany: 12.10.2010 08:00, tagi: php, symfony

Programistę aplikacji internetowych, którzy nie korzysta z żadnego frameworka, można porównać do stolarza, który produkuje meble przy pomocy młotka i gwoździ. Niby się da, ale efekt końcowy jest zawsze taki sam – opłakany. Taka właśnie myśl przyświecała mi podczas poznawania frameworków PHP. Ostatecznie mój wybór padł na Zend Frameworka i nie żałuję tej decyzji. Jakiś czas temu przeczytałem wpis Zyxa na temat EventDispatchera, który można zleźć w Symfony 2 i postanowiłem sprawdzić o co tyle szumu. Od razu zaznaczę, iż wszystkie moje wnioski dotyczą nieukończonej jeszcze wersji 2 (celowo nie zaglądałem do aktualnej wersji – 1.4), a co za tym idzie coś, co teraz nie działa, może być naprawione w stabilnej wersji. Co więcej, moje podejście do frameworków PHP jest nieco wypaczone ze względu na ZF, więc zanim zaczniecie po mnie jeździć jak po łysej kobyle, weźcie to pod uwagę.

Instalacja

Na ten temat zbyt dużo nie da się napisać. Ściągamy gotowy sandbox, rozpakowujemy na serwerze i uruchamiany testową stronę. Proste jak konstrukcja cepa.

Pierwsze kroki

Jak to zwykle bywa w przypadku nauki czegoś nowego, staramy się oprzeć na zdobytych wcześniej doświadczeniach. Nie inaczej było tym razem. Dzięki temu, że dobrze znam ZF oraz mam jakieś pojęcie o ASP.NET MVC, stosunkowo łatwo było mi się odnaleźć w strukturze projektu i aplikacji. Wprawdzie po przeczytaniu The Big Picture pojawiło się więcej pytań niż odpowiedzi, byłem jednak pozytywnie zaskoczony prostotą, jaką oferuje Symfony 2. Jedyne co mi się nie podobało to fakt, iż osoby nie mające pojęcia o frameworkach, rozbiją się o ścianę swojej niewiedzy, co może skutecznie ich zniechęcić do dalszej nauki.

Widoki

Na samym początku opisu natknąłem się na informację o szablonach Twig. Nie należę do zwolenników szablonów w PHP, więc nieco mnie zmartwiło, że framework ma takie coś wbudowane. Na szczęście można korzystać z czystego PHP.

Po tym niewielkim zgrzycie, zagłębiłem się w lekturę dalszej części przewodnika, w której opisane zostały szablony (Templates) oraz sloty (Slots). Generalnie, założenia nie odbiegają znacząco od tego, co poznałem w ZF. Zend_Layout, Zend_View oraz helpery widoku dobrze mnie przygotowały do tego, co zobaczyłem w Symfony 2.

Kontroler

Ta część była nieco enigmatyczna. Bez żadnego łagodnego wprowadzenia, od razy skok na głęboką wodę. Kolejny raz doświadczenie zdobyte podczas pracy z ZF zaowocowało. Opisane w tej części przewodnika formaty są niczym innym jak kontekstami znanymi z Zend Frameworka. Nieco inaczej się je definiuje, ale zasada działania jest identyczna.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Wojciech Sznapka, dodany: 27.09.2010 09:24, tagi: symfony, php

Na firmowym blogu XSolve xlab.pl umieściłem artykuł o uporządkowanym wysyłaniu e-maili w projektach symfony 1.4, wykorzystującym dobrodziejstwa programowania zorientowanego obiektowo. Krótki wstęp: Niemal każdy projekt, z jakim miałem do czynienia, zawierał fragmenty, w których były wysyłane e-maile. Najczęściej czynność ta jest wykonywana w kontrolerze aplikacji (klasa actions), a treścią wiadomości jest wyrenderowany partial. To rozwiązanie [...]

Autor wpisu: Damian Rusinek, Piotr Wierzgała, dodany: 18.07.2010 21:50, tagi: symfony

After integrating Symfony with Flex through Zend_Amf, I had to debug it and I needed some logs on server side. Below I present my LoggedAmfServer extending Zend_Amf_Server, which logs all methods called by Flex and its’ responses. You need to pass instance of sfLogger (ie. sfFileLogger) in the constructor.

logger = $l; parent::__construct(); } protected function _handle(Zend_Amf_Request $request) { $responseBody = $request->getAmfBodies(); $body = current($responseBody); if ($body !== false) { $data = $body->getData(); if ($data instanceof Zend_Amf_Value_Messaging_RemotingMessage) { $this->logger->log(sprintf("[Amf Request] CLIENT: [%s] OPERATION: [%s]. PARAMETERS: [%s].", $data->clientId, $data->operation, var_export($data->body, true))); } } parent::_handle($request); } public function handle($request = null) { $response = parent::handle($request); $body = current($response->getAmfBodies()); if ($body !== false) { $data = $body->getData();

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Piotr Śliwa, dodany: 17.07.2010 13:31, tagi: symfony, php

Kilka miesięcy temu popełniłem wpis na temat wielostronicowych formularzy, zaprezentowałem tam m. in. mój plugin do symfony, który tą funkcjonalność automatyzuje. Udostępniłem go niedawno w zbiorze pluginów symfony, znajduje się on tutaj. Między czasie został on zrefaktorowany i zostały dodane nowe klasy.

Wprowadzenie

Główną klasą tego pluginu jest psPageableForm, hermetyzuje ona zarządzanie formularzami. Klasa ta ma podobny interfejs co klasa sfForm, jednakże nie rozszerza jej z tego powodu, gdyż zbyt wiele metod musiałoby być unieważnionych. Podstawowymi metodami klasy wielostronicowego formularza to:
  • psPageableForm::addForm(sfForm) - dodanie formularza na koniec listy (formularz zostaje skojarzony z ostatnią stroną)
  • psPageableForm::setForm(sfForm, int) - dodanie formularza na określoną stronę, formularze ze stron wyższych bądź równych stronie podanej jako argument zostają przesunięte o jedną pozycję dalej.
  • psPageableForm::setUseGlobalNamespace(bool) - czy format poszczególnych formularzy składowych ma zostać spłaszczony do jednego wymiaru, czy też format wielostronicowego formularza oraz formularzy składowych mają zostać połączone ze sobą. Domyślna jest ta pierwsza opcja. Należy wywołać przed dodaniem pierwszego formularza składowego!
  • psPageableForm::setNameFormat(string) - ustawia format nazw widgetów wielostronicowego formularza. Należy wywołać przed dodaniem pierwszego formularza składowego!
  • psPageableForm::setCurrentPageNumber(int) - ustawienie obecnej strony formularza
  • psPageableForm::getCurrentPageNumber() - pobranie obecnej strony formularza
  • psPageableForm::bind(array, array) - wypełnienie formularza danymi oraz jego walidacja
  • psPageableForm::isValid() - sprawdzenie czy wszystkie zwalidowane formularze są prawidłowe, nie oznacza że formularz jest w całości poprawny
  • psPageableForm::getCurrentForm() - pobranie obiektu formularza składowego skojarzonego z obecną stroną
  • psPageableForm::setPersistanceStrategy(psPageableFormPersistanceStrategy) - ustawienie strategii trwałości

Istnieje również interfejs strategii trwałości, który deklaruje trzy metody:

  • psPageableFormPersistanceStrategy::persist(psPageableForm) - zapisanie formularza do źródła danych
  • psPageableFormPersistanceStrategy::getValues() - pobranie zapisanych wartości formularza
  • psPageableFormPersistanceStrategy::clear() - wyczyszczenie obiektu
Na dzień dzisiejszy są trzy implementacje tego interfejsu:
  • psPageableFormPostPersistanceStrategy - przechowuje wartości w ukrytych polach formularza
  • psPageableFormSessionPersistanceStrategy - przechowuje wartości w sesji
  • psPageableFormDatabasePersistanceStrategy - przechowuje wartości w bazie danych (wykorzystanie Doctrine)
Ostatnią klasą jest psPageableFormProcess, która automatyzuje przetwarzanie formularza, dba o odpowiednie ustawianie numerów stron podczas niepoprawnej walidacji oraz o odpowiedni stan formularza. Jedyną jej metodą (oprócz konstruktora) to metoda psPageableFormProcess::process(), która to w odpowiedni sposób przetwarza formularz. Dzięki tej klasie kod w kontrolerze jest zredukowany do minimum.

Przykład

Utworzenie wielostronicowego formularza sprowadza się do utworzenia kilku zwykłych formularzy symfony - jeden formularz na jedną stronę. Następnie definiujemy podklasę psPageableForm.

[PHP]
  1. class PageableForm extends psPageableForm
  2. {
  3. public function setup()
  4. {
  5. $this->setNameFormat('form[%s]');
  6. $this->setUseGlobalNamespace(false);
  7.  
  8. //wyłączenie ochrony csrf dla wszystkich formularzy z wyjątkiem ostatniego
  9. $form1 = new Form1(array(), array(), false);
  10. $this->addForm($form1);
  11.  
  12. $form2 = new Form2(array(), array(), false);
  13. $this->addForm($form2);
  14.  
  15. $form3 = new Form3();
  16. $this->addForm($form3);
  17. }
  18. }

W kontrolerze tworzymy obiekt zdefiniowanej klasy, ustawiamy strategię trwałości, tworzymy obiekt klasy psPageableFormProcess z odpowiednimi parametrami oraz wywołujemy metodę psPageableFormProcess::process().

[PHP]
  1. public function executeProcess(sfWebRequest $request)
  2. {
  3. $form = new PageableForm();
  4. $form->setPersistanceStrategy(new psPageableFormSessionPersistanceStrategy($this->getUser()));
  5. $process = new psPageableFormProcess($form, $request, function(){
  6. // funkcja zwrotna wywoływana gdy formularz zostanie w całości poprawnie zwalidowany
  7. }, array('formParameterName' => 'form')
  8. );
  9. $process->process();
  10. $this->form = $form;
  11. }

W szablonie wyświetlamy formularz z obecnej strony.

[PHP]
  1. <form action="<?php echo url_for('module/action?step='.($form->getCurrentPageNumber() + 1)) ?>" method="post">
  2. <?php echo $form->getCurrentForm() ?>
  3.  
  4. <?php if($form->getCurrentPageNumber() > 1): ?>
  5. <a href="?step=<?php echo $form->getCurrentPageNumber() ?>">Wróć</a>
  6. <?php endif; ?>
  7. <input type="submit" value="dalej" />
  8. </form>

Więcej przykładów z kodem źródłowym znajdziecie tutaj.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Damian Rusinek, Piotr Wierzgała, dodany: 02.07.2010 12:23, tagi: doctrine, symfony

Overriding methods should not be a problem, but it can make you confused if you don’t know how magic functions are used in Symfony 1.4 models.

In this short article I will explain why usual overriding does not work in Symfony models and how to override methods handled by magic functions.

Suppose, we have a base model class BaseTopic:

abstract class BaseTopic extends sfDoctrineRecord { public function setTableDefinition() { $this->setTableName('topic'); $this->hasColumn('name', 'string', 255, array( 'type' => 'string', 'notnull' => true, 'length' => 255, )); $this->hasColumn('updates_count', 'integer', null, array( 'type' => 'integer', )); } }

and our class:

public class Topic extends BaseTopic { }

Now we want to update updates_count field each time we modify name field.

First guess is to do the following:

public class Topic extends BaseTopic { public function setName($name) { $this->updates_count++; return parent::setName($name); } }

However it will not work unless you have declared method setName in BaseTopic literally (magical __call does not count).

Upper method will do the following:

  1. Increment updates_count field
  2. Call setName method from BaseTopic (which does not exist literally) so it will look for this method in parents
  3. Because there is no setName in any parent class, it will go to Doctrine_Record and call __call method which will find setName method in Topic class
  4. Call setName from Topic class again

To solve this problem you have to use _set function from Doctrine_Record class:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Damian Rusinek, Piotr Wierzgała, dodany: 31.05.2010 14:05, tagi: symfony

Szeroki wybór możliwości połączenia PHP i Flexa możemy uważać za coś pozytywnego, ponieważ każdy może sobie odnaleźć swój sposób integracji server-side z client-side. Jednakże na długą metę okazuje się to zmorą, bo człowiek (przynajmniej ja tak mam) zaczyna się zastanawiać, czy to drugie rozwiązanie nie jest lepsze.

Dlatego postanowiłem znaleźć jakiś sposób integracji, który będzie szybki i dobry :). Przeglądając różne stronki o Flexie, odnalazłem prezentację (niestety nie pamiętam adresu), na której ładnie przedstawiony był fakt, że AMF to idealny protokół komunikacji z Flexem. Nic dziwnego, w końcu to twór Adobe.

Ok, protokół mamy. Teraz wypada wybrać implementację. Jako, że jestem użytkownikiem frameworka Symfony, to właśnie z nim chciałbym zintegrować Flexa.

Wiem, że istnieje plugin do symfony sfAmfPlugin (strona głowna). Nie będe się o nim rozpisywał. Jak ktoś jest ciekawy, to niech śmiga na jego stronę główną. Powiem tylko, że jest on oparty na bibliotece SabreAMF, której szczerze mówiąc nie znam. Wiem natomiast, że biblioteka Zend’a jest dobra do wsyztskiego :), dlatego właśnie z niej korzystam.

Poniżej przedstawiam opis jak zrobić szybko HelloWorld we Flexie, z wykorzystaniem Symfony i AMF oraz bibliotek Zenda. We wszystkich HelloWorld’ach w necie brakowało mi tego połączenia.

Zaczynamy

Na początku trzeba postawić zwykły projekt Symfony i dodać jakąś aplikację – ja dodałem aplikacje o nazwie frontend. Zakładam, że ludzie czytający wpis o symfony wiedzą jak to zrobić :)

Następnie należy zintegrować odpowiednie biblioteki Zenda. Integracja została opisana we wpisie Integracja Symfony + Zend.

Oto lista plików jakie należy umieścić w katalogu /lib/vendor/Zend:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Wojciech Sznapka, dodany: 13.05.2010 23:00, tagi: symfony, php

The sfWidgetFormSelect doesn't provide ability to render disabled options. It's rarely used feature of a HTML select element, but sometimes it could save your life :-) In fact, we can achieve this feature by creating our own widget, which inherits from sfWidgetFormSelect.
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.