Magento2 Editing and Updating
让我们为用户提供一个编辑博客的选项。
首先,我们将编辑博客页面和一个编辑链接,让我们编辑 view / frontend / templates / list.phtml
<table>
<tr>
<th>
<?= __("Id")?>
</th>
<th>
<?= __("Title")?>
</th>
<th>
<?= __("Content")?>
</th>
</tr>
<?php
$blogs = $block->getBlogs();
foreach ($blogs as $blog) {?>
<tr>
<td>
<?= $blog->getId()?>
</td>
<td>
<?= $blog->getTitle()?>
</td>
<td>
<?= substr($blog->getContent(), 0, 20).'...'?>
</td>
<td>
<a href="<?= $block->getUrl('blog/manage/edit',['id' =>$blog->getId()])?>">
<?= __('Edit') ?></a>
</td>
</tr>
<?php } ?>
</table>
在这里,我们在列表页面上添加了一个编辑列。 您可能已经注意到,我们在getUrl函数的第二个参数中传递了一个关联数组。 像在get请求中一样,将其作为键值对(即?key = value)附加到URL。

在这里,如果您检查编辑链接的网址,您会发现类似http:// hostname / blog / manage / edit / id / 203 /的id / 203等于?id = 203
frontName / controllerName / actionName之后的任何内容均视为键值对。 这意味着我们可以将网址视为http:// hostname / frontName / controllerName / actionName / key1 / value1 / key2 / value2
Edit page
现在我们必须创建编辑页面。 为此,我们必须创建控制器,布局文件,模板文件和块。 让我们一一创建这些文件。
控制器文件将为Controller / Manage / Edit.php
<?php
namespace Yshuq\BlogManager\Controller\Manage;
use Magento\Customer\Controller\AbstractAccount;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Customer\Model\Session;
class Edit extends AbstractAccount
{
public $resultPageFactory;
public $blogFactory;
public $customerSession;
public $messageManager;
public function __construct(
Context $context,
PageFactory $resultPageFactory,
\Yshuq\BlogManager\Model\BlogFactory $blogFactory,
Session $customerSession,
\Magento\Framework\Message\ManagerInterface $messageManager
) {
$this->resultPageFactory = $resultPageFactory;
$this->blogFactory = $blogFactory;
$this->customerSession = $customerSession;
$this->messageManager = $messageManager;
parent::__construct($context);
}
public function execute()
{
// TODO: Implement execute() method.
$blogId = $this->getRequest()->getParam('id');
$customerId = $this->customerSession->getCustomerId();
$isAuthorised = $this->blogFactory->create()
->getCollection()
->addFieldToFilter('user_id',$customerId)
->addFieldToFilter('entity_id',$blogId)
->getsize();
if (!$isAuthorised) {
$this->messageManager->addError(__('You are not authorised to edit this blog.'));
return $this->resultRedirectFactory->create()->setPath('blog/manage');
}
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->set(__('Edit Blog'));
$layout = $resultPage->getLayout();
return $resultPage;
}
}
在这里,我们从获取请求中提取了博客ID,然后获得了当前客户ID。 我们正在收集所有这些信息,以检查当前用户是否是博客的授权用户。 因为如果我们不执行此检查,那么任何人都可以访问任何博客,而只需更改url中的ID。
在这里,如果您注意到我们正在使用模型工厂并调用getCollection方法,该方法将返回收集工厂。 而且我们使用了两个addFieldToFilter方法,因此这些条件将与AND运算符结合在一起。 因此条件将看起来像“ WHERE user_id = $ customerId AND entity_id = $ blogID”。
我们前面也已经讨论了所有这些。 但是什么是getSize()方法? getSize将返回计数,即集合中的行数或模型数。 因此,SQL查询将类似于select count(*)
这意味着实际的查询将类似于“从blogmanager_blog中的SELECT COUNT(*),其中user_id = $ customerId和entity_id = $ blogID”
如您在这里看到的,我们可以将方法一个接一个地链接,这使得编写复杂的查询变得更加容易。
$ isAuthorised将包含计数,如果表中没有此类条目,则计数将为零。 在这种情况下,我们已将用户重定向到带有错误消息的列表页面。 否则,我们将显示编辑表单。
现在,让我们创建布局文件view / frontend / layout / blogmanager_manage_edit.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="customer_account"/>
<body>
<referenceContainer name="content">
<block class="Yshuq\BlogManager\Block\Blog" name="blogmanager.blog.edit" template="Yshuq_BlogManager::edit.phtml" />
</referenceContainer>
</body>
</page>
这里没有新内容,因为我们也看到了列表页面的类似语法。
现在,让我们创建模板文件view / frontend / templates / edit.phtml
<?php $blog = $block->getBlog(); ?>
<div class="blog-container">
<form class="blog-form" method="post" action= <?php echo $block->getUrl('blog/manage/save');?> data-mage-init='{"validation": {}}'>
<input type="hidden" name="id" value="<?= $blog->getId()?>"/>
Title: <input type="text" name="title" class="required-entry" value="<?= $blog->getTitle(); ?>"//>
Content: <textarea name="content" class="required-entry validate-no-html-tags" rows="10"> <?= $blog->getContent(); ?></textarea>
<button type="submit">Submit</button>
</form>
</div>
在这里,我们通过调用getBlog方法通过block类获取博客数据。 我们正在其各自的输入字段中显示标题和内容。 您在这里需要注意的一件事是,我们使用了一个隐藏的输入字段,当我们提交编辑的博客数据时,该字段将用于传递博客ID和博客数据。
现在,让我们创建一个Block文件Block / Blog.php
<?php
namespace Yshuq\BlogManager\Block;
class Blog extends \Magento\Framework\View\Element\Template
{
public $blogFactory;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Yshuq\BlogManager\Model\BlogFactory $blogFactory,
array $data = []
) {
$this->blogFactory = $blogFactory;
parent::__construct($context, $data);
}
public function getBlog()
{
$blogId = $this->getRequest()->getParam('id');
return $this->blogFactory->create()->load($blogId);
}
}
在这里,我们通过调用load方法并通过在参数中传递博客ID来通过博客ID加载博客模型,因为ID是主键。 我们已经返回了加载的模型。 我们已经在模板文件中使用过。
现在,让我们来看看编辑页面的外观,

