function ( $user ) {
return get_user_meta( $user['id'], 'vrts_onboarding', true ) ?: [];
},
'update_callback' => function ( $value, $user ) {
return update_user_meta( $user->ID, 'vrts_onboarding', $value );
},
'schema' => [
'type' => 'object',
'properties' => [
'completed' => [
'type' => 'array',
'default' => [],
],
],
],
] );
}
/**
* Get onboarding.
*
* @return array
*/
public function get_onboarding() {
$onboardins = $this->get_onboardings();
foreach ( $onboardins as $onboarding ) {
if ( $this->has_user_completed_onboarding( $onboarding['id'] ) ) {
continue;
}
if ( call_user_func( $onboarding['permission_callback'] ) ) {
unset( $onboarding['permission_callback'] );
return $onboarding;
}
}
return false;
}
/**
* Has user completed onboarding.
*
* @param string $onboarding_id the onboarding id.
* @return bool
*/
public function has_user_completed_onboarding( $onboarding_id ) {
$onboarding = get_user_meta( get_current_user_id(), 'vrts_onboarding', true ) ?: [];
return in_array( $onboarding_id, $onboarding['completed'] ?? [], true );
}
/**
* Get onboardings.
*
* @return array
*/
public function get_onboardings() {
return [
[
'id' => 'tests-welcome',
'permission_callback' => [ $this, 'should_display_tests_welcome_onboarding' ],
'steps' => [
[
'title' => wp_kses_post( __( '👋 Howdy, welcome aboard!', 'visual-regression-tests' ) ),
'description' => wp_kses_post( __( "With our VRTs plugin, you can effortlessly maintain your website's visual consistency.
Automatically detect visual changes and receive Alerts to achieve pixel-perfect precision.", 'visual-regression-tests' ) ),
],
[
'title' => wp_kses_post( __( '⏰ Daily Tests & Pro Automations', 'visual-regression-tests' ) ),
'description' => wp_kses_post( __( 'The Daily Test Run captures screenshots of your Test pages and performs side-by-side comparisons to instantly spot changes.
Upgrade to Pro to automate Tests for WordPress and plugin updates, integrate deployment pipelines via API, and run Manual Tests on demand.', 'visual-regression-tests' ) ),
],
[
'side' => 'right',
'align' => 'start',
'padding' => 8,
'element' => '#show-modal-add-new',
'title' => wp_kses_post( __( "🚀 Let's get started!", 'visual-regression-tests' ) ),
'description' => wp_kses_post( __( 'Add your first Test here to enable VRTs for the selected page.', 'visual-regression-tests' ) ),
],
],
],
[
'id' => 'first-test',
'permission_callback' => [ $this, 'should_display_first_test_onboarding' ],
'steps' => [
[
'side' => 'bottom',
'align' => 'center',
'element' => '.wp-list-table tbody tr:first-child',
'title' => wp_kses_post( __( '🥳 Yay, you created your first VRT!', 'visual-regression-tests' ) ),
'description' => wp_kses_post( __( 'Starting from tomorrow, your Test will run daily, ensuring consistent monitoring of your page.', 'visual-regression-tests' ) ),
],
[
'element' => '.vrts-admin-header__navigation-link[href$="admin.php?page=vrts-settings"]',
'title' => wp_kses_post( __( '🛠️ Fine-tune your setup', 'visual-regression-tests' ) ),
'description' => wp_kses_post( __( 'Further customize your Test configuration and plugin settings for an optimized experience.', 'visual-regression-tests' ) ),
],
],
],
[
'id' => 'run-test',
'permission_callback' => [ $this, 'should_display_run_test_onboarding' ],
'steps' => [
[
'padding' => 2,
'element' => '.wp-list-table .vrts-run-test',
'title' => wp_kses_post( __( '🔬 Run your Test now', 'visual-regression-tests' ) ),
'description' => wp_kses_post( __( 'Want to see your Test in action?
Give it a go and run this Test now!', 'visual-regression-tests' ) ),
],
],
],
[
'id' => 'runs-introduction',
'permission_callback' => [ $this, 'should_display_runs_introduction_onboarding' ],
'steps' => [
[
'side' => 'bottom',
'align' => 'center',
'element' => '.vrts-admin-header__navigation-link[href$="admin.php?page=vrts-runs"]',
'title' => wp_kses_post( __( '🚀 Meet the new Runs!', 'visual-regression-tests' ) ),
'description' => wp_kses_post( __( 'Alerts are now bundled into Runs. Get a single report for each daily test, manual test, API trigger, or new: WordPress & plugin update (Pro)!', 'visual-regression-tests' ) ),
],
],
],
];
}
/**
* Should display tests welcome onboarding.
*
* @return bool
*/
public function should_display_tests_welcome_onboarding() {
$page = sanitize_text_field( wp_unslash( $_GET['page'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here.
if ( 'vrts' === $page ) {
$frontpage_id = get_option( 'page_on_front' );
$is_front_page_added = ! is_null( Test::get_item_id( $frontpage_id ) );
$next_id = Test::get_autoincrement_value();
if ( 1 === $next_id || ( $is_front_page_added && 2 === $next_id ) ) {
return true;
}
}
return false;
}
/**
* Should display first test onboarding.
*
* @return bool
*/
public function should_display_first_test_onboarding() {
$page = sanitize_text_field( wp_unslash( $_GET['page'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here.
$is_new_test_added = isset( $_GET['new-test-added'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here.
if ( 'vrts' === $page && $is_new_test_added ) {
$frontpage_id = get_option( 'page_on_front' );
$is_front_page_added = ! is_null( Test::get_item_id( $frontpage_id ) );
$next_id = Test::get_autoincrement_value();
if ( 2 === $next_id || ( $is_front_page_added && 3 === $next_id ) ) {
return true;
}
}
return false;
}
/**
* Should display run test onboarding.
*
* @return bool
*/
public function should_display_run_test_onboarding() {
$page = sanitize_text_field( wp_unslash( $_GET['page'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here.
$has_subscription = (bool) Subscription::get_subscription_status();
if ( 'vrts' === $page && $has_subscription ) {
$tests = Test::get_items();
foreach ( $tests as $test ) {
$status = Test::get_calculated_status( $test );
if ( 'scheduled' === $status ) {
return true;
}
}
}
return false;
}
/**
* Should display run introduction onboarding.
*
* @return bool
*/
public function should_display_runs_introduction_onboarding() {
$page = sanitize_text_field( wp_unslash( $_GET['page'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here.
if ( in_array( $page, [ 'vrts', 'vrts-runs', 'vrts-settings' ], true ) ) {
$has_migrated_alerts = get_option( 'vrts_test_runs_has_migrated_alerts' );
if ( $has_migrated_alerts ) {
return true;
}
}
return false;
}
}