PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.1.0
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.1.0
3.4.2 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 All 195 releases
convertkit / admin / section / class-convertkit-admin-section-tools.php

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

437 lines 12.4 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 > Kit > Tools.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Admin_Section_Tools extends ConvertKit_Admin_Section_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 // Register and maybe output notices for this settings screen, and the Intercom messenger.
32 if ( $this->on_settings_screen( $this->name ) ) {
33 add_filter( 'convertkit_settings_base_register_notices', array( $this, 'register_notices' ) );
34 add_action( 'convertkit_settings_base_render_before', array( $this, 'maybe_output_notices' ) );
35 }
36
37 parent::__construct();
38
39 $this->maybe_perform_actions();
40 }
41
42 /**
43 * Registers success and error notices for the Tools screen, to be displayed
44 * depending on the action.
45 *
46 * @since 2.5.1
47 *
48 * @param array $notices Regsitered success and error notices.
49 * @return array
50 */
51 public function register_notices( $notices ) {
52
53 return array_merge(
54 $notices,
55 array(
56 'import_configuration_upload_error' => __( 'An error occured uploading the configuration file.', 'convertkit' ),
57 'import_configuration_invalid_file_type' => __( 'The uploaded configuration file isn\'t valid.', 'convertkit' ),
58 'import_configuration_empty' => __( 'The uploaded configuration file contains no settings.', 'convertkit' ),
59 'import_configuration_success' => __( 'Configuration imported successfully.', 'convertkit' ),
60 'migrate_mc4wp_configuration_success' => __( 'MC4WP forms migrated successfully.', 'convertkit' ),
61 )
62 );
63
64 }
65
66 /**
67 * Possibly perform some actions, such as clearing the log, downloading the log,
68 * downloading system information or any third party actions now.
69 *
70 * @since 1.9.7.4
71 */
72 private function maybe_perform_actions() {
73
74 $this->maybe_clear_log();
75 $this->maybe_download_log();
76 $this->maybe_download_system_info();
77 $this->maybe_export_configuration();
78 $this->maybe_import_configuration();
79 $this->maybe_migrate_mc4wp_configuration();
80
81 }
82
83 /**
84 * Clears the Log.
85 *
86 * @since 1.9.6
87 */
88 private function maybe_clear_log() {
89
90 // Bail if nonce verification fails.
91 if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) {
92 return;
93 }
94
95 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' ) ) {
96 return;
97 }
98
99 // Bail if the submit button for clearing the debug log was not clicked.
100 // Nonce verification already performed in maybe_perform_actions() which calls this function.
101 if ( ! array_key_exists( 'convertkit-clear-debug-log', $_REQUEST ) ) {
102 return;
103 }
104
105 // Clear Log.
106 $log = new ConvertKit_Log( CONVERTKIT_PLUGIN_PATH );
107 $log->clear();
108
109 // Redirect to Tools screen.
110 $this->redirect();
111
112 }
113
114 /**
115 * Prompts a browser download for the log file, if the user clicked
116 * the Download Log button.
117 *
118 * @since 1.9.6
119 */
120 private function maybe_download_log() {
121
122 global $wp_filesystem;
123
124 // Bail if nonce verification fails.
125 if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) {
126 return;
127 }
128
129 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' ) ) {
130 return;
131 }
132
133 // Bail if the submit button for downloading the debug log was not clicked.
134 if ( ! array_key_exists( 'convertkit-download-debug-log', $_REQUEST ) ) {
135 return;
136 }
137
138 // Get Log and download.
139 $log = new ConvertKit_Log( CONVERTKIT_PLUGIN_PATH );
140
141 // Download.
142 header( 'Content-type: application/octet-stream' );
143 header( 'Content-Disposition: attachment; filename=convertkit-log.txt' );
144 header( 'Pragma: no-cache' );
145 header( 'Expires: 0' );
146 echo esc_html( $wp_filesystem->get_contents( $log->get_filename() ) );
147 exit();
148
149 }
150
151 /**
152 * Prompts a browser download for the system information, if the user clicked
153 * the Download System Info button.
154 *
155 * @since 1.9.6
156 */
157 private function maybe_download_system_info() {
158
159 global $wp_filesystem;
160
161 // Bail if nonce verification fails.
162 if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) {
163 return;
164 }
165
166 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' ) ) {
167 return;
168 }
169
170 // Bail if the submit button for downloading the system info was not clicked.
171 if ( ! array_key_exists( 'convertkit-download-system-info', $_REQUEST ) ) {
172 return;
173 }
174
175 // Get System Info.
176 $system_info = $this->get_system_info();
177
178 // Write contents to temporary file.
179 $tmpfile = tmpfile();
180 $filename = stream_get_meta_data( $tmpfile )['uri'];
181 $wp_filesystem->put_contents(
182 $filename,
183 esc_attr( $system_info )
184 );
185
186 // Download.
187 header( 'Content-type: application/octet-stream' );
188 header( 'Content-Disposition: attachment; filename=convertkit-system-info.txt' );
189 header( 'Pragma: no-cache' );
190 header( 'Expires: 0' );
191 echo esc_html( $wp_filesystem->get_contents( $filename ) );
192 $wp_filesystem->delete( $filename );
193 exit();
194
195 }
196
197 /**
198 * Prompts a browser download for the configuration file, if the user clicked
199 * the Export button.
200 *
201 * @since 1.9.7.4
202 */
203 private function maybe_export_configuration() {
204
205 // Bail if nonce verification fails.
206 if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) {
207 return;
208 }
209
210 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' ) ) {
211 return;
212 }
213
214 // Bail if the submit button for exporting the configuration was not clicked.
215 if ( ! array_key_exists( 'convertkit-export', $_REQUEST ) ) {
216 return;
217 }
218
219 // Initialize classes that hold settings.
220 $settings = new ConvertKit_Settings();
221 $restrict_content_settings = new ConvertKit_Settings_Restrict_Content();
222 $broadcasts_settings = new ConvertKit_Settings_Broadcasts();
223
224 // Define configuration data to include in the export file.
225 $json = wp_json_encode(
226 array(
227 'settings' => $settings->get(),
228 'restrict_content' => $restrict_content_settings->get(),
229 'broadcasts' => $broadcasts_settings->get(),
230 )
231 );
232
233 // Download.
234 header( 'Content-type: application/x-msdownload' );
235 header( 'Content-Disposition: attachment; filename=convertkit-export.json' );
236 header( 'Pragma: no-cache' );
237 header( 'Expires: 0' );
238 echo $json; // phpcs:ignore WordPress.Security.EscapeOutput
239 exit();
240
241 }
242
243 /**
244 * Imports the configuration file, if it's included in the form request
245 * and has the expected structure.
246 *
247 * @since 1.9.7.4
248 */
249 private function maybe_import_configuration() {
250
251 // Bail if nonce verification fails.
252 if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) {
253 return;
254 }
255
256 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' ) ) {
257 return;
258 }
259
260 // Allow us to easily interact with the filesystem.
261 require_once ABSPATH . 'wp-admin/includes/file.php';
262 WP_Filesystem();
263 global $wp_filesystem;
264
265 // Bail if the submit button for importing the configuration was not clicked.
266 if ( ! array_key_exists( 'convertkit-import', $_REQUEST ) ) {
267 return;
268 }
269
270 // Bail if no configuration file was supplied.
271 if ( isset( $_FILES['import']['error'] ) && $_FILES['import']['error'] !== 0 ) {
272 $this->redirect_with_error_notice( 'import_configuration_upload_error' );
273 }
274
275 // Bail if the file cannot be read.
276 if ( ! isset( $_FILES['import']['tmp_name'] ) ) {
277 $this->redirect_with_error_notice( 'import_configuration_upload_error' );
278 }
279
280 // Read file.
281 $json = $wp_filesystem->get_contents( sanitize_text_field( wp_unslash( $_FILES['import']['tmp_name'] ) ) );
282
283 // Decode.
284 $import = json_decode( $json, true );
285
286 // Bail if the data isn't JSON.
287 if ( is_null( $import ) ) {
288 $this->redirect_with_error_notice( 'import_configuration_invalid_file_type' );
289 }
290
291 // Bail if no settings exist.
292 if ( ! array_key_exists( 'settings', $import ) ) {
293 $this->redirect_with_error_notice( 'import_configuration_empty' );
294 }
295
296 // Import: Settings.
297 if ( array_key_exists( 'settings', $import ) ) {
298 $settings = new ConvertKit_Settings();
299 update_option( $settings::SETTINGS_NAME, $import['settings'] );
300 }
301
302 // Import: Restrict Content Settings.
303 if ( array_key_exists( 'restrict_content', $import ) ) {
304 $restrict_content_settings = new ConvertKit_Settings_Restrict_Content();
305 update_option( $restrict_content_settings::SETTINGS_NAME, $import['restrict_content'] );
306 }
307
308 // Import: Broadcasts Settings.
309 if ( array_key_exists( 'broadcasts', $import ) ) {
310 $broadcasts_settings = new ConvertKit_Settings_Broadcasts();
311 update_option( $broadcasts_settings::SETTINGS_NAME, $import['broadcasts'] );
312 }
313
314 // Redirect to Tools screen.
315 $this->redirect_with_success_notice( 'import_configuration_success' );
316
317 }
318
319 /**
320 * Replaces MC4WP Form Shortcodes with Kit Form Shortcodes, if the user submitted the
321 * MC4WP Migrate Configuration section.
322 *
323 * @since 3.1.0
324 */
325 private function maybe_migrate_mc4wp_configuration() {
326
327 // Bail if nonce verification fails.
328 if ( ! isset( $_REQUEST['_convertkit_settings_tools_nonce'] ) ) {
329 return;
330 }
331
332 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_tools_nonce'] ), 'convertkit-settings-tools' ) ) {
333 return;
334 }
335
336 // Bail if no MC4WP Form IDs were submitted.
337 if ( ! isset( $_REQUEST['_wp_convertkit_integration_mc4wp_settings'] ) ) {
338 return;
339 }
340
341 // Initialise the importer.
342 $mc4wp = new ConvertKit_Admin_Importer_MC4WP();
343
344 // Iterate through the MC4WP Form IDs and replace the shortcodes with the Kit Form Shortcodes.
345 foreach ( array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['_wp_convertkit_integration_mc4wp_settings'] ) ) as $mc4wp_form_id => $kit_form_id ) {
346 $mc4wp->replace_shortcodes_in_posts( (int) $mc4wp_form_id, (int) $kit_form_id );
347 }
348
349 // Redirect to Tools screen.
350 $this->redirect_with_success_notice( 'migrate_mc4wp_configuration_success' );
351
352 }
353
354 /**
355 * Outputs the Debug Log and System Info view.
356 *
357 * @since 1.9.6
358 */
359 public function render() {
360
361 /**
362 * Performs actions prior to rendering the settings form.
363 *
364 * @since 2.0.0
365 */
366 do_action( 'convertkit_settings_base_render_before' );
367
368 // Get Log and System Info.
369 $log = new ConvertKit_Log( CONVERTKIT_PLUGIN_PATH );
370 $system_info = $this->get_system_info();
371
372 // Get Forms.
373 $forms = new ConvertKit_Resource_Forms();
374
375 // Get Importers.
376 $mc4wp = new ConvertKit_Admin_Importer_MC4WP();
377
378 // Output view.
379 require_once CONVERTKIT_PLUGIN_PATH . '/views/backend/settings/tools.php';
380
381 /**
382 * Performs actions after rendering of the settings form.
383 *
384 * @since 2.0.0
385 */
386 do_action( 'convertkit_settings_base_render_after' );
387
388 }
389
390 /**
391 * Prints help info for this section
392 */
393 public function print_section_info() {
394
395 ?>
396 <p><?php esc_html_e( 'Tools to help you manage Kit on your site.', 'convertkit' ); ?></p>
397 <?php
398
399 }
400
401 /**
402 * Returns the URL for the ConvertKit documentation for this setting section.
403 *
404 * @since 2.0.8
405 *
406 * @return string Documentation URL.
407 */
408 public function documentation_url() {
409
410 return 'https://help.kit.com/en/articles/2502591-how-to-set-up-the-kit-plugin-on-your-wordpress-website';
411
412 }
413
414 /**
415 * Returns a string comprising of the WordPress system information, with Plugin information
416 * prepended.
417 *
418 * @since 1.9.8.3
419 */
420 private function get_system_info() {
421
422 // If we're using WordPress < 5.2, there's no WP_Debug_Data class to fetch system information from.
423 if ( version_compare( get_bloginfo( 'version' ), '5.2', '<' ) ) {
424 return __( 'WordPress 5.2 or higher is required for system information report.', 'convertkit' );
425 }
426
427 // Use WordPress' debug_data() function to get system info, matching how Tools > Site Health > Info works.
428 if ( ! class_exists( 'WP_Debug_Data' ) ) {
429 require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php';
430 }
431
432 return str_replace( '`', '', WP_Debug_Data::format( WP_Debug_Data::debug_data(), 'debug' ) );
433
434 }
435
436 }
437