PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
3.4.3 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 All 196 releases
← All changes | admin/setup-wizard/class-convertkit-admin-setup-wizard-plugin.php +221 -72 2.2.53.4.3 View file →
@@ -27,8 +27,17 @@
27 27 */
28 28 public $forms = false;
29 29
30 30 /**
31 + * Holds the ConvertKit API class.
32 + *
33 + * @since 2.5.0
34 + *
35 + * @var bool|ConvertKit_API_V4
36 + */
37 + public $api = false;
38 +
39 + /**
31 40 * Holds the ConvertKit Settings class.
32 41 *
33 42 * @since 1.9.8.4
34 43 *
@@ -56,8 +65,17 @@
56 65 */
57 66 public $preview_page_url = false;
58 67
59 68 /**
69 + * The required user capability to access the setup wizard.
70 + *
71 + * @since 2.3.2
72 + *
73 + * @var string
74 + */
75 + public $required_capability = 'manage_options';
76 +
77 + /**
60 78 * The programmatic name for this wizard.
61 79 *
62 80 * @since 1.9.8.4
63 81 *
@@ -74,8 +92,17 @@
74 92 */
75 93 public $exit_url = 'options-general.php?page=_wp_convertkit_settings';
76 94
77 95 /**
96 + * Holds the form importers.
97 + *
98 + * @since 3.1.7
99 + *
100 + * @var array
101 + */
102 + public $form_importers = array();
103 +
104 + /**
78 105 * Registers action and filter hooks.
79 106 *
80 107 * @since 1.9.8.4
81 108 */
@@ -80,39 +107,72 @@
80 107 * @since 1.9.8.4
81 108 */
82 109 public function __construct() {
83 110
111 + // Setup API and settings classes.
112 + $this->api = new ConvertKit_API_V4( CONVERTKIT_OAUTH_CLIENT_ID, CONVERTKIT_OAUTH_CLIENT_REDIRECT_URI, false, false, false, 'setup_wizard' );
113 + $this->settings = new ConvertKit_Settings();
114 +
115 + // Define the steps for the setup wizard.
116 + add_filter( 'convertkit_admin_setup_wizard_steps_convertkit-setup', array( $this, 'define_steps' ) );
117 +
118 + // Register link to Setup Wizard below Plugin Name at Plugins > Installed Plugins.
119 + add_filter( 'convertkit_plugin_screen_action_links', array( $this, 'add_setup_wizard_link_on_plugins_screen' ) );
120 +
121 + add_action( 'admin_init', array( $this, 'maybe_redirect_to_setup_screen' ), 9999 );
122 + add_action( 'convertkit_admin_setup_wizard_process_form_convertkit-setup', array( $this, 'process_form' ) );
123 + add_action( 'convertkit_admin_setup_wizard_load_screen_data_convertkit-setup', array( $this, 'load_screen_data' ) );
124 +
125 + // Call parent class constructor.
126 + parent::__construct();
127 +
128 + }
129 +
130 + /**
131 + * Define the steps for the setup wizard.
132 + *
133 + * @since 3.1.8
134 + *
135 + * @param array $steps The steps for the setup wizard.
136 + * @return array
137 + */
138 + public function define_steps( $steps ) {
139 +
140 + $show_form_importer_step = count( convertkit_get_form_importers() ) > 0 ? true : false;
141 +
84 142 // Define details for each step in the setup process.
85 - $this->steps = array(
86 - 1 => array(
87 - 'name' => __( 'Setup', 'convertkit' ),
88 - ),
89 - 2 => array(
90 - 'name' => __( 'Connect Account', 'convertkit' ),
143 + $steps = array(
144 + 'start' => array(
145 + 'name' => __( 'Connect', 'convertkit' ),
91 146 'next_button' => array(
92 147 'label' => __( 'Connect', 'convertkit' ),
148 + 'link' => $this->api->get_oauth_url( admin_url( 'options.php?page=convertkit-setup&step=configuration' ), get_site_url() ),
93 149 ),
94 150 ),
95 - 3 => array(
96 - 'name' => __( 'Form Configuration', 'convertkit' ),
151 + 'configuration' => array(
152 + 'name' => __( 'Configuration', 'convertkit' ),
97 153 'next_button' => array(
98 - 'label' => __( 'Finish Setup', 'convertkit' ),
154 + 'label' => $show_form_importer_step ? __( 'Next', 'convertkit' ) : __( 'Finish Setup', 'convertkit' ),
99 155 ),
100 156 ),
101 - 4 => array(
102 - 'name' => __( 'Done', 'convertkit' ),
103 - ),
104 157 );
105 158
106 - // Register link to Setup Wizard below Plugin Name at Plugins > Installed Plugins.
107 - add_filter( 'convertkit_plugin_screen_action_links', array( $this, 'add_setup_wizard_link_on_plugins_screen' ) );
159 + // If the Form Importer step will be displayed, add it to the steps.
160 + if ( $show_form_importer_step ) {
161 + $steps['form-importer'] = array(
162 + 'name' => __( 'Form Importer', 'convertkit' ),
163 + 'next_button' => array(
164 + 'label' => __( 'Finish Setup', 'convertkit' ),
165 + ),
166 + );
167 + }
108 168
109 - add_action( 'admin_init', array( $this, 'maybe_redirect_to_setup_screen' ), 9999 );
110 - add_action( 'convertkit_admin_setup_wizard_process_form_convertkit-setup', array( $this, 'process_form' ) );
111 - add_action( 'convertkit_admin_setup_wizard_load_screen_data_convertkit-setup', array( $this, 'load_screen_data' ) );
169 + // Add the finish step.
170 + $steps['finish'] = array(
171 + 'name' => __( 'Done', 'convertkit' ),
172 + );
112 173
113 - // Call parent class constructor.
114 - parent::__construct();
174 + return $steps;
115 175
116 176 }
117 177
118 178 /**
@@ -133,9 +193,9 @@
133 193 add_query_arg(
134 194 array(
135 195 'page' => $this->page_name,
136 196 ),
137 - admin_url( 'index.php' )
197 + admin_url( 'options.php' )
138 198 ),
139 199 __( 'Setup Wizard', 'convertkit' )
140 200 ),
141 201 )
@@ -168,14 +228,14 @@
168 228
169 229 // Check if any settings exist.
170 230 // If they do, the Plugin has already been setup, so no need to show the setup screen.
171 231 $settings = new ConvertKit_Settings();
172 - if ( $settings->has_api_key_and_secret() ) {
232 + if ( $settings->has_access_and_refresh_token() ) {
173 233 return;
174 234 }
175 235
176 236 // Show the setup screen.
177 - wp_safe_redirect( admin_url( 'index.php?page=' . $this->page_name ) );
237 + wp_safe_redirect( admin_url( 'options.php?page=' . $this->page_name ) );
178 238 exit;
179 239
180 240 }
181 241
@@ -187,54 +247,95 @@
187 247 * @param int $step Current step.
188 248 */
189 249 public function process_form( $step ) {
190 250
191 - // phpcs:disable WordPress.Security.NonceVerification.Missing
192 - // Nonce verification has been performed in ConvertKit_Admin_Setup_Wizard:process_form(), prior to calling this function.
251 + // Depending on the step, process the form data.
252 + if ( array_key_exists( 'code', $_REQUEST ) || array_key_exists( 'error', $_REQUEST ) || array_key_exists( 'error_description', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended - no nonce is sent back from OAuth.
253 + $this->save_oauth( map_deep( wp_unslash( $_REQUEST ), 'sanitize_text_field' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - no nonce is sent back from OAuth.
254 + return;
255 + }
193 256
194 - // Depending on the step, process the form data.
195 - switch ( $step ) {
196 - case 3:
197 - // Check that the API Key and Secret work.
198 - $api_key = sanitize_text_field( wp_unslash( $_POST['api_key'] ) );
199 - $api_secret = sanitize_text_field( wp_unslash( $_POST['api_secret'] ) );
257 + // Run security checks.
258 + if ( ! isset( $_REQUEST['_wpnonce'] ) ) {
259 + return;
260 + }
261 + if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), $this->page_name ) ) {
262 + // Decrement the step.
263 + $this->step = 'configuration';
264 + $this->error = __( 'Invalid nonce specified.', 'convertkit' );
265 + return;
266 + }
200 267
201 - $api = new ConvertKit_API( $api_key, $api_secret, false, 'setup_wizard' );
202 - $result = $api->account();
268 + // Configuration.
269 + if ( array_key_exists( 'post_form', $_REQUEST ) || array_key_exists( 'page_form', $_REQUEST ) || array_key_exists( 'usage_tracking', $_REQUEST ) ) {
270 + $settings = new ConvertKit_Settings();
271 + $settings->save(
272 + array(
273 + 'post_form' => isset( $_REQUEST['post_form'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['post_form'] ) ) : '0',
274 + 'page_form' => isset( $_REQUEST['page_form'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page_form'] ) ) : '0',
275 + 'usage_tracking' => isset( $_REQUEST['usage_tracking'] ) ? 'on' : '',
276 + )
277 + );
278 + return;
279 + }
203 280
204 - // Show an error message if Account Details could not be fetched e.g. API credentials supplied are invalid.
205 - if ( is_wp_error( $result ) ) {
206 - // Decrement the step.
207 - $this->step = ( $this->step - 1 );
208 - $this->error = $result->get_error_message();
209 - return;
210 - }
281 + // Form Importer.
282 + if ( array_key_exists( 'form_importer', $_REQUEST ) ) {
283 + // Replace third party form shortcodes and blocks with Kit form shortcodes and blocks.
284 + foreach ( map_deep( wp_unslash( $_REQUEST['form_importer'] ), 'sanitize_text_field' ) as $form_importer_name => $mappings ) {
285 + // Sanitize mappings.
286 + $mappings = array_map( 'sanitize_text_field', wp_unslash( $mappings ) );
211 287
212 - // If here, API credentials are valid.
213 - // Save them.
214 - $settings = new ConvertKit_Settings();
215 - $settings->save(
216 - array(
217 - 'api_key' => $api_key,
218 - 'api_secret' => $api_secret,
219 - )
220 - );
221 - break;
288 + // Replace third party form shortcodes and blocks with Kit form shortcodes and blocks.
289 + WP_ConvertKit()->get_class( 'admin_importer_' . $form_importer_name )->import( $mappings );
290 + }
222 291
223 - case 4:
224 - // Save Default Page and Post Form settings.
225 - $settings = new ConvertKit_Settings();
226 - $settings->save(
227 - array(
228 - 'post_form' => sanitize_text_field( $_POST['post_form'] ),
229 - 'page_form' => sanitize_text_field( $_POST['page_form'] ),
230 - )
231 - );
232 - break;
292 + return;
233 293 }
234 294
235 - // phpcs:enable
295 + }
236 296
297 + /**
298 + * Save the OAuth credentials.
299 + *
300 + * @since 3.1.7
301 + *
302 + * @param array $request Request.
303 + * @return void
304 + */
305 + private function save_oauth( $request ) {
306 +
307 + // If an error occured from OAuth i.e. the user did not authorize, show it now.
308 + if ( array_key_exists( 'error', $request ) || array_key_exists( 'error_description', $request ) ) {
309 + // Decrement the step.
310 + $this->step = 'start';
311 + $this->error = sanitize_text_field( wp_unslash( $request['error_description'] ) );
312 + return;
313 + }
314 +
315 + // Sanitize token.
316 + $authorization_code = sanitize_text_field( wp_unslash( $request['code'] ) );
317 +
318 + // Exchange the authorization code and verifier for an access token.
319 + $result = $this->api->get_access_token( $authorization_code );
320 +
321 + // Show an error message if we could not fetch the access token.
322 + if ( is_wp_error( $result ) ) {
323 + // Decrement the step.
324 + $this->step = 'start';
325 + $this->error = $result->get_error_message();
326 + return;
327 + }
328 +
329 + // Store Access Token, Refresh Token and expiry.
330 + $this->settings->save(
331 + array(
332 + 'access_token' => $result['access_token'],
333 + 'refresh_token' => $result['refresh_token'],
334 + 'token_expires' => ( time() + $result['expires_in'] ),
335 + )
336 + );
337 +
237 338 }
238 339
239 340 /**
240 341 * Load any data into class variables for the given setup wizard name and current step.
@@ -244,32 +345,74 @@
244 345 * @param int $step Current step.
245 346 */
246 347 public function load_screen_data( $step ) {
247 348
349 + // If this wizard is being served in a modal window, change the flow.
350 + if ( $this->is_modal() ) {
351 + switch ( $step ) {
352 + case 'start':
353 + // Setup API.
354 + $api = new ConvertKit_API_V4( CONVERTKIT_OAUTH_CLIENT_ID, CONVERTKIT_OAUTH_CLIENT_REDIRECT_URI );
355 +
356 + // Permit wp_safe_redirect to redirect to app.kit.com.
357 + add_filter(
358 + 'allowed_redirect_hosts',
359 + function ( $hosts ) {
360 +
361 + return array_merge(
362 + $hosts,
363 + array(
364 + 'app.kit.com',
365 + )
366 + );
367 +
368 + }
369 + );
370 +
371 + // Redirect to OAuth.
372 + wp_safe_redirect( $api->get_oauth_url( admin_url( 'options.php?page=convertkit-setup&step=configuration&convertkit-modal=1' ), get_site_url() ) );
373 + die();
374 +
375 + case 'configuration':
376 + // Close modal.
377 + $this->maybe_close_modal();
378 + break;
379 + }
380 + }
381 +
248 382 switch ( $step ) {
249 - case 2:
250 - // Load settings class.
383 + case 'configuration':
384 + // Re-load settings class now that the Access and Refresh Tokens have been defined.
251 385 $this->settings = new ConvertKit_Settings();
252 - break;
253 386
254 - case 3:
255 - // Re-load settings class now that the API Key and Secret has been defined.
256 - $this->settings = new ConvertKit_Settings();
257 -
258 387 // Fetch Forms.
259 388 $this->forms = new ConvertKit_Resource_Forms( 'setup_wizard' );
260 - $this->forms->refresh();
389 + $result = $this->forms->refresh();
261 390
391 + // Bail if an error occured.
392 + if ( is_wp_error( $result ) ) {
393 + // Change the next button label and make it a link to reload the screen.
394 + $this->steps['configuration']['next_button']['label'] = __( 'I\'ve created a form in Kit', 'convertkit' );
395 + $this->steps['configuration']['next_button']['link'] = add_query_arg(
396 + array(
397 + 'page' => $this->page_name,
398 + 'step' => 'configuration',
399 + ),
400 + admin_url( 'options.php' )
401 + );
402 + return;
403 + }
404 +
262 405 // If no Forms exist in ConvertKit, change the next button label and make it a link to reload
263 406 // the screen.
264 407 if ( ! $this->forms->exist() ) {
265 - $this->steps[3]['next_button']['label'] = __( 'I\'ve created a form in ConvertKit', 'convertkit' );
266 - $this->steps[3]['next_button']['link'] = add_query_arg(
408 + $this->steps['configuration']['next_button']['label'] = __( 'I\'ve created a form in Kit', 'convertkit' );
409 + $this->steps['configuration']['next_button']['link'] = add_query_arg(
267 410 array(
268 411 'page' => $this->page_name,
269 - 'step' => 3,
412 + 'step' => 'configuration',
270 413 ),
271 - admin_url( 'index.php' )
414 + admin_url( 'options.php' )
272 415 );
273 416 }
274 417
275 418 // Fetch a Post and a Page, appending the preview nonce to their URLs.
@@ -274,8 +417,14 @@
274 417
275 418 // Fetch a Post and a Page, appending the preview nonce to their URLs.
276 419 $this->preview_post_url = WP_ConvertKit()->get_class( 'preview_output' )->get_preview_form_url( 'post' );
277 420 $this->preview_page_url = WP_ConvertKit()->get_class( 'preview_output' )->get_preview_form_url( 'page' );
421 + break;
422 +
423 + case 'form-importer':
424 + // Fetch form importers and Kit Forms.
425 + $this->form_importers = convertkit_get_form_importers();
426 + $this->forms = new ConvertKit_Resource_Forms( 'setup_wizard' );
278 427 break;
279 428 }
280 429
281 430 }