2011-08-01 6 views
5

Supposons que je vais avoir la Doctrine suivante 2 entité:Constantes dans Doctrine 2 entités

/** 
* @ORM\Entity 
* @ORM\Table(name="users") 
*/ 
class User { 

    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue 
    * 
    * @var int 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(length=100) 
    * 
    * @var string 
    */ 
    protected $name; 

    /** 
    * @ORM\Column(type="integer") 
    * 
    * @var int 
    */ 
    protected $status; 
} 

L'utilisateur peut avoir plusieurs états, par exemple: En attente, actif, suspendu. Ces statuts sont nécessaires dans tout le code (services, référentiels, etc.) et également dans la couche d'interface utilisateur (un formulaire d'édition utilisateur les affiche dans une liste déroulante).

Afin d'éviter les définir en plusieurs endroits, ce que je l'ai fait jusqu'à présent était d'utiliser une classe pour les tenir tous (toutes les constantes de l'application), et il ressemble un peu à ceci:

class App_Constants extends Zrzr_Constants 
{ 

    protected static $_constants = array( 
     'users' => array( 
      'status' => array( 
       0 => 'Pending', 
       1 => 'Active', 
       2 => 'Suspended'))); 

} 

La classe de base (Zrzr_Constants) offrirait des méthodes pour les récupérer, et il ressemble à ceci:

class Zrzr_Constants 
{ 
    protected static $_constants = array(); 

    public static function getConstantValues($key, $subkey) 
    { 
     // ... 
    } 

    public static function getConstantByName($name) 
    { 
     // ... 
    } 
} 

utilisation commune serait:

// example of retrieval by constant name ... it would return an integer 
$pendingStatus = App_Constants::getConstantByName('USERS.STATUS.PENDING'); 

// example of retrieval for UI display purposes ... would return an array 
$statuses = App_Constants::getConstantValues('users', 'status'); 

Bien sûr, cela signifie qu'il y a certaines limitations dans le fait que les étiquettes constantes ne peuvent pas contenir de points, mais je peux vivre avec. Cependant, en utilisant Doctrine 2 et en suivant la méthode DDD, on me dit que le champ 'status' devrait être en fait un 'objet valeur' ​​(mais Doctrine 2 ne supporte pas encore les objets de valeur), ou du moins que je devrais avoir les constantes définies dans l'entité (en utilisant const).

Ma question est comment est-ce que je ferais ceci afin que j'évite la redéfinition constante pour la couche d'interface utilisateur? J'ai besoin d'avoir accès à la constante par son nom (dans le code) et d'avoir toutes les valeurs possibles pour un tel champ dans le cas d'une liste déroulante de l'interface utilisateur (par exemple).

+0

Votre vue est le seul endroit qui a besoin des noms.La couche UI devrait faire toute la conversion entre les noms et les valeurs; partout ailleurs devrait simplement utiliser la valeur entière. Il peut être utile d'ajouter des méthodes à votre entité comme 'isPending()' – rojoca

+0

@rojoca - Lorsque vous dites 'utiliser la valeur entière', cela ne signifie certainement pas: 'if ($ user-> getStatus() = = 2) ... '. L'interface utilisateur n'est peut-être pas la seule autre couche utilisant ces constantes. Qu'en est-il de ces constantes utilisées dans les requêtes qui ne passent pas par le modèle de domaine (lorsqu'on utilise une sorte de CQS)? – Ghola

+0

Non; Dans votre exemple, je pense que 'if ($ user-> isPending())' est meilleur car il dit exactement ce que cela signifie. Vous pouvez créer des constantes comme 'User :: STATUS_PENDING' dans votre modèle de domaine, puis les utiliser dans' App_Constants', par exemple 'User :: STATUS_PENDING => 'Pending''. App_Constants dépend de votre domaine, que vous codiez en dur les valeurs (comme vous le faites actuellement) ou que vous utilisiez des constantes de classe; vous pourriez aussi bien utiliser des constantes. – rojoca

Répondre

2

Je pense, vous pouvez le faire de cette façon:

class User { 
    const STATUS_PENDING = 'Pending'; 
    const STATUS_ACTIVE = 'Active'; 
    const STATUS_SUSPENDED = 'Suspended'; 

    public static function getStatusList() { 
    return array(
       self::STATUS_PENDING, 
       self::STATUS_ACTIVE, 
       self::STATUS_SUSPENDED 
       ); 
    } 

    public function getStatus() {...} 

    public function setStatus($value) {...} 

    public function isStatusPending() {...} //If you need it 
} 

Sur la couche d'interface utilisateur, vous pouvez obtenir des versions de texte de vos statuts en utilisant le service de localisation (si les constantes d'état sont des nombres, couche d'interface utilisateur peut les convertir en chaînes en ajoutant un préfixe, par exemple user_status_0). Dans les vues Symfony2, vous pouvez utiliser le filtre de brindilles trans pour obtenir la version texte du statut de l'utilisateur à partir du domaine de localisation user.

Si votre site Web est juste dans une langue, alors User :: STATUS_XXX ira bien, je pense. Je ne pense pas que vous devriez trop compliquer la question en créant une nouvelle classe pour maintenir les statuts de l'utilisateur.

Si vous allez avoir beaucoup de statuts ou d'autres choses liées, je pense que vous devrez créer une entité séparée pour eux.

+0

J'ai finalement fini par aller de cette façon dans les constantes de domaine, car cela semble plus naturel dans une approche DDD. Je continue d'utiliser la classe des constantes pour les autres constantes du système qui ne sont pas liées au domaine. – Ghola

2

vous pouvez définir votre classe comme dans l'exemple suivant

class ContactResource 
{ 
    const TYPE_PHONE = 1; 
    const TYPE_EMAIL = 2; 
    const TYPE_BIRTDAY = 3; 
    const TYPE_ADDRESS = 4; 
    const TYPE_OTHER = 5; 
    const TYPE_SKYPE = 6; 
    const TYPE_LINKEDIN = 7; 
    const TYPE_MEETUP = 8; 
    const TYPE_TELEGRAM = 9; 
    const TYPE_INSTAGRAM = 10; 
    const TYPE_TWITTER = 11; 

    public static $resourceType = array(
     ContactResource::TYPE_PHONE => "Phone", 
     ContactResource::TYPE_EMAIL => "Email", 
     ContactResource::TYPE_BIRTDAY => "Birtday", 
     ContactResource::TYPE_ADDRESS => "Address", 
     ContactResource::TYPE_OTHER => "Other", 
     ContactResource::TYPE_SKYPE => "Skype", 
     ContactResource::TYPE_LINKEDIN => "LinkedIn", 
     ContactResource::TYPE_MEETUP => "Meetup", 
     ContactResource::TYPE_TELEGRAM => "Telegram", 
     ContactResource::TYPE_INSTAGRAM => "Instagram", 
     ContactResource::TYPE_TWITTER => "Twitter", 
    ); 

    /** 
    * @var integer 
    * 
    * @ORM\Column(type="integer", length=2) 
    * 
    */ 
    private $type; 


    public function __toString() 
    { 
     return (string)$this->getType(); 
    } 

    public function getType() 
    { 
     if (!is_null($this->type)) { 
      return self::$resourceType[$this->type]; 
     } else { 
      return null; 
     } 
    } 

    public static function getTypeList() { 
     return self::$resourceType; 
    } 

} 

Si vous avez besoin pour obtenir le type de Brindille

{{ entity.type }} 

Pour la liste des choix

ContactResource::getTypeList() 

Espoir travaille pour vous!

+0

En quoi est-ce différent de ce que Vladislav répond? – Ghola

+0

La réponse de Vladislav est correcte, mais il est important de définir la méthode toString ainsi que les getters et setters pour l'utiliser. Je veux seulement compléter la réponse :) – xandrucancelas

+0

Je ne suis pas quand est défini le type $? Alors, comment obtenez-vous le resourceType associé à votre valeur constante? Merci. – MortisQc

Questions connexes