PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.13.3
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.13.3
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
← All changes | admin/modules/setup-wizard/setup-wizard.php +252 -13 2.8.16 → 3.13.3 View file →
@@ -7,8 +7,9 @@
7 7
8 8 namespace WPFunnels\Admin;
9 9
10 10 use WPFunnels\Traits\SingletonTrait;
11 +use WPFunnels\Wpfnl_functions;
11 12
12 13 class SetupWizard
13 14 {
14 15 use SingletonTrait;
@@ -23,8 +24,155 @@
23 24 $this->setup_wizard();
24 25 }
25 26
26 27 /**
28 + * Register AJAX handlers
29 + * This should be called early, not just when rendering the wizard
30 + *
31 + * @since 3.3.1
32 + */
33 + public static function register_ajax_handlers() {
34 + add_action('wp_ajax_wpfnl_activate_plugin', array(__CLASS__, 'ajax_activate_plugin_static'));
35 + add_action('wp_ajax_wpfnl_update_step_meta', array(__CLASS__, 'ajax_update_step_meta'));
36 + add_action('wp_ajax_wpfnl_activate_mail_mint', array(__CLASS__, 'ajax_activate_mail_mint'));
37 + }
38 +
39 + /**
40 + * AJAX handler for updating step meta
41 + *
42 + * @since 3.3.1
43 + */
44 + public static function ajax_update_step_meta() {
45 + // Check user capabilities
46 + if (!current_user_can('wpf_manage_funnels')) {
47 + wp_send_json_error(array('message' => 'Insufficient permissions'));
48 + wp_die();
49 + }
50 +
51 + $step_id = isset($_POST['step_id']) ? absint($_POST['step_id']) : 0;
52 + $meta_key = isset($_POST['meta_key']) ? sanitize_text_field($_POST['meta_key']) : '';
53 + $meta_value = isset($_POST['meta_value']) ? $_POST['meta_value'] : '';
54 +
55 + if (!$step_id || !$meta_key) {
56 + wp_send_json_error(array('message' => 'Invalid parameters'));
57 + wp_die();
58 + }
59 +
60 + // Decode JSON if it's a JSON string
61 + if (is_string($meta_value) && (substr($meta_value, 0, 1) === '{' || substr($meta_value, 0, 1) === '[')) {
62 + $decoded = json_decode(stripslashes($meta_value), true);
63 + if (json_last_error() === JSON_ERROR_NONE) {
64 + $meta_value = $decoded;
65 + }
66 + }
67 +
68 + update_post_meta($step_id, $meta_key, $meta_value);
69 +
70 + wp_send_json_success(array(
71 + 'message' => 'Meta updated successfully',
72 + 'step_id' => $step_id,
73 + 'meta_key' => $meta_key
74 + ));
75 + wp_die();
76 + }
77 +
78 + /**
79 + * Static AJAX handler for plugin activation
80 + *
81 + * @since 3.3.1
82 + */
83 + public static function ajax_activate_plugin_static() {
84 + // Check user capabilities first
85 + if (!current_user_can('activate_plugins')) {
86 + wp_send_json_error(array('message' => 'Insufficient permissions'));
87 + wp_die();
88 + }
89 +
90 + // Get the plugin parameter
91 + $plugin = isset($_POST['plugin']) ? sanitize_text_field($_POST['plugin']) : '';
92 +
93 + if (empty($plugin)) {
94 + wp_send_json_error(array('message' => 'Plugin parameter is required'));
95 + wp_die();
96 + }
97 +
98 + // Check if plugin file exists
99 + $plugin_file = WP_PLUGIN_DIR . '/' . $plugin;
100 + if (!file_exists($plugin_file)) {
101 + wp_send_json_error(array('message' => 'Plugin file not found: ' . $plugin));
102 + wp_die();
103 + }
104 +
105 + // Check if already active
106 + if (is_plugin_active($plugin)) {
107 + wp_send_json_success(array('message' => 'Plugin is already active'));
108 + wp_die();
109 + }
110 +
111 + // Activate the plugin
112 + $result = activate_plugin($plugin, '', false, true);
113 +
114 + if (is_wp_error($result)) {
115 + wp_send_json_error(array('message' => $result->get_error_message()));
116 + wp_die();
117 + }
118 +
119 + // Special handling for WooCommerce
120 + if (strpos($plugin, 'woocommerce') !== false) {
121 + delete_transient('_wc_activation_redirect');
122 + }
123 +
124 + // Special handling for Elementor
125 + if (strpos($plugin, 'elementor') !== false) {
126 + update_option('elementor_onboarded', true);
127 + }
128 +
129 + wp_send_json_success(array('message' => 'Plugin activated successfully', 'plugin' => $plugin));
130 + wp_die();
131 + }
132 +
133 + /**
134 + * AJAX handler for Mail Mint activation with explicit database initialization
135 + * This ensures Mail Mint databases are created even on PHP 7.4
136 + *
137 + * @since 3.3.1
138 + */
139 + public static function ajax_activate_mail_mint() {
140 + // Check user capabilities first
141 + if (!current_user_can('activate_plugins')) {
142 + wp_send_json_error(array('message' => 'Insufficient permissions'));
143 + wp_die();
144 + }
145 +
146 + // Activate the Mail Mint plugin
147 + $mail_mint_plugin = 'mail-mint/mail-mint.php';
148 +
149 + if (!is_plugin_active($mail_mint_plugin)) {
150 + $result = activate_plugin($mail_mint_plugin, '', false, true);
151 +
152 + if (is_wp_error($result)) {
153 + wp_send_json_error(array('message' => $result->get_error_message()));
154 + wp_die();
155 + }
156 + }
157 +
158 + // Explicitly trigger Mail Mint activation logic to ensure database creation
159 + $mail_mint_file = WP_PLUGIN_DIR . '/' . $mail_mint_plugin;
160 + if (file_exists($mail_mint_file)) {
161 + require_once WP_PLUGIN_DIR . '/mail-mint/includes/MrmActivator.php';
162 +
163 + // Call the activation method directly to ensure databases are created
164 + \MrmActivator::activate();
165 +
166 + // Remove the Mail Mint setup wizard transient to prevent it from showing
167 + delete_transient('mailmint_show_setup_wizard');
168 + }
169 +
170 + wp_send_json_success(array('message' => 'Mail Mint activated and initialized successfully'));
171 + wp_die();
172 + }
173 +
174 + /**
27 175 * Initialize setup wizards
28 176 *
29 177 * @since 1.0.0
30 178 */
@@ -29,9 +177,8 @@
29 177 * @since 1.0.0
30 178 */
31 179 private function setup_wizard()
32 180 {
33 -
34 181 $steps = array(
35 182 'type' => array(
36 183 'name' => 'Funnel Type',
37 184 'slug' => 'funnel-type',
@@ -89,19 +236,42 @@
89 236 }
90 237 }
91 238 $installed_plugins = get_plugins();
92 239
240 + $product_url = esc_url_raw(
241 + add_query_arg(
242 + array(
243 + 'post_type' => 'product',
244 + 'wpfunnels' => 'yes',
245 + ),
246 + admin_url('post-new.php')
247 + )
248 + );
249 +
250 + // Admin Name & Email Finding Starts
251 + $admin_email = get_option('admin_email');
252 + $admin_user = get_user_by('email', $admin_email);
253 + $admin_name = $admin_user ? $admin_user->display_name : '';
254 + // Admin Name & Email Finding Ends
255 +
93 256 wp_enqueue_style('setup-wizard', WPFNL_URL . 'admin/assets/css/wpfnl-admin.css', false, '1.1', 'all');
94 257 wp_enqueue_script('setup-wizard-runtime', WPFNL_URL . 'admin/assets/dist/runtime/index.min.js', array(), time(), true);
95 258 wp_enqueue_script('setup-wizard', WPFNL_URL . 'admin/assets/dist/js/setup-wizard.min.js', array('jquery', 'wp-util', 'updates', 'setup-wizard-runtime'), time(), true);
259 + Wpfnl_functions::enqueue_bundle_style( 'setup-wizard', 'setup-wizard-bundle' );
96 260 wp_localize_script('setup-wizard', 'setup_wizard_obj',
97 261 array(
98 262 'rest_api_url' => esc_url_raw(get_rest_url()),
263 + 'ajax_url' => esc_url_raw(admin_url('admin-ajax.php')),
264 + 'admin_url' => esc_url_raw(admin_url()),
99 265 'dashboard_url' => esc_url_raw(admin_url('admin.php?page=' . WPFNL_MAIN_PAGE_SLUG)),
100 266 'settings_url' => class_exists( 'WooCommerce' ) ? esc_url_raw(admin_url('admin.php?page=wpfnl_settings')) : esc_url_raw(admin_url()),
101 267 'wizard_url' => esc_url_raw(admin_url('admin.php?page=wpfunnels-setup')),
102 268 'home_url' => esc_url_raw(home_url()),
103 269 'nonce' => wp_create_nonce('wp_rest'),
270 + 'product_url' => $product_url,
271 + 'admin_nonce' => wp_create_nonce('wpfnl-admin'),
272 + 'currency_symbol' => class_exists( 'WooCommerce' ) ? get_woocommerce_currency_symbol() : '$',
273 + 'currency_position' => class_exists( 'WooCommerce' ) ? get_option('woocommerce_currency_pos', 'left') : 'left',
104 274 'current_step' => $this->step_name,
105 275 'steps' => $this->steps,
106 276 'next_step_link' => $this->get_next_step_link(),
107 277 'prev_step_link' => $this->get_prev_step_link(),
@@ -117,31 +287,100 @@
117 287 'is_mrm_active' => is_plugin_active( 'mail-mint/mail-mint.php' ) ? 'yes' : 'no',
118 288 'is_ff_active' => is_plugin_active( 'fluentform/fluentform.php' ) ? 'yes' : 'no',
119 289 'is_cl_active' => is_plugin_active( 'cart-lift/cart-lift.php' ) ? 'yes' : 'no',
120 290 'is_qb_active' => is_plugin_active( 'qubely/qubely.php' ) ? 'yes' : 'no',
121 - 'funnel_type' => $this->get_funnel_type()
291 + 'is_pro_active' => Wpfnl_functions::is_wpfnl_pro_activated() ? 'yes' : 'no',
292 + 'getPlugins' => $this->get_essential_plugins(),
293 + 'defaultSettings' => Wpfnl_functions::get_general_settings(),
294 + 'logo_url' => WPFNL_URL .'admin/assets/images/setup-funnel-logo.png',
295 + 'welcome_image' => WPFNL_URL .'admin/assets/images/welcome-image.png',
296 + 'gb_builder_img' => WPFNL_URL .'admin/assets/images/gutenberg.png',
297 + 'elementor_img' => WPFNL_URL .'admin/assets/images/elementor.png',
298 + 'oxygen_img' => WPFNL_URL .'admin/assets/images/oxygen.png',
299 + 'divi_img' => WPFNL_URL .'admin/assets/images/divi.png',
300 + 'bricks_img' => WPFNL_URL .'admin/assets/images/bricks.png',
301 + 'others_builder_img' => WPFNL_URL .'admin/assets/images/others.png',
302 + 'wc_logo' => WPFNL_URL .'admin/assets/images/wc-logo.png',
303 + 'mail_mint_logo' => WPFNL_URL .'admin/assets/images/mail-mint.png',
304 + 'wizard_video_poster' => WPFNL_URL .'admin/assets/images/setup-wizard-done-video-poster.png',
305 + 'no_plugin_image' => WPFNL_URL .'admin/assets/images/no-plugin-install.png',
306 + 'qubely_img' => WPFNL_URL .'admin/assets/images/qubely.svg',
307 + 'quote_img' => WPFNL_URL .'admin/assets/images/quote-icon.svg',
308 + 'done_icon' => WPFNL_URL .'admin/assets/images/done-icon.svg',
309 + 'generate_funnel_image' => WPFNL_URL .'admin/assets/images/generate-funnel-image.webp',
310 + 'generate_store_image' => WPFNL_URL .'admin/assets/images/generate-store-checkout.webp',
311 + 'admin_email' => $admin_email,
312 + 'admin_name' => $admin_name,
122 313 )
123 314 );
124 -
125 315 $this->output_html();
126 316 }
127 317
128 318
129 319 /**
130 - * Get funnel type
320 + * Get essential plugins for WPFunnels
131 321 *
132 - * @since 2.5.3
322 + * @return array
323 + * @since 3.3.1
133 324 */
134 - private function get_funnel_type(){
135 - $general_settings = get_option( '_wpfunnels_general_settings' );
136 - if( isset($general_settings['funnel_type']) ){
137 - if( 'woocommerce' == $general_settings['funnel_type'] ){
138 - return 'sales';
139 - }
140 - return $general_settings['funnel_type'];
325 + public function get_essential_plugins(){
326 + $plugins = [
327 + ['name' => 'wc', 'slug' => 'woocommerce', 'type' => 'plugin', 'constant' => 'WC_PLUGIN_FILE', 'path' => 'woocommerce/woocommerce.php'],
328 + ['name' => 'mailmint', 'slug' => 'mail-mint', 'type' => 'plugin', 'constant' => 'MRM_VERSION', 'path' => 'mail-mint/mail-mint.php'],
329 + ['name' => 'elementor', 'slug' => 'elementor', 'type' => 'plugin', 'constant' => 'ELEMENTOR_VERSION', 'path' => 'elementor/elementor.php'],
330 + ['name' => 'qubely', 'slug' => 'qubely', 'type' => 'plugin', 'constant' => 'QUBELY_VERSION', 'path' => 'qubely/qubely.php'],
331 + ['name' => 'divi', 'slug' => 'divi-builder', 'type' => 'plugin', 'constant' => 'ET_BUILDER_PLUGIN_VERSION', 'path' => 'divi-builder/divi-builder.php']
332 + ];
333 +
334 + foreach($plugins as &$plugin) {
335 + $plugin['status'] = $this->get_plugin_status($plugin['constant'], $plugin['path']);
141 336 }
142 - return 'sales';
337 +
338 + $oxygen_status = 'uninstalled';
339 + if (Wpfnl_functions::is_plugin_activated('oxygen/functions.php')) {
340 + $oxygen_status = 'activated';
341 + } else if (Wpfnl_functions::is_plugin_installed('oxygen/functions.php')) {
342 + $oxygen_status = 'installed';
343 + }
344 + $plugins[] = ['name' => 'oxygen', 'slug' => 'oxygen', 'type' => 'plugin', 'path' => 'oxygen/functions.php', 'status' => $oxygen_status];
345 +
346 + $maybe_bricks = Wpfnl_functions::maybe_bricks_theme();
347 + $bricks_status = $maybe_bricks ? 'activated' : 'uninstalled';
348 + if (Wpfnl_functions::maybe_theme_installed('bricks') && !$maybe_bricks ) {
349 + $bricks_status = 'installed';
350 + }
351 + $plugins[] = ['name' => 'bricks', 'slug' => 'bricks', 'type' => 'theme', 'path' => 'bricks', 'status' => $bricks_status];
352 +
353 + $is_divi_theme_active = Wpfnl_functions::wpfnl_is_theme_active('Divi');
354 + $divi_status = $is_divi_theme_active ? 'activated' : 'uninstalled';
355 + if (Wpfnl_functions::maybe_theme_installed('Divi') && !$is_divi_theme_active ) {
356 + $divi_status = 'installed';
357 + }
358 + $plugins[] = ['name' => 'divi', 'slug' => 'divi', 'type' => 'theme', 'path' => 'Divi', 'status' => $divi_status];
359 +
360 + return $plugins;
143 361 }
362 +
363 + /**
364 + * Get plugin status
365 + *
366 + * @param string $constant
367 + * @param string $path
368 + * @return string
369 + * @since 3.3.1
370 + */
371 + public function get_plugin_status($constant, $path) {
372 + $installed_plugins = get_plugins();
373 + if(defined($constant)){
374 + return 'activated';
375 + } else if(isset($installed_plugins[$path])) {
376 + return 'installed';
377 + } else {
378 + return 'uninstalled';
379 + }
380 + }
381 +
382 +
144 383
145 384
146 385
147 386