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

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