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 | includes/core/rest-api/Controllers/DashboardController.php +106 -3 3.12.11 → 3.13.3 View file →
@@ -16,8 +16,19 @@
16 16 class DashboardController extends Wpfnl_REST_Controller
17 17 {
18 18
19 19 /**
20 + * Transient holding the last known answer to "is the onboarding checklist
21 + * on show?", read by the admin page so it can decide whether to hold space
22 + * for it while the real status loads.
23 + *
24 + * @var string
25 + * @since 3.13.3
26 + */
27 + const ONBOARDING_VISIBILITY_KEY = 'wpfnl_onboarding_should_show';
28 +
29 +
30 + /**
20 31 * Endpoint namespace.
21 32 *
22 33 * @var string
23 34 * @since 3.2.0
@@ -181,8 +192,19 @@
181 192 }
182 193
183 194
184 195 /**
196 + * Cache payload version. Bump whenever the shape or the meaning of a cached
197 + * report response changes, so entries written by an older build are ignored
198 + * instead of served until they expire.
199 + *
200 + * @var string
201 + * @since 3.13.0
202 + */
203 + const CACHE_VERSION = 'v2';
204 +
205 +
206 + /**
185 207 * Build a cache key from a prefix and parameter array.
186 208 *
187 209 * @param string $prefix
188 210 * @param array $params
@@ -190,9 +212,9 @@
190 212 *
191 213 * @since 3.9.6
192 214 */
193 215 protected function get_cache_key( $prefix, $params ) {
194 - return 'wpfnl_dash_' . $prefix . '_' . md5( serialize( $params ) );
216 + return 'wpfnl_dash_' . $prefix . '_' . self::CACHE_VERSION . '_' . md5( serialize( $params ) );
195 217 }
196 218
197 219
198 220 /**
@@ -288,8 +310,31 @@
288 310 }
289 311
290 312
291 313 /**
314 + * Remember whether the checklist was on show, for the next page load.
315 + *
316 + * Working this out costs several queries, so the admin page cannot ask
317 + * before it prints — but it can read the last answer. The React dashboard
318 + * uses it for one thing: whether to hold space for the checklist while the
319 + * real status loads. Someone who is done with onboarding then sees no
320 + * placeholder at all, instead of a skeleton that resolves to nothing.
321 + *
322 + * Short lived on purpose: it only has to outlive the gap between one page
323 + * load and the next, and a stale answer costs at most one wrong placeholder.
324 + *
325 + * @param bool $is_visible Whether the checklist is on show.
326 + *
327 + * @return void
328 + * @since 3.13.3
329 + */
330 + private function remember_onboarding_visibility( $is_visible )
331 + {
332 + set_transient( self::ONBOARDING_VISIBILITY_KEY, $is_visible ? 'yes' : 'no', 15 * MINUTE_IN_SECONDS );
333 + }
334 +
335 +
336 + /**
292 337 * Get onboarding status.
293 338 *
294 339 * Determines whether the onboarding section should be shown on the dashboard.
295 340 * The onboarding is hidden when ALL three conditions are met:
@@ -306,8 +351,10 @@
306 351 {
307 352 // ── Check if onboarding has been dismissed ──
308 353 $is_dismissed = get_transient( 'wpfnl_onboarding_dismissed' );
309 354 if ( $is_dismissed ) {
355 + $this->remember_onboarding_visibility( false );
356 +
310 357 return rest_ensure_response( array(
311 358 'success' => true,
312 359 'show_onboarding' => false,
313 360 'steps' => array(),
@@ -427,8 +474,61 @@
427 474 }
428 475 }
429 476 }
430 477
478 + // ── Build the checklist deep links ──
479 + // The checklist actions should drop the user into the place where the step
480 + // actually gets done, rather than the funnel list: the order bump tab of the
481 + // newest funnel's checkout step, and the canvas of that funnel for the upsell.
482 + // Drafts count too — a funnel does not need to be live to be worked on.
483 + $order_bump_url = '';
484 + $funnel_builder_url = '';
485 + $recent_funnels = get_posts(array(
486 + 'post_type' => WPFNL_FUNNELS_POST_TYPE,
487 + 'post_status' => array('publish', 'draft'),
488 + 'numberposts' => 10,
489 + 'orderby' => 'date',
490 + 'order' => 'DESC',
491 + 'fields' => 'ids',
492 + 'meta_query' => $exclude_sc_meta,
493 + ));
494 +
495 + if (!empty($recent_funnels)) {
496 + // The upsell step is added on the canvas, so that is where its action goes.
497 + $funnel_builder_url = admin_url(
498 + sprintf('admin.php?page=edit_funnel&id=%d', $recent_funnels[0])
499 + );
500 + }
501 +
502 + foreach ($recent_funnels as $recent_funnel_id) {
503 + $recent_steps = Wpfnl_functions::get_steps($recent_funnel_id);
504 +
505 + if (!is_array($recent_steps) || empty($recent_steps)) {
506 + continue;
507 + }
508 +
509 + foreach ($recent_steps as $recent_step) {
510 + $recent_step_type = isset($recent_step['step_type']) ? $recent_step['step_type'] : '';
511 + $recent_step_id = isset($recent_step['id']) ? (int)$recent_step['id'] : 0;
512 +
513 + if ('checkout' !== $recent_step_type || !$recent_step_id) {
514 + continue;
515 + }
516 +
517 + // The hash is what tells the canvas which step settings drawer and
518 + // tab to open once the funnel editor has finished loading.
519 + $order_bump_url = admin_url(
520 + sprintf(
521 + 'admin.php?page=edit_funnel&id=%d&step_id=%d#%d/settings/order-bump/',
522 + $recent_funnel_id,
523 + $recent_step_id,
524 + $recent_step_id
525 + )
526 + );
527 + break 2;
528 + }
529 + }
530 +
431 531 // ── Step 3: Check for real orders through funnels ──
432 532 if ($is_wc_active && !empty($funnels)) {
433 533 global $wpdb;
434 534 $stats_table = $wpdb->prefix . 'wpfnl_stats';
@@ -452,11 +552,10 @@
452 552
453 553 // ── Build checklist step completion data ──
454 554 $completed_count = 0;
455 555 $steps_status = array(
456 - 'woocommerce_connected' => $is_wc_active,
556 + 'store_checkout_created' => $has_store_checkout_created,
457 557 'funnel_created' => $has_funnel_created,
458 - 'store_checkout_created' => $has_store_checkout_created,
459 558 'order_bump_added' => $has_order_bump,
460 559 'upsell_added' => $has_upsell,
461 560 'test_order_placed' => $has_real_order,
462 561 'funnel_live' => $has_live_funnel,
@@ -470,8 +569,10 @@
470 569
471 570 $total_steps = count($steps_status);
472 571 $progress_percent = $total_steps > 0 ? round(($completed_count / $total_steps) * 100) : 0;
473 572
573 + $this->remember_onboarding_visibility( !$should_hide_onboarding );
574 +
474 575 return rest_ensure_response(array(
475 576 'success' => true,
476 577 'show_onboarding' => !$should_hide_onboarding,
477 578 'steps' => $steps_status,
@@ -477,8 +578,10 @@
477 578 'steps' => $steps_status,
478 579 'completed_count' => $completed_count,
479 580 'total_steps' => $total_steps,
480 581 'progress_percent' => $progress_percent,
582 + 'order_bump_url' => $order_bump_url,
583 + 'funnel_builder_url' => $funnel_builder_url,
481 584 ));
482 585 }
483 586
484 587 /**