strony www, sklepy internetowe, oprogramowanie

Symfony2 – pobieranie routingu z katalogu bundle

2011/08/13 ; dodane przez lskowronski

Wraz z rozwojem aplikacji chcielibyśmy, aby pliku konfiguracyjne routingu odpowiedzialne za dostęp do bundle były przechowywane we właściwym bundle. Aby to osiągnąć trzeba dokonać kilku prostych modyfikacji.  Modyfikacji te analogicznie należy zastosować we wszystkich wykorzystywanych środowiskach.

Załóżmy, że chcemy wstępnie zastąpić plik routing.yml plikiem routing.php . Jak zrobić, aby Symfony zainteresowało się tym drugim?

Przechodzimy do konfiguracji app/config/config.yml i w sekcji framework zmieniamy

router:          { resource: “%kernel.root_dir%/config/routing.yml” }

na

router:          { resource: “%kernel.root_dir%/config/routing.php” }

Czyścimy cache i od teraz routing będzie pobierany z pliku routing.php .

Ale co wpisać w routing.php, aby pobierał on pliki yml z katalogów bundle? Oto przykładowy kod pliku:


use Symfony\Component\Routing\RouteCollection;

$collection = new RouteCollection();

$collection->addCollection($loader->import("@LmSecurityBundle/Resources/config/routing.yml"));
$collection->addCollection($loader->import("@LmUserBundle/Resources/config/routing.yml"));

return $collection;

Po zdefiniowaniu w ten sposób lokalizacji pliku yml będzie on pobierany i interpretowany. Dzięki czemu możemy jeszcze bardziej wykorzystać bundle jako niezależne paczki.

Należy pamiętać, aby w przypadku routing_dev.php poza lokalizacjami plików bundle dodać jeszcze :

$collection->addCollection($loader->import(”routing_dev.yml”));

Aby doczytywane były elementy typu pasek debug.

Symfony2 – jak w TWIG dostać się do zmiennej przekazanej przez URL

2011/08/08 ; dodane przez lskowronski

Oto kolejna krótka porada z cyklu Symfony2 i Twig.

Na pewno nie jeden raz trafi nam się sytuacja gdy będziemy chcieli skorzystać ze zmiennych przekazywanych poprzez GET/POST/URL .

Jak w Twig dostać się do tych zmiennych bez ich jawnego deklarowania w akcji?

To proste (aczkolwiek znowu próżno szukać tego w dokumentacji) – w szablonie korzystamy z wywołania:

app.request.attributes.get('nazwa_zmiennej_z_url')

Symfony2 i Doctrine2 – indexy wielokolumnowe

2011/07/16 ; dodane przez lskowronski

W tym krótkim artykule zaprezentujemy jak zdefiniować w symfony2 + doctrine2 indexy wielokolumnowe – zwykłe oraz unikalne.

Sprawa wydaje się być prosta i mogłaby zostać opisana w standardowej dokumentacji symfony2 – tak jednak nie jest i trzeba się troszkę namęczyć żeby takie informacje znaleźć. Skoro my już przez to przeszliśmy, dzielimy się tą wiedzą, abyście Wy już nie musieli na to tracić czasu.

Zatem – załóżmy że mamy Entity o definicji:


/**
* @ORM\Entity
* @ORM\Table(name="SitePage")
*/
class SitePage
{
/**
* @ORM\Id
* @ORM\Column(type="integer", nullable="false")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\ManyToOne(targetEntity="Site", inversedBy="pages")
* @ORM\JoinColumn(name="idSite", referencedColumnName="id", onDelete="CASCADE")
*/
protected $site;
protected $idSite;

/**
* @ORM\Column(type="string",length="255", nullable="false")
*/
protected $name;

/**
*
* @ORM\Column(type="string",length="255", nullable="false")
*/
protected $slug;
}

Zależy nam na tym, aby kolumna slug wraz z kolumną idSite stanowiły index. Rozpatrzymy dwa przypadki:

  1. index zwykły
  2. index unikalny

W obu przypadkach musimy rozszerzyć definicję

@ORM\Table(name="SitePage")

W pierwszym przypadku (zwykły index) będzie to wyglądać w sposób następujący:

