2012-03-29 10 views
4

Tut mir leid, wenn diese Frage bereits beantwortet wurde, konnte ich keine finden.Wie man einen Modellmanager in Symfony2 hat?

Ich baue dieses Modell in Symfony2:

class LogEntry { 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var \DateTime $log_timestamp 
    * 
    * @ORM\Column(name="log_timestamp", type="datetime") 
    */ 
    private $log_timestamp; 

    /** 
    * @var TranslationMapping $source 
    * 
    * @ORM\ManyToOne(targetEntity="TranslationMapping", cascade={"persist"}) 
    * @ORM\JoinColumn(name="source", referencedColumnName="id") 
    */ 
    private $source; 

    /** 
    * @var TranslationMapping $target 
    * 
    * @ORM\ManyToOne(targetEntity="TranslationMapping", cascade={"persist"}) 
    * @ORM\JoinColumn(name="target", referencedColumnName="id") 
    */ 
    private $target; 
... 
} 

Mit TranslationMapping wie folgt aus:

/** 
* LogAnalyzer\Bundle\CombatLogBundle\Entity\TranslationMapping 
* 
* @ORM\Table(name="TranslationMapping", uniqueConstraints={@ORM\UniqueConstraint(name="idValue_idx", columns={"stringId", "stringValue"})}) 
* @ORM\Entity 
* @ORM\HasLifecycleCallbacks() 
*/ 
class TranslationMapping 
{ 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string $stringId 
    * 
    * @ORM\Column(name="stringId", type="string", length=255) 
    */ 
    private $stringId; 

    /** 
    * @var string $stringValue 
    * 
    * @ORM\Column(name="stringValue", type="string", length=255) 
    */ 
    private $stringValue; 


    /** 
    * @ORM\PrePersist 
    */ 
    public function beforePersist() 
    { 
     if ($this->stringId == null) { 
      $this->stringId = "laGen_".time(); 
     } 
    } 

LogEntry basiert auf einer Schnur durch regex analysiert gebaut. TranslationMapping steht für eine Schlüssel/Wert-gespeicherte Übersetzungszeichenfolge.

Zeit, was ich tue ist:

  1. die Zeichenfolge Abrufen der LogEntry
  2. Aufbau der LogEntry aus dem String in der LogEntryRepository

    $logEntry = new LogEntry(); 
    $source = new TranslationMapping(); 
    if ($logEntry->getSourceIsPlayer()) { 
        $source->setValueKey(str_replace("@", "", $matches["source"][0])); 
    } else { 
        $source->setValueKey($matches["source"][0], $matches["source_id"][0]); 
        if (isset($matches["source_companion_name"][0])) { // It's a companion ! 
         $companion = new TranslationMapping(); 
         $companion->setValueKey($matches["source_companion_name"][0], $matches["source_companion_id"][0]); 
         $logEntry->setSourceCompanion($companion); 
         $source->setValueKey(str_replace("@", "", $matches["source"][0])); // And the source is the player's character name 
        } 
    } 
    $logEntry->setSource($source); 
    $logEntry->setTargetIsPlayer(strpos($matches["target"][0], "@") !== false); 
    $target = new TranslationMapping(); 
    if ($logEntry->getTargetIsPlayer()) { 
        $target->setValueKey(str_replace("@", "", $matches["target"][0])); 
    } else { 
        $target->setValueKey($matches["target"][0], $matches["target_id"][0]); 
        if (isset($matches["target_companion_name"][0])) { // It's a companion ! 
         $companion = new TranslationMapping(); 
         $companion->setValueKey($matches["target_companion_name"][0], $matches["target_companion_id"][0]); 
         $logEntry->setTargetCompanion($companion); 
         $target->setValueKey(str_replace("@", "", $matches["target"][0])); // And the target is the player's character name 
        } 
    } 
    $logEntry->setTarget($target); 
    
  3. Anzeige der LogEntry

    bauen

Mein Problem ist, dass ich eine Übersetzungs-Mapping-Entität erstellen möchte, wenn das Schlüssel/Wert-Paar noch nicht existiert. Allerdings sehe ich nicht, wie kann ich tun, dass seit:

  • ich nicht TranslationMappingRepository aus einem anderen Repository
  • Ich kann nicht einen Dienst von einem Repository zugreifen zugreifen kann
  • ich nicht verwenden kann, INSERT ... ON DUPLICATE KEY UPDATE Abfragen über Doctrine2

Im Grunde, was ich versuche zu tun, einen Manager für meine TranslationMapping Einheiten zu erhalten, die DB-Operationen verwalten würde (fetch & Einsatz, wenn nötig) und setzen die Entitäten durch alle Symfony-Anwendung und meistens zu den Repositories.

Ich habe mehrere Lösungen ausprobiert und keine Optionen mehr, weiß jemand, wie ich das erreichen kann?

Danke.

Antwort

5

Grundsätzlich möchten Sie einen S2-Dienst erstellen und Ihren Entity Manager hinein injizieren. Viele Beispiele in der Anleitung, obwohl ich eine schreiben könnte, wenn Sie es wirklich brauchten.

Repositories sind großartig, wenn es um einen Entitätstyp geht, aber, wie Sie herausgefunden haben, nicht so sehr im Umgang mit mehreren Typen. Ich benutze sie selten mehr. Schließen Sie einfach die Funktionalität in einem Service ab.

Das INSERT ... ON DUPLICATE KEY UPDATE ist leider kein Standard-SQL und wird daher von Doctrine nicht unterstützt, obwohl Sie es möglicherweise als benutzerdefinierte Funktion hinzufügen können. Aber am besten prüfen Sie einfach, ob der Schlüssel vorhanden ist, und passen Sie ihn entsprechend an. Achten Sie darauf, nur für den Fall Ausnahmen zu erfassen.

Ich habe Ihren Code nicht wirklich detailliert durchgearbeitet, aber S2 enthält eine Menge Übersetzungsmaterial. Es ist möglich, dass einige davon auch helfen können.

UPDATE:

Info über Dienstleistungen zu schaffen finden Sie hier: http://symfony.com/doc/current/book/service_container.html

In Ihrem services.xml Datei, die Sie so etwas wie haben könnte:

<service 
    id="zayso.core.project.manager"   
    class="Zayso\ZaysoBundle\Component\Manager\ProjectManager" public="true"> 
     <argument type="service" id="doctrine.orm.entity_manager" /> 
</service> 

Sie Manager einen __construct hätte wie:

class ProjectManager 
{ 
    protected $em = null; 

    public function getEntityManager() { return $this->em; } 

    public function __construct($em) { $this->em = $em; } 

Und dann in Ihrem Controller würden Sie etwas wie tun:

$manager = $this->get(zayso.core.project.manager); 
$manager->newLogEntry($params); 
+0

Danke für die Antwort. Ich habe kein Beispiel auf der Symfony-Website gefunden. Ich würde mich freuen, wenn Sie einen Link zur Verfügung stellen könnten. Über die Übersetzung, die Symfony anbietet, ist es eigentlich nicht, wofür es gedacht ist. Ich habe versucht, diesen Weg zu gehen, sah aber schließlich, dass ich meine eigene Implementierung brauchte. –

+0

Danke für das Update, ich hatte deinen Standpunkt nicht verstanden. Ich habe versucht, das TranslationMapping in einen Dienst zu deportieren, aber die Erstellung des LogEntry ist viel schlauer. Vielen Dank ! –