2017-04-18 1 views
2

Ich habe eine Dashboard Entity richtig serialisiert/deserialisiert von JMSSerializer (durch JMSSerializerBundle):wie Serialisierung einer Lehre Entity des Attributs ändern programmatisch

/** 
* @ORM\Table(name="dashboard", schema="myappID") 
* @ORM\Entity(repositoryClass="Belka\MyBundle\Entity\Repository\DashboardRepository") 
*/ 
class Dashboard 
{ 
    /** 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue("SEQUENCE") 
    * 
    * @Serializer\Groups({"o-all", "o-all-getCDashboard", "i-p2-editDashboard"}) 
    */ 
    protected $id; 

    /** 
    * @ORM\ManyToMany(targetEntity="Belka\MyBundle\Entity\User") 
    * 
    * @ORM\JoinTable(name="users_dashboards_associated", 
    *  schema="myAppID", 
    *  joinColumns={@ORM\JoinColumn(name="dashboard_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")} 
    *  ) 
    * 
    * @Serializer\groups({ 
    *  "o-p2-create", 
    *  "i-p2-create", 
    *  "o-p2-patch", 
    *  "i-p2-editDashboard" 
    * }) 
    */ 
    protected $users; 
} 

und ich bin mit JMSSerializer des jms_serializer.doctrine_object_constructor als Objektkonstruktor. Alles funktioniert wie Charme, aber ich habe den folgenden Eckfall: manchmal muss ich Dashboard::$users als String setzen (dh wenn der Client eine semantisch-inkorrekte users Eigenschaft sendet, gebe ich nach meinen Checks das Objekt zusammen mit einem String zurück Informieren Sie es. Dies ist ziemlich praktisch für die Front-End-Anwendungen). JMSSerializer takes advantage of the Doctrine's annotation, aber in diesem Fall möchte ich es wirklich programmgesteuert überschreiben, da es ein sehr Eckfall ist. Zwei sind die Wege, auf meinem Verstand:

  1. Gibt es eine Möglichkeit, um das zu setzen SerializationContextDashboard::$users als String-Eigenschaft auf der Karte?
  2. Gibt es einen Weg, um die Metadaten des Doctrine zu ändern, bevor Sie es serialisieren?
  3. Andere Optionen, die ich nicht realisiert habe?

Jedes Stück Vorschlag ist mehr als willkommen

+1

Vielleicht über [events] (http://jmyst.com/libs/serializer/master/event_system)? – Veve

+1

@Veve Ich denke du hattest recht. Schau dir meinen eigenen Anser an :) – Bertuz

Antwort

2

ich eine Lösung gefunden haben, obwohl es keine verschachtelten Einheiten die Eigenschaften nicht berücksichtigt (has-a Beziehungen). Das würde bedeuten, die ganze Grafik zu besuchen, aber ich habe keine Zeit gefunden, den Mut zum exzellenten JMSSSerializer zu studieren. Es funktioniert perfekt zum Erzwingen der Eigenschaften der Entität der ersten Ebene:

erstens, ein pre-serialize Teilnehmer wird benötigt. Es wird über geschützte Eigenschaften zyklisch geschaltet und überprüft, ob sie eine Zeichenfolge enthalten. Ist dies der Fall, wird der Typ für die Serialisierung außer Kraft gesetzt.

Als nächstes wollte ich nicht jedes Mal hören, wenn ich etwas serialisieren. Dies ist ein Eckfall in einem meiner Dienste. Wir können die JMS\Serializer\EventDispatcher\EventDispatcher::addSubscriber nutzen, obwohl der EventDispatcher Service als private deklariert ist. Also wenden wir uns diesen Dienst in public durch einen Compiler Pass, um die Vorteile von addSubscriber zu nehmen:

class MyBundle extends Bundle 
{ 
    public function build(ContainerBuilder $container) 
    { 
     parent::build($container); 

     $container->addCompilerPass(new OverrideJmsSerializerEventDispatcherDefPass()); 
    } 
} 

... und wenden wir uns diesen Dienst in einem public ein

class OverrideJmsSerializerEventDispatcherDefPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     $definition = $container->getDefinition('jms_serializer.event_dispatcher'); 
     $definition->setPublic(true); 
    } 
} 

Daher Wir können es in unsere Dienste einbringen. I.e. in meinem services.yml:

belka.mybundle.dashboardhandler: 
     class: Belka\MyBundle\Handlers\DashboardHandler 
     calls: 
      - [setEventDispatcher, ["@jms_serializer.event_dispatcher"]] 

In Ordnung, jetzt können wir leicht unsere Teilnehmer hinzufügen, wenn wir brauchen, ohne die Last der anderen Zuhörer jedes Mal, wenn meine Anwendung eine Serialisierung ausführt:

$serializationSubscriber = new SerializationSubscriber(); 
$this->eventDispatcher->addSubscriber($serializationSubscriber); 

Sek Vervollständige die Antwort mit einer Lösung, die den Graphen aller Entitäten aufruft. Das wäre großartig.

Verwandte Themen