@ORM\Table(name="SitePage", indexes={@ORM\Index(name="index_site_page_slug_idx", columns={"idSite","slug"})})

Natomiast w drugim przypadku (index unikalny) będzie to wyglądać tak:

@ORM\Table(name="SitePage", uniqueConstraints={@ORM\Index(name="unique_site_page_slug_idx", columns={"idSite","slug"})})

Po odpowiedniej zmianie standardowo wywołujemy komendy odpowiedzialne za ponowne przegenerowanie Entity oraz update w bazie danych czyli:

php app/console doctrine:generate:entities Namespace

php app/console doctrine:schema:update --force

I to tyle – mam nadzieję, że uda nam się oszczędzić trochę Waszego czasu.

Symfony2 style i javascript z bundle

2011/06/28 ; dodane przez lskowronski

Jeżeli chcemy w naszej aplikacji korzystać z plików css bądź js znajdujących się w bundle tworzymy w bundle ścieżki katalogów:


App\NameBundle\Resources\public\js
App\NameBundle\Resources\public\css

A następnie dodajemy w nich nasze pliki np plik test.css

Po wprowadzeniu pierwszych definicji w naszych stylach instalujemy style poprzez:

app/console assets:install --symlink web/
Należy zwrócić uwagę na wygenerowane ścieżki, ponieważ będzie to potrzebne przy linkowaniu styli.
Po tych operacjach możemy już w naszych szablonach twig korzystać z kodu:

<link rel=”stylesheet” type=”text/css”  href=”{{ asset(’bundles/appname/css/test.css’) }}” />

Od tego momentu możemy już zaobserwować zmiany wyglądu.

Symfony2 services i event listener

2011/06/27 ; dodane przez lskowronski

Jeżeli jesteś osobą programującą wcześniej w Symfony w wersji 1.* na pewno miałeś okazję korzystać z filtrów które są niesamowicie przydatnym mechanizmem. Szukając tego mechanizmu w Symfony2 niestety w pierwszej chwili możemy się rozczarować – ponieważ nie istnieje w nim rozwiązanie 1:1 takie samo.

Ale jak to zwykle bywa, nie ma tego złego co by na dobre nie wyszło. Zamiast filtrów możemy skorzystać z Event Listenerów i Serwisów.
Postawmy sobie założenie: “chcemy przed wyświetleniem treści w każdym kontrolerze/akcji wyświetlić dodatkowy tekst”

Rozpoczynamy od stworzenia klasy Listener’a .

W naszym przypadku będzie to plik w lokalizacji App\NameBundle\Listener\ o nazwie CheckListener.php

namespace App\NameBundle\Listener;

use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;

class CheckListener
{
public function onCoreController() {
echo 'added in App\NameBundle\Listener\CheckListener\Controller'.'
';
}
public function onCoreRequest() {
echo 'added in App\NameBundle\Listener\CheckListener\Request'.'
';
}
}

W klasie mamy zdefiniowane dwie metody które wykorzystamy przy zgłaszaniu eventu przez controller oraz request.

Przyszedł czas na podłączenie naszego Listenera do Symfony2. Do tego wykorzystujemy kod w pliku config.yml :

services:
kernel.listener.check_controller:
class: App\NameBundle\Listener\CheckListener
tags:
- { name: kernel.event_listener, event: kernel.controller , method: onCoreController }
kernel.listener.check_request:
class: App\NameBundle\Listener\CheckListener
tags:
- { name: kernel.event_listener, event: kernel.request , method: onCoreRequest }

Dzięki tej konfiguracji wszystko powinno już działać. Kolejny plusem jest iż po wywołaniu strony przekonamy się który z mechanizmów zostanie wykonany jako pierwszy.
Możemy uchylić rąbka tajemnicy i jednoznacznie stwierdzamy iż jako pierwszy zostanie uruchomiony kernel.request a dopiero kolejno kernel.controller.

Symfony2 i Doctrine2 relacja OneToOne

2011/06/26 ; dodane przez lskowronski

