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

461 lines 10.6 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 * The required user capability to access the setup wizard.
42 *
43 * @since 1.9.8.4
44 *
45 * @var string
46 */
47 public $required_capability = 'activate_plugins';
48
49 /**
50 * The current step in the setup process the user is on.
51 *
52 * @since 1.9.8.4
53 *
54 * @var int
55 */
56 public $step = 1;
57
58 /**
59 * The programmatic name of the setup screen.
60 *
61 * @since 1.9.8.4
62 *
63 * @var bool|string
64 */
65 public $page_name = false;
66
67 /**
68 * Whether the wizard is being served within a modal or
69 * new window.
70 *
71 * @since 2.2.6
72 *
73 * @var bool
74 */
75 public $is_modal = false;
76
77 /**
78 * The URL to take the user to when they click the Exit link.
79 *
80 * @since 1.9.8.4
81 *
82 * @var bool|string
83 */
84 public $exit_url = false;
85
86 /**
87 * Holds the URL for the current step in the setup process.
88 *
89 * @since 1.9.8.4
90 *
91 * @var bool|string
92 */
93 public $current_step_url = false;
94
95 /**
96 * Holds the URL to the next step in the setup process.
97 *
98 * @since 1.9.8.4
99 *
100 * @var bool|string
101 */
102 public $next_step_url = false;
103
104 /**
105 * Holds the URL to the previous step in the setup process.
106 *
107 * @since 1.9.8.4
108 *
109 * @var bool|string
110 */
111 public $previous_step_url = false;
112
113 /**
114 * Registers action and filter hooks.
115 *
116 * @since 1.9.8.4
117 */
118 public function __construct() {
119
120 // Bail if no page name is defined.
121 if ( $this->page_name === false ) {
122 return;
123 }
124
125 // Define actions to register the setup screen.
126 add_action( 'admin_menu', array( $this, 'register_screen' ) );
127 add_action( 'admin_head', array( $this, 'hide_screen_from_menu' ) );
128 add_action( 'admin_init', array( $this, 'maybe_load_setup_screen' ) );
129
130 }
131
132 /**
133 * Register the setup screen in WordPress' Dashboard, so that index.php?page={$this->page_name}
134 * does not 404 when in the WordPress Admin interface.
135 *
136 * @since 1.9.8.4
137 */
138 public function register_screen() {
139
140 add_dashboard_page( '', '', 'edit_posts', $this->page_name, '__return_false' );
141
142 }
143
144 /**
145 * Hides the menu registered when register_screen() above is called, otherwise
146 * we would have a blank submenu entry below the Dashboard menu.
147 *
148 * @since 1.9.8.4
149 */
150 public function hide_screen_from_menu() {
151
152 remove_submenu_page( 'index.php', $this->page_name );
153
154 }
155
156 /**
157 * Loads the setup screen if the request URL is for this class
158 *
159 * @since 1.9.8.4
160 */
161 public function maybe_load_setup_screen() {
162
163 // Bail if this isn't a request for the setup screen.
164 if ( ! $this->is_setup_request() ) {
165 return;
166 }
167
168 // Redirect back to the Dashboard if the user doesn't have the required capability to access this setup wizard.
169 if ( ! $this->user_has_access() ) {
170 wp_safe_redirect( admin_url( 'index.php' ) );
171 exit;
172 }
173
174 // Define current screen, so that calls to get_current_screen() tell Plugins which screen is loaded.
175 set_current_screen( $this->page_name );
176
177 // If the convertkit-modal parameter exists and is 1, set the flag to denote
178 // this wizard is served in a modal.
179 if ( array_key_exists( 'convertkit-modal', $_REQUEST ) && $_REQUEST['convertkit-modal'] === '1' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
180 $this->is_modal = true;
181 }
182
183 // Define the step the user is on in the setup process.
184 $this->step = ( isset( $_REQUEST['step'] ) ? absint( $_REQUEST['step'] ) : 1 ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
185
186 // Process any posted form data.
187 $this->process_form();
188
189 // Define current, previous and next step URLs.
190 $this->define_step_urls();
191
192 // Load any data for the current screen.
193 $this->load_screen_data();
194
195 // Load scripts and styles.
196 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
197 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
198
199 // Output custom HTML for the setup screen.
200 $this->output_header();
201 $this->output_content();
202 $this->output_footer();
203 exit;
204
205 }
206
207 /**
208 * Process submitted form data for the given setup wizard name and current step.
209 *
210 * @since 1.9.8.4
211 */
212 private function process_form() {
213
214 // Run security checks.
215 if ( ! isset( $_POST['_wpnonce'] ) ) {
216 return;
217 }
218 if ( ! wp_verify_nonce( sanitize_key( $_POST['_wpnonce'] ), $this->page_name ) ) {
219 $this->error = __( 'Invalid nonce specified.', 'convertkit' );
220 return;
221 }
222
223 /**
224 * Process submitted form data for the given setup wizard name and current step.
225 *
226 * @since 1.9.8.4
227 *
228 * @param int $step Current step number.
229 */
230 do_action( 'convertkit_admin_setup_wizard_process_form_' . $this->page_name, $this->step );
231
232 }
233
234 /**
235 * Populates the class variables with key information, covering:
236 * - current step in the setup process
237 * - previous, current and next step URLs.
238 *
239 * @since 1.9.8.4
240 */
241 private function define_step_urls() {
242
243 // Define the current step URL.
244 $this->current_step_url = add_query_arg(
245 array(
246 'page' => $this->page_name,
247 'convertkit-modal' => $this->is_modal(),
248 'step' => $this->step,
249 ),
250 admin_url( 'index.php' )
251 );
252
253 // Define the previous step URL if we're not on the first or last step.
254 if ( $this->step > 1 && $this->step < count( $this->steps ) ) {
255 $this->previous_step_url = add_query_arg(
256 array(
257 'page' => $this->page_name,
258 'convertkit-modal' => $this->is_modal(),
259 'step' => ( $this->step - 1 ),
260 ),
261 admin_url( 'index.php' )
262 );
263 }
264
265 // Define the next step URL if we're not on the last page.
266 if ( $this->step < count( $this->steps ) ) {
267 $this->next_step_url = add_query_arg(
268 array(
269 'page' => $this->page_name,
270 'convertkit-modal' => $this->is_modal(),
271 'step' => ( $this->step + 1 ),
272 ),
273 admin_url( 'index.php' )
274 );
275 }
276
277 }
278
279 /**
280 * Load any data into class variables for the given setup wizard name and current step.
281 *
282 * @since 1.9.8.4
283 */
284 private function load_screen_data() {
285
286 /**
287 * Load any data into class variables for the given setup wizard name and current step.
288 *
289 * @since 1.9.8.4
290 *
291 * @param int $step Current step number.
292 */
293 do_action( 'convertkit_admin_setup_wizard_load_screen_data_' . $this->page_name, $this->step );
294
295 }
296
297 /**
298 * Enqueue CSS when viewing the Setup screen.
299 *
300 * @since 1.9.8.4
301 */
302 public function enqueue_scripts() {
303
304 // Enqueue Select2 JS.
305 convertkit_select2_enqueue_scripts();
306
307 // Enqueue JS.
308 wp_enqueue_script( 'convertkit-admin-preview-output', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/preview-output.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
309 wp_enqueue_script( 'convertkit-admin-setup-wizard', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/setup-wizard.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
310
311 }
312
313 /**
314 * Enqueue CSS when viewing the setup screen.
315 *
316 * @since 1.9.8.4
317 */
318 public function enqueue_styles() {
319
320 // Enqueue WordPress default styles.
321 wp_enqueue_style( 'common' );
322 wp_enqueue_style( 'buttons' );
323 wp_enqueue_style( 'forms' );
324
325 // Enqueue Select2 CSS.
326 convertkit_select2_enqueue_styles();
327
328 // Enqueue styles for the setup wizard.
329 wp_enqueue_style( 'convertkit-admin-setup-wizard', CONVERTKIT_PLUGIN_URL . 'resources/backend/css/setup-wizard.css', array(), CONVERTKIT_PLUGIN_VERSION );
330
331 }
332
333 /**
334 * Outputs the <head> and opening <body> tag for the standalone setup screen
335 *
336 * @since 1.9.8.4
337 */
338 private function output_header() {
339
340 // Remove scripts.
341 remove_all_actions( 'admin_notices' );
342 remove_all_actions( 'all_admin_notices' );
343
344 // Enqueue scripts.
345 do_action( 'admin_enqueue_scripts' );
346
347 // Load header view.
348 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/header.php';
349
350 }
351
352 /**
353 * Outputs the HTML for the <body> section for the standalone setup screen
354 * and defines any form option data that might be needed.
355 *
356 * @since 1.9.8.4
357 */
358 private function output_content() {
359
360 // Load content view.
361 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/' . $this->page_name . '/content-' . $this->step . '.php';
362
363 }
364
365 /**
366 * Outputs the closing </body> and </html> tags, and runs some WordPress actions, for the standalone setup screen
367 *
368 * @since 1.9.8.4
369 */
370 private function output_footer() {
371
372 do_action( 'admin_print_footer_scripts' );
373
374 // Load footer view.
375 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/footer.php';
376
377 }
378
379 /**
380 * Whether this wizard is served in a modal window.
381 *
382 * @since 2.2.6
383 *
384 * @return bool
385 */
386 public function is_modal() {
387
388 return $this->is_modal;
389
390 }
391
392 /**
393 * Outputs HTML to close the current window, due to it being opened
394 * by window.open().
395 *
396 * @since 2.2.6
397 */
398 public function maybe_close_modal() {
399
400 // Sanity check we requested a modal.
401 if ( ! $this->is_modal() ) {
402 return;
403 }
404
405 // Load HTML to close the modal.
406 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/setup-wizard/close-modal.php';
407 exit;
408
409 }
410
411 /**
412 * Determines if the request is for the setup screen
413 *
414 * @since 1.9.8.4
415 *
416 * @return bool Is setup screen request
417 */
418 public function is_setup_request() {
419
420 // Don't load if this is an AJAX call.
421 if ( wp_doing_ajax() || wp_doing_cron() ) {
422 return false;
423 }
424
425 // Bail if we're not on the setup screen.
426 if ( ! isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
427 return false;
428 }
429 if ( sanitize_text_field( $_GET['page'] ) !== $this->page_name ) { // phpcs:ignore WordPress.Security.NonceVerification
430 return false;
431 }
432
433 return true;
434
435 }
436
437 /**
438 * Determines if the user has access to the setup wizard.
439 *
440 * @since 1.9.8.4
441 *
442 * @return bool Has access
443 */
444 public function user_has_access() {
445
446 // Bail if not logged in.
447 if ( ! is_user_logged_in() ) {
448 return false;
449 }
450
451 // Bail if the user doesn't have the required capability.
452 if ( ! current_user_can( $this->required_capability ) ) {
453 return false;
454 }
455
456 return true;
457
458 }
459
460 }
461