Magento 2 – Serializing a Category Tree as Primitive Types

categorymagento2PHPservice-contract

In Magento 2, I can get a category tree with the following

    $tree     = $this->treeFactory->create();
    var_dump(
        $tree->getTree(
            $tree->getRootNode()
        )->getData()
    );

However, the data in the children_data property will be a PHP array of full PHP category objects

'children_data' => 
    array (size=8)
      0 => 
        object(Magento\Catalog\Model\Category\Interceptor)[945]
      protected '_eventPrefix' => string 'catalog_category' (length=16)

I'd like this data to be serialized is a json friendly way — i.e., no PHP objects.

Is there an elegant way of doing this? — I know the native Magento 2 API supports JSON output (using native category objects via service contracts), so somewhere in Magento 2 is code that will do the serialization I'm after. I'm just not familiar enough with Magento 2's architecture to drag this up myself.

Best Answer

\Magento\Catalog\Api\Data\CategoryTreeInterface is implemented with the \Magento\Catalog\Model\Category class

Serialization logic which is used for Web API collects getters from CategoryTreeInterface using reflection, together with annotations. Then it walks through object which implements the interface, calls getters, casts result to expected return type. The output is PHP array of simple types available for JSON encoding.

If you need to call this logic, use:

/**
 * @var \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
 */
$dataObjectProcessor->buildOutputDataArray(
    $category,
    'Magento\Catalog\Api\Data\CategoryTreeInterface'
);

In future you may need opposite operation: given empty category object populate it with array of data. For this use

$category = $this->treeFactory->create();
/** 
 * @var \Magento\Framework\Api\DataObjectHelper $dataObjectHelper 
 */
$dataObjectHelper->populateWithArray($category, $treeData, 'Magento\Catalog\Api\Data\CategoryTreeInterface')
Related Topic