PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.0
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.0
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / models / FrmSolution.php

FrmSolution.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.0, at classes/models/FrmSolution.php

805 lines 20.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles the installation of a solution and any dependencies.
4 * This page is shown when a Formidable plugin is activated.
5 *
6 * @since 4.06.02
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 die( 'You are not allowed to call this page directly.' );
11 }
12
13 class FrmSolution {
14
15 protected $plugin_slug = '';
16
17 protected $plugin_file = '';
18
19 /**
20 * Hidden welcome page slug.
21 *
22 * @since 4.06.02
23 */
24 protected $page = '';
25
26 protected $icon = 'frm_icon_font frm_settings_icon';
27
28 public function __construct( $atts = array() ) {
29 if ( empty( $this->plugin_slug ) ) {
30 return;
31 }
32
33 add_action( 'plugins_loaded', array( $this, 'load_hooks' ), 50 );
34 add_action( 'admin_init', array( $this, 'redirect' ), 9999 );
35
36 if ( empty( $this->plugin_file ) ) {
37 $this->plugin_file = $this->plugin_slug . '.php';
38 }
39 }
40
41 /**
42 * Register all WP hooks.
43 *
44 * @since 4.06.02
45 */
46 public function load_hooks() {
47 // If user is in admin ajax or doing cron, return.
48 if ( wp_doing_cron() ) {
49 return;
50 }
51
52 add_filter( 'frm_add_settings_section', array( $this, 'add_settings' ) );
53
54 if ( wp_doing_ajax() ) {
55 return;
56 }
57
58 // If user cannot manage_options, return.
59 if ( ! current_user_can( 'frm_change_settings' ) && ! FrmAppHelper::is_formidable_admin() ) {
60 return;
61 }
62
63 add_filter( 'plugin_action_links_' . $this->plugin_slug . '/' . $this->plugin_file, array( $this, 'plugin_links' ) );
64 add_action( 'admin_menu', array( $this, 'register' ) );
65 add_action( 'admin_head', array( $this, 'hide_menu' ) );
66 }
67
68 public function plugin_links( $links ) {
69 if ( ! $this->is_complete() ) {
70 $settings = '<a href="' . esc_url( $this->settings_link() ) . '">' . __( 'Setup', 'formidable' ) . '</a>';
71 array_unshift( $links, $settings );
72 }
73
74 return $links;
75 }
76
77 /**
78 * Register the pages to be used for the Welcome screen (and tabs).
79 *
80 * These pages will be removed from the Dashboard menu, so they will
81 * not actually show. Sneaky, sneaky.
82 *
83 * @since 4.06.02
84 */
85 public function register() {
86
87 // Getting started - shows after installation.
88 add_dashboard_page(
89 esc_html( $this->page_title() ),
90 esc_html( $this->page_title() ),
91 'frm_change_settings',
92 $this->page,
93 array( $this, 'output' )
94 );
95 }
96
97 /**
98 * Removed the dashboard pages from the admin menu.
99 *
100 * This means the pages are still available to us, but hidden.
101 *
102 * @since 4.06.02
103 */
104 public function hide_menu() {
105 remove_submenu_page( 'index.php', $this->page );
106 }
107
108 protected function plugin_name() {
109 return '';
110 }
111
112 protected function page_title() {
113 return __( 'Welcome to Formidable Forms', 'formidable' );
114 }
115
116 protected function page_description() {
117 return __( 'Follow the steps below to get started.', 'formidable' );
118 }
119
120 /**
121 * Welcome screen redirect.
122 *
123 * This function checks if a new install or update has just occurred. If so,
124 * then we redirect the user to the appropriate page.
125 *
126 * @since 4.06.02
127 */
128 public function redirect() {
129
130 $current_page = FrmAppHelper::simple_get( 'page', 'sanitize_title' );
131 if ( $current_page === $this->page ) {
132 // Prevent endless loop.
133 return;
134 }
135
136 // Only do this for single site installs.
137 if ( isset( $_GET['activate-multi'] ) || is_network_admin() ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
138 return;
139 }
140
141 // Check if we should consider redirection.
142 if ( ! $this->is_current_plugin() ) {
143 return;
144 }
145
146 delete_transient( 'frm_activation_redirect' );
147
148 // Initial install.
149 wp_safe_redirect( $this->settings_link() );
150 exit;
151 }
152
153 protected function settings_link() {
154 return admin_url( 'index.php?page=' . $this->page );
155 }
156
157 /*
158 * Add page to global settings.
159 */
160 public function add_settings( $sections ) {
161 wp_enqueue_style( 'formidable-pro-fields' );
162 $sections[ $this->plugin_slug ] = array(
163 'class' => $this,
164 'function' => 'settings_page',
165 'name' => $this->plugin_name(),
166 'icon' => $this->icon,
167 'ajax' => true,
168 );
169 return $sections;
170 }
171
172 /*
173 * Output for global settings.
174 */
175 public function settings_page() {
176 $steps = $this->get_steps_data();
177 if ( ! $steps['license']['complete'] || ( isset( $steps['plugin'] ) && ! $steps['plugin']['complete'] ) ) {
178 // Redirect to the welcome page if install hasn't been done.
179 $url = $this->settings_link();
180 echo '<script>window.location.replace("' . esc_url_raw( $url ) . '");</script>';
181 return;
182 }
183
184 $all_imported = $this->is_complete( 'all' );
185
186 $step = $steps['import'];
187 $step['label'] = '';
188 $step['nested'] = true;
189
190 if ( $steps['complete']['current'] ) {
191 // Always show this step in settings.
192 $step['current'] = true;
193
194 $new_class = $all_imported ? ' button frm_hidden' : '';
195 $step['button_class'] = str_replace( 'frm_grey disabled', $new_class, $step['button_class'] );
196 }
197 if ( $all_imported ) {
198 $step['description'] = __( 'The following form(s) have been created.', 'formidable' );
199 }
200 $this->show_app_install( $step );
201
202 if ( ! $all_imported ) {
203 $step = $steps['complete'];
204 $step['current'] = false;
205 $step['button_class'] .= ' frm_grey disabled';
206 $this->show_page_links( $step );
207 }
208 }
209
210 /**
211 * Getting Started screen. Shows after first install.
212 */
213 public function output() {
214 FrmAppHelper::include_svg();
215 $this->css();
216 $class = FrmAppHelper::pro_is_installed() ? 'pro' : 'lite';
217
218 echo '<div id="frm-welcome" class="wrap frm-wrap frm-admin-plugin-landing upgrade_to_pro ' . sanitize_html_class( $class ) . '">';
219
220 $this->header();
221 $this->main_content();
222
223 echo '</div>';
224 }
225
226 /**
227 * Heading section.
228 */
229 protected function header() {
230 $size = array(
231 'height' => 90,
232 'width' => 90,
233 );
234
235 ?>
236 <section class="top">
237 <div class="frm-smtp-logos">
238 <?php FrmAppHelper::show_logo( $size ); ?>
239 <?php
240 FrmAppHelper::icon_by_class(
241 'frmfont frm_arrow_right_icon',
242 array(
243 'aria-label' => 'Install',
244 'style' => 'width:30px;height:30px;margin:0 35px;',
245 )
246 );
247 FrmAppHelper::icon_by_class(
248 'frmfont frm_wordpress_icon',
249 array(
250 'aria-label' => 'WordPress',
251 'style' => 'width:90px;height:90px;',
252 )
253 );
254 ?>
255 </div>
256 <h1><?php echo esc_html( $this->page_title() ); ?></h1>
257 <p><?php echo esc_html( $this->page_description() ); ?></p>
258 </section>
259 <?php
260 }
261
262 /**
263 * This is the welcome page content.
264 * Override me to insert different content.
265 */
266 protected function main_content() {
267 $steps = $this->get_steps_data();
268 $this->license_box( $steps['license'] );
269 if ( isset( $steps['plugin'] ) ) {
270 $this->show_plugin_install( $steps['plugin'] );
271 }
272 $this->show_app_install( $steps['import'] );
273 $this->show_page_links( $steps['complete'] );
274 }
275
276 protected function get_steps_data() {
277 $pro_installed = FrmAppHelper::pro_is_connected();
278
279 $steps = array(
280 'license' => array(
281 'label' => __( 'Connect to FormidableForms.com', 'formidable' ),
282 'description' => __( 'Create a connection to get plugin downloads.', 'formidable' ),
283 'button_label' => __( 'Connect an Account', 'formidable' ),
284 'current' => empty( $pro_installed ),
285 'complete' => $pro_installed,
286 'num' => 1,
287 ),
288 'plugin' => array(
289 'label' => __( 'Install and Activate Add-Ons', 'formidable' ),
290 'description' => __( 'Install any required add-ons from FormidableForms.com.', 'formidable' ),
291 'button_label' => __( 'Install & Activate', 'formidable' ),
292 'current' => false,
293 'complete' => false,
294 'num' => 2,
295 ),
296 'import' => array(
297 'label' => __( 'Setup Forms, Views, and Pages', 'formidable' ),
298 'description' => __( 'Build the forms, views, and pages automatically.', 'formidable' ),
299 'button_label' => __( 'Create Now', 'formidable' ),
300 'complete' => $this->is_complete(),
301 'num' => 3,
302 ),
303 'complete' => array(
304 'label' => __( 'Customize Your New Pages', 'formidable' ),
305 'description' => __( 'Make any required changes and publish the page.', 'formidable' ),
306 'button_label' => __( 'View Page', 'formidable' ),
307 'complete' => false,
308 'num' => 4,
309 ),
310 );
311
312 $this->adjust_plugin_install_step( $steps );
313
314 $has_current = false;
315 foreach ( $steps as $k => $step ) {
316 // Set the current step.
317 if ( ! isset( $step['current'] ) ) {
318 if ( $step['complete'] ) {
319 $steps[ $k ]['current'] = false;
320 } else {
321 $steps[ $k ]['current'] = ! $has_current;
322 $has_current = true;
323 }
324 } elseif ( $step['current'] ) {
325 $has_current = true;
326 }
327
328 // Set disabled buttons.
329 $class = isset( $step['button_class'] ) ? $step['button_class'] : '';
330 $class .= ' button-primary frm-button-primary';
331 if ( ! $steps[ $k ]['current'] ) {
332 $class .= ' frm_grey disabled';
333 }
334 $steps[ $k ]['button_class'] = $class;
335 }
336
337 return $steps;
338 }
339
340 protected function adjust_plugin_install_step( &$steps ) {
341 $plugins = $this->required_plugins();
342 if ( empty( $plugins ) ) {
343 unset( $steps['plugin'] );
344 $steps['import']['num'] = 2;
345 $steps['complete']['num'] = 3;
346 return;
347 }
348
349 $missing = array();
350 $rel = array();
351 foreach ( $plugins as $plugin_key ) {
352 $plugin = FrmAddonsController::install_link( $plugin_key );
353 if ( $plugin['status'] === 'active' ) {
354 continue;
355 }
356 $links[ $plugin_key ] = $plugin;
357 if ( isset( $plugin['url'] ) ) {
358 $rel[] = $plugin['url'];
359 } else {
360 // Add-on is required but not allowed.
361 $missing[] = $plugin_key;
362 }
363 }
364 if ( empty( $rel ) && empty( $missing ) ) {
365 $steps['plugin']['complete'] = true;
366 } elseif ( ! empty( $missing ) ) {
367 $steps['plugin']['error'] = sprintf(
368 /* translators: %1$s: Plugin name */
369 esc_html__( 'You need permission to download the Formidable %1$s plugin', 'formidable' ),
370 implode( ', ', $missing )
371 );
372 } else {
373 $steps['plugin']['links'] = $rel;
374 $steps['plugin']['button_class'] = 'frm-solution-multiple ';
375 }
376
377 if ( $steps['license']['complete'] && ! $steps['plugin']['complete'] ) {
378 $steps['plugin']['current'] = true;
379 }
380 }
381
382 protected function step_top( $step ) {
383 $section_class = ( ! isset( $step['current'] ) || ! $step['current'] ) ? 'frm_grey' : '';
384
385 ?>
386 <section class="step step-install <?php echo esc_attr( $section_class ); ?>">
387 <aside class="num">
388 <?php
389 if ( isset( $step['complete'] ) && $step['complete'] ) {
390 FrmAppHelper::icon_by_class(
391 'frmfont frm_step_complete_icon',
392 array(
393 /* translators: %1$s: Step number */
394 'aria-label' => sprintf( __( 'Step %1$d', 'formidable' ), $step['num'] ),
395 'style' => 'width:50px;height:50px;',
396 )
397 );
398 } else {
399 ?>
400 <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 100 100"><circle cx="50" cy="50" r="50" fill="#ccc"/><text x="50%" y="50%" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="2px" dy=".3em" font-size="3.7em"><?php echo esc_html( $step['num'] ); ?></text></svg>
401 <?php
402 }
403 ?>
404 <i class="loader hidden"></i>
405 </aside>
406 <div>
407 <?php if ( $step['label'] ) { ?>
408 <h3 class="frm-step-heading"><?php echo esc_html( $step['label'] ); ?></h3>
409 <?php } ?>
410 <p><?php echo esc_html( $step['description'] ); ?></p>
411 <?php if ( isset( $step['error'] ) ) { ?>
412 <p class="frm_error"><?php echo esc_html( $step['error'] ); ?></p>
413 <?php } ?>
414 <?php
415 }
416
417 protected function step_bottom( $step ) {
418 ?>
419 </div>
420 </section>
421 <?php
422 }
423
424 /**
425 * Generate and output Connect step section HTML.
426 */
427 protected function license_box( $step ) {
428 $this->step_top( $step );
429
430 if ( $step['complete'] ) {
431 ?>
432 <a href="#" class="<?php echo esc_attr( $step['button_class'] ); ?>">
433 <?php echo esc_html( $step['button_label'] ); ?>
434 </a>
435 <?php
436 } else {
437 FrmSettingsController::license_box();
438 }
439
440 $this->step_bottom( $step );
441 }
442
443 protected function show_plugin_install( $step ) {
444 $this->step_top( $step );
445
446 if ( ! isset( $step['error'] ) ) {
447 $rel = isset( $step['links'] ) ? $step['links'] : array();
448
449 ?>
450 <a rel="<?php echo esc_attr( implode( ',', $rel ) ); ?>" class="<?php echo esc_attr( $step['button_class'] ); ?>">
451 <?php echo esc_html( $step['button_label'] ); ?>
452 </a>
453 <?php
454 }
455
456 $this->step_bottom( $step );
457 }
458
459 protected function show_app_install( $step ) {
460 $is_complete = $step['complete'];
461 if ( ! empty( $this->form_options() ) && ! $is_complete ) {
462 $step['description'] = __( 'Select the form or view you would like to create.', 'formidable' );
463 }
464
465 $this->step_top( $step );
466
467 $api = new FrmFormApi();
468 $addons = $api->get_api_info();
469
470 $id = $this->download_id();
471 $has_file = isset( $addons[ $id ] ) && isset( $addons[ $id ]['beta'] );
472
473 if ( ! $step['current'] ) {
474 ?>
475 <a href="#" class="<?php echo esc_attr( $step['button_class'] ); ?>">
476 <?php echo esc_html( $step['button_label'] ); ?>
477 </a>
478 <?php
479
480 $this->step_bottom( $step );
481 return;
482 }
483
484 if ( ! $has_file ) {
485 echo '<p class="frm_error_style">' . esc_html__( 'We didn\'t find anything to import. Please contact our team.', 'formidable' ) . '</p>';
486 } elseif ( ! isset( $addons[ $id ]['beta']['package'] ) ) {
487 echo '<p class="frm_error_style">' . esc_html__( 'Looks like you may not have a current subscription for this solution. Please check your account.', 'formidable' ) . '</p>';
488 } else {
489 $xml = $addons[ $id ]['beta']['package'];
490 if ( is_array( $xml ) ) {
491 $xml = reset( $xml );
492 }
493
494 if ( isset( $step['nested'] ) ) {
495 echo '<fieldset id="frm-new-template" class="field-group">';
496 } else {
497 echo '<form name="frm-new-template" id="frm-new-template" method="post" class="field-group">';
498 }
499
500 ?>
501 <input type="hidden" name="link" id="frm_link" value="<?php echo esc_attr( $xml ); ?>" />
502 <input type="hidden" name="type" id="frm_action_type" value="frm_install_template" />
503 <input type="hidden" name="template_name" id="frm_template_name" value="" />
504 <input type="hidden" name="template_desc" id="frm_template_desc" value="" />
505 <input type="hidden" name="redirect" value="0" />
506 <input type="hidden" name="show_response" value="frm_install_error" />
507 <?php
508 $this->show_form_options( $xml );
509 $this->show_view_options();
510
511 if ( ! $this->is_complete( 'all' ) ) {
512 // Don't show on the settings page when complete.
513 $this->show_page_options();
514 }
515 ?>
516 <p>
517 <button <?php echo esc_html( isset( $step['nested'] ) ? '' : 'type="submit" ' ); ?>class="<?php echo esc_attr( $step['button_class'] ); ?>">
518 <?php echo esc_html( $step['button_label'] ); ?>
519 </button>
520 </p>
521 <p id="frm_install_error" class="frm_error_style frm_hidden"></p>
522 <?php
523 if ( isset( $step['nested'] ) ) {
524 echo '</fieldset>';
525 } else {
526 echo '</form>';
527 }
528 }
529
530 $this->step_bottom( $step );
531 }
532
533 protected function show_form_options( $xml ) {
534 $this->show_import_options( $this->form_options(), 'form', $xml );
535 }
536
537 protected function show_view_options() {
538 $this->show_import_options( $this->view_options(), 'view' );
539 }
540
541 protected function show_import_options( $options, $importing, $xml = '' ) {
542 if ( empty( $options ) ) {
543 return;
544 }
545
546 $imported = $this->previously_imported_forms();
547 $count = count( $options );
548 foreach ( $options as $info ) {
549 // Count the number of options displayed for css.
550 if ( $count > 1 && ! isset( $info['img'] ) ) {
551 $count --;
552 }
553 }
554 $width = floor( ( 533 - ( ( $count - 1 ) * 20 ) ) / $count );
555 unset( $count );
556
557 $selected = false;
558
559 include( FrmAppHelper::plugin_path() . '/classes/views/solutions/_import.php' );
560 }
561
562 protected function show_page_options() {
563 $pages = $this->needed_pages();
564 if ( empty( $pages ) ) {
565 return;
566 }
567
568 echo '<h3>Choose New Page Title</h3>';
569 foreach ( $pages as $page ) {
570 ?>
571 <p>
572 <label for="pages_<?php echo esc_html( $page['type'] ); ?>">
573 <?php echo esc_html( $page['label'] ); ?>
574 </label>
575 <input type="text" name="pages[<?php echo esc_html( $page['type'] ); ?>]" value="<?php echo esc_attr( $page['name'] ); ?>" id="pages_<?php echo esc_html( $page['type'] ); ?>" required />
576 </p>
577 <?php
578 }
579 }
580
581 protected function show_page_links( $step ) {
582 if ( $step['current'] ) {
583 return;
584 }
585
586 $this->step_top( $step );
587
588 ?>
589 <a href="#" target="_blank" rel="noopener" id="frm-redirect-link" class="<?php echo esc_attr( $step['button_class'] ); ?>">
590 <?php echo esc_html( $step['button_label'] ); ?>
591 </a>
592 <?php
593
594 $this->step_bottom( $step );
595 }
596
597 /**
598 * Only show the content for the correct plugin.
599 */
600 protected function is_current_plugin() {
601 $to_redirect = get_transient( 'frm_activation_redirect' );
602 return $to_redirect === $this->plugin_slug && empty( $this->is_complete() );
603 }
604
605 /**
606 * Override this function to indicate when install is complete.
607 */
608 protected function is_complete( $count = 1 ) {
609 $imported = $this->previously_imported_forms();
610 if ( $count === 'all' ) {
611 return count( $imported ) >= count( $this->form_options() );
612 }
613 return ! empty( $imported );
614 }
615
616 /**
617 * Get an array of all of the forms that have been imported.
618 *
619 * @return array
620 */
621 protected function previously_imported_forms() {
622 $imported = array();
623 $forms = $this->form_options();
624 foreach ( $forms as $form ) {
625 $was_imported = isset( $form['form'] ) ? FrmForm::get_id_by_key( $form['form'] ) : false;
626 if ( $was_imported ) {
627 $imported[ $form['form'] ] = $was_imported;
628 }
629 }
630
631 return $imported;
632 }
633
634 /**
635 * In the new plugin has any dependencies, include them here.
636 */
637 protected function required_plugins() {
638 return array();
639 }
640
641 /**
642 * This needs to be overridden.
643 */
644 protected function download_id() {
645 return 0;
646 }
647
648 /**
649 * Give options for which forms to import.
650 */
651 protected function form_options() {
652 /**
653 * Example:
654 * array(
655 * 'unique-key' => array(
656 * 'keys' => 'forms keys here',
657 * 'name' => 'displayed label here',
658 * 'img' => 'svg code',
659 * ),
660 * )
661 */
662 return array();
663 }
664
665 /**
666 * Give options for which view to use.
667 */
668 protected function view_options() {
669 return array();
670 }
671
672 /**
673 * If the pages aren't imported automatically, set the page names.
674 */
675 protected function needed_pages() {
676 /**
677 * Example:
678 * array(
679 * array(
680 * 'label' => 'Page Name',
681 * 'name' => 'Default name',
682 * 'type' => 'form' or 'view',
683 * ),
684 * )
685 */
686
687 return array();
688 }
689
690 private function css() {
691 wp_enqueue_style( 'formidable-pro-fields' );
692 ?>
693 <style>
694 #frm-welcome *, #frm-welcome *::before, #frm-welcome *::after {
695 -webkit-box-sizing: border-box;
696 -moz-box-sizing: border-box;
697 box-sizing: border-box;
698 }
699 #frm-welcome{
700 width: 700px;
701 margin: 0 auto;
702 }
703 #frm-welcome p {
704 font-size: 15px;
705 }
706 #frm-welcome section{
707 margin: 50px 0;
708 text-align: left;
709 clear: both;
710 }
711 #frm-welcome .top{
712 text-align: center;
713 }
714 .frm-smtp-logos {
715 margin-bottom: 38px;
716 }
717 .frm-smtp-logos svg {
718 vertical-align: middle;
719 }
720 #frm-welcome .top h1 {
721 font-size: 26px;
722 font-weight: 600;
723 margin-bottom: 0;
724 padding: 0;
725 }
726 #frm-welcome .top p {
727 font-size: 17px;
728 color: #777;
729 margin-top: .5em;
730 }
731 #frm-welcome .screenshot ul {
732 display: inline-block;
733 margin: 0 0 0 30px;
734 list-style-type: none;
735 max-width: calc(100% - 350px);
736 }
737 #frm-welcome .screenshot li {
738 margin: 16px 0;
739 padding: 0;
740 font-size: 15px;
741 color: #777;
742 }
743 #frm-welcome .screenshot .cont img {
744 max-width: 100%;
745 display: block;
746 }
747 #frm-welcome .screenshot .cont {
748 display: inline-block;
749 position: relative;
750 width: 315px;
751 padding: 5px;
752 background-color: #fff;
753 border-radius: 3px;
754 }
755 #frm-welcome .step,
756 #frm-welcome .screenshot .cont {
757 -webkit-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.05);
758 -moz-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.05);
759 box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.05);
760 }
761 #frm-welcome .step {
762 background-color: #F9F9F9;
763 border: 1px solid #E5E5E5;
764 margin: 0 0 25px;
765 }
766 #frm-welcome .screenshot > *,
767 #frm-welcome .step > * {
768 vertical-align: middle;
769 }
770 #frm-welcome .step p {
771 font-size: 16px;
772 color: #777777;
773 }
774 #frm-welcome .step .num {
775 display: inline-block;
776 position: relative;
777 width: 100px;
778 height: 50px;
779 text-align: center;
780 }
781 #frm-welcome .step > div {
782 display: inline-block;
783 width: calc(100% - 104px);
784 background-color: #fff;
785 padding: 30px;
786 border-left: 1px solid #eee;
787 }
788 #frm-welcome .step h3.frm-step-heading {
789 font-size: 24px;
790 line-height: 22px;
791 margin-top: 0;
792 margin-bottom: 15px;
793 }
794 #frm-welcome .button.disabled {
795 cursor: default;
796 }
797 #frm-welcome #frm-using-lite {
798 display: none;
799 }
800 </style>
801 <?php
802 }
803
804 }
805