feat: add signup flow metrics and post-signup activity tracking#420
feat: add signup flow metrics and post-signup activity tracking#420superdav42 merged 4 commits intomainfrom
Conversation
📝 WalkthroughWalkthroughThese changes implement signup funnel event tracking and post-signup activity monitoring. A new Changes
Sequence DiagramsequenceDiagram
actor User
participant Checkout as Checkout Flow
participant Metrics as Signup_Metrics
participant DB as wu_events Table
participant Dashboard as Dashboard_Statistics
User->>Checkout: Load checkout page
Checkout->>Metrics: do_action('wu_checkout_before_render')
Metrics->>DB: Insert checkout_started event
User->>Checkout: Complete form steps
Checkout->>Metrics: do_action('wu_checkout_order_created')
Metrics->>DB: Insert checkout_step_completed event
User->>Checkout: Submit checkout
alt Checkout Success
Checkout->>Metrics: do_action('wu_checkout_success')
Metrics->>DB: Insert checkout_completed event
else Checkout Failed
Checkout->>Metrics: do_action('wu_checkout_error')
Metrics->>DB: Insert checkout_failed event
end
Dashboard->>DB: Query checkout_* events
Dashboard->>Dashboard: Calculate conversion_rate
Dashboard-->>User: Display funnel metrics
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
…#398) Implements two new tracking classes: - Signup_Metrics: hooks into the checkout lifecycle to record checkout_started, checkout_step_completed, checkout_completed, and checkout_failed events in the wu_events table. Each event type is also registered for webhooks and email triggers. - Activity_Tracker: hooks into sub-site WordPress actions to record site_post_published, site_user_registered, and site_woocommerce_order events for any customer-owned sub-site. Only tracks sites managed by WP Ultimo (via wu_get_site_by_blog_id). Dashboard_Statistics gains two new data methods: - get_data_signup_funnel(): returns per-stage counts + conversion rate - get_data_site_activity(): returns post/user/order counts per date range Both classes are wired up in class-wp-ultimo.php alongside the existing Tracker singleton. Tests cover singleton behaviour, event type registration, filter pass-through, and dashboard statistics key structure. Closes #297 Closes #398
…ty_Manager) Post_Signup_Activity_Manager was merged into main in #416 before this branch was rebased. Remove the duplicate Activity_Tracker class and its instantiation from class-wp-ultimo.php. Update Dashboard_Statistics::get_data_site_activity() to use the event slugs produced by Post_Signup_Activity_Manager (subsite_post_created, subsite_cpt_created, subsite_user_registered, subsite_woocommerce_order) instead of the now-removed Activity_Tracker slugs. Update Signup_Metrics_Test to match the corrected slugs.
b6a38b0 to
2da0041
Compare
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
|
[Pulse Supervisor] E2E checkout tests are failing on this PR but passing on main (run 23523339169). The regression was introduced by the metrics/Activity_Tracker changes. The 'Run Checkout Tests (After Setup)' step fails — please investigate whether the new metrics hooks interfere with the checkout flow (e.g., hooks firing during checkout that cause unexpected side effects). |
wu_checkout_errors is an action (not a filter) that fires with the checkout form name as a string argument (views/checkout/form.php:23). The previous implementation used add_filter and declared a return type of \WP_Error. When the action fired with a string argument, the method returned the string, causing a PHP TypeError (return type mismatch) that produced a fatal error on the /register page. Fix: - Change add_filter to add_action (correct hook type) - Change method signature to accept a string form name - Remove \WP_Error return type (void action callback) - Access checkout errors via Checkout::get_instance()->errors - Update test to verify string argument is accepted without error
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
inc/class-dashboard-statistics.php (1)
226-235: Consider combining queries for better performance.Each slug is queried individually, resulting in 4 separate database calls. While acceptable for dashboard use, this could be optimized into a single query with
GROUP BY.♻️ Optional: Single query with GROUP BY
- foreach ($slugs as $slug) { - $counts[ $slug ] = (int) $wpdb->get_var( - $wpdb->prepare( - "SELECT COUNT(*) FROM {$table} WHERE slug = %s AND date_created BETWEEN %s AND %s", - $slug, - $this->start_date, - $this->end_date - ) - ); - } + $placeholders = implode(',', array_fill(0, count($slugs), '%s')); + $query_args = array_merge($slugs, [$this->start_date, $this->end_date]); + + // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT slug, COUNT(*) as cnt FROM {$table} WHERE slug IN ({$placeholders}) AND date_created BETWEEN %s AND %s GROUP BY slug", + ...$query_args + ), + OBJECT_K + ); + + foreach ($slugs as $slug) { + $counts[ $slug ] = isset($results[ $slug ]) ? (int) $results[ $slug ]->cnt : 0; + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@inc/class-dashboard-statistics.php` around lines 226 - 235, The loop issues multiple DB calls: replace the per-slug $wpdb->get_var calls with one grouped query using $wpdb->prepare and IN(...) to fetch counts for all $slugs at once (e.g. SELECT slug, COUNT(*) FROM {$table} WHERE slug IN (...) AND date_created BETWEEN %s AND %s GROUP BY slug), then map the result rows back into $counts (ensuring every slug in $slugs gets an integer 0 if not returned); update the logic around $slugs, $counts, $wpdb->prepare, and date range ($this->start_date, $this->end_date) accordingly so a single query supplies the counts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@inc/class-dashboard-statistics.php`:
- Around line 226-235: The loop issues multiple DB calls: replace the per-slug
$wpdb->get_var calls with one grouped query using $wpdb->prepare and IN(...) to
fetch counts for all $slugs at once (e.g. SELECT slug, COUNT(*) FROM {$table}
WHERE slug IN (...) AND date_created BETWEEN %s AND %s GROUP BY slug), then map
the result rows back into $counts (ensuring every slug in $slugs gets an integer
0 if not returned); update the logic around $slugs, $counts, $wpdb->prepare, and
date range ($this->start_date, $this->end_date) accordingly so a single query
supplies the counts.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: def77e56-2365-4fd5-aef8-1ebc29278b41
📒 Files selected for processing (4)
inc/class-dashboard-statistics.phpinc/class-signup-metrics.phpinc/class-wp-ultimo.phptests/WP_Ultimo/Signup_Metrics_Test.php
Summary
Implements issue #297 (Finish Metrics and Onboarding) and subtask #398 (Track signup flow).
What's added
inc/class-signup-metrics.php— Signup funnel trackingwu_checkout_element_render,wu_checkout_order_created,wu_checkout_done, andwu_checkout_errorswu_eventstable:checkout_started,checkout_step_completed,checkout_completed,checkout_failedwu_register_all_eventsinc/class-activity-tracker.php— Post-signup activity trackingtransition_post_status,user_register, andwoocommerce_new_orderon customer sub-sitessite_post_published,site_user_registered, andsite_woocommerce_orderevents at the network levelwu_get_site_by_blog_id)EXCLUDED_POST_TYPESconstant (filterable)inc/class-dashboard-statistics.php— Two new statistics methodsget_data_signup_funnel(): per-stage event counts + conversion rate (started → completed)get_data_site_activity(): post/user/WooCommerce order counts per date rangeinc/class-wp-ultimo.php— Both classes instantiated alongside the existingTrackersingletontests/WP_Ultimo/Signup_Metrics_Test.php— Unit tests covering singleton, event type registration, filter pass-through, and dashboard statistics key structureDesign decisions
wu_eventstable — no new DB tables requiredwoocommerce_new_orderhook — no hard WooCommerce dependencywu_get_site_by_blog_idlookups per requestCloses #297
Closes #398
Summary by CodeRabbit