Piszę właśnie aplikację do automatycznej obsługi rejestracji, zarządzania i płatności dla strony http://document-management.pl/ i napotkałem pewien problem z walidacją danych. Potrzebowałem sprawdzić w unikalność Stringa w dwóch różnych tabelach. Niestety Doctrine domyślnie tego nie obsługuje więc pośpieszyłem z napisaniem własnego walidatora. Dziarsko przeczytałem “How to create a Custom Validation Constraint“, napisałem walidator i … zonk

Fatal error: Class 'Symfony\Component\Validator\Constraints\UniqueDomain' not found in /home/kirkor/Projects/Beriko Software/document-management.pl/public_html_register/Symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php on line 73

Continue reading

Ostatnio programując na co dzień w Javie i używając Springa, Hibernate, Struts i Velocity nie natrafiłem na żaden interesujący problem dlatego nie pojawił się na blogu żaden wpis, który tego dotyczy.

Ale za to jest coś ciekawego w Doctrine :) W wersji 1.2 nie ma rozsądnej formy dziedziczenia, to co proponują autorzy nie podoba mi się. postanowiłem użyć takiego przypadku:

sf_guard_user to klasa standardowego pluginu, która odpowiada użytkownikowi. Dodatkowo stworzyłem tabelę ae_experts z jednym kluczem obcym odwołującym się do użytkownika. Czyli każdy ekspert jest również użytkownikiem. Tak sobie pokrętnie wytłumaczyłem obiektowo relacyjną bazę danych.

Efekt, który chciałem osiągnąć to przy każdym pobraniu eksperta jest również pobierany użytkownik. Skoro ekspert to user, to warto wyświetlać domyślnie imię i nazwisko. Aby to osiągnąć w klasie Expert (Expert.class.php) dodałem taki kod:

/**
 * Expert
 *
 * This class has been auto-generated by the Doctrine ORM Framework
 *
 * @package    ask-expert
 * @subpackage model
 * @author     Beriko Software, Grzegorz Bernaś
 * @version    SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $
 */
class Expert extends BaseExpert
{
	public function preDqlSelect($event)
	{
		$params = $event->getParams();
		$query  = $event->getQuery();
		$alias  = $params['alias'] . '.sfGuardUser';
		if ((!$query->isSubquery() || ($query->isSubquery() && $query->contains(' '.$params['alias'].' '))) && !$query->contains($alias))
		{
			$query->innerJoin($alias);
		}
	}

	public function __toString() {
		return $this->getSfGuardUser()->getFirstName().' '.$this->getSfGuardUser()->getLastName();
	}
}

Ale to nie wszystko, kod nie będzie działać jeżeli nie włączymy DQL’a (Doctrine Query Language). Aby to zrobić w pliku ProjectConfiguration.class.php do klasy ProjectConfiguration dodaj taki kod:

class ProjectConfiguration extends sfProjectConfiguration
{
	public function configureDoctrine(Doctrine_Manager $manager)
	{
		$manager->setAttribute(Doctrine_Core::ATTR_USE_DQL_CALLBACKS, true);
	}
}

Dzięki temu nie mam dwóch zapytań tylko jedno :) Nie wiem jaki to będzie miało wpływ na wydajność i pracę w przyszłości kiedy mój projekt edukacyjny urośnie, ale czas pokaże.

W ramach odświeżenia swojej wiedzy, wróciłem do zabawy z frameworkiem Symfony. Realizując mały i prosty “projekt edukacyjny” natrafiłem na pewien problem. Mianowicie kodowanie tabel w MySQL oraz kodowanie połączenie z bazą danych. Osobiście preferuję używania wszędzie UTF-8 dlatego domyślne kodowanie latin1 nie do końca mnie zadowalało. Dzięki dziadkowi google znalazłem na sieci bardzo przydatne rozwiązanie.

Jeżeli chcesz używać kodowania UTF-8,  powinieneś dodać do swojej definicji schematu (schema.yml) następujacy kod:

User:
  options:
    type: MyISAM
    collate: utf8_unicode_ci
    charset: utf8
  columns:
    username: string(255)
    password: string(255)

Jak widać elegancko ustawiamy collate: utf8_unicode_ci oraz charset: utf8. Powyższe opcje sprawiają, że tylko jedna konkretna tabela będzie kodowana w UTF-8, jeżeli chcemy aby wszystkie table miały takie kodowanie oraz aby kodowanie połączenia było ustawione na UTF-8 musimy do pliku ProjectConfiguration.class.php dodać następującą metodę:

public function configureDoctrine(Doctrine_Manager $manager)
{
  $manager->setCollate('utf8_unicode_ci');
  $manager->setCharset('utf8');
}

Następnie trzeba przebudować cały mode (aby w bazie danych zmieniło się kodowanie tabel) oraz na nowo wgrać dane inicjalne już z odpowiednimi znaczkami.

symfony doctrine:build --all --and-load --env=dev --no-confirmation

Miejmy na uwadze, że tak komenda usunie wszystkie dotychczasowe tabele i stworzy je na nowo z kodowaniem UTF-8.