Joomla Bài học 34: Lập trình Controller, Model và Form View để xử lý Thêm và Sửa bản ghi phía Administrator
Trong Joomla Bài học 33, chúng ta đã hoàn thành việc hiển thị danh sách bản ghi dạng bảng. Tuy nhiên, một hệ thống quản trị hoàn chỉnh không chỉ để xem mà còn phải cho phép Thêm mới (Create) và Chỉnh sửa (Update) dữ liệu.
Trong Joomla Bài học 34, chúng ta sẽ tiến hành lập trình nhóm ba thành phần quản lý form bao gồm: Form Model (lưu trữ và validate dữ liệu), Form Controller (xử lý hành động lưu/hủy) và Form View / Layout (giao diện nhập liệu với các trường biểu mẫu chuẩn).
1. Cấu trúc thư mục bổ sung cho chức năng Thêm/Sửa (Form)
Để component hỗ trợ thao tác Form, chúng ta cần bổ sung các tệp tin cấu hình XML và mã nguồn xử lý vào cấu trúc hiện tại của phần Administrator:
Plaintext
com_custom/admin/
├── forms/
│ └── item.xml <-- Định nghĩa các trường nhập liệu của Form
├── src/
│ ├── Controller/
│ │ └── ItemController.php <-- Controller xử lý lưu/hủy cho từng bản ghi đơn lẻ
│ ├── Model/
│ │ └── ItemModel.php <-- Model quản lý logic lấy dữ liệu 1 bản ghi và lưu vào DB
│ └── View/
│ └── Item/
│ └── HtmlView.php <-- View render form nhập liệu
└── tmpl/
└── item/
└── edit.php <-- Giao diện HTML form nhập liệu (Bootstrap 5)
2. Định nghĩa cấu trúc Form bằng XML (forms/item.xml)
Joomla sử dụng hệ thống Form XML để tự động sinh các thẻ <input>, <select>, xác thực dữ liệu (validate="required") và bộ lọc đầu vào (filter="...") mà không cần viết thủ công HTML validation phức tạp.
Tạo file tại: src/administrator/components/com_custom/forms/item.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset name="details">
<field
name="id"
type="hidden"
default="0"
/>
<field
name="title"
type="text"
label="COM_CUSTOM_FIELD_TITLE_LABEL"
description="COM_CUSTOM_FIELD_TITLE_DESC"
class="form-control"
required="true"
filter="string"
/>
<field
name="alias"
type="text"
label="COM_CUSTOM_FIELD_ALIAS_LABEL"
description="COM_CUSTOM_FIELD_ALIAS_DESC"
class="form-control"
hint="COM_CUSTOM_FIELD_ALIAS_HINT"
filter="safehtml"
/>
<field
name="state"
type="list"
label="JSTATUS"
description="JFIELD_PUBLISHED_DESC"
class="form-select"
default="1"
filter="integer"
validate="options"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
</field>
</fieldset>
</form>
3. Lập trình Form Model (Model/ItemModel.php)
Lớp AdminModel của Joomla cung cấp sẵn các phương thức tự động liên kết với file XML ở trên, kiểm tra quyền hạn (core.edit, core.create) và thực thi câu lệnh INSERT / UPDATE vào cơ sở dữ liệu.
Tạo file tại: src/administrator/components/com_custom/src/Model/ItemModel.php
PHP
<?php
namespace MyCompany\Component\Custom\Administrator\Model;
\defined('_JEXEC') or die;
use Joomla\CMS\MVC\Model\AdminModel;
class ItemModel extends AdminModel
{
protected $text_prefix = 'COM_CUSTOM';
public function getTable($type = 'Item', $prefix = 'Table', $config = [])
{
// Trả về lớp Table tương ứng để tương tác với bảng #__custom_items
return \Joomla\CMS\Table\Table::getInstance('Item', 'MyCompany\Component\Custom\Administrator\Table\\', $config);
}
public function getForm($data = [], $loadData = true)
{
$form = $this->loadForm('com_custom.item', 'item', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
return $form;
}
protected function loadFormData()
{
$data = $this->app->getUserState('com_custom.edit.item.data', []);
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
}
4. Lập trình Form Controller (Controller/ItemController.php)
Controller này kế thừa từ lớp FormController chuẩn, tự động quản lý các tác vụ item.add, item.edit, item.save, item.cancel và điều hướng người dùng sau khi thao tác thành công.
Tạo file tại: src/administrator/components/com_custom/src/Controller/ItemController.php
PHP
<?php
namespace MyCompany\Component\Custom\Administrator\Controller;
\defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\FormController;
class ItemController extends FormController
{
// Lớp cha đã tự động xử lý toàn bộ logic CRUD chuẩn của Joomla Admin.
}
5. Lập trình Form View và Layout Template (View/Item/HtmlView.php & tmpl/item/edit.php)
A. View Logic (View/Item/HtmlView.php)
Tạo file tại: src/administrator/components/com_custom/src/View/Item/HtmlView.php
PHP
<?php
namespace MyCompany\Component\Custom\Administrator\View\Item;
\defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
use Joomla\CMS\Language\Text;
class HtmlView extends BaseHtmlView
{
protected $form;
protected $item;
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
$this->addToolbar();
parent::display($tpl);
}
protected function addToolbar()
{
$isNew = ($this->item->id == 0);
ToolbarHelper::title($isNew ? Text::_('COM_CUSTOM_MANAGER_ITEM_NEW') : Text::_('COM_CUSTOM_MANAGER_ITEM_EDIT'), 'pencil-2');
ToolbarHelper::apply('item.apply');
ToolbarHelper::save('item.save');
ToolbarHelper::cancel('item.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');
}
}
B. Layout Giao diện (tmpl/item/edit.php)
Tạo file tại: src/administrator/components/com_custom/tmpl/item/edit.php
PHP
<?php
\defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Language\Text;
/** @var \Joomla\CMS\MVC\View\HtmlView $this */
HTMLHelper::_('behavior.formvalidator');
?>
<form action="<?php echo Route::_('index.php?option=com_custom&layout=edit&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="item-form" class="form-validate">
<div class="row">
<div class="col-lg-9">
<div class="card shadow-sm border-0 p-4 mb-4">
<fieldset class="mb-3">
<legend class="text-primary fs-5 fw-bold mb-3"><?php echo Text::_('COM_CUSTOM_DETAILS'); ?></legend>
<div class="mb-3">
<?php echo $this->form->getLabel('title'); ?>
<?php echo $this->form->getInput('title'); ?>
</div>
<div class="mb-3">
<?php echo $this->form->getLabel('alias'); ?>
<?php echo $this->form->getInput('alias'); ?>
</div>
<div class="mb-3">
<?php echo $this->form->getLabel('state'); ?>
<?php echo $this->form->getInput('state'); ?>
</div>
<?php echo $this->form->getInput('id'); ?>
</fieldset>
</div>
</div>
</div>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>
6. Tổng kết bài học
-
Hiểu rõ cách khai báo các trường nhập liệu nhanh chóng và an toàn thông qua cấu hình Form XML (
forms/item.xml). -
Nắm vững cách sử dụng lớp
AdminModelđể tự động xử lý validation và kết nối cơ sở dữ liệu khi Thêm / Sửa. -
Thành thạo việc xây dựng giao diện chỉnh sửa chuyên nghiệp với Bootstrap 5 và các hàm trợ giúp biểu mẫu (
$this->form->getLabel()/$this->form->getInput()).
Trong Bài học 35, chúng ta sẽ chuyển sang lập trình phần hiển thị phía người dùng cuối (Frontend): Lập trình Site Controller, Model và View hiển thị dữ liệu ngoài Frontend (Site MVC).
All rights reserved