# wdesignkit/2.7.1/includes/admin/hooks/class-wdkit-widget-ajax.php

WDesignKit – AI Templates, Widget Builder &amp; MCP Workflow, version 2.7.1. 1,546 lines.

- Page: https://pluginprobe.com/plugins/wdesignkit/2.7.1/code/includes/admin/hooks/class-wdkit-widget-ajax.php
- Raw: https://pluginprobe.com/plugins/wdesignkit/2.7.1/raw/includes/admin/hooks/class-wdkit-widget-ajax.php
- Modified: 2026-08-17T07:08:44+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/wdesignkit/2.7.1/code/includes/admin/hooks/class-wdkit-widget-ajax.php#L10-L20`.

```php
<?php
/**
 * The file that defines the core plugin class
 *
 * @link       https://posimyth.com/
 * @since      1.1.1
 *
 * @package    Wdesignkit
 * @subpackage Wdesignkit/includes
 */

/**
 * Exit if accessed directly.
 * */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use wdkit\Wdkit_Wdesignkit;
use wdkit\wdkit_datahooks\Wdkit_Data_Hooks;



if ( ! class_exists( 'Wdkit_Widget_Ajax' ) ) {

	/**
	 * It is wdesignkit Main Class
	 *
	 * @since 1.1.1
	 */
	class Wdkit_Widget_Ajax {

		/**
		 * Member Variable
		 *
		 * @var instance
		 */
		private static $instance;

		/**
		 * Member Variable
		 *
		 * @var staring $wdkit_api
		 */
		public $wdkit_api = WDKIT_SERVER_API_URL . 'api/wp/';

		/**
		 * Member Variable
		 *
		 * @var string $widget_folder_u_r_l
		 */
		public $widget_folder_u_r_l = '';

		/**
		 *  Initiator
		 */
		public static function get_instance() {
			if ( ! isset( self::$instance ) ) {
				self::$instance = new self();
			}

			return self::$instance;
		}

		/**
		 * Define the core functionality of the plugin.
		 */
		public function __construct() {
			add_filter( 'wp_wdkit_widget_ajax', array( $this, 'wdkit_widget_ajax_call' ) );
		}

		/**
		 * Get Wdkit Api Call Ajax.
		 *
		 * @since 1.1.1
		 */
		public function wdkit_widget_ajax_call( $type ) {

			check_ajax_referer( 'wdkit_nonce', 'kit_nonce' );

			if ( ! is_user_logged_in() || ! current_user_can( 'manage_options' ) ) {
				wp_send_json_error( array( 'content' => __( 'Insufficient permissions.', 'wdesignkit' ) ) );
			}

			if ( ! $type ) {
				$this->wdkit_error_msg( 'Something went wrong.' );
			}

			switch ( $type ) {
				case 'widget_browse_page':
					$response = $this->wdkit_widget_browse_page();
					break;
				case 'wkit_public_download_widget':
					$response = $this->wdkit_public_download_widget();
					break;
				case 'wkit_create_widget':
					$response = $this->wkit_create_widget();
					break;
				case 'wkit_import_widget':
					$response = $this->wkit_import_widget();
					break;
				case 'wkit_export_widget':
					$response = $this->wkit_export_widget();
					break;
				case 'wkit_delete_widget':
					$response = $this->wkit_delete_widget();
					break;
				case 'wkit_widget_preview':
					$response = $this->wkit_widget_preview();
					break;
				case 'wkit_check_widget_versions':
					$response = $this->wkit_check_widget_versions();
					break;
				case 'wkit_widget_builder_get':
					$response = $this->wkit_widget_builder_get();
					break;
				case 'wkit_plugin_download_get':
					$response = $this->wkit_plugin_download_get();
					break;
			}

			wp_send_json( $response );
			wp_die();
		}

		/**
		 *
		 * It is Use to get data for widget browse page
		 *
		 * @since 1.0.4
		 */
		public function wdkit_widget_browse_page() {
			$array_data = array(
				'CurrentPage' => isset( $_POST['page'] ) ? (int) $_POST['page'] : 1,
				'builder'     => isset( $_POST['buildertype'] ) ? wp_unslash( $_POST['buildertype'] ) : '',
				'sub_builder' => isset( $_POST['sub_builder'] ) ? wp_unslash( $_POST['sub_builder'] ) : '',
				'category'    => isset( $_POST['category'] ) ? sanitize_text_field( wp_unslash( $_POST['category'] ) ) : '',
				'ParPage'     => isset( $_POST['perpage'] ) ? (int) $_POST['perpage'] : 12,
				'search'      => isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : '',
				'free_pro'    => isset( $_POST['free_pro'] ) ? sanitize_text_field( wp_unslash( $_POST['free_pro'] ) ) : '',
			);

			$response = $this->wkit_api_call( $array_data, 'browse_widget' );
			$success  = ! empty( $response['success'] ) ? $response['success'] : false;

			if ( empty( $success ) ) {
				$response = array(
					'success'      => false,
					'message'      => esc_html__( 'Data Not Found', 'wdesignkit' ),
					'description'  => esc_html__( 'Widget List Not Found', 'wdesignkit' ),

					'widgets'      => array(),
					'widgetscount' => 0,
					'showwidgets'  => 0,
				);

				wp_send_json( $response );
				wp_die();
			}

			$response = json_decode( wp_json_encode( $response['data'] ), true );

			return $response;
		}

		/**
		 *
		 * It is Use for download widget from browse page.
		 *
		 * @since 1.1.4
		 */
		public function wdkit_public_download_widget() {
			$data = ! empty( $_POST['widget_info'] ) ? $this->wdkit_extract_post_field( $_POST, 'widget_info', 'none' ) : '';
			$data = json_decode( stripslashes( $data ) );

			$api_type = isset( $data->api_type ) ? sanitize_text_field( $data->api_type ) : 'widget/download';

			$array_data = array(
				'id'   => isset( $data->w_uniq ) ? sanitize_text_field( $data->w_uniq ) : '',
				'u_id' => isset( $data->u_id ) ? sanitize_text_field( $data->u_id ) : '',
				'type' => isset( $data->d_type ) ? sanitize_text_field( $data->d_type ) : '',
				'unique_id' => get_option( 'wdkit_unique_id' ) ?? '',
			);

			$response = $this->wkit_api_call( $array_data, $api_type );
			$success  = ! empty( $response['success'] ) ? $response['success'] : false;

			if ( empty( $success ) ) {
				$massage = ! empty( $response['massage'] ) ? $response['massage'] : esc_html__( 'server error', 'wdesignkit' );

				$result = (object) array(
					'success'     => false,
					'message'     => $massage,
					'description' => esc_html__( 'Widget not Downloaded', 'wdesignkit' ),
				);

				wp_send_json( $result );
				wp_die();
			}

			$response = json_decode( wp_json_encode( $response['data'] ), true );
			if ( ! empty( $response ) && ! empty( $response['data'] ) ) {
				$img_url = ! empty( $response['data']['image'] ) ? esc_url_raw( $response['data']['image'] ) : '';
				$json    = ! empty( $response['data']['json'] ) ? wp_json_encode( $response['data']['json'] ) : '';

				if ( ! empty( $json ) ) {
					include_once ABSPATH . 'wp-admin/includes/file.php';
					\WP_Filesystem();
					global $wp_filesystem;

					$json_data = json_decode( $json );
					$json_data = json_decode( $json_data );
					$title     = ! empty( $json_data->widget_data->widgetdata->name ) ? sanitize_file_name( $json_data->widget_data->widgetdata->name ) : '';
					// sanitize_key() strips path separators and dots from the builder segment;
					// the allowlist below then rejects anything outside the known builders so a
					// crafted "type" can never escape WDKIT_BUILDER_PATH before wp_mkdir_p() runs.
					$builder   = ! empty( $json_data->widget_data->widgetdata->type ) ? sanitize_key( $json_data->widget_data->widgetdata->type ) : '';
					$widget_id = ! empty( $json_data->widget_data->widgetdata->widget_id ) ? sanitize_file_name( $json_data->widget_data->widgetdata->widget_id ) : '';

					$allowed_builders = array( 'elementor', 'gutenberg', 'gutenberg_core', 'bricks' );
					if ( '' === $title || '' === $widget_id || ! in_array( $builder, $allowed_builders, true ) ) {
						wp_send_json(
							(object) array(
								'success' => false,
								'message' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
							)
						);
						wp_die();
					}

					// Canonical helpers replace spaces BEFORE sanitize_file_name(). $title above is
					// already sanitized, so spaces had become hyphens and the underscore pass did
					// nothing — a multi-word title wrote "My-Widget_id.json" while the builder's
					// save path writes "My_Widget_id.php". The loader pairs them by swapping .php
					// for .json, so the widget never registered (ClickUp 86d41cck5).
					$folder_name = wdesignkit_widget_folder_name( $title, $widget_id );
					$file_name   = wdesignkit_widget_file_name( $title, $widget_id );

					$builder_type_path = WDKIT_BUILDER_PATH . "/{$builder}/";

					if ( ! is_dir( $builder_type_path . $folder_name ) ) {
						wp_mkdir_p( $builder_type_path . $folder_name );
					}

					// Realpath validation — ensure we're still inside WDKIT_BUILDER_PATH.
					$real_widget = realpath( $builder_type_path . $folder_name );
					$real_base   = realpath( WDKIT_BUILDER_PATH );
					if ( ! $real_widget || ! $real_base || strpos( $real_widget, $real_base . DIRECTORY_SEPARATOR ) !== 0 ) {
						wp_send_json(
							(object) array(
								'success' => false,
								'message' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
							)
						);
						wp_die();
					}

					if ( ! empty( $img_url ) ) {
						// SSRF guard (CWE-918): validate the resolved host before fetching.
						$img_body = wdesignkit_safe_remote_get( $img_url );
						if ( ! is_wp_error( $img_body ) ) {
							// The remote extension was written verbatim here, so a ".php" image URL
							// in a cloud response landed executable PHP in the builder directory
							// (CWE-434, ClickUp 86d41cczd). '' means the bytes are not an image.
							$img_ext = wdesignkit_safe_image_extension( $img_url, $img_body['body'] );

							if ( '' !== $img_ext ) {
								$wp_filesystem->put_contents( WDKIT_BUILDER_PATH . "/$builder/$folder_name/$file_name.$img_ext", $img_body['body'] );

								$json_data->widget_data->widgetdata->w_image = WDKIT_SERVER_PATH . "/$builder/$folder_name/$file_name.$img_ext";
							}
						}
					}

					if ( function_exists( 'wdesignkit_invalidate_widget_registry' ) ) {
						wdesignkit_invalidate_widget_registry( $builder );
					}

					$response = (object) array(
						'message'     => ! empty( $response['message'] ) ? $response['message'] : '',
						'description' => ! empty( $response['description'] ) ? $response['description'] : '',
						'success'     => ! empty( $response['success'] ) ? $response['success'] : false,
						'r_id'        => ! empty( $response['data']['rid'] ) ? $response['data']['rid'] : 0,
						'json'        => wp_json_encode( $json_data ),
					);
				}
			}

			wp_send_json( $response );
			wp_die();
		}

		/**
		 * Get widget builder data from server for plugin download.
		 *
		 * @since 1.1.4
		 */
		public function wkit_widget_builder_get() {
			$token = isset( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '';
			$id    = isset( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '';

			$array_data = array(
				'token'     => $token,
				'id'        => $id,
				'unique_id' => get_option( 'wdkit_unique_id' ) ?? '',
			);

			$response = $this->wkit_api_call( $array_data, 'widget/builder/get', WDKIT_SERVER_API_URL . 'api/v2/' );
			$success  = ! empty( $response['success'] ) ? $response['success'] : false;

			if ( empty( $success ) ) {
				$massage = ! empty( $response['massage'] ) ? $response['massage'] : esc_html__( 'server error', 'wdesignkit' );

				$result = (object) array(
					'success'     => false,
					'message'     => $massage,
					'description' => esc_html__( 'Widget builder data not found.', 'wdesignkit' ),
				);

				wp_send_json( $result );
				wp_die();
			}

			return $response['data'];
		}

		/**
		 * Generate and download a widget as a standalone WordPress plugin.
		 *
		 * @since 1.1.4
		 */
		public function wkit_plugin_download_get() {
			$fields = array(
				'pluginName',
				// The popup has a Version field and the cloud reads 'version' for the plugin
				// header — leaving it out of this allowlist silently discarded whatever the
				// user typed and stamped every download 1.0.0.
				'version',
				'licenceUrl',
				'pluginSlug',
				'pluginPrefix',
				'authorName',
				'authorUrl',
				'requiredPhpVersion',
				'requiredWpVersion',
				'contributors',
				'shortDescription',
				'tags',
				'textDomain',
				'faq',
				'changelog',
				'php_file',
				'js_file',
				'css_file',
				'js_react_file',
				'widgetdata',
				'token',
				'id',
			);

			$array_data = array();
			foreach ( $fields as $field ) {
				if ( isset( $_POST[ $field ] ) ) {
					// Code/file payloads must not be sanitized; only unslash the magic-quoted value.
					$array_data[ $field ] = wp_unslash( $_POST[ $field ] );
				}
			}

			$array_data['unique_id'] = get_option( 'wdkit_unique_id' ) ?? '';

			$response = $this->wkit_api_call( $array_data, 'plugin/download/get', WDKIT_SERVER_API_URL . 'api/v2/' );
			$success  = ! empty( $response['success'] ) ? $response['success'] : false;

			if ( empty( $success ) ) {
				$massage = ! empty( $response['massage'] ) ? $response['massage'] : esc_html__( 'server error', 'wdesignkit' );

				$result = (object) array(
					'success'     => false,
					'message'     => $massage,
					'description' => esc_html__( 'Plugin not downloaded.', 'wdesignkit' ),
				);

				wp_send_json( $result );
				wp_die();
			}

			return $response['data'];
		}

		/**
		 * Create a new widget
		 *
		 * @since 1.1.4
		 */
		public function wkit_create_widget() {
			// Site-level opt-out for generated widget PHP (ClickUp 86d41zavc). Defaults to allowed,
			// so this changes nothing unless an operator explicitly filters it off:
			//   add_filter( 'wdesignkit_allow_widget_php_write', '__return_false' );
			// See wdesignkit_widget_php_write_allowed() for why this is a dedicated filter rather
			// than a DISALLOW_FILE_MODS / DISALLOW_FILE_EDIT check.
			if ( function_exists( 'wdesignkit_widget_php_write_allowed' ) && ! wdesignkit_widget_php_write_allowed() ) {
				wp_send_json(
					(object) array(
						'success'     => false,
						'message'     => esc_html__( 'File modifications are disabled on this site', 'wdesignkit' ),
						'description' => esc_html__( 'Generated widget PHP writes have been turned off via the wdesignkit_allow_widget_php_write filter.', 'wdesignkit' ),
					)
				);
				wp_die();
			}

			$image = '';
			if ( isset( $_FILES ) && ! empty( $_FILES ) && isset( $_FILES['image'] ) && ! empty( $_FILES['image'] ) ) {
				$image = Wdkit_Data_Hooks::get_super_global_value( $_FILES, 'image' );
			}

			$icon = '';
			if ( isset( $_FILES ) && ! empty( $_FILES ) && isset( $_FILES['icon'] ) && ! empty( $_FILES['icon'] ) ) {
				$icon = Wdkit_Data_Hooks::get_super_global_value( $_FILES, 'icon' );
			}

			$data   = ! empty( $_POST['value'] ) ? $this->wdkit_extract_post_field( $_POST, 'value', 'cr_widget' ) : '';
			// $data   = ! empty( $data ) ? stripslashes( $data ) : '';
			$return = ! empty( $data ) ? json_decode( $data ) : '';

			$all_val = ! empty( $return ) ? $return : '';
			if ( empty( $all_val ) ) {

				$responce = array(
					'message'     => esc_html__( 'Data Not Found', 'wdesignkit' ),
					'description' => esc_html__( 'something went wrong! please try again later.', 'wdesignkit' ),
					'success'     => false,
				);

				wp_send_json( $responce );
				wp_die();
			}

			$file_name     = ! empty( $all_val->file_name ) ? sanitize_text_field( $all_val->file_name ) : '';
			$folder_name   = ! empty( $all_val->folder_name ) ? sanitize_text_field( $all_val->folder_name ) : '';
			$old_widget    = ! empty( $all_val->old_folder ) ? sanitize_text_field( $all_val->old_folder ) : '';
			$description   = ! empty( $all_val->description ) ? sanitize_text_field( $all_val->description ) : '';
			$json_file     = ! empty( $all_val->json_file ) ? $all_val->json_file : '';
			$function_call = ! empty( $all_val->call ) ? sanitize_text_field( $all_val->call ) : '';
			$plugin        = ! empty( $all_val->plugin ) ? $all_val->plugin : '';
			$d_image       = ! empty( $all_val->d_image ) ? $all_val->d_image : '';
			$data          = json_decode( $json_file );

			$elementor_php_file = ! empty( $all_val->elementor_php_file ) ? $all_val->elementor_php_file : '';
			$elementor_js       = ! empty( $all_val->elementor_js ) ? $all_val->elementor_js : '';
			$elementor_css      = ! empty( $all_val->elementor_css ) ? $all_val->elementor_css : '';

			$gutenberg_php_file = ! empty( $all_val->gutenberg_php_file ) ? $all_val->gutenberg_php_file : '';
			$gutenberg_js       = ! empty( $all_val->gutenberg_js ) ? $all_val->gutenberg_js : '';
			$gutenberg_css      = ! empty( $all_val->gutenberg_css ) ? $all_val->gutenberg_css : '';
			$external_js_file   = ! empty( $all_val->external_js_file ) ? $all_val->external_js_file : '';
			$style_file         = ! empty( $all_val->style_file ) ? $all_val->style_file : '';

			$bricks_php_file = ! empty( $all_val->bricks_php_file ) ? $all_val->bricks_php_file : '';
			$bricks_js       = ! empty( $all_val->bricks_js ) ? $all_val->bricks_js : '';
			$bricks_css      = ! empty( $all_val->bricks_css ) ? $all_val->bricks_css : '';

			$old_folder  = ! empty( $old_widget ) ? str_replace( ' ', '-', $old_widget ) : '';
			$widget_type = ! empty( $data->widget_data->widgetdata->type ) ? sanitize_text_field( $data->widget_data->widgetdata->type ) : '';

			// For gutenberg_core plugin, use the plugin value as widget_type for folder path
			if ( 'gutenberg_core' === $plugin ) {
				$widget_type = 'gutenberg_core';
			}

			if ( empty( $widget_type ) ) {
				$responce = array(
					'message'     => esc_html__( 'Builder Type not found', 'wdesignkit' ),
					'description' => esc_html__( 'something went wrong! please try again later.', 'wdesignkit' ),
					'success'     => false,
				);

				wp_send_json( $responce );
				wp_die();
			}

			// $file_name, $folder_name and $widget_type arrive from the request body and were only
			// passed through sanitize_text_field(), which leaves "../../../../plugins/hello"
			// untouched — so this handler would write executable PHP anywhere the web user can
			// reach, outside the builder directory and its .htaccess deny rule. The sibling
			// download handler above has had these guards since 2.6.4; this one was missed
			// (CWE-22, ClickUp 86d41cckh).
			$safe_path = wdesignkit_widget_path_guard( $widget_type, $folder_name, $file_name );
			if ( false === $safe_path ) {
				wp_send_json(
					(object) array(
						'success'     => false,
						'message'     => esc_html__( 'Operation Failed!', 'wdesignkit' ),
						'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
					)
				);
				wp_die();
			}

			$widget_type       = $safe_path['builder'];
			$folder_name       = $safe_path['folder'];
			$file_name         = $safe_path['file'];
			$builder_type_path = trailingslashit( $safe_path['builder_dir'] );
			$widget_file_url   = $safe_path['dir'];

			if ( ! is_dir( $widget_file_url ) ) {
				wp_mkdir_p( $widget_file_url );
			}

			// Re-check the created directory: the component guard above cannot see a symlink.
			if ( ! wdesignkit_path_inside_builder_dir( $widget_file_url ) ) {
				wp_send_json(
					(object) array(
						'success'     => false,
						'message'     => esc_html__( 'Operation Failed!', 'wdesignkit' ),
						'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
					)
				);
				wp_die();
			}

			include_once ABSPATH . 'wp-admin/includes/file.php';
			\WP_Filesystem();
			global $wp_filesystem;
			$widget_folder_u_r_l       = trailingslashit( $widget_file_url ) . $file_name;
			$this->widget_folder_u_r_l = $widget_file_url;

			if ( 'elementor' === $plugin ) {
				$widget_file_list = scandir( $widget_file_url );
				$widget_file_list = array_diff( $widget_file_list, array( '.', '..' ) );

				foreach ( $widget_file_list as $sub_dir_value ) {
					$file      = new SplFileInfo( $sub_dir_value );
					$check_ext = $file->getExtension();
					$extiona   = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );

					if ( 'js' === $extiona || 'css' === $extiona || 'json' === $extiona || 'php' === $extiona ) {
						$wp_filesystem->rmdir( "$widget_file_url/$sub_dir_value", true );
					}
				}

				if ( ! empty( $elementor_php_file ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.php", $elementor_php_file );
				}
				if ( ! empty( $json_file ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.json", $json_file );
				}
				if ( ! empty( $elementor_css ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.css", $elementor_css );
				}
				if ( ! empty( $elementor_js ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.js", $elementor_js );
				}
			} elseif ( 'bricks' === $plugin ) {

				$widget_file_list = scandir( $widget_file_url );
				$widget_file_list = array_diff( $widget_file_list, array( '.', '..' ) );

				foreach ( $widget_file_list as $sub_dir_value ) {
					$file      = new SplFileInfo( $sub_dir_value );
					$check_ext = $file->getExtension();
					$extiona   = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );

					if ( 'js' === $extiona || 'css' === $extiona || 'json' === $extiona || 'php' === $extiona ) {
						$wp_filesystem->rmdir( "$widget_file_url/$sub_dir_value", true );
					}
				}

				$wp_filesystem->put_contents( "$widget_folder_u_r_l.php", $bricks_php_file );
				$wp_filesystem->put_contents( "$widget_folder_u_r_l.json", $json_file );

				if ( ! empty( $bricks_css ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.css", $bricks_css );
				}

				if ( ! empty( $bricks_js ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.js", $bricks_js );
				}
			} elseif ( 'gutenberg' === $plugin ) {

				$widget_file_list = scandir( $widget_file_url );
				$widget_file_list = array_diff( $widget_file_list, array( '.', '..' ) );

				foreach ( $widget_file_list as $sub_dir_value ) {
					$file      = new SplFileInfo( $sub_dir_value );
					$check_ext = $file->getExtension();
					$extiona   = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );

					if ( 'js' === $extiona || 'css' === $extiona || 'json' === $extiona || 'php' === $extiona ) {
						$wp_filesystem->rmdir( "$widget_file_url/$sub_dir_value", true );
					}
				}

				if ( ! empty( $external_js_file ) ) {
					$wp_filesystem->put_contents( "$widget_file_url/index.js", $external_js_file );
				}
				$wp_filesystem->put_contents( "$widget_folder_u_r_l.php", $gutenberg_php_file );
				$wp_filesystem->put_contents( "$widget_folder_u_r_l.json", $json_file );
				if ( ! empty( $gutenberg_css ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.css", $gutenberg_css );
				}
				$wp_filesystem->put_contents( "$widget_folder_u_r_l.js", $gutenberg_js );
			} elseif ( 'gutenberg_core' === $plugin ) {

				$widget_file_list = scandir( $widget_file_url );
				$widget_file_list = array_diff( $widget_file_list, array( '.', '..' ) );

				foreach ( $widget_file_list as $sub_dir_value ) {
					$file      = new SplFileInfo( $sub_dir_value );
					$check_ext = $file->getExtension();
					$extiona   = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );

					if ( 'js' === $extiona || 'css' === $extiona || 'json' === $extiona || 'php' === $extiona ) {
						$wp_filesystem->rmdir( "$widget_file_url/$sub_dir_value", true );
					}
				}

				if ( ! empty( $external_js_file ) ) {
					$wp_filesystem->put_contents( "$widget_file_url/index.js", $external_js_file );
				}
				$wp_filesystem->put_contents( "$widget_folder_u_r_l.php", $gutenberg_php_file );
				$wp_filesystem->put_contents( "$widget_folder_u_r_l.json", $json_file );
				if ( ! empty( $gutenberg_css ) ) {
					$wp_filesystem->put_contents( "$widget_folder_u_r_l.css", $gutenberg_css );
				}
				$wp_filesystem->put_contents( "$widget_folder_u_r_l.js", $gutenberg_js );
			}

			if ( ! empty( $image ) && ! empty( $image['tmp_name'] ) ) {

				$img_type = array( 'jpg', 'png' );

				foreach ( $img_type as $imgext ) {
					$wp_filesystem->rmdir( "$widget_folder_u_r_l . $imgext", true );
				}

				$ext     = $image['type'];
				$img_ext = '';
				if ( strpos( $ext, 'jpeg' ) ) {
					$img_ext = 'jpg';
				} elseif ( strpos( $ext, 'png' ) ) {
					$img_ext = 'png';
				}
				if ( ! empty( $img_ext ) ) {
					add_filter( 'upload_dir', array( $this, 'custom_upload_dir' ) );

					$uploaded_file = wp_handle_upload( $image, array( 'test_form' => false ) );

					rename( $uploaded_file['file'], $widget_folder_u_r_l . '.' . $img_ext );

					remove_filter( 'upload_dir', array( $this, 'custom_upload_dir' ) );

				}
			} elseif ( ! empty( $old_widget ) ) {
				$img_url = $data->widget_data->widgetdata->w_image;
				// Copy of an existing local thumbnail, so there are no downloaded bytes to verify —
				// the allowlist alone keeps the stored w_image extension from naming the copy
				// something executable (ClickUp 86d41cczd). A non-image extension yields 'png',
				// which then fails the file_exists() check below and copies nothing.
				$img_ext = wdesignkit_safe_image_extension( $img_url );

				if ( ! empty( $img_ext ) ) {
					$old_widget_folder = str_replace( ' ', '-', $old_widget );
					$old_widget_file   = str_replace( ' ', '_', $old_widget );
					$img_path          = "$builder_type_path$old_widget_folder/$old_widget_file.$img_ext";
					$img_path          = str_replace( '\\', '/', $img_path );

					if ( file_exists( $img_path ) ) {
						$get_img = $img_path;
						$put_img = "$widget_folder_u_r_l.$img_ext";

						if ( ! empty( $get_img ) && ! empty( $put_img ) ) {
							rename( $get_img, $put_img );
						}
					}
				}
			}

			if ( ! empty( $d_image ) ) {
				$d_image   = str_replace( '\\', '', $d_image );
				$d_img_url = $d_image;
				// SSRF guard (CWE-918): validate the resolved host before fetching.
				$img_body  = wdesignkit_safe_remote_get( $d_img_url );
				if ( ! is_wp_error( $img_body ) ) {
					// The on-disk extension must never be taken verbatim from a remote URL (CWE-434) —
					// a poisoned response pointing at a ".php" path would otherwise write executable
					// PHP into the builder directory. Restrict to an image allowlist, falling back to
					// png, and verify the downloaded bytes' real MIME type before writing.
					$allowed_img_exts = array( 'jpg', 'jpeg', 'png', 'webp' );
					$img_ext          = strtolower( pathinfo( $d_img_url, PATHINFO_EXTENSION ) );
					$img_ext          = in_array( $img_ext, $allowed_img_exts, true ) ? $img_ext : 'png';

					$tmp_check = wp_check_filetype_and_ext( '', "temp.$img_ext" );
					$mime_ok   = ! empty( $tmp_check['ext'] ) && in_array( $tmp_check['ext'], $allowed_img_exts, true );

					$finfo     = function_exists( 'finfo_open' ) ? finfo_open( FILEINFO_MIME_TYPE ) : false;
					$real_mime = $finfo ? finfo_buffer( $finfo, $img_body['body'] ) : '';
					if ( $finfo ) {
						finfo_close( $finfo );
					}
					$allowed_mimes = array( 'image/jpeg', 'image/png', 'image/webp' );

					if ( $mime_ok && ( ! $real_mime || in_array( $real_mime, $allowed_mimes, true ) ) ) {
						$wp_filesystem->put_contents( WDKIT_BUILDER_PATH . "/$widget_type/$folder_name/$file_name.$img_ext", $img_body['body'] );
					}
				}
			}

			if ( ! empty( $function_call ) && 'import' !== $function_call && ! empty( $old_folder ) && strtolower( $old_folder ) !== strtolower( $folder_name ) && is_dir( $builder_type_path . $old_folder ) ) {
				require_once ABSPATH . 'wp-admin/includes/file.php';
				global $wp_filesystem;
				WP_Filesystem();
				$wp_filesystem->rmdir( $builder_type_path . $old_folder, true );
			} elseif ( ! empty( $old_folder ) && $old_folder !== $folder_name ) {
				$old_path = wp_normalize_path( trailingslashit( WDKIT_BUILDER_PATH ) . $widget_type . '/' . $old_folder );
				$new_path = wp_normalize_path( trailingslashit( WDKIT_BUILDER_PATH ) . $widget_type . '/' . $folder_name );
				
				if ( is_dir( $old_path ) && ! is_dir( $new_path ) ) {
					rename( $old_path, $new_path );
				}
			}

			if ( function_exists( 'wdesignkit_invalidate_widget_registry' ) ) {
				wdesignkit_invalidate_widget_registry( $widget_type );
			}

			$responce = array(
				'message'     => esc_html__( 'Updates Saved!', 'wdesignkit' ),
				'description' => esc_html__( 'Your changes have been saved successfully.', 'wdesignkit' ),
				'success'     => true,
			);

			return $responce;
		}

		/**
		 * It is Use for delete widget from server
		 *
		 * @since 1.1.4
		 */
		public function wkit_import_widget() {
			$filename = '';
			if ( isset( $_FILES ) && ! empty( $_FILES ) && isset( $_FILES['zipName'] ) && ! empty( $_FILES['zipName'] ) ) {
				$filename = ! empty( $_FILES['zipName']['name'] ) ? sanitize_file_name( $_FILES['zipName']['name'] ) : '';
			}

			$zip = new ZipArchive();

			$zipname = '';
			if ( ! empty( $_FILES['zipName']['tmp_name'] ) ) {
				$zipname = $this->wdkit_file_sanitizer_bypass( $_FILES, 'zipName', 'name' );
			}

			$res = $zip->open( $zipname );

			if ( true === $res ) {
				$widget_name = $image = $json_file = '';

				for ( $i = 0; $i < $zip->numFiles; $i++ ) {

					$sub_dir_value = $zip->getNameIndex( $i );

					$file      = new SplFileInfo( $sub_dir_value );
					$check_ext = $file->getExtension();
					$extiona   = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );
					if ( 'json' === $extiona ) {
						$json_file = $zip->getFromName( $sub_dir_value );
						$u_r_l     = json_decode( $json_file, true );

						if ( ! empty( $u_r_l['widget_data']['widgetdata']['name'] ) && ! empty( $u_r_l['widget_data']['widgetdata']['widget_id'] ) ) {
							// Sanitize as filenames before they are used to build the import path
							// (CWE-22). sanitize_file_name()/sanitize_key() strip path separators
							// and dots so a crafted .wdk JSON cannot escape WDKIT_BUILDER_PATH.
							$widget_name = sanitize_file_name( $u_r_l['widget_data']['widgetdata']['name'] );
							$widget_id   = sanitize_file_name( $u_r_l['widget_data']['widgetdata']['widget_id'] );
							$widget_type = ! empty( $u_r_l['widget_data']['widgetdata']['type'] ) ? sanitize_key( $u_r_l['widget_data']['widgetdata']['type'] ) : '';
						}
					} elseif ( 'jpg' === $extiona || 'png' === $extiona || 'jpeg' === $extiona ) {
						$img_ext   = $extiona;
						$imageData = $zip->getFromName( $sub_dir_value );
					}
				}

				if ( ! empty( $widget_name ) && ! empty( $json_file ) ) {

					$local_list = $this->wdkit_get_local_widgets();

					if ( ! empty( $widget_id ) ) {

						if ( count( $local_list ) > 0 ) {
							foreach ( $local_list as $key => $value ) {
								$old_id = $value['widgetdata']['widget_id'];

								if ( $old_id == $widget_id ) {
									$responce = (object) array(
										'success'     => false,
										'message'     => esc_html__( 'Widget Already Exist!', 'wdesignkit' ),
										'description' => esc_html__( 'Widget Already Exist in plugin', 'wdesignkit' ),
									);

									wp_send_json( $responce );
									wp_die();
								}
							}
						}
					} else {
						$responce = (object) array(
							'success'     => false,
							'message'     => esc_html__( 'Operation Failed!', 'wdesignkit' ),
							'description' => esc_html__( 'Widget can not imported', 'wdesignkit' ),
						);

						wp_send_json( $responce );
						wp_die();
					}

					// .wdk zip import. Same ordering bug as the download path above: $widget_name
					// is already sanitize_file_name()'d, so the underscore pass was a no-op and a
					// multi-word title landed as "My-Widget_id" where the loader expects
					// "My_Widget_id" (ClickUp 86d41cck5). The helpers include the id, so the
					// "_{$widget_id}" that used to be appended at each use site is gone.
					$folder_name = wdesignkit_widget_folder_name( $widget_name, $widget_id );
					$file_name   = wdesignkit_widget_file_name( $widget_name, $widget_id );

					$allowed_builders = array( 'elementor', 'gutenberg', 'gutenberg_core', 'bricks' );
					if ( ! in_array( $widget_type, $allowed_builders, true ) ) {
						$responce = (object) array(
							'success'     => false,
							'message'     => esc_html__( 'Operation Failed!', 'wdesignkit' ),
							'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
						);

						wp_send_json( $responce );
						wp_die();
					}

					if ( ! is_dir( WDKIT_BUILDER_PATH . "/{$widget_type}" ) ) {
						wp_mkdir_p( WDKIT_BUILDER_PATH . "/{$widget_type}" );
					}
					$file_path = WDKIT_BUILDER_PATH . "/{$widget_type}/{$folder_name}";

					// Realpath containment — ensure the resolved builder dir stays inside WDKIT_BUILDER_PATH.
					$real_base = realpath( WDKIT_BUILDER_PATH );
					$real_type = realpath( WDKIT_BUILDER_PATH . "/{$widget_type}" );
					if ( ! $real_base || ! $real_type || strpos( $real_type, $real_base . DIRECTORY_SEPARATOR ) !== 0 ) {
						$responce = (object) array(
							'success'     => false,
							'message'     => esc_html__( 'Operation Failed!', 'wdesignkit' ),
							'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
						);

						wp_send_json( $responce );
						wp_die();
					}

					if ( ! empty( $imageData ) ) {
						include_once ABSPATH . 'wp-admin/includes/file.php';
						\WP_Filesystem();
						global $wp_filesystem;
						if ( ! is_dir( $file_path ) ) {
							wp_mkdir_p( $file_path );
						}

						$wp_filesystem->put_contents( "{$file_path}/{$file_name}.$img_ext", $imageData );
					}
				}

				if ( function_exists( 'wdesignkit_invalidate_widget_registry' ) ) {
					wdesignkit_invalidate_widget_registry( $widget_type );
				}

				$responce = (object) array(
					'success'     => true,
					'message'     => esc_html__( 'Widget imported', 'wdesignkit' ),
					'description' => esc_html__( 'Widget imported successfully', 'wdesignkit' ),
					'json'        => $u_r_l,
				);

				return $responce;

			} else {
				$responce = (object) array(
					'success'     => false,
					'message'     => esc_html__( 'Operation Failed!', 'wdesignkit' ),
					'description' => esc_html__( 'Widget can not imported', 'wdesignkit' ),
				);

				wp_send_json( $responce );
				wp_die();
			}
		}

		/**
		 *
		 * It is Use for delete widget from server
		 *
		 * @since 1.1.4
		 */
		public function wkit_export_widget() {
			$data = isset( $_POST['info'] ) ? wp_unslash( $_POST['info'] ) : '';
			$data = json_decode( stripslashes( $data ) );

			// Sanitize as filenames before they are used to build the export path
			// (CWE-22). sanitize_file_name()/sanitize_key() strip path separators
			// and dots so a crafted widget_name/widget_type cannot escape WDKIT_BUILDER_PATH.
			$widget_name_temp = isset( $data->widget_name ) ? sanitize_file_name( $data->widget_name ) : '';
			$widget_type      = isset( $data->widget_type ) ? sanitize_key( $data->widget_type ) : '';

			$widget_name    = str_replace( ' ', '_', $widget_name_temp );
			$folder         = str_replace( ' ', '-', $widget_name_temp );
			$unique_version = $this->wdkit_generate_unique_id();

			if ( empty( $widget_type ) ) {
				$result = (object) array(
					'success'     => false,
					'url'         => '',
					'message'     => esc_html__( 'Widget Type Fail', 'wdesignkit' ),
					'description' => esc_html__( 'Widget Type Not Exists', 'wdesignkit' ),
				);

				wp_send_json( $result );
				wp_die();
			}

			$downlod_path = WDKIT_BUILDER_PATH . "/{$widget_type}/";
			$new_path     = "{$downlod_path}/{$folder}/{$widget_name}";

			// Realpath containment — ensure the resolved widget path stays inside WDKIT_BUILDER_PATH.
			$real_base = realpath( WDKIT_BUILDER_PATH );
			$real_new  = realpath( "$new_path.json" );
			if ( ! $real_base || ! $real_new || strpos( $real_new, $real_base . DIRECTORY_SEPARATOR ) !== 0 ) {
				$result = (object) array(
					'success'     => false,
					'url'         => '',
					'message'     => esc_html__( 'Widget Exported Fail', 'wdesignkit' ),
					'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
				);

				wp_send_json( $result );
				wp_die();
			}

			$download_url = WDKIT_SERVER_PATH . "/{$widget_type}/{$widget_name}.zip";
			$zip          = new ZipArchive();
			$tmp_file     = "{$downlod_path}{$widget_name}.zip";

			$json_data = wp_json_file_decode( "$new_path.json" );
			$img_ext   = $json_data->widget_data->widgetdata->img_ext;

			if ( true === $zip->open( $tmp_file, ZipArchive::CREATE ) ) {
				$widget_wb = str_replace( '-', '_', $folder );
				$zip->addFile( "$new_path.json", "$widget_wb.json" );
				if ( ! empty( $img_ext ) ) {
					$zip->addFile( "$new_path.$img_ext", "$widget_wb.$img_ext" );
				}
				$zip->close();

				$result = (object) array(
					'success'     => true,
					'url'         => $download_url,
					'message'     => esc_html__( 'Widget Exported', 'wdesignkit' ),
					'description' => esc_html__( 'Your widget has been exported successfully.', 'wdesignkit' ),
				);

				wp_send_json( $result );
				wp_die();
			} else {
				$result = (object) array(
					'success'     => false,
					'url'         => '',
					'message'     => esc_html__( 'Widget Exported Fail', 'wdesignkit' ),
					'description' => esc_html__( 'Something went wrong! please try again later.', 'wdesignkit' ),
				);

				return $result;
			}
		}

		/**
		 *
		 * It is Use for delete widget from server
		 *
		 * @since 1.1.4
		 */
		public function wkit_delete_widget() {
			$data = isset( $_POST['info'] ) ? sanitize_text_field( wp_unslash( $_POST['info'] ) ) : '';
			$data = json_decode( stripslashes( $data ) );

			$delete_type = isset( $data->delete_type ) ? sanitize_text_field( $data->delete_type ) : '';

			if ( 'plugin_server' === $delete_type ) {
				$array_data = array(
					'token'    => isset( $data->token ) ? sanitize_text_field( $data->token ) : '',
					'type'     => isset( $data->type ) ? sanitize_text_field( $data->type ) : '',
					'w_unique' => isset( $data->w_unique ) ? sanitize_text_field( $data->w_unique ) : '',
					'id'       => isset( $data->id ) ? sanitize_text_field( $data->id ) : '',
				);

				$response = $this->wkit_api_call( $array_data, 'save_widget' );
				$success  = ! empty( $response['success'] ) ? $response['success'] : false;

				if ( empty( $success ) ) {
					$massage = ! empty( $response['massage'] ) ? $response['massage'] : esc_html__( 'server error', 'wdesignkit' );

					$result = (object) array(
						'success'     => false,
						'message'     => esc_html__( 'Widget Not Deleted', 'wdesignkit' ),
						'description' => esc_html__( 'Widget Not Deleted', 'wdesignkit' ),
					);

					wp_send_json( $result );
					wp_die();
				}
			}

			$dir_name    = isset( $data->name ) ? sanitize_text_field( $data->name ) : '';
			$widget_type = isset( $data->builder ) ? sanitize_text_field( $data->builder ) : '';

			// Same missing guards as wkit_create_widget, but the sink here is a RECURSIVE rmdir:
			// sanitize_text_field() leaves traversal intact, so a crafted name/builder could
			// delete any directory the web user owns (CWE-22, ClickUp 86d41cckh). Require a
			// builder from the allowlist and a name that is a single path segment.
			$safe_path = wdesignkit_widget_path_guard( $widget_type, $dir_name );
			if ( false === $safe_path || '' === $safe_path['folder'] ) {
				wp_send_json(
					(object) array(
						'success'     => false,
						'message'     => esc_html__( 'Widget Not Deleted', 'wdesignkit' ),
						'description' => esc_html__( 'Invalid widget path.', 'wdesignkit' ),
					)
				);
				wp_die();
			}

			$widget_type = $safe_path['builder'];
			$dir         = $safe_path['dir'];

			require_once ABSPATH . 'wp-admin/includes/file.php';
			global $wp_filesystem;
			WP_Filesystem();

			// Remove only a directory that resolves inside the builder path — the containment
			// re-check also rules out a symlinked folder. A missing directory is not an error:
			// a 'plugin_server' delete legitimately has no local folder, and the server call
			// above has already succeeded, so skip the removal and report success as before.
			if ( is_dir( $dir ) && wdesignkit_path_inside_builder_dir( $dir ) ) {
				$wp_filesystem->rmdir( $dir, true );
			}

			if ( function_exists( 'wdesignkit_invalidate_widget_registry' ) ) {
				wdesignkit_invalidate_widget_registry( $widget_type );
			}

			if ( 'plugin_server' === $delete_type ) {
				wp_send_json( $response['data'] );
				wp_die();
			} else {
				$result = (object) array(
					'success'     => true,
					'message'     => esc_html__( 'Widget Deleted', 'wdesignkit' ),
					'description' => esc_html__( 'Your widget has been deleted successfully.', 'wdesignkit' ),
				);

				return $result;
			}
		}

		/**
		 *
		 * It is Use for Check Widegt live preview
		 *
		 * @since 1.1.19
		 */
		public function wkit_widget_preview() {

			$widget_data = !empty( $_POST['widget_data'] ) ? json_decode(stripslashes($_POST['widget_data']), true) : '';

			if ( empty( $widget_data ) ) {
				$response = array(
					'success'     => true,
					'message'     => esc_html__( 'Invalid widget data', 'wdesignkit' ),
					'description' => esc_html__( 'Invalid widget data', 'wdesignkit' ),
				);

				wp_send_json($response);
				wp_die();
			}

			$widget_name = !empty( $widget_data['widget_name'] ) ? sanitize_text_field( $widget_data['widget_name'] ) : ''; 
			$widget_id   = !empty( $widget_data['widget_id'] ) ? sanitize_title($widget_data['widget_id']) : '';
			$widget_type = !empty( $widget_data['widget_type'] ) ? sanitize_key($widget_data['widget_type']) : '';
			$page_data =  !empty( $widget_data['page_data'] ) ? sanitize_key($widget_data['page_data']) : '';

			if ( $widget_type == "gutenberg_core" ){
				$widget_type = "gutenberg";
			}
		
			if ( 'elementor' === $widget_type ) {
				$existing_page = get_posts([
					'post_type'      => 'page',
					'meta_key'       => '_wkit_preview_widget_id',
					'meta_value'     => $widget_id,
					'posts_per_page' => 1,
				]);

				if ( !empty( $existing_page ) ) {
					$page_id = $existing_page[0]->ID;
				} else {
					$page_id = wp_insert_post([
						'post_title'   => $widget_name . '-Preview',
						'post_status'  => 'publish',
						'post_type'    => 'page',
						'post_name'    => $widget_id,
						'post_content' => '',
						'meta_input'   => [
							'_is_preview_page'     => true,
							'_wkit_preview_widget_id' => $widget_id,
							'_elementor_edit_mode' => 'builder',
							'_wp_page_template'    => 'elementor_canvas',
						],
					]);
				}
		
				$this->wdkit_update_elementor_data($page_id, $page_data, $widget_id, $widget_name);
		
				if (class_exists('\Elementor\Plugin')) {
					\Elementor\Plugin::$instance->files_manager->clear_cache($page_id);
					\Elementor\Plugin::$instance->files_manager->generate_css($page_id);
				}
		
				$preview_url = admin_url('post.php?post=' . $page_id . '&action=elementor');
			} else if ( "gutenberg" === $widget_type ) {
				$existing_page = get_posts([
					'post_type'      => 'page',
					'meta_key'       => '_wkit_preview_widget_id',
					'meta_value'     => $widget_id,
					'posts_per_page' => 1,
				]);
			
				if ( !empty( $existing_page ) ) {
					$page_id = $existing_page[0]->ID;
				} else {
					$post_name = wp_unique_post_slug($widget_id, 0, 'publish', 'page', 0);

					$page_id = wp_insert_post([
						'post_title'   => $widget_name . ' - Preview',
						'post_status'  => 'publish',
						'post_type'    => 'page',
						'post_name'    => sanitize_title($post_name),
						'post_content' => '',
						'meta_input'   => [
							'gutenberg_preview'  => true,
							'_wkit_preview_widget_id' => $widget_id,
							'_wp_page_template'  => 'default',
						],
					]);
			
					if ( is_wp_error($page_id) || !$page_id ) {						
						$response = array(
							'success'     => true,
							'message'     => esc_html__( 'Page Not Found!', 'wdesignkit' ),
							'description' => esc_html__( 'Page Not Found!', 'wdesignkit' ),
						);

						wp_send_json($response);
						wp_die();
					}
			
					update_post_meta($page_id, '_edit_lock', time() . ':1');
					update_post_meta($page_id, '_edit_last', get_current_user_id());
				}
			
				if (!function_exists('serialize_blocks')) {
					$response = array(
						'success'     => true,
						'message'     => esc_html__( 'Invalid serialize_blocks', 'wdesignkit' ),
						'description' => esc_html__( 'Invalid serialize_blocks', 'wdesignkit' ),
					);
	
					wp_send_json($response);
					wp_die();
				}
			
				$blocks = [
					[
						'blockName'    => 'wdkit/' . $page_data,
						'attrs'        => [],
						'innerHTML'    => '',
						'innerContent' => [],
					]
				];
			
				$updated_content = serialize_blocks($blocks);
			
				wp_update_post([
					'ID'           => $page_id,
					'post_content' => $updated_content,
				]);
			
				$preview_url = admin_url('post.php?post=' . $page_id . '&action=edit');
			} else {
				$result = (object) array(
					'success'     => true,
					'message'     => esc_html__( 'widget Type Not Found', 'wdesignkit' ),
					'description' => esc_html__( 'widget Type Not Found', 'wdesignkit' ),
				);

				// Bug G fix: $response was undefined here — should send $result (set 3 lines above).
				wp_send_json($result);
				wp_die();
			}
				
			$response = array(
				'success' => true,
				'preview_url' => $preview_url
			);

			wp_send_json($response);
			wp_die();
		}

		/**
		 * Check widget versions by r_id
		 *
		 * @since 2.1.6
		 */
		public function wkit_check_widget_versions() {
			$r_ids = isset( $_POST['r_ids'] ) ? sanitize_text_field( wp_unslash( $_POST['r_ids'] ) ) : '';
			$token = isset( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '';

			if ( empty( $r_ids ) ) {
				$response = array(
					'success' => false,
					'message' => esc_html__( 'No widget IDs provided', 'wdesignkit' ),
					'description' => esc_html__( 'Please provide widget r_id values', 'wdesignkit' ),
					'versions' => array(),
				);

				wp_send_json( $response );
				wp_die();
			}

			$array_data = array(
				'id' => $r_ids,
				'token' => $token,
			);

			$response = $this->wkit_api_call( $array_data, 'widget/version/get' );
			$success  = ! empty( $response['success'] ) ? $response['success'] : false;

			if ( empty( $success ) ) {
				$massage = ! empty( $response['massage'] ) ? $response['massage'] : esc_html__( 'Server error', 'wdesignkit' );

				$result = array(
					'success'     => false,
					'message'     => $massage,
					'description' => esc_html__( 'Failed to check widget versions', 'wdesignkit' ),
					'versions'    => array(),
				);

				wp_send_json( $result );
				wp_die();
			}

			$versions = json_decode( wp_json_encode( $response['data'] ), true );

			$result = array(
				'success'     => true,
				'message'     => esc_html__( 'Version check completed', 'wdesignkit' ),
				'description' => esc_html__( 'Widget versions retrieved successfully', 'wdesignkit' ),
				'versions'    => ! empty( $versions ) ? $versions : array(),
			);

			wp_send_json($result);
			wp_die();
		}
		public function wdkit_update_elementor_data($page_id, $page_data, $widget_id, $widget_name) {
			$experiments_manager = Elementor\Plugin::$instance->experiments;

        	if( $experiments_manager->is_feature_active( 'container' ) ) {
				$elementor_data = [
					[
						'id'        => 'container_' . wp_generate_uuid4(),
						'elType'    => 'container',
						'settings'  => [],
						'elements'  => [
							[
								'id'         => 'widget_' . wp_generate_uuid4(),
								'elType'     => 'widget',
								'widgetType' => $page_data,
								'settings'   => [
									'title'     => $widget_name,
									'widget_id' => $widget_id,
								],
							],
						],
					],
				];
			} else {
				$elementor_data = [
					[
						'id'        => 'section_' . wp_generate_uuid4(),
						'elType'    => 'section',
						'settings'  => [],
						'elements'  => [
							[
								'id'       => 'column_' . wp_generate_uuid4(),
								'elType'   => 'column',
								'settings' => [],
								'elements' => [
									[
										'id'         => 'widget_' . wp_generate_uuid4(),
										'elType'     => 'widget',
										'widgetType' => $page_data,
										'settings'   => [
											'title'     => $widget_name,
											'widget_id' => $widget_id,
										],
									],
								],
							],
						],
					],
				];
			}
			
			update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($elementor_data)));
			update_post_meta($page_id, '_elementor_edit_mode', 'builder');
			update_post_meta($page_id, '_wp_page_template', 'elementor_canvas');
			
		}
		/* All below functions are helper functions for this file */

		/**
		 *
		 * This Function is used for API call
		 *
		 * @since 1.1.4
		 *
		 * @param array $data give array.
		 * @param array $name store data.
		 */
		public function wkit_api_call( $data, $name, $base = '' ) {
			$u_r_l = ! empty( $base ) ? $base : $this->wdkit_api;

			if ( empty( $u_r_l ) ) {
				return array(
					'massage' => esc_html__( 'API Not Found', 'wdesignkit' ),
					'success' => false,
				);
			}

			$args     = array(
				'method'  => 'POST',
				'body'    => $data,
				'timeout' => 100,
			);
			$response = wp_remote_post( $u_r_l . $name, $args );

			if ( is_wp_error( $response ) ) {
				$error_message = $response->get_error_message();

				/* Translators: %s is a placeholder for the error message */
				$error_message = sprintf( esc_html__( 'API request error: %s', 'wdesignkit' ), esc_html( $error_message ) );

				return array(
					'massage' => $error_message,
					'success' => false,
				);
			}

			$status_code = wp_remote_retrieve_response_code( $response );
			if ( 200 === $status_code ) {

				return array(
					'data'    => json_decode( wp_remote_retrieve_body( $response ) ),
					'massage' => esc_html__( 'Success', 'wdesignkit' ),
					'status'  => $status_code,
					'success' => true,
				);
			}

			$error_message = sprintf( 'Server error: %d', esc_html( $status_code ) );

			if ( isset( $error_data->message ) ) {
				$error_message .= ' (' . $error_data->message . ')';
			}

			return array(
				'massage' => $error_message,
				'status'  => $status_code,
				'success' => false,
			);
		}

		/**
		 *
		 * Custom_upload_dir
		 *
		 * @since 1.1.4
		 *
		 * @param array $upload store data.
		 */
		public function custom_upload_dir( $upload ) {
			// Specify the path to your custom upload directory.
			if ( isset( $this->widget_folder_u_r_l ) && ! empty( $this->widget_folder_u_r_l ) ) {

				// Set the custom directory as the upload path.
				$upload['path'] = $this->widget_folder_u_r_l;
				// Set the URL for the uploaded file.
				$upload['url'] = $upload['baseurl'] . $upload['subdir'];
			}

			return $upload;
		}

		/**
		 * Parse args $_POST
		 *
		 * @since 1.1.1
		 *
		 * @param string $data send all post data.
		 * @param string $type store text data.
		 * @param string $condition store text data.
		 */

		public function wdkit_extract_post_field( $data, $type, $condition = 'none' ) {

			if ( 'none' === $condition ) {
				return $data[ $type ];
			} elseif ( 'cr_widget' === $condition ) {
				return base64_decode($data[ $type ]);
			}

			return null;
		}

		/**
		 * Parse args $_POST
		 *
		 * @since 1.1.4
		 *
		 * @param string $data send all post data.
		 * @param string $type store text data.
		 * @param string $condition store text data.
		 */
		public function wdkit_file_sanitizer_bypass( $data, $type, $condition = 'none' ) {

			if ( 'name' === $condition ) {
				return wp_normalize_path( $data[ $type ]['tmp_name'] );
			}
		}

		/**
		 * Get list local Widget List
		 *
		 * @since 1.1.4
		 */
		public function wdkit_get_local_widgets() {
			$builder       = array();
			$a_c_s_d_s_c   = array();
			$j_s_o_n_array = array();

			if ( Wdkit_Wdesignkit::wdkit_is_compatible( 'bricks', 'widget' ) ) {
				array_push( $builder, 'bricks' );
			}

			if ( Wdkit_Wdesignkit::wdkit_is_compatible( 'elementor', 'widget' ) ) {
				array_push( $builder, 'elementor' );
			}

			if ( Wdkit_Wdesignkit::wdkit_is_compatible( 'gutenberg', 'widget' ) ) {
				array_push( $builder, 'gutenberg' );
			}

			foreach ( $builder as $key => $name ) {
				$elementor_dir = WDKIT_BUILDER_PATH . '/' . $name;

				if ( ! empty( $elementor_dir ) && is_dir( $elementor_dir ) ) {
					$elementor_list = scandir( $elementor_dir );
					$elementor_list = array_diff( $elementor_list, array( '.', '..' ) );

					if ( ! empty( $elementor_list ) ) {
						foreach ( $elementor_list as $key => $value ) {
							$a_c_s_d_s_c[ filemtime( "{$elementor_dir}/{$value}" ) ]['data']    = $value;
							$a_c_s_d_s_c[ filemtime( "{$elementor_dir}/{$value}" ) ]['builder'] = $name;
						}
					}
				}
			}

			ksort( $a_c_s_d_s_c );
			$a_c_s_d_s_c = array_reverse( $a_c_s_d_s_c );

			foreach ( $a_c_s_d_s_c as $key => $value ) {
				$elementor_dir = WDKIT_BUILDER_PATH . '/' . $value['builder'];

				if ( file_exists( "{$elementor_dir}/{$value['data']}" ) && is_dir( "{$elementor_dir}/{$value['data']}" ) ) {
					$sub_dir = scandir( "{$elementor_dir}/{$value['data']}" );
					$sub     = array_diff( $sub_dir, array( '.', '..' ) );

					foreach ( $sub as $sub_dir_value ) {
						$file      = new SplFileInfo( $sub_dir_value );
						$check_ext = $file->getExtension();
						$ext       = pathinfo( $sub_dir_value, PATHINFO_EXTENSION );

						if ( 'json' === $ext ) {
							$widget1     = WDKIT_BUILDER_PATH . "/{$value['builder']}/{$value['data']}/{$sub_dir_value}";
							$filedata    = wp_json_file_decode( $widget1 );
							$decode_data = json_decode( wp_json_encode( $filedata ), true );
							array_push( $j_s_o_n_array, $decode_data['widget_data'] );
						}
					}
				}
			}

			return $j_s_o_n_array;
		}

		/**
		 * Error JSON message
		 *
		 * @param array $data give array.
		 *
		 * @since 1.1.4
		 * */
		public function wdkit_error_msg( $data = null ) {
			wp_send_json_error( $data );
			wp_die();
		}

		/**
		 * Create Uniq name
		 *
		 * @since 1.1.4
		 */
		public function wdkit_generate_unique_id() {
			$now        = new DateTime();
			$unique_i_d = $now->format( 'YmdHis' );
			$hashed_i_d = (int) $unique_i_d % 10000;
			return str_pad( $hashed_i_d, 4, '0', STR_PAD_LEFT );
		}
	}

	Wdkit_Widget_Ajax::get_instance();
}
```
