Magento2 エクステンションの作成 その6
Rev.1を表示中。最新版はこちら。
1. 概要
前回は、新規投稿ページ、編集ページの表示を実装したが、実際の保存処理は未実装だったので今回実装する。
2. コントローラーの作成
保存処理を行うコントローラーを作成する。
Topic/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 の実行は忘れずに。
ついでに、削除処理の方も実装する。
Topic/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
今回はここまで。次回は最後に投稿記事をフロント側に表示できるようにする。