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
今回はここまで。次回は最後に投稿記事をフロント側に表示できるようにする。
