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?
- Me who cannot read / understand @api comments and code properly
- 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
Repositories is not for bulk operation, this affect performance.