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 CMS 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;
    }
}