PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / trunk
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages vtrunk
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 / class-convertkit-admin-setup-wizard.php

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

545 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Admin Setup Wizard class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Provides a UI for displaying a step by step wizard style screen in the WordPress
11 * Administration.
12 *
13 * To use this class, extend it with your own configuration.
14 *
15 * Refer to the admin/setup-wizard folder for current implementations.
16 *
17 * @package ConvertKit
18 * @author ConvertKit
19 */
20 class ConvertKit_Admin_Setup_Wizard {
21
22 /**
23 * The steps available in this wizard.
24 *
25 * @since 1.9.8.4
26 *
27 * @var array
28 */
29 public $steps = array();
30
31 /**
32 * Holds an error message to display on screen.
33 *
34 * @since 1.9.8.4
35 *
36 * @var bool|string
37 */
38 public $error = false;
39
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 /**
50 * The required user capability to access the setup wizard.
51 *
52 * @since 1.9.8.4
53 *
54 * @var string
55 */
56 public $required_capability = 'activate_plugins';
57
58 /**
59 * The current step in the setup process the user is on.
60 *
61 * @since 1.9.8.4
62 *
63 * @var string
64 */
65 public $step = 'start';
66
67 /**
68 * The programmatic name of the setup screen.
69 *
70 * @since 1.9.8.4
71 *
72 * @var bool|string
73 */
74 public $page_name = false;
75
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 /**
87 * The URL to take the user to when they click the Exit link.
88 *
89 * @since 1.9.8.4
90 *
91 * @var bool|string
92 */
93 public $exit_url = false;
94
95 /**
96 * Holds the URL for the current step in the setup process.
97 *
98 * @since 1.9.8.4
99 *
100 * @var bool|string
101 */
102 public $current_step_url = false;
103
104 /**
105 * Holds the URL to the next step in the setup process.
106 *
107 * @since 1.9.8.4
108 *
109 * @var bool|string
110 */
111 public $next_step_url = false;
112
113 /**
114 * Holds the URL to the previous step in the setup process.
115 *
116 * @since 1.9.8.4
117 *
118 * @var bool|string
119 */
120 public $previous_step_url = false;
121
122 /**
123 * Registers action and filter hooks.
124 *
125 * @since 1.9.8.4
126 */
127 public function __construct() {
128
129 // Bail if no page name is defined.
130 if ( $this->page_name === false ) {
131 return;
132 }
133
134 // Define actions to register the setup screen.
135 add_action( 'admin_menu', array( $this, 'register_screen' ) );
136 add_action( 'admin_init', array( $this, 'maybe_load_setup_screen' ) );
137
138 }
139
140 /**
141 * Register the wizard screen in WordPress' Dashboard, so that options.php?page={$this->page_name}
142 * does not 404 when in the WordPress Admin interface.
143 *
144 * Ensures the WordPress user has the given required_capability to access this screen.
145 *
146 * @since 1.9.8.4
147 */
148 public function register_screen() {
149
150 add_submenu_page( '', '', '', $this->required_capability, $this->page_name, '__return_false' );
151
152 }
153
154 /**
155 * Loads the setup screen if the request URL is for this class
156 *
157 * @since 1.9.8.4
158 */
159 public function maybe_load_setup_screen() {
160
161 // Bail if this isn't a request for the setup screen.
162 if ( ! $this->is_setup_request() ) {
163 return;
164 }
165
166 // Redirect back to the Dashboard if the user doesn't have the required capability to access this setup wizard.
167 if ( ! $this->user_has_access() ) {
168 wp_safe_redirect( admin_url( 'index.php' ) );
169 exit;
170 }
171
172 // Define current screen, so that calls to get_current_screen() tell Plugins which screen is loaded.
173 set_current_screen( $this->page_name );
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
191 // Define the step the user is on in the setup process.
192 $this->step = $this->get_current_step();
193
194 // Process any posted form data.
195 $this->process_form();
196
197 // Define current, previous and next step URLs.
198 $this->define_step_urls();
199
200 // Load any data for the current screen.
201 $this->load_screen_data();
202
203 // Load scripts and styles.
204 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
205 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
206
207 // Output custom HTML for the setup screen.
208 $this->output_header();
209 $this->output_content();
210 $this->output_footer();
211 exit;
212
213 }
214
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 /**
276 * Process submitted form data for the given setup wizard name and current step.
277 *
278 * @since 1.9.8.4
279 */
280 private function process_form() {
281
282 /**
283 * Process submitted form data for the given setup wizard name and current step.
284 *
285 * @since 1.9.8.4
286 *
287 * @param string $step Current step.
288 */
289 do_action( 'convertkit_admin_setup_wizard_process_form_' . $this->page_name, $this->step );
290
291 }
292
293 /**
294 * Populates the class variables with key information, covering:
295 * - current step in the setup process
296 * - previous, current and next step URLs.
297 *
298 * @since 1.9.8.4
299 */
300 private function define_step_urls() {
301
302 // Define the current step URL.
303 $this->current_step_url = add_query_arg(
304 array(
305 'page' => $this->page_name,
306 'convertkit-modal' => $this->is_modal(),
307 'step' => $this->step,
308 ),
309 admin_url( 'options.php' )
310 );
311
312 // Define the previous step URL if we're not on the first or last step.
313 if ( $this->get_current_step_number() > 1 && $this->get_current_step_number() < $this->get_total_steps() ) {
314 $this->previous_step_url = add_query_arg(
315 array(
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 ),
319 ),
320 admin_url( 'options.php' )
321 );
322 }
323
324 // Define the next step URL if we're not on the last page.
325 if ( $this->get_current_step_number() < $this->get_total_steps() ) {
326 $this->next_step_url = add_query_arg(
327 array(
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 ),
331 ),
332 admin_url( 'options.php' )
333 );
334 }
335
336 }
337
338 /**
339 * Load any data into class variables for the given setup wizard name and current step.
340 *
341 * @since 1.9.8.4
342 */
343 private function load_screen_data() {
344
345 /**
346 * Load any data into class variables for the given setup wizard name and current step.
347 *
348 * @since 1.9.8.4
349 *
350 * @param string $step Current step.
351 */
352 do_action( 'convertkit_admin_setup_wizard_load_screen_data_' . $this->page_name, $this->step );
353
354 }
355
356 /**
357 * Enqueue CSS when viewing the Setup screen.
358 *
359 * @since 1.9.8.4
360 */
361 public function enqueue_scripts() {
362
363 // Enqueue Select2 JS.
364 convertkit_select2_enqueue_scripts();
365
366 // Enqueue JS.
367 wp_enqueue_script( 'convertkit-admin-preview-output', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/preview-output.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 );
369
370 }
371
372 /**
373 * Enqueue CSS when viewing the setup screen.
374 *
375 * @since 1.9.8.4
376 */
377 public function enqueue_styles() {
378
379 // Enqueue WordPress default styles.
380 wp_enqueue_style( 'common' );
381 wp_enqueue_style( 'buttons' );
382 wp_enqueue_style( 'forms' );
383
384 // Enqueue Select2 CSS.
385 convertkit_select2_enqueue_styles();
386
387 // Enqueue styles for the setup wizard.
388 wp_enqueue_style( 'convertkit-admin-setup-wizard', CONVERTKIT_PLUGIN_URL . 'resources/backend/css/setup-wizard.css', array(), CONVERTKIT_PLUGIN_VERSION );
389
390 }
391
392 /**
393 * Outputs the <head> and opening <body> tag for the standalone setup screen
394 *
395 * @since 1.9.8.4
396 */
397 private function output_header() {
398
399 // Remove scripts.
400 remove_all_actions( 'admin_notices' );
401 remove_all_actions( 'all_admin_notices' );
402
403 // Enqueue scripts.
404 do_action( 'admin_enqueue_scripts' );
405
406 // Load header view.
407 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/header.php';
408
409 }
410
411 /**
412 * Outputs the HTML for the <body> section for the standalone setup screen
413 * and defines any form option data that might be needed.
414 *
415 * @since 1.9.8.4
416 */
417 private function output_content() {
418
419 // Load content view.
420 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/' . $this->page_name . '/content-' . $this->step . '.php';
421
422 }
423
424 /**
425 * Outputs the closing </body> and </html> tags, and runs some WordPress actions, for the standalone setup screen
426 *
427 * @since 1.9.8.4
428 */
429 private function output_footer() {
430
431 do_action( 'admin_print_footer_scripts' );
432
433 // Load footer view.
434 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/footer.php';
435
436 }
437
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 /**
471 * Determines if the request is for the setup screen
472 *
473 * @since 1.9.8.4
474 *
475 * @return bool Is setup screen request
476 */
477 public function is_setup_request() {
478
479 // Don't load if this is an AJAX call.
480 if ( wp_doing_ajax() || wp_doing_cron() ) {
481 return false;
482 }
483
484 // Bail if we're not on the setup screen.
485 if ( ! filter_has_var( INPUT_GET, 'page' ) ) {
486 return false;
487 }
488 if ( filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) !== $this->page_name ) {
489 return false;
490 }
491
492 return true;
493
494 }
495
496 /**
497 * Determines if the user has access to the setup wizard.
498 *
499 * @since 1.9.8.4
500 *
501 * @return bool Has access
502 */
503 public function user_has_access() {
504
505 // Bail if not logged in.
506 if ( ! is_user_logged_in() ) {
507 return false;
508 }
509
510 // Bail if the user doesn't have the required capability.
511 if ( ! current_user_can( $this->required_capability ) ) {
512 return false;
513 }
514
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 }
541
542 }
543
544 }
545