Jak zrobić relację jeden do jednego w Symfony2 i Doctrine2 – sprawa wydaje się banalnie prosta i w rzeczy samej taka jest, ale niestety pominięto to w dokumentacji Symfony2. Przy okazji tego problemu weźmiemy też pod uwagę wykorzystanie Entity z innego Bundle.

Załóżmy więc, że mamy Entity Foo\NaszeBundle\Entity\Tabela1 oraz Foo\IchBundle\Entity\Tabela2

W tabeli Tabela2 chcemy umieścić klucz obcy do tabeli Tabela1. Zatem w definicji Entity Tabela2 umieszczamy następujący kod:

/**
* @ORM\OneToOne(targetEntity=”Foo\NaszeBundle\Entity\Tabela1″)
* @ORM\JoinColumn(name=”idTabela1″, referencedColumnName=”id”)
*/
protected $idTabela1;

Dzięki tak prostej regule w definicji Entity Tabela2 zmienna $idTabela1 stanie się kluczem obcym do Tabela1.

mssql i freetds w ubuntu lub debian

2011/06/22 ; dodane przez lskowronski

Jeżeli w swojej pracy bądź pasji tworząc nową aplikację trafiliście na konieczność współdziałania php z bazą mssql i do tego na serwerze opartym o debian/ubuntu na pewno trafiliście na problem braku sterownika do połączenia.

Aby móc połączyć naszą aplikację php z serwerem mssql konieczne będzie zainstalowanie i skonfigurowanie freetds.
Można zrobić to w kilku szybkich krokach – oto one:

  1. Instalujemy freetds z pakietów deb
    sudo apt-get install freetds-dev
  2. Instalujemy bibliotekę mssql w php (o ile nie została zainstalowana wcześniej)
    sudo apt-get install php5-mssql
  3. Znajdujemy plik konfiguracyjny freetds i edytujemy go
    sudo find / -name freetds

    Z listy wyszukanych plików wybieramy odpowiedni, w naszym przypadku jest to plik:
    sudo mcedit /etc/freetds/freetds.conf

    na końcu pliku dodajemy sekcję:
    [nasz_host]
    host=nasz_host
    port=1433
    tds version=8.0

  4. Edytujemy plik hosts
    sudo mcedit /etc/hosts

    i dodajemy w nim nasz host np.
    127.0.0.1 nasz_host

  5. Restartujemy apache
    sudo etc/init.d/apache2 restart

Od teraz możemy korzystać już z naszego host’a do połączeń z serwerem mssql .

polecenia symfony2 spod konsoli

2011/04/19 ; dodane przez lskowronski

Zaczynamy naukę symfony 2. Zapewne większa część osób które próbują swoich sił z symfony 2 miało już do czynienia z wersjami symfony < 2. W poprzednich wersjach zostaliśmy przyzwyczajeni do wygodnego dostępu do tasków poprzez szybką komendę

symfony

W nowej wersji stety/niestety zostało to zmienione i obecnie, aby dostać się do tasków musimy korzystać ze składni:

php app/console

Nawiązuje to bardziej do nowej struktury aplikacji w symfony. Przykładowo, aby wykonać czyszczenie cache nie skorzystamy już z wygodnego

symfony cc

ale będziemy musieli wywołać komendę:

php app/console cache:clear

Aby wyświetlić wszystkie standardowe taski na wzór poprzedniego symfony wywołujemy po prostu php app/console

Automatyczny backup plików i bazy danych

2011/04/17 ; dodane przez lskowronski

Jeżeli ktoś z Was dysponuje dedykowanym serwerem i chciałby cyklicznie wykonywać backup plików i bazy danych bądź chciałby zabezpieczać dane ze swojego komputera – rozwiązaniem może być skrypt uruchamiany poprzez Cron’a. Rozwiązanie to jest skuteczne w przypadku systemów Linux. Nasz przykład będzie opierał się o system FreeBSD.

