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/class-convertkit-admin-setup-wizard.php +178 -43 2.2.53.4.3 View file →
@@ -37,8 +37,17 @@
37 37 */
38 38 public $error = false;
39 39
40 40 /**
41 + * Holds the Post Type to generate.
42 + *
43 + * @since 3.3.9
44 + *
45 + * @var string
46 + */
47 + public $post_type = 'page';
48 +
49 + /**
41 50 * The required user capability to access the setup wizard.
42 51 *
43 52 * @since 1.9.8.4
44 53 *
@@ -50,11 +59,11 @@
50 59 * The current step in the setup process the user is on.
51 60 *
52 61 * @since 1.9.8.4
53 62 *
54 - * @var int
63 + * @var string
55 64 */
56 - public $step = 1;
65 + public $step = 'start';
57 66
58 67 /**
59 68 * The programmatic name of the setup screen.
60 69 *
@@ -64,8 +73,18 @@
64 73 */
65 74 public $page_name = false;
66 75
67 76 /**
77 + * Whether the wizard is being served within a modal or
78 + * new window.
79 + *
80 + * @since 2.2.6
81 + *
82 + * @var bool
83 + */
84 + public $is_modal = false;
85 +
86 + /**
68 87 * The URL to take the user to when they click the Exit link.
69 88 *
70 89 * @since 1.9.8.4
71 90 *
@@ -113,38 +132,27 @@
113 132 }
114 133
115 134 // Define actions to register the setup screen.
116 135 add_action( 'admin_menu', array( $this, 'register_screen' ) );
117 - add_action( 'admin_head', array( $this, 'hide_screen_from_menu' ) );
118 136 add_action( 'admin_init', array( $this, 'maybe_load_setup_screen' ) );
119 137
120 138 }
121 139
122 140 /**
123 - * Register the setup screen in WordPress' Dashboard, so that index.php?page={$this->page_name}
141 + * Register the wizard screen in WordPress' Dashboard, so that options.php?page={$this->page_name}
124 142 * does not 404 when in the WordPress Admin interface.
125 143 *
144 + * Ensures the WordPress user has the given required_capability to access this screen.
145 + *
126 146 * @since 1.9.8.4
127 147 */
128 148 public function register_screen() {
129 149
130 - add_dashboard_page( '', '', 'edit_posts', $this->page_name, '__return_false' );
150 + add_submenu_page( '', '', '', $this->required_capability, $this->page_name, '__return_false' );
131 151
132 152 }
133 153
134 154 /**
135 - * Hides the menu registered when register_screen() above is called, otherwise
136 - * we would have a blank submenu entry below the Dashboard menu.
137 - *
138 - * @since 1.9.8.4
139 - */
140 - public function hide_screen_from_menu() {
141 -
142 - remove_submenu_page( 'index.php', $this->page_name );
143 -
144 - }
145 -
146 - /**
147 155 * Loads the setup screen if the request URL is for this class
148 156 *
149 157 * @since 1.9.8.4
150 158 */
@@ -163,10 +171,26 @@
163 171
164 172 // Define current screen, so that calls to get_current_screen() tell Plugins which screen is loaded.
165 173 set_current_screen( $this->page_name );
166 174
175 + // If the convertkit-modal parameter exists and is 1, set the flag to denote
176 + // this wizard is served in a modal.
177 + if ( filter_has_var( INPUT_GET, 'convertkit-modal' ) && filter_input( INPUT_GET, 'convertkit-modal', FILTER_SANITIZE_NUMBER_INT ) === '1' ) {
178 + $this->is_modal = true;
179 + }
180 +
181 + /**
182 + * Define the steps for the setup wizard.
183 + *
184 + * @since 3.1.8
185 + *
186 + * @param array $steps The steps for the setup wizard.
187 + * @return array The steps for the setup wizard.
188 + */
189 + $this->steps = apply_filters( 'convertkit_admin_setup_wizard_steps_' . $this->page_name, $this->steps );
190 +
167 191 // Define the step the user is on in the setup process.
168 - $this->step = ( isset( $_REQUEST['step'] ) ? absint( $_REQUEST['step'] ) : 1 ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
192 + $this->step = $this->get_current_step();
169 193
170 194 // Process any posted form data.
171 195 $this->process_form();
172 196
@@ -188,8 +212,68 @@
188 212
189 213 }
190 214
191 215 /**
216 + * Returns the current step in the setup process.
217 + *
218 + * @since 3.1.7
219 + *
220 + * @return string Current step.
221 + */
222 + public function get_current_step() {
223 +
224 + $step = ( filter_has_var( INPUT_GET, 'step' ) ? filter_input( INPUT_GET, 'step', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : 'start' );
225 +
226 + // Fallback to 'start' if the step is a registered step.
227 + if ( ! array_key_exists( $step, $this->steps ) ) {
228 + $step = 'start';
229 + }
230 +
231 + return $step;
232 +
233 + }
234 +
235 + /**
236 + * Get the number of the current step.
237 + *
238 + * @since 3.1.7
239 + *
240 + * @return int Step number.
241 + */
242 + public function get_current_step_number() {
243 +
244 + return array_search( $this->step, array_keys( $this->steps ), true ) + 1;
245 +
246 + }
247 +
248 + /**
249 + * Get the step by number.
250 + *
251 + * @since 3.1.7
252 + *
253 + * @param int $number Step number (1 based index).
254 + * @return string Step name/key.
255 + */
256 + public function get_step_key_by_number( $number ) {
257 +
258 + return array_keys( $this->steps )[ $number - 1 ];
259 +
260 + }
261 +
262 + /**
263 + * Get the total number of steps.
264 + *
265 + * @since 3.1.7
266 + *
267 + * @return int Total steps.
268 + */
269 + public function get_total_steps() {
270 +
271 + return count( $this->steps );
272 +
273 + }
274 +
275 + /**
192 276 * Process submitted form data for the given setup wizard name and current step.
193 277 *
194 278 * @since 1.9.8.4
195 279 */
@@ -194,23 +278,14 @@
194 278 * @since 1.9.8.4
195 279 */
196 280 private function process_form() {
197 281
198 - // Run security checks.
199 - if ( ! isset( $_POST['_wpnonce'] ) ) {
200 - return;
201 - }
202 - if ( ! wp_verify_nonce( sanitize_key( $_POST['_wpnonce'] ), $this->page_name ) ) {
203 - $this->error = __( 'Invalid nonce specified.', 'convertkit' );
204 - return;
205 - }
206 -
207 282 /**
208 283 * Process submitted form data for the given setup wizard name and current step.
209 284 *
210 285 * @since 1.9.8.4
211 286 *
212 - * @param int $step Current step number.
287 + * @param string $step Current step.
213 288 */
214 289 do_action( 'convertkit_admin_setup_wizard_process_form_' . $this->page_name, $this->step );
215 290
216 291 }
@@ -226,33 +301,36 @@
226 301
227 302 // Define the current step URL.
228 303 $this->current_step_url = add_query_arg(
229 304 array(
230 - 'page' => $this->page_name,
231 - 'step' => $this->step,
305 + 'page' => $this->page_name,
306 + 'convertkit-modal' => $this->is_modal(),
307 + 'step' => $this->step,
232 308 ),
233 - admin_url( 'index.php' )
309 + admin_url( 'options.php' )
234 310 );
235 311
236 312 // Define the previous step URL if we're not on the first or last step.
237 - if ( $this->step > 1 && $this->step < count( $this->steps ) ) {
313 + if ( $this->get_current_step_number() > 1 && $this->get_current_step_number() < $this->get_total_steps() ) {
238 314 $this->previous_step_url = add_query_arg(
239 315 array(
240 - 'page' => $this->page_name,
241 - 'step' => ( $this->step - 1 ),
316 + 'page' => $this->page_name,
317 + 'convertkit-modal' => $this->is_modal(),
318 + 'step' => $this->get_step_key_by_number( $this->get_current_step_number() - 1 ),
242 319 ),
243 - admin_url( 'index.php' )
320 + admin_url( 'options.php' )
244 321 );
245 322 }
246 323
247 324 // Define the next step URL if we're not on the last page.
248 - if ( $this->step < count( $this->steps ) ) {
325 + if ( $this->get_current_step_number() < $this->get_total_steps() ) {
249 326 $this->next_step_url = add_query_arg(
250 327 array(
251 - 'page' => $this->page_name,
252 - 'step' => ( $this->step + 1 ),
328 + 'page' => $this->page_name,
329 + 'convertkit-modal' => $this->is_modal(),
330 + 'step' => $this->get_step_key_by_number( $this->get_current_step_number() + 1 ),
253 331 ),
254 - admin_url( 'index.php' )
332 + admin_url( 'options.php' )
255 333 );
256 334 }
257 335
258 336 }
@@ -268,9 +346,9 @@
268 346 * Load any data into class variables for the given setup wizard name and current step.
269 347 *
270 348 * @since 1.9.8.4
271 349 *
272 - * @param int $step Current step number.
350 + * @param string $step Current step.
273 351 */
274 352 do_action( 'convertkit_admin_setup_wizard_load_screen_data_' . $this->page_name, $this->step );
275 353
276 354 }
@@ -286,9 +364,9 @@
286 364 convertkit_select2_enqueue_scripts();
287 365
288 366 // Enqueue JS.
289 367 wp_enqueue_script( 'convertkit-admin-preview-output', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/preview-output.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
290 - wp_enqueue_script( 'convertkit-admin-setup-wizard', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/setup-wizard.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
368 + wp_enqueue_script( 'convertkit-admin-setup-wizard', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/setup-wizard.js', array(), CONVERTKIT_PLUGIN_VERSION, true );
291 369
292 370 }
293 371
294 372 /**
@@ -357,8 +435,40 @@
357 435
358 436 }
359 437
360 438 /**
439 + * Whether this wizard is served in a modal window.
440 + *
441 + * @since 2.2.6
442 + *
443 + * @return bool
444 + */
445 + public function is_modal() {
446 +
447 + return $this->is_modal;
448 +
449 + }
450 +
451 + /**
452 + * Outputs HTML to close the current window, due to it being opened
453 + * by window.open().
454 + *
455 + * @since 2.2.6
456 + */
457 + public function maybe_close_modal() {
458 +
459 + // Sanity check we requested a modal.
460 + if ( ! $this->is_modal() ) {
461 + return;
462 + }
463 +
464 + // Load HTML to close the modal.
465 + include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/close-modal.php';
466 + exit;
467 +
468 + }
469 +
470 + /**
361 471 * Determines if the request is for the setup screen
362 472 *
363 473 * @since 1.9.8.4
364 474 *
@@ -371,12 +481,12 @@
371 481 return false;
372 482 }
373 483
374 484 // Bail if we're not on the setup screen.
375 - if ( ! isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
485 + if ( ! filter_has_var( INPUT_GET, 'page' ) ) {
376 486 return false;
377 487 }
378 - if ( sanitize_text_field( $_GET['page'] ) !== $this->page_name ) { // phpcs:ignore WordPress.Security.NonceVerification
488 + if ( filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) !== $this->page_name ) {
379 489 return false;
380 490 }
381 491
382 492 return true;
@@ -402,8 +512,33 @@
402 512 return false;
403 513 }
404 514
405 515 return true;
516 +
517 + }
518 +
519 + /**
520 + * Sets the Post Type from the request, ensuring it is supported by the Plugin.
521 + *
522 + * @since 3.3.9
523 + */
524 + protected function set_post_type() {
525 +
526 + $this->post_type = ( filter_has_var( INPUT_GET, 'ck_post_type' ) ? filter_input( INPUT_GET, 'ck_post_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : 'page' );
527 +
528 + if ( ! in_array( $this->post_type, convertkit_get_supported_post_types(), true ) ) {
529 + wp_die(
530 + sprintf(
531 + /* translators: Post Type */
532 + esc_html__( 'The post type `%s` is not supported for Member Content.', 'convertkit' ),
533 + esc_html( $this->post_type )
534 + ),
535 + esc_html__( 'WordPress Error', 'convertkit' ),
536 + array(
537 + 'back_link' => true,
538 + )
539 + );
540 + }
406 541
407 542 }
408 543
409 544 }