сериализуйте массив объектов с помощью аннотаций Doctrine и JMSSerializer


У меня есть модель

    /**
     * @ORM\Table(name="polygon")
     * @ORM\Entity(repositoryClass="MyBundle\Repository\PolygonRepository")
     * @JMS\ExclusionPolicy("none")
     */
    class Polygon {
         /**
          * @var string
          *
          * @ORM\Column(name="polygon", type="json_array")
          * @JMS\Type("array<MyBundle\Model\Point>")
          */
          private $points;

          /***/
    }

В БД он хранится как текст '[{"x":1, "y":1} ...]'

В контроллере у меня есть

/**
 * Matches /polygon exactly
 *
 * @Route("/", name="polygon_list")
 * @Method("GET")
 *
 * @Rest\Get("/")
 *
 */
public function listAction()
{
    return $this->container->get('doctrine.orm.entity_manager')
        ->getRepository('MyBundle:Polygon')
        ->findAll();
}

Итак, я получаю ReflectionProperty::GetValue() ожидает, что параметр 1 будет объектом, заданным массивом

В...поставщик/jms/метаданные/src/Метаданные/PropertyMetadata.php:51

Если бы это было только для получения результата, это можно было бы решить с помощью виртуального свойства

/**
 * @JMS\Exclude
 */
private $points;

/**
 * @JMS\VirtualProperty
 * @JMS\Type("array<MyBundle\Model\Point>")
 * @JMS\SerializedName("points")
 * @JMS\Groups({"common"})
 *
 * @return array
 */
public function getMyPoints() {
    return [new Point(), new Point()]
}

Но мне нужно получить эти баллы в виде JSON с ПОСТА, поэтому единственный способ, который я нашел, так насколько тип обычая доктрины похож на https://github.com/sonata-project/sonata-doctrine-extensions

С той лишь разницей, что в методе convertToPHPValue я добавляю дополнительный тип для получения объектов вместо массива assoc:

// pass my [{"x":1, "y":1} ...]
public function convertToPHPValue($value, AbstractPlatform $platform)
    {
       return array_map(function($a){ return (object)$a;}, json_decode($value));
    }

Есть ли более чистое решение без добавления сериализации пользовательских доктрин?

Если бы только это ... поставщик/jms/метаданные/src/Метаданные/PropertyMetadata.php:51 имел

return $this->reflection->getValue((object)$obj);

Но это

return $this->reflection->getValue($obj); // :(
Author: 2oppin, 2016-11-02

1 answers

Моя проблема заключалась в использовании @JMS\Type вообще

    class Polygon {
         /**
          * @ORM\Column(name="polygon", type="json_array")
          */
          private $points;

          public function getPoints() { return $this->points;}
          public function setPoints($points) {
               $this->points = $points;
               return $this;
          }
          /***/
    }

Работает просто отлично, спасибо @Matteo за то, что указал, что я все усложняю:)

 0
Author: 2oppin, 2016-11-04 08:23:12