Розробка кастомного плагіну October CMS
Плагіни October CMS — це Laravel-пакети, що розширюють функціональність через реєстрацію компонентів, моделей, маршрутів, backend-контроллерів. Один плагін може містити всю бізнес-логіку проекту.
Генерація через Builder
php artisan create:plugin MyCompany.MySite
Структура плагіну
plugins/mycompany/mysite/
├── Plugin.php # реєстрація всього
├── composer.json
├── models/
│ ├── Review.php
│ └── Review/
│ ├── columns.yaml # список у backend
│ └── fields.yaml # форма редактування
├── components/
│ └── ReviewList.php
├── controllers/
│ └── Reviews.php # backend-контроллер
├── views/
│ └── reviews/
│ └── index.htm
├── updates/
│ ├── version.yaml
│ └── 1_0_1_create_reviews_table.php
└── lang/
├── en/lang.php
└── ru/lang.php
Plugin.php — точка реєстрації
// Plugin.php
namespace MyCompany\MySite;
use Backend;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function pluginDetails(): array
{
return [
'name' => 'My Site',
'description' => 'Site-specific functionality',
'author' => 'My Company',
'icon' => 'icon-leaf',
];
}
public function registerComponents(): array
{
return [
\MyCompany\MySite\Components\ReviewList::class => 'reviewList',
\MyCompany\MySite\Components\ReviewForm::class => 'reviewForm',
];
}
public function registerNavigation(): array
{
return [
'mysite' => [
'label' => 'My Site',
'url' => Backend::url('mycompany/mysite/reviews'),
'icon' => 'icon-star',
'permissions' => ['mycompany.mysite.*'],
'order' => 500,
'sideMenu' => [
'reviews' => [
'label' => 'Reviews',
'icon' => 'icon-comments',
'url' => Backend::url('mycompany/mysite/reviews'),
'permissions' => ['mycompany.mysite.reviews'],
],
],
],
];
}
public function registerSettings(): array
{
return [
'settings' => [
'label' => 'My Site Settings',
'description' => 'Configure My Site plugin',
'icon' => 'icon-cog',
'class' => \MyCompany\MySite\Models\Settings::class,
'order' => 500,
],
];
}
public function boot(): void
{
// Підписка на події
\Event::listen('cms.page.beforeDisplay', function ($controller, $url, $page) {
// Логіка перед рендером сторінки
});
}
}
Модель з Eloquent
// models/Review.php
namespace MyCompany\MySite\Models;
use Model;
class Review extends Model
{
use \October\Rain\Database\Traits\Validation;
use \October\Rain\Database\Traits\SoftDelete;
public $table = 'mycompany_mysite_reviews';
public $rules = [
'author_name' => 'required|string|max:255',
'email' => 'required|email',
'rating' => 'required|integer|between:1,5',
'body' => 'required|string|min:10',
];
protected $fillable = ['author_name', 'email', 'rating', 'body', 'is_approved'];
protected $casts = [
'is_approved' => 'boolean',
'rating' => 'integer',
];
public $attachOne = [
'avatar' => \System\Models\File::class,
];
public $belongsTo = [
'product' => [\MyCompany\MySite\Models\Product::class],
];
public function scopeApproved($query)
{
return $query->where('is_approved', true);
}
public function scopeByProduct($query, int $productId)
{
return $query->where('product_id', $productId);
}
}
Компонент
// components/ReviewList.php
namespace MyCompany\MySite\Components;
use Cms\Classes\ComponentBase;
use MyCompany\MySite\Models\Review;
class ReviewList extends ComponentBase
{
public function componentDetails(): array
{
return [
'name' => 'Review List',
'description' => 'Displays product reviews',
];
}
public function defineProperties(): array
{
return [
'productId' => ['title' => 'Product ID', 'type' => 'string'],
'limit' => ['title' => 'Limit', 'type' => 'string', 'default' => '10'],
];
}
public function onRun(): void
{
$this->page['reviews'] = Review::approved()
->byProduct((int) $this->property('productId'))
->with('avatar')
->orderBy('created_at', 'desc')
->limit((int) $this->property('limit'))
->get();
$this->page['avgRating'] = Review::approved()
->byProduct((int) $this->property('productId'))
->avg('rating');
}
public function onSubmitReview(): array
{
$data = post();
$review = new Review($data);
$review->product_id = $this->property('productId');
if (!$review->save()) {
throw new \ValidationException($review);
}
return ['success' => true];
}
}
Міграція
// updates/1_0_1_create_reviews_table.php
use October\Rain\Database\Schema\Blueprint;
use October\Rain\Database\Updates\Migration;
class CreateReviewsTable extends Migration
{
public function up(): void
{
Schema::create('mycompany_mysite_reviews', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned()->index();
$table->string('author_name');
$table->string('email');
$table->tinyInteger('rating');
$table->text('body');
$table->boolean('is_approved')->default(false);
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('mycompany_mysite_reviews');
}
}
Розробка плагіну з 1–2 моделями, компонентами та backend-інтерфейсом займає 3–7 днів.







