PluginProbe
AliNext – WooCommerce Dropshipping Plugin for AliExpress / trunk
AliNext – WooCommerce Dropshipping Plugin for AliExpress vtrunk
ali2woo-lite / includes / classes / controller / WooCommerceProductListController.php

WooCommerceProductListController.php in AliNext – WooCommerce Dropshipping Plugin for AliExpress trunk, at includes/classes/controller/WooCommerceProductListController.php

350 lines 13.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /* * class
3 * Description of WooCommerceProductListController
4 *
5 * @author Ali2Woo Team
6 *
7 * @autoload: a2wl_admin_init
8 *
9 * @ajax: true
10 */
11 // phpcs:ignoreFile WordPress.Security.EscapeOutput.OutputNotEscaped
12 namespace AliNext_Lite;;
13
14 use Pages;
15 use Throwable;
16
17 class WooCommerceProductListController extends AbstractController
18 {
19 protected ProductService $ProductService;
20 protected ProductReviewsService $ProductReviewsService;
21 protected WoocommerceService $WoocommerceService;
22 protected Woocommerce $WoocommerceModel;
23 protected PriceFormulaService $PriceFormulaService;
24
25 private $bulk_actions = [];
26 private $bulk_actions_text = [];
27
28 public function __construct(
29 ProductService $ProductService,
30 ProductReviewsService $ProductReviewsService,
31 WoocommerceService $WoocommerceService,
32 Woocommerce $WoocommerceModel,
33 PriceFormulaService $PriceFormulaService
34 ) {
35 parent::__construct();
36
37 $this->ProductService = $ProductService;
38 $this->ProductReviewsService = $ProductReviewsService;
39 $this->WoocommerceService = $WoocommerceService;
40 $this->WoocommerceModel = $WoocommerceModel;
41 $this->PriceFormulaService = $PriceFormulaService;
42
43 add_action('admin_footer-edit.php', array($this, 'scripts'));
44 add_action('load-edit.php', array($this, 'bulk_actions'));
45 add_filter('post_row_actions', array($this, 'row_actions'), 2, 150);
46 add_action('admin_enqueue_scripts', array($this, 'assets'));
47 add_action('admin_init', array($this, 'init'));
48
49 add_action('wp_ajax_a2wl_product_info', [$this, 'ajax_product_info']);
50 add_action('wp_ajax_a2wl_sync_products', [$this, 'ajax_sync_products']);
51 add_action('wp_ajax_a2wl_sync_products_reviews', [$this, 'ajax_sync_products_reviews']);
52 //todo: it looks like rudiment function
53 add_action('wp_ajax_a2wl_get_product_id', [$this, 'ajax_get_product_id']);
54
55 add_action('current_screen', array($this, 'setup_screen'));
56 }
57
58 public function setup_screen()
59 {
60 $screen_id = false;
61 if (function_exists('get_current_screen')) {
62 $screen = get_current_screen();
63 $screen_id = isset($screen, $screen->id) ? $screen->id : '';
64 }
65
66 if ($screen_id == 'edit-product') {
67 add_action('admin_notices', array($this, 'admin_notices'));
68 }
69
70 remove_action('current_screen', array($this, 'setup_screen'));
71 }
72
73 public function admin_notices()
74 {
75 $daily_limits = get_transient('_a2w_daily_limits_warning');
76
77 if ($daily_limits && isset($daily_limits['until']) && $daily_limits['until'] > time()) {
78 ?>
79 <div id="a2wl-daily-limits-warning-message" class="notice error is-dismissible">
80 <p>You have reached your daily synchronization quota. You can synchronize up to <?php echo $daily_limits['limit']; ?> products per day.</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
81 </div>
82 <?php
83 }
84 }
85
86 public function init()
87 {
88
89 list($this->bulk_actions, $this->bulk_actions_text) = apply_filters('a2wl_wcpl_bulk_actions_init', array($this->bulk_actions, $this->bulk_actions_text));
90 }
91
92 public function row_actions($actions, $post)
93 {
94 if ('product' === $post->post_type) {
95 $external_id = get_post_meta($post->ID, "_a2w_external_id", true);
96 if ($external_id) {
97 $actions = array_merge($actions, array('a2wl_product_info' => sprintf('<a class="a2wl-product-info" id="a2wl-%1$d" data-external-id="%2$s" href="#">%3$s</a>', $post->ID, $external_id, 'Aliexpress Info')));
98 }
99 }
100
101 return $actions;
102 }
103
104 public function assets()
105 {
106 if (!wp_script_is('a2wl-admin-script', 'enqueued')) {
107 wp_enqueue_script('a2wl-admin-script',
108 A2WL()->plugin_url() . '/assets/js/admin_script.js',
109 array('jquery'),
110 A2WL()->version
111 );
112 }
113
114 AbstractAdminPage::localizeAdminScript();
115
116 wp_enqueue_style('a2wl-wc-pl-style', A2WL()->plugin_url() . '/assets/css/wc_pl_style.css', [], A2WL()->version);
117
118 wp_style_add_data('a2wl-wc-pl-style', 'rtl', 'replace');
119
120 wp_enqueue_script('a2wl-wc-pl-script', A2WL()->plugin_url() . '/assets/js/wc_pl_script.js', ['jquery-ui-core', 'jquery-ui-dialog'], A2WL()->version);
121
122 wp_enqueue_script('a2wl-sprintf-script', A2WL()->plugin_url() . '/assets/js/sprintf.js', array(), A2WL()->version);
123
124 $lang_data = array(
125 'please_wait_data_loads' => _x('Please wait, data loads..', 'Status', 'ali2woo'),
126 'process_update_d_of_d' => _x('Process update %d of %d.', 'Status', 'ali2woo'),
127 'process_update_d_of_d_erros_d' => _x('Process update %d of %d. Errors: %d.', 'Status', 'ali2woo'),
128 'complete_result_updated_d_erros_d' => _x('Complete! Result updated: %d; errors: %d.', 'Status', 'ali2woo'),
129 );
130
131 $localizator = AliexpressLocalizator::getInstance();
132
133 wp_localize_script('a2wl-wc-pl-script', 'a2wl_wc_pl_script',
134 [
135 'lang' => $lang_data,
136 'lang_cookies' => AliexpressLocalizator::getInstance()->getLocaleCookies(false),
137 'locale' => $localizator->getLangCode(),
138 'currency' => $localizator->currency,
139 'chrome_ext_import' => a2wl_check_defined('A2WL_CHROME_EXT_IMPORT'),
140 'chrome_url' => A2WL()->chrome_url,
141 'ajaxurl' => admin_url('admin-ajax.php'),
142 'nonce_action' => wp_create_nonce(self::AJAX_NONCE_ACTION),
143 ]
144 );
145 }
146
147 public function scripts()
148 {
149 global $post_type;
150
151 if ($post_type == 'product') {
152
153 foreach ($this->bulk_actions as $action) {
154 $text = $this->bulk_actions_text[$action];
155 ?>
156 <script type="text/javascript">
157 jQuery(document).ready(function () {
158 jQuery('<option>').val('<?php echo $action; ?>').text('<?php echo $text; ?>').appendTo("select[name='action']");
159 jQuery('<option>').val('<?php echo $action; ?>').text('<?php echo $text; ?>').appendTo("select[name='action2']");
160 });
161 </script>
162 <?php
163 }
164 }
165 }
166
167 public function bulk_actions()
168 {
169 global $typenow;
170 $post_type = $typenow;
171
172 if ($post_type == 'product') {
173
174 $wp_list_table = _get_list_table('WP_Posts_List_Table');
175 $action = $wp_list_table->current_action();
176
177 $allowed_actions = $this->bulk_actions;
178 if (!in_array($action, $allowed_actions)) {
179 return;
180 }
181
182 check_admin_referer('bulk-posts');
183
184 // make sure ids are submitted. depending on the resource type, this may be 'media' or 'ids'
185 if (isset($_REQUEST['post'])) {
186 $post_ids = array_map('intval', $_REQUEST['post']);
187 }
188
189 if (empty($post_ids)) {
190 return;
191 }
192
193 $sendback = remove_query_arg(array_merge($allowed_actions, array('untrashed', 'deleted', 'ids')), wp_get_referer());
194 if (!$sendback) {
195 $sendback = admin_url("edit.php?post_type=$post_type");
196 }
197
198 $pagenum = $wp_list_table->get_pagenum();
199 $sendback = add_query_arg('paged', $pagenum, $sendback);
200
201 $sendback = apply_filters('a2wl_wcpl_bulk_actions_perform', $sendback, $action, $post_ids);
202
203 $sendback = remove_query_arg(array('action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view'), $sendback);
204
205 wp_redirect($sendback);
206 exit();
207 }
208 }
209
210 public function ajax_product_info(): void
211 {
212 check_admin_referer(self::AJAX_NONCE_ACTION, self::NONCE);
213
214 if (!PageGuardHelper::canAccessPage(Pages::IMPORT_LIST)) {
215 $result = ResultBuilder::buildError($this->getErrorTextNoPermissions());
216 echo wp_json_encode($result);
217 wp_die();
218 }
219
220 $result = array("state" => "ok", "data" => "");
221
222 $post_id = isset($_POST['id']) ? $_POST['id'] : false;
223
224 if (!$post_id) {
225 $result['state'] = 'error';
226 echo wp_json_encode($result);
227 wp_die();
228 }
229
230 $external_id = get_post_meta($post_id, "_a2w_external_id", true);
231
232 $time_value = get_post_meta($post_id, '_a2w_last_update', true);
233 $time_value = $time_value ? gmdate("Y-m-d H:i:s", $time_value) : 'not updated';
234
235 $product_url = get_post_meta($post_id, '_a2w_product_url', true);
236 if (!$product_url) {
237 $product_url = get_post_meta($post_id, '_a2w_original_product_url', true);
238 }
239
240 $content = array();
241
242 $content[] = "Product: <a target='_blank' href='" . $product_url . "'>here</a>";
243
244 $seller_url = get_post_meta($post_id, '_a2w_seller_url', true);
245 $store_id = get_post_meta($post_id, '_a2w_store_id', true);
246 $seller_id = get_post_meta($post_id, '_a2w_seller_id', true);
247 $seller_name = get_post_meta($post_id, '_a2w_seller_name', true);
248
249 if ($seller_url && $seller_name) {
250 $content[] = "Seller: <a target='_blank' href='" . $seller_url . "'>" . $seller_name . "</a>";
251 }
252
253 if ($store_id){
254 $content[] = "Store ID: <span class='a2wl_value'>" . $store_id . "</span>";
255 }
256
257 if ($seller_id){
258 $content[] = "Seller ID: <span class='a2wl_value'>" . $seller_id . "</span>";
259 }
260
261 $content[] = "External ID: <span class='a2wl_value'>" . $external_id . "</span>";
262 $content[] = "Last auto-update: <span class='a2wl_value'>" . $time_value . "</span>";
263
264 $content = apply_filters('a2wl_ajax_product_info', $content, $post_id, $external_id);
265 $result['data'] = array('content' => $content, 'id' => $post_id);
266
267 echo wp_json_encode($result);
268 wp_die();
269 }
270
271 public function ajax_sync_products(): void
272 {
273 check_admin_referer(self::AJAX_NONCE_ACTION, self::NONCE);
274
275 if (!PageGuardHelper::canAccessPage(Pages::IMPORT_LIST)) {
276 $result = ResultBuilder::buildError($this->getErrorTextNoPermissions());
277 echo wp_json_encode($result);
278 wp_die();
279 }
280
281 if (A2WL()->isFreePlugin()) {
282 $errorMessage = _x(
283 'Product sync functionality is exclusive to the premium version of the plugin.',
284 'Error text', 'ali2woo'
285 );
286 $result = ResultBuilder::buildError($errorMessage);
287 }
288 echo wp_json_encode($result);
289 wp_die();
290 }
291
292 public function ajax_sync_products_reviews(): void
293 {
294 check_admin_referer(self::AJAX_NONCE_ACTION, self::NONCE);
295
296 if (!PageGuardHelper::canAccessPage(Pages::IMPORT_LIST)) {
297 $result = ResultBuilder::buildError($this->getErrorTextNoPermissions());
298 echo wp_json_encode($result);
299 wp_die();
300 }
301
302 a2wl_init_error_handler();
303 try {
304 $ids = isset($_POST['ids']) ? (is_array($_POST['ids']) ? $_POST['ids'] : [$_POST['ids']]) : [];
305 $error = $this->ProductReviewsService->loadReviewsForProductIds($ids);
306
307 $result = [
308 "state" => "ok",
309 "update_state" => [
310 'ok' => count($ids),
311 'error' => $error
312 ]
313 ];
314 } catch (Throwable $e) {
315 a2wl_print_throwable($e);
316 $result = ResultBuilder::buildError($e->getMessage());
317 }
318
319 echo wp_json_encode($result);
320 wp_die();
321 }
322
323 //todo: it looks like rudiment function
324 public function ajax_get_product_id(): void
325 {
326 check_admin_referer(self::AJAX_NONCE_ACTION, self::NONCE);
327
328 if (!PageGuardHelper::canAccessPage(Pages::IMPORT_LIST)) {
329 $result = ResultBuilder::buildError($this->getErrorTextNoPermissions());
330 echo wp_json_encode($result);
331 wp_die();
332 }
333
334 if (!empty($_POST['post_id'])) {
335 $id = $this->WoocommerceModel->get_product_external_id($_POST['post_id']);
336 if ($id) {
337 $result = ResultBuilder::buildOk(array('id' => $id));
338 } else {
339 $result = ResultBuilder::buildError('uncknown ID');
340 }
341 } else {
342 $result = ResultBuilder::buildError("get_product_id: waiting for ID...");
343 }
344
345 echo wp_json_encode($result);
346 wp_die();
347 }
348
349 }
350