PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.9
ووسلام – همگام سازی ووکامرس و باسلام v1.10.9
1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 1.8.6 All 53 releases
sync-basalam / includes / Registrar / AdminRegistrar.php

AdminRegistrar.php in ووسلام – همگام سازی ووکامرس و باسلام 1.10.9, at includes/Registrar/AdminRegistrar.php

503 lines 19.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SyncBasalam\Registrar;
4
5 use SyncBasalam\Actions\RegisterActions;
6 use SyncBasalam\Admin\Pages;
7 use SyncBasalam\Registrar\Contracts\RegistrarInterface;
8 use SyncBasalam\Admin\Product\elements\ProductList\StatusColumn;
9 use SyncBasalam\Admin\Product\elements\ProductList\MetaBox;
10 use SyncBasalam\Admin\Product\elements\ProductList\BulkEdit;
11 use SyncBasalam\Admin\Product\elements\SingleProduct\Tab;
12 use SyncBasalam\Admin\Product\elements\SingleProduct\VideoField;
13 use SyncBasalam\Admin\Product\elements\ProductList\Filter;
14 use SyncBasalam\Admin\Product\elements\ProductList\Actions;
15 use SyncBasalam\Admin\Order\OrderColumn;
16 use SyncBasalam\Admin\Order\OrderMetaBox;
17 use SyncBasalam\Admin\Components\OrderPageComponents;
18 use SyncBasalam\Admin\Order\OrderStatuses;
19 use SyncBasalam\Admin\Product\Operations\ConnectProduct;
20 use SyncBasalam\Admin\Announcement\AnnouncementCenter;
21 use SyncBasalam\Admin\Onboarding\PointerTour;
22 use SyncBasalam\Services\Products\DuplicateConnectionReport;
23 use SyncBasalam\Services\Products\ProductConnection;
24 use SyncBasalam\Services\SystemResourceMonitor;
25 use SyncBasalam\Utilities\ProductMetaKey;
26 use SyncBasalam\Utilities\ChatWidget;
27 use SyncBasalam\Utilities\TicketFlashNotice;
28 use SyncBasalam\Admin\Settings\SettingsPageHandler;
29 use SyncBasalam\Admin\FinancialManagement\Menu as FinancialManagementMenu;
30 use SyncBasalam\Admin\FinancialManagement\BalanceSettlement;
31 use SyncBasalam\Admin\FinancialManagement\FinancialManagementHistory;
32
33 defined("ABSPATH") || exit;
34
35 class AdminRegistrar implements RegistrarInterface
36 {
37 public static function register(): void
38 {
39 $container = syncBasalamContainer();
40 $pages = $container->get(Pages::class);
41 $filter = $container->get(Filter::class);
42 $orderColumn = $container->get(OrderColumn::class);
43 $orderMetaBox = $container->get(OrderMetaBox::class);
44 $orderStatuses = $container->get(OrderStatuses::class);
45 $actions = $container->get(Actions::class);
46 $bulkEdit = $container->get(BulkEdit::class);
47
48 // Initialize Admin Actions
49 $container->get(RegisterActions::class);
50
51 // Admin Menu
52 \add_action("admin_menu", [$pages, "registerMenus"]);
53 \add_filter("script_loader_tag", [ChatWidget::class, "addTokenToWidgetScript"], 10, 3);
54
55 // Admin Scripts & Styles
56 \add_action("admin_enqueue_scripts", [self::class, "adminEnqueueStyles"]);
57 \add_action("admin_enqueue_scripts", [self::class, "adminEnqueueScripts"]);
58 \add_action("admin_enqueue_scripts", [self::class, "financialManagementEnqueueAssets"]);
59 \add_action("admin_footer", [AnnouncementCenter::class, 'renderPanel']);
60
61 // Financial Management (�
62 دیریت �
63 الی)
64 FinancialManagementHistory::register();
65 BalanceSettlement::register();
66
67 // Product Columns
68 \add_filter("manage_edit-product_columns", [StatusColumn::class, "registerStatusColumn"]);
69 \add_action("manage_product_posts_custom_column", [StatusColumn::class, "renderStatusColumnContent"], 10, 2);
70
71 // Product Meta Boxes
72 \add_action("add_meta_boxes_product", [MetaBox::class, "registerMetaBox"]);
73
74 // Basalam Product Settings Tab
75 \add_filter('woocommerce_product_data_tabs', [Tab::class, 'registerTab']);
76 \add_action('woocommerce_product_data_panels', [Tab::class, 'renderTabContent']);
77 \add_action('woocommerce_process_product_meta', [Tab::class, 'saveTabData']);
78
79 // Basalam Product Video Meta Box (sidebar, like product image/gallery)
80 \add_action('add_meta_boxes_product', [VideoField::class, 'registerMetaBox']);
81 \add_action('woocommerce_process_product_meta', [VideoField::class, 'save']);
82
83 // Product Filter
84 \add_action("restrict_manage_posts", [$filter, "renderFilterDropdown"]);
85 \add_action("pre_get_posts", [$filter, "applyFilterToQuery"]);
86
87 // Order Columns (HPOS)
88 \add_action("manage_woocommerce_page_wc-orders_custom_column", [$orderColumn, "renderColumn"], 10, 2);
89 \add_filter("manage_woocommerce_page_wc-orders_columns", [$orderColumn, "addColumn"]);
90
91 // Order Columns (Traditional CPT - non-HPOS)
92 \add_action("manage_shop_order_posts_custom_column", [$orderColumn, "renderColumn"], 10, 2);
93 \add_filter("manage_edit-shop_order_columns", [$orderColumn, "addColumn"]);
94
95 // Order Meta Boxes
96 \add_action("add_meta_boxes", [$orderMetaBox, "registerMetaBox"], 10);
97
98 // Order Meta Boxes (Traditional CPT - non-HPOS)
99 \add_action("add_meta_boxes_shop_order", [$orderMetaBox, "registerMetaBox"], 10);
100
101 // Order Statuses
102 \add_filter("wc_order_statuses", [$orderStatuses, "registerorderStatuses"]);
103
104 // Order Stock Levels
105 \add_action("woocommerce_order_status_bslm-rejected", "wc_maybe_increase_stock_levels");
106 \add_action("woocommerce_order_status_bslm-preparation", "wc_maybe_reduce_stock_levels");
107 \add_action("woocommerce_order_status_bslm-shipping", "wc_maybe_reduce_stock_levels");
108 \add_action("woocommerce_order_status_bslm-completed", "wc_maybe_reduce_stock_levels");
109
110 // Bulk Actions
111 \add_filter("bulk_actions-edit-product", [$actions, "registerBulkActions"]);
112 \add_filter("handle_bulk_actions-edit-product", [$actions, "handleBulkAction"], 10, 3);
113 \add_action('bulk_edit_custom_box', [$bulkEdit, 'renderFields'], 10, 2);
114 \add_action('admin_action_sync_basalam_bulk_edit', [$bulkEdit, 'save']);
115
116 // Product Duplicate
117 // نسخه کپی یک �
118 حصول تازه است و نباید هیچ داده ووسلا�
119 ی از �
120 حصول اصلی به ارث ببرد؛
121 // �
122 خصوصا شناسه اتصال، وگرنه بروزرسانی نسخه کپی، �
123 حصول اصلی را در باسلا�
124 تغییر �
125 ی‌دهد.
126 \add_filter("woocommerce_duplicate_product_exclude_meta", [self::class, "excludePluginMetaFromDuplicate"], 10, 2);
127
128 \add_action("woocommerce_product_duplicate", function ($newProduct) {
129 if (!is_object($newProduct) || !method_exists($newProduct, "get_id")) return;
130
131 ProductConnection::purgeAll($newProduct->get_id());
132 }, 10, 1);
133
134 // Product Duplicate (third party plugins, e.g. Yoast Duplicate Post)
135 foreach (["dp_duplicate_post", "dp_duplicate_page", "duplicate_post_post_copy"] as $duplicateHook) {
136 \add_action($duplicateHook, function ($newPostId, $sourcePost = null) {
137 if (!is_scalar($newPostId) || \get_post_type((int) $newPostId) !== "product") return;
138
139 // اگر هوک، پست �
140 بدا را ه�
141 بدهد �
142 ط�
143 ئنی�
144 شناسه اول نسخه کپی است.
145 if (is_object($sourcePost) && !empty($sourcePost->ID) && (int) $sourcePost->ID !== (int) $newPostId) {
146 ProductConnection::purgeAll((int) $newPostId);
147
148 return;
149 }
150
151 // در غیر این صورت �
152 حافظه‌کارانه ع�
153 ل �
154 ی‌کنی�
155 تا داده �
156 حصول اصلی پاک نشود.
157 ProductConnection::purgeIfCopy((int) $newPostId);
158 }, 10, 2);
159 }
160
161 // Duplicate connection report (admin notice + dismiss handler)
162 DuplicateConnectionReport::registerHooks();
163
164 // Order Check Buttons (HPOS)
165 \add_action("woocommerce_order_list_table_extra_tablenav", [OrderPageComponents::class, "renderCheckOrdersButton"], 20, 1);
166
167 // Order Check Buttons (Traditional CPT - uses same hook as product filter)
168 \add_action("restrict_manage_posts", [OrderPageComponents::class, "renderCheckOrdersButtonTraditional"]);
169
170 // Initialize AJAX handlers
171 $connectProduct = $container->get(ConnectProduct::class);
172 add_action('wp_ajax_basalam_search_products', [$connectProduct, 'handleSearchProducts']);
173 add_action('wp_ajax_sync_basalam_mark_pointer_onboarding_completed', [PointerTour::class, 'markPointerOnboardingCompleted']);
174 add_action('wp_ajax_' . AnnouncementCenter::MARK_SEEN_ACTION, [AnnouncementCenter::class, 'markAllSeen']);
175 add_action('wp_ajax_' . AnnouncementCenter::FETCH_PAGE_ACTION, [AnnouncementCenter::class, 'fetchPage']);
176
177 // Tasks per minute calculation handler
178 add_action('wp_ajax_basalam_calculate_tasks_per_minute', function () {
179 check_ajax_referer('basalam_update_setting_nonce', 'nonce', true);
180
181 $monitor = syncBasalamContainer()->get(SystemResourceMonitor::class);
182 $optimal = $monitor->calculateOptimalTasksPerMinute();
183
184 wp_send_json_success([
185 'optimal_tasks_per_minute' => $optimal
186 ]);
187 });
188 }
189
190
191 /**
192 * حذف ه�
193 ه �
194 تاهای ووسلا�
195 از نسخه کپی، پیش از ذخیره شدن آن توسط ووکا�
196 رس.
197 * ووکا�
198 رس ه�
199 ین فهرست را روی تنوع‌های کپی شده ه�
200 اع�
201 ال �
202 ی‌کند.
203 *
204 * @param array $excludedMeta کلیدهایی که تا اینجا برای حذف انتخاب شده‌اند.
205 * @param array $productMetaKeys کلیدهای �
206 تای �
207 حصول اصلی.
208 */
209 public static function excludePluginMetaFromDuplicate($excludedMeta, $productMetaKeys = [])
210 {
211 $excludedMeta = is_array($excludedMeta) ? $excludedMeta : [];
212
213 foreach ((array) $productMetaKeys as $metaKey) {
214 if (ProductConnection::isPluginMetaKey($metaKey)) $excludedMeta[] = $metaKey;
215 }
216
217 // کلیدهای تنوع‌ها در فهرست �
218 تای �
219 حصول والد نیستند و باید دستی اضافه شوند.
220 $excludedMeta = array_merge(
221 $excludedMeta,
222 ProductMetaKey::basalamProductMetaKeys(),
223 [ProductMetaKey::basalamVariationId(), ProductMetaKey::DISCOUNTED]
224 );
225
226 return array_values(array_unique($excludedMeta));
227 }
228
229 public static function assetsUrl($path = null)
230 {
231 return plugin_dir_url(dirname(__FILE__, 2)) . "assets/" . $path;
232 }
233
234 public static function adminEnqueueStyles($hook = '')
235 {
236 $version = syncbasalamplugin()->getVersion();
237
238 wp_enqueue_style(
239 "basalam-admin-style",
240 self::assetsUrl("css/style.css"),
241 array(),
242 $version
243 );
244 wp_enqueue_style(
245 "basalam-admin-font-style",
246 self::assetsUrl("css/font.css"),
247 array(),
248 $version
249 );
250 wp_enqueue_style(
251 "basalam-admin-social-style",
252 self::assetsUrl("css/social.css"),
253 array(),
254 $version
255 );
256 wp_enqueue_style(
257 "basalam-admin-logs-style",
258 self::assetsUrl("css/logs.css"),
259 array(),
260 $version
261 );
262 wp_enqueue_style(
263 "basalam-admin-onboarding-style",
264 self::assetsUrl("css/onboarding.css"),
265 array(),
266 $version
267 );
268 wp_enqueue_style(
269 "basalam-admin-toast-style",
270 self::assetsUrl("css/toast.css"),
271 array(),
272 $version
273 );
274
275 if (PointerTour::shouldLoadPointerTour((string) $hook)) {
276 wp_enqueue_style('wp-pointer');
277 }
278 }
279
280 public static function adminEnqueueScripts($hook = '')
281 {
282 $shouldLoadPointerTour = PointerTour::shouldLoadPointerTour((string) $hook);
283 $version = syncbasalamplugin()->getVersion();
284
285 if ($shouldLoadPointerTour) {
286 wp_enqueue_script('wp-pointer');
287 }
288
289 wp_enqueue_script(
290 "basalam-admin-toast-script",
291 self::assetsUrl("js/toast.js"),
292 [],
293 $version,
294 true
295 );
296
297 $ticketNotice = TicketFlashNotice::pull();
298 if ($ticketNotice !== null) {
299 wp_add_inline_script(
300 "basalam-admin-toast-script",
301 sprintf(
302 'window.addEventListener("DOMContentLoaded",function(){if(window.BasalamToast){window.BasalamToast.show(%s,%s);}});',
303 wp_json_encode($ticketNotice['message'], JSON_UNESCAPED_UNICODE),
304 wp_json_encode($ticketNotice['type'])
305 ),
306 'after'
307 );
308 }
309
310 $settingsValidationError = SettingsPageHandler::pullValidationError();
311 if ($settingsValidationError !== '') {
312 wp_add_inline_script(
313 "basalam-admin-toast-script",
314 sprintf(
315 'window.addEventListener("DOMContentLoaded",function(){if(window.BasalamToast){window.BasalamToast.error(%s);}});',
316 wp_json_encode($settingsValidationError, JSON_UNESCAPED_UNICODE)
317 ),
318 'after'
319 );
320 }
321 wp_enqueue_script(
322 "basalam-admin-logs-script",
323 self::assetsUrl("js/logs.js"),
324 ["jquery", "basalam-admin-toast-script"],
325 $version,
326 true
327 );
328 wp_enqueue_script(
329 "basalam-admin-help-script",
330 self::assetsUrl("js/help.js"),
331 ["jquery", "basalam-admin-toast-script"],
332 $version,
333 true
334 );
335 wp_enqueue_script(
336 "basalam-admin-product-fields-script",
337 self::assetsUrl("js/product-fields.js"),
338 ["jquery", "basalam-admin-toast-script"],
339 $version,
340 true
341 );
342 wp_enqueue_script(
343 "basalam-admin-manage-box-script",
344 self::assetsUrl("js/manage-box.js"),
345 ["jquery", "basalam-admin-toast-script"],
346 $version,
347 true
348 );
349 wp_enqueue_script(
350 "basalam-admin-connect-modal-script",
351 self::assetsUrl("js/connect-modal.js"),
352 ["jquery", "basalam-admin-toast-script"],
353 $version,
354 true
355 );
356 wp_enqueue_script(
357 "basalam-round-script",
358 self::assetsUrl("js/round.js"),
359 ["jquery", "basalam-admin-toast-script"],
360 $version,
361 true
362 );
363 wp_enqueue_script(
364 "basalam-get-category-script",
365 self::assetsUrl("js/get-category.js"),
366 ["jquery", "basalam-admin-toast-script"],
367 $version,
368 true
369 );
370 wp_enqueue_script(
371 "basalam-order-script",
372 self::assetsUrl("js/order.js"),
373 ["jquery", "basalam-admin-toast-script"],
374 $version,
375 true
376 );
377 $adminScriptPath = syncBasalamPlugin()->pluginPath() . '/assets/js/admin.js';
378 $adminScriptVersion = file_exists($adminScriptPath)
379 ? $version . '-' . filemtime($adminScriptPath)
380 : $version;
381 wp_enqueue_script(
382 "basalam-admin-script",
383 self::assetsUrl("js/admin.js"),
384 $shouldLoadPointerTour ? ["jquery", "wp-pointer", "basalam-admin-toast-script"] : ["jquery", "basalam-admin-toast-script"],
385 $adminScriptVersion,
386 true
387 );
388 wp_enqueue_script(
389 "basalam-check-sync-script",
390 self::assetsUrl("js/check-sync.js"),
391 ["jquery", "basalam-admin-toast-script"],
392 $version,
393 true
394 );
395 wp_enqueue_script(
396 "basalam-map-category-option-script",
397 self::assetsUrl("js/map-category-option.js"),
398 ["jquery", "basalam-admin-toast-script"],
399 $version,
400 true
401 );
402
403 wp_enqueue_script(
404 "basalam-generate-product-variation-script",
405 self::assetsUrl("js/generate-product-variation.js"),
406 ["jquery", "basalam-admin-toast-script"],
407 $version,
408 true
409 );
410
411 $ticketScriptPath = syncBasalamPlugin()->pluginPath() . '/assets/js/ticket.js';
412 $ticketScriptVersion = file_exists($ticketScriptPath)
413 ? $version . '-' . filemtime($ticketScriptPath)
414 : $version;
415 wp_enqueue_script(
416 "basalam-ticket-script",
417 self::assetsUrl("js/ticket.js"),
418 ["basalam-admin-toast-script"],
419 $ticketScriptVersion,
420 true
421 );
422
423 if (ChatWidget::shouldLoadWidget()) {
424 wp_enqueue_script(
425 "basalam-chat-widget-script",
426 self::assetsUrl("chat/widget-loader.js"),
427 [],
428 $version,
429 true
430 );
431 }
432
433 if ($shouldLoadPointerTour) {
434 wp_localize_script('basalam-admin-script', 'basalamPointerTour', PointerTour::getPointerTourConfig());
435 }
436
437 if (AnnouncementCenter::shouldLoadAnnouncement()) {
438 wp_localize_script('basalam-admin-script', 'basalamAnnouncements', AnnouncementCenter::getConfig());
439 }
440 }
441
442 public static function financialManagementEnqueueAssets($hook = '')
443 {
444 $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
445 if ($page !== FinancialManagementMenu::PAGE_SLUG) {
446 return;
447 }
448
449 $version = syncbasalamplugin()->getVersion();
450
451 wp_enqueue_style(
452 'sync-basalam-finance-style',
453 self::assetsUrl('css/finance.css'),
454 [],
455 $version
456 );
457
458 wp_enqueue_script(
459 'sync-basalam-finance-history-pagination',
460 self::assetsUrl('js/finance-history-pagination.js'),
461 [],
462 $version,
463 true
464 );
465
466 wp_localize_script('sync-basalam-finance-history-pagination', 'syncBasalamHistoryPagination', [
467 'ajaxUrl' => admin_url('admin-ajax.php'),
468 'action' => FinancialManagementHistory::AJAX_ACTION,
469 'nonce' => wp_create_nonce(FinancialManagementHistory::AJAX_ACTION),
470 'pageSlug' => FinancialManagementMenu::PAGE_SLUG,
471 'errorMessage' => 'بارگذاری تاریخچه تسویه انجا�
472 نشد.',
473 ]);
474
475 wp_enqueue_script(
476 'sync-basalam-finance-balance-settlement',
477 self::assetsUrl('js/finance-balance-settlement.js'),
478 [],
479 $version,
480 true
481 );
482
483 wp_localize_script('sync-basalam-finance-balance-settlement', 'syncBasalamBalanceSettlement', [
484 'ajaxUrl' => admin_url('admin-ajax.php'),
485 'action' => BalanceSettlement::AJAX_ACTION,
486 'bankAccountsAction' => BalanceSettlement::AJAX_ACTION_BANK_ACCOUNTS,
487 'nonce' => wp_create_nonce(BalanceSettlement::AJAX_ACTION),
488 'submitText' => 'ثبت درخواست',
489 'loadingText' => 'در حال ارسال...',
490 'errorMessage' => 'خطا در ثبت درخواست تسویه.',
491 'successMessage' => 'درخواست تسویه با �
492 وفقیت ثبت شد.',
493 'amountError' => 'لطفاً �
494 بلغ �
495 عتبری وارد کنید.',
496 'walletTitle' => 'انتقال به کیف پول',
497 'bankTitle' => 'انتقال به حساب بانکی',
498 'bankAccountsError' => 'خطا در دریافت لیست حساب‌های بانکی.',
499 ]);
500 }
501
502 }
503