PluginProbe
WDesignKit – AI Templates, Widget Builder & MCP Workflow / 1.0.21
WDesignKit – AI Templates, Widget Builder & MCP Workflow v1.0.21
2.6.6 2.6.5 2.6.4 2.6.3 2.6.2 2.6.1 2.6.0 2.5.5 2.5.4 2.5.3 2.5.2 2.5.1 2.5.0 2.4.0 2.3.3 2.3.2 2.3.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 All 128 releases
← All changes | includes/admin/class-api.php +1039 -4261 2.6.61.0.21 View file →
@@ -36,31 +36,15 @@
36 36
37 37 /**
38 38 * Member Variable
39 39 *
40 - * @var staring widgets_with_post_category
41 - */
42 - public $widgets_with_post_category = array(
43 - 'post_category', 'include_products',
44 - );
45 -
46 - /**
47 - * Member Variable
48 - *
49 40 * @var staring $wdkit_api
50 41 */
51 - public $wdkit_api = WDKIT_SERVER_API_URL . 'api/wp/';
42 + public $wdkit_api = WDKIT_SERVER_SITE_URL . 'api/wp/';
52 43
53 44 /**
54 45 * Member Variable
55 46 *
56 - * @var staring $wdkit_api_v2
57 - */
58 - public $wdkit_api_v2 = WDKIT_SERVER_API_URL . 'api/v2/wp/';
59 -
60 - /**
61 - * Member Variable
62 - *
63 47 * @var staring $widget_folder_u_r_l
64 48 */
65 49 public $widget_folder_u_r_l = '';
66 50
@@ -114,10 +98,8 @@
114 98 * Error JSON message
115 99 *
116 100 * @param array $data give array.
117 101 * @param string $status api code number.
118 - *
119 - * @since 1.0.0
120 102 * */
121 103 public function wdkit_error_msg( $data = null, $status = null ) {
122 104 wp_send_json_error( $data );
123 105 wp_die();
@@ -127,10 +109,8 @@
127 109 * Success JSON message
128 110 *
129 111 * @param array $data give array.
130 112 * @param string $status api code number.
131 - *
132 - * @since 1.0.0
133 113 * */
134 114 public function wdkit_success_msg( $data = null, $status = null ) {
135 115 wp_send_json_success( $data, $status );
136 116 wp_die();
@@ -135,84 +115,9 @@
135 115 wp_send_json_success( $data, $status );
136 116 wp_die();
137 117 }
138 118
139 -
140 119 /**
141 - * Memory headroom left for image work, in bytes. 0 means unlimited.
142 - */
143 - private static function wdkit_available_image_memory() {
144 - $limit = wp_convert_hr_to_bytes( ini_get( 'memory_limit' ) );
145 -
146 - if ( $limit <= 0 ) {
147 - return 0;
148 - }
149 -
150 - return max( 0, $limit - memory_get_usage( true ) );
151 - }
152 -
153 - /**
154 - * Stop WordPress decoding images that cannot fit in the memory available.
155 - *
156 - * Both filters are consulted by wp_create_image_subsizes() *before* it loads an image
157 - * editor, so refusing here means the oversized image is never decoded:
158 - *
159 - * big_image_size_threshold -> falsy skips the "-scaled" copy (needs a full decode)
160 - * intermediate_image_sizes_advanced -> empty makes _wp_make_subsizes() return early,
161 - * ahead of its wp_get_image_editor() call
162 - *
163 - * The original file is still attached and usable; only the derived sizes are skipped.
164 - * That trades ideal thumbnails for an import that completes, instead of a fatal that
165 - * takes the whole page down and repeats on every retry.
166 - *
167 - * @since 2.6.2
168 - */
169 - private static function wdkit_guard_oversized_images() {
170 - static $registered = false;
171 -
172 - // Registering twice would stack duplicate closures on both filters.
173 - if ( $registered ) {
174 - return;
175 - }
176 -
177 - $registered = true;
178 -
179 - if ( ! class_exists( 'Wdkit_Image_Guard' ) ) {
180 - require_once WDKIT_INCLUDES . 'admin/class-wdkit-image-guard.php';
181 - }
182 -
183 - add_filter(
184 - 'big_image_size_threshold',
185 - function ( $threshold, $imagesize = array(), $file = '', $attachment_id = 0 ) {
186 - if ( ! empty( $imagesize[0] ) && ! empty( $imagesize[1] )
187 - && ! Wdkit_Image_Guard::decode_fits( $imagesize[0], $imagesize[1], self::wdkit_available_image_memory() )
188 - ) {
189 - return false;
190 - }
191 -
192 - return $threshold;
193 - },
194 - 99,
195 - 4
196 - );
197 -
198 - add_filter(
199 - 'intermediate_image_sizes_advanced',
200 - function ( $sizes, $image_meta = array(), $attachment_id = 0 ) {
201 - if ( ! empty( $image_meta['width'] ) && ! empty( $image_meta['height'] )
202 - && ! Wdkit_Image_Guard::decode_fits( $image_meta['width'], $image_meta['height'], self::wdkit_available_image_memory() )
203 - ) {
204 - return array();
205 - }
206 -
207 - return $sizes;
208 - },
209 - 99,
210 - 3
211 - );
212 - }
213 -
214 - /**
215 120 * Get Wdkit Api Call Ajax.
216 121 */
217 122 public function wdkit_api_call() {
218 123
@@ -231,40 +136,33 @@
231 136 case 'onboarding_handler':
232 137 $data = $this->wdkit_onboarding_handler();
233 138 break;
234 139 case 'wkit_login':
235 - $data = apply_filters( 'wp_wdkit_login_ajax', 'wkit_login' );
140 + $data = $this->wdkit_login();
236 141 break;
237 142 case 'api_login':
238 - $data = apply_filters( 'wp_wdkit_login_ajax', 'api_login' );
143 + $data = $this->wdkit_api_login();
239 144 break;
240 145 case 'social_login':
241 - $data = apply_filters( 'wp_wdkit_login_ajax', 'social_login' );
146 + $data = $this->wdkit_social_login();
242 147 break;
243 - case 'forgot_password':
244 - $data = apply_filters( 'wp_wdkit_login_ajax', 'forgot_password' );
245 - break;
246 - case 'wdkit_user_signup':
247 - $data = apply_filters( 'wp_wdkit_login_ajax', 'wdkit_user_signup' );
248 - break;
249 148 case 'wkit_meta_data':
250 149 $data = $this->wdkit_meta_data();
251 150 break;
252 151 case 'get_user_info':
152 + $id = isset( $_POST['id'] ) ? strtolower( sanitize_text_field( wp_unslash( $_POST['id'] ) ) ) : false;
253 153 $data = $this->wdkit_get_user_info();
254 154 break;
255 155 case 'browse_page':
256 156 $data = $this->wdkit_browse_page();
257 157 break;
158 + case 'widget_browse_page':
159 + $data = $this->wdkit_widget_browse_page();
160 + break;
258 161 case 'kit_template':
162 + $id = isset( $_POST['id'] ) ? strtolower( sanitize_text_field( wp_unslash( $_POST['id'] ) ) ) : false;
259 163 $data = $this->wdkit_template();
260 164 break;
261 - case 'wkit_preset_template':
262 - $data = apply_filters( 'wp_wdkit_preset_ajax', 'wdkit_preset_template' );
263 - break;
264 - case 'wdkit_preset_dwnld_template':
265 - $data = apply_filters( 'wp_wdkit_preset_ajax', 'wdkit_preset_dwnld_template' );
266 - break;
267 165 case 'template_remove':
268 166 $data = $this->wdkit_template_remove();
269 167 break;
270 168 case 'save_template':
@@ -269,29 +167,8 @@
269 167 break;
270 168 case 'save_template':
271 169 $data = $this->wdkit_put_save_template();
272 170 break;
273 - case 'update_save_temp_image':
274 - $data = $this->wdkit_update_save_temp_image();
275 - break;
276 - case 'save_wp_images':
277 - $data = $this->wdkit_save_wp_images();
278 - break;
279 - case 'get_global_val':
280 - $data = $this->wdkit_get_global_val();
281 - break;
282 - case 'update_global_val':
283 - $data = $this->wdkit_update_global_val();
284 - break;
285 - case 'wdkit_get_site_setting':
286 - $data = $this->wdkit_get_site_setting();
287 - break;
288 - case 'wdkit_update_site_setting':
289 - $data = $this->wdkit_update_site_setting();
290 - break;
291 - case 'update_preset_setting':
292 - $data = $this->wdkit_update_preset();
293 - break;
294 171 case 'find_template':
295 172 $data = $this->wdkit_find_existing_template();
296 173 break;
297 174 case 'update_template':
@@ -305,65 +182,11 @@
305 182 break;
306 183 case 'install_plugins_depends':
307 184 $data = $this->wdkit_install_plugins_depends();
308 185 break;
309 - case 'generate_site_logo':
310 - $data = $this->wkit_generate_site_logo();
311 - break;
312 - case 'generate_ai_content':
313 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'generate_ai_content' );
314 - break;
315 - case 'generate_ai_content_batch':
316 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'generate_ai_content_batch' );
317 - break;
318 - case 'reset_site':
319 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'reset_site' );
320 - break;
321 - case 'wdkit_nxt_thembuilder_reset':
322 - $data = $this->wdkit_nxt_thembuilder_reset();
323 - break;
324 - case 'wdkit_check_user_credit':
325 - $data = $this->wdkit_check_user_credit();
326 - break;
327 - case 'wdkit_remove_header_footer':
328 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wdkit_remove_header_footer' );
329 - break;
330 - case 'check_post_count':
331 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'check_post_count' );
332 - break;
333 - case 'wkit_check_product_count':
334 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wkit_check_product_count' );
335 - break;
336 - case 'select_team_img':
337 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'select_team_img' );
338 - break;
339 - case 'wkit_ai_desc_keyword':
340 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wkit_ai_desc_keyword' );
341 - break;
342 - case 'wkit_ai_credit_update':
343 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wkit_ai_credit_update' );
344 - break;
345 - case 'wkit_generate_post_data':
346 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wkit_generate_post_data' );
347 - break;
348 - case 'wkit_generate_product_data':
349 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wkit_generate_product_data' );
350 - break;
351 - case 'wkit_cteate_product':
352 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wkit_cteate_product' );
353 - break;
354 - case 'wkit_remove_dummy_post':
355 - $data = apply_filters( 'wp_wdkit_import_temp_ajax', 'wkit_remove_dummy_post' );
356 - break;
357 186 case 'update_latest_plugin':
358 187 $data = $this->wdkit_update_latest_plugin();
359 188 break;
360 - case 'activate_container':
361 - $data = $this->wdkit_activate_container();
362 - break;
363 - case 'import_taxonomy':
364 - $data = $this->wdkit_import_taxonomy();
365 - break;
366 189 case 'import_template':
367 190 $data = $this->wdkit_import_template();
368 191 break;
369 192 case 'import_multi_template':
@@ -368,58 +191,11 @@
368 191 break;
369 192 case 'import_multi_template':
370 193 $data = $this->wdkit_import_multi_template();
371 194 break;
372 - case 'import_page_section':
373 - $data = $this->import_page_section_content();
374 - break;
375 - case 'wkit_update_elementor_template':
376 - $data = $this->wkit_update_elementor_template();
377 - break;
378 - case 'wdkit_update_page_content':
379 - $data = $this->wdkit_update_page_content();
380 - break;
381 - case 'update_plugin_setting':
382 - $data = $this->update_plugin_setting();
383 - break;
384 - case 'update_theme_setting':
385 - $data = $this->update_theme_setting();
386 - break;
387 - case 'update_site_setting':
388 - $data = $this->update_site_setting();
389 - break;
390 195 case 'import_kit_template':
391 196 $data = $this->wdkit_import_kit_template();
392 197 break;
393 - case 'enable_template_widgets':
394 - $data = $this->wdkit_enable_template_widgets();
395 - break;
396 - case 'scan_nexter_widgets':
397 - if ( ! empty( $_POST['blockNames'] ) && has_filter( 'nexter_block_list_merge' ) ) {
398 -
399 - $posted_blocks = json_decode( stripslashes( $_POST['blockNames'] ), true );
400 -
401 - if ( is_array( $posted_blocks ) ) {
402 - $blockList = array_map( 'sanitize_text_field', $posted_blocks );
403 -
404 - // अब filter call करो
405 - $result = apply_filters( 'nexter_block_list_merge', $blockList );
406 -
407 - wp_send_json( $result );
408 - wp_die();
409 - }
410 - }
411 -
412 - wp_send_json(
413 - array(
414 - 'success' => false,
415 - 'message' => __( 'No block names received or filter not found.', 'wdesignkit' ),
416 - 'description' => 'Ensure blockNames are posted and the filter is attached.',
417 - )
418 - );
419 - wp_die();
420 - $data = '';
421 - break;
422 198 case 'shared_with_me':
423 199 $data = $this->wdkit_shared_with_me();
424 200 break;
425 201 case 'manage_workspace':
@@ -424,32 +200,8 @@
424 200 break;
425 201 case 'manage_workspace':
426 202 $data = $this->wdkit_manage_workspace();
427 203 break;
428 - case 'widget_browse_page':
429 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'widget_browse_page' );
430 - break;
431 - case 'wkit_create_widget':
432 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_create_widget' );
433 - break;
434 - case 'wkit_import_widget':
435 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_import_widget' );
436 - break;
437 - case 'wkit_export_widget':
438 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_export_widget' );
439 - break;
440 - case 'wkit_delete_widget':
441 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_delete_widget' );
442 - break;
443 - case 'wkit_widget_preview':
444 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_widget_preview' );
445 - break;
446 - case 'wkit_check_widget_versions':
447 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_check_widget_versions' );
448 - break;
449 - case 'wkit_plugin_download_get':
450 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_plugin_download_get' );
451 - break;
452 204 case 'wkit_manage_widget_workspace':
453 205 $data = $this->wdkit_manage_widget_workspace();
454 206 break;
455 207 case 'wkit_activate_key':
@@ -457,16 +209,25 @@
457 209 break;
458 210 case 'wkit_manage_widget_category':
459 211 $data = $this->wdkit_manage_widget_category();
460 212 break;
461 - case 'wkit_widget_json':
462 - $data = $this->wkit_widget_json();
213 + case 'wkit_create_widget':
214 + $data = $this->wdkit_create_widget();
463 215 break;
216 + case 'wkit_export_widget':
217 + $data = $this->wdkit_export_widget();
218 + break;
219 + case 'wkit_import_widget':
220 + $data = $this->wdkit_import_widget();
221 + break;
222 + case 'wkit_delete_widget':
223 + $data = $this->wdkit_delete_widget();
224 + break;
464 225 case 'wkit_download_widget':
465 226 $data = $this->wdkit_download_widget();
466 227 break;
467 228 case 'wkit_public_download_widget':
468 - $data = apply_filters( 'wp_wdkit_widget_ajax', 'wkit_public_download_widget' );
229 + $data = $this->wdkit_public_download_widget();
469 230 break;
470 231 case 'wkit_add_widget':
471 232 $data = $this->wdkit_add_widget();
472 233 break;
@@ -487,36 +248,14 @@
487 248 break;
488 249 case 'sync_licence':
489 250 $data = $this->wdkit_sync_licence_key();
490 251 break;
491 - case 'get_wkit_version':
492 - $data = $this->wdkit_prev_version();
493 - break;
494 - case 'rollback_wdkit':
495 - $data = $this->wdkit_rollback_check();
496 - break;
497 252 case 'wkit_logout':
498 253 $data = $this->wdkit_logout();
499 254 break;
500 - case 'wkit_white_label':
501 - $this->wkit_white_label();
502 - break;
503 - case 'wkit_reset_wl':
504 - $data = $this->wkit_reset_wl();
505 - break;
506 - case 'wdkit_dark_mode':
507 - $data = $this->wdkit_dark_mode();
508 - break;
509 - case 'wdkit_get_workspace_data':
510 - $data = $this->wdkit_get_workspace_data();
511 - break;
512 - default:
513 - $this->wdkit_error_msg( __( 'Unknown request type.', 'wdesignkit' ) );
514 - return;
515 255 }
516 256
517 257 $this->wdkit_success_msg( $data );
518 - // wp_die();
519 258 }
520 259
521 260 /**
522 261 *
@@ -523,13 +262,12 @@
523 262 * This Function is used for API call
524 263 *
525 264 * @since 1.0.0
526 265 *
527 - * @param array $data give array.
528 - * @param array $name store data.
529 - * @param int $timeout optional HTTP timeout in seconds. Default 100.
266 + * @param array $data give array.
267 + * @param array $name store data.
530 268 */
531 - protected function wkit_api_call( $data, $name, $timeout = 100 ) {
269 + protected function wkit_api_call( $data, $name ) {
532 270 $u_r_l = $this->wdkit_api;
533 271
534 272 if ( empty( $u_r_l ) ) {
535 273 return array(
@@ -540,9 +278,9 @@
540 278
541 279 $args = array(
542 280 'method' => 'POST',
543 281 'body' => $data,
544 - 'timeout' => $timeout,
282 + 'timeout' => 100,
545 283 );
546 284 $response = wp_remote_post( $u_r_l . $name, $args );
547 285
548 286 if ( is_wp_error( $response ) ) {
@@ -548,9 +286,9 @@
548 286 if ( is_wp_error( $response ) ) {
549 287 $error_message = $response->get_error_message();
550 288
551 289 /* Translators: %s is a placeholder for the error message */
552 - $error_message = sprintf( esc_html__( 'API request error: %s', 'wdesignkit' ), esc_html( $error_message ) );
290 + $error_message = printf( esc_html__( 'API request error: %s', 'wdesignkit' ), esc_html( $error_message ) );
553 291
554 292 return array(
555 293 'massage' => $error_message,
556 294 'success' => false,
@@ -567,9 +305,9 @@
567 305 'success' => true,
568 306 );
569 307 }
570 308
571 - $error_message = sprintf( 'Server error: %d', esc_html( $status_code ) );
309 + $error_message = printf( 'Server error: %d', esc_html( $status_code ) );
572 310
573 311 if ( isset( $error_data->message ) ) {
574 312 $error_message .= ' (' . $error_data->message . ')';
575 313 }
@@ -581,9 +319,41 @@
581 319 );
582 320 }
583 321
584 322 /**
323 + * This Function is used for API call
585 324 *
325 + * @since 1.0.0
326 + *
327 + * @param string $user_key Dynamic key.
328 + * @param string $user_email User email.
329 + * @param string $token User token.
330 + */
331 + protected function wdkit_set_time_out( $user_key, $user_email, $token, $login_type = '' ) {
332 +
333 + if ( 'normal' === $login_type ) {
334 + set_transient(
335 + 'wdkit_auth_' . $user_key,
336 + array(
337 + 'user_email' => sanitize_email( $user_email ),
338 + 'token' => $token,
339 + ),
340 + 7776000
341 + );
342 + } else {
343 + set_transient(
344 + 'wdkit_auth_' . $user_key,
345 + array(
346 + 'user_email' => sanitize_email( $user_email ),
347 + 'token' => $token,
348 + ),
349 + 86400
350 + );
351 + }
352 + }
353 +
354 + /**
355 + *
586 356 * It is Use for handle onboarding data.
587 357 *
588 358 * @since 1.0.9
589 359 */
@@ -593,9 +363,8 @@
593 363
594 364 $elementor_plugin = isset( $_POST['elementor_plugin'] ) ? (int) sanitize_text_field( wp_unslash( $_POST['elementor_plugin'] ) ) : 0;
595 365 $tpag_plugin = isset( $_POST['tpag_plugin'] ) ? (int) sanitize_text_field( wp_unslash( $_POST['tpag_plugin'] ) ) : 0;
596 366 $bricks_theme = isset( $_POST['bricks_theme'] ) ? (int) sanitize_text_field( wp_unslash( $_POST['bricks_theme'] ) ) : 0;
597 - $site_info = isset( $_POST['info'] ) ? sanitize_text_field( wp_unslash( $_POST['info'] ) ) : false;
598 367
599 368 $server_software = ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
600 369
601 370 $web_server = $server_software;
@@ -634,27 +403,23 @@
634 403 'tpag_install' => $tpag_plugin,
635 404 'bricks_install' => $bricks_theme,
636 405 );
637 406
638 - if ( ! empty( $site_info ) ) {
639 - $final = array(
640 - 'web_server' => $web_server,
641 - 'memory_limit' => $memory_limit,
642 - 'max_execution_time' => $max_execution_time,
643 - 'php_version' => $php_version,
644 - 'wp_version' => $wp_version,
645 - 'email' => $email,
646 - 'site_url' => $siteurl,
647 - 'site_language' => $language,
648 - 'theme' => $theme,
649 - 'plugins' => $act_plugin,
650 - 'basic_requirements' => $basic_requirements,
651 - 'page_template' => $page_template,
652 - 'page_builder' => $page_builder,
653 - );
654 - } else {
655 - $final = array();
656 - }
407 + $final = array(
408 + 'web_server' => $web_server,
409 + 'memory_limit' => $memory_limit,
410 + 'max_execution_time' => $max_execution_time,
411 + 'php_version' => $php_version,
412 + 'wp_version' => $wp_version,
413 + 'email' => $email,
414 + 'site_url' => $siteurl,
415 + 'site_language' => $language,
416 + 'theme' => $theme,
417 + 'plugins' => $act_plugin,
418 + 'basic_requirements' => $basic_requirements,
419 + 'page_template' => $page_template,
420 + 'page_builder' => $page_builder,
421 + );
657 422
658 423 $response = wp_remote_post(
659 424 $this->wdkit_onbording_api,
660 425 array(
@@ -707,11 +472,172 @@
707 472 }
708 473
709 474 /**
710 475 *
476 + * It is Use for user login with email and password.
477 + *
478 + * @since 1.0.0
479 + */
480 + protected function wdkit_login() {
481 + $user_email = isset( $_POST['user_email'] ) ? strtolower( sanitize_email( wp_unslash( $_POST['user_email'] ) ) ) : false;
482 + $user_password = isset( $_POST['user_password'] ) ? sanitize_text_field( wp_unslash( $_POST['user_password'] ) ) : false;
483 + $login_type = isset( $_POST['login_type'] ) ? sanitize_text_field( wp_unslash( $_POST['login_type'] ) ) : false;
484 + $site_url = isset( $_POST['site_url'] ) ? esc_url_raw( wp_unslash( $_POST['site_url'] ) ) : '';
485 +
486 + $user_key = strstr( $user_email, '@', true );
487 + $response = '';
488 +
489 + delete_transient( 'wdkit_auth_' . $user_key );
490 +
491 + $get_login = get_transient( 'wdkit_auth_' . $user_key );
492 +
493 + if ( ! empty( $user_email ) && ! empty( $user_password ) && false === $get_login ) {
494 + $response = WDesignKit_Data_Query::get_data(
495 + 'login',
496 + array(
497 + 'user_email' => $user_email,
498 + 'password' => $user_password,
499 + 'site_url' => $site_url,
500 + )
501 + );
502 +
503 + if ( ! empty( $response ) && ! empty( $response['success'] ) ) {
504 + if ( ! empty( $response['message'] ) && ! empty( $response['token'] ) ) {
505 + if ( false === get_transient( 'wdkit_auth_' . $user_key ) ) {
506 + $this->wdkit_set_time_out( $user_key, $user_email, $response['token'], $login_type );
507 + }
508 + }
509 + }
510 + } elseif ( ! empty( $get_login ) && ! empty( $get_login['token'] ) ) {
511 + $response = array_merge(
512 + array(
513 + 'success' => true,
514 + 'message' => esc_html__( 'Success! Login successful.', 'wdesignkit' ),
515 + 'description' => esc_html__( 'Login successful. Keep it up!', 'wdesignkit' ),
516 + ),
517 + $get_login
518 + );
519 + }
520 +
521 + wp_send_json( $response );
522 + wp_die();
523 + }
524 +
525 + /**
526 + *
527 + * This Function is used for Login with Api (token)
528 + *
529 + * @version 1.0.0
530 + */
531 + protected function wdkit_api_login() {
532 + $user_token = isset( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '';
533 + $login_type = isset( $_POST['login_type'] ) ? sanitize_text_field( wp_unslash( $_POST['login_type'] ) ) : '';
534 +
535 + $site_url = isset( $_POST['site_url'] ) ? esc_url_raw( wp_unslash( $_POST['site_url'] ) ) : '';
536 +
537 + if ( empty( $user_token ) ) {
538 + $result = array(
539 + 'success' => false,
540 + 'token' => '',
541 + 'data' => array(
542 + 'message' => $this->e_msg_login,
543 + 'description' => $this->e_desc_login,
544 + ),
545 + );
546 +
547 + wp_send_json( $result );
548 + wp_die();
549 + }
550 +
551 + $array_data = array(
552 + 'token' => $user_token,
553 + 'site_url' => $site_url,
554 + );
555 +
556 + $response = $this->wkit_api_call( $array_data, 'login/api' );
557 +
558 + $success = ! empty( $response['success'] ) ? is_bool( $response['success'] ) : false;
559 +
560 + if ( empty( $success ) ) {
561 + $result = array(
562 + 'data' => $response,
563 + 'token' => '',
564 + 'success' => false,
565 + );
566 +
567 + wp_send_json( $result );
568 + wp_die();
569 + }
570 +
571 + $response = json_decode( wp_json_encode( $response['data'] ), true );
572 + $user_email = ! empty( $response['user']['user_email'] ) ? sanitize_email( $response['user']['user_email'] ) : '';
573 + $user_key = strstr( $user_email, '@', true );
574 +
575 + $this->wdkit_set_time_out( $user_key, $user_email, $user_token, $login_type );
576 +
577 + $result = array(
578 + 'success' => true,
579 + 'data' => $response,
580 + 'token' => $user_token,
581 + );
582 +
583 + wp_send_json( $result );
584 + wp_die();
585 + }
586 +
587 + /**
588 + *
589 + * This Function is used for social Login
590 + *
591 + * @version 1.0.0
592 + */
593 + protected function wdkit_social_login() {
594 + $user_state = isset( $_POST['state'] ) ? sanitize_text_field( wp_unslash( $_POST['state'] ) ) : '';
595 + $login_type = isset( $_POST['login_type'] ) ? sanitize_text_field( wp_unslash( $_POST['login_type'] ) ) : '';
596 +
597 + $site_url = isset( $_POST['site_url'] ) ? esc_url_raw( wp_unslash( $_POST['site_url'] ) ) : '';
598 +
599 + $array_data = array(
600 + 'state' => $user_state,
601 + 'site_url' => $site_url,
602 + );
603 +
604 + $response = $this->wkit_api_call( $array_data, 'login/ip' );
605 + $success = ! empty( $response['success'] ) ? $response['success'] : false;
606 +
607 + if ( empty( $success ) ) {
608 + $result = array(
609 + 'data' => $response,
610 + 'success' => false,
611 + );
612 +
613 + wp_send_json( $result );
614 + wp_die();
615 + }
616 +
617 + $response = json_decode( wp_json_encode( $response['data'] ), true );
618 + $user_email = ! empty( $response['user']['user_email'] ) ? sanitize_email( $response['user']['user_email'] ) : '';
619 + $user_token = ! empty( $response['token'] ) ? sanitize_text_field( $response['token'] ) : '';
620 + $user_key = strstr( $user_email, '@', true );
621 +
622 + if ( ! empty( $response ) && ! empty( $user_token ) ) {
623 + $this->wdkit_set_time_out( $user_key, $user_email, $user_token, $login_type );
624 + }
625 +
626 + $result = array(
627 + 'data' => $response,
628 + 'token' => $user_token,
629 + );
630 +
631 + wp_send_json( $result );
632 + wp_die();
633 + }
634 +
635 + /**
636 + *
711 637 * It is Use for get meta data for non login user
712 638 *
713 - * @since 1.0.0
639 + * @since 1.0.0\
714 640 */
715 641 protected function wdkit_meta_data() {
716 642 $type = isset( $_POST['meta_type'] ) ? sanitize_text_field( wp_unslash( $_POST['meta_type'] ) ) : '';
717 643 $data = array( 'type' => $type );
@@ -755,49 +681,13 @@
755 681 }
756 682
757 683 /**
758 684 *
759 - * It is Use for get activate license key data from tpae and nexter blocks.
760 - *
761 - * @since 1.1.6
762 - */
763 - protected function wkit_manage_license_data() {
764 - $manage_licence = array();
765 - $theplus_active_check = is_plugin_active( 'the-plus-addons-for-elementor-page-builder/theplus_elementor_addon.php' );
766 - $nexter_active_check = is_plugin_active( 'the-plus-addons-for-block-editor/the-plus-addons-for-block-editor.php' );
767 -
768 - $theplus_licence = get_option( 'tpaep_licence_data', array() );
769 -
770 - // Also require the TPAE Pro plugin to be active (Pro defines THEPLUS_VERSION;
771 - // the free plugin defines L_THEPLUS_VERSION). This hides the "found active
772 - // key" notice when the Pro plugin is removed even though its licence option
773 - // still lingers in the database.
774 - if ( ! empty( $theplus_active_check ) && defined( 'THEPLUS_VERSION' ) && ! empty( $theplus_licence ) ) {
775 - $manage_licence['tpae'] = $theplus_licence;
776 - }
777 -
778 - $nexter_licence = get_option( 'tpgb_activate', array() );
779 -
780 - // Also require the Nexter Blocks Pro plugin to be active (Pro defines
781 - // TPGBP_VERSION; the free plugin defines TPGB_VERSION), so the notice hides
782 - // when the Pro plugin is removed but its licence option persists.
783 - if ( ! empty( $nexter_active_check ) && defined( 'TPGBP_VERSION' ) && ! empty( $nexter_licence ) && ! empty( $nexter_licence['tpgb_activate_key'] ) ) {
784 - $tpgb_license_status = get_option( 'tpgbp_license_status', array() );
785 - $tpgb_license_status['license_key'] = $nexter_licence['tpgb_activate_key'];
786 - $manage_licence['tpag'] = $tpgb_license_status;
787 - }
788 -
789 - return $manage_licence;
790 - }
791 -
792 - /**
793 - *
794 685 * It is Use for get all info of user.
795 686 *
796 687 * @since 1.0.0
797 688 */
798 689 protected function wdkit_get_user_info() {
799 - $token = isset( $_POST['token'] ) ? wp_unslash( $_POST['token'] ) : false;
800 690 $email = isset( $_POST['email'] ) ? strtolower( sanitize_email( wp_unslash( $_POST['email'] ) ) ) : false;
801 691 $builder = isset( $_POST['builder'] ) ? strtolower( sanitize_text_field( wp_unslash( $_POST['builder'] ) ) ) : '';
802 692
803 693 $site_url = isset( $_POST['site_url'] ) ? esc_url_raw( wp_unslash( $_POST['site_url'] ) ) : '';
@@ -803,9 +693,9 @@
803 693 $site_url = isset( $_POST['site_url'] ) ? esc_url_raw( wp_unslash( $_POST['site_url'] ) ) : '';
804 694
805 695 $response = array();
806 696
807 - if ( empty( $token ) ) {
697 + if ( empty( $email ) ) {
808 698 $response = array(
809 699 'success' => false,
810 700 'message' => $this->e_msg_login,
811 701 'description' => $this->e_desc_login,
@@ -814,10 +704,10 @@
814 704 wp_send_json( $response );
815 705 wp_die();
816 706 }
817 707
818 - // $token = $this->wdkit_login_user_token( $email );
819 - $args = array(
708 + $token = $this->wdkit_login_user_token( $email );
709 + $args = array(
820 710 'token' => $token,
821 711 'builder' => $builder,
822 712 'site_url' => $site_url,
823 713 );
@@ -822,48 +712,19 @@
822 712 'site_url' => $site_url,
823 713 );
824 714
825 715 $response = WDesignKit_Data_Query::get_data( 'get_user_info', $args );
826 -
827 - if ( is_wp_error( $response ) ) {
828 - wp_send_json( array(
829 - 'success' => false,
830 - 'message' => $response->get_error_message(),
831 - 'description' => $response->get_error_message(),
832 - ) );
833 - wp_die();
834 - }
835 -
836 716 $status = ( ! empty( $response['status'] ) ) ? sanitize_text_field( $response['status'] ) : 'error';
837 717 $email = isset( $_POST['email'] ) ? strtolower( sanitize_email( wp_unslash( $_POST['email'] ) ) ) : false;
838 718
839 719 /**Condtion user for user logout & expire token*/
840 720 if ( 'Token is Expired' === $status || 'Authorization Token not found' === $status ) {
841 - delete_transient( 'wdkit_auth_' . wdesignkit_cloud_session_key( $email ) );
842 - // Clear stored license data when token expires so banner shows again
843 - delete_option( 'wdkit_licence_data' );
721 + delete_transient( 'wdkit_auth_' . $email );
844 722 }
845 723
846 - if ( empty( $response ) ) {
847 - $response['login_reset'] = 'yes';
848 - }
724 + $response['Setting'] = $this->wkit_get_settings_panel();
725 + $response['widget_list'] = $this->wkit_manage_widget_sequence( $response );
849 726
850 - // Store WDesignKit license data locally if present in response
851 - if ( ! empty( $response['credits']['wdkit_licence'] ) && is_array( $response['credits']['wdkit_licence'] ) ) {
852 - $wdkit_licence = $response['credits']['wdkit_licence'];
853 - // Handle serialized data
854 - if ( is_string( $wdkit_licence ) && is_serialized( $wdkit_licence ) ) {
855 - $wdkit_licence = unserialize( $wdkit_licence, array( 'allowed_classes' => false ) );
856 - }
857 - if ( ! empty( $wdkit_licence ) && is_array( $wdkit_licence ) ) {
858 - update_option( 'wdkit_licence_data', $wdkit_licence );
859 - }
860 - }
861 -
862 - $response['Setting'] = $this->wkit_get_settings_panel();
863 - $response['widget_list'] = $this->wkit_manage_widget_sequence( $response );
864 - $response['manage_licence'] = $this->wkit_manage_license_data();
865 -
866 727 $response = array(
867 728 'data' => $response,
868 729 'success' => true,
869 730 );
@@ -884,16 +745,8 @@
884 745 $credits = ! empty( $response['credits']['widget_limit']['meta_value'] ) ? $response['credits']['widget_limit']['meta_value'] : 10;
885 746 $server_list = ! empty( $response['widgettemplate'] ) ? $response['widgettemplate'] : array();
886 747 $db_builder_list = ! empty( $response['widgetbuilder'] ) ? $response['widgetbuilder'] : array();
887 748
888 - // Whether this call actually carried the server widget list that activation state is
889 - // derived from. Captured before the loops below, which unset() matched $server_list
890 - // entries as they go. wdkit_meta_data() calls this method with array(), and without
891 - // this flag that call rebuilt $db_widget from local widgets only — every one of which
892 - // is forced 'active' further down — and then wrote the empty result over
893 - // wkit_deactivate_widgets, erasing every deactivation the user had made.
894 - $has_server_widgets = ! empty( $server_list );
895 -
896 749 $placeholderimg = WDKIT_URL . 'assets/images/placeholder.jpg';
897 750
898 751 $local_list = $this->wdkit_get_local_widgets();
899 752
@@ -900,13 +753,13 @@
900 753 $server_w_unique = array_column( $server_list, 'w_unique' );
901 754
902 755 $idx_builder = array();
903 756 foreach ( $db_builder_list as $index => $value ) {
904 - $builder_name = ! empty( $value['builder_slug'] ) ? $value['builder_slug'] : '';
757 + $builder_name = ! empty( $value['builder_name'] ) ? $value['builder_name'] : '';
905 758 $w_id = ! empty( $value['w_id'] ) ? $value['w_id'] : '';
906 759
907 760 if ( ! empty( $builder_name ) ) {
908 - $idx_builder[ $w_id ] = strtolower( str_replace( ' ', '_', trim( $builder_name ) ) );
761 + $idx_builder[ $w_id ] = strtolower( $builder_name );
909 762 }
910 763 }
911 764
912 765 foreach ( $server_list as $index => $value ) {
@@ -918,9 +771,9 @@
918 771
919 772 $count = 0;
920 773
921 774 foreach ( $local_list as $key => $value ) {
922 - $widget_id = ! empty( $value['widgetdata']['widget_id'] ) ? $value['widgetdata']['widget_id'] : '';
775 + $widget_id = ! empty( $value['widgetdata']['widget_id'] ) ? $value['widgetdata']['widget_id'] : '';
923 776 $allow_push = isset( $value['widgetdata']['allow_push'] ) ? $value['widgetdata']['allow_push'] : true;
924 777
925 778 if ( in_array( $widget_id, $server_w_unique ) ) {
926 779
@@ -940,9 +793,9 @@
940 793 unset( $server_list[ $index ] );
941 794 } else {
942 795 $local_list[ $key ]['widgetdata']['builder'] = $local_list[ $key ]['widgetdata']['type'];
943 796 $local_list[ $key ]['widgetdata']['w_unique'] = $local_list[ $key ]['widgetdata']['widget_id'];
944 - $local_list[ $key ]['widgetdata']['allow_push'] = $allow_push;
797 + $local_list[ $key ]['widgetdata']['allow_push'] = $allow_push;
945 798 $local_list[ $key ]['widgetdata']['image'] = ! empty( $local_list[ $key ]['widgetdata']['w_image'] ) ? $local_list[ $key ]['widgetdata']['w_image'] : $placeholderimg;
946 799 $local_list[ $key ]['widgetdata']['is_activated'] = 'active';
947 800
948 801 $local_list[ $key ]['widgetdata']['type'] = 'plugin';
@@ -965,9 +818,9 @@
965 818 if ( 'active' === $is_activated ) {
966 819 ++$count;
967 820 }
968 821
969 - if ( ( $count > $credits ) && ( 'unlimited' !== $credits ) ) {
822 + if ( ($count > $credits) && ('unlimited' !== $credits)) {
970 823 $final[ $key ]['is_activated'] = 'deactive';
971 824 }
972 825
973 826 if ( ! empty( $self['is_activated'] ) && 'active' !== $self['is_activated'] ) {
@@ -979,31 +832,13 @@
979 832 );
980 833 }
981 834 }
982 835
983 - // Only persist activation state when the server list it is derived from was actually
984 - // supplied. See $has_server_widgets above.
985 - if ( $has_server_widgets ) {
986 - // update_option() creates the row when it is missing, so it covers both cases.
987 - // The previous add_option()/update_option() split was chosen on empty( $option ),
988 - // but wdkit_db_widgetlist() creates this row as an empty array on every install —
989 - // so the empty branch ran while the row already existed, and add_option() is a
990 - // no-op for an existing option. Deactivating from the My Widgets screen was
991 - // therefore silently discarded on effectively every site. Autoload stays 'yes',
992 - // matching the original add_option() call and wdkit_db_widgetlist().
993 - update_option( 'wkit_deactivate_widgets', $db_widget, 'yes' );
994 -
995 - // The cached widget registry bakes in wkit_deactivate_widgets membership and is
996 - // stored as a no-expiry transient, so it never self-heals. Without this the
997 - // loaders kept registering a widget the user had just switched off (and kept
998 - // hiding one they had switched back on) until the transient was flushed by hand.
999 - // The write above is not per-builder — one save can change any builder's set, and
1000 - // a widget can move between builders — so clear all four.
1001 - if ( function_exists( 'wdesignkit_invalidate_widget_registry' ) ) {
1002 - foreach ( array( 'elementor', 'gutenberg', 'gutenberg_core', 'bricks' ) as $builder_slug ) {
1003 - wdesignkit_invalidate_widget_registry( $builder_slug );
1004 - }
1005 - }
836 + $get_db_widget = get_option( 'wkit_deactivate_widgets', array() );
837 + if ( empty( $get_db_widget ) ) {
838 + add_option( 'wkit_deactivate_widgets', $db_widget, '', 'yes' );
839 + } else {
840 + update_option( 'wkit_deactivate_widgets', $db_widget );
1006 841 }
1007 842
1008 843 return $final;
1009 844 }
@@ -1017,21 +852,47 @@
1017 852 $args = $this->wdkit_parse_args( $_POST );
1018 853
1019 854 $response = WDesignKit_Data_Query::get_data( 'browse_page', $args );
1020 855
1021 - if ( is_wp_error( $response ) ) {
1022 - wp_send_json( array(
1023 - 'success' => false,
1024 - 'message' => $response->get_error_message(),
1025 - ) );
856 + wp_send_json( $response );
857 + wp_die();
858 + }
859 +
860 + /**
861 + *
862 + * It is Use to get data for widget browse page
863 + *
864 + * @since 1.0.0
865 + */
866 + protected function wdkit_widget_browse_page() {
867 + $array_data = array(
868 + 'CurrentPage' => isset( $_POST['page'] ) ? (int) $_POST['page'] : 1,
869 + 'builder' => isset( $_POST['buildertype'] ) ? wp_unslash( $_POST['buildertype'] ) : '',
870 + 'category' => isset( $_POST['category'] ) ? sanitize_text_field( wp_unslash( $_POST['category'] ) ) : '',
871 + 'ParPage' => isset( $_POST['perpage'] ) ? (int) $_POST['perpage'] : 12,
872 + 'search' => isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : '',
873 + 'free_pro' => isset( $_POST['free_pro'] ) ? sanitize_text_field( wp_unslash( $_POST['free_pro'] ) ) : '',
874 + );
875 +
876 + $response = $this->wkit_api_call( $array_data, 'browse_widget' );
877 + $success = ! empty( $response['success'] ) ? $response['success'] : false;
878 +
879 + if ( empty( $success ) ) {
880 + $response = array(
881 + 'success' => false,
882 + 'message' => esc_html__( 'Data Not Found', 'wdesignkit' ),
883 + 'description' => esc_html__( 'Widget List Not Found', 'wdesignkit' ),
884 +
885 + 'widgets' => array(),
886 + 'widgetscount' => 0,
887 + 'showwidgets' => 0,
888 + );
889 +
890 + wp_send_json( $response );
1026 891 wp_die();
1027 892 }
1028 893
1029 - $manage_licence = array();
1030 - $manage_licence['theplus_elementor_addon'] = ! empty( defined( 'THEPLUS_VERSION' ) ) ? true : false;
1031 - $manage_licence['tpag'] = ! empty( defined( 'TPGBP_VERSION' ) ) ? true : false;
1032 - $manage_licence['elementor-pro'] = ! empty( defined( 'ELEMENTOR_PRO_VERSION' ) ) ? true : false;
1033 - $response['manage_licence'] = $manage_licence;
894 + $response = json_decode( wp_json_encode( $response['data'] ), true );
1034 895
1035 896 wp_send_json( $response );
1036 897 wp_die();
1037 898 }
@@ -1062,14 +923,15 @@
1062 923
1063 924 $user_email = strtolower( sanitize_email( $args['email'] ) );
1064 925 $response = '';
1065 926
1066 - // Bug D fix: response()->json() is Laravel syntax — causes PHP fatal. Use plain array.
1067 927 if ( empty( $user_email ) || empty( $args['template_id'] ) ) {
1068 - $response = array(
1069 - 'message' => $this->e_msg_login,
1070 - 'description' => $this->e_desc_login,
1071 - 'success' => false,
928 + $response = response()->json(
929 + array(
930 + 'message' => $this->e_msg_login,
931 + 'description' => $this->e_desc_login,
932 + 'success' => true,
933 + )
1072 934 );
1073 935
1074 936 wp_send_json( $response );
1075 937 wp_die();
@@ -1090,12 +952,9 @@
1090 952 *
1091 953 * @since 1.0.0
1092 954 */
1093 955 protected function wdkit_put_save_template() {
1094 - $email = isset( $_POST['email'] ) ? strtolower( sanitize_email( wp_unslash( $_POST['email'] ) ) ) : false;
1095 - $post_id = isset( $_POST['post_id'] ) ? sanitize_text_field( wp_unslash( $_POST['post_id'] ) ) : '';
1096 - $builder = isset( $_POST['builder'] ) ? sanitize_text_field( wp_unslash( $_POST['builder'] ) ) : '';
1097 -
956 + $email = isset( $_POST['email'] ) ? strtolower( sanitize_email( wp_unslash( $_POST['email'] ) ) ) : false;
1098 957 $response = '';
1099 958
1100 959 if ( empty( $email ) ) {
1101 960 $response = array(
@@ -1113,19 +972,14 @@
1113 972 $args = $this->wdkit_parse_args( $_POST );
1114 973 $args['token'] = $this->wdkit_login_user_token( $email );
1115 974 unset( $args['email'] );
1116 975
1117 - if( 'elementor' === $builder ){
1118 - $args['data'] = base64_decode( $args['data'] );
1119 - } else if ( 'gutenberg' === $builder ) {
1120 - $args['data'] = base64_decode( $args['data'] );
1121 - }
1122 -
1123 976 global $post;
1124 977
978 + $post_id = get_the_ID();
1125 979 $custom_fields = array();
1126 980 if ( ! empty( $post_id ) ) {
1127 - $meta_fields = get_post_custom( $post_id );
981 + $meta_fields = get_post_custom( get_the_ID() );
1128 982
1129 983 foreach ( $meta_fields as $key => $value ) {
1130 984 if ( str_contains( $key, 'nxt-' ) ) {
1131 985 $custom_fields[ $key ] = $value;
@@ -1140,24 +994,8 @@
1140 994 }
1141 995
1142 996 $response = WDesignKit_Data_Query::get_data( 'save_template', $args );
1143 997
1144 - /**
1145 - * The cloud call can come back as a WP_Error (timeout, DNS, refused) or with an
1146 - * empty / unparsable body, which json_decode()s to null. Forwarding that as-is
1147 - * makes admin-ajax answer with a literal `null` that the editor then reads
1148 - * `.id` off, killing the whole app. Normalise it to the failure shape used above.
1149 - */
1150 - if ( is_wp_error( $response ) || ! is_array( $response ) ) {
1151 - $response = array(
1152 - 'id' => 0,
1153 - 'editpage' => '',
1154 - 'message' => esc_html__( 'Template Not Saved !', 'wdesignkit' ),
1155 - 'description' => is_wp_error( $response ) ? $response->get_error_message() : esc_html__( 'Could not reach the WDesignKit server. Please try again.', 'wdesignkit' ),
1156 - 'success' => false,
1157 - );
1158 - }
1159 -
1160 998 wp_send_json( $response );
1161 999 wp_die();
1162 1000 }
1163 1001
@@ -1162,1344 +1000,8 @@
1162 1000 }
1163 1001
1164 1002 /**
1165 1003 *
1166 - * It is Use for update save template image.
1167 - *
1168 - * @since 2.0.6
1169 - */
1170 - protected function wdkit_update_save_temp_image() {
1171 - $temp_content = isset( $_POST['temp_content'] ) ? esc_url_raw( $_POST['temp_content'] ) : '';
1172 - $content_name = isset( $_POST['content_name'] ) ? sanitize_text_field( $_POST['content_name'] ) : '';
1173 - $token = isset( $_POST['token'] ) ? sanitize_text_field( $_POST['token'] ) : '';
1174 - $user_type = isset( $_POST['user_type'] ) ? sanitize_text_field( $_POST['user_type'] ) : '';
1175 - $type = isset( $_POST['content_type'] ) ? sanitize_text_field( $_POST['content_type'] ) : '';
1176 - $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : '';
1177 - if ( empty( $temp_content ) || empty( $user_type ) || empty( $id ) || empty( $token ) ) {
1178 - $response = array(
1179 - 'message' => __( 'Data not found', 'wdesignkit' ),
1180 - 'description' => __( 'Data not found', 'wdesignkit' ),
1181 - 'success' => false,
1182 - );
1183 - } else {
1184 - $temp_content = str_replace( '\\', '', $temp_content );
1185 - // SSRF guard (CWE-918): validate the resolved host before fetching a caller-supplied URL.
1186 - $fetched = wdesignkit_safe_remote_get( $temp_content );
1187 - $temp_content = is_wp_error( $fetched ) ? '' : wp_remote_retrieve_body( $fetched );
1188 - $temp_content = base64_encode( $temp_content );
1189 -
1190 - $args = array(
1191 - 'token' => $token,
1192 - 'template_id' => $id,
1193 - 'name' => $content_name,
1194 - 'content' => $temp_content,
1195 - 'type' => $type,
1196 - );
1197 -
1198 - $response = $this->wkit_api_call( $args, 'save_images' );
1199 - $success = ! empty( $response['success'] ) ? $response['success'] : false;
1200 -
1201 - if ( $success ) {
1202 - $response = array(
1203 - 'data' => $response['data'],
1204 - 'success' => true,
1205 - );
1206 - } else {
1207 - $response = array(
1208 - 'message' => __( 'API Error', 'wdesignkit' ),
1209 - 'description' => __( 'API Error', 'wdesignkit' ),
1210 - 'data' => $response['data'],
1211 - 'success' => false,
1212 - );
1213 - }
1214 - }
1215 -
1216 - wp_send_json( $response );
1217 - wp_die();
1218 - }
1219 -
1220 - /**
1221 - *
1222 - * It is Use for save image to WordPress Media Library.
1223 - *
1224 - * @since 2.3.3
1225 - */
1226 - protected function wdkit_save_wp_images() {
1227 -
1228 - // media_sideload_image() generates every registered thumbnail size, which decodes
1229 - // the full source bitmap. Same guard as the page import.
1230 - $this->wdkit_guard_oversized_images();
1231 -
1232 - $image_url = isset( $_POST['image'] ) ? sanitize_text_field( $_POST['image'] ) : '';
1233 -
1234 - if ( empty( $image_url ) ) {
1235 - $response = array(
1236 - 'message' => __( 'No Image Provided', 'wdesignkit' ),
1237 - 'description' => __( 'No Image URL provided for save.', 'wdesignkit' ),
1238 - 'success' => false,
1239 - );
1240 - } else {
1241 -
1242 - $attachment_id = media_sideload_image( $image_url, 0, null, 'id' );
1243 -
1244 - if ( is_wp_error( $attachment_id ) ) {
1245 - $response = array(
1246 - 'message' => __( 'Upload Failed', 'wdesignkit' ),
1247 - 'description' => $attachment_id->get_error_message(),
1248 - 'success' => false,
1249 - );
1250 - } else {
1251 - $saved_url = wp_get_attachment_url( $attachment_id );
1252 -
1253 - // Elementor's importer skips an image only when it finds
1254 - // _elementor_source_image_hash matching sha1 of the URL it is given. The
1255 - // content we hand it now carries this local URL, so stamp the hash of that
1256 - // URL too - without it Elementor re-downloads a file already on disk and
1257 - // leaves a "-1" duplicate behind for every image on every page that uses it.
1258 - if ( $saved_url ) {
1259 - update_post_meta( $attachment_id, '_elementor_source_image_hash', sha1( $saved_url ) );
1260 -
1261 - // Same purpose for the block importer, which keys off its own meta.
1262 - update_post_meta( $attachment_id, 'tpgb_source_image_key', sha1( $saved_url ) );
1263 - }
1264 -
1265 - $response = array(
1266 - 'message' => __( 'Image Saved', 'wdesignkit' ),
1267 - 'description' => __( 'Image successfully saved to Media Library.', 'wdesignkit' ),
1268 - 'success' => true,
1269 - 'url' => $saved_url,
1270 - );
1271 - }
1272 -
1273 - }
1274 -
1275 - wp_send_json( $response );
1276 - wp_die();
1277 - }
1278 -
1279 - /**
1280 - *
1281 - * Get Elementor Global color and Typography.
1282 - *
1283 - * @since 1.1.16
1284 - */
1285 - /**
1286 - * Kit settings holding The Plus Addons' own globals.
1287 - *
1288 - * These sit in the Elementor kit's `_elementor_page_settings` alongside Elementor's
1289 - * system_colors / system_typography, but the save flow only ever collected the four
1290 - * Elementor keys. Widgets reference an entry in these lists by its `_id` through a
1291 - * `tp_global_preset` setting, so a template saved without them travels with the
1292 - * reference but not the definition - which is why imported sections come in missing
1293 - * their button styling, radii and shadows.
1294 - *
1295 - * @since 2.6.4
1296 - *
1297 - * @return array Kit setting keys.
1298 - */
1299 - private function wdkit_tp_global_kit_keys() {
1300 - return array(
1301 - 'tp_global_button_style_list',
1302 - 'tp_global_dimensions_list',
1303 - 'tp_global_box_shadow_list',
1304 - 'tp_global_gradient_list',
1305 - 'tp_global_gsap_list',
1306 - 'tp_global_scroll_animation_list',
1307 - 'tp_text_global_gsap_list',
1308 - 'tp_image_global_gsap_list',
1309 - );
1310 - }
1311 -
1312 - /**
1313 - * Merge incoming Plus globals into the active kit, keyed by `_id`.
1314 - *
1315 - * Entries are matched on their `_id`, never on position: an existing entry is always
1316 - * left as it is, and only genuinely new ones are appended. That matters because
1317 - * widgets - and the entries themselves, a button style points at dimension and shadow
1318 - * entries - resolve by `_id`. Renumbering or overwriting would repoint references on
1319 - * the destination site's own content.
1320 - *
1321 - * @since 2.6.4
1322 - *
1323 - * @param array $incoming Lists captured with the template.
1324 - * @return bool True when the kit was changed.
1325 - */
1326 - /**
1327 - * Global colour / typography ids this site already defines.
1328 - *
1329 - * @since 2.6.4
1330 - *
1331 - * @param array $kit_meta Kit `_elementor_page_settings`.
1332 - * @return array{color:array<string,bool>,typography:array<string,bool>}
1333 - */
1334 - private function wdkit_known_global_ids( $kit_meta ) {
1335 - $known = array(
1336 - 'color' => array(),
1337 - 'typography' => array(),
1338 - );
1339 -
1340 - $sources = array(
1341 - 'color' => array( 'system_colors', 'custom_colors' ),
1342 - 'typography' => array( 'system_typography', 'custom_typography' ),
1343 - );
1344 -
1345 - foreach ( $sources as $kind => $keys ) {
1346 - foreach ( $keys as $key ) {
1347 - if ( empty( $kit_meta[ $key ] ) || ! is_array( $kit_meta[ $key ] ) ) {
1348 - continue;
1349 - }
1350 -
1351 - foreach ( $kit_meta[ $key ] as $entry ) {
1352 - if ( ! empty( $entry['_id'] ) ) {
1353 - $known[ $kind ][ $entry['_id'] ] = true;
1354 - }
1355 - }
1356 - }
1357 - }
1358 -
1359 - return $known;
1360 - }
1361 -
1362 - /**
1363 - * Make one incoming Plus global's colour / font references resolvable here.
1364 - *
1365 - * A Plus global can point at an Elementor global: the "Primary Button" entry holds
1366 - * `__globals__: { text_color: "globals/colors?id=72e09b4", … }`, which The Plus Addons
1367 - * turns into `var(--e-global-color-72e09b4)`. Elementor only emits that variable for ids
1368 - * present in the kit, so on a site without `72e09b4` the button renders with no colour.
1369 - *
1370 - * Two cases, and the difference is deliberate:
1371 - *
1372 - * - The site ALREADY defines that id — leave the reference alone. The button then picks
1373 - * up the destination's own colour, which is the point of a global. Their palette is
1374 - * never read from or written to beyond this check.
1375 - * - The site does NOT define it — write the captured value straight into the entry and
1376 - * drop the reference, so it renders as designed.
1377 - *
1378 - * Nothing is ever added to the user's global colours or fonts. An earlier version injected
1379 - * the missing definitions into their palette, which made the reference resolve but grew
1380 - * their Site Settings by every colour an imported template happened to use.
1381 - *
1382 - * @since 2.6.4
1383 - *
1384 - * @param array $entry One repeater entry.
1385 - * @param array $refs Definitions captured with the template.
1386 - * @param array $known Ids this site defines, from wdkit_known_global_ids().
1387 - * @return array Entry, with unresolvable references replaced by their values.
1388 - */
1389 - private function wdkit_resolve_entry_globals( $entry, $refs, $known ) {
1390 - if ( empty( $entry['__globals__'] ) || ! is_array( $entry['__globals__'] ) ) {
1391 - return $entry;
1392 - }
1393 -
1394 - foreach ( $entry['__globals__'] as $control => $ref ) {
1395 - if ( ! is_string( $ref ) || false === strpos( $ref, 'id=' ) ) {
1396 - continue;
1397 - }
1398 -
1399 - if ( false !== strpos( $ref, 'globals/colors' ) ) {
1400 - $kind = 'color';
1401 - } elseif ( false !== strpos( $ref, 'globals/typography' ) ) {
1402 - $kind = 'typography';
1403 - } else {
1404 - continue;
1405 - }
1406 -
1407 - $id = substr( $ref, strpos( $ref, 'id=' ) + 3 );
1408 - if ( '' === $id || isset( $known[ $kind ][ $id ] ) ) {
1409 - // Defined here already — their value wins.
1410 - continue;
1411 - }
1412 -
1413 - $definition = null;
1414 - foreach ( ( $refs[ $kind ] ?? array() ) as $candidate ) {
1415 - if ( is_array( $candidate ) && ( $candidate['_id'] ?? '' ) === $id ) {
1416 - $definition = $candidate;
1417 - break;
1418 - }
1419 - }
1420 -
1421 - if ( null === $definition ) {
1422 - // Nothing captured for it, so leave the reference rather than blank the field.
1423 - continue;
1424 - }
1425 -
1426 - if ( 'color' === $kind ) {
1427 - if ( empty( $definition['color'] ) ) {
1428 - continue;
1429 - }
1430 -
1431 - $entry[ $control ] = $definition['color'];
1432 - } else {
1433 - // A typography global expands into its own set of controls: the reference is
1434 - // held under e.g. `typography_typography`, and each definition key replaces
1435 - // that suffix — `typography_font_family`, `typography_font_weight`, and so on.
1436 - foreach ( $definition as $def_key => $def_value ) {
1437 - if ( '_id' === $def_key || 'title' === $def_key ) {
1438 - continue;
1439 - }
1440 -
1441 - $entry[ str_replace( 'typography_typography', $def_key, $control ) ] = $def_value;
1442 - }
1443 - }
1444 -
1445 - unset( $entry['__globals__'][ $control ] );
1446 - }
1447 -
1448 - return $entry;
1449 - }
1450 -
1451 - private function wdkit_merge_tp_globals( $incoming, $refs = array() ) {
1452 - if ( empty( $incoming ) || ! is_array( $incoming ) ) {
1453 - return false;
1454 - }
1455 -
1456 - $kit_id = get_option( 'elementor_active_kit' );
1457 - if ( empty( $kit_id ) ) {
1458 - return false;
1459 - }
1460 -
1461 - $kit_meta = get_post_meta( $kit_id, '_elementor_page_settings', true );
1462 - if ( ! is_array( $kit_meta ) ) {
1463 - $kit_meta = array();
1464 - }
1465 -
1466 - // Which global ids this site already defines. The Plus Addons turns a reference into
1467 - // var(--e-global-color-<_id>), and Elementor only emits that variable for ids in the
1468 - // kit — so a reference the destination does not define resolves to nothing at all.
1469 - $known = $this->wdkit_known_global_ids( $kit_meta );
1470 -
1471 - $changed = false;
1472 -
1473 - foreach ( $this->wdkit_tp_global_kit_keys() as $key ) {
1474 - if ( empty( $incoming[ $key ] ) || ! is_array( $incoming[ $key ] ) ) {
1475 - continue;
1476 - }
1477 -
1478 - $existing = ( ! empty( $kit_meta[ $key ] ) && is_array( $kit_meta[ $key ] ) ) ? $kit_meta[ $key ] : array();
1479 -
1480 - $seen = array();
1481 - foreach ( $existing as $entry ) {
1482 - if ( ! empty( $entry['_id'] ) ) {
1483 - $seen[ $entry['_id'] ] = true;
1484 - }
1485 - }
1486 -
1487 - foreach ( $incoming[ $key ] as $entry ) {
1488 - if ( ! is_array( $entry ) || empty( $entry['_id'] ) || isset( $seen[ $entry['_id'] ] ) ) {
1489 - continue;
1490 - }
1491 -
1492 - // Only ever rewrite the entry being added — never one already in the kit.
1493 - $existing[] = $this->wdkit_resolve_entry_globals( $entry, $refs, $known );
1494 - $seen[ $entry['_id'] ] = true;
1495 - $changed = true;
1496 - }
1497 -
1498 - $kit_meta[ $key ] = array_values( $existing );
1499 - }
1500 -
1501 - if ( $changed ) {
1502 - update_post_meta( $kit_id, '_elementor_page_settings', $kit_meta );
1503 -
1504 - // Writing kit meta directly does not rebuild the kit stylesheet, so the
1505 - // merged globals would never reach the frontend.
1506 - $this->wdkit_regenerate_elementor_kit_css();
1507 - }
1508 -
1509 - return $changed;
1510 - }
1511 -
1512 - protected function wdkit_get_global_val() {
1513 -
1514 - $builder = isset( $_POST['builder'] ) ? strtolower( sanitize_text_field( $_POST['builder'] ) ) : '';
1515 -
1516 - if ( 'elementor' === $builder ) {
1517 - $kit_id = get_option( 'elementor_active_kit' );
1518 - if ( empty( $kit_id ) ) {
1519 - $response = array(
1520 - 'message' => __( 'Elementor kit not found', 'wdesignkit' ),
1521 - 'description' => __( 'No active Elementor kit found', 'wdesignkit' ),
1522 - 'success' => false,
1523 - );
1524 -
1525 - wp_send_json( $response );
1526 - wp_die();
1527 - }
1528 -
1529 - $kit_meta = get_post_meta( $kit_id, '_elementor_page_settings', true );
1530 - if ( empty( $kit_meta['system_colors'] ) ) {
1531 - $static_meta = array(
1532 - 'system_colors' => array(
1533 - 0 => array(
1534 - '_id' => 'primary',
1535 - 'title' => 'Primary',
1536 - 'color' => '#6EC1E4',
1537 - ),
1538 - 1 => array(
1539 - '_id' => 'secondary',
1540 - 'title' => 'Secondary',
1541 - 'color' => '#54595F',
1542 - ),
1543 - 2 => array(
1544 - '_id' => 'text',
1545 - 'title' => 'Text',
1546 - 'color' => '#7A7A7A',
1547 - ),
1548 - 3 => array(
1549 - '_id' => 'accent',
1550 - 'title' => 'Accent',
1551 - 'color' => '#61CE70',
1552 - ),
1553 - ),
1554 - 'custom_colors' => array(),
1555 - 'system_typography' => array(
1556 - 0 => array(
1557 - '_id' => 'primary',
1558 - 'title' => 'Primary',
1559 - 'typography_typography' => 'custom',
1560 - 'typography_font_family' => 'Roboto',
1561 - 'typography_font_weight' => '600',
1562 - ),
1563 - 1 => array(
1564 - '_id' => 'secondary',
1565 - 'title' => 'Secondary',
1566 - 'typography_typography' => 'custom',
1567 - 'typography_font_family' => 'Roboto Slab',
1568 - 'typography_font_weight' => '400',
1569 - ),
1570 - 2 => array(
1571 - '_id' => 'text',
1572 - 'title' => 'Text',
1573 - 'typography_typography' => 'custom',
1574 - 'typography_font_family' => 'Roboto',
1575 - 'typography_font_weight' => '400',
1576 - ),
1577 - 3 => array(
1578 - '_id' => 'accent',
1579 - 'title' => 'Accent',
1580 - 'typography_typography' => 'custom',
1581 - 'typography_font_family' => 'Roboto',
1582 - 'typography_font_weight' => '500',
1583 - ),
1584 - ),
1585 - 'custom_typography' => array(),
1586 - 'default_generic_fonts' => 'Sans-serif',
1587 - 'site_name' => ! empty( get_bloginfo( 'name' ) ) ? get_bloginfo( 'name' ) : '',
1588 - 'page_title_selector' => 'h1.entry-title',
1589 - 'activeItemIndex' => 1,
1590 - 'viewport_md' => 768,
1591 - 'viewport_lg' => 1025,
1592 - );
1593 -
1594 - $kit_meta = $static_meta;
1595 - update_post_meta( $kit_id, '_elementor_page_settings', $kit_meta );
1596 - }
1597 -
1598 - $system_colors = ! empty( $kit_meta['system_colors'] ) ? $kit_meta['system_colors'] : array();
1599 - $custom_colors = ! empty( $kit_meta['custom_colors'] ) ? $kit_meta['custom_colors'] : array();
1600 - $system_typography = ! empty( $kit_meta['system_typography'] ) ? $kit_meta['system_typography'] : array();
1601 - $custom_typography = ! empty( $kit_meta['custom_typography'] ) ? $kit_meta['custom_typography'] : array();
1602 -
1603 - $color_array = array_merge( $system_colors, $custom_colors );
1604 - $typo_array = array_merge( $system_typography, $custom_typography );
1605 -
1606 - $global_data = array(
1607 - 'color' => $color_array,
1608 - 'typography' => $typo_array,
1609 - );
1610 -
1611 - $response = array(
1612 - 'message' => __( 'Global data Found', 'wdesignkit' ),
1613 - 'description' => __( 'Global Color and Typography found', 'wdesignkit' ),
1614 - 'data' => $global_data,
1615 - 'success' => true,
1616 - );
1617 -
1618 - } elseif ( 'gutenberg' === $builder ) {
1619 -
1620 - $plus_settings = get_option( 'tpgb_global_options', false );
1621 - $plus_settings = ! empty( $plus_settings ) ? json_decode( $plus_settings, true ) : json_decode( '[]' );
1622 -
1623 - if ( empty( $plus_settings ) ) {
1624 -
1625 - $static_meta = array(
1626 - 'active' => 'preset1',
1627 - 'darkMode' => 'none',
1628 - 'presets' => array(
1629 - 'preset1' => array(
1630 - 'name' => 'Preset 1',
1631 - 'key' => 'preset1',
1632 - 'colors' => array(
1633 - array(
1634 - 'label' => 'Primary',
1635 - 'value' => '#8072FC',
1636 - ),
1637 - array(
1638 - 'label' => 'Secondary',
1639 - 'value' => '#6FC784',
1640 - ),
1641 - array(
1642 - 'label' => 'Tertiary',
1643 - 'value' => '#FF5A6E',
1644 - ),
1645 - array(
1646 - 'label' => 'Accent',
1647 - 'value' => '#F3F3F3',
1648 - ),
1649 - array(
1650 - 'label' => 'Background',
1651 - 'value' => '#888888',
1652 - ),
1653 - ),
1654 - 'gradient' => array(
1655 - array(
1656 - 'label' => 'Primary',
1657 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1658 - ),
1659 -
1660 - array(
1661 - 'label' => 'Secondary',
1662 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1663 - ),
1664 -
1665 - array(
1666 - 'label' => 'Tertiary',
1667 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1668 - ),
1669 -
1670 - array(
1671 - 'label' => 'Accent',
1672 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1673 - ),
1674 -
1675 - array(
1676 - 'label' => 'Background',
1677 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1678 - ),
1679 - ),
1680 - 'spacing' => array(
1681 - array(
1682 - 'label' => 'Large',
1683 - 'value' => array(
1684 - 'md' => 70,
1685 - 'unit' => 'px',
1686 - ),
1687 - ),
1688 - array(
1689 - 'label' => 'Medium',
1690 - 'value' => array(
1691 - 'md' => 40,
1692 - 'unit' => 'px',
1693 - ),
1694 - ),
1695 - array(
1696 - 'label' => 'Small',
1697 - 'value' => array(
1698 - 'md' => 20,
1699 - 'unit' => 'px',
1700 - ),
1701 -
1702 - ),
1703 - ),
1704 - 'typography' => array(
1705 - array(
1706 - 'label' => 'Display Text',
1707 - 'value' => array(
1708 - 'openTypography' => 1,
1709 - 'size' => array(
1710 - 'md' => 65,
1711 - 'unit' => 'px',
1712 - ),
1713 - 'height' => array(
1714 - 'md' => 75,
1715 - 'unit' => 'px',
1716 - ),
1717 - 'fontFamily' => array(
1718 - 'family' => 'Roboto',
1719 - 'type' => 'sans-serif',
1720 - 'fontWeight' => 700,
1721 - ),
1722 - 'spacing' => array(
1723 - 'md' => 0,
1724 - 'unit' => 'px',
1725 - ),
1726 - ),
1727 - ),
1728 - array(
1729 - 'label' => 'Headline',
1730 - 'value' => array(
1731 - 'openTypography' => 1,
1732 - 'size' => array(
1733 - 'md' => 45,
1734 - 'unit' => 'px',
1735 - ),
1736 - 'height' => array(
1737 - 'md' => 60,
1738 - 'unit' => 'px',
1739 - ),
1740 - 'fontFamily' => array(
1741 - 'family' => 'Roboto',
1742 - 'type' => 'sans-serif',
1743 - 'fontWeight' => 700,
1744 - ),
1745 - 'spacing' => array(
1746 - 'md' => 0,
1747 - 'unit' => 'px',
1748 - ),
1749 - ),
1750 - ),
1751 - array(
1752 - 'label' => 'Sub Headline',
1753 - 'value' => array(
1754 - 'openTypography' => 1,
1755 - 'size' => array(
1756 - 'md' => 38,
1757 - 'unit' => 'px',
1758 - ),
1759 - 'height' => array(
1760 - 'md' => 45,
1761 - 'unit' => 'px',
1762 - ),
1763 - 'fontFamily' => array(
1764 - 'family' => 'Roboto',
1765 - 'type' => 'sans-serif',
1766 - 'fontWeight' => 500,
1767 - ),
1768 - 'spacing' => array(
1769 - 'md' => 0,
1770 - 'unit' => 'px',
1771 - ),
1772 - ),
1773 - ),
1774 - array(
1775 - 'label' => 'Title 1',
1776 - 'value' => array(
1777 - 'openTypography' => 1,
1778 - 'size' => array(
1779 - 'md' => 30,
1780 - 'unit' => 'px',
1781 - ),
1782 - 'height' => array(
1783 - 'md' => 40,
1784 - 'unit' => 'px',
1785 - ),
1786 - 'fontFamily' => array(
1787 - 'family' => 'Roboto',
1788 - 'type' => 'sans-serif',
1789 - 'fontWeight' => 500,
1790 - ),
1791 - 'spacing' => array(
1792 - 'md' => 0,
1793 - 'unit' => 'px',
1794 - ),
1795 - ),
1796 - ),
1797 - array(
1798 - 'label' => 'Title 2',
1799 - 'value' => array(
1800 - 'openTypography' => 1,
1801 - 'size' => array(
1802 - 'md' => 25,
1803 - 'unit' => 'px',
1804 - ),
1805 - 'height' => array(
1806 - 'md' => 30,
1807 - 'unit' => 'px',
1808 - ),
1809 - 'fontFamily' => array(
1810 - 'family' => 'Roboto',
1811 - 'type' => 'sans-serif',
1812 - 'fontWeight' => 400,
1813 - ),
1814 - 'spacing' => array(
1815 - 'md' => 0,
1816 - 'unit' => 'px',
1817 - ),
1818 - ),
1819 - ),
1820 - array(
1821 - 'label' => 'Body',
1822 - 'value' => array(
1823 - 'openTypography' => 1,
1824 - 'size' => array(
1825 - 'md' => 17,
1826 - 'unit' => 'px',
1827 - ),
1828 - 'height' => array(
1829 - 'md' => 22,
1830 - 'unit' => 'px',
1831 - ),
1832 - 'fontFamily' => array(
1833 - 'family' => 'Roboto',
1834 - 'type' => 'sans-serif',
1835 - 'fontWeight' => 400,
1836 - ),
1837 - 'spacing' => array(
1838 - 'md' => 0,
1839 - 'unit' => 'px',
1840 - ),
1841 - ),
1842 - ),
1843 - array(
1844 - 'label' => 'Captions',
1845 - 'value' => array(
1846 - 'openTypography' => 1,
1847 - 'size' => array(
1848 - 'md' => 13,
1849 - 'unit' => 'px',
1850 - ),
1851 - 'height' => array(
1852 - 'md' => 16,
1853 - 'unit' => 'px',
1854 - ),
1855 - 'fontFamily' => array(
1856 - 'family' => 'Roboto',
1857 - 'type' => 'sans-serif',
1858 - 'fontWeight' => 400,
1859 - ),
1860 - 'spacing' => array(
1861 - 'md' => 0,
1862 - 'unit' => 'px',
1863 - ),
1864 - ),
1865 - ),
1866 - ),
1867 - 'boxshadow' => array(
1868 - array(
1869 - 'label' => 'Normal Shadow',
1870 - 'value' => array(
1871 - 'openShadow' => 1,
1872 - 'inset' => 0,
1873 - 'horizontal' => 2,
1874 - 'vertical' => 6,
1875 - 'blur' => 10,
1876 - 'spread' => 0,
1877 - 'color' => 'rgba(0,0,0,0.15)',
1878 - ),
1879 - ),
1880 - array(
1881 - 'label' => 'Hover Shadow',
1882 - 'value' => array(
1883 - 'openShadow' => 1,
1884 - 'inset' => 0,
1885 - 'horizontal' => 2,
1886 - 'vertical' => 5,
1887 - 'blur' => 14,
1888 - 'spread' => 3,
1889 - 'color' => 'rgba(0,0,0,0.2)',
1890 - ),
1891 - ),
1892 - ),
1893 - ),
1894 - 'preset2' => array(
1895 - 'name' => 'Preset 2',
1896 - 'key' => 'preset2',
1897 - 'colors' => array(
1898 - array(
1899 - 'label' => 'Primary',
1900 - 'value' => '#8072FC',
1901 - ),
1902 - array(
1903 - 'label' => 'Secondary',
1904 - 'value' => '#6FC784',
1905 - ),
1906 - array(
1907 - 'label' => 'Tertiary',
1908 - 'value' => '#FF5A6E',
1909 - ),
1910 - array(
1911 - 'label' => 'Accent',
1912 - 'value' => '#F3F3F3',
1913 - ),
1914 - array(
1915 - 'label' => 'Background',
1916 - 'value' => '#888888',
1917 - ),
1918 - ),
1919 - 'gradient' => array(
1920 - array(
1921 - 'label' => 'Primary',
1922 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1923 - ),
1924 -
1925 - array(
1926 - 'label' => 'Secondary',
1927 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1928 - ),
1929 -
1930 - array(
1931 - 'label' => 'Tertiary',
1932 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1933 - ),
1934 -
1935 - array(
1936 - 'label' => 'Accent',
1937 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1938 - ),
1939 -
1940 - array(
1941 - 'label' => 'Background',
1942 - 'value' => 'linear-gradient(135deg,rgb(8,148,229) 0%,rgb(155,81,224) 100%)',
1943 - ),
1944 - ),
1945 - 'spacing' => array(
1946 - array(
1947 - 'label' => 'Large',
1948 - 'value' => array(
1949 - 'md' => 70,
1950 - 'unit' => 'px',
1951 - ),
1952 - ),
1953 - array(
1954 - 'label' => 'Medium',
1955 - 'value' => array(
1956 - 'md' => 40,
1957 - 'unit' => 'px',
1958 - ),
1959 - ),
1960 - array(
1961 - 'label' => 'Small',
1962 - 'value' => array(
1963 - 'md' => 20,
1964 - 'unit' => 'px',
1965 - ),
1966 -
1967 - ),
1968 - ),
1969 - 'typography' => array(
1970 - array(
1971 - 'label' => 'Display Text',
1972 - 'value' => array(
1973 - 'openTypography' => 1,
1974 - 'size' => array(
1975 - 'md' => 65,
1976 - 'unit' => 'px',
1977 - ),
1978 - 'height' => array(
1979 - 'md' => 75,
1980 - 'unit' => 'px',
1981 - ),
1982 - 'fontFamily' => array(
1983 - 'family' => 'Roboto',
1984 - 'type' => 'sans-serif',
1985 - 'fontWeight' => 700,
1986 - ),
1987 - 'spacing' => array(
1988 - 'md' => 0,
1989 - 'unit' => 'px',
1990 - ),
1991 - ),
1992 - ),
1993 - array(
1994 - 'label' => 'Headline',
1995 - 'value' => array(
1996 - 'openTypography' => 1,
1997 - 'size' => array(
1998 - 'md' => 45,
1999 - 'unit' => 'px',
2000 - ),
2001 - 'height' => array(
2002 - 'md' => 60,
2003 - 'unit' => 'px',
2004 - ),
2005 - 'fontFamily' => array(
2006 - 'family' => 'Roboto',
2007 - 'type' => 'sans-serif',
2008 - 'fontWeight' => 700,
2009 - ),
2010 - 'spacing' => array(
2011 - 'md' => 0,
2012 - 'unit' => 'px',
2013 - ),
2014 - ),
2015 - ),
2016 - array(
2017 - 'label' => 'Sub Headline',
2018 - 'value' => array(
2019 - 'openTypography' => 1,
2020 - 'size' => array(
2021 - 'md' => 38,
2022 - 'unit' => 'px',
2023 - ),
2024 - 'height' => array(
2025 - 'md' => 45,
2026 - 'unit' => 'px',
2027 - ),
2028 - 'fontFamily' => array(
2029 - 'family' => 'Roboto',
2030 - 'type' => 'sans-serif',
2031 - 'fontWeight' => 500,
2032 - ),
2033 - 'spacing' => array(
2034 - 'md' => 0,
2035 - 'unit' => 'px',
2036 - ),
2037 - ),
2038 - ),
2039 - array(
2040 - 'label' => 'Title 1',
2041 - 'value' => array(
2042 - 'openTypography' => 1,
2043 - 'size' => array(
2044 - 'md' => 30,
2045 - 'unit' => 'px',
2046 - ),
2047 - 'height' => array(
2048 - 'md' => 40,
2049 - 'unit' => 'px',
2050 - ),
2051 - 'fontFamily' => array(
2052 - 'family' => 'Roboto',
2053 - 'type' => 'sans-serif',
2054 - 'fontWeight' => 500,
2055 - ),
2056 - 'spacing' => array(
2057 - 'md' => 0,
2058 - 'unit' => 'px',
2059 - ),
2060 - ),
2061 - ),
2062 - array(
2063 - 'label' => 'Title 2',
2064 - 'value' => array(
2065 - 'openTypography' => 1,
2066 - 'size' => array(
2067 - 'md' => 25,
2068 - 'unit' => 'px',
2069 - ),
2070 - 'height' => array(
2071 - 'md' => 30,
2072 - 'unit' => 'px',
2073 - ),
2074 - 'fontFamily' => array(
2075 - 'family' => 'Roboto',
2076 - 'type' => 'sans-serif',
2077 - 'fontWeight' => 400,
2078 - ),
2079 - 'spacing' => array(
2080 - 'md' => 0,
2081 - 'unit' => 'px',
2082 - ),
2083 - ),
2084 - ),
2085 - array(
2086 - 'label' => 'Body',
2087 - 'value' => array(
2088 - 'openTypography' => 1,
2089 - 'size' => array(
2090 - 'md' => 17,
2091 - 'unit' => 'px',
2092 - ),
2093 - 'height' => array(
2094 - 'md' => 22,
2095 - 'unit' => 'px',
2096 - ),
2097 - 'fontFamily' => array(
2098 - 'family' => 'Roboto',
2099 - 'type' => 'sans-serif',
2100 - 'fontWeight' => 400,
2101 - ),
2102 - 'spacing' => array(
2103 - 'md' => 0,
2104 - 'unit' => 'px',
2105 - ),
2106 - ),
2107 - ),
2108 - array(
2109 - 'label' => 'Captions',
2110 - 'value' => array(
2111 - 'openTypography' => 1,
2112 - 'size' => array(
2113 - 'md' => 13,
2114 - 'unit' => 'px',
2115 - ),
2116 - 'height' => array(
2117 - 'md' => 16,
2118 - 'unit' => 'px',
2119 - ),
2120 - 'fontFamily' => array(
2121 - 'family' => 'Roboto',
2122 - 'type' => 'sans-serif',
2123 - 'fontWeight' => 400,
2124 - ),
2125 - 'spacing' => array(
2126 - 'md' => 0,
2127 - 'unit' => 'px',
2128 - ),
2129 - ),
2130 - ),
2131 - ),
2132 - 'boxshadow' => array(
2133 - array(
2134 - 'label' => 'Normal Shadow',
2135 - 'value' => array(
2136 - 'openShadow' => 1,
2137 - 'inset' => 0,
2138 - 'horizontal' => 2,
2139 - 'vertical' => 6,
2140 - 'blur' => 10,
2141 - 'spread' => 0,
2142 - 'color' => 'rgba(0,0,0,0.15)',
2143 - ),
2144 - ),
2145 - array(
2146 - 'label' => 'Hover Shadow',
2147 - 'value' => array(
2148 - 'openShadow' => 1,
2149 - 'inset' => 0,
2150 - 'horizontal' => 2,
2151 - 'vertical' => 5,
2152 - 'blur' => 14,
2153 - 'spread' => 3,
2154 - 'color' => 'rgba(0,0,0,0.2)',
2155 - ),
2156 - ),
2157 - ),
2158 - ),
2159 - ),
2160 - 'globalContainer' => array(
2161 - 'md' => '',
2162 - 'unit' => 'px',
2163 - ),
2164 - );
2165 -
2166 - update_option( 'tpgb_global_options', json_encode( $static_meta ) );
2167 - $plus_settings = $static_meta;
2168 - }
2169 -
2170 - $active_id = ! empty( $plus_settings['active'] ) ? $plus_settings['active'] : '';
2171 - $preset_array = ! empty( $plus_settings['presets'] ) ? $plus_settings['presets'] : array();
2172 - $act_preset = ! empty( $plus_settings['presets'][ $active_id ] ) ? $plus_settings['presets'][ $active_id ] : array();
2173 -
2174 - foreach ( $act_preset['colors'] as $index => &$item ) {
2175 - $item['id'] = $index + 1;
2176 - }
2177 - unset( $item );
2178 -
2179 - foreach ( $act_preset['typography'] as $index => &$item ) {
2180 - $item['id'] = $index + 1;
2181 - }
2182 - unset( $item );
2183 -
2184 - $act_preset['color'] = $act_preset['colors'];
2185 - unset( $act_preset['colors'] );
2186 -
2187 - $response = array(
2188 - 'message' => __( 'Global data Found', 'wdesignkit' ),
2189 - 'description' => __( 'Global Color and Typography found', 'wdesignkit' ),
2190 - 'data' => $act_preset,
2191 - 'success' => true,
2192 - );
2193 - }
2194 -
2195 - wp_send_json( $response );
2196 - wp_die();
2197 - }
2198 -
2199 - /**
2200 - *
2201 - * Get site settings.
2202 - *
2203 - * @since 2.1.3
2204 - */
2205 - protected function wdkit_get_site_setting() {
2206 -
2207 - $kit_id = get_option( 'elementor_active_kit' );
2208 - if ( empty( $kit_id ) ) {
2209 - $response = array(
2210 - 'message' => __( 'Elementor kit not found', 'wdesignkit' ),
2211 - 'description' => __( 'No active Elementor kit found', 'wdesignkit' ),
2212 - 'success' => false,
2213 - );
2214 -
2215 - wp_send_json( $response );
2216 - wp_die();
2217 - }
2218 -
2219 - $kit_meta = get_post_meta( $kit_id, '_elementor_page_settings', true );
2220 -
2221 - $container_width = ! empty( $kit_meta['container_width'] ) ? $kit_meta['container_width'] : array();
2222 - $globals = ! empty( $kit_meta['__globals__'] ) ? $kit_meta['__globals__'] : array();
2223 - $body_background_color = ! empty( $kit_meta['body_background_color'] ) ? $kit_meta['body_background_color'] : array();
2224 -
2225 - $site_globals = array(
2226 - 'body_background_color' => $body_background_color,
2227 - 'container_width' => $container_width,
2228 - 'globals' => $globals,
2229 - );
2230 -
2231 - $response = array(
2232 - 'message' => __( 'Global data Found', 'wdesignkit' ),
2233 - 'description' => __( 'Global Color and Typography found', 'wdesignkit' ),
2234 - 'data' => $site_globals,
2235 - 'success' => true,
2236 - );
2237 -
2238 - wp_send_json( $response );
2239 - wp_die();
2240 - }
2241 -
2242 - /**
2243 - *
2244 - * update site settings.
2245 - *
2246 - * @since 2.1.3
2247 - */
2248 - protected function wdkit_update_site_setting() {
2249 -
2250 - $builder = ! empty( $_POST['builder'] ) ? sanitize_text_field( $_POST['builder'] ) : '';
2251 - $site_data = ! empty( $_POST['site_data'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['site_data'] ) ), true ) : array();
2252 -
2253 - if ( 'elementor' == $builder ) {
2254 - $kit_id = get_option( 'elementor_active_kit' );
2255 - if ( ! $kit_id && did_action( 'elementor/loaded' ) && class_exists( '\Elementor\Core\Kits\Manager' ) ) {
2256 - \Elementor\Core\Kits\Manager::create_default_kit();
2257 - $kit_id = get_option( 'elementor_active_kit' );
2258 - }
2259 -
2260 - if ( ! $kit_id ) {
2261 - $response = array(
2262 - 'message' => __( 'Elementor kit not found', 'wdesignkit' ),
2263 - 'description' => __( 'No active Elementor kit found', 'wdesignkit' ),
2264 - 'success' => false,
2265 - );
2266 -
2267 - wp_send_json( $response );
2268 - wp_die();
2269 - }
2270 -
2271 - // A freshly created kit has no `_elementor_page_settings` meta yet,
2272 - // so an empty result here is a valid starting point, not an error.
2273 - $kit_meta = get_post_meta( $kit_id, '_elementor_page_settings', true );
2274 - if ( ! is_array( $kit_meta ) ) {
2275 - $kit_meta = array();
2276 - }
2277 -
2278 - $kit_meta['container_width'] = ! empty( $site_data['container_width'] ) ? $site_data['container_width'] : array();
2279 - $kit_meta['__globals__'] = ! empty( $site_data['globals'] ) ? $site_data['globals'] : array();
2280 - $kit_meta['body_background_color'] = ! empty( $site_data['body_background_color'] ) ? $site_data['body_background_color'] : array();
2281 -
2282 - update_post_meta( $kit_id, '_elementor_page_settings', $kit_meta );
2283 -
2284 - // Regenerate Elementor's cached CSS. Writing the kit meta directly does
2285 - // not rebuild the kit stylesheet, so the imported body background colour
2286 - // and container width would otherwise never render on the frontend.
2287 - $this->wdkit_regenerate_elementor_kit_css();
2288 -
2289 - $response = array(
2290 - 'message' => __( 'Site data Updated', 'wdesignkit' ),
2291 - 'description' => __( 'Site Globals Updated', 'wdesignkit' ),
2292 - 'success' => true,
2293 - );
2294 -
2295 - } elseif ( 'gutenberg' == $builder ) {
2296 - $plus_settings = get_option( 'tpgb_global_options' );
2297 -
2298 - $site_preset = json_decode( $plus_settings, true );
2299 - $site_preset['globalContainer'] = $site_data;
2300 -
2301 - update_option( 'tpgb_global_options', json_encode( $site_preset ) );
2302 -
2303 - $response = array(
2304 - 'message' => __( 'Site data Updated', 'wdesignkit' ),
2305 - 'description' => __( 'Site Globals Updated', 'wdesignkit' ),
2306 - 'success' => true,
2307 - );
2308 -
2309 - } else {
2310 - $response = array(
2311 - 'message' => __( 'Builder Not Found !', 'wdesignkit' ),
2312 - 'description' => __( 'Template Builder not Found', 'wdesignkit' ),
2313 - 'success' => true,
2314 - );
2315 - }
2316 -
2317 - wp_send_json( $response );
2318 - wp_die();
2319 - }
2320 -
2321 - /**
2322 - *
2323 - * Update Elementor Global color and Typography.
2324 - *
2325 - * @since 1.1.20
2326 - */
2327 - protected function wdkit_update_global_val() {
2328 -
2329 - $builder = ! empty( $_POST['builder'] ) ? sanitize_text_field( $_POST['builder'] ) : '';
2330 -
2331 - if ( 'elementor' == $builder ) {
2332 -
2333 - $g_color = ! empty( $_POST['g_color'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['g_color'] ) ), true ) : array();
2334 - $g_typo = ! empty( $_POST['g_typography'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['g_typography'] ) ), true ) : array();
2335 -
2336 - // Get colors from Elementor Site Kit
2337 - $kit_id = get_option( 'elementor_active_kit' );
2338 - if ( ! $kit_id && did_action( 'elementor/loaded' ) && class_exists( '\Elementor\Core\Kits\Manager' ) ) {
2339 - // No kit has ever been created on this site (the option is only
2340 - // ever populated by Elementor's own activation hook). Create one
2341 - // via Elementor's own helper so the import has somewhere to write.
2342 - \Elementor\Core\Kits\Manager::create_default_kit();
2343 - $kit_id = get_option( 'elementor_active_kit' );
2344 - }
2345 -
2346 - if ( ! $kit_id ) {
2347 - $response = array(
2348 - 'message' => __( 'Elementor kit not found', 'wdesignkit' ),
2349 - 'description' => __( 'No active Elementor kit found', 'wdesignkit' ),
2350 - 'success' => false,
2351 - );
2352 -
2353 - wp_send_json( $response );
2354 - wp_die();
2355 - }
2356 -
2357 - // A freshly created kit has no `_elementor_page_settings` meta yet,
2358 - // so an empty result here is a valid starting point, not an error.
2359 - $kit_meta = get_post_meta( $kit_id, '_elementor_page_settings', true );
2360 - if ( ! is_array( $kit_meta ) ) {
2361 - $kit_meta = array();
2362 - }
2363 -
2364 - $kit_meta['custom_colors'] = array_merge( $g_color, $kit_meta['custom_colors'] ?? array() );
2365 - $kit_meta['custom_typography'] = array_merge( $g_typo, $kit_meta['custom_typography'] ?? array() );
2366 -
2367 - update_post_meta( $kit_id, '_elementor_page_settings', $kit_meta );
2368 -
2369 - // Regenerate Elementor's cached CSS. Writing the kit meta directly does
2370 - // not rebuild the kit stylesheet, so the imported global colours and
2371 - // fonts would otherwise never render on the frontend.
2372 - $this->wdkit_regenerate_elementor_kit_css();
2373 -
2374 - $response = array(
2375 - 'message' => __( 'Global data Updated', 'wdesignkit' ),
2376 - 'description' => __( 'Global Color and Typography Updated', 'wdesignkit' ),
2377 - 'success' => true,
2378 - );
2379 -
2380 - } elseif ( 'gutenberg' == $builder ) {
2381 - $new_preset = ! empty( $_POST['new_preset'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['new_preset'] ) ), true ) : array();
2382 - $new_preset_id = ! empty( $new_preset['key'] ) ? $new_preset['key'] : '';
2383 - $plus_settings = get_option( 'tpgb_global_options' );
2384 - $site_preset = json_decode( $plus_settings, true );
2385 -
2386 - $site_preset['presets'][ $new_preset_id ] = $new_preset;
2387 - $site_preset['active'] = $new_preset_id;
2388 -
2389 - update_option( 'tpgb_global_options', json_encode( $site_preset ) );
2390 -
2391 - $response = array(
2392 - 'message' => __( 'Global data Updated', 'wdesignkit' ),
2393 - 'description' => __( 'Global Color and Typography Updated', 'wdesignkit' ),
2394 - 'success' => true,
2395 - );
2396 -
2397 - } else {
2398 - $response = array(
2399 - 'message' => __( 'Builder Not Found !', 'wdesignkit' ),
2400 - 'description' => __( 'Template Builder not Found', 'wdesignkit' ),
2401 - 'success' => true,
2402 - );
2403 - }
2404 -
2405 - wp_send_json( $response );
2406 - wp_die();
2407 - }
2408 -
2409 - /**
2410 - * Regenerate Elementor's cached CSS files after the active kit's
2411 - * `_elementor_page_settings` meta has been changed directly.
2412 - *
2413 - * Elementor renders global colours, global fonts and the body background
2414 - * colour into a cached kit stylesheet. Updating the meta via
2415 - * update_post_meta() does not rebuild that stylesheet, so imported site
2416 - * settings never reach the frontend until the cache is cleared. This
2417 - * mirrors the clear_cache() call already used by the page/section import.
2418 - *
2419 - * @since 2.3.2
2420 - *
2421 - * @return void
2422 - */
2423 - protected function wdkit_regenerate_elementor_kit_css() {
2424 - if ( did_action( 'elementor/loaded' ) && class_exists( '\Elementor\Plugin' ) ) {
2425 - \Elementor\Plugin::$instance->files_manager->clear_cache();
2426 - }
2427 - }
2428 -
2429 - /**
2430 - *
2431 - * Create Gutenberg page and save for re-generate css file.
2432 - *
2433 - * @since 1.2.3
2434 - */
2435 - protected function wdkit_update_preset() {
2436 -
2437 - $act_type = ! empty( $_POST['act_type'] ) ? sanitize_text_field( $_POST['act_type'] ) : '';
2438 - $post_id = ! empty( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : '';
2439 -
2440 - if ( 'create' == $act_type ) {
2441 -
2442 - $page_id = wp_insert_post(
2443 - array(
2444 - 'post_title' => 'WDesignKit Gutenberg',
2445 - 'post_status' => 'publish',
2446 - 'post_type' => 'post',
2447 - 'post_name' => sanitize_title( 'wdesignkit' ),
2448 - 'post_content' => '<!-- wp:heading --><h2 class="wp-block-heading">Add Your Heading Text Here<h2><!-- /wp:heading -->',
2449 - 'meta_input' => array(
2450 - 'gutenberg_preview' => true,
2451 - '_wp_page_template' => 'default',
2452 - ),
2453 - )
2454 - );
2455 -
2456 - if ( is_wp_error( $page_id ) || ! $page_id ) {
2457 - $response = array(
2458 - 'success' => true,
2459 - 'message' => esc_html__( 'Page Not Found!', 'wdesignkit' ),
2460 - 'description' => esc_html__( 'Page Not Found!', 'wdesignkit' ),
2461 - );
2462 -
2463 - wp_send_json( $response );
2464 - wp_die();
2465 - }
2466 -
2467 - update_post_meta( $page_id, '_edit_lock', time() . ':1' );
2468 - update_post_meta( $page_id, '_edit_last', get_current_user_id() );
2469 -
2470 - $preview_url = admin_url( 'post.php?post=' . $page_id . '&action=edit' );
2471 -
2472 - $response = array(
2473 - 'success' => true,
2474 - 'post_id' => $page_id,
2475 - 'preview_url' => $preview_url,
2476 - 'message' => esc_html__( 'Page Created', 'wdesignkit' ),
2477 - 'description' => esc_html__( 'Page Created', 'wdesignkit' ),
2478 - );
2479 -
2480 - wp_send_json( $response );
2481 - wp_die();
2482 -
2483 - }
2484 -
2485 - if ( ! empty( $post_id ) && ( $act_type == 'remove' ) ) {
2486 -
2487 - wp_delete_post( $post_id, true );
2488 -
2489 - $response = array(
2490 - 'success' => true,
2491 - 'message' => esc_html__( 'post deleted', 'wdesignkit' ),
2492 - 'description' => esc_html__( 'post deleted', 'wdesignkit' ),
2493 - );
2494 -
2495 - wp_send_json( $response );
2496 - wp_die();
2497 - }
2498 - }
2499 -
2500 - /**
2501 - *
2502 1004 * It is For Find User Existing template List.
2503 1005 *
2504 1006 * @since 1.0.6
2505 1007 */
@@ -2526,39 +1028,16 @@
2526 1028 * @since 1.0.6
2527 1029 */
2528 1030 protected function wdkit_update_template() {
2529 1031 $array_data = array(
2530 - 'data' => isset( $_POST['data'] ) ? wp_unslash( $_POST['data'] ) : '',
2531 - 'post_id' => isset( $_POST['post_id'] ) ? sanitize_text_field( wp_unslash( $_POST['post_id'] ) ) : '',
2532 - 'token' => isset( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '',
2533 - 'type' => isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '',
2534 - 'id' => isset( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '',
2535 - 'global_data' => isset( $_POST['global_data'] ) ? wp_unslash( $_POST['global_data'] ) : array(),
2536 - // 'global_font_family' => isset( $_POST['global_font_family'] ) ? wp_unslash( $_POST['global_font_family'] ) : array(),
2537 - // 'global_color' => isset( $_POST['global_color'] ) ? wp_unslash( $_POST['global_color'] ) : array(),
1032 + 'data' => isset( $_POST['data'] ) ? wp_unslash( $_POST['data'] ) : '',
1033 + 'token' => isset( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '',
1034 + 'type' => isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '',
1035 + 'id' => isset( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '',
2538 1036 );
2539 1037
2540 - if ( ! empty( $array_data['post_id'] ) ) {
2541 - $custom_fields = array();
2542 - $post_id = $array_data['post_id'];
1038 + $response = $this->wkit_api_call( $array_data, 'existing_template' );
2543 1039
2544 - $meta_fields = get_post_custom( $post_id );
2545 -
2546 - foreach ( $meta_fields as $key => $value ) {
2547 - if ( str_contains( $key, 'nxt-' ) ) {
2548 - $custom_fields[ $key ] = $value;
2549 - }
2550 - }
2551 -
2552 - if ( ! empty( $custom_fields ) ) {
2553 - $data = json_decode( $array_data['data'], true );
2554 - $data['custom_meta'] = $custom_fields;
2555 - $array_data['data'] = wp_json_encode( $data );
2556 - }
2557 - }
2558 -
2559 - $array_data['remove'] = 'yes';
2560 - $response = $this->wkit_api_call( $array_data, 'existing_template' );
2561 1040 wp_send_json( $response );
2562 1041 wp_die();
2563 1042 }
2564 1043
@@ -2602,9 +1081,8 @@
2602 1081 */
2603 1082 protected function wdkit_check_plugins_depends() {
2604 1083 $plugins = isset( $_POST['plugins'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['plugins'] ) ) ) : array();
2605 1084 $update_plugin = array();
2606 - $update_theme = array();
2607 1085
2608 1086 if ( empty( $plugins ) || ! is_array( $plugins ) ) {
2609 1087 $this->wdkit_error_msg( array( 'plugins' => 'No Plugins' ) );
2610 1088 }
@@ -2617,9 +1095,8 @@
2617 1095
2618 1096 if ( is_null( $pluginslug ) ) {
2619 1097 $plugin->status = 'warning';
2620 1098 $update_plugin[] = $plugin;
2621 - $update_theme[] = $plugin;
2622 1099
2623 1100 continue;
2624 1101 }
2625 1102
@@ -2640,13 +1117,12 @@
2640 1117 $plugin->status = 'active';
2641 1118 $update_plugin[] = $plugin;
2642 1119 }
2643 1120 } elseif ( 'theme' === $type ) {
2644 - $theme_array = array_keys( wp_get_themes() );
2645 - $theme_slug = get_stylesheet();
2646 - $parent_theme_slug = get_template();
1121 + $theme_array = array_keys( wp_get_themes() );
1122 + $theme_slug = get_stylesheet();
2647 1123
2648 - if ( $theme_slug === $plugin->original_slug || $parent_theme_slug === $plugin->original_slug ) {
1124 + if ( $theme_slug === $plugin->original_slug ) {
2649 1125
2650 1126 $plugin->status = 'active';
2651 1127 } else {
2652 1128 $theme_name = $plugin->original_slug;
@@ -2660,19 +1136,13 @@
2660 1136 $plugin->status = 'inactive';
2661 1137 }
2662 1138 }
2663 1139
2664 - $update_theme[] = $plugin;
1140 + $update_plugin[] = $plugin;
2665 1141 }
2666 1142 }
2667 1143
2668 - $response = array(
2669 - 'plugins' => $update_plugin,
2670 - 'theme' => $update_theme,
2671 - 'ele_container' => get_option( 'elementor_experiment-container', false ),
2672 - );
2673 -
2674 - $this->wdkit_success_msg( $response );
1144 + $this->wdkit_success_msg( array( 'plugins' => $update_plugin ) );
2675 1145 }
2676 1146
2677 1147 /**
2678 1148 *
@@ -2683,9 +1153,8 @@
2683 1153 */
2684 1154 protected function wdkit_install_plugins_depends() {
2685 1155 $plugins = isset( $_POST['plugins'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['plugins'] ) ), true ) : array();
2686 1156 $type = ! empty( $plugins['type'] ) ? $plugins['type'] : 'plugin';
2687 - $p_id = ! empty( $plugins['p_id'] ) ? $plugins['p_id'] : 'plugin';
2688 1157
2689 1158 $responce = '';
2690 1159 if ( 'plugin' === $type ) {
2691 1160 $responce = Wdkit_Depends_Installer::get_instance()->wdkit_install_plugin( $plugins );
@@ -2692,46 +1161,24 @@
2692 1161 } elseif ( 'theme' === $type ) {
2693 1162 $theme_name = ! empty( $plugins['original_slug'] ) ? $plugins['original_slug'] : '';
2694 1163 if ( ! empty( $theme_name ) ) {
2695 1164
2696 - $theme_array = array_keys( wp_get_themes() );
2697 - $theme_slug = get_stylesheet();
1165 + $activate_result = switch_theme( $theme_name );
2698 1166
2699 - if ( in_array( $theme_name, $theme_array ) ) {
2700 - $activate_result = switch_theme( $theme_name );
2701 -
2702 - if ( ! is_wp_error( $activate_result ) ) {
2703 - $responce = array(
2704 - 'message' => esc_html__( 'Theme activated successfully', 'wdesignkit' ),
2705 - 'description' => esc_html__( 'Theme successfully activated', 'wdesignkit' ),
2706 - 'slug' => 'nexter',
2707 - 'p_id' => $p_id,
2708 - 'status' => 'active',
2709 - 'success' => true,
2710 - );
2711 - } else {
2712 - $responce = array(
2713 - 'message' => esc_html__( 'Theme Not Activated !', 'wdesignkit' ),
2714 - 'description' => $activate_result->get_error_message(),
2715 - 'status' => 'inactive',
2716 - 'p_id' => $p_id,
2717 - 'success' => false,
2718 - );
2719 - }
1167 + if ( ! is_wp_error( $activate_result ) ) {
1168 + $responce = array(
1169 + 'message' => esc_html__( 'Theme activated successfully', 'wdesignkit' ),
1170 + 'description' => esc_html__( 'Theme successfully activated', 'wdesignkit' ),
1171 + 'slug' => 'the-plus-addons-for-block-editor',
1172 + 'status' => 'active',
1173 + 'success' => true,
1174 + );
2720 1175 } else {
2721 - $result = $this->wdkit_install_theme_depends( $theme_name );
2722 -
2723 - $message = ! empty( $result['message'] ) ? $result['message'] : esc_html__( 'Somthing Wrong', 'wdesignkit' );
2724 - $description = ! empty( $result['description'] ) ? $result['description'] : esc_html__( 'Error Somthing Wrong', 'wdesignkit' );
2725 - $status = ! empty( $result['status'] ) ? $result['status'] : esc_html__( 'inactive', 'wdesignkit' );
2726 - $success = ! empty( $result['success'] ) ? $result['success'] : false;
2727 -
2728 1176 $responce = array(
2729 - 'message' => $message,
2730 - 'description' => $description,
2731 - 'p_id' => $p_id,
2732 - 'status' => $status,
2733 - 'success' => $success,
1177 + 'message' => esc_html__( 'Theme Not Activated !', 'wdesignkit' ),
1178 + 'description' => $activate_result->get_error_message(),
1179 + 'status' => 'inactive',
1180 + 'success' => false,
2734 1181 );
2735 1182 }
2736 1183 } else {
2737 1184 $responce = array(
@@ -2736,9 +1183,9 @@
2736 1183 } else {
2737 1184 $responce = array(
2738 1185 'message' => esc_html__( 'Theme Name not Found', 'wdesignkit' ),
2739 1186 'description' => esc_html__( 'Can Not Found Theme Name you Enterd.', 'wdesignkit' ),
2740 - 'success' => false,
1187 + 'success' => true,
2741 1188 );
2742 1189 }
2743 1190 }
2744 1191
@@ -2745,125 +1192,8 @@
2745 1192 wp_send_json( $responce );
2746 1193 wp_die();
2747 1194 }
2748 1195
2749 - protected function wdkit_install_theme_depends( $name = 'nexter' ) {
2750 -
2751 - if ( ! current_user_can( 'install_themes' ) ) {
2752 - $response = $this->tpae_set_response( false, 'Invalid nonce.', 'The security check failed. Please refresh the page and try again.' );
2753 - return $response;
2754 - }
2755 -
2756 - $theme_slug = $name;
2757 - $theme_api_url = 'https://api.wordpress.org/themes/info/1.0/';
2758 -
2759 - // Parameters for the request
2760 - $args = array(
2761 - 'body' => array(
2762 - 'action' => 'theme_information',
2763 - 'request' => serialize(
2764 - (object) array(
2765 - 'slug' => $name,
2766 - 'fields' => array(
2767 - 'description' => false,
2768 - 'sections' => false,
2769 - 'rating' => true,
2770 - 'ratings' => false,
2771 - 'downloaded' => true,
2772 - 'download_link' => true,
2773 - 'last_updated' => true,
2774 - 'homepage' => true,
2775 - 'tags' => true,
2776 - 'template' => true,
2777 - 'active_installs' => false,
2778 - 'parent' => false,
2779 - 'versions' => false,
2780 - 'screenshot_url' => true,
2781 - 'active_installs' => false,
2782 - ),
2783 - )
2784 - ),
2785 - ),
2786 - );
2787 -
2788 - // Make the request
2789 - $response = wp_remote_post( $theme_api_url, $args );
2790 - // Check for errors
2791 - if ( is_wp_error( $response ) ) {
2792 - $error_message = $response->get_error_message();
2793 -
2794 - $result = $this->tpae_set_response( false, 'oops', 'oops', '' );
2795 - } else {
2796 - // api.wordpress.org's theme_information response is a serialized stdClass
2797 - // (accessed below via ->name / ->download_link). allowed_classes => false
2798 - // blocks stdClass too, turning it into an __PHP_Incomplete_Class whose
2799 - // properties silently don't exist — allow only stdClass, still refusing any
2800 - // other (potentially dangerous) class the payload might reference.
2801 - $theme_info = unserialize( $response['body'], array( 'allowed_classes' => array( 'stdClass' ) ) );
2802 - $theme_name = $theme_info->name;
2803 - $theme_zip_url = $theme_info->download_link;
2804 -
2805 - // SSRF guard (CWE-918): validate the resolved host before fetching the ZIP
2806 - // referenced by the external theme_info response.
2807 - if ( ! wdesignkit_validate_external_url( $theme_zip_url ) ) {
2808 - return array(
2809 - 'message' => esc_html__( 'Theme Not Activated !', 'wdesignkit' ),
2810 - 'description' => esc_html__( 'The theme package URL is not allowed.', 'wdesignkit' ),
2811 - 'status' => 'inactive',
2812 - 'success' => false,
2813 - );
2814 - }
2815 -
2816 - if ( ! function_exists( 'WP_Filesystem' ) ) {
2817 - require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
2818 - }
2819 -
2820 - require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
2821 - require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/theme.php' );
2822 -
2823 - WP_Filesystem();
2824 -
2825 - $active_theme = wp_get_theme();
2826 - $theme_name = $active_theme->get( 'Name' );
2827 -
2828 - // Install via WordPress core's Theme_Upgrader instead of manually fetching and
2829 - // ZipArchive::extractTo()'ing the remote package: core already performs the
2830 - // standard download -> unpack -> validate-package-structure -> move-into-place
2831 - // flow (including cleanup on failure) used for every trusted theme install.
2832 - $upgrader = new Theme_Upgrader( new Automatic_Upgrader_Skin() );
2833 - $install = $upgrader->install( $theme_zip_url );
2834 -
2835 - if ( is_wp_error( $install ) || ! $install ) {
2836 - return array(
2837 - 'message' => esc_html__( 'Theme Not Activated !', 'wdesignkit' ),
2838 - 'description' => is_wp_error( $install ) ? $install->get_error_message() : esc_html__( 'Theme could not be installed.', 'wdesignkit' ),
2839 - 'status' => 'inactive',
2840 - 'success' => false,
2841 - );
2842 - }
2843 -
2844 - $activate_result = switch_theme( $name );
2845 -
2846 - if ( ! is_wp_error( $activate_result ) ) {
2847 - $response = array(
2848 - 'message' => esc_html__( 'Theme activated successfully', 'wdesignkit' ),
2849 - 'description' => esc_html__( 'Theme successfully activated', 'wdesignkit' ),
2850 - 'status' => 'active',
2851 - 'success' => true,
2852 - );
2853 - } else {
2854 - $response = array(
2855 - 'message' => esc_html__( 'Theme Not Activated !', 'wdesignkit' ),
2856 - 'description' => $activate_result->get_error_message(),
2857 - 'status' => 'inactive',
2858 - 'success' => false,
2859 - );
2860 - }
2861 - }
2862 -
2863 - return $response;
2864 - }
2865 -
2866 1196 /**
2867 1197 *
2868 1198 * It is Use Update WDesignKit plugin latest version.
2869 1199 *
@@ -2892,118 +1222,25 @@
2892 1222 * Get Download Template Content
2893 1223 *
2894 1224 * @since 1.0.0
2895 1225 */
2896 - protected function wdkit_activate_container() {
1226 + protected function wdkit_import_template() {
1227 + $args = $this->wdkit_parse_args( $_POST );
2897 1228
2898 - $option_value = get_option( 'elementor_experiment-container', false );
1229 + if ( empty( $args['email'] ) ) {
1230 + $response = array(
1231 + 'content' => '',
1232 + 'message' => esc_html__( 'Invalid import', 'wdesignkit' ),
1233 + 'description' => esc_html__( 'Invalid import: Check your details and try again.', 'wdesignkit' ),
1234 + 'success' => true,
1235 + );
2899 1236
2900 - if ( $option_value === false ) {
2901 - add_option( 'elementor_experiment-container', 'active' );
2902 - } else {
2903 - update_option( 'elementor_experiment-container', 'active' );
1237 + wp_send_json( $response );
1238 + wp_die();
2904 1239 }
2905 1240
2906 - $result = array(
2907 - 'message' => esc_html__( 'Container Activated Successfully', 'wdesignkit' ),
2908 - 'description' => esc_html__( 'Elementor Container Activated Successfully.', 'wdesignkit' ),
2909 - 'success' => true,
2910 - );
2911 -
2912 - wp_send_json( $response );
2913 - wp_die();
2914 - }
2915 -
2916 - /**
2917 - * import category and tags for post
2918 - *
2919 - * @since 2.0.0
2920 - */
2921 - protected function wdkit_import_taxonomy() {
2922 - $category = isset( $_POST['category'] ) ? json_decode( wp_unslash( $_POST['category'] ) ) : array();
2923 - $tags = isset( $_POST['tags'] ) ? json_decode( wp_unslash( $_POST['tags'] ) ) : array();
2924 -
2925 - $response = array(
2926 - 'success' => false,
2927 - 'categories' => array(),
2928 - 'tags' => array(),
2929 - );
2930 -
2931 - if ( ! empty( $category ) && count( $category ) > 0 ) {
2932 - foreach ( $category as $category_name ) {
2933 - $category_name = sanitize_text_field( $category_name );
2934 -
2935 - $term_exists = term_exists( $category_name, 'category' );
2936 - if ( ! $term_exists ) {
2937 - $result = wp_insert_term( $category_name, 'category' );
2938 - if ( ! is_wp_error( $result ) ) {
2939 - $response['categories'][] = array(
2940 - 'name' => $category_name,
2941 - 'term_id' => $result['term_id'],
2942 - );
2943 - } else {
2944 - $response['categories'][] = array(
2945 - 'name' => $category_name,
2946 - 'error' => $result->get_error_message(),
2947 - );
2948 - }
2949 - } else {
2950 - $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
2951 - $response['categories'][] = array(
2952 - 'name' => $category_name,
2953 - 'term_id' => $term_id,
2954 - );
2955 - }
2956 - }
2957 -
2958 - $response['success'] = true;
2959 - }
2960 -
2961 - if ( ! empty( $tags ) && count( $tags ) > 0 ) {
2962 - foreach ( $tags as $tags_name ) {
2963 - $tags_name = sanitize_text_field( $tags_name );
2964 -
2965 - $term_exists = term_exists( $tags_name, 'post_tag' );
2966 - if ( ! $term_exists ) {
2967 - $result = wp_insert_term( $tags_name, 'post_tag' );
2968 - if ( ! is_wp_error( $result ) ) {
2969 - $response['tags'][] = array(
2970 - 'name' => $tags_name,
2971 - 'term_id' => $result['term_id'],
2972 - );
2973 - } else {
2974 - $response['tags'][] = array(
2975 - 'name' => $tags_name,
2976 - 'error' => $result->get_error_message(),
2977 - );
2978 - }
2979 - } else {
2980 - $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
2981 - $response['tags'][] = array(
2982 - 'name' => $tags_name,
2983 - 'term_id' => $term_id,
2984 - );
2985 - }
2986 - }
2987 -
2988 - $response['success'] = true;
2989 - }
2990 -
2991 - wp_send_json( $response );
2992 - wp_die();
2993 - }
2994 -
2995 - /**
2996 - * Get Download Template Content
2997 - *
2998 - * @since 1.0.0
2999 - */
3000 - protected function wdkit_import_template() {
3001 - $args = $this->wdkit_parse_args( $_POST );
3002 - $api_type = isset( $_POST['api_type'] ) ? sanitize_text_field( wp_unslash( $_POST['api_type'] ) ) : 'import_template';
3003 -
3004 1241 $response = '';
3005 - if ( empty( $args['template_id'] ) ) {
1242 + if ( empty( $args['email'] ) || empty( $args['template_id'] ) ) {
3006 1243 $result = array(
3007 1244 'content' => '',
3008 1245 'message' => esc_html__( 'Invalid import', 'wdesignkit' ),
3009 1246 'description' => esc_html__( 'Invalid import: Check your details and try again.', 'wdesignkit' ),
@@ -3016,19 +1253,9 @@
3016 1253
3017 1254 $args['token'] = $this->wdkit_login_user_token( $args['email'] );
3018 1255
3019 1256 unset( $args['email'] );
3020 - $args['unique_id'] = get_option( 'wdkit_unique_id' ) ?? '';
3021 - $response = WDesignKit_Data_Query::get_data( $api_type, $args );
3022 -
3023 - if ( is_wp_error( $response ) ) {
3024 - wp_send_json( array(
3025 - 'success' => false,
3026 - 'message' => $response->get_error_message(),
3027 - ) );
3028 - wp_die();
3029 - }
3030 -
1257 + $response = WDesignKit_Data_Query::get_data( 'import_template', $args );
3031 1258 $custom_meta = isset( $_POST['custom_meta'] ) ? sanitize_text_field( wp_unslash( $_POST['custom_meta'] ) ) : false;
3032 1259
3033 1260 /** Custom meta Field */
3034 1261 if ( ! empty( $custom_meta ) && 'true' === $custom_meta && ! empty( $response ) && ! empty( $response['content'] ) ) {
@@ -3039,9 +1266,9 @@
3039 1266
3040 1267 if ( ! empty( $meta_data ) ) {
3041 1268 foreach ( $meta_data as $meta_key => $meta_val ) {
3042 1269 if ( ! empty( $meta_val[0] ) && is_serialized( $meta_val[0] ) ) {
3043 - $meta_val[0] = unserialize( $meta_val[0], array( 'allowed_classes' => false ) );
1270 + $meta_val[0] = maybe_unserialize( $meta_val[0] );
3044 1271 }
3045 1272
3046 1273 if ( get_post_meta( get_the_ID(), $meta_key, true ) === '' ) {
3047 1274 add_post_meta( get_the_ID(), $meta_key, $meta_val[0] );
@@ -3052,34 +1279,8 @@
3052 1279 }
3053 1280 }
3054 1281 }
3055 1282
3056 - /**
3057 - * Fires after a template has been imported from the cloud.
3058 - *
3059 - * WDesignKit's templates live in the cloud, so nothing local records that an import
3060 - * happened — there is no post type, no option, nothing to count after the fact. This is the
3061 - * only moment the information exists.
3062 - *
3063 - * @since 2.6.4
3064 - *
3065 - * @param string $kind 'single' or 'kit'.
3066 - * @param string $builder Builder the template was imported for, e.g. 'elementor'.
3067 - * @param int $count How many templates this import brought in.
3068 - */
3069 - // Only a completed import counts. The cloud's failure shape for this endpoint family sets
3070 - // content => 'error' (see the sibling check in wdkit_import_kit_template() above) — that is
3071 - // non-empty, so the previous `||` fired the counter on failed imports too. Require success
3072 - // AND an absent/non-'error' content instead.
3073 - if ( ! empty( $response['success'] ) && ( ! isset( $response['content'] ) || 'error' !== $response['content'] ) ) {
3074 - do_action(
3075 - 'wdkit_template_imported',
3076 - 'import_kit_template' === $api_type ? 'kit' : 'single',
3077 - isset( $_POST['builder'] ) ? sanitize_key( wp_unslash( $_POST['builder'] ) ) : '',
3078 - 1
3079 - );
3080 - }
3081 -
3082 1283 wp_send_json( $response );
3083 1284 wp_die();
3084 1285 }
3085 1286
@@ -3090,265 +1291,8 @@
3090 1291 *
3091 1292 * @param array $content store media content.
3092 1293 * @param string $editor it is check editor.
3093 1294 */
3094 - /**
3095 - * Resolve a local upload URL back to its attachment ID.
3096 - *
3097 - * Handles the "-scaled" copy WordPress makes for large originals and any
3098 - * "-1920x1280" size suffix, both of which attachment_url_to_postid() misses because
3099 - * they are not the value stored in _wp_attached_file.
3100 - *
3101 - * @since 2.6.2
3102 - *
3103 - * @param string $url Local upload URL.
3104 - * @return int Attachment ID, or 0.
3105 - */
3106 - private static function wdkit_attachment_id_from_url( $url ) {
3107 - static $cache = array();
3108 -
3109 - if ( isset( $cache[ $url ] ) ) {
3110 - return $cache[ $url ];
3111 - }
3112 -
3113 - $id = (int) attachment_url_to_postid( $url );
3114 -
3115 - if ( ! $id ) {
3116 - // Try the original file behind a -scaled or -WxH derivative.
3117 - $stripped = preg_replace( '/-scaled(\.[a-z0-9]+)$/i', '$1', $url );
3118 - $stripped = preg_replace( '/-\d+x\d+(\.[a-z0-9]+)$/i', '$1', (string) $stripped );
3119 -
3120 - if ( $stripped && $stripped !== $url ) {
3121 - $id = (int) attachment_url_to_postid( $stripped );
3122 - }
3123 - }
3124 -
3125 - // Only remember hits. Page imports run concurrently, so an attachment created by a
3126 - // sibling request may not exist yet when this is first asked — caching that miss
3127 - // would keep every later control in this request pointing at nothing.
3128 - if ( $id ) {
3129 - $cache[ $url ] = $id;
3130 - }
3131 -
3132 - return $id;
3133 - }
3134 -
3135 - /**
3136 - * Is this media reference still pointing off-site?
3137 - *
3138 - * Template content arrives holding the URLs of wherever the media lived before. Those
3139 - * carry that site's attachment IDs, which have no meaning here - and can collide with
3140 - * unrelated local posts.
3141 - *
3142 - * @since 2.6.2
3143 - *
3144 - * @param string $url URL from a media control.
3145 - * @return bool True when the URL points at another site's uploads.
3146 - */
3147 - private static function wdkit_is_foreign_media_url( $url ) {
3148 -
3149 - if ( ! class_exists( 'Wdkit_Image_Guard' ) ) {
3150 - require_once WDKIT_INCLUDES . 'admin/class-wdkit-image-guard.php';
3151 - }
3152 -
3153 - $uploads = wp_get_upload_dir();
3154 -
3155 - return Wdkit_Image_Guard::is_foreign_media( $url, isset( $uploads['baseurl'] ) ? $uploads['baseurl'] : '' );
3156 - }
3157 -
3158 - /**
3159 - * Find - or make - the local attachment behind a source-site media URL.
3160 - *
3161 - * Elementor stamps every image it imports with `_elementor_source_image_hash`
3162 - * (sha1 of the URL it came from), and its importer consults that before doing any
3163 - * network work. Delegating here means a URL already imported at create time resolves
3164 - * from the database, and one that never made it is fetched exactly once.
3165 - *
3166 - * Only ever called for foreign URLs. Handing it a local URL would re-download the
3167 - * file and leave a duplicate, because the stored hash is of the *remote* URL and so
3168 - * would never match.
3169 - *
3170 - * @since 2.6.2
3171 - *
3172 - * @param string $url Source-site media URL.
3173 - * @param int $source_id The source site's attachment ID, used as Elementor's cache key.
3174 - * @return array Local `id` and `url`, or an empty array when it cannot be resolved.
3175 - */
3176 - private static function wdkit_localise_media_url( $url, $source_id = 0 ) {
3177 - static $cache = array();
3178 -
3179 - if ( isset( $cache[ $url ] ) ) {
3180 - return $cache[ $url ];
3181 - }
3182 -
3183 - if ( ! did_action( 'elementor/loaded' ) || ! class_exists( '\\Elementor\\Plugin' ) ) {
3184 - return array();
3185 - }
3186 -
3187 - $images = \Elementor\Plugin::$instance->templates_manager->get_import_images_instance();
3188 -
3189 - if ( ! $images ) {
3190 - return array();
3191 - }
3192 -
3193 - // A download may happen, so keep the oversized-image guard in force.
3194 - self::wdkit_guard_oversized_images();
3195 -
3196 - $imported = $images->import(
3197 - array(
3198 - // Elementor only checks its hash table when an id is present.
3199 - 'id' => $source_id ? $source_id : 1,
3200 - 'url' => $url,
3201 - )
3202 - );
3203 -
3204 - $local = ( ! empty( $imported['id'] ) && ! empty( $imported['url'] ) )
3205 - ? array(
3206 - 'id' => (int) $imported['id'],
3207 - 'url' => $imported['url'],
3208 - )
3209 - : array();
3210 -
3211 - // Remember hits only: a sibling request importing concurrently may simply not have
3212 - // finished yet, and caching that miss would strand every later control on this page.
3213 - if ( $local ) {
3214 - $cache[ $url ] = $local;
3215 - }
3216 -
3217 - return $local;
3218 - }
3219 -
3220 - /**
3221 - * Repair dangling attachment IDs across every page of a finished import.
3222 - *
3223 - * The create-time repair in wdkit_media_import() can only see attachments that already
3224 - * exist. Pages import concurrently and share images — an icon first imported by one
3225 - * page is referenced by several others — so a page that runs early legitimately cannot
3226 - * resolve an image a sibling request has not created yet.
3227 - *
3228 - * This runs at the finalize step, once every page and attachment exists, and fixes
3229 - * whatever the per-page pass had to leave behind.
3230 - *
3231 - * @since 2.6.2
3232 - *
3233 - * @param array $page_ids Imported post IDs.
3234 - * @return int Number of pages actually rewritten.
3235 - */
3236 - private function wdkit_sweep_attachment_ids( $page_ids ) {
3237 -
3238 - if ( empty( $page_ids ) || ! did_action( 'elementor/loaded' ) ) {
3239 - return 0;
3240 - }
3241 -
3242 - $fixed = 0;
3243 - $ids = array_unique( array_map( 'intval', $page_ids ) );
3244 -
3245 - // Primes the meta cache for the whole batch in one query, so the
3246 - // get_post_meta() call below hits the cache instead of issuing one query
3247 - // per imported page.
3248 - update_meta_cache( 'post', $ids );
3249 -
3250 - foreach ( $ids as $post_id ) {
3251 -
3252 - if ( ! $post_id ) {
3253 - continue;
3254 - }
3255 -
3256 - $raw = get_post_meta( $post_id, '_elementor_data', true );
3257 -
3258 - if ( empty( $raw ) ) {
3259 - continue;
3260 - }
3261 -
3262 - $data = is_array( $raw ) ? $raw : json_decode( $raw, true );
3263 -
3264 - if ( ! is_array( $data ) ) {
3265 - continue;
3266 - }
3267 -
3268 - $repaired = self::wdkit_repair_attachment_ids( $data );
3269 -
3270 - if ( wp_json_encode( $repaired ) === wp_json_encode( $data ) ) {
3271 - continue;
3272 - }
3273 -
3274 - // Save through the document API so Elementor regenerates the page CSS — the
3275 - // background-image rules are only emitted once the IDs resolve.
3276 - $document = \Elementor\Plugin::$instance->documents->get( $post_id );
3277 -
3278 - // Count only a save that actually happened. Document::save() returns false
3279 - // without saving when the current user cannot edit the post, and reporting
3280 - // those as repaired hides the fact that nothing changed.
3281 - if ( $document && $document->save( array( 'elements' => $repaired ) ) ) {
3282 - ++$fixed;
3283 - }
3284 - }
3285 -
3286 - if ( $fixed ) {
3287 - \Elementor\Plugin::$instance->files_manager->clear_cache();
3288 - }
3289 -
3290 - return $fixed;
3291 - }
3292 -
3293 - /**
3294 - * Repair media controls whose attachment ID does not resolve.
3295 - *
3296 - * Elementor media controls store `{ url, id }`. Controls flagged `has_sizes` — the
3297 - * container/section **background image** among them — do not render from `url` at all:
3298 - * CSS generation resolves the image through the attachment ID, so a dangling ID
3299 - * produces no `background-image` rule and the section renders with no image even
3300 - * though its URL is perfectly correct.
3301 - *
3302 - * IDs arrive dangling whenever Elementor's own importer does not rewrite a control —
3303 - * it carries the source site's ID, which means nothing locally. Now that the URL is
3304 - * already a local upload before import, the ID can simply be looked up from it.
3305 - *
3306 - * @since 2.6.2
3307 - *
3308 - * @param mixed $node Elementor data, walked recursively.
3309 - * @return mixed Data with resolvable attachment IDs.
3310 - */
3311 - private static function wdkit_repair_attachment_ids( $node ) {
3312 -
3313 - if ( ! is_array( $node ) ) {
3314 - return $node;
3315 - }
3316 -
3317 - // A media control value: has a url, and an id slot to correct.
3318 - if ( isset( $node['url'] ) && is_string( $node['url'] ) && array_key_exists( 'id', $node ) ) {
3319 -
3320 - $current = (int) $node['id'];
3321 - $is_live = $current && 'attachment' === get_post_type( $current );
3322 -
3323 - if ( self::wdkit_is_foreign_media_url( $node['url'] ) ) {
3324 - // Still pointing at the source site. Ask Elementor for the local copy: its
3325 - // _elementor_source_image_hash lookup returns the attachment the create-time
3326 - // import already made, so this normally costs a single query and no download.
3327 - $local = self::wdkit_localise_media_url( $node['url'], $current );
3328 -
3329 - if ( ! empty( $local['id'] ) && ! empty( $local['url'] ) ) {
3330 - $node['id'] = $local['id'];
3331 - $node['url'] = $local['url'];
3332 - }
3333 - } elseif ( ! $is_live && false !== strpos( $node['url'], '/wp-content/uploads/' ) ) {
3334 - $resolved = self::wdkit_attachment_id_from_url( $node['url'] );
3335 -
3336 - if ( $resolved ) {
3337 - $node['id'] = $resolved;
3338 - }
3339 - }
3340 - }
3341 -
3342 - foreach ( $node as $key => $value ) {
3343 - if ( is_array( $value ) ) {
3344 - $node[ $key ] = self::wdkit_repair_attachment_ids( $value );
3345 - }
3346 - }
3347 -
3348 - return $node;
3349 - }
3350 -
3351 1295 public function wdkit_media_import( $content = array(), $editor = '' ) {
3352 1296
3353 1297 if ( empty( $content ) && empty( $editor ) ) {
3354 1298 $args = $this->wdkit_parse_args( $_POST );
@@ -3368,9 +1312,8 @@
3368 1312 if ( ! class_exists( 'Wdkit_Import_Images' ) ) {
3369 1313 require_once WDKIT_INCLUDES . 'admin/class-wdkit-import-images.php';
3370 1314 }
3371 1315
3372 -
3373 1316 if ( ! empty( $args['editor'] ) && 'gutenberg' === $args['editor'] && ! empty( $content ) ) {
3374 1317 $media_import = array( $content );
3375 1318 $media_import = self::blocks_import_media_copy_content( $media_import );
3376 1319 $content = $media_import[0];
@@ -3378,13 +1321,8 @@
3378 1321 $media_import = array( $content );
3379 1322 $media_import = self::widgets_elements_id_change( $media_import );
3380 1323 $media_import = self::widgets_import_media_copy_content( $media_import );
3381 1324 $content = $media_import[0];
3382 -
3383 - // Last: point any control Elementor left holding a foreign attachment ID at the
3384 - // local attachment its URL already refers to. Without this, has_sizes controls
3385 - // such as container background images resolve to nothing and render empty.
3386 - $content = self::wdkit_repair_attachment_ids( $content );
3387 1325 }
3388 1326
3389 1327 return $content;
3390 1328 }
@@ -3455,13 +1393,9 @@
3455 1393 $control_type = \Elementor\Plugin::instance()->controls_manager->get_control( $get_control['type'] );
3456 1394 $control_name = $get_control['name'];
3457 1395
3458 1396 if ( ! $control_type ) {
3459 - // Skip just this control. Returning here would abandon every control after
3460 - // it, so a single unregistered type - routine when a kit uses an addon that
3461 - // is not fully active yet - would silently leave the rest of the element's
3462 - // media pointing at the source site.
3463 - continue;
1397 + return $get_element_instance;
3464 1398 }
3465 1399
3466 1400 if ( method_exists( $control_type, $tp_mi_on_fun ) ) {
3467 1401 $get_element_instance['settings'][ $control_name ] = $control_type->{$tp_mi_on_fun}( $element->get_settings( $control_name ), $get_control );
@@ -3536,16 +1470,57 @@
3536 1470 public static function blocks_data_instance( array $block_data, array $args = array(), $block_args = null ) {
3537 1471
3538 1472 if ( ( isset( $block_data['name'] ) && isset( $block_data['clientId'] ) && isset( $block_data['attributes'] ) ) || ( isset( $block_data['blockName'] ) && isset( $block_data['attrs'] ) && ! empty( $block_data['attrs'] ) ) ) {
3539 1473 $blocks_attr = isset( $block_data['attributes'] ) ? $block_data['attributes'] : ( isset( $block_data['attrs'] ) ? $block_data['attrs'] : array() );
3540 - $blocks_attr = self::wdkit_import_block_media( $blocks_attr );
1474 + foreach ( $blocks_attr as $block_key => $block_val ) {
1475 + if ( isset( $block_val['url'] ) && isset( $block_val['id'] ) && ! empty( $block_val['url'] ) ) {
1476 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $block_val );
1477 + $blocks_attr[ $block_key ] = $new_media;
1478 + } elseif ( isset( $block_val['url'] ) && ! empty( $block_val['url'] ) && preg_match( '/\.(jpg|png|jpeg|gif|svg|webp)$/', $block_val['url'] ) ) {
1479 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $block_val );
1480 + $blocks_attr[ $block_key ] = $new_media;
1481 + } elseif ( is_array( $block_val ) && ! empty( $block_val ) ) {
1482 + if ( ! array_key_exists( 'md', $block_val ) && ! array_key_exists( 'openTypography', $block_val ) && ! array_key_exists( 'openBorder', $block_val ) && ! array_key_exists( 'openShadow', $block_val ) && ! array_key_exists( 'openFilter', $block_val ) ) {
1483 + foreach ( $block_val as $key => $val ) {
1484 + if ( is_array( $val ) && ! empty( $val ) ) {
1485 +
1486 + if ( isset( $val['url'] ) && ( isset( $val['Id'] ) || isset( $val['id'] ) ) && ! empty( $val['url'] ) ) {
1487 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $val );
1488 + $blocks_attr[ $block_key ][ $key ] = $new_media;
1489 + } elseif ( isset( $val['url'] ) && ! empty( $val['url'] ) && preg_match( '/\.(jpg|png|jpeg|gif|svg|webp)$/', $val['url'] ) ) {
1490 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $val );
1491 + $blocks_attr[ $block_key ][ $key ] = $new_media;
1492 + } else {
1493 + foreach ( $val as $sub_key => $sub_val ) {
1494 + if ( isset( $sub_val['url'] ) && ( isset( $sub_val['Id'] ) || isset( $sub_val['id'] ) ) && ! empty( $sub_val['url'] ) ) {
1495 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $sub_val );
1496 + $blocks_attr[ $block_key ][ $key ][ $sub_key ] = $new_media;
1497 + } elseif ( isset( $sub_val['url'] ) && ! empty( $sub_val['url'] ) && preg_match( '/\.(jpg|png|jpeg|gif|svg|webp)$/', $sub_val['url'] ) ) {
1498 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $sub_val );
1499 + $blocks_attr[ $block_key ][ $key ][ $sub_key ] = $new_media;
1500 + } elseif ( is_array( $sub_val ) && ! empty( $sub_val ) ) {
1501 + foreach ( $sub_val as $sub_key1 => $sub_val1 ) {
1502 + if ( isset( $sub_val1['url'] ) && ( isset( $sub_val1['Id'] ) || isset( $sub_val1['id'] ) ) && ! empty( $sub_val1['url'] ) ) {
1503 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $sub_val1 );
1504 + $blocks_attr[ $block_key ][ $key ][ $sub_key ][ $sub_key1 ] = $new_media;
1505 + } elseif ( isset( $sub_val1['url'] ) && ! empty( $sub_val1['url'] ) && preg_match( '/\.(jpg|png|jpeg|gif|svg|webp)$/', $sub_val1['url'] ) ) {
1506 + $new_media = Wdkit_Import_Images::wdkit_Import_media( $sub_val1 );
1507 + $blocks_attr[ $block_key ][ $key ][ $sub_key ][ $sub_key1 ] = $new_media;
1508 + }
1509 + }
1510 + }
1511 + }
1512 + }
1513 + }
1514 + }
1515 + }
1516 + }
1517 + }
3541 1518 if ( isset( $block_data['attributes'] ) ) {
3542 1519 $block_data['attributes'] = $blocks_attr;
3543 1520 } elseif ( isset( $block_data['attrs'] ) ) {
3544 1521 $block_data['attrs'] = $blocks_attr;
3545 1522 }
3546 -
3547 - $block_data = self::wdkit_relink_block_markup( $block_data );
3548 1523 }
3549 1524
3550 1525 return $block_data;
3551 1526 }
@@ -3550,284 +1525,8 @@
3550 1525 return $block_data;
3551 1526 }
3552 1527
3553 1528 /**
3554 - * Run block markup through the media import, the way the create path does.
3555 - *
3556 - * Used wherever block content is written from the browser: media import, then the Nexter
3557 - * block processor so each block's rendered copy matches its attributes, then serialise.
3558 - *
3559 - * @since 2.6.2
3560 - *
3561 - * @param string $content Block markup.
3562 - * @return string Block markup with local media.
3563 - */
3564 - private function wdkit_relink_gutenberg_content( $content ) {
3565 -
3566 - if ( ! is_string( $content ) || false === strpos( $content, '<!-- wp:' ) ) {
3567 - return $content;
3568 - }
3569 -
3570 - // wdkit_media_import() loads this itself, but it is referenced before that below.
3571 - if ( ! class_exists( 'Wdkit_Import_Images' ) ) {
3572 - require_once WDKIT_INCLUDES . 'admin/class-wdkit-import-images.php';
3573 - }
3574 -
3575 - // Thumbnail generation decodes each image, so keep the oversized-image guard in force.
3576 - self::wdkit_guard_oversized_images();
3577 -
3578 -
3579 - // Block attributes are JSON inside the block delimiters, so they only survive a parse
3580 - // when the string carries exactly one level of escaping. Arrive with an extra level and
3581 - // parse_blocks() reads no attributes at all - serialising that back out writes every
3582 - // block bare, throwing away titles, body text, icons and styling.
3583 - $parsable = self::wdkit_parsable_block_content( $content );
3584 -
3585 - if ( null === $parsable ) {
3586 -
3587 - return $content;
3588 - }
3589 -
3590 - $blocks = parse_blocks( $parsable );
3591 - $blocks = $this->wdkit_media_import( $blocks, 'gutenberg' );
3592 -
3593 - if ( empty( $blocks ) || ! is_array( $blocks ) ) {
3594 - return $content;
3595 - }
3596 -
3597 - if ( class_exists( 'WDKIT_Nexter_Block_Processor' ) ) {
3598 - $processor = new WDKIT_Nexter_Block_Processor();
3599 - $blocks = $processor->run( $blocks );
3600 - }
3601 -
3602 - $serialised = serialize_blocks( $blocks );
3603 -
3604 - // Last line of defence. This function exists to repoint media, so a result carrying
3605 - // fewer block attributes than it started with is a broken round trip, not a rewrite.
3606 - // Leaving the media wrong is recoverable; saving gutted content is not.
3607 - $before = self::wdkit_block_attr_count( $parsable );
3608 - $after = self::wdkit_block_attr_count( $serialised );
3609 -
3610 - if ( $after < $before ) {
3611 -
3612 - return $content;
3613 - }
3614 -
3615 - // Never hand back nothing: an empty result would blank the page.
3616 - return ! empty( $serialised ) ? $serialised : $content;
3617 - }
3618 -
3619 - /**
3620 - * Rebuild the block stylesheet for a page whose content we just rewrote.
3621 - *
3622 - * The addon keeps each block's styling in a generated per-page stylesheet, and every rule
3623 - * is keyed to the block id it was written for. That file is produced when the page is
3624 - * saved through the editor - not by wp_update_post() from an AJAX handler - so rewriting
3625 - * content here leaves the page pointing at a stylesheet built for the previous markup.
3626 - * Blocks whose ids are not in that file get no rules at all and render unstyled.
3627 - *
3628 - * @since 2.6.2
3629 - *
3630 - * @param int $post_id Page whose content changed.
3631 - * @return bool True when a rebuild was triggered.
3632 - */
3633 - private static function wdkit_rebuild_block_css( $post_id ) {
3634 -
3635 - if ( ! $post_id ) {
3636 - return false;
3637 - }
3638 -
3639 - foreach ( get_declared_classes() as $class ) {
3640 - if ( ! method_exists( $class, 'make_block_css_by_post_id' ) ) {
3641 - continue;
3642 - }
3643 -
3644 - try {
3645 - if ( method_exists( $class, 'instance' ) ) {
3646 - $instance = $class::instance();
3647 - } elseif ( method_exists( $class, 'get_instance' ) ) {
3648 - $instance = $class::get_instance();
3649 - } else {
3650 - $instance = new $class();
3651 - }
3652 -
3653 - $instance->make_block_css_by_post_id( $post_id );
3654 -
3655 -
3656 - return true;
3657 - } catch ( \Throwable $e ) {
3658 - // Styling is best-effort: a failure here must not fail the import.
3659 -
3660 - return false;
3661 - }
3662 - }
3663 -
3664 - return false;
3665 - }
3666 -
3667 - /**
3668 - * How many block attributes does this markup actually yield when parsed?
3669 - *
3670 - * Used as a before/after measure: block attributes are the part of block markup a round
3671 - * trip can silently drop, so counting them is how we tell a rewrite from a mangling.
3672 - *
3673 - * @since 2.6.2
3674 - *
3675 - * @param string $content Block markup.
3676 - * @return int Total attributes across every block.
3677 - */
3678 - private static function wdkit_block_attr_count( $content ) {
3679 - $total = 0;
3680 -
3681 - $walk = function ( $blocks ) use ( &$walk, &$total ) {
3682 - foreach ( $blocks as $block ) {
3683 - if ( ! empty( $block['attrs'] ) && is_array( $block['attrs'] ) ) {
3684 - $total += count( $block['attrs'] );
3685 - }
3686 -
3687 - if ( ! empty( $block['innerBlocks'] ) ) {
3688 - $walk( $block['innerBlocks'] );
3689 - }
3690 - }
3691 - };
3692 -
3693 - $walk( parse_blocks( (string) $content ) );
3694 -
3695 - return $total;
3696 - }
3697 -
3698 - /**
3699 - * Return this content in a form whose block attributes actually parse.
3700 - *
3701 - * Content written straight to post_content never had to parse, so an extra level of
3702 - * escaping on the way in did no harm. Parsing it - which repointing media requires - makes
3703 - * that escaping fatal: `{\"Title\":\"…\"}` is not JSON, so every attribute is discarded.
3704 - *
3705 - * Rather than assume a slash depth, this measures: if stripping one level yields more
3706 - * attributes, the content was over-escaped and the stripped form is the real one.
3707 - *
3708 - * @since 2.6.2
3709 - *
3710 - * @param string $content Block markup as received.
3711 - * @return string|null Markup safe to parse, or null when no form of it parses.
3712 - */
3713 - private static function wdkit_parsable_block_content( $content ) {
3714 -
3715 - $as_is = self::wdkit_block_attr_count( $content );
3716 -
3717 - // Nothing claims to carry attributes, so there is nothing to lose either.
3718 - if ( false === strpos( $content, '{' ) ) {
3719 - return $content;
3720 - }
3721 -
3722 - $stripped = wp_unslash( $content );
3723 - $stripped_attrs = self::wdkit_block_attr_count( $stripped );
3724 -
3725 - if ( $stripped_attrs > $as_is ) {
3726 - return $stripped;
3727 - }
3728 -
3729 - if ( $as_is > 0 ) {
3730 - return $content;
3731 - }
3732 -
3733 - // Neither form parses into attributes even though the markup contains JSON: better to
3734 - // leave the content exactly as it arrived than to rewrite it into something bare.
3735 - return null;
3736 - }
3737 -
3738 - /**
3739 - * Point a block's saved markup at the media that was just localised.
3740 - *
3741 - * A block stores a rendered copy of itself in `innerHTML` / `innerContent`, and for many
3742 - * blocks that copy is what the front end actually outputs. Importing the attributes alone
3743 - * therefore fixes the editor while leaving the page still loading from the site the
3744 - * template came from - and those hosts answer 403, so the image renders broken.
3745 - *
3746 - * @since 2.6.2
3747 - *
3748 - * @param array $block_data One parsed block.
3749 - * @return array The block with its markup repointed.
3750 - */
3751 - private static function wdkit_relink_block_markup( $block_data ) {
3752 -
3753 - $map = Wdkit_Import_Images::get_url_map();
3754 -
3755 - if ( empty( $map ) ) {
3756 - return $block_data;
3757 - }
3758 -
3759 - $from = array_keys( $map );
3760 - $to = array_values( $map );
3761 -
3762 - if ( ! empty( $block_data['innerHTML'] ) && is_string( $block_data['innerHTML'] ) ) {
3763 - $block_data['innerHTML'] = str_replace( $from, $to, $block_data['innerHTML'] );
3764 - }
3765 -
3766 - if ( ! empty( $block_data['innerContent'] ) && is_array( $block_data['innerContent'] ) ) {
3767 - foreach ( $block_data['innerContent'] as $index => $chunk ) {
3768 - if ( is_string( $chunk ) ) {
3769 - $block_data['innerContent'][ $index ] = str_replace( $from, $to, $chunk );
3770 - }
3771 - }
3772 - }
3773 -
3774 - return $block_data;
3775 - }
3776 -
3777 - /**
3778 - * Import every media reference held in a block's attributes.
3779 - *
3780 - * Block attributes nest arbitrarily - a repeater of cards each with an image, responsive
3781 - * variants, nested inner settings - so this recurses rather than reaching a fixed number
3782 - * of levels down. The previous version was unrolled exactly four levels deep and also
3783 - * skipped any subtree carrying an `md` key, which meant anything below that simply kept
3784 - * the source site's URL and attachment ID and rendered as an empty placeholder.
3785 - *
3786 - * A node counts as media when it has a non-empty string `url` and either an id slot or a
3787 - * URL that names an image file. That pairing is what distinguishes a media control from
3788 - * a link, which also carries a `url`.
3789 - *
3790 - * @since 2.6.2
3791 - *
3792 - * @param mixed $node Block attributes, walked recursively.
3793 - * @return mixed Attributes with local media.
3794 - */
3795 - private static function wdkit_import_block_media( $node ) {
3796 -
3797 - if ( ! is_array( $node ) ) {
3798 - return $node;
3799 - }
3800 -
3801 - $url = isset( $node['url'] ) && is_string( $node['url'] ) ? $node['url'] : '';
3802 -
3803 - if ( '' !== $url
3804 - && ( array_key_exists( 'id', $node ) || array_key_exists( 'Id', $node )
3805 - || preg_match( '/\.(?:jpe?g|png|gif|svg|webp|avif|bmp)$/i', (string) wp_parse_url( $url, PHP_URL_PATH ) ) )
3806 - ) {
3807 - $imported = Wdkit_Import_Images::wdkit_Import_media( $node );
3808 -
3809 - // Only accept a real result. The importer returns the node untouched when it
3810 - // cannot localise the file, and anything falsy here would wipe out the URL and
3811 - // leave the block with no image at all.
3812 - if ( ! empty( $imported['url'] ) ) {
3813 - $node = array_merge( $node, $imported );
3814 - }
3815 - }
3816 -
3817 - // Keep walking even after importing this node. A media value carries its own `sizes`
3818 - // map of per-size URLs, and returning here left every one of those pointing at the
3819 - // site the template came from - which is what the widgets actually render from.
3820 - foreach ( $node as $key => $value ) {
3821 - if ( is_array( $value ) ) {
3822 - $node[ $key ] = self::wdkit_import_block_media( $value );
3823 - }
3824 - }
3825 -
3826 - return $node;
3827 - }
3828 -
3829 - /**
3830 1529 * Kit Template Import Pages/Sections
3831 1530 *
3832 1531 * @since 1.0.0
3833 1532 * */
@@ -3836,10 +1535,8 @@
3836 1535 if ( ! current_user_can( 'manage_options' ) ) {
3837 1536 return false;
3838 1537 }
3839 1538
3840 - $builder = isset( $_POST['builder'] ) ? sanitize_text_field( wp_unslash( $_POST['builder'] ) ) : '';
3841 -
3842 1539 $page_section = ! empty( $_POST['page_section'] ) ? sanitize_text_field( wp_unslash( $_POST['page_section'] ) ) : '';
3843 1540
3844 1541 if ( isset( $page_section ) ) {
3845 1542 $args['page_section'] = ! empty( $page_section ) ? sanitize_text_field( wp_unslash( $page_section ) ) : '';
@@ -3844,16 +1541,14 @@
3844 1541 if ( isset( $page_section ) ) {
3845 1542 $args['page_section'] = ! empty( $page_section ) ? sanitize_text_field( wp_unslash( $page_section ) ) : '';
3846 1543 }
3847 1544
3848 - $template_ids = ! empty( $_POST['template_ids'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['template_ids'] ) ), true ) : array();
3849 - $email = ! empty( $_POST['email'] ) ? strtolower( sanitize_email( wp_unslash( $_POST['email'] ) ) ) : '';
3850 - $editor = isset( $_POST['editor'] ) ? sanitize_text_field( wp_unslash( $_POST['editor'] ) ) : '';
3851 - $website_kit = isset( $_POST['website_kit'] ) ? sanitize_text_field( wp_unslash( $_POST['website_kit'] ) ) : '';
3852 - $api_type = isset( $_POST['api_type'] ) ? sanitize_text_field( wp_unslash( $_POST['api_type'] ) ) : 'import_template';
3853 - $ai_compitible = isset( $_POST['ai_compitible'] ) ? sanitize_text_field( wp_unslash( $_POST['ai_compitible'] ) ) : false;
1545 + $template_ids = ! empty( $_POST['template_ids'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['template_ids'] ) ), true ) : array();
1546 + $email = ! empty( $_POST['email'] ) ? strtolower( sanitize_email( wp_unslash( $_POST['email'] ) ) ) : '';
1547 + $editor = isset( $_POST['editor'] ) ? sanitize_text_field( wp_unslash( $_POST['editor'] ) ) : '';
1548 + $website_kit = isset( $_POST['website_kit'] ) ? sanitize_text_field( wp_unslash( $_POST['website_kit'] ) ) : '';
3854 1549
3855 - if ( empty( $template_ids ) ) {
1550 + if ( empty( $email ) || empty( $template_ids ) ) {
3856 1551 $output = array(
3857 1552 'message' => esc_html__( 'Invalid import', 'wdesignkit' ),
3858 1553 'description' => esc_html__( 'Invalid import: Check your details and try again.', 'wdesignkit' ),
3859 1554 'success' => false,
@@ -3877,120 +1572,32 @@
3877 1572 'token' => $token,
3878 1573 'template_id' => $template_ids['id'],
3879 1574 'editor' => $editor,
3880 1575 'website_kit' => $website_kit,
3881 - 'unique_id' => get_option( 'wdkit_unique_id' ) ?? '',
3882 1576 );
3883 1577
3884 - $response = WDesignKit_Data_Query::get_data( $api_type, $temp_args );
1578 + $response = WDesignKit_Data_Query::get_data( 'import_template', $temp_args );
3885 1579 $output = array();
3886 1580
3887 - if ( is_wp_error( $response ) ) {
3888 -
1581 + if ( 'error' === $response['content'] ) {
3889 1582 wp_send_json( $response );
3890 1583 wp_die();
1584 + } else {
1585 + $output[ $template_ids['id'] ] = $this->import_page_section_content( $args, $template_ids['id'], $response, $template_ids );
1586 + $output['message'] = $response['message'];
1587 + $output['description'] = $response['description'];
1588 + $output['success'] = $response['success'];
3891 1589 }
3892 1590
3893 - if ( isset( $response['content'] ) && 'error' === $response['content'] ) {
3894 - wp_send_json( $response );
3895 - wp_die();
3896 - }
3897 -
3898 - $result = array(
3899 - 'response' => $response,
3900 - 'args' => $args,
3901 - 'id' => $template_ids['id'],
3902 - 'temp_data' => $template_ids,
3903 - );
3904 -
3905 - $output['message'] = $response['message'];
3906 - $output['description'] = $response['description'];
3907 - $output['data'] = $result;
3908 - $output['success'] = $response['success'];
3909 -
3910 - // Counts the IMPORT ACTION, not what it brought in. A kit import always counts as 1 kit,
3911 - // no matter how many blocks/pages that kit contains — confirmed live: a single gutenberg
3912 - // kit import recorded total=680, kinds.kit=680, because $template_ids for that call was a
3913 - // 680-element array of the kit's own blocks and count( $template_ids ) counted every one of
3914 - // them. A page-kit's *size* is not tracking's concern; "was a kit imported" is.
3915 - //
3916 - // The 'single' branch keeps a defensive fallback for the one shape this endpoint's own
3917 - // $template_ids reliably takes when it is not a kit — a single {id, name, slug, thumb...}
3918 - // object — where count() would likewise count JSON keys instead of "1 template imported".
3919 - if ( ! empty( $output['success'] ) ) {
3920 - $is_kit = ( '' !== $website_kit );
3921 - $import_count = $is_kit ? 1 : ( isset( $template_ids['id'] ) ? 1 : ( is_array( $template_ids ) ? count( $template_ids ) : 1 ) );
3922 - do_action(
3923 - 'wdkit_template_imported',
3924 - $is_kit ? 'kit' : 'single',
3925 - sanitize_key( $builder ),
3926 - $import_count
3927 - );
3928 - }
3929 -
3930 1591 wp_send_json( $output );
3931 1592 wp_die();
3932 1593 }
3933 1594
3934 - public function wdkit_enable_template_widgets() {
3935 - $widget_list = ! empty( $_POST['widget_list'] ) ? json_decode( wp_unslash( $_POST['widget_list'] ), true ) : array();
3936 - $extensions_list = ! empty( $_POST['extensions_list'] ) ? json_decode( wp_unslash( $_POST['extensions_list'] ), true ) : array();
3937 -
3938 - if ( empty( $widget_list ) && empty( $extensions_list ) ) {
3939 - $res = array(
3940 - 'massage' => __( 'Widget array not found', 'wdesignkit' ),
3941 - 'description' => __( 'Widget array not found', 'wdesignkit' ),
3942 - 'success' => false,
3943 - );
3944 - wp_send_json( $res );
3945 - wp_die();
3946 - }
3947 -
3948 - if ( ! has_filter( 'tpae_enable_selected_widgets' ) ) {
3949 - $res = array(
3950 - 'massage' => __( 'Relevant Plugin not Activated', 'wdesignkit' ),
3951 - 'description' => __( 'Relevant Plugin not Installed / Activated', 'wdesignkit' ),
3952 - 'success' => false,
3953 - );
3954 - wp_send_json( $res );
3955 - wp_die();
3956 - }
3957 -
3958 - $w_list = array(
3959 - 'widgets' => $widget_list,
3960 - 'extensions' => $extensions_list,
3961 - );
3962 -
3963 - $result = apply_filters( 'tpae_enable_selected_widgets', $w_list );
3964 -
3965 - if ( ! empty( $result['success'] ) ) {
3966 - $res = array(
3967 - 'massage' => __( 'Enabled widgets successfully', 'wdesignkit' ),
3968 - 'description' => __( 'Used widgets have been enabled successfully', 'wdesignkit' ),
3969 - 'success' => true,
3970 - );
3971 - } else {
3972 -
3973 - $message = isset( $result['message'] ) ? $result['message'] : __( 'Failed to enable widgets', 'wdesignkit' );
3974 - $description = isset( $result['description'] ) ? $result['description'] : __( 'Failed to enable widgets', 'wdesignkit' );
3975 -
3976 - $res = array(
3977 - 'massage' => $message,
3978 - 'description' => $description,
3979 - 'success' => false,
3980 - );
3981 - }
3982 -
3983 - wp_send_json( $res );
3984 - wp_die();
3985 - }
3986 -
3987 1595 /**
3988 1596 * Import single template and section from plugin only
3989 1597 * */
3990 1598 protected function wdkit_import_multi_template() {
3991 - $args = $this->wdkit_parse_args( $_POST );
3992 - $api_type = isset( $_POST['api_type'] ) ? sanitize_text_field( wp_unslash( $_POST['api_type'] ) ) : 'import_template';
1599 + $args = $this->wdkit_parse_args( $_POST );
3993 1600
3994 1601 if ( ! current_user_can( 'manage_options' ) ) {
3995 1602 return false;
3996 1603 }
@@ -4019,50 +1626,56 @@
4019 1626 $args['post_type'] = ! empty( $_POST['select'] ) ? sanitize_text_field( wp_unslash( $_POST['select'] ) ) : '';
4020 1627 }
4021 1628
4022 1629 $args['custom_meta'] = isset( $_POST['custom_meta'] ) ? sanitize_text_field( wp_unslash( $_POST['custom_meta'] ) ) : false;
4023 -
4024 1630 if ( ! empty( $args['template_ids'] ) && ! empty( $args['page_section'] ) ) {
4025 1631 $output = array();
4026 - if ( ! empty( $args['template_ids']['id'] ) ) {
1632 + if ( is_array( $args['template_ids'] ) ) {
1633 + foreach ( $args['template_ids'] as $key => $value ) {
1634 + if ( ! empty( $value['id'] ) ) {
1635 + $token = $this->wdkit_login_user_token( $args['email'] );
1636 + $temp_args = array(
1637 + 'token' => $token,
1638 + 'template_id' => $value['id'],
1639 + 'editor' => $args['editor'],
1640 + );
1641 +
1642 + $response = WDesignKit_Data_Query::get_data( 'import_template', $temp_args );
1643 +
1644 + if ( 'error' === $response['content'] ) {
1645 + wp_send_json( $response );
1646 + wp_die();
1647 + } else {
1648 + $output[ $value['id'] ] = $this->import_page_section_content( $args, $value['id'], $response, $value );
1649 + $output['message'] = $response['message'];
1650 + $output['description'] = $response['description'];
1651 + $output['success'] = $response['success'];
1652 + }
1653 + }
1654 + }
1655 + } else {
4027 1656 $token = $this->wdkit_login_user_token( $args['email'] );
4028 -
4029 1657 $temp_args = array(
4030 1658 'token' => $token,
4031 - 'template_id' => $args['template_ids']['id'],
1659 + 'template_id' => $args['template_ids'],
4032 1660 'editor' => $args['editor'],
4033 - 'unique_id' => get_option( 'wdkit_unique_id' ) ?? '',
4034 1661 );
4035 1662
4036 - $response = WDesignKit_Data_Query::get_data( $api_type, $temp_args );
1663 + $response = WDesignKit_Data_Query::get_data( 'import_template', $temp_args );
4037 1664
4038 - if ( is_wp_error( $response ) ) {
4039 - wp_send_json( array(
4040 - 'success' => false,
4041 - 'message' => $response->get_error_message(),
4042 - ) );
4043 - wp_die();
4044 - }
4045 -
4046 - if ( isset( $response['content'] ) && 'error' === $response['content'] ) {
1665 + if ( 'error' === $response['content'] ) {
4047 1666 wp_send_json( $response );
4048 1667 wp_die();
1668 + } else {
1669 + $output[ $args['template_ids'] ] = $this->import_page_section_content( $args, $args['template_ids'], $response );
1670 + $output['message'] = $response['message'];
1671 + $output['description'] = $response['description'];
1672 + $output['success'] = $response['success'];
4049 1673 }
1674 + }
4050 1675
4051 - $result = array(
4052 - 'response' => $response,
4053 - 'args' => $args,
4054 - 'id' => $args['template_ids'],
4055 - 'value' => $args['template_ids'],
4056 - );
1676 + $output['success'] = true;
4057 1677
4058 - $output['message'] = $response['message'];
4059 - $output['description'] = $response['description'];
4060 - $output['data'] = $result;
4061 - $output['success'] = true;
4062 -
4063 - }
4064 -
4065 1678 wp_send_json( $output );
4066 1679 wp_die();
4067 1680 }
4068 1681 }
@@ -4067,151 +1680,8 @@
4067 1680 }
4068 1681 }
4069 1682
4070 1683 /**
4071 - * It is Use for remove selected category from content.
4072 - *
4073 - * @since 2.0.5
4074 - */
4075 - public function wdkit_content_remover( &$data ) {
4076 -
4077 - if ( is_array( $data ) ) {
4078 -
4079 - foreach ( $data as $key => &$value ) {
4080 - if ( $key === 'post_category' ) {
4081 - $data[ $key ] = array();
4082 - } else if ($key === 'include_products'){
4083 - $data[ $key ] = "";
4084 - } else {
4085 - $this->wdkit_content_remover( $value );
4086 - }
4087 - }
4088 - } elseif ( is_object( $data ) ) {
4089 -
4090 - foreach ( $data as $key => &$value ) {
4091 - if ( $key === 'post_category' ) {
4092 - $data->$key = array();
4093 - } else if ($key === 'include_products'){
4094 - $data->$key = "";
4095 - } else {
4096 - $this->wdkit_content_remover( $value );
4097 - }
4098 - }
4099 - }
4100 -
4101 - return $data;
4102 - }
4103 -
4104 - protected function wkit_update_elementor_template(){
4105 -
4106 - if ( isset( $_POST['data'] ) ) {
4107 - $content = ! empty( $_POST['data'] ) ? json_decode( wp_unslash( $_POST['data'] ), true ) : '';
4108 - }
4109 -
4110 - if ( isset( $_POST['template_id'] ) ) {
4111 - $template_id = ! empty( $_POST['template_id'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['template_id'] ), true ) ) : '';
4112 - }
4113 -
4114 - $document = \Elementor\Plugin::$instance->documents->get($template_id);
4115 -
4116 - // This saves content posted straight from the browser, which carries local image
4117 - // URLs but still the source template's attachment IDs. Without repairing them the
4118 - // save undoes what wdkit_media_import() fixed on create, and has_sizes controls —
4119 - // container background images especially — resolve to nothing and render empty.
4120 - $content = self::wdkit_repair_attachment_ids( $content );
4121 -
4122 - $document->save([
4123 - 'elements' => $content
4124 - ]);
4125 - }
4126 -
4127 - /**
4128 - * Update the content of an already-created page.
4129 - *
4130 - * Used by the async ("Site Ready first") import path: pages are created up front with
4131 - * their un-rewritten template content, then this writes the AI-rewritten content into
4132 - * each page in the background. Elementor saves via the document API (same as
4133 - * wkit_update_elementor_template); Gutenberg writes post_content directly.
4134 - *
4135 - * @since 2.6.2
4136 - */
4137 - protected function wdkit_update_page_content() {
4138 - $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
4139 - $builder = isset( $_POST['builder'] ) ? sanitize_text_field( wp_unslash( $_POST['builder'] ) ) : '';
4140 -
4141 - if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
4142 - return array(
4143 - 'success' => false,
4144 - 'message' => esc_html__( 'Invalid page or insufficient permission', 'wdesignkit' ),
4145 - );
4146 - }
4147 -
4148 - if ( 'gutenberg' === $builder ) {
4149 - // Do NOT run kses here: Gutenberg block delimiters are HTML comments
4150 - // (<!-- wp:... -->) which kses strips. Mirror the create path, which stores
4151 - // the block markup slashed and unfiltered (endpoint is manage_options-gated
4152 - // and the content is plugin-generated).
4153 - $content = isset( $_POST['content'] ) ? wp_unslash( $_POST['content'] ) : '';
4154 -
4155 - // This content comes straight from the browser and still carries the template
4156 - // site's media URLs and attachment IDs, so it has to go through the same pipeline
4157 - // the create path uses. Without this the save simply undid the import: the files
4158 - // were fetched, then overwritten by a copy still pointing at the source site.
4159 - //
4160 - // Re-running is cheap. Every URL already handled resolves from the source-hash
4161 - // lookup, and media that is already local resolves straight from its URL, so no
4162 - // image is fetched or stored twice.
4163 - $content = $this->wdkit_relink_gutenberg_content( $content );
4164 -
4165 - $result = wp_update_post(
4166 - array(
4167 - 'ID' => $post_id,
4168 - 'post_content' => wp_slash( $content ),
4169 - ),
4170 - true
4171 - );
4172 -
4173 - if ( is_wp_error( $result ) ) {
4174 - return array(
4175 - 'success' => false,
4176 - 'message' => $result->get_error_message(),
4177 - );
4178 - }
4179 -
4180 - self::wdkit_rebuild_block_css( $post_id );
4181 - } else {
4182 - $elements = isset( $_POST['content'] ) ? json_decode( wp_unslash( $_POST['content'] ), true ) : array();
4183 -
4184 - if ( ! class_exists( '\\Elementor\\Plugin' ) ) {
4185 - return array(
4186 - 'success' => false,
4187 - 'message' => esc_html__( 'Elementor not available', 'wdesignkit' ),
4188 - );
4189 - }
4190 -
4191 - $document = \Elementor\Plugin::$instance->documents->get( $post_id );
4192 - if ( ! $document ) {
4193 - return array(
4194 - 'success' => false,
4195 - 'message' => esc_html__( 'Elementor document not found', 'wdesignkit' ),
4196 - );
4197 - }
4198 -
4199 - // Same as wkit_update_elementor_template(): browser-posted content keeps the
4200 - // source template's attachment IDs, so repair them or this save undoes the
4201 - // create-time fix and background images stop rendering.
4202 - $elements = self::wdkit_repair_attachment_ids( $elements );
4203 -
4204 - $document->save( array( 'elements' => $elements ) );
4205 - }
4206 -
4207 - return array(
4208 - 'success' => true,
4209 - 'message' => esc_html__( 'Page content updated', 'wdesignkit' ),
4210 - );
4211 - }
4212 -
4213 - /**
4214 1684 * Import single template and section from plugin only
4215 1685 *
4216 1686 * @param array $args store data.
4217 1687 * @param array $template_id store data.
@@ -4217,53 +1687,9 @@
4217 1687 * @param array $template_id store data.
4218 1688 * @param array $data store data.
4219 1689 * @param array $temp_data store data.
4220 1690 * */
4221 - protected function import_page_section_content() {
4222 -
4223 - // Elementor sideloads every image referenced by the page from inside this request.
4224 - // A single oversized source image decodes to more than the whole memory limit, so
4225 - // guard before any of that starts.
4226 - $this->wdkit_guard_oversized_images();
4227 -
4228 - // Sideloading images for image-heavy pages (wdkit_media_import → Imagick
4229 - // thumbnail generation per image) can exceed the default 30s execution
4230 - // limit and fatal the request mid-import. Give this single page import
4231 - // more headroom; harmless no-op where set_time_limit() is disabled.
4232 - if ( function_exists( 'set_time_limit' ) ) {
4233 - @set_time_limit( 120 );
4234 - }
4235 -
4236 - if ( isset( $_POST['args'] ) ) {
4237 - $args = ! empty( $_POST['args'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['args'] ) ), true ) : array();
4238 - }
4239 -
4240 - if ( isset( $_POST['temp_data'] ) ) {
4241 - $temp_data = ! empty( $_POST['temp_data'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['temp_data'] ) ), true ) : array();
4242 - }
4243 -
4244 - if ( isset( $_POST['category_list'] ) ) {
4245 - $category_list = ! empty( $_POST['category_list'] ) ? json_decode( wp_unslash( $_POST['category_list'] ), true ) : '';
4246 - }
4247 -
4248 - if ( isset( $_POST['tag_list'] ) ) {
4249 - $tag_list = ! empty( $_POST['tag_list'] ) ? json_decode( wp_unslash( $_POST['tag_list'] ), true ) : '';
4250 - }
4251 -
4252 - if ( isset( $_POST['thumb_image'] ) ) {
4253 - $thumb_image = ! empty( $_POST['thumb_image'] ) ? esc_url_raw( $_POST['thumb_image'] ) : '';
4254 - }
4255 -
4256 - if ( isset( $_POST['template_id'] ) ) {
4257 - $template_id = ! empty( $_POST['template_id'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['template_id'] ), true ) ) : '';
4258 - }
4259 -
4260 - $temp_type = isset( $_POST['temp_type'] ) ? sanitize_text_field( wp_unslash( $_POST['temp_type'] ) ) : 'normal';
4261 -
4262 - if ( isset( $_POST['data'] ) ) {
4263 - $data = ! empty( $_POST['data'] ) ? json_decode( wp_unslash( $_POST['data'] ) ) : '';
4264 - }
4265 -
1691 + private function import_page_section_content( $args, $template_id, $data, $temp_data = array() ) {
4266 1692 $enqueue_instance = new Wdkit_Enqueue();
4267 1693 $get_post_type = $enqueue_instance->wdkit_get_post_type_list();
4268 1694
4269 1695 $post_type = ! empty( $temp_data['type'] ) ? sanitize_text_field( wp_unslash( $temp_data['type'] ) ) : 'page';
@@ -4269,10 +1695,8 @@
4269 1695 $post_type = ! empty( $temp_data['type'] ) ? sanitize_text_field( wp_unslash( $temp_data['type'] ) ) : 'page';
4270 1696
4271 1697 if ( 'section' === $post_type ) {
4272 1698 $post_type = $temp_data['wp_post_type'];
4273 - } else {
4274 - $post_type = $temp_data['wp_post_type'];
4275 1699 }
4276 1700
4277 1701 if ( ! array_key_exists( $post_type, $get_post_type ) ) {
4278 1702 $post_type = 'page';
@@ -4277,28 +1701,13 @@
4277 1701 if ( ! array_key_exists( $post_type, $get_post_type ) ) {
4278 1702 $post_type = 'page';
4279 1703 }
4280 1704
4281 - if ( ! empty( $data ) && ! empty( $template_id ) && ! empty( $post_type ) && current_user_can( 'manage_options' ) ) {
4282 - $post_content = $data;
4283 - // Restore The Plus Addons' globals before the page is built, so the widgets'
4284 - // tp_global_preset references resolve as soon as it renders. Done here rather
4285 - // than in the save-template UI's confirmation dialog so that every import path
4286 - // - the library, the abilities, the theme builder - gets it.
4287 - if ( isset( $post_content->tp_globals ) && ! empty( $post_content->tp_globals ) ) {
4288 - $this->wdkit_merge_tp_globals(
4289 - json_decode( wp_json_encode( $post_content->tp_globals ), true ),
4290 - isset( $post_content->tp_global_refs )
4291 - ? json_decode( wp_json_encode( $post_content->tp_global_refs ), true )
4292 - : array()
4293 - );
4294 - }
4295 -
1705 + if ( ! empty( $data ) && ! empty( $data['content'] ) && ! empty( $template_id ) && ! empty( $post_type ) && current_user_can( 'manage_options' ) ) {
1706 + $post_content = json_decode( $data['content'] );
4296 1707 $post_title = isset( $post_content->title ) ? sanitize_text_field( $post_content->title ) : '';
4297 - $post_slug = isset( $post_content->slug ) ? sanitize_text_field( $post_content->slug ) : '';
4298 1708 $file_type = isset( $post_content->file_type ) ? sanitize_text_field( $post_content->file_type ) : '';
4299 1709 $content = isset( $post_content->content ) ? wp_slash( $post_content->content ) : '';
4300 - $temp_con = '';
4301 1710
4302 1711 if ( 'gutenberg' === $args['editor'] || ( 'wdkit' === $args['editor'] && ! empty( $file_type ) && 'wp_block' === $file_type ) ) {
4303 1712 if ( empty( $content ) ) {
4304 1713 wp_send_json(
@@ -4303,31 +1712,24 @@
4303 1712 if ( empty( $content ) ) {
4304 1713 wp_send_json(
4305 1714 array(
4306 1715 'template_id' => $template_id,
4307 - 'message' => __( 'Content is Empty.', 'wdesignkit' ),
1716 + 'message' => 'Content is Empty.',
4308 1717 )
4309 1718 );
4310 1719 wp_die();
4311 1720 } elseif ( ! empty( $content ) && ! empty( $file_type ) && 'wp_block' === $file_type ) {
1721 + $parse_blocks = parse_blocks( stripslashes( $content ) );
4312 1722
4313 1723 $editor = ( 'wdkit' === $args['editor'] ) ? 'gutenberg' : $args['editor'];
4314 - $blocks = parse_blocks( stripslashes( $content ) );
1724 + $content = $this->wdkit_media_import( $parse_blocks, $editor );
1725 + $content = addslashes( serialize_blocks( $content ) );
4315 1726
4316 - $blocks = $this->wdkit_media_import( $blocks, $editor );
4317 -
4318 - $processor = new WDKIT_Nexter_Block_Processor();
4319 - $blocks = $processor->run( $blocks );
4320 - $content = serialize_blocks( $blocks );
4321 -
4322 - $content = $this->replace_unicode_glitch( serialize_blocks( $blocks ) );
4323 -
4324 1727 $inserted_post = wp_insert_post(
4325 1728 array(
4326 1729 'post_status' => 'publish',
4327 1730 'post_type' => $post_type,
4328 1731 'post_title' => $post_title,
4329 - 'post_name' => $post_slug,
4330 1732 'post_content' => $content,
4331 1733 )
4332 1734 );
4333 1735
@@ -4340,47 +1742,14 @@
4340 1742 );
4341 1743 wp_die();
4342 1744 }
4343 1745
4344 - if ( ! empty( $thumb_image ) && wdesignkit_validate_external_url( $thumb_image ) ) {
4345 - // $featured_image_url = esc_url_raw( $thumb_image );
4346 - $tmp = download_url( $thumb_image );
4347 - if ( is_wp_error( $tmp ) ) {
4348 - error_log( 'Image download failed: ' . esc_html( $tmp->get_error_message() ) );
4349 - } else {
4350 - $file_array = array(
4351 - 'name' => wp_basename( $thumb_image ),
4352 - 'tmp_name' => $tmp,
4353 - );
4354 -
4355 - $image_id = media_handle_sideload( $file_array, $inserted_post );
4356 -
4357 - if ( is_wp_error( $image_id ) ) {
4358 - error_log( 'Image sideload failed: ' . esc_html( $image_id->get_error_message() ) );
4359 - } else {
4360 - set_post_thumbnail( $inserted_post, $image_id );
4361 - }
4362 -
4363 - @unlink( $tmp );
4364 - }
4365 - }
4366 -
4367 - if ( ! empty( $category_list ) && is_array( $category_list ) ) {
4368 - $category_ids = array_map( 'intval', $category_list );
4369 - wp_set_post_terms( $inserted_post, $category_ids, 'category' );
4370 - }
4371 -
4372 - if ( ! empty( $tag_list ) && is_array( $tag_list ) ) {
4373 - $tag_ids = array_map( 'intval', $tag_list );
4374 - wp_set_post_terms( $inserted_post, $tag_ids, 'post_tag' );
4375 - }
4376 -
4377 1746 if ( ! empty( $args['custom_meta'] ) && 'true' == $args['custom_meta'] ) {
4378 1747 $custom_meta = isset( $post_content->custom_meta ) ? json_decode( wp_json_encode( $post_content->custom_meta ), true ) : '';
4379 1748 if ( ! empty( $custom_meta ) ) {
4380 1749 foreach ( $custom_meta as $meta_key => $meta_val ) {
4381 1750 if ( isset( $meta_val[0] ) && ! empty( $meta_val[0] ) && is_serialized( $meta_val[0] ) ) {
4382 - $meta_val[0] = unserialize( $meta_val[0], array( 'allowed_classes' => false ) );
1751 + $meta_val[0] = maybe_unserialize( $meta_val[0] );
4383 1752 }
4384 1753
4385 1754 if ( '' === get_post_meta( $inserted_post, $meta_key, true ) && isset( $meta_val[0] ) ) {
4386 1755 add_post_meta( $inserted_post, $meta_key, $meta_val[0] );
@@ -4388,49 +1757,13 @@
4388 1757 }
4389 1758 }
4390 1759 }
4391 1760
4392 - $temp_detail = array(
1761 + return array(
4393 1762 'title' => get_the_title( $inserted_post ),
4394 1763 'edit_link' => get_edit_post_link( $inserted_post, 'internal' ),
4395 1764 'view' => get_permalink( $inserted_post ),
4396 - 'id' => $inserted_post,
4397 1765 );
4398 -
4399 - if ( ! empty( $template_id->id ) ) {
4400 - $temp_id = $template_id->id;
4401 - } elseif ( ! empty( $template_id ) ) {
4402 - $temp_id = $template_id;
4403 - } else {
4404 - $temp_id = '';
4405 - }
4406 -
4407 - wp_update_post([
4408 - 'ID' => $inserted_post,
4409 - ]);
4410 -
4411 - if (class_exists('Tpgb_Library') && method_exists('Tpgb_Library', 'remove_backend_dir_files')) {
4412 - Tpgb_Library()->remove_backend_dir_files();
4413 - }
4414 -
4415 - clean_post_cache( $inserted_post );
4416 -
4417 - // This whole method imports exactly one section per call — unlike
4418 - // wdkit_import_template()/wdkit_import_kit_template(), it never fired this hook
4419 - // at all, so single-section imports (Header/Footer/CTA/etc., a primary import
4420 - // path per the Template Type sidebar) were invisible to tracking entirely.
4421 - do_action( 'wdkit_template_imported', 'single', sanitize_key( $editor ), 1 );
4422 -
4423 - wp_send_json(
4424 - array(
4425 - $temp_id => $temp_detail,
4426 - 'description' => 'Yay! Your Section has been Successfully Imported.',
4427 - 'message' => __( 'Successfully Imported.', 'wdesignkit' ),
4428 - 'inserted_id' => $inserted_post,
4429 - 'success' => true,
4430 - )
4431 - );
4432 - wp_die();
4433 1766 }
4434 1767 } elseif ( 'elementor' === $args['editor'] || ( 'wdkit' === $args['editor'] && ! empty( $file_type ) && 'elementor' === $file_type ) ) {
4435 1768 if ( did_action( 'elementor/loaded' ) ) {
4436 1769 if ( empty( $content ) ) {
@@ -4436,21 +1769,17 @@
4436 1769 if ( empty( $content ) ) {
4437 1770 wp_send_json(
4438 1771 array(
4439 1772 'template_id' => $template_id,
4440 - 'message' => __( 'Content is Empty.', 'wdesignkit' ),
1773 + 'message' => 'Content is Empty.',
4441 1774 )
4442 1775 );
4443 1776 wp_die();
4444 1777 } elseif ( ! empty( $content ) && ! empty( $file_type ) && 'elementor' === $file_type ) {
4445 -
4446 - $content = $this->wdkit_content_remover( $content );
4447 -
4448 1778 $post_attributes = array(
4449 1779 'post_title' => $post_title,
4450 1780 'post_type' => $post_type,
4451 1781 'post_status' => 'publish',
4452 - 'post_name' => $post_slug,
4453 1782 );
4454 1783
4455 1784 if ( 'elementor_library' === $post_type ) {
4456 1785 $el_type = ( isset( $post_content->el_type ) && ! empty( $post_content->el_type ) ) ? sanitize_text_field( $post_content->el_type ) : 'page';
@@ -4474,43 +1803,8 @@
4474 1803 );
4475 1804 wp_die();
4476 1805 }
4477 1806
4478 - $inserted_id = $new_document->get_main_id();
4479 -
4480 - if ( ! empty( $thumb_image ) && wdesignkit_validate_external_url( $thumb_image ) ) {
4481 - // $featured_image_url = esc_url_raw( $thumb_image );
4482 - $tmp = download_url( $thumb_image );
4483 - if ( is_wp_error( $tmp ) ) {
4484 - error_log( 'Image download failed: ' . esc_html( $tmp->get_error_message() ) );
4485 - } else {
4486 - $file_array = array(
4487 - 'name' => wp_basename( $thumb_image ),
4488 - 'tmp_name' => $tmp,
4489 - );
4490 -
4491 - $image_id = media_handle_sideload( $file_array, $inserted_id );
4492 -
4493 - if ( is_wp_error( $image_id ) ) {
4494 - error_log( 'Image sideload failed: ' . esc_html( $image_id->get_error_message() ) );
4495 - } else {
4496 - set_post_thumbnail( $inserted_id, $image_id );
4497 - }
4498 -
4499 - @unlink( $tmp );
4500 - }
4501 - }
4502 -
4503 - if ( ! empty( $category_list ) && is_array( $category_list ) ) {
4504 - $category_ids = array_map( 'intval', $category_list );
4505 - wp_set_post_terms( $inserted_id, $category_ids, 'category' );
4506 - }
4507 -
4508 - if ( ! empty( $tag_list ) && is_array( $tag_list ) ) {
4509 - $tag_ids = array_map( 'intval', $tag_list );
4510 - wp_set_post_terms( $inserted_id, $tag_ids, 'post_tag' );
4511 - }
4512 -
4513 1807 $settings = ( isset( $post_content->settings ) && ! empty( $post_content->settings ) ) ? json_decode( wp_json_encode( $post_content->settings ), true ) : array();
4514 1808
4515 1809 $content = wp_json_encode( $content );
4516 1810 $content = $this->wdkit_media_import( $content, $file_type );
@@ -4523,18 +1817,14 @@
4523 1817 );
4524 1818
4525 1819 $inserted_id = $new_document->get_main_id();
4526 1820
4527 - if( $temp_type == 'navigation' ){
4528 - $temp_con = $content;
4529 - }
4530 -
4531 1821 if ( ! empty( $args['custom_meta'] ) && 'true' == $args['custom_meta'] ) {
4532 1822 $custom_meta = isset( $post_content->custom_meta ) ? json_decode( wp_json_encode( $post_content->custom_meta ), true ) : '';
4533 1823 if ( ! empty( $custom_meta ) ) {
4534 1824 foreach ( $custom_meta as $meta_key => $meta_val ) {
4535 1825 if ( ! empty( $meta_val[0] ) && is_serialized( $meta_val[0] ) ) {
4536 - $meta_val[0] = unserialize( $meta_val[0], array( 'allowed_classes' => false ) );
1826 + $meta_val[0] = maybe_unserialize( $meta_val[0] );
4537 1827 }
4538 1828 if ( '' === get_post_meta( $inserted_id, $meta_key, true ) ) {
4539 1829 add_post_meta( $inserted_id, $meta_key, $meta_val[0] );
4540 1830 }
@@ -4541,40 +1831,13 @@
4541 1831 }
4542 1832 }
4543 1833 }
4544 1834
4545 - $temp_detail = array(
1835 + return array(
4546 1836 'title' => get_the_title( $inserted_id ),
4547 1837 'edit_link' => get_edit_post_link( $inserted_id, 'internal' ),
4548 1838 'view' => get_permalink( $inserted_id ),
4549 - 'id' => $inserted_id,
4550 1839 );
4551 -
4552 - if ( ! empty( $template_id->id ) ) {
4553 - $temp_id = $template_id->id;
4554 - } elseif ( ! empty( $template_id ) ) {
4555 - $temp_id = $template_id;
4556 - } else {
4557 - $temp_id = '';
4558 - }
4559 -
4560 - \Elementor\Plugin::$instance->files_manager->clear_cache();
4561 -
4562 - // See the matching note in the Gutenberg branch above — this method never
4563 - // fired the tracking hook for either editor.
4564 - do_action( 'wdkit_template_imported', 'single', 'elementor', 1 );
4565 -
4566 - wp_send_json(
4567 - array(
4568 - $temp_id => $temp_detail,
4569 - 'content' => $temp_con,
4570 - 'description' => 'Yay! Your Section has been Successfully Imported.',
4571 - 'message' => __( 'Successfully Imported.', 'wdesignkit' ),
4572 - 'inserted_id' => $inserted_id,
4573 - 'success' => true,
4574 - )
4575 - );
4576 - wp_die();
4577 1840 }
4578 1841 } else {
4579 1842 wp_send_json(
4580 1843 array(
@@ -4585,610 +1848,11 @@
4585 1848 wp_die();
4586 1849 }
4587 1850 }
4588 1851 }
4589 -
4590 - wp_send_json(
4591 - array(
4592 - 'success' => false,
4593 - 'message' => esc_html__( 'Something went wrong', 'wdesignkit' ),
4594 - )
4595 - );
4596 - wp_die();
4597 1852 }
4598 1853
4599 1854 /**
4600 - * Replace unicode glitch
4601 - *
4602 - * @since 2.0.0
4603 - */
4604 - private function replace_unicode_glitch( $content ) {
4605 -
4606 - // Fix escaped unicode like \u003c → <
4607 - $content = preg_replace_callback(
4608 - '/\\\\u([0-9a-fA-F]{4})/',
4609 - function ( $match ) {
4610 - return html_entity_decode(
4611 - mb_convert_encoding(
4612 - pack('H*', $match[1]),
4613 - 'UTF-8',
4614 - 'UCS-2BE'
4615 - ),
4616 - ENT_QUOTES,
4617 - 'UTF-8'
4618 - );
4619 - },
4620 - $content
4621 - );
4622 -
4623 - return $content;
4624 - }
4625 -
4626 -
4627 - /**
4628 - * change plugins setting for import kit
4629 - *
4630 - * @since 2.0.0
4631 - */
4632 - protected function update_plugin_setting() {
4633 - $temp_id = isset( $_POST['plugin_type'] ) ? sanitize_text_field( $_POST['plugin_type'] ) : '';
4634 -
4635 - if ( $temp_id == 'elementor' ) {
4636 - $unfiltered_files = get_option( 'elementor_unfiltered_files_upload', false );
4637 - $load_fa4 = get_option( 'elementor_load_fa4_shim', false );
4638 - $Inline_font_icons = get_option( 'elementor_experiment-e_font_icon_svg', false );
4639 - $container = get_option( 'elementor_experiment-container', false );
4640 -
4641 - if ( isset( $unfiltered_files ) ) {
4642 - update_option( 'elementor_unfiltered_files_upload', 1 );
4643 - } else {
4644 - add_option( 'elementor_unfiltered_files_upload', 1 );
4645 - }
4646 -
4647 - if ( isset( $load_fa4 ) ) {
4648 - update_option( 'elementor_load_fa4_shim', 'yes' );
4649 - } else {
4650 - add_option( 'elementor_load_fa4_shim', 'yes' );
4651 - }
4652 -
4653 - if ( isset( $container ) ) {
4654 - update_option( 'elementor_experiment-container', 'active' );
4655 - } else {
4656 - add_option( 'elementor_experiment-container', 'active' );
4657 - }
4658 -
4659 - if ( isset( $Inline_font_icons ) ) {
4660 - update_option( 'elementor_experiment-e_font_icon_svg', 'inactive' );
4661 - } else {
4662 - add_option( 'elementor_experiment-e_font_icon_svg', 'inactive' );
4663 - }
4664 -
4665 - $response = array(
4666 - 'message' => esc_html__( 'Plugin Setting updated', 'wdesignkit' ),
4667 - 'description' => esc_html__( 'Plugin Setting updated', 'wdesignkit' ),
4668 - 'success' => true,
4669 - );
4670 - } else {
4671 - $response = array(
4672 - 'message' => esc_html__( 'Plugin not found', 'wdesignkit' ),
4673 - 'description' => esc_html__( 'Plugin not found', 'wdesignkit' ),
4674 - 'success' => false,
4675 - );
4676 - }
4677 -
4678 - wp_send_json( $response );
4679 - wp_die();
4680 - }
4681 -
4682 - /**
4683 - * generate different color logo
4684 - *
4685 - * @since 2.0.0
4686 - */
4687 - protected function wkit_generate_site_logo() {
4688 -
4689 - if ( empty( $_POST['image_url'] ) ) {
4690 - wp_send_json_error( 'Image URL not provided.' );
4691 - }
4692 -
4693 - if ( isset( $_POST['colors'] ) ) {
4694 - $img_colors = ! empty( $_POST['colors'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['colors'] ) ), true ) : array();
4695 - }
4696 -
4697 - if ( empty( $img_colors ) ) {
4698 - wp_send_json_error( 'Image color not provided.' );
4699 - }
4700 -
4701 - $image_url = esc_url_raw( $_POST['image_url'] );
4702 -
4703 - if ( ! wdesignkit_validate_external_url( $image_url ) ) {
4704 - wp_send_json_error( 'Image could not be downloaded.' );
4705 - }
4706 -
4707 - $tmp_file = download_url( $image_url );
4708 - if ( is_wp_error( $tmp_file ) ) {
4709 - wp_send_json_error( 'Image could not be downloaded.' );
4710 - }
4711 -
4712 - if ( mime_content_type( $tmp_file ) !== 'image/png' ) {
4713 - unlink( $tmp_file );
4714 - wp_send_json_error( 'Not a PNG file.' );
4715 - }
4716 -
4717 - $src = imagecreatefrompng( $tmp_file );
4718 - imagesavealpha( $src, true );
4719 -
4720 - $width = imagesx( $src );
4721 - $height = imagesy( $src );
4722 -
4723 - $hasTransparency = false;
4724 - for ( $x = 0; $x < $width; $x++ ) {
4725 - for ( $y = 0; $y < $height; $y++ ) {
4726 - $rgba = imagecolorat( $src, $x, $y );
4727 - $alpha = ( $rgba & 0x7F000000 ) >> 24;
4728 -
4729 - if ( $alpha > 0 ) {
4730 - $hasTransparency = true;
4731 - break 2;
4732 - }
4733 - }
4734 - }
4735 -
4736 - if ( ! $hasTransparency ) {
4737 - unlink( $tmp_file );
4738 - wp_send_json_error( 'PNG has no transparent pixels.' );
4739 - }
4740 -
4741 - $upload_dir = wp_upload_dir();
4742 - $result_urls = array();
4743 -
4744 - $colour_index = 0;
4745 - foreach ( $img_colors as $name => $rgb ) {
4746 - // $name is a key from the posted colours payload and went straight into the output
4747 - // filename, so traversal sequences in it steered imagepng() outside the upload
4748 - // directory (CWE-22, ClickUp 86d41ced6). sanitize_file_name() flattens it to one
4749 - // path segment; a key made only of dots/separators sanitizes to empty, so fall back
4750 - // to a positional index rather than writing to a bare "colored--<time>.png".
4751 - ++$colour_index;
4752 - $safe_name = sanitize_file_name( (string) $name );
4753 - if ( '' === $safe_name ) {
4754 - $safe_name = 'colour-' . $colour_index;
4755 - }
4756 -
4757 - $new = imagecreatetruecolor( $width, $height );
4758 - imagesavealpha( $new, true );
4759 - imagealphablending( $new, false );
4760 -
4761 - $transparent = imagecolorallocatealpha( $new, 0, 0, 0, 127 );
4762 - imagefill( $new, 0, 0, $transparent );
4763 -
4764 - for ( $x = 0; $x < $width; $x++ ) {
4765 - for ( $y = 0; $y < $height; $y++ ) {
4766 - $rgba = imagecolorat( $src, $x, $y );
4767 - $alpha = ( $rgba & 0x7F000000 ) >> 24;
4768 -
4769 - // Skip fully transparent pixels
4770 - if ( $alpha === 127 ) {
4771 - continue;
4772 - }
4773 -
4774 - // Replace pixel color directly
4775 - $new_r = $rgb[0];
4776 - $new_g = $rgb[1];
4777 - $new_b = $rgb[2];
4778 -
4779 - $color = imagecolorallocatealpha( $new, $new_r, $new_g, $new_b, $alpha );
4780 - imagesetpixel( $new, $x, $y, $color );
4781 - }
4782 - }
4783 -
4784 - $filename = 'colored-' . $safe_name . '-' . time() . '.png';
4785 - $filepath = $upload_dir['path'] . '/' . $filename;
4786 -
4787 - imagepng( $new, $filepath );
4788 - imagedestroy( $new );
4789 -
4790 - $attachment = array(
4791 - 'post_mime_type' => 'image/png',
4792 - 'post_title' => sanitize_file_name( $filename ),
4793 - 'post_content' => '',
4794 - 'post_status' => 'inherit',
4795 - );
4796 -
4797 - $attach_id = wp_insert_attachment( $attachment, $filepath );
4798 - require_once ABSPATH . 'wp-admin/includes/image.php';
4799 - $attach_data = wp_generate_attachment_metadata( $attach_id, $filepath );
4800 - wp_update_attachment_metadata( $attach_id, $attach_data );
4801 -
4802 - $result_urls[ $name ] = wp_get_attachment_url( $attach_id );
4803 - }
4804 -
4805 - imagedestroy( $src );
4806 - unlink( $tmp_file );
4807 -
4808 - wp_send_json_success( $result_urls );
4809 - }
4810 -
4811 - /**
4812 - * change theme setting for import kit
4813 - *
4814 - * @since 2.0.0
4815 - */
4816 - protected function update_theme_setting() {
4817 - $theme_db = get_option( 'nxt-theme-options', false );
4818 -
4819 - $container_type = 'container-fluid';
4820 - $fluid_spacing = array(
4821 - 'md' => array(
4822 - 'left' => '0',
4823 - 'right' => '0',
4824 - ),
4825 - 'sm' => array(
4826 - 'left' => '',
4827 - 'right' => '',
4828 - ),
4829 - 'xs' => array(
4830 - 'left' => '',
4831 - 'right' => '',
4832 - ),
4833 - 'md-unit' => 'px',
4834 - 'sm-unit' => 'px',
4835 - 'xs-unit' => 'px',
4836 - );
4837 -
4838 - if ( isset( $theme_db ) ) {
4839 - $nexter_setting = $theme_db;
4840 - $nexter_setting['site-header-container'] = $container_type;
4841 - $nexter_setting['site-footer-container'] = $container_type;
4842 - $nexter_setting['site-layout-container'] = $container_type;
4843 - $nexter_setting['site-page-container'] = $container_type;
4844 -
4845 - $nexter_setting['header-fluid-spacing'] = $fluid_spacing;
4846 - $nexter_setting['footer-fluid-spacing'] = $fluid_spacing;
4847 - $nexter_setting['site-fluid-spacing'] = $fluid_spacing;
4848 - $nexter_setting['page-fluid-spacing'] = $fluid_spacing;
4849 -
4850 - update_option( 'nxt-theme-options', $nexter_setting );
4851 - } else {
4852 - $nexter_setting = array(
4853 - 'site-header-container' => 'container-fluid',
4854 - 'header-fluid-spacing' => array(
4855 - 'md' => array(
4856 - 'left' => '0',
4857 - 'right' => '0',
4858 - ),
4859 - 'sm' => array(
4860 - 'left' => '',
4861 - 'right' => '',
4862 - ),
4863 - 'xs' => array(
4864 - 'left' => '',
4865 - 'right' => '',
4866 - ),
4867 - 'md-unit' => 'px',
4868 - 'sm-unit' => 'px',
4869 - 'xs-unit' => 'px',
4870 - ),
4871 - 'site-footer-container' => 'container-fluid',
4872 - 'footer-fluid-spacing' => array(
4873 - 'md' => array(
4874 - 'left' => '0',
4875 - 'right' => '0',
4876 - ),
4877 - 'sm' => array(
4878 - 'left' => '',
4879 - 'right' => '',
4880 - ),
4881 - 'xs' => array(
4882 - 'left' => '',
4883 - 'right' => '',
4884 - ),
4885 - 'md-unit' => 'px',
4886 - 'sm-unit' => 'px',
4887 - 'xs-unit' => 'px',
4888 - ),
4889 - 'site-layout-container' => 'container-fluid',
4890 - 'site-fluid-spacing' => array(
4891 - 'md' => array(
4892 - 'left' => '0',
4893 - 'right' => '0',
4894 - ),
4895 - 'sm' => array(
4896 - 'left' => '',
4897 - 'right' => '',
4898 - ),
4899 - 'xs' => array(
4900 - 'left' => '',
4901 - 'right' => '',
4902 - ),
4903 - 'md-unit' => 'px',
4904 - 'sm-unit' => 'px',
4905 - 'xs-unit' => 'px',
4906 - ),
4907 - 'site-page-container' => 'container-fluid',
4908 - 'page-fluid-spacing' => array(
4909 - 'md' => array(
4910 - 'left' => '0',
4911 - 'right' => '0',
4912 - ),
4913 - 'sm' => array(
4914 - 'left' => '',
4915 - 'right' => '',
4916 - ),
4917 - 'xs' => array(
4918 - 'left' => '',
4919 - 'right' => '',
4920 - ),
4921 - 'md-unit' => 'px',
4922 - 'sm-unit' => 'px',
4923 - 'xs-unit' => 'px',
4924 - ),
4925 - 'site-page-container' => '',
4926 - 'site-posts-container' => '',
4927 - 'site-archive-container' => '',
4928 - );
4929 -
4930 - add_option( 'nxt-theme-options', $nexter_setting );
4931 - }
4932 -
4933 - $response = array(
4934 - 'message' => esc_html__( 'Theme Setting updated', 'wdesignkit' ),
4935 - 'description' => esc_html__( 'Theme Setting updated', 'wdesignkit' ),
4936 - 'success' => true,
4937 - );
4938 -
4939 - wp_send_json( $response );
4940 - wp_die();
4941 - }
4942 -
4943 - /**
4944 - * change site setting for import kit
4945 - *
4946 - * @since 2.0.0
4947 - */
4948 - protected function update_site_setting() {
4949 - $temp_id = isset( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '';
4950 - $shop_id = isset( $_POST['shop_id'] ) ? sanitize_text_field( wp_unslash( $_POST['shop_id'] ) ) : '';
4951 - $temp_type = isset( $_POST['temp_type'] ) ? sanitize_text_field( wp_unslash( $_POST['temp_type'] ) ) : 'page';
4952 - $site_name = isset( $_POST['site_name'] ) ? sanitize_text_field( wp_unslash( $_POST['site_name'] ) ) : '';
4953 - $site_tagline = isset( $_POST['site_tagline'] ) ? sanitize_text_field( wp_unslash( $_POST['site_tagline'] ) ) : '';
4954 -
4955 - $this->wdkit_nxt_thembuilder_update();
4956 -
4957 - if ( ! empty( $shop_id ) ) {
4958 - update_option( 'woocommerce_shop_page_id', $shop_id );
4959 - }
4960 -
4961 - if ( $temp_id ) {
4962 - update_option( 'show_on_front', $temp_type );
4963 - update_option( 'page_on_front', $temp_id );
4964 -
4965 - if ( ! empty( $site_name ) ) {
4966 - update_option( 'blogname', $site_name );
4967 - }
4968 -
4969 - if ( ! empty( $site_tagline ) ) {
4970 - update_option( 'blogdescription', $site_tagline );
4971 - }
4972 -
4973 - $response = array(
4974 - 'message' => esc_html__( 'Site link updated', 'wdesignkit' ),
4975 - 'description' => esc_html__( 'Site link updated', 'wdesignkit' ),
4976 - 'site_link' => get_site_url(),
4977 - 'success' => true,
4978 - );
4979 - } else {
4980 - $response = array(
4981 - 'message' => esc_html__( 'Site not found', 'wdesignkit' ),
4982 - 'description' => esc_html__( 'Site not found', 'wdesignkit' ),
4983 - 'success' => false,
4984 - );
4985 - }
4986 -
4987 - wp_send_json( $response );
4988 - wp_die();
4989 - }
4990 -
4991 - /**
4992 - * update theme builder
4993 - *
4994 - * @since 2.0.4
4995 - */
4996 - public function wdkit_nxt_thembuilder_update() {
4997 -
4998 - $page_information = isset( $_POST['page_information'] ) ? sanitize_text_field( wp_unslash( $_POST['page_information'] ) ) : '';
4999 - $page_information = json_decode( $page_information, true );
5000 -
5001 - if ( ! empty( $page_information ) && is_array( $page_information ) ) {
5002 -
5003 - // Every page and attachment now exists, so resolve any image ID the per-page
5004 - // pass could not (siblings import concurrently and share icons).
5005 - $this->wdkit_sweep_attachment_ids( wp_list_pluck( $page_information, 'inserted_id' ) );
5006 -
5007 - // Step 1: banavo mapping [ old_id => new_id ]
5008 - $id_mapping = array();
5009 - foreach ( $page_information as $page_info ) {
5010 - if ( ! empty( $page_info['old_page_id'] ) ) {
5011 - $id_mapping[ $page_info['old_page_id'] ] = $page_info['inserted_id'];
5012 - }
5013 - }
5014 -
5015 - // Step 2: loop karo and update exclude
5016 - foreach ( $page_information as $page_info ) {
5017 -
5018 - $post_id = $page_info['inserted_id'] ?? '';
5019 - $old_post_id = $page_info['old_page_id'] ?? '';
5020 - $post_type = $page_info['post_type'] ?? '';
5021 -
5022 - if ( empty( $old_post_id ) ) {
5023 - continue; // only update where old id exists
5024 - }
5025 -
5026 - if ( $post_type != 'nxt_builder' ) {
5027 - continue;
5028 - }
5029 -
5030 - $include_specific = get_post_meta( $post_id, 'nxt-hooks-layout-specific', true );
5031 - if ( ! empty( $include_specific ) && is_array( $include_specific ) ) {
5032 -
5033 - foreach ( $include_specific as $key => $val ) {
5034 -
5035 - // check karo ke koi old_id ka post match kare che ke nahi
5036 - foreach ( $id_mapping as $old_id => $new_id ) {
5037 - $search = 'post-' . $old_id;
5038 - $replace = 'post-' . $new_id;
5039 -
5040 - if ( $val === $search ) {
5041 - $include_specific[ $key ] = $replace;
5042 - }
5043 - }
5044 - }
5045 -
5046 - // save back updated array
5047 - update_post_meta( $post_id, 'nxt-hooks-layout-specific', $include_specific );
5048 - }
5049 -
5050 - // Get exclude meta
5051 - $exclude_specific = get_post_meta( $post_id, 'nxt-hooks-layout-exclude-specific', true );
5052 - if ( ! empty( $exclude_specific ) && is_array( $exclude_specific ) ) {
5053 -
5054 - foreach ( $exclude_specific as $key => $val ) {
5055 -
5056 - // check karo ke koi old_id ka post match kare che ke nahi
5057 - foreach ( $id_mapping as $old_id => $new_id ) {
5058 - $search = 'post-' . $old_id;
5059 - $replace = 'post-' . $new_id;
5060 -
5061 - if ( $val === $search ) {
5062 - $exclude_specific[ $key ] = $replace;
5063 - }
5064 - }
5065 - }
5066 -
5067 - // save back updated array
5068 - update_post_meta( $post_id, 'nxt-hooks-layout-exclude-specific', $exclude_specific );
5069 - }
5070 - }
5071 - }
5072 - }
5073 -
5074 - /**
5075 - *
5076 - * select team image for import kit
5077 - *
5078 - * @since 2.2.2
5079 - */
5080 - public function wdkit_check_user_credit() {
5081 - $array_data = array(
5082 - 'token' => isset( $_POST['token'] ) ? sanitize_text_field( $_POST['token'] ) : '',
5083 - );
5084 -
5085 - $response = $this->wkit_api_call( $array_data, 'ai/credits/get' );
5086 - $success = ! empty( $response['success'] ) ? $response['success'] : false;
5087 -
5088 - if ( empty( $success ) ) {
5089 - $response = array(
5090 - 'success' => false,
5091 - 'message' => esc_html__( 'Data Not Found', 'wdesignkit' ),
5092 - 'description' => esc_html__( 'Data not found', 'wdesignkit' ),
5093 - );
5094 -
5095 - wp_send_json( $response );
5096 - wp_die();
5097 - }
5098 -
5099 - $response = json_decode( wp_json_encode( $response['data'] ), true );
5100 -
5101 - $this->wdkit_cache_cloud_usage( $response );
5102 -
5103 - wp_send_json( $response );
5104 - wp_die();
5105 - }
5106 -
5107 - /**
5108 - * Caches the storage / credit figures this response carried.
5109 - *
5110 - * This handler is the ONLY place those numbers ever exist on the site: the cloud endpoint
5111 - * authenticates with a user token that only a logged-in dashboard request carries, so the
5112 - * analytics heartbeat — which runs on cron with no user at all — can never fetch them itself.
5113 - * Caching them here is what lets Posimyth_Tracker_WDK report them, and it reports the cache's
5114 - * age alongside so a stale reading is recognisable as one.
5115 - *
5116 - * Field names are probed rather than assumed: the cloud has renamed these before, and the
5117 - * licence ability already carries six spellings of its own key field for the same reason. An
5118 - * unrecognised shape simply caches nothing rather than storing a wrong number.
5119 - *
5120 - * Only the figures are kept. No token, no account id, no email — the analytics consent copy
5121 - * promises non-sensitive data only, and this is read by the payload builder.
5122 - *
5123 - * @since 2.6.4
5124 - *
5125 - * @param mixed $data Decoded `data` object from the credits endpoint.
5126 - * @return void
5127 - */
5128 - private function wdkit_cache_cloud_usage( $data ) {
5129 - if ( ! is_array( $data ) ) {
5130 - return;
5131 - }
5132 -
5133 - $pick = static function ( $source, array $fields ) {
5134 - foreach ( $fields as $field ) {
5135 - if ( isset( $source[ $field ] ) && is_numeric( $source[ $field ] ) ) {
5136 - return (float) $source[ $field ];
5137 - }
5138 - }
5139 - return null;
5140 - };
5141 -
5142 - $usage = array(
5143 - 'storage_used' => $pick( $data, array( 'used_storage', 'storage_used', 'used_space' ) ),
5144 - 'storage_total' => $pick( $data, array( 'total_storage', 'storage_total', 'storage', 'total_space' ) ),
5145 - 'credit_used' => $pick( $data, array( 'used_credit', 'credit_used', 'used_credits' ) ),
5146 - 'credit_total' => $pick( $data, array( 'total_credit', 'credit_total', 'credits', 'real_credit' ) ),
5147 - );
5148 -
5149 - $usage = array_filter(
5150 - $usage,
5151 - static function ( $value ) {
5152 - return null !== $value;
5153 - }
5154 - );
5155 -
5156 - if ( empty( $usage ) ) {
5157 - return;
5158 - }
5159 -
5160 - $usage['cached_at'] = gmdate( 'Y-m-d H:i:s' );
5161 -
5162 - // Not autoloaded: read once a week by the heartbeat, never on a front-end request.
5163 - update_option( 'wdkit_cloud_usage', $usage, false );
5164 - }
5165 -
5166 - public function wdkit_nxt_thembuilder_reset() {
5167 - $post_id = isset( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : '';
5168 - $sections_layout = get_post_meta( $post_id, 'nxt-hooks-layout-sections', true );
5169 -
5170 - if ( ( ! empty( $sections_layout ) && ( $sections_layout == 'header' || $sections_layout == 'footer' || $sections_layout == 'breadcrumb' || $sections_layout == 'hooks' ) ) ) {
5171 - if ( get_post_meta( $post_id, 'nxt-add-display-rule' ) ) {
5172 - delete_post_meta( $post_id, 'nxt-add-display-rule' );
5173 - }
5174 -
5175 - if ( get_post_meta( $post_id, 'nxt-hooks-layout-specific' ) ) {
5176 - update_post_meta( $post_id, 'nxt-hooks-layout-specific', '' );
5177 - }
5178 -
5179 - if ( get_post_meta( $post_id, 'nxt-exclude-display-rule' ) ) {
5180 - update_post_meta( $post_id, 'nxt-exclude-display-rule', '' );
5181 - }
5182 -
5183 - if ( get_post_meta( $post_id, 'nxt-hooks-layout-exclude-specific' ) ) {
5184 - update_post_meta( $post_id, 'nxt-hooks-layout-exclude-specific', '' );
5185 - }
5186 - }
5187 - }
5188 -
5189 -
5190 - /**
5191 1855 * Share with Me Template and widgets
5192 1856 *
5193 1857 * @since 1.0.0
5194 1858 */
@@ -5275,10 +1939,9 @@
5275 1939 protected function wdkit_activate_key() {
5276 1940 $email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
5277 1941 $response = '';
5278 1942
5279 - // Bug C fix: variable was $user_email but only $email is set above — always triggered empty() guard.
5280 - if ( empty( $email ) ) {
1943 + if ( empty( $user_email ) ) {
5281 1944 $response = array(
5282 1945 'message' => $this->e_msg_login,
5283 1946 'description' => $this->e_desc_login,
5284 1947 'success' => false,
@@ -5333,12 +1996,8 @@
5333 1996 if ( Wdkit_Wdesignkit::wdkit_is_compatible( 'gutenberg', 'widget' ) ) {
5334 1997 array_push( $builder, 'gutenberg' );
5335 1998 }
5336 1999
5337 - if ( Wdkit_Wdesignkit::wdkit_is_compatible( 'gutenberg_core', 'widget' ) ) {
5338 - array_push( $builder, 'gutenberg_core' );
5339 - }
5340 -
5341 2000 foreach ( $builder as $key => $name ) {
5342 2001 $elementor_dir = WDKIT_BUILDER_PATH . '/' . $name;
5343 2002
5344 2003 if ( ! empty( $elementor_dir ) && is_dir( $elementor_dir ) ) {
@@ -5346,10 +2005,10 @@
5346 2005 $elementor_list = array_diff( $elementor_list, array( '.', '..' ) );
5347 2006
5348 2007 if ( ! empty( $elementor_list ) ) {
5349 2008 foreach ( $elementor_list as $key => $value ) {
5350 - $a_c_s_d_s_c[ filemtime( "{$elementor_dir}/{$value}" ) . $key ]['data'] = $value;
5351 - $a_c_s_d_s_c[ filemtime( "{$elementor_dir}/{$value}" ) . $key ]['builder'] = $name;
2009 + $a_c_s_d_s_c[ filemtime( "{$elementor_dir}/{$value}" ) ]['data'] = $value;
2010 + $a_c_s_d_s_c[ filemtime( "{$elementor_dir}/{$value}" ) ]['builder'] = $name;
5352 2011 }
5353 2012 }
5354 2013 }
5355 2014 }
@@ -5416,133 +2075,521 @@
5416 2075 wp_send_json( get_option( 'wkit_builder' ) );
5417 2076 }
5418 2077
5419 2078 /**
5420 - * Get Workspace data
5421 2079 *
5422 - * @since 2.2.5
2080 + * Custom_upload_dir
2081 + *
2082 + * @since 1.0.0
2083 + *
2084 + * @param array $upload store data.
5423 2085 */
5424 - public function wdkit_get_workspace_data() {
2086 + public function custom_upload_dir( $upload ) {
2087 + // Specify the path to your custom upload directory.
2088 + if ( isset( $this->widget_folder_u_r_l ) && ! empty( $this->widget_folder_u_r_l ) ) {
5425 2089
5426 - $wid = isset( $_POST['wid'] ) ? sanitize_text_field( $_POST['wid'] ) : '';
5427 - $token = isset( $_POST['token'] ) ? sanitize_text_field( $_POST['token'] ) : '';
2090 + // Set the custom directory as the upload path.
2091 + $upload['path'] = $this->widget_folder_u_r_l;
2092 + // Set the URL for the uploaded file.
2093 + $upload['url'] = $upload['baseurl'] . $upload['subdir'];
2094 + }
5428 2095
5429 - if ( empty( $wid ) ) {
5430 - return array(
2096 + return $upload;
2097 + }
2098 +
2099 + /**
2100 + *
2101 + * It is Use for create widget for local
2102 + *
2103 + * @since 1.0.0
2104 + */
2105 + protected function wdkit_create_widget() {
2106 + $image = '';
2107 + if ( isset( $_FILES ) && ! empty( $_FILES ) && isset( $_FILES['image'] ) && ! empty( $_FILES['image'] ) ) {
2108 + $image = Wdkit_Data_Hooks::get_super_global_value( $_FILES, 'image' );
2109 + }
2110 +
2111 + $icon = '';
2112 + if ( isset( $_FILES ) && ! empty( $_FILES ) && isset( $_FILES['icon'] ) && ! empty( $_FILES['icon'] ) ) {
2113 + $icon = Wdkit_Data_Hooks::get_super_global_value( $_FILES, 'icon' );
2114 + }
2115 +
2116 + $data = ! empty( $_POST['value'] ) ? $this->wdkit_sanitizer_bypass( $_POST, 'value', 'cr_widget' ) : '';
2117 + $data = ! empty( $data ) ? stripslashes( $data ) : '';
2118 + $return = ! empty( $data ) ? json_decode( $data ) : '';
2119 +
2120 + $all_val = ! empty( $return ) ? $return : '';
2121 + if ( empty( $all_val ) ) {
2122 +
2123 + $responce = array(
2124 + 'message' => esc_html__( 'Data Not Found', 'wdesignkit' ),
2125 + 'description' => esc_html__( 'something went wrong! please try again later.', 'wdesignkit' ),
5431 2126 'success' => false,
5432 - 'message' => esc_html__( 'Workspace ID Not Found', 'wdesignkit' ),
5433 - 'description' => esc_html__( 'Workspace ID is required', 'wdesignkit' ),
5434 2127 );
2128 +
2129 + wp_send_json( $responce );
2130 + wp_die();
5435 2131 }
5436 2132
5437 - if ( empty( $token ) ) {
5438 - return array(
2133 + $file_name = ! empty( $all_val->file_name ) ? sanitize_text_field( $all_val->file_name ) : '';
2134 + $folder_name = ! empty( $all_val->folder_name ) ? sanitize_text_field( $all_val->folder_name ) : '';
2135 + $old_widget = ! empty( $all_val->old_folder ) ? sanitize_text_field( $all_val->old_folder ) : '';
2136 + $description = ! empty( $all_val->description ) ? sanitize_text_field( $all_val->description ) : '';
2137 + $json_file = ! empty( $all_val->json_file ) ? $all_val->json_file : '';
2138 + $function_call = ! empty( $all_val->call ) ? sanitize_text_field( $all_val->call ) : '';
2139 + $plugin = ! empty( $all_val->plugin ) ? $all_val->plugin : '';
2140 + $d_image = ! empty( $all_val->d_image ) ? $all_val->d_image : '';
2141 + $data = json_decode( $json_file );
2142 +
2143 + $elementor_php_file = ! empty( $all_val->elementor_php_file ) ? $all_val->elementor_php_file : '';
2144 + $elementor_js = ! empty( $all_val->elementor_js ) ? $all_val->elementor_js : '';
2145 + $elementor_css = ! empty( $all_val->elementor_css ) ? $all_val->elementor_css : '';
2146 +
2147 + $gutenberg_php_file = ! empty( $all_val->gutenberg_php_file ) ? $all_val->gutenberg_php_file : '';
2148 + $gutenberg_js = ! empty( $all_val->gutenberg_js ) ? $all_val->gutenberg_js : '';
2149 + $gutenberg_css = ! empty( $all_val->gutenberg_css ) ? $all_val->gutenberg_css : '';
2150 + $external_js_file = ! empty( $all_val->external_js_file ) ? $all_val->external_js_file : '';
2151 + $style_file = ! empty( $all_val->style_file ) ? $all_val->style_file : '';
2152 +
2153 + $bricks_php_file = ! empty( $all_val->bricks_php_file ) ? $all_val->bricks_php_file : '';
2154 + $bricks_js = ! empty( $all_val->bricks_js ) ? $all_val->bricks_js : '';
2155 + $bricks_css = ! empty( $all_val->bricks_css ) ? $all_val->bricks_css : '';
2156 +
2157 + $old_folder = ! empty( $old_widget ) ? str_replace( ' ', '-', $old_widget ) : '';
2158 + $widget_type = ! empty( $data->widget_data->widgetdata->type ) ? sanitize_text_field( $data->widget_data->widgetdata->type ) : '';
2159 +
2160 + if ( empty( $widget_type ) ) {
2161 + $responce = array(
2162 + 'message' => esc_html__( 'Builder Type not found', 'wdesignkit' ),
2163 + 'description' => esc_html__( 'something went wrong! please try again later.', 'wdesignkit' ),
5439 2164 'success' => false,
5440 - 'message' => esc_html__( 'Token Not Found', 'wdesignkit' ),
5441 - 'description' => esc_html__( 'Token is required', 'wdesignkit' ),
5442 2165 );
2166 +
2167 + wp_send_json( $responce );
2168 + wp_die();
5443 2169 }
5444 2170
5445 - $args = array(
5446 - 'token' => $token,
5447 - 'wid' => $wid,
5448 - );
2171 + $builder_type_path = trailingslashit( WDKIT_BUILDER_PATH ) . trailingslashit( $widget_type );
2172 + $widget_file_url = $builder_type_path . $folder_name;
5449 2173
5450 - $this->wdkit_api = $this->wdkit_api_v2;
2174 + if ( ! is_dir( $widget_file_url ) ) {
2175 + wp_mkdir_p( $widget_file_url );
2176 + }
5451 2177
5452 - $url = "workspace/{$wid}/get";
2178 + include_once ABSPATH . 'wp-admin/includes/file.php';
2179 + \WP_Filesystem();
2180 + global $wp_filesystem;
2181 + $widget_folder_u_r_l = trailingslashit( $widget_file_url ) . $file_name;
2182 + $this->widget_folder_u_r_l = $widget_file_url;
5453 2183
5454 - $response = $this->wkit_api_call( $args, $url );
2184 + if ( 'elementor' === $plugin ) {
2185 + $widget_file_list = scandir( $widget_file_url );
2186 + $widget_file_list = array_diff( $widget_file_list, array( '.', '..' ) );
5455 2187
5456 - wp_send_json( $response['data'] );
2188 + foreach ( $widget_file_list as $sub_dir_value ) {
2189 + $file = new SplFileInfo( $sub_dir_value );
2190 + $check_ext = $file->getExtension();
2191 + $extiona = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );
2192 +
2193 + if ( 'js' === $extiona || 'css' === $extiona || 'json' === $extiona || 'php' === $extiona ) {
2194 + $wp_filesystem->rmdir( "$widget_file_url/$sub_dir_value", true );
2195 + }
2196 + }
2197 +
2198 + if ( ! empty( $elementor_php_file ) ) {
2199 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.php", $elementor_php_file );
2200 + }
2201 + if ( ! empty( $json_file ) ) {
2202 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.json", $json_file );
2203 + }
2204 + if ( ! empty( $elementor_css ) ) {
2205 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.css", $elementor_css );
2206 + }
2207 + if ( ! empty( $elementor_js ) ) {
2208 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.js", $elementor_js );
2209 + }
2210 + } elseif ( 'bricks' === $plugin ) {
2211 +
2212 + $widget_file_list = scandir( $widget_file_url );
2213 + $widget_file_list = array_diff( $widget_file_list, array( '.', '..' ) );
2214 +
2215 + foreach ( $widget_file_list as $sub_dir_value ) {
2216 + $file = new SplFileInfo( $sub_dir_value );
2217 + $check_ext = $file->getExtension();
2218 + $extiona = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );
2219 +
2220 + if ( 'js' === $extiona || 'css' === $extiona || 'json' === $extiona || 'php' === $extiona ) {
2221 + $wp_filesystem->rmdir( "$widget_file_url/$sub_dir_value", true );
2222 + }
2223 + }
2224 +
2225 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.php", $bricks_php_file );
2226 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.json", $json_file );
2227 +
2228 + if ( ! empty( $bricks_css ) ) {
2229 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.css", $bricks_css );
2230 + }
2231 +
2232 + if ( ! empty( $bricks_js ) ) {
2233 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.js", $bricks_js );
2234 + }
2235 + } elseif ( 'gutenberg' === $plugin ) {
2236 +
2237 + $widget_file_list = scandir( $widget_file_url );
2238 + $widget_file_list = array_diff( $widget_file_list, array( '.', '..' ) );
2239 +
2240 + foreach ( $widget_file_list as $sub_dir_value ) {
2241 + $file = new SplFileInfo( $sub_dir_value );
2242 + $check_ext = $file->getExtension();
2243 + $extiona = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );
2244 +
2245 + if ( 'js' === $extiona || 'css' === $extiona || 'json' === $extiona || 'php' === $extiona ) {
2246 + $wp_filesystem->rmdir( "$widget_file_url/$sub_dir_value", true );
2247 + }
2248 + }
2249 +
2250 + if ( ! empty( $external_js_file ) ) {
2251 + $wp_filesystem->put_contents( "$widget_file_url/index.js", $external_js_file );
2252 + }
2253 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.php", $gutenberg_php_file );
2254 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.json", $json_file );
2255 + if ( ! empty( $gutenberg_css ) ) {
2256 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.css", $gutenberg_css );
2257 + }
2258 + $wp_filesystem->put_contents( "$widget_folder_u_r_l.js", $gutenberg_js );
2259 + }
2260 +
2261 + if ( ! empty( $image ) && ! empty( $image['tmp_name'] ) ) {
2262 +
2263 + $img_type = array( 'jpg', 'png' );
2264 +
2265 + foreach ( $img_type as $imgext ) {
2266 + $wp_filesystem->rmdir( "$widget_folder_u_r_l . $imgext", true );
2267 + }
2268 +
2269 + $ext = $image['type'];
2270 + $img_ext = '';
2271 + if ( strpos( $ext, 'jpeg' ) ) {
2272 + $img_ext = 'jpg';
2273 + } elseif ( strpos( $ext, 'png' ) ) {
2274 + $img_ext = 'png';
2275 + }
2276 + if ( ! empty( $img_ext ) ) {
2277 + add_filter( 'upload_dir', array( $this, 'custom_upload_dir' ) );
2278 +
2279 + $uploaded_file = wp_handle_upload( $image, array( 'test_form' => false ) );
2280 +
2281 + rename( $uploaded_file['file'], $widget_folder_u_r_l . '.' . $img_ext );
2282 +
2283 + remove_filter( 'upload_dir', array( $this, 'custom_upload_dir' ) );
2284 +
2285 + }
2286 + } elseif ( ! empty( $old_widget ) ) {
2287 + $img_url = $data->widget_data->widgetdata->w_image;
2288 + $img_ext = ! empty( pathinfo( $img_url )['extension'] ) ? pathinfo( $img_url )['extension'] : '';
2289 +
2290 + if ( ! empty( $img_ext ) ) {
2291 + $old_widget_folder = str_replace( ' ', '-', $old_widget );
2292 + $old_widget_file = str_replace( ' ', '_', $old_widget );
2293 + $img_path = "$builder_type_path$old_widget_folder/$old_widget_file.$img_ext";
2294 + $img_path = str_replace( '\\', '/', $img_path );
2295 +
2296 + if ( file_exists( $img_path ) ) {
2297 + $get_img = $img_path;
2298 + $put_img = "$widget_folder_u_r_l.$img_ext";
2299 +
2300 + if ( ! empty( $get_img ) && ! empty( $put_img ) ) {
2301 + rename( $get_img, $put_img );
2302 + }
2303 + }
2304 + }
2305 + }
2306 +
2307 + if ( ! empty( $d_image ) ) {
2308 + $d_image = str_replace( '\\', '', $d_image );
2309 + $d_img_url = $d_image;
2310 + $img_body = wp_remote_get( $d_img_url );
2311 + $img_ext = pathinfo( $d_img_url )['extension'];
2312 + $wp_filesystem->put_contents( WDKIT_BUILDER_PATH . "/$widget_type/$folder_name/$file_name.$img_ext", $img_body['body'] );
2313 + }
2314 +
2315 + if ( ! empty( $function_call ) && 'import' !== $function_call && ! empty( $old_folder ) && strtolower( $old_folder ) !== strtolower( $folder_name ) && is_dir( $builder_type_path . $old_folder ) ) {
2316 + require_once ABSPATH . 'wp-admin/includes/file.php';
2317 + global $wp_filesystem;
2318 + WP_Filesystem();
2319 + $wp_filesystem->rmdir( $builder_type_path . $old_folder, true );
2320 + } elseif ( $old_folder !== $folder_name ) {
2321 + rename( WDKIT_BUILDER_PATH . "/$widget_type/$old_folder", WDKIT_BUILDER_PATH . "/$widget_type/$folder_name" );
2322 + }
2323 +
2324 + $responce = array(
2325 + 'message' => esc_html__( 'Update Saved Successfully', 'wdesignkit' ),
2326 + 'description' => esc_html__( 'Success! Update Saved', 'wdesignkit' ),
2327 + 'success' => true,
2328 + );
2329 +
2330 + wp_send_json( $responce );
5457 2331 wp_die();
5458 2332 }
5459 2333
5460 2334 /**
5461 2335 *
5462 - * Custom_upload_dir
2336 + * It is Use for delete widget from server
5463 2337 *
5464 2338 * @since 1.0.0
5465 - *
5466 - * @param array $upload store data.
5467 2339 */
5468 - public function custom_upload_dir( $upload ) {
5469 - // Specify the path to your custom upload directory.
5470 - if ( isset( $this->widget_folder_u_r_l ) && ! empty( $this->widget_folder_u_r_l ) ) {
2340 + protected function wdkit_import_widget() {
2341 + $filename = '';
2342 + if ( isset( $_FILES ) && ! empty( $_FILES ) && isset( $_FILES['zipName'] ) && ! empty( $_FILES['zipName'] ) ) {
2343 + $filename = ! empty( $_FILES['zipName']['name'] ) ? sanitize_file_name( $_FILES['zipName']['name'] ) : '';
2344 + }
5471 2345
5472 - // Set the custom directory as the upload path.
5473 - $upload['path'] = $this->widget_folder_u_r_l;
5474 - // Set the URL for the uploaded file.
5475 - $upload['url'] = $upload['baseurl'] . $upload['subdir'];
2346 + $name = rtrim( $filename, '.zip' );
2347 + $ext = WDKIT_BUILDER_PATH . '/elementor/dump/';
2348 +
2349 + if ( ! is_dir( $ext ) ) {
2350 + wp_mkdir_p( $ext );
2351 + } else {
2352 + require_once ABSPATH . 'wp-admin/includes/file.php';
2353 + global $wp_filesystem;
2354 + WP_Filesystem();
2355 + $wp_filesystem->rmdir( $ext, true );
5476 2356 }
5477 2357
5478 - return $upload;
2358 + $dir = WDKIT_BUILDER_PATH . '/elementor/dump';
2359 + $getall_json = array();
2360 + $zip = new ZipArchive();
2361 +
2362 + $zipname = '';
2363 + if ( ! empty( $_FILES['zipName']['tmp_name'] ) ) {
2364 + $zipname = $this->wdkit_file_sanitizer_bypass( $_FILES, 'zipName', 'name' );
2365 + }
2366 +
2367 + $res = $zip->open( $zipname );
2368 + if ( true === $res ) {
2369 + $zip->extractTo( $ext );
2370 + $zip->close();
2371 + $widget_name = $image = $json_file = '';
2372 + $list = scandir( $dir );
2373 + $list = array_diff( $list, array( '.', '..' ) );
2374 + foreach ( $list as $sub_dir_value ) {
2375 + $file = new SplFileInfo( $sub_dir_value );
2376 + $check_ext = $file->getExtension();
2377 + $extiona = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );
2378 + if ( 'json' === $extiona ) {
2379 + $json_file = $sub_dir_value;
2380 + $u_r_l = wp_json_file_decode( $ext . $sub_dir_value );
2381 + if ( ! empty( $u_r_l->widget_data->widgetdata->name ) && ! empty( $u_r_l->widget_data->widgetdata->widget_id ) ) {
2382 + $widget_name = $u_r_l->widget_data->widgetdata->name;
2383 + $widget_id = $u_r_l->widget_data->widgetdata->widget_id;
2384 + $widget_type = ! empty( $u_r_l->widget_data->widgetdata->type ) ? $u_r_l->widget_data->widgetdata->type : '';
2385 + }
2386 + } elseif ( 'jpg' === $extiona || 'png' === $extiona || 'jpeg' === $extiona ) {
2387 + $img_ext = $extiona;
2388 + $image = $sub_dir_value;
2389 + }
2390 + }
2391 +
2392 + if ( ! empty( $widget_name ) && ! empty( $json_file ) ) {
2393 + $folder_name = str_replace( ' ', '-', $widget_name );
2394 + $file_name = str_replace( ' ', '_', $widget_name );
2395 + if ( ! is_dir( WDKIT_BUILDER_PATH . "/{$widget_type}" ) ) {
2396 + wp_mkdir_p( WDKIT_BUILDER_PATH . "/{$widget_type}" );
2397 + }
2398 + $file_path = WDKIT_BUILDER_PATH . "/{$widget_type}/{$folder_name}_{$widget_id}";
2399 + $dummy_path = WDKIT_BUILDER_PATH . '/elementor/dump';
2400 +
2401 + if ( is_dir( $dummy_path ) ) {
2402 + if ( ! rename( $dummy_path, $file_path ) ) {
2403 +
2404 + require_once ABSPATH . 'wp-admin/includes/file.php';
2405 + global $wp_filesystem;
2406 + WP_Filesystem();
2407 + $wp_filesystem->rmdir( $dummy_path, true );
2408 +
2409 + $responce = (object) array(
2410 + 'success' => false,
2411 + 'message' => esc_html__( 'Widget Not imported', 'wdesignkit' ),
2412 + 'description' => esc_html__( 'Widget alreday exist!', 'wdesignkit' ),
2413 + );
2414 +
2415 + wp_send_json( $responce );
2416 + wp_die();
2417 + }
2418 + }
2419 +
2420 + rename( "{$file_path}/{$json_file}", "{$file_path}/{$file_name}_{$widget_id}.json" );
2421 +
2422 + $get_img_file = "{$file_path}/{$image}";
2423 +
2424 + if ( file_exists( $get_img_file ) ) {
2425 + rename( $get_img_file, "{$file_path}/{$file_name}_{$widget_id}.{$img_ext}" );
2426 + }
2427 + }
2428 +
2429 + $responce = (object) array(
2430 + 'success' => true,
2431 + 'message' => esc_html__( 'Widget imported', 'wdesignkit' ),
2432 + 'description' => esc_html__( 'Widget imported successfully', 'wdesignkit' ),
2433 + 'json' => $u_r_l,
2434 + );
2435 +
2436 + wp_send_json( $responce );
2437 + wp_die();
2438 +
2439 + } else {
2440 + $responce = (object) array(
2441 + 'success' => false,
2442 + 'message' => esc_html__( 'Operation Fial!', 'wdesignkit' ),
2443 + 'description' => esc_html__( 'Widget can not imported', 'wdesignkit' ),
2444 + );
2445 +
2446 + wp_send_json( $responce );
2447 + wp_die();
2448 + }
5479 2449 }
5480 2450
5481 2451 /**
5482 2452 *
2453 + * Create Uniq name
2454 + *
2455 + * @since 1.0.0
2456 + */
2457 + protected function generate_unique_id() {
2458 + $now = new DateTime();
2459 + $unique_i_d = $now->format( 'YmdHis' );
2460 + $hashed_i_d = (int) $unique_i_d % 10000;
2461 + return str_pad( $hashed_i_d, 4, '0', STR_PAD_LEFT );
2462 + }
2463 +
2464 + /**
2465 + *
5483 2466 * It is Use for delete widget from server
5484 2467 *
5485 2468 * @since 1.0.0
5486 2469 */
5487 - protected function wkit_widget_json() {
5488 - $widget_type = ! empty( $_POST['widget_type'] ) ? wp_unslash( $_POST['widget_type'] ) : '';
5489 - $folder_name = ! empty( $_POST['folder_name'] ) ? wp_unslash( $_POST['folder_name'] ) : '';
5490 - $file_name = ! empty( $_POST['file_name'] ) ? ( wp_unslash( $_POST['file_name'] ) ) : '';
2470 + protected function wdkit_export_widget() {
2471 + $data = isset( $_POST['info'] ) ? sanitize_text_field( wp_unslash( $_POST['info'] ) ) : '';
2472 + $data = json_decode( stripslashes( $data ) );
5491 2473
5492 - if ( empty( $widget_type ) || empty( $folder_name ) || empty( $file_name ) ) {
5493 - return array(
2474 + $widget_name_temp = isset( $data->widget_name ) ? sanitize_text_field( $data->widget_name ) : '';
2475 + $widget_type = isset( $data->widget_type ) ? sanitize_text_field( $data->widget_type ) : '';
2476 +
2477 + $widget_name = str_replace( ' ', '_', $widget_name_temp );
2478 + $folder = str_replace( ' ', '-', $widget_name_temp );
2479 + $unique_version = $this->generate_unique_id();
2480 +
2481 + if ( empty( $widget_type ) ) {
2482 + $result = (object) array(
5494 2483 'success' => false,
5495 - 'message' => esc_html__( 'Widget JSON not found', 'wdesignkit' ),
5496 - 'description' => esc_html__( 'widget JSON file not found.', 'wdesignkit' ),
2484 + 'url' => '',
2485 + 'message' => esc_html__( 'Widget Type Fail', 'wdesignkit' ),
2486 + 'description' => esc_html__( 'Widget Type Not Exists', 'wdesignkit' ),
5497 2487 );
2488 +
2489 + wp_send_json( $result );
2490 + wp_die();
5498 2491 }
5499 2492
5500 - // Read-side twin of the write and delete traversals fixed in 86d41cckh / 86d41ccz2: all
5501 - // three segments arrive from $_POST with only wp_unslash() applied — which strips
5502 - // nothing path-relevant — so "../" in any of them walked out of the builder directory
5503 - // and this handler returned the decoded contents of any .json file the web server user
5504 - // could read (CWE-22, ClickUp 86d41zaun).
5505 - $safe_path = wdesignkit_widget_path_guard( $widget_type, $folder_name, $file_name );
2493 + $downlod_path = WDKIT_BUILDER_PATH . "/{$widget_type}/";
2494 + $new_path = "{$downlod_path}/{$folder}/{$widget_name}";
5506 2495
5507 - if ( false === $safe_path || '' === $safe_path['folder'] || '' === $safe_path['file'] ) {
5508 - return array(
2496 + $download_url = WDKIT_SERVER_PATH . "/{$widget_type}/{$widget_name}.zip";
2497 + $zip = new ZipArchive();
2498 + $tmp_file = "{$downlod_path}{$widget_name}.zip";
2499 +
2500 + $json_data = wp_json_file_decode( "$new_path.json" );
2501 + $img_ext = $json_data->widget_data->widgetdata->img_ext;
2502 +
2503 + if ( true === $zip->open( $tmp_file, ZipArchive::CREATE ) ) {
2504 + $widget_wb = str_replace( '-', '_', $folder );
2505 + $zip->addFile( "$new_path.json", "$widget_wb.json" );
2506 + if ( ! empty( $img_ext ) ) {
2507 + $zip->addFile( "$new_path.$img_ext", "$widget_wb.$img_ext" );
2508 + }
2509 + $zip->close();
2510 +
2511 + $result = (object) array(
2512 + 'success' => true,
2513 + 'url' => $download_url,
2514 + 'message' => esc_html__( 'Widget Exported', 'wdesignkit' ),
2515 + 'description' => esc_html__( 'Widget Exported successfully', 'wdesignkit' ),
2516 + );
2517 +
2518 + wp_send_json( $result );
2519 + wp_die();
2520 + } else {
2521 + $result = (object) array(
5509 2522 'success' => false,
5510 - 'message' => esc_html__( 'Widget JSON not found', 'wdesignkit' ),
5511 - 'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
2523 + 'url' => '',
2524 + 'message' => esc_html__( 'Widget Exported Fail', 'wdesignkit' ),
2525 + 'description' => esc_html__( 'something went wrong! please try again later.', 'wdesignkit' ),
5512 2526 );
2527 +
2528 + wp_send_json( $result );
2529 + wp_die();
5513 2530 }
2531 + }
5514 2532
5515 - $json_path = $safe_path['base'];
2533 + /**
2534 + *
2535 + * It is Use for delete widget from server
2536 + *
2537 + * @since 1.0.0
2538 + */
2539 + protected function wdkit_delete_widget() {
2540 + $data = isset( $_POST['info'] ) ? sanitize_text_field( wp_unslash( $_POST['info'] ) ) : '';
2541 + $data = json_decode( stripslashes( $data ) );
5516 2542
5517 - // Re-check the resolved file: the component guard above cannot see a symlink. Returns
5518 - // false for a path that does not exist, which is the same answer we want anyway.
5519 - if ( ! wdesignkit_path_inside_builder_dir( "$json_path.json" ) ) {
5520 - return array(
5521 - 'success' => false,
5522 - 'message' => esc_html__( 'Widget JSON not found', 'wdesignkit' ),
5523 - 'description' => esc_html__( 'widget JSON file not found.', 'wdesignkit' ),
2543 + $delete_type = isset( $data->delete_type ) ? sanitize_text_field( $data->delete_type ) : '';
2544 +
2545 + if ( 'plugin_server' === $delete_type ) {
2546 + $array_data = array(
2547 + 'token' => isset( $data->token ) ? sanitize_text_field( $data->token ) : '',
2548 + 'type' => isset( $data->type ) ? sanitize_text_field( $data->type ) : '',
2549 + 'w_unique' => isset( $data->w_unique ) ? sanitize_text_field( $data->w_unique ) : '',
2550 + 'id' => isset( $data->id ) ? sanitize_text_field( $data->id ) : '',
5524 2551 );
2552 +
2553 + $response = $this->wkit_api_call( $array_data, 'save_widget' );
2554 + $success = ! empty( $response['success'] ) ? $response['success'] : false;
2555 +
2556 + if ( empty( $success ) ) {
2557 + $massage = ! empty( $response['massage'] ) ? $response['massage'] : esc_html__( 'server error', 'wdesignkit' );
2558 +
2559 + $result = (object) array(
2560 + 'success' => false,
2561 + 'message' => esc_html__( 'Widget Not Deleted', 'wdesignkit' ),
2562 + 'description' => esc_html__( 'Widget Not Deleted', 'wdesignkit' ),
2563 + );
2564 +
2565 + wp_send_json( $result );
2566 + wp_die();
2567 + }
5525 2568 }
5526 2569
5527 - $json_data = wp_json_file_decode( "$json_path.json" );
5528 - if ( ! empty( $json_data ) ) {
2570 + $dir_name = isset( $data->name ) ? sanitize_text_field( $data->name ) : '';
2571 + $widget_type = isset( $data->builder ) ? sanitize_text_field( $data->builder ) : '';
2572 + $dir = WDKIT_BUILDER_PATH . "/{$widget_type}/{$dir_name}";
2573 +
2574 + require_once ABSPATH . 'wp-admin/includes/file.php';
2575 + global $wp_filesystem;
2576 + WP_Filesystem();
2577 + $wp_filesystem->rmdir( $dir, true );
2578 +
2579 + if ( 'plugin_server' === $delete_type ) {
2580 + wp_send_json( $response['data'] );
2581 + wp_die();
2582 + } else {
5529 2583 $result = (object) array(
5530 2584 'success' => true,
5531 - 'data' => $json_data,
5532 - 'message' => esc_html__( 'Widget get Successfully', 'wdesignkit' ),
5533 - 'description' => esc_html__( 'Widget JSON get Successfully', 'wdesignkit' ),
2585 + 'message' => esc_html__( 'widget deleted', 'wdesignkit' ),
2586 + 'description' => esc_html__( 'Widget deleted successfully', 'wdesignkit' ),
5534 2587 );
5535 - } else {
5536 - $result = (object) array(
5537 - 'success' => false,
5538 - 'message' => esc_html__( 'Widget not get', 'wdesignkit' ),
5539 - 'description' => esc_html__( 'Widget JSON not get', 'wdesignkit' ),
5540 - );
2588 +
2589 + wp_send_json( $result );
2590 + wp_die();
5541 2591 }
5542 -
5543 - wp_send_json( $result );
5544 - wp_die();
5545 2592 }
5546 2593
5547 2594 /**
5548 2595 *
@@ -5550,9 +2597,9 @@
5550 2597 *
5551 2598 * @since 1.0.0
5552 2599 */
5553 2600 protected function wdkit_download_widget() {
5554 - $data = ! empty( $_POST['widget_info'] ) ? $this->wdkit_extract_post_field( $_POST, 'widget_info', 'none' ) : '';
2601 + $data = ! empty( $_POST['widget_info'] ) ? $this->wdkit_sanitizer_bypass( $_POST, 'widget_info', 'none' ) : '';
5555 2602 $data = json_decode( stripslashes( $data ) );
5556 2603
5557 2604 $array_data = array(
5558 2605 'token' => isset( $data->token ) ? sanitize_text_field( $data->token ) : '',
@@ -5557,10 +2604,8 @@
5557 2604 $array_data = array(
5558 2605 'token' => isset( $data->token ) ? sanitize_text_field( $data->token ) : '',
5559 2606 'type' => isset( $data->type ) ? sanitize_text_field( $data->type ) : '',
5560 2607 'w_unique' => isset( $data->w_uniq ) ? sanitize_text_field( $data->w_uniq ) : '',
5561 - // Bug F fix: u_id (widget owner's user ID) was missing — cloud cannot locate the widget without it.
5562 - 'u_id' => isset( $data->u_id ) ? sanitize_text_field( $data->u_id ) : '',
5563 2608 );
5564 2609
5565 2610 $response = $this->wkit_api_call( $array_data, 'save_widget' );
5566 2611 $success = ! empty( $response['success'] ) ? $response['success'] : false;
@@ -5593,16 +2638,10 @@
5593 2638 wp_die();
5594 2639 }
5595 2640
5596 2641 $img_url = ! empty( $response['data']['image'] ) ? $response['data']['image'] : '';
5597 - $json_data = ! empty( $response['data']['json'] ) ? json_decode( $response['data']['json'], true ) : '';
2642 + $json_data = ! empty( $response['data']['json'] ) ? json_decode( $response['data']['json'] ) : '';
5598 2643
5599 - // Bug E fix (part 1): $responce was a typo of $response — sent undefined variable (null) to frontend.
5600 - if ( empty( $response['success'] ) ) {
5601 - wp_send_json( $response );
5602 - wp_die();
5603 - }
5604 -
5605 2644 if ( empty( $img_url ) && empty( $json_data ) ) {
5606 2645 $responce = (object) array(
5607 2646 'success' => false,
5608 2647 'message' => esc_html__( 'No Response Found', 'wdesignkit' ),
@@ -5616,38 +2655,14 @@
5616 2655 include_once ABSPATH . 'wp-admin/includes/file.php';
5617 2656 \WP_Filesystem();
5618 2657 global $wp_filesystem;
5619 2658
5620 - if ( ! is_array( $json_data ) ) {
5621 - $json_data = json_decode( $json_data, true );
5622 - }
2659 + $title = ! empty( $json_data->widget_data->widgetdata->name ) ? sanitize_text_field( $json_data->widget_data->widgetdata->name ) : '';
2660 + $builder = ! empty( $json_data->widget_data->widgetdata->type ) ? sanitize_text_field( $json_data->widget_data->widgetdata->type ) : '';
2661 + $w_uniq = ! empty( $json_data->widget_data->widgetdata->widget_id ) ? sanitize_text_field( $json_data->widget_data->widgetdata->widget_id ) : '';
5623 2662
5624 - // Sanitize as filenames before use in the widget path (CWE-22): sanitize_file_name()
5625 - // on name/id and sanitize_key() + allowlist on the builder strip path separators and
5626 - // dots so a crafted cloud response cannot escape WDKIT_BUILDER_PATH.
5627 - $title = ! empty( $json_data['widget_data']['widgetdata']['name'] ) ? sanitize_file_name( $json_data['widget_data']['widgetdata']['name'] ) : '';
5628 - $builder = ! empty( $json_data['widget_data']['widgetdata']['type'] ) ? sanitize_key( $json_data['widget_data']['widgetdata']['type'] ) : '';
5629 - $w_uniq = ! empty( $json_data['widget_data']['widgetdata']['widget_id'] ) ? sanitize_file_name( $json_data['widget_data']['widgetdata']['widget_id'] ) : '';
5630 -
5631 - $allowed_builders = array( 'elementor', 'gutenberg', 'gutenberg_core', 'bricks' );
5632 - if ( '' === $title || '' === $w_uniq || ! in_array( $builder, $allowed_builders, true ) ) {
5633 - $responce = (object) array(
5634 - 'success' => false,
5635 - 'message' => esc_html__( 'Operation Failed!', 'wdesignkit' ),
5636 - 'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
5637 - );
5638 -
5639 - wp_send_json( $responce );
5640 - wp_die();
5641 - }
5642 -
5643 - // Canonical helpers replace spaces BEFORE sanitize_file_name(). $title above is
5644 - // already sanitized, which collapsed spaces to hyphens and left the underscore pass
5645 - // with nothing to do — a multi-word title wrote "My-Widget_id.json" next to the
5646 - // "My_Widget_id.php" the builder's save path writes. The loader pairs the two by
5647 - // swapping .php for .json, so the widget was silently dropped (ClickUp 86d41cck5).
5648 - $folder_name = wdesignkit_widget_folder_name( $title, $w_uniq );
5649 - $file_name = wdesignkit_widget_file_name( $title, $w_uniq );
2663 + $folder_name = str_replace( ' ', '-', $title ) . '_' . $w_uniq;
2664 + $file_name = str_replace( ' ', '_', $title ) . '_' . $w_uniq;
5650 2665 $builder_type_path = WDKIT_BUILDER_PATH . "/{$builder}/";
5651 2666
5652 2667 if ( ! is_dir( $builder_type_path ) ) {
5653 2668 wp_mkdir_p( $builder_type_path );
@@ -5657,30 +2672,17 @@
5657 2672 wp_mkdir_p( $builder_type_path . $folder_name );
5658 2673 }
5659 2674
5660 2675 if ( ! empty( $img_url ) ) {
5661 - // SSRF guard (CWE-918): validate the resolved host before fetching.
5662 - $img_body = wdesignkit_safe_remote_get( $img_url );
5663 - if ( ! is_wp_error( $img_body ) ) {
5664 - // The remote extension was written verbatim here, so a cloud response naming a
5665 - // ".php" image put executable PHP in the builder directory (CWE-434,
5666 - // ClickUp 86d41cczd). An empty return means the bytes are not an image.
5667 - $img_ext = wdesignkit_safe_image_extension( $img_url, $img_body['body'] );
2676 + $img_body = wp_remote_get( $img_url );
2677 + $img_ext = pathinfo( $img_url )['extension'];
5668 2678
5669 - if ( '' !== $img_ext ) {
5670 - $wp_filesystem->put_contents( WDKIT_BUILDER_PATH . "/$builder/$folder_name/$file_name.$img_ext", $img_body['body'] );
5671 - $json_data['widget_data']['widgetdata']['w_image'] = WDKIT_SERVER_PATH . "/$builder/$folder_name/$file_name.$img_ext";
5672 - }
5673 - }
2679 + $wp_filesystem->put_contents( WDKIT_BUILDER_PATH . "/$builder/$folder_name/$file_name.$img_ext", $img_body['body'] );
2680 + $json_data->widget_data->widgetdata->w_image = WDKIT_SERVER_PATH . "/$builder/$folder_name/$file_name.$img_ext";
5674 2681 }
5675 2682
5676 - if ( function_exists( 'wdesignkit_invalidate_widget_registry' ) ) {
5677 - wdesignkit_invalidate_widget_registry( $builder );
5678 - }
5679 -
5680 - // Bug E fix (part 2): success was hardcoded false on the successful download path — always reported failure.
5681 2683 $result = (object) array(
5682 - 'success' => true,
2684 + 'success' => false,
5683 2685 'message' => ! empty( $response['message'] ) ? $response['message'] : esc_html__( 'no message', 'wdesignkit' ),
5684 2686 'description' => '',
5685 2687 'json' => wp_json_encode( $json_data ),
5686 2688 );
@@ -5690,16 +2692,94 @@
5690 2692 }
5691 2693
5692 2694 /**
5693 2695 *
2696 + * It is Use for download widget from browse page.
2697 + *
2698 + * @since 1.0.0
2699 + */
2700 + protected function wdkit_public_download_widget() {
2701 + $data = ! empty( $_POST['widget_info'] ) ? $this->wdkit_sanitizer_bypass( $_POST, 'widget_info', 'none' ) : '';
2702 + $data = json_decode( stripslashes( $data ) );
2703 +
2704 + $array_data = array(
2705 + 'id' => isset( $data->w_uniq ) ? sanitize_text_field( $data->w_uniq ) : '',
2706 + 'u_id' => isset( $data->u_id ) ? sanitize_text_field( $data->u_id ) : '',
2707 + 'type' => isset( $data->d_type ) ? sanitize_text_field( $data->d_type ) : '',
2708 + );
2709 +
2710 + $response = $this->wkit_api_call( $array_data, 'widget/download' );
2711 + $success = ! empty( $response['success'] ) ? $response['success'] : false;
2712 +
2713 + if ( empty( $success ) ) {
2714 + $massage = ! empty( $response['massage'] ) ? $response['massage'] : esc_html__( 'server error', 'wdesignkit' );
2715 +
2716 + $result = (object) array(
2717 + 'success' => false,
2718 + 'message' => $massage,
2719 + 'description' => esc_html__( 'Widget not Downloaded', 'wdesignkit' ),
2720 + );
2721 +
2722 + wp_send_json( $result );
2723 + wp_die();
2724 + }
2725 +
2726 + $response = json_decode( wp_json_encode( $response['data'] ), true );
2727 + if ( ! empty( $response ) && ! empty( $response['data'] ) ) {
2728 + $img_url = ! empty( $response['data']['image'] ) ? esc_url_raw( $response['data']['image'] ) : '';
2729 + $json = ! empty( $response['data']['json'] ) ? wp_json_encode( $response['data']['json'] ) : '';
2730 +
2731 + if ( ! empty( $json ) ) {
2732 + include_once ABSPATH . 'wp-admin/includes/file.php';
2733 + \WP_Filesystem();
2734 + global $wp_filesystem;
2735 +
2736 + $json_data = json_decode( $json );
2737 + $json_data = json_decode( $json_data );
2738 + $title = ! empty( $json_data->widget_data->widgetdata->name ) ? sanitize_text_field( $json_data->widget_data->widgetdata->name ) : '';
2739 + $builder = ! empty( $json_data->widget_data->widgetdata->type ) ? sanitize_text_field( $json_data->widget_data->widgetdata->type ) : '';
2740 + $widget_id = ! empty( $json_data->widget_data->widgetdata->widget_id ) ? sanitize_text_field( $json_data->widget_data->widgetdata->widget_id ) : '';
2741 +
2742 + $folder_name = str_replace( ' ', '-', $title ) . '_' . $widget_id;
2743 + $file_name = str_replace( ' ', '_', $title ) . '_' . $widget_id;
2744 +
2745 + $builder_type_path = WDKIT_BUILDER_PATH . "/{$builder}/";
2746 +
2747 + if ( ! is_dir( $builder_type_path . $folder_name ) ) {
2748 + wp_mkdir_p( $builder_type_path . $folder_name );
2749 + }
2750 +
2751 + if ( ! empty( $img_url ) ) {
2752 + $img_body = wp_remote_get( $img_url );
2753 + $img_ext = pathinfo( $img_url )['extension'];
2754 + $wp_filesystem->put_contents( WDKIT_BUILDER_PATH . "/$builder/$folder_name/$file_name.$img_ext", $img_body['body'] );
2755 +
2756 + $json_data->widget_data->widgetdata->w_image = WDKIT_SERVER_PATH . "/$builder/$folder_name/$file_name.$img_ext";
2757 + }
2758 +
2759 + $response = (object) array(
2760 + 'message' => ! empty( $response['message'] ) ? $response['message'] : '',
2761 + 'description' => ! empty( $response['description'] ) ? $response['description'] : '',
2762 + 'success' => ! empty( $response['success'] ) ? $response['success'] : false,
2763 + 'r_id' => ! empty( $response['data']['rid'] ) ? $response['data']['rid'] : 0,
2764 + 'json' => wp_json_encode( $json_data ),
2765 + );
2766 + }
2767 + }
2768 +
2769 + wp_send_json( $response );
2770 + wp_die();
2771 + }
2772 +
2773 + /**
2774 + *
5694 2775 * It is Use for sync widget to server
5695 2776 *
5696 2777 * @since 1.0.0
5697 2778 */
5698 2779 protected function wdkit_add_widget() {
5699 - $data = ! empty( $_POST['widget_info'] ) ? $this->wdkit_extract_post_field( $_POST, 'widget_info', 'none' ) : '';
5700 - $data = base64_decode( $data );
5701 - $data = json_decode( $data );
2780 + $data = ! empty( $_POST['widget_info'] ) ? $this->wdkit_sanitizer_bypass( $_POST, 'widget_info', 'none' ) : '';
2781 + $data = json_decode( stripslashes( $data ) );
5702 2782
5703 2783 $title = isset( $data->title ) ? sanitize_text_field( $data->title ) : '';
5704 2784 $builder = isset( $data->builder ) ? sanitize_text_field( $data->builder ) : '';
5705 2785 $w_uniq = isset( $data->w_uniq ) ? sanitize_text_field( $data->w_uniq ) : '';
@@ -5706,11 +2786,9 @@
5706 2786 $w_image = isset( $data->w_image ) ? esc_url_raw( $data->w_image ) : '';
5707 2787
5708 2788 if ( ! empty( $w_image ) ) {
5709 2789 $w_image = str_replace( '\\', '', $w_image );
5710 - // SSRF guard (CWE-918): validate the resolved host before fetching.
5711 - $fetched = wdesignkit_safe_remote_get( $w_image );
5712 - $w_image = is_wp_error( $fetched ) ? '' : wp_remote_retrieve_body( $fetched );
2790 + $w_image = wp_remote_get( $w_image )['body'];
5713 2791 }
5714 2792
5715 2793 $array_data = array(
5716 2794 'token' => isset( $data->token ) ? sanitize_text_field( $data->token ) : '',
@@ -5724,9 +2802,8 @@
5724 2802 'w_imgext' => isset( $data->w_imgext ) ? sanitize_text_field( $data->w_imgext ) : '',
5725 2803 'w_version' => isset( $data->w_version ) ? $data->w_version : '',
5726 2804 'w_updates' => ! empty( $data->w_updates ) ? serialize( $data->w_updates ) : serialize( array() ),
5727 2805 'r_id' => isset( $data->r_id ) ? $data->r_id : 0,
5728 - 'unique_id' => get_option( 'wdkit_unique_id' ) ?? '',
5729 2806 );
5730 2807
5731 2808 $response = $this->wkit_api_call( $array_data, 'save_widget' );
5732 2809 $success = ! empty( $response['success'] ) ? $response['success'] : false;
@@ -5749,52 +2826,22 @@
5749 2826 $response = json_decode( wp_json_encode( $res ), true );
5750 2827 $img_url = ! empty( $response['data']['imgurl'] ) ? $response['data']['imgurl'] : '';
5751 2828
5752 2829 if ( ! empty( $img_url ) && 'error' !== $res ) {
2830 + $img_body = wp_remote_get( $img_url );
2831 + $img_ext = pathinfo( $img_url )['extension'];
2832 + include_once ABSPATH . 'wp-admin/includes/file.php';
2833 + \WP_Filesystem();
2834 + global $wp_filesystem;
2835 + $folder_name = str_replace( ' ', '-', $title ) . '_' . $w_uniq;
2836 + $file_name = str_replace( ' ', '_', $title ) . '_' . $w_uniq;
2837 + $file_path = WDKIT_BUILDER_PATH . "/$builder/$folder_name/$file_name";
5753 2838
5754 - // SSRF guard (CWE-918): validate the resolved host before fetching.
5755 - $img_body = wdesignkit_safe_remote_get( $img_url );
5756 - if ( ! is_wp_error( $img_body ) ) {
5757 - // Verified against the payload rather than trusted from the URL (CWE-434,
5758 - // ClickUp 86d41cczd); '' means the bytes are not an image we accept.
5759 - $img_ext = wdesignkit_safe_image_extension( $img_url, $img_body['body'] );
5760 - include_once ABSPATH . 'wp-admin/includes/file.php';
5761 - \WP_Filesystem();
5762 - global $wp_filesystem;
5763 - // Canonical helpers, so the JSON read and the image write here address the same
5764 - // base name every other writer uses (ClickUp 86d41cck5). They also apply
5765 - // sanitize_file_name(), which $title and $w_uniq had not been through.
5766 - $folder_name = wdesignkit_widget_folder_name( $title, $w_uniq );
5767 - $file_name = wdesignkit_widget_file_name( $title, $w_uniq );
2839 + $u_r_l = wp_json_file_decode( "$file_path.json" );
2840 + $u_r_l->widget_data->widgetdata->w_image = WDKIT_SERVER_PATH . "/$builder/$folder_name/$file_name.$img_ext";
5768 2841
5769 - // $builder reaches here with only sanitize_text_field() applied and no
5770 - // allowlist, so it was a live traversal segment in this path (CWE-22,
5771 - // ClickUp 86d41cckh). Unlike the download handler earlier in this file, this
5772 - // one had neither the builder allowlist nor a containment check.
5773 - $safe_path = wdesignkit_widget_path_guard( $builder, $folder_name, $file_name );
5774 - if ( false === $safe_path || ! wdesignkit_path_inside_builder_dir( $safe_path['dir'] ) ) {
5775 - wp_send_json(
5776 - (object) array(
5777 - 'success' => false,
5778 - 'message' => esc_html__( 'Operation Failed!', 'wdesignkit' ),
5779 - 'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
5780 - )
5781 - );
5782 - wp_die();
5783 - }
5784 -
5785 - $builder = $safe_path['builder'];
5786 - $file_path = $safe_path['base'];
5787 -
5788 - $u_r_l = wp_json_file_decode( "$file_path.json" );
5789 -
5790 - if ( '' !== $img_ext ) {
5791 - $u_r_l->widget_data->widgetdata->w_image = WDKIT_SERVER_PATH . "/$builder/$folder_name/$file_name.$img_ext";
5792 - $wp_filesystem->put_contents( "$file_path.$img_ext", $img_body['body'] );
5793 - }
5794 -
5795 - $wp_filesystem->put_contents( "$file_path.json", wp_json_encode( $u_r_l ) );
5796 - }
2842 + $wp_filesystem->put_contents( "$file_path.json", wp_json_encode( $u_r_l ) );
2843 + $wp_filesystem->put_contents( "$file_path.$img_ext", $img_body['body'] );
5797 2844 }
5798 2845
5799 2846 wp_send_json( $response );
5800 2847 wp_die();
@@ -5861,9 +2908,9 @@
5861 2908 *
5862 2909 * @since 1.0.0
5863 2910 */
5864 2911 protected static function wkit_get_settings_panel() {
5865 - $new_version = '';
2912 +
5866 2913 $current_version = WDKIT_VERSION;
5867 2914 $response = wp_remote_get( 'https://api.wordpress.org/plugins/info/1.0/wdesignkit.json' );
5868 2915
5869 2916 if ( is_wp_error( $response ) ) {
@@ -5888,108 +2935,23 @@
5888 2935 }
5889 2936
5890 2937 $get_setting = get_option( 'wkit_settings_panel', false );
5891 2938
5892 - $setting_data = array(
5893 - 'builder' => isset( $get_setting['builder'] ) ? $get_setting['builder'] : true,
5894 - 'template' => isset( $get_setting['template'] ) ? $get_setting['template'] : true,
5895 - 'gutenberg_builder' => isset( $get_setting['gutenberg_builder'] ) ? $get_setting['gutenberg_builder'] : true,
5896 - 'gutenberg_core_builder' => isset( $get_setting['gutenberg_core_builder'] ) ? $get_setting['gutenberg_core_builder'] : false,
5897 - 'elementor_builder' => isset( $get_setting['elementor_builder'] ) ? $get_setting['elementor_builder'] : true,
5898 - 'bricks_builder' => isset( $get_setting['bricks_builder'] ) ? $get_setting['bricks_builder'] : true,
5899 - 'gutenberg_template' => isset( $get_setting['gutenberg_template'] ) ? $get_setting['gutenberg_template'] : true,
5900 - 'elementor_template' => isset( $get_setting['elementor_template'] ) ? $get_setting['elementor_template'] : true,
5901 - 'code_snippet' => isset( $get_setting['code_snippet'] ) ? $get_setting['code_snippet'] : true,
5902 - 'cross_copy_paste' => isset( $get_setting['cross_copy_paste'] ) ? $get_setting['cross_copy_paste'] : false,
5903 - 'cross_copy_paste_elementor' => isset( $get_setting['cross_copy_paste_elementor'] ) ? $get_setting['cross_copy_paste_elementor'] : false,
5904 - 'cross_copy_paste_gutenberg' => isset( $get_setting['cross_copy_paste_gutenberg'] ) ? $get_setting['cross_copy_paste_gutenberg'] : false,
5905 - 'cross_copy_paste_bricks' => isset( $get_setting['cross_copy_paste_bricks'] ) ? $get_setting['cross_copy_paste_bricks'] : false,
5906 - 'plugin_version' => $version_check,
2939 + return array(
2940 + 'builder' => isset( $get_setting['builder'] ) ? $get_setting['builder'] : true,
2941 + 'template' => isset( $get_setting['template'] ) ? $get_setting['template'] : true,
2942 + 'gutenberg_builder' => isset( $get_setting['gutenberg_builder'] ) ? $get_setting['gutenberg_builder'] : true,
2943 + 'elementor_builder' => isset( $get_setting['elementor_builder'] ) ? $get_setting['elementor_builder'] : true,
2944 + 'bricks_builder' => isset( $get_setting['bricks_builder'] ) ? $get_setting['bricks_builder'] : false,
2945 + 'debugger_mode' => isset( $get_setting['debugger_mode'] ) ? $get_setting['debugger_mode'] : false,
2946 + 'gutenberg_template' => isset( $get_setting['gutenberg_template'] ) ? $get_setting['gutenberg_template'] : true,
2947 + 'elementor_template' => isset( $get_setting['elementor_template'] ) ? $get_setting['elementor_template'] : true,
2948 + 'plugin_version' => $version_check,
5907 2949 );
5908 -
5909 - if ( isset( $get_setting['remove_db'] ) ) {
5910 - $setting_data['remove_db'] = $get_setting['remove_db'];
5911 - }
5912 -
5913 - if ( isset( $get_setting['debugger_mode'] ) ) {
5914 - $setting_data['debugger_mode'] = $get_setting['debugger_mode'];
5915 - }
5916 -
5917 - return $setting_data;
5918 2950 }
5919 2951
5920 2952 /**
5921 - * Updated White Label Data.
5922 2953 *
5923 - * @since 1.1.8
5924 - */
5925 - protected function wkit_white_label() {
5926 -
5927 - $get_wl_data = ! empty( $_POST['WhiteLabelData'] ) ? wp_unslash( $_POST['WhiteLabelData'] ) : array();
5928 -
5929 - if ( ! empty( $get_wl_data ) ) {
5930 - $white_label_data = json_decode( $get_wl_data, true );
5931 - $plugin_name = $white_label_data['plugin_name'];
5932 - } else {
5933 - $result = array(
5934 - 'success' => false,
5935 - 'message' => esc_html__( 'Data Not Found', 'wdesignkit' ),
5936 - );
5937 -
5938 - wp_send_json( $result );
5939 - wp_die();
5940 - }
5941 -
5942 - if ( ! empty( $plugin_name ) ) {
5943 - $get_white_label = get_option( 'wkit_white_label', false );
5944 - if ( ! empty( $get_white_label ) ) {
5945 - update_option( 'wkit_white_label', $white_label_data );
5946 - } else {
5947 - add_option( 'wkit_white_label', $white_label_data );
5948 - }
5949 - } else {
5950 - $result = array(
5951 - 'success' => false,
5952 - 'message' => esc_html__( 'Plugin Name Not Found', 'wdesignkit' ),
5953 - );
5954 -
5955 - wp_send_json( $result );
5956 - wp_die();
5957 - }
5958 -
5959 - $get_updated_data = get_option( 'wkit_white_label', false );
5960 - $response = array(
5961 - 'message' => __( 'Data Added successfully', 'wdesignkit' ),
5962 - 'success' => true,
5963 - 'data' => $get_updated_data,
5964 - );
5965 -
5966 - wp_send_json( $response );
5967 - }
5968 -
5969 - /**
5970 - * Reset White Label Data.
5971 - *
5972 - * @since 1.1.8
5973 - */
5974 - public function wkit_reset_wl() {
5975 - $wl_data = get_option( 'wkit_white_label' );
5976 -
5977 - if ( ! empty( $wl_data ) ) {
5978 - delete_option( 'wkit_white_label' );
5979 -
5980 - $result = array(
5981 - 'success' => true,
5982 - 'message' => esc_html__( 'Reset White Label Successfully', 'wdesignkit' ),
5983 - );
5984 -
5985 - wp_send_json( $result );
5986 - wp_die();
5987 - }
5988 - }
5989 -
5990 - /**
5991 - *
5992 2954 * Use for Add new licence key.
5993 2955 *
5994 2956 * @since 1.0.0
5995 2957 */
@@ -6002,38 +2964,9 @@
6002 2964 );
6003 2965
6004 2966 $response = $this->wkit_api_call( $args, 'wkit_activate_key' );
6005 2967
6006 - if ( ! empty( $response['data'] ) ) {
6007 - $response = json_decode( wp_json_encode( $response['data'] ), true );
6008 -
6009 - if ( ! empty( $response['data']['tpae_licence'] ) && is_serialized( $response['data']['tpae_licence'] ) ) {
6010 - $response['data']['tpae_licence'] = unserialize( $response['data']['tpae_licence'], array( 'allowed_classes' => false ) );
6011 - }
6012 -
6013 - if ( ! empty( $response['data']['tpag_licence'] ) && is_serialized( $response['data']['tpag_licence'] ) ) {
6014 - $response['data']['tpag_licence'] = unserialize( $response['data']['tpag_licence'], array( 'allowed_classes' => false ) );
6015 - }
6016 -
6017 - if ( ! empty( $response['data']['uichemy_licence'] ) && is_serialized( $response['data']['uichemy_licence'] ) ) {
6018 - $response['data']['uichemy_licence'] = unserialize( $response['data']['uichemy_licence'], array( 'allowed_classes' => false ) );
6019 - }
6020 -
6021 - if ( ! empty( $response['data']['wdkit_licence'] ) && is_serialized( $response['data']['wdkit_licence'] ) ) {
6022 - $response['data']['wdkit_licence'] = unserialize( $response['data']['wdkit_licence'], array( 'allowed_classes' => false ) );
6023 -
6024 - // Store WDesignKit license status locally for quick access
6025 - if ( ! empty( $response['data']['wdkit_licence'] ) && is_array( $response['data']['wdkit_licence'] ) ) {
6026 - update_option( 'wdkit_licence_data', $response['data']['wdkit_licence'] );
6027 - }
6028 - }
6029 -
6030 - if ( ! empty( $response['data']['wdkit_licence_extra'] ) && is_serialized( $response['data']['wdkit_licence_extra'] ) ) {
6031 - $response['data']['wdkit_licence_extra'] = unserialize( $response['data']['wdkit_licence_extra'], array( 'allowed_classes' => false ) );
6032 - }
6033 - }
6034 -
6035 - wp_send_json( $response );
2968 + wp_send_json( $response['data'] );
6036 2969 wp_die();
6037 2970 }
6038 2971
6039 2972 /**
@@ -6044,23 +2977,16 @@
6044 2977 */
6045 2978 protected function wdkit_delete_licence_key() {
6046 2979 $token = ! empty( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '';
6047 2980 $licencename = ! empty( $_POST['licencename'] ) ? sanitize_text_field( wp_unslash( $_POST['licencename'] ) ) : '';
6048 - $apikey = ! empty( $_POST['apikey'] ) ? sanitize_text_field( wp_unslash( $_POST['apikey'] ) ) : '';
6049 2981
6050 2982 $args = array(
6051 2983 'token' => $token,
6052 2984 'licencename' => $licencename,
6053 - 'apikey' => $apikey,
6054 2985 );
6055 2986
6056 2987 $response = $this->wkit_api_call( $args, 'licence_delete' );
6057 2988
6058 - // Remove local WDesignKit license data if deleting WDesignKit license
6059 - if ( 'wdkit' === $licencename ) {
6060 - delete_option( 'wdkit_licence_data' );
6061 - }
6062 -
6063 2989 wp_send_json( $response['data'] );
6064 2990 wp_die();
6065 2991 }
6066 2992
@@ -6072,16 +2998,12 @@
6072 2998 */
6073 2999 protected function wdkit_sync_licence_key() {
6074 3000 $token = ! empty( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '';
6075 3001 $licencename = ! empty( $_POST['licencename'] ) ? sanitize_text_field( wp_unslash( $_POST['licencename'] ) ) : '';
6076 - // Needed to identify which extra-credit key to sync (wdkit_extra / wdkit_ai_extra
6077 - // are arrays matched by the api key's last digits on the server).
6078 - $apikey = ! empty( $_POST['apikey'] ) ? sanitize_text_field( wp_unslash( $_POST['apikey'] ) ) : '';
6079 3002
6080 3003 $args = array(
6081 3004 'token' => $token,
6082 3005 'licencename' => $licencename,
6083 - 'apikey' => $apikey,
6084 3006 );
6085 3007
6086 3008 $response = $this->wkit_api_call( $args, 'licence_sync' );
6087 3009
@@ -6089,118 +3011,9 @@
6089 3011 wp_die();
6090 3012 }
6091 3013
6092 3014 /**
6093 - * Rollback to Previous Versions
6094 3015 *
6095 - * @since 1.1.0
6096 - */
6097 - protected function wdkit_prev_version() {
6098 -
6099 - require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
6100 -
6101 - $plugin_info = plugins_api(
6102 - 'plugin_information',
6103 - array(
6104 - 'slug' => 'wdesignkit',
6105 - )
6106 - );
6107 -
6108 - if ( empty( $plugin_info->versions ) || ! is_array( $plugin_info->versions ) ) {
6109 - return array();
6110 - }
6111 -
6112 - krsort( $plugin_info->versions );
6113 -
6114 - $versions_list = array();
6115 - $index = 0;
6116 -
6117 - foreach ( $plugin_info->versions as $version => $download_link ) {
6118 -
6119 - $lowercase_version = strtolower( $version );
6120 -
6121 - $is_valid_version = ! preg_match( '/(beta|rc|trunk|dev)/i', $lowercase_version );
6122 -
6123 - $is_valid_version = apply_filters( 'wdkit_check_rollback_version', $is_valid_version, $lowercase_version );
6124 -
6125 - if ( ! $is_valid_version || version_compare( $version, WDKIT_VERSION, '>=' ) ) {
6126 - continue;
6127 - }
6128 -
6129 - $versions_list[] = $version;
6130 - ++$index;
6131 - }
6132 -
6133 - // set_transient( 'wdkit_rollback_version_' . WDKIT_VERSION, $versions_list, WEEK_IN_SECONDS );
6134 -
6135 - return $versions_list;
6136 - }
6137 -
6138 - /**
6139 - * Rollback to Previous Versions
6140 - *
6141 - * @since 1.1.0
6142 - */
6143 - protected function wdkit_rollback_check() {
6144 -
6145 - $current_ver = isset( $_POST['version'] ) ? sanitize_text_field( wp_unslash( $_POST['version'] ) ) : '';
6146 - $rv = $this->wdkit_prev_version();
6147 -
6148 - if ( empty( $current_ver ) || ! in_array( $current_ver, $rv ) ) {
6149 - return array(
6150 - 'message' => esc_html__( 'Invalid Nonce or version not found', 'wdesignkit' ),
6151 - 'status' => 'error',
6152 - 'success' => false,
6153 - );
6154 - }
6155 -
6156 - $plugin_slug = basename( WDKIT_PBNAME, '.php' );
6157 -
6158 - $this_version = $current_ver;
6159 - $this_pluginname = WDKIT_PBNAME;
6160 - $this_plugin_u_r_l = sprintf( 'https://downloads.wordpress.org/plugin/%s.%s.zip', $plugin_slug, $this_version );
6161 -
6162 - $plugin_info = new \stdClass();
6163 - $plugin_info->new_version = $this_version;
6164 - $plugin_info->slug = $plugin_slug;
6165 - $plugin_info->package = $this_plugin_u_r_l;
6166 - $plugin_info->url = 'https://wdesignkit.com/';
6167 -
6168 - $update_plugins_data = get_site_transient( 'update_plugins' );
6169 -
6170 - if ( ! is_object( $update_plugins_data ) ) {
6171 - $update_plugins_data = new \stdClass();
6172 - }
6173 -
6174 - $update_plugins_data->response[ $this_pluginname ] = $plugin_info;
6175 -
6176 - set_site_transient( 'update_plugins', $update_plugins_data );
6177 -
6178 - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
6179 -
6180 - $logo_url = WDKIT_URL . 'assets/images/jpg/Wdesignkit-logo.png';
6181 -
6182 - $args = array(
6183 - 'url' => 'update.php?action=upgrade-plugin&plugin=' . rawurlencode( $this_pluginname ),
6184 - 'plugin' => $this_pluginname,
6185 - 'nonce' => 'upgrade-plugin_' . $this_pluginname,
6186 - 'title' => '<img src="' . esc_url( $logo_url ) . '" alt="wdesignkit-logo"><div class="theplus-rb-subtitle">' . esc_html__( 'Rollback to Previous Version', 'wdesignkit' ) . '</div>',
6187 - );
6188 -
6189 - $upgrader_plugin = new \Plugin_Upgrader( new \Plugin_Upgrader_Skin( $args ) );
6190 - $upgrader_plugin->upgrade( $this_pluginname );
6191 -
6192 - activate_plugin( $this_pluginname );
6193 -
6194 - return array(
6195 - 'message' => esc_html__( 'Rollback Successful, Plugin Re-activated', 'wdesignkit' ),
6196 - 'status' => 'Success',
6197 - 'success' => true,
6198 - );
6199 - }
6200 -
6201 - /**
6202 - *
6203 3016 * It is Use for logout.
6204 3017 *
6205 3018 * @since 1.0.0
6206 3019 */
@@ -6214,11 +3027,9 @@
6214 3027 $token = $this->wdkit_login_user_token( $email );
6215 3028 $args = array( 'token' => $token );
6216 3029
6217 3030 if ( 'session' !== $logout_type ) {
6218 - delete_transient( 'wdkit_auth_' . wdesignkit_cloud_session_key( $email ) );
6219 - // Clear stored license data on logout so banner shows again
6220 - delete_option( 'wdkit_licence_data' );
3031 + delete_transient( 'wdkit_auth_' . $email );
6221 3032 $response = WDesignKit_Data_Query::get_data( 'logout', $args );
6222 3033 }
6223 3034 }
6224 3035
@@ -6236,9 +3047,9 @@
6236 3047 */
6237 3048 protected function wdkit_login_user_token( $email = '' ) {
6238 3049
6239 3050 if ( ! empty( $email ) ) {
6240 - $user_key = wdesignkit_cloud_session_key( $email );
3051 + $user_key = strstr( $email, '@', true );
6241 3052 $get_login = get_transient( 'wdkit_auth_' . $user_key );
6242 3053
6243 3054 if ( ! empty( $get_login ) && ! empty( $get_login['token'] ) ) {
6244 3055 return $get_login['token'];
@@ -6256,9 +3067,9 @@
6256 3067 * @param string $data send all post data.
6257 3068 * @param string $type store text data.
6258 3069 * @param string $condition store text data.
6259 3070 */
6260 - protected function wdkit_extract_post_field( $data, $type, $condition = 'none' ) {
3071 + protected function wdkit_sanitizer_bypass( $data, $type, $condition = 'none' ) {
6261 3072
6262 3073 if ( 'none' === $condition ) {
6263 3074 return $data[ $type ];
6264 3075 } elseif ( 'cr_widget' === $condition ) {
@@ -6263,13 +3074,26 @@
6263 3074 return $data[ $type ];
6264 3075 } elseif ( 'cr_widget' === $condition ) {
6265 3076 return $data[ $type ];
6266 3077 }
3078 + }
6267 3079
6268 - return null;
3080 + /**
3081 + * Parse args $_POST
3082 + *
3083 + * @since 1.0.0
3084 + *
3085 + * @param string $data send all post data.
3086 + * @param string $type store text data.
3087 + * @param string $condition store text data.
3088 + */
3089 + protected function wdkit_file_sanitizer_bypass( $data, $type, $condition = 'none' ) {
3090 +
3091 + if ( 'name' === $condition ) {
3092 + return wp_normalize_path( $data[ $type ]['tmp_name'] );
3093 + }
6269 3094 }
6270 3095
6271 -
6272 3096 /**
6273 3097 * Parse args $_POST
6274 3098 *
6275 3099 * @since 1.0.0
@@ -6345,28 +3169,8 @@
6345 3169 if ( isset( $data['plugin'] ) ) {
6346 3170 $args['plugin'] = isset( $data['plugin'] ) ? wp_unslash( $data['plugin'] ) : array();
6347 3171 }
6348 3172
6349 - if ( isset( $data['plugin_exclude'] ) ) {
6350 - $args['plugin_exclude'] = isset( $data['plugin_exclude'] ) ? wp_unslash( $data['plugin_exclude'] ) : array();
6351 - }
6352 -
6353 - if ( isset( $data['ai_compatibility'] ) ) {
6354 - $args['ai_compatibility'] = isset( $data['ai_compatibility'] ) ? wp_unslash( $data['ai_compatibility'] ) : array();
6355 - }
6356 -
6357 - // if ( isset( $data['global_color'] ) ) {
6358 - // $args['global_color'] = isset( $data['global_color'] ) ? wp_unslash( $data['global_color'] ) : array();
6359 - // }
6360 -
6361 - // if ( isset( $data['global_font_family'] ) ) {
6362 - // $args['global_font_family'] = isset( $data['global_font_family'] ) ? wp_unslash( $data['global_font_family'] ) : array();
6363 - // }
6364 -
6365 - if ( isset( $data['global_data'] ) ) {
6366 - $args['global_data'] = isset( $data['global_data'] ) ? wp_unslash( $data['global_data'] ) : array();
6367 - }
6368 -
6369 3173 if ( isset( $data['tag'] ) ) {
6370 3174 $args['tag'] = isset( $data['tag'] ) ? wp_unslash( $data['tag'] ) : array();
6371 3175 }
6372 3176
@@ -6395,34 +3199,8 @@
6395 3199 }
6396 3200
6397 3201 return $args;
6398 3202 }
6399 -
6400 - /**
6401 - * Dark Mode
6402 - *
6403 - * @since 2.0.0
6404 - *
6405 - * @param string store darkmode value in database.
6406 - */
6407 - protected function wdkit_dark_mode() {
6408 - $dark_mode = ! empty( $_POST['dark_mode'] ) ? sanitize_text_field( $_POST['dark_mode'] ) : 'light';
6409 -
6410 - if ( get_option( 'wdkit_dark_mode' ) ) {
6411 - update_option( 'wdkit_dark_mode', $dark_mode );
6412 - } else {
6413 - add_option( 'wdkit_dark_mode', $dark_mode );
6414 - }
6415 -
6416 - $response = array(
6417 - 'message' => esc_html__( 'Dark Mode Updated', 'wdesignkit' ),
6418 - 'status' => 'Success',
6419 - 'success' => true,
6420 - );
6421 -
6422 - wp_send_json( $response );
6423 - wp_die();
6424 - }
6425 3203 }
6426 3204
6427 3205 Wdkit_Api_Call::get_instance();
6428 -}
3206 +}