1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* The Jetpack Connection error handler class for invalid blog tokens |
4
|
|
|
* |
5
|
|
|
* @package automattic/jetpack-connection |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Automattic\Jetpack\Connection\Error_Handlers; |
9
|
|
|
|
10
|
|
|
use Automattic\Jetpack\Connection\Manager; |
11
|
|
|
use Automattic\Jetpack\Connection\Error_Handler; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* This class handles all the error codes that indicates a broken blog token and |
15
|
|
|
* suggests the user to reconnect. |
16
|
|
|
* |
17
|
|
|
* @since 8.7.0 |
18
|
|
|
*/ |
19
|
|
|
class Invalid_Blog_Token { |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Number of times we will try to regenerate the blog token |
23
|
|
|
* |
24
|
|
|
* @var integer |
25
|
|
|
*/ |
26
|
|
|
private $max_heal_attempts = 1000; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Name of the option where we store the number of attempts to self heal |
30
|
|
|
* |
31
|
|
|
* @var string |
32
|
|
|
*/ |
33
|
|
|
private $attempts_option_name = '_jetpack_connection_blog_token_heal_attempts'; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Set up hooks |
37
|
|
|
* |
38
|
|
|
* @since 8.7.0 |
39
|
|
|
* |
40
|
|
|
* @param array $errors The array containing verified errors stored in the database. |
41
|
|
|
*/ |
42
|
|
|
public function __construct( $errors ) { |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Filters the message to be displayed in the admin notices area when there's a invalid blog token xmlrpc error |
46
|
|
|
* |
47
|
|
|
* Return an empty value to disable the message. |
48
|
|
|
* |
49
|
|
|
* @since 8.7.0 |
50
|
|
|
* |
51
|
|
|
* @param string $message The error message. |
52
|
|
|
*/ |
53
|
|
|
$this->message = apply_filters( 'jetpack_connection_invalid_blog_token_admin_notice', __( 'Your connection with WordPress.com seems to be broken. If you\'re experiencing issues, please try reconnecting.', 'jetpack' ) ); |
|
|
|
|
54
|
|
|
|
55
|
|
|
if ( empty( $this->message ) ) { |
56
|
|
|
return; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
// In this class, we will only handle errors with the blog token, so ignoring if there are only errors with user tokens. |
60
|
|
|
if ( ! isset( $errors[0] ) && ! isset( $errors['invalid'] ) ) { |
61
|
|
|
return; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
$this->attempts = (int) get_option( $this->attempts_option_name ); |
|
|
|
|
65
|
|
|
|
66
|
|
|
if ( $this->should_self_heal() ) { |
67
|
|
|
$this->refresh_blog_token(); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
add_action( 'react_connection_errors_initial_state', array( $this, 'jetpack_react_dashboard_error' ) ); |
71
|
|
|
// do not add admin notice to the jetpack dashboard. |
72
|
|
|
global $pagenow; |
73
|
|
|
if ( 'admin.php' === $pagenow || isset( $_GET['page'] ) && 'jetpack' === $_GET['page'] ) { // phpcs:ignore |
74
|
|
|
return; |
75
|
|
|
} |
76
|
|
|
add_action( 'admin_notices', array( $this, 'admin_notice' ) ); |
77
|
|
|
|
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Prints an admin notice for the blog token error |
82
|
|
|
* |
83
|
|
|
* @since 8.7.0 |
84
|
|
|
* |
85
|
|
|
* @return void |
86
|
|
|
*/ |
87
|
|
|
public function admin_notice() { |
88
|
|
|
|
89
|
|
|
if ( ! current_user_can( 'jetpack_connect' ) ) { |
90
|
|
|
return; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
?> |
94
|
|
|
<div class="notice notice-error is-dismissible jetpack-message jp-connect" style="display:block !important;"> |
95
|
|
|
<p><?php echo esc_html( $this->message ); ?></p> |
96
|
|
|
</div> |
97
|
|
|
<?php |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Adds the error message to the Jetpack React Dashboard |
102
|
|
|
* |
103
|
|
|
* @param array $errors The array of errors. |
104
|
|
|
* @return array |
105
|
|
|
*/ |
106
|
|
|
public function jetpack_react_dashboard_error( $errors ) { |
107
|
|
|
|
108
|
|
|
$errors[] = array( |
109
|
|
|
'code' => 'invalid_blog_token', |
110
|
|
|
'message' => $this->message, |
111
|
|
|
'action' => 'reconnect', |
112
|
|
|
); |
113
|
|
|
return $errors; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Checks the number of healing attempts and returns a boolean indicating if we should |
118
|
|
|
* try again or not |
119
|
|
|
* |
120
|
|
|
* @return boolean |
121
|
|
|
*/ |
122
|
|
|
public function should_self_heal() { |
123
|
|
|
return $this->attempts > 0 && $this->attempts < $this->max_heal_attempts; |
|
|
|
|
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Gets the number of times this blog attempted to regenerate the blog token |
128
|
|
|
* and updates it in the database |
129
|
|
|
* |
130
|
|
|
* @return integer |
131
|
|
|
*/ |
132
|
|
|
public function get_heal_attempts() { |
133
|
|
|
$attempts = (int) get_option( $this->attempts_option_name ); |
134
|
|
|
$attempts ++; |
135
|
|
|
update_option( $this->attempts_option_name, $attempts ); |
136
|
|
|
return $attempts; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Lock attempts |
141
|
|
|
* |
142
|
|
|
* @return void |
143
|
|
|
*/ |
144
|
|
|
private function lock_attempts() { |
145
|
|
|
update_option( $this->attempts_option_name, -1 ); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Unlock attempts |
150
|
|
|
* |
151
|
|
|
* @return void |
152
|
|
|
*/ |
153
|
|
|
private function unlock_attempts() { |
154
|
|
|
update_option( $this->attempts_option_name, $this->attempts ); |
|
|
|
|
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Tries to register the site again and refresh the blog token |
159
|
|
|
* |
160
|
|
|
* @return void |
161
|
|
|
*/ |
162
|
|
|
public function refresh_blog_token() { |
163
|
|
|
|
164
|
|
|
$this->lock_attempts(); |
165
|
|
|
|
166
|
|
|
$manager = new Manager(); |
167
|
|
|
|
168
|
|
|
$heal = $manager->register(); |
169
|
|
|
l( $heal ); |
170
|
|
|
|
171
|
|
|
$this->attempts ++; |
|
|
|
|
172
|
|
|
|
173
|
|
|
if ( true === $heal ) { |
174
|
|
|
Error_Handler::get_instance()->delete_all_errors(); |
175
|
|
|
delete_option( $this->attempts_option_name ); |
176
|
|
|
} else { |
177
|
|
|
$this->unlock_attempts(); |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
} |
182
|
|
|
|
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: