Magento – Magento 2 CMS Page getList() repository methods does not return expected object

magento2

I need to delete all CMS pages.

Here is the code:

namespace Soon\Core\Setup;

use Magento\Cms\Api\PageRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaInterface;

class Cms
{
    /**
     * @var SearchCriteriaInterface
     */
    private $searchCriteria;
    /**
     * @var PageRepositoryInterface
     */
    private $cmsPageRepository;

    /**
     * Cms constructor.
     * @param SearchCriteriaInterface $searchCriteria
     * @param PageRepositoryInterface $cmsPageRepository
     */
    public function __construct(
        SearchCriteriaInterface $searchCriteria,
        PageRepositoryInterface $cmsPageRepository
    )
    {
        $this->searchCriteria = $searchCriteria;
        $this->cmsPageRepository = $cmsPageRepository;
    }

    /**
     * Delete all existing CMS pages
     */
    public function cleanCmsPages()
    {
        $cmsPageCollection = $this->cmsPageRepository
            ->getList($this->searchCriteria)
            ->getItems();

        foreach ($cmsPageCollection as $cmsPage) {
            $this->cmsPageRepository->delete($cmsPage);
        }
    }
}

So, calling \Soon\Core\Setup\Cms::cleanCmsPages should delete all CMS pages.

But when doing so, I get this error:

Argument 1 passed to Magento\Cms\Model\PageRepository::delete() must implement interface Magento\Cms\Api\Data\PageInterface, array given

So I dumped the $cmsPage used in my foreach ($cmsPageCollection as $cmsPage) and it appears that, indeed, $cmsPage is an array.

I digged into the code:

\Magento\Cms\Api\PageRepositoryInterface::getList is implemented by \Magento\Cms\Model\PageRepository::getList.

Then in \Magento\Cms\Model\PageRepository::getList, we can see this bit of code:

            $pages[] = $this->dataObjectProcessor->buildOutputDataArray(
                $pageData,
                'Magento\Cms\Api\Data\PageInterface'
            );
        }
        $searchResults->setItems($pages);

If I am correct, this code creates an array that populates the $pages array.
So this code may explain why $cmsPage is an array!

BUT…

By reading @return statement of \Magento\Cms\Api\PageRepositoryInterface::getList, we can see @return \Magento\Cms\Api\Data\PageSearchResultsInterface.

And, then by reading the @return statement from \Magento\Cms\Api\Data\PageSearchResultsInterface::getItems, we can see \Magento\Cms\Api\Data\PageInterface[]!

So the $cmsPage in my foreach loop should be an implementation of \Magento\Cms\Api\Data\PageInterface which then can be passed properly to \Magento\Cms\Api\PageRepositoryInterface::delete.

Who's wrong?

  1. Me who cannot read / understand @api comments and code properly
  2. Magento who whether does not give the right comment in their @api classes… or does not implements the interface as it should.

This analysis is for the CMS Page API but also applies to the CMS Block API.

Best Answer

You can create bug issue on github if you want. But more faster way for you is to use resource model or if you want use this repository method deleteById() where you can pass id of entity.

vendor/magento/module-cms/Model/PageRepository.php

public function deleteById($pageId)
{
    return $this->delete($this->getById($pageId));
}

Repositories is not for bulk operation, this affect performance.

Related Topic