PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.7
ووسلام – همگام سازی ووکامرس و باسلام v1.10.7
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.7, at includes/Registrar/AdminRegistrar.php

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