PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.2.7
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.2.7
3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 2.3.2 2.3.3 All 194 releases
convertkit / admin / section / class-convertkit-settings-tools.php

class-convertkit-settings-tools.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 2.2.7, at admin/section/class-convertkit-settings-tools.php

405 lines 11.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Settings Tools class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Registers Tools for debugging and system information that can be accessed at Settings > ConvertKit > Tools.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Settings_Tools extends ConvertKit_Settings_Base {
16
17 /**
18 * Constructor
19 */
20 public function __construct() {
21
22 // Initialize WP_Filesystem.
23 require_once ABSPATH . 'wp-admin/includes/file.php';
24 WP_Filesystem();
25
26 $this->settings_key = '_wp_convertkit_tools'; // Required for ConvertKit_Settings_Base, but we don't save settings on the Tools screen.
27 $this->name = 'tools';
28 $this->title = __( 'Tools', 'convertkit' );
29 $this->tab_text = __( 'Tools', 'convertkit' );
30
31 // Output notices.
32 add_action( 'convertkit_settings_base_render_before', array( $this, 'maybe_output_notices' ) );
33
34 parent::__construct();
35
36 $this->maybe_perform_actions();
37 }
38
39 /**
40 * Possibly perform some actions, such as clearing the log, downloading the log,
41 * downloading system information or any third party actions now.
42 *
43 * @since 1.9.7.4
44 */
45 private function maybe_perform_actions() {
46
47 // Bail if nonce is invalid.
48 if ( ! $this->verify_nonce() ) {
49 return;
50 }
51
52 $this->maybe_clear_log();
53 $this->maybe_download_log();
54 $this->maybe_download_system_info();
55 $this->maybe_export_configuration();
56 $this->maybe_import_configuration();
57
58 }
59
60 /**
61 * Clears the Log.
62 *
63 * @since 1.9.6
64 */
65 private function maybe_clear_log() {
66
67 // Bail if the submit button for clearing the debug log was not clicked.
68 // Nonce verification already performed in maybe_perform_actions() which calls this function.
69 if ( ! array_key_exists( 'convertkit-clear-debug-log', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
70 return;
71 }
72
73 // Clear Log.
74 $log = new ConvertKit_Log( CONVERTKIT_PLUGIN_PATH );
75 $log->clear();
76
77 // Redirect to Tools screen.
78 $this->redirect_to_tools_screen();
79
80 }
81
82 /**
83 * Prompts a browser download for the log file, if the user clicked
84 * the Download Log button.
85 *
86 * @since 1.9.6
87 */
88 private function maybe_download_log() {
89
90 global $wp_filesystem;
91
92 // Bail if the submit button for downloading the debug log was not clicked.
93 // Nonce verification already performed in maybe_perform_actions() which calls this function.
94 if ( ! array_key_exists( 'convertkit-download-debug-log', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
95 return;
96 }
97
98 // Get Log and download.
99 $log = new ConvertKit_Log( CONVERTKIT_PLUGIN_PATH );
100
101 // Download.
102 header( 'Content-type: application/octet-stream' );
103 header( 'Content-Disposition: attachment; filename=convertkit-log.txt' );
104 header( 'Pragma: no-cache' );
105 header( 'Expires: 0' );
106 echo esc_html( $wp_filesystem->get_contents( $log->get_filename() ) );
107 exit();
108
109 }
110
111 /**
112 * Prompts a browser download for the system information, if the user clicked
113 * the Download System Info button.
114 *
115 * @since 1.9.6
116 */
117 private function maybe_download_system_info() {
118
119 global $wp_filesystem;
120
121 // Bail if the submit button for downloading the system info was not clicked.
122 // Nonce verification already performed in maybe_perform_actions() which calls this function.
123 if ( ! array_key_exists( 'convertkit-download-system-info', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
124 return;
125 }
126
127 // Get System Info.
128 $system_info = $this->get_system_info();
129
130 // Write contents to temporary file.
131 $tmpfile = tmpfile();
132 $filename = stream_get_meta_data( $tmpfile )['uri'];
133 $wp_filesystem->put_contents(
134 $filename,
135 esc_attr( $system_info )
136 );
137
138 // Download.
139 header( 'Content-type: application/octet-stream' );
140 header( 'Content-Disposition: attachment; filename=convertkit-system-info.txt' );
141 header( 'Pragma: no-cache' );
142 header( 'Expires: 0' );
143 echo esc_html( $wp_filesystem->get_contents( $filename ) );
144 $wp_filesystem->delete( $filename );
145 exit();
146
147 }
148
149 /**
150 * Prompts a browser download for the configuration file, if the user clicked
151 * the Export button.
152 *
153 * @since 1.9.7.4
154 */
155 private function maybe_export_configuration() {
156
157 // Bail if the submit button for exporting the configuration was not clicked.
158 // Nonce verification already performed in maybe_perform_actions() which calls this function.
159 if ( ! array_key_exists( 'convertkit-export', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
160 return;
161 }
162
163 // Initialize classes that hold settings.
164 $settings = new ConvertKit_Settings();
165 $restrict_content_settings = new ConvertKit_Settings_Restrict_Content();
166
167 // Define configuration data to include in the export file.
168 $json = wp_json_encode(
169 array(
170 'settings' => $settings->get(),
171 'restrict_content' => $restrict_content_settings->get(),
172 )
173 );
174
175 // Download.
176 header( 'Content-type: application/x-msdownload' );
177 header( 'Content-Disposition: attachment; filename=convertkit-export.json' );
178 header( 'Pragma: no-cache' );
179 header( 'Expires: 0' );
180 echo $json; // phpcs:ignore WordPress.Security.EscapeOutput
181 exit();
182
183 }
184
185 /**
186 * Imports the configuration file, if it's included in the form request
187 * and has the expected structure.
188 *
189 * @since 1.9.7.4
190 */
191 private function maybe_import_configuration() {
192
193 // Allow us to easily interact with the filesystem.
194 require_once ABSPATH . 'wp-admin/includes/file.php';
195 WP_Filesystem();
196 global $wp_filesystem;
197
198 // Bail if the submit button for importing the configuration was not clicked.
199 // Nonce verification already performed in maybe_perform_actions() which calls this function.
200 if ( ! array_key_exists( 'convertkit-import', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
201 return;
202 }
203
204 // Bail if no configuration file was supplied.
205 if ( ! is_array( $_FILES ) ) {
206 $this->redirect_to_tools_screen();
207 }
208 if ( $_FILES['import']['error'] !== 0 ) {
209 $this->redirect_to_tools_screen( 'import_configuration_upload_error' );
210 }
211
212 // Read file.
213 $json = $wp_filesystem->get_contents( $_FILES['import']['tmp_name'] );
214
215 // Decode.
216 $import = json_decode( $json, true );
217
218 // Bail if the data isn't JSON.
219 if ( is_null( $import ) ) {
220 $this->redirect_to_tools_screen( 'import_configuration_invalid_file_type' );
221 }
222
223 // Bail if no settings exist.
224 if ( ! array_key_exists( 'settings', $import ) ) {
225 $this->redirect_to_tools_screen( 'import_configuration_empty' );
226 }
227
228 // Import: Settings.
229 if ( array_key_exists( 'settings', $import ) ) {
230 $settings = new ConvertKit_Settings();
231 update_option( $settings::SETTINGS_NAME, $import['settings'] );
232 }
233
234 // Import: Restrict Content Settings.
235 if ( array_key_exists( 'restrict_content', $import ) ) {
236 $restrict_content_settings = new ConvertKit_Settings_Restrict_Content();
237 update_option( $restrict_content_settings::SETTINGS_NAME, $import['restrict_content'] );
238 }
239
240 // Redirect to Tools screen.
241 $this->redirect_to_tools_screen( false, 'import_configuration_success' );
242
243 }
244
245 /**
246 * Verifies if the _convertkit_settings_tools_nonce nonce was included in the request,
247 * and if so whether the nonce action is valid.
248 *
249 * @since 1.9.6
250 *
251 * @return bool
252 */
253 private function verify_nonce() {
254
255 // Bail if nonce verification fails.
256 if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) {
257 return false;
258 }
259
260 return wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' );
261
262 }
263
264 /**
265 * Redirects to the ConvertKit > Tools screen.
266 *
267 * @since 1.9.7.4
268 *
269 * @param false|string $error The error message key.
270 * @param false|string $success The success message key.
271 */
272 private function redirect_to_tools_screen( $error = false, $success = false ) {
273
274 // Build URL to redirect to, depending on whether a message is included.
275 $args = array(
276 'page' => '_wp_convertkit_settings',
277 'tab' => 'tools',
278 );
279 if ( $error !== false ) {
280 $args['error'] = $error;
281 }
282 if ( $success !== false ) {
283 $args['success'] = $success;
284 }
285
286 // Redirect to ConvertKit > Tools screen.
287 wp_safe_redirect( add_query_arg( $args, 'options-general.php' ) );
288 exit();
289
290 }
291
292 /**
293 * Register fields for this section
294 */
295 public function register_fields() {
296
297 // No fields are registered for the Debug Log.
298 // This function is deliberately blank.
299 }
300
301 /**
302 * Outputs success and/or error notices if required.
303 *
304 * @since 2.0.0
305 */
306 public function maybe_output_notices() {
307
308 // Define messages that might be displayed as a notification.
309 $messages = array(
310 'import_configuration_upload_error' => __( 'An error occured uploading the configuration file.', 'convertkit' ),
311 'import_configuration_invalid_file_type' => __( 'The uploaded configuration file isn\'t valid.', 'convertkit' ),
312 'import_configuration_empty' => __( 'The uploaded configuration file contains no settings.', 'convertkit' ),
313 'import_configuration_success' => __( 'Configuration imported successfully.', 'convertkit' ),
314 );
315
316 // Output error notification if defined.
317 if ( isset( $_REQUEST['error'] ) && array_key_exists( sanitize_text_field( $_REQUEST['error'] ), $messages ) ) { // phpcs:ignore WordPress.Security.NonceVerification
318 $this->output_error( $messages[ sanitize_text_field( $_REQUEST['error'] ) ] ); // phpcs:ignore WordPress.Security.NonceVerification
319 }
320
321 // Output success notification if defined.
322 if ( isset( $_REQUEST['success'] ) && array_key_exists( sanitize_text_field( $_REQUEST['success'] ), $messages ) ) { // phpcs:ignore WordPress.Security.NonceVerification
323 $this->output_success( $messages[ sanitize_text_field( $_REQUEST['success'] ) ] ); // phpcs:ignore WordPress.Security.NonceVerification
324 }
325
326 }
327
328 /**
329 * Outputs the Debug Log and System Info view.
330 *
331 * @since 1.9.6
332 */
333 public function render() {
334
335 /**
336 * Performs actions prior to rendering the settings form.
337 *
338 * @since 2.0.0
339 */
340 do_action( 'convertkit_settings_base_render_before' );
341
342 // Get Log and System Info.
343 $log = new ConvertKit_Log( CONVERTKIT_PLUGIN_PATH );
344 $system_info = $this->get_system_info();
345
346 // Output view.
347 require_once CONVERTKIT_PLUGIN_PATH . '/views/backend/settings/tools.php';
348
349 /**
350 * Performs actions after rendering of the settings form.
351 *
352 * @since 2.0.0
353 */
354 do_action( 'convertkit_settings_base_render_after' );
355
356 }
357
358 /**
359 * Prints help info for this section
360 */
361 public function print_section_info() {
362
363 ?>
364 <p><?php esc_html_e( 'Tools to help you manage ConvertKit on your site.', 'convertkit' ); ?></p>
365 <?php
366
367 }
368
369 /**
370 * Returns the URL for the ConvertKit documentation for this setting section.
371 *
372 * @since 2.0.8
373 *
374 * @return string Documentation URL.
375 */
376 public function documentation_url() {
377
378 return 'https://help.convertkit.com/en/articles/2502591-the-convertkit-wordpress-plugin';
379
380 }
381
382 /**
383 * Returns a string comprising of the WordPress system information, with Plugin information
384 * prepended.
385 *
386 * @since 1.9.8.3
387 */
388 private function get_system_info() {
389
390 // If we're using WordPress < 5.2, there's no WP_Debug_Data class to fetch system information from.
391 if ( version_compare( get_bloginfo( 'version' ), '5.2', '<' ) ) {
392 return __( 'WordPress 5.2 or higher is required for system information report.', 'convertkit' );
393 }
394
395 // Use WordPress' debug_data() function to get system info, matching how Tools > Site Health > Info works.
396 if ( ! class_exists( 'WP_Debug_Data' ) ) {
397 require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php';
398 }
399
400 return str_replace( '`', '', WP_Debug_Data::format( WP_Debug_Data::debug_data(), 'debug' ) );
401
402 }
403
404 }
405