W pierwszej kolejności opiszmy schemat działania. W kolejnych krokach wygląda to w sposób następujący:

  1. utworzenie katalogu tymczasowego w którego nazwie będzie dzisiejsza data
  2. utworzenie wewnątrz katalogu tymczasowego katalogu na pliki i oddzielnego na dump bazy danych
  3. utworzenie backupu bazy danych i zapisanie w naszej lokalizacji
  4. utworzenie backupu plików w naszej lokalizacji
  5. usunięcie ewentualnych plików SVN
  6. spakowanie wszystkiego do formatu tar.gz
  7. wysłanie informacji o utworzeniu kopii na naszego maila
  8. czyszczenie plików tymczasowych
  9. zakończenie skryptu

Na podstawie tego schematu możemy utworzyć niezbędny kod.

#!/bin/sh
# utworzenie zmiennej wykorzystanej do budowania ścieżki
BACKUP_DIR=backup_"`/bin/data +%d_%m_%Y`"
# utworzenie katalogu tymczasowego z datą
/bin/mkdir /usr/home/uzytkownik/$BACKUP_DIR
# utworzenie katalogu na pliki wewnątrz katalogu tymczasowego
/bin/mkdir /usr/home/uzytkownik/$BACKUP_DIR/www
# utworzenie backupu bazy danych
/usr/local/bin/mysqldump -u user -phaslo nazwa_bazy > /usr/home/uzytkownik/$BACKUP_DIR/dump.sql
# backup plików
/bin/cp -rf /sciezka/katalog_z_plikami/* /usr/home/uzytkownik/$BACKUP_DIR/www/
# usuniecie plików SVN jeżeli takie istnieją
/bin/rm -rf `/usr/bin/find /usr/home/uzytkownik/$BACKUP_DIR/www/ -type d -name .svn`
# spakowanie wszystkiego do pliku tar.gz
/usr/bin/tar -zcvf /usr/home/uzytkownik/$BACKUP_DIR.tar.gz /usr/home/uzytkownik/$BACKUP_DIR/*
# utworzenie tresci maila o stworzeniu backupu
/usr/bin/touch /usr/home/uzytkownik/$BACKUP_DIR/mail.txt && /bin/echo "NASZA TREŚĆ WIADOMOŚCI">/usr/home/uzytkownik/$BACKUP_DIR/mail.txt
# wysyłka wiadomości

/usr/bin/mail -s "tytul wiadomosci" "adresat@domena.pl" # usuniecie katalogu tymczasowego
/bin/rm -rf /usr/home/uzytkownik/$BACKUP_DIR
# zakończenie skryptu
exit

Skrypt tez zapisujemy pod dowolną nazwą a następnie przyznajemy mu prawa wykonywania 0777 i możemy już uruchamiać.
Należy zwrócić uwagę na ścieżki poleceń i plików – muszą one być ścieżkami bezwzględnymi. Mogą one również różnić się od tu podanych, które obowiązują w FreeBSD.

Jeżeli chcemy, możemy również plik ten uruchamiać poprzez crona np komendą:
1 1 * * * root cd /usr/home/uzytkownik && ./nasz_plik.sh

MySQL Multi Delete – usuwanie przy wykorzystaniu wielu tabel

2011/04/04 ; dodane przez lskowronski

Załóżmy że mam złożone zapytanie którego zadaniem jest pobieranie danych z dwóch tabel połączonych ze sobą poprzez LEFT JOIN.

Zapytanie będzie miało postać podobną do:

SELECT * FROM table1 as t1 LEFT JOIN table2 as t2 ON (t1.property1=t2.property1 AND t1.property2=t2.property2) WHERE t1.property3=123 AND t1.property4 IS NOT NULL

Jak teraz sprawnie przekształcić to zapytanie w usuwanie?

Musimy skorzystać z mechanizmu nazywanego w MySQL “Multi Delete” . Modyfikujemy zapytanie do postaci następuącej:

DELETE t1 FROM table1 as t1 LEFT JOIN table2 as t2 ON (t1.property1=t2.property1 AND t1.property2=t2.property2) WHERE t1.property3=123 AND t1.property4 IS NOT NULL

W formule dodajemy po prostu tabelę z której chcemy usuwać. Równie dobrze moglibyśmy usuwać jednocześnie z dwóch tabel modyfikując początek zapytania do postaci:

DELETE t1,t2 FROM …

Więcej na ten temat można doczytać na stronie MySQL : http://dev.mysql.com/doc/refman/5.0/en/delete.html