strip_tags serialize remove ejemplo array php symfony jmsserializerbundle

php - serialize - Relación de la entidad de serialización solo con el identificador con el serializador JMS



strip_tags wordpress (5)

El autor quiere conservar el nombre de la propiedad, que no se aplica a la respuesta aceptada. Por lo que yo entiendo, la respuesta de ScayTrase mantendría el nombre original de la propiedad, pero tiene otra desventaja de acuerdo con los comentarios: el objeto relacionado se buscará si está utilizando Doctrine ORM @ManyToOne , disminuyendo así el rendimiento.

Si desea conservar el nombre de la propiedad original, debe definir @VirtualProperty en el nivel de clase y @Exclude la propiedad original. De lo contrario, el nombre de la propiedad serializada se derivará del método getter ( countryId en este caso):

/** * @Serializer/VirtualProperty( * "country", * exp="object.getCountryId()", * options={@Serializer/SerializedName("country")} * ) */ class Ad { /** * @Serializer/Exclude */ private $country; public function getCountryId() { return $this->country === null ? null : $this->country->getId(); } }

Estoy tratando de serializar una relación de entidad con el Serializador JMS.

Aquí está la Entidad:

class Ad { /** * @Type("string") * @Groups({"manage"}) * * @var string */ private $description; /** * @Type("Acme/SearchBundle/Entity/Country") * @Groups({"manage"}) * * @var /Acme/SearchBundle/Entity/Country */ private $country; /** * @Type("string") * @Groups({"manage"}) * * @var string */ private $title; /** * Set description * * @param string $description * @return Ad */ public function setDescription($description) { $this->description = $description; return $this; } /** * Get description * * @return string */ public function getDescription() { return $this->description; } /** * Set country * * @param /Acme/SearchBundle/Entity/Country $country * @return Ad */ public function setCountry($country) { $this->country= $country; return $this; } /** * Get country * * @return string */ public function getCountry() { return $this->country; } /** * Set title * * @param string $title * @return Ad */ public function setTituloanuncio($title) { $this->title = $title; return $this; } /** * Get title * * @return string */ public function getTitle() { return $this->title; } }

Y la Entidad de la relación:

class Country { /** * @Type("string") * @Groups("manage") * * @var string */ private $id; /** * @Type("string") * @Groups("admin") * * @var string */ private $description; /** * Set description * @Groups("") * * @param string $description * @return Country */ public function setDescripcionpais($description) { $this->description = $description; return $this; } /** * Get description * * @return string */ public function getDescription() { return $this->description; } } /** * Get id * * @return string */ public function getId() { return $this->id; } }

Yo serializo la entidad pero no sé cómo convertir el atributo de país en un campo simple.

Obtengo este resultado en json:

{"description":"foo", "title":"bar", "country":{"id":"en"} }

Pero quiero obtener el campo de identificación del país de esta manera:

{"description":"foo", "title":"bar", "country": "en" }

¿Es posible con el serializador JMS?

Gracias.

[EDITAR]

@VirtualProperty no funciona.


Puedes usar las anotaciones @Type y @Accessor :

/** * @Type("string") * @Accessor(getter="serializeType",setter="setType") */ protected $type; public function serializeType() { return $this->type->getId(); }


Sé que esto ya ha sido respondido, pero también puedes usar @Accessor. Esto probablemente (puede, no estoy seguro) también funciona con la deserialización.

/** * @Type("Acme/SearchBundle/Entity/Country") * @Groups({"manage"}) * * @var /Acme/SearchBundle/Entity/Country * * @Serializer/Accessor(getter="getCountryMinusId",setter="setCountryWithId") */ private $country; /** * @return string|null */ public function getCountryMinusId() { if (is_array($this->country) && isset($this->country[''id''])) { return $this->country[''id'']; } return null; } /** * @param string $country * @return $this */ public function setCountryWithId($country) { if (!is_array($this->country)) { $this->country = array(); ) $this->country[''id''] = $country; return $this; }


Sí, puedes usar la anotación @VirtualProperty :

/** * @VirtualProperty * @SerializedName("foo") */ public function bar() { return $this->country->getCode(); }

Pero ten cuidado cuando se trata de deserialización:

@VirtualProperty Esta anotación se puede definir en un método para indicar que los datos devueltos por el método deben aparecer como una propiedad del objeto.

> Nota: Esto solo funciona para la serialización y se ignora por completo durante la deserialización.

Espero que esto ayude...


Solo para seguir la pregunta respondida:

Si no le gusta escribir un método para cada relación que tiene, simplemente escriba su propio controlador. Es fácil como

final class RelationsHandler { /** * @var EntityManagerInterface */ private $manager; /** * RelationsHandler constructor. * * @param EntityManagerInterface $manager */ public function __construct(EntityManagerInterface $manager) { $this->manager = $manager; } public function serializeRelation(JsonSerializationVisitor $visitor, $relation, array $type, Context $context) { if ($relation instanceof /Traversable) { $relation = iterator_to_array($relation); } if (is_array($relation)) { return array_map([$this, ''getSingleEntityRelation''], $relation); } return $this->getSingleEntityRelation($relation); } /** * @param $relation * * @return array|mixed */ protected function getSingleEntityRelation($relation) { $metadata = $this->manager->getClassMetadata(get_class($relation)); $ids = $metadata->getIdentifierValues($relation); if (!$metadata->isIdentifierComposite) { $ids = array_shift($ids); } return $ids; } }

Registre el controlador

jms_serializer.handler.relation: class: MyBundle/RelationsHandler arguments: - "@doctrine.orm.entity_manager" tags: - { name: jms_serializer.handler, type: Relation, direction: serialization, format: json, method: serializeRelation} - { name: jms_serializer.handler, type: Relation, direction: deserialization, format: json, method: deserializeRelation} - { name: jms_serializer.handler, type: Relation<?>, direction: serialization, format: json, method: serializeRelation} - { name: jms_serializer.handler, type: Relation<?>, direction: deserialization, format: json, method: deserializeRelation}

Esto le permite reemplazar métodos getter virtuales con `Type (" Relation ").

Si no desea deserializar la relación, debe indicar a cada @Type("Relation") el nombre de clase ( @Type("Relation<FQCN>") ) que debe deserializar o ajustar el controlador de metadatos con uno que lo haga para ti.

public function deserializeRelation(JsonDeserializationVisitor $visitor, $relation, array $type, Context $context) { $className = isset($type[''params''][0][''name'']) ? $type[''params''][0][''name''] : null; if (!class_exists($className, false)) { throw new /InvalidArgumentException(''Class name should be explicitly set for deserialization''); } $metadata = $this->manager->getClassMetadata($className); if (!is_array($relation)) { return $this->manager->getReference($className, $relation); } $single = false; if ($metadata->isIdentifierComposite) { $single = true; foreach ($metadata->getIdentifierFieldNames() as $idName) { $single = $single && array_key_exists($idName, $relation); } } if ($single) { return $this->manager->getReference($className, $relation); } $objects = []; foreach ($relation as $idSet) { $objects[] = $this->manager->getReference($className, $idSet); } return $objects; }