EC-CUBE là nền tảng thương mại điện tử mã nguồn mở phổ biến nhất tại Nhật Bản. Với phiên bản 4.4, hệ thống plugin đã trở nên mạnh mẽ và linh hoạt hơn bao giờ hết, cho phép các kỹ sư tùy biến sâu sắc mà không làm ảnh hưởng đến mã nguồn cốt lõi (core). Bài viết này sẽ hướng dẫn bạn quy trình xây dựng một plugin hoàn chỉnh theo tiêu chuẩn của thị trường Nhật Bản.
1. Chuẩn bị môi trường phát triển
Trước khi bắt đầu, hãy đảm bảo hệ thống của bạn đã cài đặt môi trường phù hợp với EC-CUBE 4.4:
- PHP 8.2 trở lên.
- Composer để quản lý thư viện.
- Docker (khuyến nghị) để triển khai nhanh chóng.
# Sao chép mã nguồn từ repository
git clone https://github.com/EC-CUBE/ec-cube.git
cd ec-cube
composer install
# Khởi động môi trường bằng Docker
docker-compose up -d
2. Cấu trúc thư mục của một Plugin
Một plugin trong EC-CUBE 4.4 được đặt trong thư mục app/Plugin/. Giả sử chúng ta tạo một plugin có tên là VnExtension.
app/Plugin/VnExtension/
├── Controller/
│ └── HelloController.php # Xử lý logic request
├── Entity/ # Định nghĩa cơ sở dữ liệu
├── Form/ # Mở rộng Form hệ thống
├── Resource/
│ └── template/
│ └── hello.twig # Giao diện hiển thị
├── PluginManager.php # Quản lý vòng đời plugin
└── composer.json # Cấu hình plugin
Định nghĩa composer.json
Tệp này chứa thông tin metadata quan trọng để hệ thống nhận diện plugin:
{
"name": "vn-dev/vn-extension",
"version": "1.0.0",
"description": "Tiện ích mở rộng cho thị trường Việt - Nhật",
"type": "eccube-plugin",
"extra": {
"code": "VnExtension"
}
}
3. Xây dựng Controller và Giao diện
Bước 1: Tạo Controller
Sử dụng PHP 8 Attributes để định nghĩa route và template:
<?php
namespace Plugin\VnExtension\Controller;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
class HelloController
{
#[Route(path: '/vn_extension/hello', name: 'vn_extension_hello')]
#[Template('VnExtension/Resource/template/hello.twig')]
public function index(Request $request)
{
return [
'status' => 'Success',
'content' => 'Chào mừng bạn đến với Plugin EC-CUBE đầu tiên!'
];
}
}
Bước 2: Tạo Template Twig
Tạo file tại Resource/template/hello.twig để hiển thị dữ liệu:
{% extends '@admin/default_frame.twig' %}
{% block main %}
<div class="c-contentsArea__cols">
<div class="c-contentsArea__primaryCol">
<div class="card shadow-sm mb-4">
<div class="card-header">
<h3 class="card-title">{{ status }}</h3>
</div>
<div class="card-body">
<p>{{ content }}</p>
<small>Hệ thống đã sẵn sàng cho các tính năng nâng cao.</small>
</div>
</div>
</div>
</div>
{% endblock %}
4. Quản lý vòng đời Plugin (PluginManager)
Lớp PluginManager cho phép bạn thực hiện các tác vụ khi cài đặt hoặc gỡ bỏ plugin, chẳng hạn như tạo bảng hoặc xóa cache.
<?php
namespace Plugin\VnExtension;
use Eccube\Plugin\AbstractPluginManager;
use Psr\Container\ContainerInterface;
class PluginManager extends AbstractPluginManager
{
public function install(array $meta, ContainerInterface $container): void
{
// Thực thi khi cài đặt: Khởi tạo dữ liệu mặc định
}
public function enable(array $meta, ContainerInterface $container): void
{
// Thực thi khi kích hoạt plugin
}
public function uninstall(array $meta, ContainerInterface $container): void
{
// Thực thi khi gỡ cài đặt: Xóa bảng trong DB
}
}
5. Mở rộng Entity (Sử dụng Trait)
Một trong những tính năng mạnh nhất của EC-CUBE là khả năng thêm trường vào các bảng có sẵn mà không cần can thiệp trực tiếp vào file core. Ví dụ, thêm trường "Ghi chú nội bộ" vào bảng khách hàng (Customer).
Tạo Trait mở rộng
<?php
namespace Plugin\VnExtension\Entity;
use Doctrine\ORM\Mapping as ORM;
use Eccube\Attribute\EntityExtension;
#[EntityExtension(\Eccube\Entity\Customer::class)]
trait MemberExtraTrait
{
#[ORM\Column(name: 'internal_note', type: 'text', nullable: true)]
public $internal_note;
}
Mở rộng Form Admin
Để người quản trị có thể nhập liệu vào trường mới, chúng ta cần mở rộng Form Type:
<?php
namespace Plugin\VnExtension\Form\Extension;
use Eccube\Form\Type\Admin\CustomerType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
class MemberFormExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('internal_note', TextareaType::class, [
'required' => false,
'label' => 'Ghi chú nội bộ (Plugin)'
]);
}
public static function getExtendedTypes(): iterable
{
return [CustomerType::class];
}
}
6. Lắng nghe sự kiện (Event Listener)
Sử dụng Event Listener để can thiệp vào quy trình xử lý của hệ thống mà không thay đổi logic core.
<?php
namespace Plugin\VnExtension\EventListener;
use Eccube\Event\EccubeEvents;
use Eccube\Event\TemplateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductDetailSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
EccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE => 'handleDetailInit',
];
}
public function handleDetailInit(TemplateEvent $event): void
{
// Chèn thêm một đoạn mã Twig vào trang chi tiết sản phẩm
$event->addSnippet('@VnExtension/product_custom_info.twig');
}
}
7. Đóng gói và Triển khai
Sau khi hoàn thiện mã nguồn, bạn cần đóng gói plugin để phân phối hoặc cài đặt trên môi trường production:
- Nén toàn bộ nội dung thư mục
VnExtensionthành file.zip. - Truy cập vào trang quản trị (Admin) của EC-CUBE.
- Chọn Cài đặt hệ thống > Quản lý Plugin.
- Tải file
.ziplên và nhấn Cài đặt. - Bật (Enable) plugin để bắt đầu sử dụng.
Các lưu ý quan trọng
- Tiền tố bảng: Luôn sử dụng tiền tố
plg_cho các bảng mới tạo để tránh xung đột với hệ thống. - Logging: Sử dụng hệ thống log của EC-CUBE thông qua
var/log/để dễ dàng gỡ lỗi. - Cấu hình Service: Nếu plugin có các logic phức tạp, hãy tách chúng ra thành Service và đăng ký trong
Resource/config/services.yaml.