|
1 <?php |
|
2 /** |
|
3 * Error Protection API: WP_Paused_Extensions_Storage class |
|
4 * |
|
5 * @package WordPress |
|
6 * @since 5.2.0 |
|
7 */ |
|
8 |
|
9 /** |
|
10 * Core class used for storing paused extensions. |
|
11 * |
|
12 * @since 5.2.0 |
|
13 */ |
|
14 class WP_Paused_Extensions_Storage { |
|
15 |
|
16 /** |
|
17 * Type of extension. Used to key extension storage. |
|
18 * |
|
19 * @since 5.2.0 |
|
20 * @var string |
|
21 */ |
|
22 protected $type; |
|
23 |
|
24 /** |
|
25 * Constructor. |
|
26 * |
|
27 * @since 5.2.0 |
|
28 * |
|
29 * @param string $extension_type Extension type. Either 'plugin' or 'theme'. |
|
30 */ |
|
31 public function __construct( $extension_type ) { |
|
32 $this->type = $extension_type; |
|
33 } |
|
34 |
|
35 /** |
|
36 * Records an extension error. |
|
37 * |
|
38 * Only one error is stored per extension, with subsequent errors for the same extension overriding the |
|
39 * previously stored error. |
|
40 * |
|
41 * @since 5.2.0 |
|
42 * |
|
43 * @param string $extension Plugin or theme directory name. |
|
44 * @param array $error { |
|
45 * Error that was triggered. |
|
46 * |
|
47 * @type string $type The error type. |
|
48 * @type string $file The name of the file in which the error occurred. |
|
49 * @type string $line The line number in which the error occurred. |
|
50 * @type string $message The error message. |
|
51 * } |
|
52 * @return bool True on success, false on failure. |
|
53 */ |
|
54 public function set( $extension, $error ) { |
|
55 if ( ! $this->is_api_loaded() ) { |
|
56 return false; |
|
57 } |
|
58 |
|
59 $option_name = $this->get_option_name(); |
|
60 |
|
61 if ( ! $option_name ) { |
|
62 return false; |
|
63 } |
|
64 |
|
65 $paused_extensions = (array) get_option( $option_name, array() ); |
|
66 |
|
67 // Do not update if the error is already stored. |
|
68 if ( isset( $paused_extensions[ $this->type ][ $extension ] ) && $paused_extensions[ $this->type ][ $extension ] === $error ) { |
|
69 return true; |
|
70 } |
|
71 |
|
72 $paused_extensions[ $this->type ][ $extension ] = $error; |
|
73 |
|
74 return update_option( $option_name, $paused_extensions ); |
|
75 } |
|
76 |
|
77 /** |
|
78 * Forgets a previously recorded extension error. |
|
79 * |
|
80 * @since 5.2.0 |
|
81 * |
|
82 * @param string $extension Plugin or theme directory name. |
|
83 * |
|
84 * @return bool True on success, false on failure. |
|
85 */ |
|
86 public function delete( $extension ) { |
|
87 if ( ! $this->is_api_loaded() ) { |
|
88 return false; |
|
89 } |
|
90 |
|
91 $option_name = $this->get_option_name(); |
|
92 |
|
93 if ( ! $option_name ) { |
|
94 return false; |
|
95 } |
|
96 |
|
97 $paused_extensions = (array) get_option( $option_name, array() ); |
|
98 |
|
99 // Do not delete if no error is stored. |
|
100 if ( ! isset( $paused_extensions[ $this->type ][ $extension ] ) ) { |
|
101 return true; |
|
102 } |
|
103 |
|
104 unset( $paused_extensions[ $this->type ][ $extension ] ); |
|
105 |
|
106 if ( empty( $paused_extensions[ $this->type ] ) ) { |
|
107 unset( $paused_extensions[ $this->type ] ); |
|
108 } |
|
109 |
|
110 // Clean up the entire option if we're removing the only error. |
|
111 if ( ! $paused_extensions ) { |
|
112 return delete_option( $option_name ); |
|
113 } |
|
114 |
|
115 return update_option( $option_name, $paused_extensions ); |
|
116 } |
|
117 |
|
118 /** |
|
119 * Gets the error for an extension, if paused. |
|
120 * |
|
121 * @since 5.2.0 |
|
122 * |
|
123 * @param string $extension Plugin or theme directory name. |
|
124 * |
|
125 * @return array|null Error that is stored, or null if the extension is not paused. |
|
126 */ |
|
127 public function get( $extension ) { |
|
128 if ( ! $this->is_api_loaded() ) { |
|
129 return null; |
|
130 } |
|
131 |
|
132 $paused_extensions = $this->get_all(); |
|
133 |
|
134 if ( ! isset( $paused_extensions[ $extension ] ) ) { |
|
135 return null; |
|
136 } |
|
137 |
|
138 return $paused_extensions[ $extension ]; |
|
139 } |
|
140 |
|
141 /** |
|
142 * Gets the paused extensions with their errors. |
|
143 * |
|
144 * @since 5.2.0 |
|
145 * |
|
146 * @return array Associative array of extension slugs to the error recorded. |
|
147 */ |
|
148 public function get_all() { |
|
149 if ( ! $this->is_api_loaded() ) { |
|
150 return array(); |
|
151 } |
|
152 |
|
153 $option_name = $this->get_option_name(); |
|
154 |
|
155 if ( ! $option_name ) { |
|
156 return array(); |
|
157 } |
|
158 |
|
159 $paused_extensions = (array) get_option( $option_name, array() ); |
|
160 |
|
161 return isset( $paused_extensions[ $this->type ] ) ? $paused_extensions[ $this->type ] : array(); |
|
162 } |
|
163 |
|
164 /** |
|
165 * Remove all paused extensions. |
|
166 * |
|
167 * @since 5.2.0 |
|
168 * |
|
169 * @return bool |
|
170 */ |
|
171 public function delete_all() { |
|
172 if ( ! $this->is_api_loaded() ) { |
|
173 return false; |
|
174 } |
|
175 |
|
176 $option_name = $this->get_option_name(); |
|
177 |
|
178 if ( ! $option_name ) { |
|
179 return false; |
|
180 } |
|
181 |
|
182 $paused_extensions = (array) get_option( $option_name, array() ); |
|
183 |
|
184 unset( $paused_extensions[ $this->type ] ); |
|
185 |
|
186 if ( ! $paused_extensions ) { |
|
187 return delete_option( $option_name ); |
|
188 } |
|
189 |
|
190 return update_option( $option_name, $paused_extensions ); |
|
191 } |
|
192 |
|
193 /** |
|
194 * Checks whether the underlying API to store paused extensions is loaded. |
|
195 * |
|
196 * @since 5.2.0 |
|
197 * |
|
198 * @return bool True if the API is loaded, false otherwise. |
|
199 */ |
|
200 protected function is_api_loaded() { |
|
201 return function_exists( 'get_option' ); |
|
202 } |
|
203 |
|
204 /** |
|
205 * Get the option name for storing paused extensions. |
|
206 * |
|
207 * @since 5.2.0 |
|
208 * |
|
209 * @return string |
|
210 */ |
|
211 protected function get_option_name() { |
|
212 if ( ! wp_recovery_mode()->is_active() ) { |
|
213 return ''; |
|
214 } |
|
215 |
|
216 $session_id = wp_recovery_mode()->get_session_id(); |
|
217 if ( empty( $session_id ) ) { |
|
218 return ''; |
|
219 } |
|
220 |
|
221 return "{$session_id}_paused_extensions"; |
|
222 } |
|
223 } |