بناء تطبيق

تشريح البلاجن: المانيفست، البروڤايدر، الراوتس، الميجريشنز، القوالب، الترجمة.

تشريح البلاجن

البلاجن مجلد مستقل تحت plugins/{your-slug}/. مفيش أي حاجة فيه بتلمس نواة المنصة — النواة تكتشفه، تحمّل ميجريشنزه، وتُقلع سيرفس بروڤايدره تلقائيًا.

plugins/product-compare/
├── plugin.json                     # المانيفست (الهوية، البروڤايدر، الصلاحيات)
├── img.png                         # أيقونة السوق
├── database/migrations/            # جداولك أنت فقط
├── resources/
│   ├── assets/{css,js}/            # أصول متجر مُجمّعة
│   ├── lang/{en,ar}/ui.php         # ترجمات (اللغتين دائمًا)
│   └── views/                      # قوالب blade
└── src/
    ├── ProductCompareServiceProvider.php
    ├── Http/Controllers/
    ├── Models/
    └── Services/

المانيفست — plugin.json

المانيفست هو المصدر الوحيد لهوية بلاجنك وإيه المسموح له يعمله. مثال حقيقي مبسّط:

{
    "slug": "product-compare",
    "name":        { "en": "Product Compare", "ar": "مقارنة المنتجات" },
    "description": { "en": "Compare products side by side…", "ar": "قارن المنتجات جنبًا إلى جنب…" },
    "version": "1.0.0",
    "author": "اسمك",
    "provider": "ProductCompareServiceProvider",
    "type": "general",
    "target": "user",
    "is_system": false,
    "icon": "columns",
    "features": {
        "en": ["Side-by-side comparison", "Compare button on product cards"],
        "ar": ["مقارنة جنبًا إلى جنب", "زر مقارنة على بطاقات المنتجات"]
    }
}

الحقول المهمة:

  • slug — لازم يطابق اسم المجلد، kebab-case. هو اللي بيقود الـPSR-4 autoloader.
  • provider — اسم كلاس السيرفس بروڤايدر داخل Plugins\{StudlySlug\}. النواة تحلّ Plugins\ProductCompare\ProductCompareServiceProvider من "provider": "ProductCompareServiceProvider".
  • typegeneral, platform، إلخ. targetuser, admin, both، أو متجر.
  • permissions — قائمة القدرات اللي الماسح يفرضها (راجع الأمان والمراجعة).

إزاي النواة بتحمّلك

App\Providers\PluginServiceProvider بيعمل ٣ حاجات عند الإقلاع، فبتاخدهم مجانًا:

  1. التحميل التلقائي. أي كلاس Plugins\StudlySlug\... يتحلّ لـplugins/{slug}/src/...php. بس سمّي كلاساتك بالـnamespace Plugins\YourSlug\....
  2. الميجريشنز. كل مجلد plugins/*/database/migrations يتسجّل تلقائيًا — جداولك تتهاجر مع المنصة.
  3. الإقلاع. لكل بلاجن مُفعّل، النواة تقرأ plugin.json، تلاقي provider، وتسجّله.

إنت أبدًا ما بتسجّل بلاجنك يدويًا — بتشحن المجلد، والأدمن يفعّله.

السيرفس بروڤايدر

البروڤايدر بتاعك هو مكان توصيل كل حاجة في boot(). حمّل views وترجمات وميجريشنز بتاعتك، وبعدين سجّل الراوتس والـsidebar والإعدادات والـobservers والمهام المجدولة. النمط ماخوذ من بلاجن حقيقي:

namespace Plugins\ProductCompare;

use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;

class ProductCompareServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        $this->loadMigrationsFrom(dirname(__DIR__).'/database/migrations');
        $this->loadViewsFrom(dirname(__DIR__).'/resources/views', 'product-compare');
        $this->loadTranslationsFrom(dirname(__DIR__).'/resources/lang', 'product-compare');

        $this->registerRoutes();
        $this->registerSidebarItem();
    }

    private function registerRoutes(): void
    {
        Route::middleware(['web', 'auth', 'verified', 'user', 'store.setup', 'plugin.access:product-compare'])
            ->prefix('user/product-compare')
            ->name('product-compare.')
            ->group(function (): void {
                Route::get('/', [CompareMerchantController::class, 'index'])->name('index');
            });
    }
}

لاحظ ميدل‌وير plugin.access:{slug} — بيقصر الراوت على التجار اللي فعلاً مفعّلين بلاجنك.

الميجريشنز — جداولك أنت فقط

اعمل جداول مسمّاة على بلاجنك (مثلاً product_compares, pc_*). ما تعدّلش جدول نواة أبدًا. لو محتاج تربط بيانات بمتجر، اربط على user_id / store_id واقصر كل استعلام على التاجر الحالي.

القوالب والأصول والترجمة

  • استدعِ قوالبك بالـnamespace اللي سجّلته: view('product-compare::merchant.index').
  • اشحن CSS/JS مُجمّع تحت resources/assets/ — لا سكربتات CDN، ولا @php في Blade.
  • الترجمات إلزامية في en وar. كل نص __('...') يظهر للمستخدم محتاج مفتاح في اللغتين. المتجر لازم يرندر RTL نظيف.

إضافات للتاجر

البلاجن الحقيقي عادةً يسجّل:

  • عنصر sidebar عبر App\Services\SidebarRegistry عشان التاجر يلاقي صفحتك.
  • إعدادات البلاجن عبر App\Services\PluginSettingsRegistry لشاشة إعدادات لكل بلاجن.
  • Observers (Model::observe(...)) أو مهام مجدولة ($schedule->command(...)->daily()) — افتكر تعلن eloquent_observer / schedule في المانيفست.

ودجت المتجر

عشان ترندر على المتجر، أعلن storefront_widget واعرض partial بـBlade (مثلاً زر قارن يتحقن في بطاقات المنتجات). خليه مبني على متغيرات ألوان الثيم --sf-* عشان يبان أصلي في كل ثيم (راجع بناء ثيم).