| @@ -41,8 +41,23 @@ | ||
| 41 | 41 | return "notice-{$notification_type}"; |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | 44 | /** |
| 45 | + * Countdown + redirect markup (paired with routeapp-admin.js .routeapp-redirect-countdown). | |
| 46 | + * | |
| 47 | + * @param string $redirect_url Full URL. | |
| 48 | + * @param string $mode "always" = ignore route_installed cookie (ownership / conflict flows). "once" = legacy cookie so we do not loop every visit. | |
| 49 | + * @return string | |
| 50 | + */ | |
| 51 | + private function redirect_countdown_html( $redirect_url, $mode = 'always' ) { | |
| 52 | + $url = esc_url( $redirect_url ); | |
| 53 | + $countdown = '<span class="routeapp-redirect-countdown" data-countdown-mode="' . esc_attr( $mode ) . '" data-seconds="5" data-redirect-src="' . $url . '"><span class="routeapp-redirect-countdown__num">5</span> ' . esc_html__( 'seconds', 'routeapp' ) . '</span>'; | |
| 54 | + $manual = ' <span class="routeapp-redirect-manual"> — <a href="' . $url . '" class="routeapp-redirect-manual-link" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Open manually', 'routeapp' ) . '</a></span>'; | |
| 55 | + | |
| 56 | + return $countdown . $manual; | |
| 57 | + } | |
| 58 | + | |
| 59 | + /** | |
| 45 | 60 | * Import all admin notices message |
| 46 | 61 | * @since 1.0.4 |
| 47 | 62 | * @param void |
| 48 | 63 | */ |
| @@ -49,8 +64,9 @@ | ||
| 49 | 64 | public function routeapp_attention_required() |
| 50 | 65 | { |
| 51 | 66 | //$this->billing_attention_required(); //MSS-5023: disabling this alert until we get a new FR to check the billing info. |
| 52 | 67 | $this->user_attention_required(); |
| 68 | + $this->merchant_token_recovery_attention_required(); | |
| 53 | 69 | $this->merchant_attention_required(); |
| 54 | 70 | $this->redirect_attention_required(); |
| 55 | 71 | } |
| 56 | 72 | |
| @@ -82,9 +98,42 @@ | ||
| 82 | 98 | public function user_attention_required() |
| 83 | 99 | { |
| 84 | 100 | $routeapp_public = $this->get_route_public_instance(); |
| 85 | 101 | if ($routeapp_public->has_user_creation_conflicted()) { |
| 86 | - require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/routeapp-admin-user-conflict.php'; | |
| 102 | + $dashboard_url = Route_Setup::get_dashboard_ownership_login_url(); | |
| 103 | + $failed_step = get_option( Route_Setup::FAILED_REGISTRATION ); | |
| 104 | + $auto_done = get_option( Route_Setup::USER_CONFLICT_AUTO_REDIRECT_DONE_OPTION ); | |
| 105 | + | |
| 106 | + if ( $auto_done ) { | |
| 107 | + $link = sprintf( | |
| 108 | + '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>', | |
| 109 | + esc_url( $dashboard_url ), | |
| 110 | + esc_html__( 'Open the Route Dashboard', 'routeapp' ) | |
| 111 | + ); | |
| 112 | + if ( Route_Setup::FAILED_REGISTRATION_STEP_USER_LOGIN_FAILED === $failed_step ) { | |
| 113 | + $message = sprintf( | |
| 114 | + /* translators: %s: "Open the Route Dashboard" link HTML */ | |
| 115 | + __( 'Route could not sign you in. %s to sign in and link this store.', 'routeapp' ), | |
| 116 | + $link | |
| 117 | + ); | |
| 118 | + } else { | |
| 119 | + $message = sprintf( | |
| 120 | + /* translators: %s: "Open the Route Dashboard" link HTML */ | |
| 121 | + __( 'This email is already registered with Route. %s to sign in and link this store.', 'routeapp' ), | |
| 122 | + $link | |
| 123 | + ); | |
| 124 | + } | |
| 125 | + $this->add_notice( wp_kses_post( $message ), 'warning' ); | |
| 126 | + } else { | |
| 127 | + update_option( Route_Setup::USER_CONFLICT_AUTO_REDIRECT_DONE_OPTION, '1', false ); | |
| 128 | + if ( Route_Setup::FAILED_REGISTRATION_STEP_USER_LOGIN_FAILED === $failed_step ) { | |
| 129 | + $intro = esc_html__( 'Route could not sign you in. We\'re redirecting you to the Route Dashboard to sign in and link this store.', 'routeapp' ); | |
| 130 | + } else { | |
| 131 | + $intro = esc_html__( 'This email is already registered with Route. We\'re redirecting you to the Route Dashboard to sign in and link this store.', 'routeapp' ); | |
| 132 | + } | |
| 133 | + $message = $intro . ' ' . $this->redirect_countdown_html( $dashboard_url, 'always' ); | |
| 134 | + $this->add_notice( $message, 'warning' ); | |
| 135 | + } | |
| 87 | 136 | } |
| 88 | 137 | if ($routeapp_public->has_user_creation_failed()) { |
| 89 | 138 | $this->add_notice("We couldn't create your account, please contact our support or <a href=\"/wp-json/route/recreate_user\"> try again </a></span>.", "warning"); |
| 90 | 139 | } |
| @@ -90,8 +139,32 @@ | ||
| 90 | 139 | } |
| 91 | 140 | } |
| 92 | 141 | |
| 93 | 142 | /** |
| 143 | + * When public/secret tokens were cleared but onboarding state remains — prompt Dashboard OTP or password login to refresh keys. | |
| 144 | + */ | |
| 145 | + public function merchant_token_recovery_attention_required() | |
| 146 | + { | |
| 147 | + $routeapp_public = $this->get_route_public_instance(); | |
| 148 | + if ( ! $routeapp_public || $routeapp_public->has_user_creation_conflicted() ) { | |
| 149 | + return; | |
| 150 | + } | |
| 151 | + if ( ! Route_Setup::should_prompt_merchant_token_recovery() ) { | |
| 152 | + return; | |
| 153 | + } | |
| 154 | + $dashboard_url = Route_Setup::get_dashboard_ownership_login_url(); | |
| 155 | + $this->add_notice( | |
| 156 | + 'Route configurations missing from this site. ' . | |
| 157 | + sprintf( | |
| 158 | + '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>', | |
| 159 | + esc_url( $dashboard_url ), | |
| 160 | + esc_html__( 'Open Route Dashboard to reconnect', 'routeapp' ) | |
| 161 | + ), | |
| 162 | + 'warning' | |
| 163 | + ); | |
| 164 | + } | |
| 165 | + | |
| 166 | + /** | |
| 94 | 167 | * @return WP_User |
| 95 | 168 | */ |
| 96 | 169 | private function get_current_user() |
| 97 | 170 | { |
| @@ -127,13 +200,28 @@ | ||
| 127 | 200 | public function redirect_attention_required() |
| 128 | 201 | { |
| 129 | 202 | $routeapp_public = $this->get_route_public_instance(); |
| 130 | 203 | if ($routeapp_public->successful_registration() && !$routeapp_public->was_redirected()) { |
| 131 | - $this->add_notice("You're almost there! We're redirecting you to Route website to finalize your account setup... <span id=\"route_counter\" data-redirect-src=\"". Route_Setup::get_route_redirect() ."\">5</span>", "success"); | |
| 204 | + $this->add_notice( | |
| 205 | + "You're almost there! We're redirecting you to Route website to finalize your account setup... " . | |
| 206 | + $this->redirect_countdown_html( Route_Setup::get_route_redirect(), 'once' ), | |
| 207 | + 'success' | |
| 208 | + ); | |
| 132 | 209 | $routeapp_public->set_as_redirected(); |
| 133 | 210 | } |
| 134 | 211 | if ($routeapp_public->has_merchant_creation_conflicted()) { |
| 135 | - $this->add_notice("Your merchant account already exists. We're redirecting you to Route website to finalize your account setup...<span id=\"route_counter\" data-redirect-src=\"". Route_Setup::get_route_redirect() ."\">5</span>.", "warning"); | |
| 212 | + $dashboard_url = Route_Setup::get_dashboard_ownership_login_url(); | |
| 213 | + $link = sprintf( | |
| 214 | + '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>', | |
| 215 | + esc_url( $dashboard_url ), | |
| 216 | + esc_html__( 'Sign in on the Route Dashboard', 'routeapp' ) | |
| 217 | + ); | |
| 218 | + $message = sprintf( | |
| 219 | + /* translators: %s: "Sign in on the Route Dashboard" link HTML */ | |
| 220 | + __( 'Your merchant account already exists. %s to link this store.', 'routeapp' ), | |
| 221 | + $link | |
| 222 | + ); | |
| 223 | + $this->add_notice( wp_kses_post( $message ), 'warning' ); | |
| 136 | 224 | } |
| 137 | 225 | } |
| 138 | 226 | |
| 139 | 227 | private function get_route_public_instance() |