Doctrine MongoDB how to get Embedded Document in PersistentArray as its actual class instead of Array

837 Views Asked by At

My document is an ItemsList, having an Items embedded document.

The problem is that Doctrine Mongo is not mapping the embedded document as an Item object, but as an array. Is this correct? How would I update an Item in an OOP way?

ItemsList.php

<?php

namespace App\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\Document(collection="itemslists")
 */
class ItemsList implements \JsonSerializable {

    /**
     * @MongoDB\Id
     */
    private $id;

    /**
     * @MongoDB\EmbedMany(targetDocument="Item")
     */
    private $items;

    /**
     * @return mixed
     */
    public function getId() {
        return $this->id;
    }

    /**
     * @param mixed $id
     */
    public function setId($id): void {
        $this->id = $id;
    }

    /**
     * @return mixed
     */
    public function getItems() {
        return $this->items;
    }

    /**
     * @param mixed $items
     */
    public function setItems($items): void {
        $this->items = $items;
    }

    public function jsonSerialize() {
        return [
            'id' => $this->getId(),
            'items' => json_encode($this->getItems()),
        ];
    }

}

Item.php

<?php

namespace App\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\EmbeddedDocument
 */
class Item implements \JsonSerializable {

    /**
     * @MongoDB\Id
     */
    private $id;

    /**
     * @MongoDB\Field(type="string")
     */
    private $imgPath;

    /**
     * @MongoDB\Field(type="string")
     */
    private $description;

    /**
     * @return mixed
     */
    public function getId() {
        return $this->id;
    }

    /**
     * @param mixed $id
     */
    public function setId($id): void {
        $this->id = $id;
    }

    /**
     * @return mixed
     */
    public function getImgPath() {
        return $this->imgPath;
    }

    /**
     * @param mixed $imgPath
     */
    public function setImgPath($imgPath): void {
        $this->imgPath = $imgPath;
    }

    /**
     * @return mixed
     */
    public function getDescription() {
        return $this->description;
    }

    /**
     * @param mixed $description
     */
    public function setDescription($description): void {
        $this->description = $description;
    }

    public function jsonSerialize() {
        return [
            'id' => $this->getId(),
            'img_path' => $this->getImgPath(),
            'description' => $this->getDescription(),
        ];
    }
}

Dump of $itemsList = $itemsListRepository->findBy([], null, 1);

ItemsListController.php on line 23:
array:1 [▼
  0 => ItemsList {#579 ▼
    -id: "5b63016b3faeb7e511d6d064"
    -items: PersistentCollection {#584 ▼
      -snapshot: []
      -owner: ItemsList {#579}
      -mapping: array:21 [▶]
      -isDirty: false
      -initialized: false
      -coll: ArrayCollection {#583 ▶}
      -dm: DocumentManager {#483 …13}
      -uow: UnitOfWork {#486 ▶}
      -mongoData: array:3 [▼
        0 => array:3 [▼
          "_id" => MongoId {#572 ▶}
          "img_path" => "/tmp/1.jpg"
          "description" => "Una descripcion"
        ]
        1 => array:3 [▶]
        2 => array:3 [▶]
      ]
      -hints: []
    }
  }
]
1

There are 1 best solutions below

1
JorgeeFG On

It seems that they are converted when using the methods of PersistentCollection

public function getFirstList() {
        /** @var Repository $itemsListRepository */
        $itemsListRepository = $this->get('doctrine_mongodb')->getRepository('App:ItemsList');
        /** @var ItemsList $itemsList */
        $itemsLists = $itemsListRepository->findBy([], null, 1);
        $itemsList = $itemsLists[0];
        /** @var PersistentCollection $items */
        $items = $itemsList->getItems();
        dump($items->first(), json_encode($itemsList));
        exit;
    }