Magento 2

Magento 2 + CMS page create via Data Patch

It’s easy to create a Cms Page via admin, but when code is moved to another server or in some cases of data loss, might be a chance to lose that page, and is not recoverable. Creating a CMS Page via data patch is easy to use, it will create automatically pages when the source moves to another server, and no worry about data loss.

<?php

declare(strict_types=1);

namespace Mage2\Demo\Setup\Patch\Data;

use Magento\Cms\Api\PageRepositoryInterface;
use Magento\Cms\Model\Page;
use Magento\Cms\Model\PageFactory;
use Magento\Framework\App\Area;
use Magento\Framework\App\State;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Store\Model\Store;
use Psr\Log\LoggerInterface;

/**
 * class CustomCmsPage create a Custom Cms page
 */
class CustomCmsPage implements DataPatchInterface
{
    private const PAGE_IDENTIFIER = "custom-cms-page";

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @var PageFactory
     */
    private $pageFactory;

    /**
     * @var State
     */
    private $state;

    /**
     * @var ModuleDataSetupInterface
     */
    private $moduleDataSetup;

    /**
     * @var PageRepositoryInterface
     */
    private $pageRepository;

    /**
     * @param PageFactory $pageFactory
     * @param LoggerInterface $logger
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param State $state
     * @param PageRepositoryInterface $pageRepository
     */
    public function __construct(
        PageFactory              $pageFactory,
        LoggerInterface          $logger,
        ModuleDataSetupInterface $moduleDataSetup,
        State                    $state,
        PageRepositoryInterface  $pageRepository
    ) {
        $this->logger = $logger;
        $this->pageFactory = $pageFactory;
        $this->state = $state;
        $this->moduleDataSetup = $moduleDataSetup;
        $this->pageRepository = $pageRepository;
    }

    /**
     * Get array of patches that have to be executed prior to this.
     *
     * @return string[]
     */
    public static function getDependencies()
    {
        return [];
    }

    /**
     * Get aliases (previous names) for the patch.
     *
     * @return string[]
     */
    public function getAliases()
    {
        return [];
    }

    /**
     * This patch is create Custom Cms Page
     *
     * @return $this|CustomCmsPage
     */
    public function apply()
    {
        $this->moduleDataSetup->startSetup();

        try {
            $this->state->emulateAreaCode(
                Area::AREA_ADMINHTML,
                [$this, 'setupCustomCmsPage']
            );
        } catch (\Exception $e) {
            $this->logger->error(
                'Error when Saving settings for patch CustomCmsPage: ' . $e->getMessage()
            );
        }

        $this->moduleDataSetup->endSetup();
        return $this;
    }

    /**
     * This patch is to create Custom Cms Page
     */
    public function setupCustomCmsPage()
    {
        $cmsPage = $this->createPage()->setData($this->getPage());
        $this->pageRepository->save($cmsPage);
    }

    /**
     * Create page instance.
     *
     * @return Page
     */
    private function createPage()
    {
        return $this->pageFactory->create();
    }

    /**
     * Get Page Config
     *
     * @return array
     */
    private function getPage(): array
    {
        return [
            'title' => 'Test CMS Page',
            'page_layout' => '1column',
            'meta_keywords' => '',
            'meta_description' => '',
            'identifier' => self::PAGE_IDENTIFIER,
            'content_heading' => '',
            'content' => $this->getCmsPageHtml(),
            'layout_update_xml' => '',
            'is_active' => 1,
            'stores' => [Store::DEFAULT_STORE_ID],
            'sort_order' => 0
        ];
    }

    /**
     * Get Custom CMS page html
     *
     * @return string
     */
    private function getCmsPageHtml(): string
    {
        // Set HTML content here
        $html = <<<HTML
You can set here Html Content
HTML;

        return $html;
    }
}