نحوه ثبت ویجتهای سفارشی که در داشبورد اصلی CRM نمایش داده میشوند.
مرور کلی
فیلتر `la24_widgets` ویجتهای سفارشی را برای داشبورد اصلی CRM ثبت میکند. ادمین میتواند ویجتها را از طریق رابط داشبورد (یک گرید مبتنی بر Gridster) اضافه، حذف و مرتبسازی کند. هر کلاس ویجت **باید** از کلاس انتزاعی `\LoyalAxis\classes\services\widgets\Widget` که در `includes/classes/services/widgets/Widget.php` تعریف شده ارثبری کند — LA24Core کلاس شما را بهصورت `new $callback( $widget_id, $params )` نمونهسازی کرده و متدهای چرخه حیات آن را مستقیماً فرا میخواند، بنابراین یک کلاس ساده که از این کلاس پایه ارثبری نکند با خطای Fatal مواجه میشود.

امضای هوک
php
apply_filters( 'la24_widgets', array $widgets );**نوع:** Filter
**پارامترها:** `$widgets` (آرایه) — رجیستری ویجتهای فعلی
**بازگشتی:** آرایه — رجیستری ویجتهای تغییریافته
> **نکته:** برای خواندن رجیستری، مستقیماً `apply_filters( 'la24_widgets', ... )` را فراخوانی نکنید. بهجای آن از `la24_get_widget_items()` (`includes/helpers/la24-core-functions.php`) استفاده کنید — این تابع هم فیلتر را اعمال میکند و هم هر ویجت را نرمالایز میکند (آیکون پیشفرض و fallback دستهبندی که در ادامه توضیح داده شده را اختصاص میدهد) پیش از بازگرداندن آرایه. این همان چیزی است که هم کنترلرهای داشبورد و هم مودال «افزودن ویجت» از آن استفاده میکنند.
ثبت یک ویجت
php
add_filter( 'la24_widgets', function ( $widgets ) {
$widgets['900'] = array(
'name' => __( 'خلاصه CRM من', 'my-crm-ext' ),
'class_icon' => 'fa fa-pie-chart',
'category' => array( 'reporting' ),
'callback' => '\MyPlugin\Widgets\CrmSummaryWidget',
);
return $widgets;
} );فیلدهای ویجت
| فیلد | نوع | توضیح |
|---|---|---|
| کلید (کلید آرایه) | string | شناسه عددی منحصربهفرد ویجت (قراردادهای شناسه را ببینید) |
| `name` | string | نام نمایشی ویجت در انتخابگر ویجت داشبورد |
| `class_icon` | string | *اختیاری.* کلاس FontAwesome برای آیکون ویجت. در صورت عدم تعیین، `la24_get_widget_items()` یک آیکون پیشفرض (`fas fa-th-large`) اختصاص میدهد. |
| `category` | string\ | array |
| `callback` | string | نام کامل کلاس ویجت (با namespace)؛ باید از `Widget` ارثبری کند |
دستهبندیهای ویجت
ویجتها میتوانند یک یا چند برچسب دستهبندی تعریف کنند تا در مودال «افزودن ویجت به داشبورد» قابل جستوجو و فیلتر باشند. دستهبندیها توسط `la24_get_widget_items()` — همان تابعی که تمام کنترلرها و تمپلیت مودال برای خواندن رجیستری استفاده میکنند — نرمالایز (و در صورت نیاز پیشفرضگذاری) میشوند، بنابراین شما هرگز نیازی به مدیریت دستی fallback ندارید.
php
function la24_get_widget_categories(); // includes/helpers/la24-core-functions.phpاین تابع طبقهبندی ثابت مورد استفاده در سراسر LA24Core را برمیگرداند:
| Slug | برچسب | آیکون |
|---|---|---|
| `administrative` | ویجتهای مدیریتی | `fas fa-user-shield` |
| `woocommerce_panel` | پنل کاربری ووکامرس | `fas fa-shopping-cart` |
| `operational` | عملیاتی | `fas fa-cogs` |
| `reporting` | گزارشگیری | `fas fa-chart-line` |
| `general` | عمومی | `fas fa-th-large` |
یک یا چند برچسب را روی ویجت خود تعریف کنید:
php
$widgets['900'] = array(
'name' => __( 'خلاصه CRM من', 'my-crm-ext' ),
'class_icon' => 'fa fa-pie-chart',
'category' => array( 'reporting' ),
'callback' => '\MyPlugin\Widgets\CrmSummaryWidget',
);- هر برچسبی که ارائه دهید و در فهرست بالا نباشد، بهطور خاموش نادیده گرفته میشود.
- اگر `category` تعیین نشود یا هیچکدام از برچسبهای ارائهشده شناختهشده نباشند، ویجت بهطور پیشفرض در دسته `general` قرار میگیرد.
- این طبقهبندی ثابت است — هیچ فیلتری برای افزودن دستهبندی سفارشی وجود ندارد. اگر افزونه شما در هیچکدام از این برچسبها جا نمیشود، `general` انتخاب مناسبی است.
قراردادهای شناسه ویجت
کلیدهای آرایه ویجت، رشتههای عددی هستند. ماژولهای داخلی خود LA24Core، شناسههایی از `100` تا نزدیک `800` را اشغال کردهاند (مثلاً `100` برای ویجت داخلی دکمه لینک، `101` تا `110` برای UMS/Office/Voip، `200` تا `206` برای گزارشها، `301` تا `306` برای پنل کاربری ووکامرس، `401`/`402` برای اعلانها، `600` تا `604` برای گزارشهای ووکامرس، `702` برای تحلیل شکست فرصت فروش).
- **ویجتهای افزونههای سفارشی و شخصثالث باید از شناسه عددی `900` یا بالاتر استفاده کنند** (مثلاً `'900'`، `'901'`، `'9001'`) تا هرگز با شناسهای که در نسخههای آینده LA24Core به هسته اضافه میشود تداخل نداشته باشند.
- کلید را با یک رشته پیشوندی نسازید (`'my_plugin_201'`) — کلید باید همان شناسه عددی خالص باشد، زیرا دقیقاً به همین شکل در دادههای سریالایزشده چیدمان داشبورد ذخیره شده و از طریق `la24_get_widget_items()[$id]` جستوجو میشود.
php
// درست
$widgets['900'] = array( ... );
$widgets['901'] = array( ... );
// از این اجتناب کنید — پایینتر از بازه رزرو شده برای افزونههای سفارشی، ممکن است با یک ویجت هسته تداخل داشته باشد
$widgets['201'] = array( ... );
// از این اجتناب کنید — کلید باید عددی باشد، نه یک رشته با پیشوند
$widgets['my_deals_900'] = array( ... );کلاس پایه Widget
فایل `includes/classes/services/widgets/Widget.php` قراردادی را تعریف میکند که هر کلاس ویجت باید رعایت کند. یک کلاس ویجت واقعی باید تمام اعضای انتزاعی زیر را پیادهسازی کند:
| عضو | امضا | هدف |
|---|---|---|
| `content()` | `public function content( $settings )` | خروجی HTML ویجت را echo میکند |
| `desktop_size()` | `public static function desktop_size()` | مقادیر `size_x`/`size_y`/`minx`/`miny`/`maxx`/`maxy` را برای گرید دسکتاپ برمیگرداند |
| `mobile_size()` | `public static function mobile_size()` | مشابه بالا، برای گرید موبایل |
| `default_settings()` | `public function default_settings(): array` | آرایه تنظیمات پیشفرض را برمیگرداند (کلیدهایی که ذخیره میشوند را نیز مشخص میکند) |
| `widget_title()` | `public function widget_title()` | عنوانی که در هدر/تمپلیت ویجت نمایش داده میشود را برمیگرداند |
| `widget_bg_color()` | `public function widget_bg_color()` | رنگ پسزمینهای که تمپلیت مشترک ویجت استفاده میکند را برمیگرداند |
| `style_settings()` | `public function style_settings( $settings )` | تب «Style» فرم تنظیمات ویجت را echo میکند |
| `master_settings()` | `public function master_settings( $settings )` | تب «مدیریت» فرم تنظیمات ویجت را echo میکند |
کلاس پایه از قبل موارد زیر را مدیریت میکند: سازنده (`$widget_id`، `uniq_id`، `tab`، `type`، `device`، `user_id`)، بارگذاری/ادغام تنظیمات ذخیرهشده از طریق `get_settings()`، ذخیره تنظیمات از طریق `save_Settings()`، بررسی دسترسیها (`la24_view_widget_{id}`، `la24_setting_admin_widget_{id}`)، و رندر پوسته مشترک ویجت (`template()`) مگر اینکه `use_template()` را override کرده و `false` برگردانید.
نوشتن یک کلاس ویجت
از ویجت داخلی `Simple_Button` (`includes/classes/services/widgets/Simple_Button.php`، ثبتشده با شناسه هستهای `100`) بهعنوان پیادهسازی مرجع استفاده کنید:
php
<?php
namespace MyPlugin\Widgets;
defined( 'ABSPATH' ) || exit;
use LoyalAxis\classes\services\widgets\Widget;
use LoyalAxis\classes\utilities\Form;
class CrmSummaryWidget extends Widget {
public function content( $settings ) {
global $wpdb;
$total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}my_crm_records" );
echo "<div class='small-box' style='box-shadow: none !important;'>
<div class='inner'>
<h3 style='color: {$settings['text_color_900']};'>
<span style=\"font-size: 20px;\">" . esc_html( $total ) . "</span>
</h3>
<p>" . esc_html__( 'تعداد کل رکوردها', 'my-crm-ext' ) . "</p>
</div>
</div>";
}
public static function desktop_size() {
return array(
'size_x' => 3, 'size_y' => 1,
'minx' => 1, 'miny' => 1,
'maxx' => 6, 'maxy' => 12,
);
}
public static function mobile_size() {
return array(
'size_x' => 2, 'size_y' => 1,
'minx' => 1, 'miny' => 1,
'maxx' => 2, 'maxy' => 6,
);
}
public function default_settings(): array {
return array(
'head_text_900' => __( 'خلاصه CRM', 'my-crm-ext' ),
'text_color_900' => 'rgba(0,0,0,1)',
);
}
public function widget_title() {
return $this->settings['head_text_900'] ?? '';
}
public function widget_bg_color() {
return 'rgba(255,255,255,1)';
}
public function style_settings( $settings ) {
echo Form::start_form( 0, 'la24-section-box' );
echo Form::header( __( 'تنظیمات ظاهری:', 'my-crm-ext' ), 12, 'la24-titr' );
echo Form::color_picker( __( 'رنگ متن', 'my-crm-ext' ), 6, 'text_color_900', 'text_color_900', 'center', $settings['text_color_900'], 0, '' );
echo Form::close_form();
}
public function master_settings( $settings ) {
echo Form::start_form( 0, 'la24-section-box' );
echo Form::header( __( 'تنظیمات مدیریتی:', 'my-crm-ext' ), 12, 'la24-titr' );
echo Form::text_input( __( 'عنوان', 'my-crm-ext' ), 6, 'head_text_900', 'head_text_900', '', $settings['head_text_900'], '', 0 );
echo Form::close_form();
}
}آن را با شناسهای `900` یا بالاتر ثبت کنید، همانطور که در بخش [ثبت یک ویجت](#ثبت-یک-ویجت) نشان داده شد.

فرمهای تنظیمات
هر دو متد `style_settings()` و `master_settings()` آرایه `$settings` فعلی ویجت را دریافت کرده و انتظار میرود فرمی ساختهشده با کمککننده `\LoyalAxis\classes\utilities\Form` (`includes/classes/utilities/Form.php`) را `echo` کنند — همان کمککنندهای که در سراسر صفحات مدیریت LA24Core استفاده میشود. بلوکهای رایج: `Form::start_form()`، `Form::header()`، `Form::text_input()`، `Form::checkbox()`، `Form::color_picker()`، `Form::close_form()`. نام/شناسه فیلدهایی که به این کمککنندهها میدهید باید با کلیدهای بازگرداندهشده از `default_settings()` مطابقت داشته باشد، زیرا `Widget::save_Settings()` مقادیر ارسالی را با پیمایش همان کلیدها میخواند.
Query های پایگاهداده در ویجتها
ویجتها در هر بارگذاری صفحه داشبورد اجرا میشوند، پس query های داخل `content()` را بهینه نگه دارید:
php
public function content( $settings ) {
global $wpdb;
// از get_var برای مقادیر تکی استفاده کنید
$total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}my_table" );
// از get_results برای آمار گروهبندیشده استفاده کنید
$stats = $wpdb->get_results(
"SELECT status, COUNT(*) as total FROM {$wpdb->prefix}my_table GROUP BY status"
);
}از JOIN های سنگین یا full-table scan در `content()` خودداری کنید. در صورت نیاز از WordPress transient ها برای cache کردن نتایج استفاده کنید.