Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
StatusService
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 8
870
0.00% covered (danger)
0.00%
0 / 1
 handle_started
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 handle_abandoned
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 handle_completed
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 is_site_created_within_last_9_months
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 is_onboarding_restart_eligible
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
30
 update_onboarding_restart_status
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
90
 track
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 save_site_info
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace NewfoldLabs\WP\Module\Onboarding\Services;
3
4use NewfoldLabs\WP\Module\Onboarding\Data\Brands;
5use NewfoldLabs\WP\Module\Onboarding\Data\Options;
6use NewfoldLabs\WP\Module\Onboarding\WP_Admin;
7use NewfoldLabs\WP\Module\Onboarding\Data\Config;
8use NewfoldLabs\WP\Module\Onboarding\Data\Flows\Flows;
9use NewfoldLabs\WP\Module\Onboarding\Data\Services\SiteGenService;
10use NewfoldLabs\WP\Module\Onboarding\Services\ReduxStateService;
11
12/**
13 * Tracks the Status of Onboarding.
14 */
15class StatusService {
16
17    /**
18     * Handle Onboarding started event.
19     *
20     * @return bool True if the onboarding started was marked, false if it was already marked.
21     */
22    public static function handle_started(): bool {
23        $status = get_option( Options::get_option_name( 'status' ) );
24        if ( 'started' !== $status && 'completed' !== $status ) {
25            update_option( Options::get_option_name( 'status' ), 'started' );
26
27            // Store start time when onboarding begins
28            update_option( Options::get_option_name( 'start_time' ), time() );
29
30            do_action( 'newfold/onboarding/started' );
31            return true;
32        }
33        return false;
34    }
35
36    /**
37     * Handles Onboarding abandoned event.
38     *
39     * @return void
40     */
41    public static function handle_abandoned(): void {
42        if ( 'started' === get_option( Options::get_option_name( 'status' ) ) ) {
43            update_option( Options::get_option_name( 'status' ), 'abandoned' );
44
45            // Clean up time tracking when onboarding is abandoned
46            delete_option( Options::get_option_name( 'start_time' ) );
47            delete_option( Options::get_option_name( 'completed_time' ) );
48        }
49    }
50
51    /**
52     * Handles Onboarding completed event.
53     *
54     * @return void
55     */
56    public static function handle_completed(): void {
57        if ( 'started' === get_option( Options::get_option_name( 'status' ) ) ) {
58            update_option( Options::get_option_name( 'status' ), 'completed' );
59
60            // Save onboarding site information to database option.
61            self::save_site_info();
62
63            // Store completion time
64            update_option( Options::get_option_name( 'completed_time' ), time() );
65
66            /**
67             * We're disabling the restart onboarding feature for now.
68             */
69            // self::update_onboarding_restart_status();
70            do_action( 'newfold/onboarding/completed' );
71        }
72    }
73
74    /**
75     * Checks if the WordPress site was created within the last 9 months (275 days)
76     * using the 'bluehost_plugin_install_date' option.
77     *
78     * @return bool True if the site was created within the last 275 days, false otherwise.
79     */
80    private static function is_site_created_within_last_9_months(): bool {
81        $install_date_timestamp = get_option( Options::get_option_name( 'bluehost_plugin_install_date', false ) );
82
83        // If the option is not set or is invalid, return false
84        if ( ! $install_date_timestamp ) {
85            return false;
86        }
87
88        // Calculate the timestamp for 275 days ago (9 months)
89        $nine_months_ago = time() - ( 275 * 24 * 60 * 60 );
90
91        return $install_date_timestamp >= $nine_months_ago;
92    }
93
94    /**
95     * Checks if the user is eligible to restart onboarding based on brand configuration and AI SiteGen capability.
96     *
97     * @return bool True if eligible, false otherwise.
98     */
99    public static function is_onboarding_restart_eligible(): bool {
100        // Check if the brand is eligible for Restarting Onboarding
101        $brand_config = Brands::get_brands()[ NFD_ONBOARDING_PLUGIN_BRAND ]['config'] ?? array();
102        if ( empty( $brand_config['canRestartOnboarding'] ) || ! $brand_config['canRestartOnboarding'] ) {
103            return false;
104        }
105
106        // Check if AI SiteGen Hiive capability is active and the site was created in the last 9 months
107        if ( ! Config::has_ai_sitegen() || ! self::is_site_created_within_last_9_months() ) {
108            return false;
109        }
110
111        return true;
112    }
113
114    /**
115     * Handles the flow data and updates the restart eligibility status based on total onboarding tries.
116     *
117     * @return void
118     */
119    public static function update_onboarding_restart_status(): void {
120        if ( isset( $_GET['page'] ) && \sanitize_text_field( wp_unslash( $_GET['page'] ) ) === 'nfd-onboarding' ) {
121            return;
122        }
123
124        // Don't do anything if the customer is not eligible
125        if ( ! self::is_onboarding_restart_eligible() ) {
126            return;
127        }
128
129        // Get flow data
130        $flow_data   = get_option( Options::get_option_name( 'flow' ) );
131        $active_flow = $flow_data['activeFlow'];
132        $homepages   = $flow_data['sitegen']['homepages'];
133
134        if ( isset( $flow_data['onboardingRetries'] ) && ! empty( $flow_data['onboardingRetries'] ) ) {
135            // Increment the total onboarding tries
136            $flow_data['onboardingRetries']['retryCount'] = ( $flow_data['onboardingRetries']['retryCount'] ?? 0 ) + 1;
137
138            // Update the flow data with the incremented total onboarding tries count
139            update_option( Options::get_option_name( 'flow' ), $flow_data );
140
141            // Determine eligibility for restarting onboarding
142            $current_retry_count = $flow_data['onboardingRetries']['retryCount'];
143            $can_restart         = $current_retry_count < $flow_data['onboardingRetries']['maxRetryCount'];
144
145            // Update the eligibility status in wp_option
146            update_option( Options::get_option_name( 'can_restart' ), $can_restart );
147
148            if ( $can_restart ) {
149                // Module AI prefix
150                $prefix = 'nfd-ai-site-gen-';
151                // Sitemeta Options
152                $enabled_identifiers = array_keys( array_filter( SiteGenService::enabled_identifiers() ) );
153
154                // Delete enabled identifiers options
155                foreach ( $enabled_identifiers as $identifier ) {
156                    delete_option( $prefix . SiteGenService::get_identifier_name( $identifier ) );
157                }
158
159                // Extra NFD-AI Options
160                $sitegen_identifiers = array(
161                    'keywords',
162                    'homepages',
163                    'generatedpatterns',
164                    'contentstructures',
165                    'siteclassificationmapping',
166                    'refinedsitedescription',
167                );
168                foreach ( $sitegen_identifiers as $identifier ) {
169                    delete_option( $prefix . $identifier );
170                }
171
172                delete_option( Options::get_option_name( 'flow' ) );
173                $flow_data_copy                                    = Flows::get_data();
174                $flow_data_copy['activeFlow']                      = $active_flow;
175                $flow_data_copy['sitegen']['homepages']            = $homepages;
176                $flow_data_copy['onboardingRetries']['retryCount'] = $current_retry_count;
177
178                // Update the flow data with the incremented total onboarding tries count and add to db
179                add_option( Options::get_option_name( 'flow' ), $flow_data_copy );
180
181                delete_option( Options::get_option_name( 'start_date' ) );
182                delete_option( Options::get_option_name( 'status' ) );
183                delete_option( Options::get_option_name( 'sitegen_regenerated_homepages' ) );
184            }
185        }
186    }
187
188    /**
189     * Begin tracking the Onboarding status in an option.
190     *
191     * @return void
192     */
193    public static function track(): void {
194        // Ignore if the request is an AJAX request.
195        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
196            return;
197        }
198
199        // Ignore if the request is not for the onboarding page.
200        if ( isset( $_GET['page'] ) && \sanitize_text_field( $_GET['page'] ) === WP_Admin::$slug ) {
201            return;
202        }
203
204        // Handle abandoned event.
205        self::handle_abandoned();
206    }
207
208    /**
209     * Save onboarding site information to database option for other modules to access.
210     *
211     * @return void
212     */
213    public static function save_site_info(): void {
214        $site_info = array();
215
216        // Get experience level and site type from ReduxStateService
217        $data = ReduxStateService::get( 'input' );
218        $site_info['experience_level'] = $data['experienceLevel'] ?? 'advanced';
219        $site_info['site_type'] = $data['siteType'] ?? 'business';
220
221        // Save to database option
222        update_option( Options::get_option_name( 'site_info' ), $site_info );
223    }
224}