PluginProbe
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings / 7.2.1
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings v7.2.1
7.2.2 7.2.1 7.2 7.1.2 7.1.1 7.1 7.0.4 7.0.6 7.0.7 6.3.8 6.3.7 6.3.6 6.3.5 6.3.4 6.3.3 6.3.1 trunk 5.7.3 5.7.5 5.8.1 5.8.2 5.8.3 5.8.4 5.8.6 6.0.4 All 37 releases
mlsimport / includes / mlsimport-account-status.php

mlsimport-account-status.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.2.1, at includes/mlsimport-account-status.php

135 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MLSImport account status: WHY the last SaaS token request failed.
4 *
5 * The SaaS 'token' endpoint answers three ways:
6 * - HTTP 200 -> the password was right and the account is active (token);
7 * - HTTP 401 -> wrong password or unknown username/email ("Invalid credentials");
8 * - HTTP 403 -> the password was right but the account has NO active
9 * subscription (the portal's is_active flag is not "yes").
10 *
11 * Before this module the plugin reduced all three to "got a token or not"
12 * and every screen blamed the password, so customers without a subscription
13 * opened tickets about a password that was correct. This file owns the one
14 * option that remembers the reason and the one message builder every
15 * "not connected" surface prints, so the wording lives in a single place.
16 * All login failures use the same prominent notice with a heading and message.
17 * Only subscription failures add a plans button. Both account screens use it.
18 *
19 * Public interface:
20 * mlsimport_account_status_record( $answer ) record the token reply reason
21 * mlsimport_account_status() 'no_subscription' | 'invalid_credentials' | ''
22 * mlsimport_account_not_connected_html() the warning box for the reason
23 *
24 * @package Mlsimport
25 * @subpackage Mlsimport/includes
26 */
27
28 if ( ! defined( 'ABSPATH' ) ) {
29 exit;
30 }
31
32 /** Option holding the reason of the last failed token request. */
33 define( 'MLSIMPORT_ACCOUNT_STATUS_OPTION', 'mlsimport_account_status' );
34
35 /** Portal page where a customer without a subscription can buy one. */
36 define( 'MLSIMPORT_ACCOUNT_SUBSCRIBE_URL', 'https://mlsimport.com/mls-import-plugin-pricing/' );
37
38 /**
39 * Record the outcome of a SaaS token request.
40 *
41 * Accepts the reply as returned by ThemeImport::globalApiRequestSaas(): the
42 * decoded body on HTTP 200 (success => true) or the failure descriptor
43 * (success => false, error_code => HTTP status) on anything else. Only the
44 * two definitive server verdicts are remembered:
45 *
46 * 1. success true -> the reason is cleared (account is fine);
47 * 2. error_code 403 -> 'no_subscription';
48 * 3. error_code 401 -> 'invalid_credentials';
49 * 4. anything else (transport error, 5xx, malformed) -> left untouched,
50 * because a hiccup says nothing about the account.
51 *
52 * @param mixed $answer The token endpoint reply.
53 * @return void
54 */
55 function mlsimport_account_status_record( $answer ) {
56 // Step 1: a successful login wipes any previous failure reason.
57 if ( is_array( $answer ) && ! empty( $answer['success'] ) ) {
58 delete_option( MLSIMPORT_ACCOUNT_STATUS_OPTION );
59 return;
60 }
61
62 // Step 2: map the HTTP status the server answered with to a reason.
63 $code = is_array( $answer ) && isset( $answer['error_code'] ) ? (int) $answer['error_code'] : 0;
64 if ( 403 === $code ) {
65 update_option( MLSIMPORT_ACCOUNT_STATUS_OPTION, 'no_subscription', false );
66 } elseif ( 401 === $code ) {
67 update_option( MLSIMPORT_ACCOUNT_STATUS_OPTION, 'invalid_credentials', false );
68 }
69 // Step 3: any other outcome is not a verdict about the account; keep the
70 // last known reason so the screens do not flip on a transient failure.
71 }
72
73 /**
74 * The reason of the last failed token request.
75 *
76 * @return string 'no_subscription', 'invalid_credentials' or '' when unknown.
77 */
78 function mlsimport_account_status() {
79 return (string) get_option( MLSIMPORT_ACCOUNT_STATUS_OPTION, '' );
80 }
81
82 /**
83 * The "not connected" sentence for the current account status, plain text.
84 *
85 * Used where only text can be shown (the Connections screen sign-in error
86 * line, the AJAX 'message' field). The login hint names both supported account
87 * identifiers. No markup, no link.
88 *
89 * @return string Translated sentence.
90 */
91 function mlsimport_account_not_connected_message() {
92 // Step 1: no subscription -> say so, point at the portal.
93 if ( 'no_subscription' === mlsimport_account_status() ) {
94 return esc_html__( 'Your MLSImport account was found, but it has no active subscription. Please subscribe at mlsimport.com to connect the plugin.', 'mlsimport' );
95 }
96
97 // Step 2: suggest either accepted account identifier for a failed login.
98 return esc_html__( 'You are not connected to MLSImport - Please check your username or email and password.', 'mlsimport' );
99 }
100
101 /**
102 * The "not connected" warning box for the current account status.
103 *
104 * Every surface that used to print the generic "check your Username and
105 * Password" box calls this instead, so a customer whose password is right
106 * but who has no subscription is sent to the portal rather than to the
107 * password field. The generic wording stays for every other reason.
108 *
109 * Every failure uses the same heading, explanatory paragraph and notice layout.
110 * Subscription failures additionally include a prominent plans action.
111 * The action's WordPress button class excludes it from the admin's text-link
112 * color override, preserving its white label on the dark button background.
113 *
114 * @return string Escaped HTML of one <div class="mlsimport_warning">.
115 */
116 function mlsimport_account_not_connected_html() {
117 // Step 1: share one layout; the account verdict changes only the content.
118 $is_unsubscribed = 'no_subscription' === mlsimport_account_status();
119 $title = $is_unsubscribed
120 ? esc_html__( 'No active subscription', 'mlsimport' )
121 : esc_html__( 'Unable to connect', 'mlsimport' );
122 $html = '<div class="mlsimport_warning mlsimport-account-notice'
123 . ( $is_unsubscribed ? ' mlsimport-account-subscription' : '' ) . '" role="alert">'
124 . '<strong class="mlsimport-account-notice-title">' . $title . '</strong>'
125 . '<p>' . mlsimport_account_not_connected_message() . '</p>';
126
127 // Step 2: offer a purchase action only after confirmed subscription failure.
128 if ( $is_unsubscribed ) {
129 $html .= '<a class="button mlsimport-account-subscription-action" href="' . esc_url( MLSIMPORT_ACCOUNT_SUBSCRIBE_URL ) . '" target="_blank" rel="noopener">'
130 . esc_html__( 'View plans', 'mlsimport' )
131 . '</a>';
132 }
133 return $html . '</div>';
134 }
135