feat(Core): add optimize and complete code

This commit is contained in:
2026-05-17 20:05:15 +03:30
parent aa944bf339
commit 4e60b7efdd
25 changed files with 858 additions and 54 deletions

View File

@@ -146,6 +146,15 @@ add_action('admin_menu', function() use ($adminController) {
[$adminController, 'addRulePage']
);
add_submenu_page(
'sodino-dashboard',
__('قالب‌های آماده', 'sodino'),
__('قالب‌های آماده', 'sodino'),
'manage_options',
'sodino-templates',
[$adminController, 'templatesPage']
);
add_submenu_page(
'sodino-dashboard',
__('آپسل (پیشنهاد فروش)', 'sodino'),
@@ -247,8 +256,8 @@ add_action('admin_enqueue_scripts', function($hook) {
* Handle admin actions
*/
add_action('admin_init', function() use ($ruleController, $settingsController, $adminController) {
$page = $_GET['page'] ?? '';
$action = $_GET['action'] ?? '';
$page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
$action = isset($_GET['action']) ? sanitize_key(wp_unslash($_GET['action'])) : '';
// Rule actions
if ($page === 'sodino-rules' && $action === 'delete') {

View File

@@ -131,6 +131,10 @@ class Sodino_Banner_List_Table extends WP_List_Table {
public function process_bulk_action() {
if ('delete' === $this->current_action()) {
if (!current_user_can('manage_options')) {
return;
}
$banner_ids = isset($_POST['banner_ids']) ? array_map('intval', $_POST['banner_ids']) : [];
if (!empty($banner_ids) && check_admin_referer('bulk-' . $this->_args['plural'])) {
foreach ($banner_ids as $id) {

View File

@@ -85,6 +85,9 @@ class Sodino_Rules_List_Table extends WP_List_Table {
'cart_contains_category' => __('سبد شامل دسته‌بندی', 'sodino'),
'customer_order_count_min' => __('حداقل سفارش مشتری', 'sodino'),
'customer_order_count_max' => __('حداکثر سفارش مشتری', 'sodino'),
'customer_days_since_last_order_min' => __('حداقل روز از آخرین سفارش', 'sodino'),
'product_total_sales_max' => __('حداکثر فروش کل محصول', 'sodino'),
'product_total_sales_min' => __('حداقل فروش کل محصول', 'sodino'),
'day_of_week' => __('روز هفته', 'sodino'),
];
}
@@ -171,6 +174,10 @@ class Sodino_Rules_List_Table extends WP_List_Table {
public function process_bulk_action() {
if ('delete' === $this->current_action()) {
if (!current_user_can('manage_options')) {
return;
}
$rule_ids = isset($_POST['rule_ids']) ? array_map('intval', $_POST['rule_ids']) : [];
if (!empty($rule_ids) && check_admin_referer('bulk-' . $this->_args['plural'])) {
foreach ($rule_ids as $id) {

View File

@@ -144,6 +144,10 @@ class Sodino_Upsell_List_Table extends WP_List_Table {
public function process_bulk_action() {
if ('delete' === $this->current_action()) {
if (!current_user_can('manage_options')) {
return;
}
$upsell_ids = isset($_POST['upsell_ids']) ? array_map('intval', $_POST['upsell_ids']) : [];
if (!empty($upsell_ids) && check_admin_referer('bulk-' . $this->_args['plural'])) {
foreach ($upsell_ids as $id) {

View File

@@ -9,6 +9,7 @@ $menu_items = [
'sodino-dashboard' => __('داشبورد', 'sodino'),
'sodino-rules' => __('قوانین', 'sodino'),
'sodino-add-rule' => __('افزودن قانون', 'sodino'),
'sodino-templates' => __('قالب‌های آماده', 'sodino'),
'sodino-upsells' => __('آپسل (پیشنهاد فروش)', 'sodino'),
'sodino-add-upsell' => __('افزودن آپسل', 'sodino'),
'sodino-banners' => __('بنرهای هوشمند', 'sodino'),

View File

@@ -26,6 +26,9 @@ $condition_value = $condition['value'] ?? '';
<option value="cart_contains_category" <?php selected($condition_type, 'cart_contains_category'); ?>><?php _e('سبد شامل دسته‌بندی', 'sodino'); ?></option>
<option value="customer_order_count_min" <?php selected($condition_type, 'customer_order_count_min'); ?>><?php _e('حداقل سفارش مشتری', 'sodino'); ?></option>
<option value="customer_order_count_max" <?php selected($condition_type, 'customer_order_count_max'); ?>><?php _e('حداکثر سفارش مشتری', 'sodino'); ?></option>
<option value="customer_days_since_last_order_min" <?php selected($condition_type, 'customer_days_since_last_order_min'); ?>><?php _e('حداقل روز از آخرین سفارش', 'sodino'); ?></option>
<option value="product_total_sales_max" <?php selected($condition_type, 'product_total_sales_max'); ?>><?php _e('حداکثر فروش کل محصول', 'sodino'); ?></option>
<option value="product_total_sales_min" <?php selected($condition_type, 'product_total_sales_min'); ?>><?php _e('حداقل فروش کل محصول', 'sodino'); ?></option>
<option value="day_of_week" <?php selected($condition_type, 'day_of_week'); ?>><?php _e('روز هفته', 'sodino'); ?></option>
</select>
</div>

View File

@@ -49,6 +49,13 @@ $weekdays = [
</div>
</div>
<?php if (!empty($selectedTemplate)) : ?>
<div class="mb-6 rounded-lg border border-blue-200 bg-blue-50 p-4 text-sm text-blue-800">
<strong><?php echo esc_html(sprintf(__('قالب انتخاب‌شده: %s', 'sodino'), $selectedTemplate['title'])); ?></strong>
<p class="mt-1"><?php _e('شرط‌ها و عملیات پیشنهادی آماده شده‌اند. قبل از ذخیره، مقدار تخفیف و محدودیت‌ها را با سیاست فروشگاه هماهنگ کنید.', 'sodino'); ?></p>
</div>
<?php endif; ?>
<form method="post" class="space-y-6" id="sodino-rule-form">
<?php wp_nonce_field('sodino_save_rule', 'sodino_rule_nonce'); ?>

View File

@@ -81,6 +81,7 @@ $current_page = sanitize_text_field($_GET['page'] ?? 'sodino-rules');
<!-- Rules Table -->
<div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
<form method="post">
<?php wp_nonce_field('bulk-sodino_rules'); ?>
<?php $rulesTable->display(); ?>
</form>
</div>

80
admin/views/templates.php Normal file
View File

@@ -0,0 +1,80 @@
<?php
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
$current_page = 'sodino-templates';
require_once SODINO_PLUGIN_DIR . 'admin/components/layout.php';
sodino_admin_layout($current_page, function() use ($ruleTemplates, $upsellTemplates) {
?>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-8">
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
<div>
<h2 class="text-2xl font-semibold text-gray-900"><?php _e('قالب‌های آماده فروش', 'sodino'); ?></h2>
<p class="mt-2 text-gray-600"><?php _e('یک سناریوی آماده را انتخاب کنید؛ فرم مربوط با شرط‌ها و عملیات پیشنهادی پر می‌شود.', 'sodino'); ?></p>
</div>
</div>
</div>
<section class="mb-8">
<div class="mb-4">
<h3 class="text-lg font-semibold text-gray-900"><?php _e('قالب‌های قوانین قیمت‌گذاری', 'sodino'); ?></h3>
<p class="mt-1 text-sm text-gray-500"><?php _e('بعد از انتخاب قالب، مقدارها را مطابق استراتژی فروشگاه تنظیم و ذخیره کنید.', 'sodino'); ?></p>
</div>
<div class="grid gap-4 lg:grid-cols-2">
<?php foreach ($ruleTemplates as $key => $template) : ?>
<article class="bg-white rounded-lg border border-gray-200 p-5 shadow-sm">
<div class="flex h-full flex-col justify-between gap-5">
<div>
<h4 class="text-base font-semibold text-gray-900"><?php echo esc_html($template['title']); ?></h4>
<p class="mt-2 text-sm leading-6 text-gray-600"><?php echo esc_html($template['description']); ?></p>
<div class="mt-4 flex flex-wrap gap-2">
<?php foreach ((array) $template['actions'] as $action) : ?>
<span class="rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700">
<?php echo esc_html(sprintf('%s: %s', $action['type'], $action['value'])); ?>
</span>
<?php endforeach; ?>
</div>
</div>
<a href="<?php echo esc_url(admin_url('admin.php?page=sodino-add-rule&template=' . $key)); ?>" class="inline-flex items-center justify-center rounded-lg bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-700">
<?php _e('استفاده از قالب', 'sodino'); ?>
</a>
</div>
</article>
<?php endforeach; ?>
</div>
</section>
<section>
<div class="mb-4">
<h3 class="text-lg font-semibold text-gray-900"><?php _e('قالب‌های آپسل', 'sodino'); ?></h3>
<p class="mt-1 text-sm text-gray-500"><?php _e('برای پیشنهاد محصول مکمل، محصول فعال‌ساز و محصول پیشنهادی را در فرم انتخاب کنید.', 'sodino'); ?></p>
</div>
<div class="grid gap-4 lg:grid-cols-2">
<?php foreach ($upsellTemplates as $key => $template) : ?>
<article class="bg-white rounded-lg border border-gray-200 p-5 shadow-sm">
<div class="flex h-full flex-col justify-between gap-5">
<div>
<h4 class="text-base font-semibold text-gray-900"><?php echo esc_html($template['title']); ?></h4>
<p class="mt-2 text-sm leading-6 text-gray-600"><?php echo esc_html($template['description']); ?></p>
<div class="mt-4 flex flex-wrap gap-2">
<span class="rounded-full bg-emerald-50 px-3 py-1 text-xs font-medium text-emerald-700">
<?php echo esc_html(sprintf(__('تخفیف پیش‌فرض: %s%%', 'sodino'), $template['discount_value'])); ?>
</span>
</div>
</div>
<a href="<?php echo esc_url(admin_url('admin.php?page=sodino-add-upsell&template=' . $key)); ?>" class="inline-flex items-center justify-center rounded-lg bg-emerald-600 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-700">
<?php _e('ساخت آپسل از قالب', 'sodino'); ?>
</a>
</div>
</article>
<?php endforeach; ?>
</div>
</section>
<?php
});
?>

View File

@@ -92,6 +92,13 @@ $product_categories = get_terms([
</div>
</div>
<?php if (!empty($selectedTemplate)) : ?>
<div class="mb-6 rounded-lg border border-emerald-200 bg-emerald-50 p-4 text-sm text-emerald-800">
<strong><?php echo esc_html(sprintf(__('قالب انتخاب‌شده: %s', 'sodino'), $selectedTemplate['title'])); ?></strong>
<p class="mt-1"><?php _e('ساختار آپسل آماده شده است. محصول فعال‌ساز و محصول پیشنهادی را انتخاب کنید و سپس ذخیره کنید.', 'sodino'); ?></p>
</div>
<?php endif; ?>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<form method="post" class="space-y-6">
<?php wp_nonce_field('sodino_save_upsell', 'sodino_upsell_nonce'); ?>

View File

@@ -76,6 +76,7 @@ $current_page = sanitize_text_field($_GET['page'] ?? 'sodino-upsells');
<div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
<form method="post">
<?php wp_nonce_field('bulk-sodino_upsells'); ?>
<?php $upsellTable->display(); ?>
</form>
</div>