Linuxなどのメモ書き

Magento2 エクステンションの作成 その6


1. 概要

Magento2 エクステンションの作成 その5の続き。

前回は、新規投稿ページ、編集ページの表示を実装したが、実際の保存処理は未実装だったので今回実装する。

2. コントローラーの作成

保存処理を行うコントローラーを作成する。

Controller/Adminhtml/Posts/Save.php

<?php
namespace BitHive\Topic\Controller\Adminhtml\Posts;

class Save extends \Magento\Backend\App\Action
{
    protected $pageFactory;
    protected $postFactory;
    protected $dataPersistor;
    protected $timezone;
    protected $timezoneHelper;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $pageFactory,
        \BitHive\Topic\Model\PostFactory $postFactory,
        \Magento\Framework\App\Request\DataPersistorInterface $dataPersistor,
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone,
        \BitHive\Topic\Helper\Timezone $timezoneHelper
    )
    {
        $this->pageFactory = $pageFactory;
        $this->postFactory = $postFactory;
        $this->dataPersistor = $dataPersistor;
        $this->timezone = $timezone;
        $this->timezoneHelper = $timezoneHelper;
        return parent::__construct($context);
    }

    public function execute()
    {
        $this->dataPersistor->clear('bithive_topic');

        $data = $this->getRequest()->getPostValue();

        $resultRedirect = $this->resultRedirectFactory->create();

        // validation
        $error = 0;
        if ($data['date']) {
            if (strtotime($data['date']) === false) {
                $this->messageManager->addErrorMessage( __('Date is invalid') );
                $error++;
            }
        }
        if ($error) {
            $this->dataPersistor->set('bithive_topic', $data);
            if (isset($data['post_id'])) {
                return $resultRedirect->setPath('*/*/edit', ['id' => $data['post_id']]);
            } else {
                return $resultRedirect->setPath('*/*/new');
            }
        }

        // システムのtimezone(UTC)に変換
        if ($data['date']) {
            $data['date'] = $this->timezoneHelper->convertTz($data['date'], $this->timezone->getConfigTimezone(), $this->timezone->getDefaultTimezone());
        }

        $model = $this->postFactory->create();

        $model->setData($data);

        $model->save();

        $this->messageManager->addSuccess( __('Saved.') );

        $this->_redirect('*/*/');
    }
}

基本的には、POSTされたフォームデータを元にPostモデルのオブジェクトを作成し、保存しているだけ。dateフィールドの時刻については、dateカラムはTIMESTAMP型となっており、MagentoのデフォルトタイムゾーンはUTCで動作しているので、DBに保存する前にUTCに変換する必要がある。

あと、フォーム入力値にエラーがあった場合は、DataPersistorにフォーム入力値を保存しておき、新規投稿ページ/編集ページに戻した際に入力値がフォームに戻されるようにする。DataPersistorからフォームに値を戻す処理はModel\DataProvider.phpで行っている(Magento2 エクステンションの作成 その5で説明した)。

これで、新規投稿の保存や編集ができるようになる。./bin/magento setup:di:compile の実行は忘れずに。

ついでに、削除処理の方も実装する。

Controller/Adminhtml/Posts/Delete.php

?php
namespace BitHive\Topic\Controller\Adminhtml\Posts;

class Delete extends \Magento\Backend\App\Action
{
    protected $pageFactory;
    protected $postFactory;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $pageFactory,
        \BitHive\Topic\Model\PostFactory $postFactory)
    {
        $this->pageFactory = $pageFactory;
        $this->postFactory = $postFactory;
        return parent::__construct($context);
    }

    public function execute()
    {
        $resultRedirect = $this->resultRedirectFactory->create();

        $postId = $this->getRequest()->getParam('id');

        if ($postId) {
            try {
                $model = $this->postFactory->create();

                $model->load($postId);
                $model->delete();

                $this->messageManager->addSuccess(__('You deleted the post.'));

                // 一覧ページへ
                return $resultRedirect->setPath('*/*/');
            } catch (\Exception $e) {
                // display error message
                $this->messageManager->addError($e->getMessage());
                // 編集フォームへ戻す
                return $resultRedirect->setPath('*/*/edit', ['id' => $postId]);
            }
        }

        $this->messageManager->addError(__('We can\'t find a record to delete.'));
        // 一覧ページへ
        return $resultRedirect->setPath('*/*/');
    }
}

これは、指定IDのPostモデルを取得して削除しているだけで特筆すべき処理はない。

 

ここまでの段階で、管理画面で投稿の一覧表示、新規投稿、編集、削除を行えるようなった。

現時点でTopic配下は以下のようになっている。

./registration.php
./Model/ResourceModel/Post/Collection.php
./Model/ResourceModel/Post.php
./Model/DataProvider.php
./Model/Post.php
./view/adminhtml/templates/posts.phtml
./view/adminhtml/layout/topic_posts_index.xml
./view/adminhtml/layout/topic_posts_edit.xml
./view/adminhtml/ui_component/topic_edit_form.xml
./view/adminhtml/ui_component/topic_listing.xml
./Ui/Component/Listing/Columns/PostActions.php
./Setup/InstallSchema.php
./Block/Adminhtml/Edit/SaveButton.php
./Block/Adminhtml/Edit/BackButton.php
./Block/Adminhtml/Edit/GenericButton.php
./Controller/Adminhtml/Posts/Save.php
./Controller/Adminhtml/Posts/Index.php
./Controller/Adminhtml/Posts/NewAction.php
./Controller/Adminhtml/Posts/Edit.php
./Controller/Adminhtml/Posts/Delete.php
./etc/module.xml
./etc/di.xml
./etc/adminhtml/menu.xml
./etc/adminhtml/routes.xml
./Helper/Timezone.php

今回はここまで。次回は最後に投稿記事をフロント側に表示できるようにする。

 


最終更新 2018/12/11 14:31:40 - kztomita
(2018/12/11 14:22:44 作成)