7

У меня есть абстрактный родительский (отображенный супер) класс, который имеет несколько дочерних элементов с разными свойствами, которые я хотел бы десериализовать. Я храню данные с использованием MongoDB и Doctrine ODM, поэтому у меня также есть поле дискриминатора, которое сообщает доктрине, какой подкласс используется (а также имеет свойство custom type type ontop, которое используется в другом месте для определения того, какой класс обрабатывается в данный момент) ,JMS Serializer Deserialize с абстрактным родительским классом

При десериализации моей модели я получаю исключение, говорящее, что его невозможно создать экземпляр абстрактного класса (конечно) - теперь мне интересно, как я могу описать Deserializer JMS, который унаследовал класс, который он должен использовать (что поэтому я использую настраиваемую переменную экземпляра type, например, потому что у меня нет доступа к отображению поля дискриминатора доктрины).

Я могу успешно подключиться к preDeserializeEvent - так что, возможно, там можно сделать некоторые переключатели/случаи (или используя)?

Моя модель в коротком (абстрактный класс):

<?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.. 
} 

?> 

Один из подклассов

<?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.. 
?> 

Другой тест должен был не сделать класс модуля абстрактные и создать собственный статический метод

/** 
* 
* @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?? 
} 

любые идеи?

+0

вы должны скопировать «обновление» в качестве anwser и отметьте этот вопрос андезированным - таким образом, у других, у кого может быть такая же проблема, будет ясно видно, что на этой странице есть рабочее решение – loostro

+0

. сделанный. – con

ответ

8

Я нашел отображение дискриминатор в каталоге Tests плагина, к сожалению, это еще не документированы: https://github.com/schmittjoh/serializer/blob/master/tests/JMS/Serializer/Tests/Fixtures/Discriminator/Vehicle.php

Документация обновляется http://jmsyst.com/libs/serializer/master/reference/annotations#discriminator

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; 
    } 
}