JMSSerializer, сериализовать значения сущностей в пару (ключ, значение) в объекте json

Сущность предоставляется со следующими свойствами:

class Translation
{
  /**
   * @var string
   * @SerializedName("language_code")
   */
  private $lang;

  /**
   * @var string
   * @SerializedName("text")
   */
  private $translation;

  /**
   * @var int
   */
  private $language_id;
}

Контроллер выглядит так:

class DefaultController extends {
    public function indexAction(Request $request) {
        $translation = $this->getDoctrine()->getRepository('AppBundle:Translation')->findAll();
        $serializer = SerializerBuilder::create()->build();
        $translationJson = $serializer->serialize($translation, 'json');

        return new Response($translationJson);
   }    
}

Мой интерфейс ожидает формат JSON, как это:

 {
  "en" : "yes",
  "de" : "ja",
  "it" : "si"  
 }

Мой проект намного сложнее, но это краткое описание проблемы. Меня беспокоит только то, как я могу отформатировать свойства в пару ключ-значение в объекте json.

Могу ли я добиться этого с помощью аннотаций?
Если нет, то как?

РЕДАКТИРОВАТЬ

Бюро переводов имеет связь ManyToOne с организацией "Языки":

class Languages
{
  /**
   * @var int
   */
  private $id;

  /**
   * @var int
   * @ORM\OneToMany(targetEntity="Translation", mappedBy="translation_id", cascade={"persist"}, orphanRemoval=true)
   */
  private $translations;
}

2 ответа

Решение

Моя ошибка, я думал, что мне не нужно упоминать, что эта сущность имеет отношение ManyToOne с другой. Но @Matteo указал в правильном направлении. С небольшой настройкой его кода мне удалось заставить это работать.

Работа с объектом $obj = new \StdClass; В следующих getWhateva() не работал вообще. Я не пробовал это в контроллере, хотя. Конфиг выглядит следующим образом:

Добавить в Languages.php:

/**
 * @VirtualProperty
 * @SerializedName("whateva")
 */
public function getWhateva() {
    $arr = array();
    foreach ($this-> translation as $elem) {
        $arr[$elem-> getLang()] = $elem->getTranslation();
    }
    return $arr;
}

и в контроллере:

    $langu = $this->getDoctrine()->getRepository('AppBundle:Language')->findAll();
    $languageJson = $serializer->serialize($language, 'json');

Выход:

"whateva": {
       "en" : "yes",
       "de" : "ja",
       "it" : "si"  
 }

Ваши требования не настолько стандартны, чтобы быть реализованными в стандартной библиотеке: вы хотите, чтобы коллекция объектов была переведена в один объект и перечислена как атрибут со значением (как данные транспонирования Json).

Вы можете заархивировать свою цель с помощью специальной реализации следующим образом:

public function indexAction(Request $request) {
        $translation = $this->getDoctrine()->getRepository('AppBundle:Translation')->findAll();

        $obj = new \StdClass;

        foreach ($translation as $elem)
        {
            // transform each value in an attribute/value of the single object 
            $obj->{$elem->getLang()} = $elem->getTranslation();
        }

        return new JsonResponse($obj);
   }    

Надеюсь это поможет

Другие вопросы по тегам