ugrás a tartalomhoz

Doctrine: "virtuális" tulajdonság létrehozása

fchris82 · 2009. Jún. 1. (H), 17.41
Eddig a Propelt használtam, és most szeretnék áttérni Doctrine-ra. A problémám az, hogy jelen esetben van egy payoff tábla. Tömören az alábbi tulajdonságokkal bír:
payoff:
  id: serial primary key
  created: datetime
  ...
Propel alatt létre tudtam hozni egy valójában nem létező tulajdonságot, melynek neve: number . Ez olyasmi, mint a számlaszám, a létrehozás éve + '-' + id, nullákkal feltöltve. Pl:
id = 23
created = '2009-03-20'
--------------------------
number = 2009-000023
Ennek megvalósítása egyszerű volt, a Payoff osztályban létrehoztam egy getNumber() fv. Ez Doctrine alatt sem lenne probléma, ami viszont az, hogy így nem tudom "egységesen" kezelni a objektum tulajdonságait. Propel alatt:
echo $obj->getId();
echo $obj->getCreated('Y-m-d');
echo $obj->getNumber();
Doctrine alatt? :
echo $obj->id;
echo $obj->created;
echo $obj->getNumber();
Van vmi tapasztaltabb embernek erre a "problémára" vmi szebb megoldása? Nincs vmi kiegészítés Doctrine alá, hogy a generált fájlokba belekerüljenek a get[oszlopnév]() fv-ek? Nekem az a megoldás sokkal szimpatikusabb volt. A set fv-eket felülbírálva lehetett módosítani az adaton mielőtt az adatbázisba kerül és get fv-eknél pedig kiolvasásánál lehetett vele játszani, esetleg létre lehetett hozni ilyen "vírtuális" tulajdonságokat is, amik az adatbázisban valójában nem léteztek, de a modell rendelkezett vele.
 
1

Átmeneti megoldásként

fchris82 · 2009. Jún. 1. (H), 21.35
Átmeneti megoldásként a Doctrine_Record osztály __call() fv-ét kiegészítettem az alábbival:
      /**
       * SAJÁT KIEGÉSZÍTÉS
       * Lehetővé teszi, hogy a tulajdonságokhoz hozzáférjünk get[Tulajdonság]() formában is!
       */
      if(substr($method, 0, 3)=='get') {
        $key = Doctrine_Inflector::tableize(substr($method, 3));

        // Ha létezik ilyen oszlop
        if(array_key_exists($key, $this->_data)) {
          // Ha érkezik paraméter ÉS a mező timestamp,
          // akkor valószínűleg formázni szeretnénk a kimenetet.
          // Pl: $obj->getCreated('Y.m.d');
          if(count($args)>0 AND $this->getTable()->getTypeOfColumn($key)=='timestamp') {
            $v  = $this->get($key);
            $ts = strtotime($v);
            return ($ts>0) ? date($args[0], $ts) : $v;
          }

          return $this->get($key);
        }
      }

      if(substr($method, 0, 3)=='set') {
        $key = Doctrine_Inflector::tableize(substr($method, 3));

        if(array_key_exists($key, $this->_data)) {
          switch(count($args)) {
            case 0 : $value = null; break;
            case 1 : $value = $args[0]; break;
            default: $value = $args;
          }

          return $this->set($key, $value);
        }
      }

      /* Az eredeti kód jön ezután ... */
Lehetne még azt csinálni, hogy létrehozok egy saját Self_Doctrine_Record osztályt, származtatva a Doctrine_Record-ból, és generálásnál az options-ben megadom, hogy ezt az osztályt használja ( $options = array('baseClassName' => 'Self_Doctrine_Record'); ) és abban az osztályban definiálom felül a fv-t, akkor nem kell az eredeti fájlokban turkálni.

Ez a megoldás "lassú". A Base osztályokba belegenerálva viszont gyorsabb is lenne a $obj->getVar(), mint a $obj->var, mivel az utóbbi a szintén mágikus __get() fv-t használja... Az a gond, hogy a Doctrine_Record sok "getes" fv-t tartalmaz alapból, pl a getLastModified() bezavarhat egyes tábláknál így nehéz "általánosítani" ezt a módszert, anélkül, hogy ne kellene alaposan átírni az alap kódot :-/
2

Szerintem...

Protezis · 2009. Jún. 1. (H), 22.54
A modellben:
public function __get( $key ) {
 if ( $key == 'number' ) {
  return $this -> getNumber();
 }
 return parent::__get( $key );
}
6

Erre én is gondoltam...

fchris82 · 2009. Jún. 3. (Sze), 12.43
Erre én is gondoltam, de vmiért nekem szimpatikusabb a fv hívás, "több lehetőséget" látok benne. Pl dátum esetén rögtön tudom azt formázni! Bár efpe válasza lesz valószínűleg a jó, a HydrationListener, hiszen a dátum formázása az oldalon nyelvfüggő és mindenhol ugyanaz, ha a formázást berakom egy konstansba és a dátumos táblákat kiegészítem ezzel, akkor megoldódik ez a probléma is.
3

Hydration listener? Lehet en

efpe · 2009. Jún. 2. (K), 10.40
Hydration listener?
Lehet en ertettem felre a dolgot, de nem valami ilyesmit szeretnel?
4

symfony?

Sulik Szabolcs · 2009. Jún. 2. (K), 12.50
bevezetod alapjan symfony alatt probalkozol. a doctrine valoban nem tudja ezt, viszont sf alatt a model osztalyaid az sfDoctrineRecord leszarmazottai, amely viszont mar tudja.
5

Részben "nyert"

fchris82 · 2009. Jún. 3. (Sze), 12.22
Nem, nem Symfony alatt csinálom, de onnan vettem az "ötletet". Saját keretrendszer. És igazából nem is a Propelt cserélem le, hanem a saját ORM rendszeremet, de csináltam Symfony-s oldalt, és ott alkalmaztam a fentit, de itt is kellett vmi hasonló, és... Szóval ez bonyolult, és a valóság részletezése nem változtat a problémán ;) De köszi az infót, ez még jól jöhet, mert Symfony-t még fogom használni Doctrine-nal.