| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- <?php
- /**
- * Settings class.
- *
- * @since 1.0.0
- */
- class WPForms_Settings {
- /**
- * The current active tab.
- *
- * @since 1.3.9
- *
- * @var string
- */
- public $view;
- /**
- * Primary class constructor.
- *
- * @since 1.0.0
- */
- public function __construct() {
- // Maybe load settings page.
- add_action( 'admin_init', array( $this, 'init' ) );
- }
- /**
- * Determine if the user is viewing the settings page, if so, party on.
- *
- * @since 1.0.0
- */
- public function init() {
- // Only load if we are actually on the settings page.
- if ( ! wpforms_is_admin_page( 'settings' ) ) {
- return;
- }
- // Include API callbacks and functions.
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/settings-api.php';
- // Watch for triggered save.
- $this->save_settings();
- // Determine the current active settings tab.
- $this->view = isset( $_GET['view'] ) ? sanitize_key( wp_unslash( $_GET['view'] ) ) : 'general'; // phpcs:ignore WordPress.CSRF.NonceVerification
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ) );
- add_action( 'wpforms_admin_page', array( $this, 'output' ) );
- // Monitor custom tables.
- $this->monitor_custom_tables();
- // Hook for addons.
- do_action( 'wpforms_settings_init', $this );
- }
- /**
- * Sanitize and save settings.
- *
- * @since 1.3.9
- */
- public function save_settings() {
- // Check nonce and other various security checks.
- if ( ! isset( $_POST['wpforms-settings-submit'] ) || empty( $_POST['nonce'] ) ) {
- return;
- }
- if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wpforms-settings-nonce' ) ) {
- return;
- }
- if ( ! wpforms_current_user_can() ) {
- return;
- }
- if ( empty( $_POST['view'] ) ) {
- return;
- }
- $current_view = sanitize_key( $_POST['view'] );
- // Get registered fields and current settings.
- $fields = $this->get_registered_settings( $current_view );
- $settings = get_option( 'wpforms_settings', array() );
- // Views excluded from saving list.
- $exclude_views = apply_filters( 'wpforms_settings_exclude_view', array(), $fields, $settings );
- if ( is_array( $exclude_views ) && in_array( $current_view, $exclude_views, true ) ) {
- // Run a custom save processing for excluded views.
- do_action( 'wpforms_settings_custom_process', $current_view, $fields, $settings );
- return;
- }
- if ( empty( $fields ) || ! is_array( $fields ) ) {
- return;
- }
- // Sanitize and prep each field.
- foreach ( $fields as $id => $field ) {
- // Certain field types are not valid for saving and are skipped.
- $exclude = apply_filters( 'wpforms_settings_exclude_type', array( 'content', 'license', 'providers' ) );
- if ( empty( $field['type'] ) || in_array( $field['type'], $exclude, true ) ) {
- continue;
- }
- // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
- $value = isset( $_POST[ $id ] ) ? trim( wp_unslash( $_POST[ $id ] ) ) : false;
- $value_prev = isset( $settings[ $id ] ) ? $settings[ $id ] : false;
- // Custom filter can be provided for sanitizing, otherwise use defaults.
- if ( ! empty( $field['filter'] ) && is_callable( $field['filter'] ) ) {
- $value = call_user_func( $field['filter'], $value, $id, $field, $value_prev );
- } else {
- switch ( $field['type'] ) {
- case 'checkbox':
- $value = (bool) $value;
- break;
- case 'image':
- $value = esc_url_raw( $value );
- break;
- case 'color':
- $value = wpforms_sanitize_hex_color( $value );
- break;
- case 'number':
- $value = (float) $value;
- break;
- case 'text':
- case 'radio':
- case 'select':
- default:
- $value = sanitize_text_field( $value );
- break;
- }
- }
- // Add to settings.
- $settings[ $id ] = $value;
- }
- // Save settings.
- wpforms_update_settings( $settings );
- \WPForms\Admin\Notice::success( esc_html__( 'Settings were successfully saved.', 'wpforms-lite' ) );
- }
- /**
- * Enqueue assets for the settings page.
- *
- * @since 1.0.0
- */
- public function enqueues() {
- do_action( 'wpforms_settings_enqueue' );
- }
- /**
- * Return registered settings tabs.
- *
- * @since 1.3.9
- *
- * @return array
- */
- public function get_tabs() {
- $tabs = [
- 'general' => [
- 'name' => esc_html__( 'General', 'wpforms-lite' ),
- 'form' => true,
- 'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
- ],
- 'email' => [
- 'name' => esc_html__( 'Email', 'wpforms-lite' ),
- 'form' => true,
- 'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
- ],
- 'validation' => [
- 'name' => esc_html__( 'Validation', 'wpforms-lite' ),
- 'form' => true,
- 'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
- ],
- 'integrations' => [
- 'name' => esc_html__( 'Integrations', 'wpforms-lite' ),
- 'form' => false,
- 'submit' => false,
- ],
- 'geolocation' => [
- 'name' => esc_html__( 'Geolocation', 'wpforms-lite' ),
- 'form' => false,
- 'submit' => false,
- ],
- 'misc' => [
- 'name' => esc_html__( 'Misc', 'wpforms-lite' ),
- 'form' => true,
- 'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
- ],
- ];
- return apply_filters( 'wpforms_settings_tabs', $tabs );
- }
- /**
- * Output tab navigation area.
- *
- * @since 1.3.9
- */
- public function tabs() {
- $tabs = $this->get_tabs();
- echo '<ul class="wpforms-admin-tabs">';
- foreach ( $tabs as $id => $tab ) {
- $active = $id === $this->view ? 'active' : '';
- $link = add_query_arg( 'view', $id, admin_url( 'admin.php?page=wpforms-settings' ) );
- echo '<li><a href="' . esc_url_raw( $link ) . '" class="' . esc_attr( $active ) . '">' . esc_html( $tab['name'] ) . '</a></li>';
- }
- echo '</ul>';
- }
- /**
- * Return all the default registered settings fields.
- *
- * @since 1.3.9
- *
- * @param string $view The current view (tab) on Settings page.
- *
- * @return array
- */
- public function get_registered_settings( $view = '' ) {
- $defaults = [
- // General Settings tab.
- 'general' => [
- 'license-heading' => [
- 'id' => 'license-heading',
- 'content' => '<h4>' . esc_html__( 'License', 'wpforms-lite' ) . '</h4><p>' . esc_html__( 'Your license key provides access to updates and addons.', 'wpforms-lite' ) . '</p>',
- 'type' => 'content',
- 'no_label' => true,
- 'class' => [ 'section-heading' ],
- ],
- 'license-key' => [
- 'id' => 'license-key',
- 'name' => esc_html__( 'License Key', 'wpforms-lite' ),
- 'type' => 'license',
- ],
- 'general-heading' => [
- 'id' => 'general-heading',
- 'content' => '<h4>' . esc_html__( 'General', 'wpforms-lite' ) . '</h4>',
- 'type' => 'content',
- 'no_label' => true,
- 'class' => [ 'section-heading', 'no-desc' ],
- ],
- 'disable-css' => [
- 'id' => 'disable-css',
- 'name' => esc_html__( 'Include Form Styling', 'wpforms-lite' ),
- 'desc' => sprintf(
- wp_kses( /* translators: %s - WPForms.com form styling setting URL. */
- __( 'Determines which CSS files to load and use for the site (<a href="%s" target="_blank" rel="noopener noreferrer">please see our tutorial for full details</a>). "Base and Form Theme Styling" is recommended, unless you are experienced with CSS or instructed by support to change settings. ', 'wpforms-lite' ),
- [
- 'a' => [
- 'href' => [],
- 'target' => [],
- 'rel' => [],
- ],
- ]
- ),
- 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/'
- ),
- 'type' => 'select',
- 'choicesjs' => true,
- 'default' => 1,
- 'options' => [
- 1 => esc_html__( 'Base and form theme styling', 'wpforms-lite' ),
- 2 => esc_html__( 'Base styling only', 'wpforms-lite' ),
- 3 => esc_html__( 'No styling', 'wpforms-lite' ),
- ],
- ],
- 'global-assets' => [
- 'id' => 'global-assets',
- 'name' => esc_html__( 'Load Assets Globally', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Check this option to load WPForms assets site-wide. Only check if your site is having compatibility issues or instructed to by support.', 'wpforms-lite' ),
- 'type' => 'checkbox',
- ],
- 'gdpr-heading' => [
- 'id' => 'GDPR',
- 'content' => '<h4>' . esc_html__( 'GDPR', 'wpforms-lite' ) . '</h4>',
- 'type' => 'content',
- 'no_label' => true,
- 'class' => [ 'section-heading', 'no-desc' ],
- ],
- 'gdpr' => [
- 'id' => 'gdpr',
- 'name' => esc_html__( 'GDPR Enhancements', 'wpforms-lite' ),
- 'desc' => sprintf(
- wp_kses( /* translators: %s - WPForms.com GDPR documentation URL. */
- __( 'Check this option to enable GDPR related features and enhancements. <a href="%s" target="_blank" rel="noopener noreferrer">Read our GDPR documentation</a> to learn more.', 'wpforms-lite' ),
- [
- 'a' => [
- 'href' => [],
- 'target' => [],
- 'rel' => [],
- ],
- ]
- ),
- 'https://wpforms.com/docs/how-to-create-gdpr-compliant-forms/'
- ),
- 'type' => 'checkbox',
- ],
- ],
- // Email settings tab.
- 'email' => [
- 'email-heading' => [
- 'id' => 'email-heading',
- 'content' => '<h4>' . esc_html__( 'Email', 'wpforms-lite' ) . '</h4>',
- 'type' => 'content',
- 'no_label' => true,
- 'class' => [ 'section-heading', 'no-desc' ],
- ],
- 'email-async' => [
- 'id' => 'email-async',
- 'name' => esc_html__( 'Optimize Email Sending', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Check this option to enable sending emails asynchronously, which can make submission processing faster.', 'wpforms-lite' ),
- 'type' => 'checkbox',
- ],
- 'email-template' => [
- 'id' => 'email-template',
- 'name' => esc_html__( 'Template', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Determines how email notifications will be formatted. HTML Templates are the default.', 'wpforms-lite' ),
- 'type' => 'radio',
- 'default' => 'default',
- 'options' => [
- 'default' => esc_html__( 'HTML Template', 'wpforms-lite' ),
- 'none' => esc_html__( 'Plain text', 'wpforms-lite' ),
- ],
- ],
- 'email-header-image' => [
- 'id' => 'email-header-image',
- 'name' => esc_html__( 'Header Image', 'wpforms-lite' ),
- 'desc' => wp_kses( __( 'Upload or choose a logo to be displayed at the top of email notifications.<br>Recommended size is 300x100 or smaller for best support on all devices.', 'wpforms-lite' ), [ 'br' => [] ] ),
- 'type' => 'image',
- ],
- 'email-background-color' => [
- 'id' => 'email-background-color',
- 'name' => esc_html__( 'Background Color', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Customize the background color of the HTML email template.', 'wpforms-lite' ),
- 'type' => 'color',
- 'default' => '#e9eaec',
- ],
- 'email-carbon-copy' => [
- 'id' => 'email-carbon-copy',
- 'name' => esc_html__( 'Carbon Copy', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Check this option to enable the ability to CC: email addresses in the form notification settings.', 'wpforms-lite' ),
- 'type' => 'checkbox',
- ],
- ],
- // Validation messages settings tab.
- 'validation' => [
- 'validation-heading' => [
- 'id' => 'validation-heading',
- 'content' => sprintf( /* translators: %s - WPForms.com smart tags documentation URL. */
- esc_html__( '%1$s These messages are displayed to the users as they fill out a form in real-time. Messages can include plain text and/or %2$sSmart Tags%3$s.', 'wpforms-lite' ),
- '<h4>' . esc_html__( 'Validation Messages', 'wpforms-lite' )
- . '</h4><p>',
- '<a href="https://wpforms.com/docs/how-to-use-smart-tags-in-wpforms/#smart-tags" target="_blank" rel="noopener noreferrer">',
- '</a>'
- ),
- 'type' => 'content',
- 'no_label' => true,
- 'class' => [ 'section-heading' ],
- ],
- 'validation-required' => [
- 'id' => 'validation-required',
- 'name' => esc_html__( 'Required', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'This field is required.', 'wpforms-lite' ),
- ],
- 'validation-url' => [
- 'id' => 'validation-url',
- 'name' => esc_html__( 'Website URL', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'Please enter a valid URL.', 'wpforms-lite' ),
- ],
- 'validation-email' => [
- 'id' => 'validation-email',
- 'name' => esc_html__( 'Email', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'Please enter a valid email address.', 'wpforms-lite' ),
- ],
- 'validation-email-suggestion' => [
- 'id' => 'validation-email-suggestion',
- 'name' => esc_html__( 'Email Suggestion', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => sprintf( /* translators: %s - suggested email address. */
- esc_html__( 'Did you mean %s?', 'wpforms-lite' ),
- '{suggestion}'
- ),
- ],
- 'validation-email-restricted' => [
- 'id' => 'validation-email-restricted',
- 'name' => esc_html__( 'Email Restricted', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'This email address is not allowed.', 'wpforms-lite' ),
- ],
- 'validation-number' => [
- 'id' => 'validation-number',
- 'name' => esc_html__( 'Number', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'Please enter a valid number.', 'wpforms-lite' ),
- ],
- 'validation-number-positive' => [
- 'id' => 'validation-number-positive',
- 'name' => esc_html__( 'Number Positive', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'Please enter a valid positive number.', 'wpforms-lite' ),
- ],
- 'validation-confirm' => [
- 'id' => 'validation-confirm',
- 'name' => esc_html__( 'Confirm Value', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'Field values do not match.', 'wpforms-lite' ),
- ],
- 'validation-input-mask-incomplete' => [
- 'id' => 'validation-input-mask-incomplete',
- 'name' => esc_html__( 'Input Mask Incomplete', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'Please fill out all blanks.', 'wpforms-lite' ),
- ],
- 'validation-check-limit' => [
- 'id' => 'validation-check-limit',
- 'name' => esc_html__( 'Checkbox Selection Limit', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => esc_html__( 'You have exceeded the number of allowed selections: {#}.', 'wpforms-lite' ),
- ],
- 'validation-character-limit' => [
- 'id' => 'validation-character-limit',
- 'name' => esc_html__( 'Character Limit', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => sprintf( /* translators: %1$s - characters limit, %2$s - number of characters left. */
- esc_html__( 'Limit is %1$s characters. Characters remaining: %2$s.', 'wpforms-lite' ),
- '{limit}',
- '{remaining}'
- ),
- ],
- 'validation-word-limit' => [
- 'id' => 'validation-word-limit',
- 'name' => esc_html__( 'Word Limit', 'wpforms-lite' ),
- 'type' => 'text',
- 'default' => sprintf( /* translators: %1$s - words limit, %2$s - number of words left. */
- esc_html__( 'Limit is %1$s words. Words remaining: %2$s.', 'wpforms-lite' ),
- '{limit}',
- '{remaining}'
- ),
- ],
- ],
- // Provider integrations settings tab.
- 'integrations' => [
- 'integrations-heading' => [
- 'id' => 'integrations-heading',
- 'content' => '<h4>' . esc_html__( 'Integrations', 'wpforms-lite' ) . '</h4><p>' . esc_html__( 'Manage integrations with popular providers such as Constant Contact, Mailchimp, Zapier, and more.', 'wpforms-lite' ) . '</p>',
- 'type' => 'content',
- 'no_label' => true,
- 'class' => [ 'section-heading' ],
- ],
- 'integrations-providers' => [
- 'id' => 'integrations-providers',
- 'content' => '<h4>' . esc_html__( 'Integrations', 'wpforms-lite' ) . '</h4><p>' . esc_html__( 'Manage integrations with popular providers such as Constant Contact, Mailchimp, Zapier, and more.', 'wpforms-lite' ) . '</p>',
- 'type' => 'providers',
- 'wrap' => 'none',
- ],
- ],
- // Misc. settings tab.
- 'misc' => [
- 'misc-heading' => [
- 'id' => 'misc-heading',
- 'content' => '<h4>' . esc_html__( 'Misc', 'wpforms-lite' ) . '</h4>',
- 'type' => 'content',
- 'no_label' => true,
- 'class' => [ 'section-heading', 'no-desc' ],
- ],
- 'hide-announcements' => [
- 'id' => 'hide-announcements',
- 'name' => esc_html__( 'Hide Announcements', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Check this option to hide plugin announcements and update details.', 'wpforms-lite' ),
- 'type' => 'checkbox',
- ],
- 'hide-admin-bar' => [
- 'id' => 'hide-admin-bar',
- 'name' => esc_html__( 'Hide Admin Bar Menu', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Check this option to hide the WPForms admin bar menu.', 'wpforms-lite' ),
- 'type' => 'checkbox',
- ],
- 'uninstall-data' => [
- 'id' => 'uninstall-data',
- 'name' => esc_html__( 'Uninstall WPForms', 'wpforms-lite' ),
- 'desc' => esc_html__( 'Check this option to remove ALL WPForms data upon plugin deletion. All forms and settings will be unrecoverable.', 'wpforms-lite' ),
- 'type' => 'checkbox',
- ],
- ],
- ];
- // TODO: move this to Pro.
- if ( wpforms()->pro ) {
- $defaults['misc']['uninstall-data']['desc'] = esc_html__( 'Check this option to remove ALL WPForms data upon plugin deletion. All forms, entries, and uploaded files will be unrecoverable.', 'wpforms-lite' );
- }
- $defaults = apply_filters( 'wpforms_settings_defaults', $defaults );
- // Take care of invalid views.
- if ( ! empty( $view ) && ! array_key_exists( $view, $defaults ) ) {
- $this->view = key( $defaults );
- return reset( $defaults );
- }
- return empty( $view ) ? $defaults : $defaults[ $view ];
- }
- /**
- * Return array containing markup for all the appropriate settings fields.
- *
- * @since 1.3.9
- *
- * @param string $view View slug.
- *
- * @return array
- */
- public function get_settings_fields( $view = '' ) {
- $fields = array();
- $settings = $this->get_registered_settings( $view );
- foreach ( $settings as $id => $args ) {
- $fields[ $id ] = wpforms_settings_output_field( $args );
- }
- return apply_filters( 'wpforms_settings_fields', $fields, $view );
- }
- /**
- * Build the output for the plugin settings page.
- *
- * @since 1.0.0
- */
- public function output() {
- $tabs = $this->get_tabs();
- $fields = $this->get_settings_fields( $this->view );
- ?>
- <div id="wpforms-settings" class="wrap wpforms-admin-wrap">
- <?php $this->tabs(); ?>
- <h1 class="wpforms-h1-placeholder"></h1>
- <?php
- if ( wpforms()->pro && class_exists( 'WPForms_License', false ) ) {
- wpforms()->license->notices( true );
- }
- ?>
- <div class="wpforms-admin-content wpforms-admin-settings wpforms-admin-content-<?php echo esc_attr( $this->view ); ?> wpforms-admin-settings-<?php echo esc_attr( $this->view ); ?>">
- <?php
- // Some tabs rely on AJAX and do not contain a form, such as Integrations.
- if ( ! empty( $tabs[ $this->view ]['form'] ) ) :
- ?>
- <form class="wpforms-admin-settings-form" method="post">
- <input type="hidden" name="action" value="update-settings">
- <input type="hidden" name="view" value="<?php echo esc_attr( $this->view ); ?>">
- <input type="hidden" name="nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpforms-settings-nonce' ) ); ?>">
- <?php endif; ?>
- <?php do_action( 'wpforms_admin_settings_before', $this->view, $fields ); ?>
- <?php
- foreach ( $fields as $field ) {
- echo $field; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
- }
- ?>
- <?php if ( ! empty( $tabs[ $this->view ]['submit'] ) ) : ?>
- <p class="submit">
- <button type="submit" class="wpforms-btn wpforms-btn-md wpforms-btn-orange" name="wpforms-settings-submit">
- <?php
- // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
- echo $tabs[ $this->view ]['submit'];
- ?>
- </button>
- </p>
- <?php endif; ?>
- <?php do_action( 'wpforms_admin_settings_after', $this->view, $fields ); ?>
- <?php if ( ! empty( $tabs[ $this->view ]['form'] ) ) : ?>
- </form>
- <?php endif; ?>
- </div>
- </div>
- <?php
- }
- /**
- * Monitor that all custom tables exist and recreate if missing.
- * This logic works on Settings > General page only.
- *
- * @since 1.6.2
- */
- public function monitor_custom_tables() {
- // Proceed on Settings plugin admin area page only.
- if ( $this->view !== 'general' ) {
- return;
- }
- /*
- * Tasks Meta table.
- */
- $meta = new \WPForms\Tasks\Meta();
- if ( $meta->table_exists() ) {
- return;
- }
- $meta->create_table();
- }
- }
- new WPForms_Settings();
|