7

Ich habe eine abstrakte Eltern (mapped super-) -Klasse, die mehrere Kinder mit verschiedenen Eigenschaften hat, die ich deserialize möchte. Ich speichere die Daten mit MongoDB und Doctrine ODM, also habe ich auch ein Diskriminatorfeld, das der Doktrin sagt, welche Unterklasse verwendet wird (und auch eine benutzerdefinierte "type" -Eigenschaft ontop hat, die an anderer Stelle verwendet wird, um festzustellen, welche Klasse gerade verarbeitet wird) .JMS Serializer Deserialize mit abstrakten Elternklasse

Wenn ich mein Modell deserialisiere, bekomme ich eine Ausnahme, dass es unmöglich ist, eine Instanz einer abstrakten Klasse zu erstellen (natürlich) - jetzt frage ich mich, wie ich dem JMS Deserializer mitteilen kann, welche Klasse er verwenden soll Deshalb verwende ich zum Beispiel eine benutzerdefinierte type Instanzvariable - weil ich keinen Zugang zum Diskriminator-Feld-Mapping habe.

Ich kann erfolgreich in die preDeserializeEvent Haken - so ist es vielleicht möglich, einige Schalter/Fälle (oder über die) zu machen?

Mein Modell in kurzen (abstrakte Klasse):

<?php 

namespace VBCMS\Bundle\AdminBundle\Document; 

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; 
use JMS\Serializer\Annotation as Serializer; 

/** 
* abstract Class Module 
* @Serializer\AccessType("public_method") 
* @MongoDB\MappedSuperclass 
* @MongoDB\InheritanceType("SINGLE_COLLECTION") 
* @MongoDB\DiscriminatorField(fieldName="_discriminator_field") 
* @MongoDB\DiscriminatorMap({ 
* "module"="Module", 
* "text_module"="TextModule", 
* "menu_module"="MenuModule", 
* "image_module"="ImageModule" 
* }) 
*/ 
abstract class Module { 

    const TYPE_MODULE_TEXT  = 'module.text'; 
    const TYPE_MODULE_MENU  = 'module.menu'; 
    const TYPE_MODULE_MEDIA_ITEM = 'module.media.item'; 

    /** 
    * @Serializer\Type("string") 
    * @MongoDB\Field(type="string") 
    * @var String 
    */ 
    protected $type; 

    /** 
    * @Serializer\Type("boolean") 
    * @MongoDB\Field(type="boolean") 
    * @var boolean 
    */ 
    protected $visible; 

    // getter/setter methods etc.. 
} 

?> 

Einer der Subklassen

<?php 
namespace VBCMS\Bundle\AdminBundle\Document; 

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; 
use JMS\Serializer\Annotation as Serializer; 

/** 
* Class TextModule 
* @package VBCMS\Bundle\AdminBundle\Document 
* @Serializer\AccessType("public_method") 
* @MongoDB\EmbeddedDocument 
*/ 
class TextModule extends Module { 

    const TEXT_TYPE_SPLASH_HEADLINE = 'splashscreen.headline'; 
    const TEXT_TYPE_SPLASH_SUBLINE = 'splashscreen.subline'; 

    /** 
    * the actual text 
    * 
    * @var string 
    * @Serializer\Type("string") 
    * @MongoDB\Field(type="string") 
    */ 
    protected $text; 

    /** 
    * how it is called in the admin interface 
    * 
    * @var string 
    * @Serializer\Type("string") 
    * @MongoDB\Field(type="string") 
    */ 
    protected $label; 

    /** 
    * @var string 
    * @Serializer\Type("string") 
    * @MongoDB\Field(type="string") 
    */ 
    protected $textType; 

    // getter/setter methods etc.. 
?> 

Ein weiterer Test auf war nicht die Module Klasse abstrakt machen und eine eigene statische Methode zu erstellen

/** 
* 
* @Serializer\HandlerCallback("json", direction="deserialization") 
* @param JsonDeserializationVisitor $visitor 
*/ 
public static function deserializeToObject(JsonDeserializationVisitor $visitor) 
{ 
    // modify visitor somehow to return an instance of the desired inherited module class?? 
} 

irgendwelche ideen?

+0

sollten Sie Ihre „update“ als anwser kopieren und markieren Sie diese Frage anwsered - auf diese Weise andere, die das gleiche Problem haben könnte, wird deutlich, dass es eine funktionierende Lösung auf dieser Seite – loostro

+0

guter Punkt. erledigt. – con

Antwort

8

fand ich einen Diskriminator-Mapping im Test-Verzeichnis des Plugins leider ist dies noch nicht dokumentiert: https://github.com/schmittjoh/serializer/blob/master/tests/JMS/Serializer/Tests/Fixtures/Discriminator/Vehicle.php

Dokumentation wird http://jmsyst.com/libs/serializer/master/reference/annotations#discriminator aktualisiert

namespace JMS\Serializer\Tests\Fixtures\Discriminator; 

use JMS\Serializer\Annotation as Serializer; 

/** 
* @Serializer\Discriminator(field = "type", map = { 
* "car": "JMS\Serializer\Tests\Fixtures\Discriminator\Car", 
* "moped": "JMS\Serializer\Tests\Fixtures\Discriminator\Moped", 
* }) 
*/ 
abstract class Vehicle 
{ 
    /** @Serializer\Type("integer") */ 
    public $km; 

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