Updating Blog
我们将修改用于保存新博客的Controller / Save.php,而不是创建一个新的控制器来提交编辑数据。
<?php
namespace Yshuq\BlogManager\Controller\Manage;
use Magento\Customer\Controller\AbstractAccount;
use Magento\Framework\App\Action\Context;
use Magento\Customer\Model\Session;
class Save extends AbstractAccount
{
public $blogFactory;
public $customerSession;
public $messageManager;
public function __construct(
Context $context,
\Yshuq\BlogManager\Model\BlogFactory $blogFactory,
Session $customerSession,
\Magento\Framework\Message\ManagerInterface $messageManager
){
$this->blogFactory = $blogFactory;
$this->customerSession = $customerSession;
$this->messageManager = $messageManager;
parent::__construct($context);
}
public function execute()
{
$data = $this->getRequest()->getParams();
$customerId = $this->customerSession->getCustomerId();
if (isset($data['id']) && $data['id']) {
$isAuthorised = $this->blogFactory->create()
->getCollection()
->addFieldToFilter('user_id', $customerId)
->addFieldToFilter('entity_id', $data['id'])
->getSize();
if (!$isAuthorised) {
$this->messageManager->addError(__('You are not authorised to edit this blog.'));
return $this->resultRedirectFactory->create()->setPath('blog/manage');
} else {
$model = $this->blogFactory->create()->load($data['id']);
$model->setTitle($data['title'])
->setContent($data['content'])
->save();
$this->messageManager->addSuccess(__('You have updated the blog successfully.'));
}
}else{
$model = $this->blogFactory->create();
$model->setData($data);
$model->setUserId($customerId);
$model->save();
$this->messageManager->addSuccess(__('Blog saved successfully.'));
}
return $this->resultRedirectFactory->create()->setPath('blog/manage');
}
}
在这里,我们首先检查id字段是否存在。 如果帖子数据中存在id,则用户正在更新博客,否则将在创建新博客。 因此,我们已将之前的代码放在了else部分中。
让我们集中讨论if部分,在这里我们再次检查了它是否是正确的用户,因为有人可以使用inspect element功能更改id字段。
为了保存更新的数据,我们使用load方法加载了模型,并通过setTitle和setContent分别设置了更新的标题和内容。 之后,我们保存了模型并添加了成功消息,最后,我们已重定向到列表页面。

文件夹结构应该是什么样,