Form_Settings_Page

Class representing the form settings page in the admin.

Description

Source

File: src/db-objects/forms/form-settings-page.php

class Form_Settings_Page extends Tabbed_Settings_Page {

	/**
	 * Form manager instance.
	 *
	 * @since 1.0.0
	 * @var Form_Manager
	 */
	protected $form_manager;

	/**
	 * Array of sub-tabs as `$id => $args` pairs.
	 *
	 * @since 1.0.0
	 * @var array
	 */
	protected $subtabs = array();

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param string       $slug         Page slug.
	 * @param Admin_Pages  $manager      Admin page manager instance.
	 * @param Form_Manager $form_manager Form manager instance.
	 */
	public function __construct( $slug, $manager, $form_manager ) {
		$this->slug         = $slug;
		$this->manager      = $manager;
		$this->form_manager = $form_manager;

		$this->title = __( 'Settings', 'torro-forms' );
		$this->menu_title = $this->title;

		$this->capability = 'manage_' . $form_manager->get_prefix() . $form_manager->get_singular_slug() . '_settings';
	}

	/**
	 * Adds a tab to the settings page.
	 *
	 * @since 1.0.0
	 *
	 * @param string $id   Tab identifier.
	 * @param array  $args {
	 *     Optional. Tab arguments.
	 *
	 *     @type string $title Tab title.
	 * }
	 */
	public function add_tab( $id, $args = array() ) {
		$prefix = $this->manager->get_prefix();

		if ( 0 !== strpos( $id, $prefix ) ) {
			$id = $prefix . $id;
		}

		$this->tabs[ $id ] = wp_parse_args( $args, array(
			'title'            => '',
			'rest_description' => '',
		) );

		$services = array(
			'ajax'          => $this->manager->ajax(),
			'assets'        => $this->manager->assets(),
			'error_handler' => $this->manager->error_handler(),
		);

		$this->tabs[ $id ]['field_manager'] = new Field_Manager( $this->manager->get_prefix(), $services, array(
			'get_value_callback_args'    => array( $id ),
			'update_value_callback_args' => array( $id, '{value}' ),
			'name_prefix'                => $id,
		) );
	}

	/**
	 * Adds a sub-tab to the settings page.
	 *
	 * @since 1.0.0
	 *
	 * @param string $id   Sub-tab identifier.
	 * @param array  $args {
	 *     Optional. Sub-tab arguments.
	 *
	 *     @type string $title       Sub-tab title.
	 *     @type string $description Sub-tab description. Default empty.
	 *     @type string $tab         Identifier of the tab this sub-tab should belong to.
	 * }
	 */
	public function add_subtab( $id, $args = array() ) {
		if ( ! empty( $args['tab'] ) ) {
			$prefix = $this->manager->get_prefix();

			if ( 0 !== strpos( $args['tab'], $prefix ) ) {
				$args['tab'] = $prefix . $args['tab'];
			}
		}

		$this->subtabs[ $id ] = wp_parse_args( $args, array(
			'title'       => '',
			'description' => '',
			'tab'         => '',
		) );
	}

	/**
	 * Adds a section to the settings page.
	 *
	 * @since 1.0.0
	 *
	 * @param string $id   Section identifier.
	 * @param array  $args {
	 *     Optional. Section arguments.
	 *
	 *     @type string $title       Section title.
	 *     @type string $description Section description. Default empty.
	 *     @type string $subtab      Identifier of the sub-tab this section should belong to.
	 * }
	 */
	public function add_section( $id, $args = array() ) {
		$this->sections[ $id ] = wp_parse_args( $args, array(
			'title'       => '',
			'description' => '',
			'subtab'      => '',
		) );
	}

	/**
	 * Adds a field to the settings page.
	 *
	 * @since 1.0.0
	 *
	 * @param string $id      Field identifier.
	 * @param string $type    Identifier of the type.
	 * @param array  $args    {
	 *     Optional. Field arguments. See the field class constructor for further arguments.
	 *
	 *     @type string $section       Section identifier this field belongs to. Default empty.
	 *     @type string $label         Field label. Default empty.
	 *     @type string $description   Field description. Default empty.
	 *     @type mixed  $default       Default value for the field. Default null.
	 *     @type array  $input_classes Array of CSS classes for the field input. Default empty array.
	 *     @type array  $label_classes Array of CSS classes for the field label. Default empty array.
	 *     @type array  $input_attrs   Array of additional input attributes as `$key => $value` pairs.
	 *                                 Default empty array.
	 * }
	 */
	public function add_field( $id, $type, $args = array() ) {
		if ( ! isset( $args['section'] ) ) {
			return;
		}

		if ( ! isset( $this->sections[ $args['section'] ] ) ) {
			return;
		}

		if ( ! isset( $this->subtabs[ $this->sections[ $args['section'] ]['subtab'] ] ) ) {
			return;
		}

		if ( ! isset( $this->tabs[ $this->subtabs[ $this->sections[ $args['section'] ]['subtab'] ]['tab'] ] ) ) {
			return;
		}

		$tab_args = $this->tabs[ $this->subtabs[ $this->sections[ $args['section'] ]['subtab'] ]['tab'] ];
		$tab_args['field_manager']->add( $id, $type, $args );
	}

	/**
	 * Enqueues assets to load on the page.
	 *
	 * @since 1.0.0
	 */
	public function enqueue_assets() {
		parent::enqueue_assets();

		$this->manager->assets()->enqueue_script( 'admin-settings' );
		$this->manager->assets()->enqueue_style( 'admin-settings' );
	}

	/**
	 * Registers the settings, tabs, sections and fields for this page in WordPress.
	 *
	 * This method is only meant for internal usage.
	 *
	 * @since 1.0.0
	 */
	public function register() {
		$this->add_page_content();

		foreach ( $this->tabs as $id => $tab_args ) {
			foreach ( $tab_args['field_manager']->get_fields() as $field ) {
				if ( ! isset( $this->sections[ $field->section ] ) ) {
					continue;
				}

				if ( ! isset( $this->subtabs[ $this->sections[ $field->section ]['subtab'] ] ) ) {
					continue;
				}

				$tab_subtab_slug = $this->subtabs[ $this->sections[ $field->section ]['subtab'] ]['tab'] . '_' . $this->sections[ $field->section ]['subtab'];

				add_settings_field( $field->id, $field->label, array( $this, 'render_field' ), $tab_subtab_slug, $field->section, array(
					'label_for'      => $tab_args['field_manager']->make_id( $field->id ),
					'field_instance' => $field,
				) );
			}

			register_setting( $id, $id );
			add_filter( "sanitize_option_{$id}", array( $this, 'validate' ), 10, 2 );
		}

		foreach ( $this->sections as $id => $section_args ) {
			if ( ! isset( $this->subtabs[ $section_args['subtab'] ] ) ) {
				continue;
			}

			$tab_subtab_slug = $this->subtabs[ $section_args['subtab'] ]['tab'] . '_' . $section_args['subtab'];

			add_settings_section( $id, $section_args['title'], array( $this, 'render_section_description' ), $tab_subtab_slug );
		}
	}

	/**
	 * Registers the settings for this page in the WordPress REST API.
	 *
	 * This method is only meant for internal usage.
	 *
	 * @since 1.0.0
	 */
	public function register_rest_api_settings() {
		$this->add_page_content();

		foreach ( $this->tabs as $id => $tab_args ) {
			$setting_args = array(
				'type'         => 'object',
				'description'  => $tab_args['rest_description'],
				'show_in_rest' => array(
					'schema' => array(
						'type'       => 'object',
						'properties' => array(),
					),
				),
				'default'      => array(),
			);

			foreach ( $tab_args['field_manager']->get_fields() as $field ) {
				if ( ! isset( $this->sections[ $field->section ] ) ) {
					continue;
				}

				if ( ! isset( $this->subtabs[ $this->sections[ $field->section ]['subtab'] ] ) ) {
					continue;
				}

				$setting_args['show_in_rest']['schema']['properties'][ $field->id ] = $this->build_rest_schema_for_field( $field );
				$setting_args['default'][ $field->id ]                              = $this->get_rest_default_for_field( $field );
			}

			if ( empty( $setting_args['show_in_rest']['schema']['properties'] ) ) {
				$setting_args['show_in_rest'] = false;
			}

			register_setting( $id, $id, $setting_args );
			add_filter( "sanitize_option_{$id}", array( $this, 'validate' ), 10, 2 );
		}
	}

	/**
	 * Builds the REST schema array data for a field.
	 *
	 * @since 1.0.0
	 *
	 * @param Field $field Field to build the schema for.
	 * @return array Schema data for the field.
	 */
	protected function build_rest_schema_for_field( $field ) {
		$schema = array();

		switch ( $field->slug ) {
			case 'group':
				$schema['type']       = 'object';
				$schema['properties'] = array();
				foreach ( $field->fields as $sub_field ) {
					$schema['properties'][ $sub_field->id ] = $this->build_rest_schema_for_field( $sub_field );
				}
				break;

			case 'multiselect':
			case 'multibox':
				$schema['type']  = 'array';
				$schema['items'] = array(
					'type' => 'string',
					'enum' => array_map( 'strval', array_keys( $field->choices ) ),
				);
				break;

			case 'select':
			case 'radio':
				$schema['type'] = 'string';
				$schema['enum'] = array_map( 'strval', array_keys( $field->choices ) );
				break;

			case 'checkbox':
				$schema['type'] = 'boolean';
				break;

			case 'number':
			case 'range':
				$input_attrs    = $field->input_attrs;
				$schema['type'] = ( ! empty( $input_attrs['step'] ) && is_int( $input_attrs['step'] ) ) ? 'integer' : 'number';
				if ( isset( $input_attrs['min'] ) ) {
					$schema['minimum'] = $input_attrs['min'];
				}
				if ( isset( $input_attrs['max'] ) ) {
					$schema['maximum'] = $input_attrs['max'];
				}
				break;

			case 'media':
				if ( 'url' === $field->store ) {
					$schema['type']   = 'string';
					$schema['format'] = 'uri';
				} else {
					$schema['type']    = 'integer';
					$schema['minimum'] = 0;
				}
				break;

			case 'url':
				$schema['type'] = 'string';
				$schema['format'] = 'uri';
				break;

			case 'email':
				$schema['type'] = 'string';
				$schema['format'] = 'email';
				break;

			default:
				$schema['type'] = 'string';
		}

		if ( $field->repeatable ) {
			$schema['items'] = $schema;
			$schema['type']  = 'array';
		}

		if ( ! empty( $field->description ) ) {
			$schema['description'] = strip_tags( $field->description );
		} elseif ( 'checkbox' === $field->slug && ! empty( $field->label ) ) {
			$schema['description'] = strip_tags( $field->label );
		}

		return $schema;
	}

	/**
	 * Gets the REST default value for a field.
	 *
	 * @since 1.0.0
	 *
	 * @param Field $field Field to get the default value for.
	 * @return array Default value for the field.
	 */
	protected function get_rest_default_for_field( $field ) {
		if ( null !== $field->default ) {
			return $field->default;
		}

		if ( $field->repeatable ) {
			return array();
		}

		switch ( $field->slug ) {
			case 'group':
			case 'multiselect':
			case 'multibox':
				return array();
			case 'checkbox':
				return false;
			case 'number':
			case 'range':
				$input_attrs = $field->input_attrs;
				if ( ! empty( $input_attrs['step'] ) && is_int( $input_attrs['step'] ) ) {
					if ( isset( $input_attrs['min'] ) && $input_attrs['min'] > 0 ) {
						return (int) $input_attrs['min'];
					}
					return 0;
				}
				if ( isset( $input_attrs['min'] ) && $input_attrs['min'] > 0.0 ) {
					return (float) $input_attrs['min'];
				}
				return 0.0;
			case 'media':
				if ( 'url' === $field->store ) {
					return '';
				}
				return 0;
		}

		return '';
	}

	/**
	 * Validates field values for an array of fields.
	 *
	 * @since 1.0.0
	 *
	 * @param array  $values Array of values.
	 * @param string $option Option name.
	 * @param array  $fields Array of field instances.
	 * @return array Array of validated values.
	 */
	protected function validate_values( $values, $option, $fields ) {
		$old_values = get_option( $option, array() );
		$new_values = parent::validate_values( $values, $option, $fields );

		if ( ! empty( $old_values['slug'] ) && ! empty( $new_values['slug'] ) && $new_values['slug'] !== $old_values['slug'] ) {
			// Deleting this option ensures that rewrite rules are flushed.
			$this->form_manager->options()->delete( 'rewrite_rules' );
		}

		return $new_values;
	}

	/**
	 * Renders the tab navigation.
	 *
	 * @since 1.0.0
	 *
	 * @param string $current_tab_id Identifier of the current tab.
	 */
	protected function render_tab_navigation( $current_tab_id ) {
		$tabs = array_intersect_key( $this->tabs, array_flip( wp_list_pluck( $this->subtabs, 'tab' ) ) );

		if ( count( $tabs ) > 1 ) : ?>
			<h2 class="nav-tab-wrapper">
				<?php foreach ( $tabs as $tab_id => $tab_args ) : ?>
					<a class="nav-tab<?php echo $tab_id === $current_tab_id ? ' nav-tab-active' : ''; ?>" href="<?php echo add_query_arg( 'tab', $tab_id ); ?>">
						<?php echo $tab_args['title']; ?>
					</a>
				<?php endforeach; ?>
			</h2>
		<?php else : ?>
			<h2 class="screen-reader-text">
				<?php echo $tabs[ $current_tab_id ]['title']; ?>
			</h2>
		<?php endif;
	}

	/**
	 * Renders the settings page form.
	 *
	 * @since 1.0.0
	 *
	 * @param string $option Option name.
	 */
	protected function render_form( $option ) {
		$current_subtab_id = $this->get_current_subtab( $option );

		?>
		<form action="options.php" method="post" novalidate="novalidate">
			<?php settings_fields( $option ); ?>

			<?php $this->render_form_content( $option, $current_subtab_id ); ?>

			<?php submit_button(); ?>
		</form>
		<?php
	}

	/**
	 * Renders the settings page form content.
	 *
	 * @since 1.0.0
	 *
	 * @param string $current_tab_id    Identifier of the current tab.
	 * @param string $current_subtab_id Identifier of the current sub-tab.
	 */
	protected function render_form_content( $current_tab_id, $current_subtab_id ) {
		if ( $this->manager->get_prefix() . 'general_settings' === $current_tab_id ) {
			?>
			<div class="welcome-to-torro">
				<h3><?php _e( 'Welcome to Torro Forms!', 'torro-forms' ); ?></h3>
				<p><?php _e( 'You want to build forms in an easy way? Torro Forms will help you do it quickly, yet with tons of options.', 'torro-forms' ); ?></p>
			</div>
			<?php
		}

		$subtabs = wp_list_filter( $this->subtabs, array(
			'tab' => $current_tab_id,
		) );
		if ( empty( $subtabs ) ) {
			return;
		}

		$use_subtabs = count( $subtabs ) > 1;

		?>
		<div class="torro-form-content <?php echo $use_subtabs ? 'tabbed' : 'no-tabs'; ?>">

			<?php if ( $use_subtabs ) : ?>
				<div class="torro-subtab-wrapper" role="tablist">
					<?php foreach ( $subtabs as $subtab_id => $subtab_args ) :
						$url = add_query_arg( array(
							'tab'    => $current_tab_id,
							'subtab' => $subtab_id,
						), $this->url );

						?>
						<a id="<?php echo esc_attr( 'torro-subtab-label-' . $subtab_id ); ?>" class="torro-subtab" href="<?php echo esc_url( $url ); ?>" aria-controls="<?php echo esc_attr( 'torro-subtab-' . $subtab_id ); ?>" aria-selected="<?php echo $subtab_id === $current_subtab_id ? 'true' : 'false'; ?>" role="tab">
							<?php echo $subtab_args['title']; ?>
						</a>
					<?php endforeach; ?>
				</div>
			<?php else : ?>
				<div class="screen-reader-text"><?php echo $subtabs[ $current_subtab_id ]['title']; ?></div>
			<?php endif; ?>

			<?php foreach ( $subtabs as $subtab_id => $subtab_args ) :
				$atts = $use_subtabs ? ' aria-labelledby="' . esc_attr( 'torro-subtab-label-' . $subtab_id ) . '" aria-hidden="' . ( $subtab_id === $current_subtab_id ? 'false' : 'true' ) . '" role="tabpanel"' : '';

				?>
				<div id="<?php echo esc_attr( 'torro-subtab-' . $subtab_id ); ?>" class="torro-subtab-panel"<?php echo $atts; ?>>

					<?php if ( ! empty( $subtab_args['description'] ) ) : ?>
						<p class="description"><?php echo $subtab_args['description']; ?></p>
					<?php endif; ?>

					<?php $this->do_settings_sections( $current_tab_id . '_' . $subtab_id ); ?>

				</div>
			<?php endforeach; ?>

		</div>
		<?php
	}

	/**
	 * Returns the identifier of the current sub-tab.
	 *
	 * @since 1.0.0
	 *
	 * @param string $current_tab_id Identifier of the current tab.
	 * @return string Identifier of the current sub-tab.
	 */
	protected function get_current_subtab( $current_tab_id ) {
		if ( isset( $_GET['subtab'] ) ) {
			$current_subtab_id = wp_unslash( $_GET['subtab'] );

			if ( isset( $this->subtabs[ $current_subtab_id ] ) && $current_tab_id === $this->subtabs[ $current_subtab_id ]['tab'] ) {
				return $current_subtab_id;
			}
		}

		foreach ( $this->subtabs as $slug => $args ) {
			if ( $current_tab_id === $args['tab'] ) {
				return $slug;
			}
		}

		return key( $this->subtabs );
	}

	/**
	 * Adds tabs, sub-tabs, sections and fields to this page.
	 *
	 * This method should call the methods `add_tab()`, `add_subtab()`, `add_section()` and
	 * `add_field()` to populate the page.
	 *
	 * @since 1.0.0
	 */
	protected function add_page_content() {
		$tabs = $this->get_tabs();
		foreach ( $tabs as $slug => $args ) {
			$this->add_tab( $slug, $args );
		}

		$subtabs = $this->get_subtabs();
		foreach ( $subtabs as $slug => $args ) {
			$this->add_subtab( $slug, $args );
		}

		$sections = $this->get_sections();
		foreach ( $sections as $slug => $args ) {
			$this->add_section( $slug, $args );
		}

		$fields = $this->get_fields();
		foreach ( $fields as $slug => $args ) {
			$type = 'text';
			if ( isset( $args['type'] ) ) {
				$type = $args['type'];
				unset( $args['type'] );
			}

			$this->add_field( $slug, $type, $args );
		}

		/**
		 * Fires after the form settings page content has been registered.
		 *
		 * @since 1.0.0
		 *
		 * @param awsmug\Torro_Forms\DB_Objects\Forms\Form_Settings_Page $settings_page The settings page instance.
		 */
		do_action( "{$this->manager->get_prefix()}add_settings_content", $this );
	}

	/**
	 * Returns the available settings tabs.
	 *
	 * @since 1.0.0
	 *
	 * @return array Associative array of `$tab_slug => $tab_args` pairs.
	 */
	protected function get_tabs() {
		$tabs = array(
			'general_settings' => array(
				'title'            => _x( 'General', 'form settings', 'torro-forms' ),
				'rest_description' => _x( 'Torro Forms general settings.', 'REST API description', 'torro-forms' ),
			),
			'extension_settings' => array(
				'title'            => _x( 'Extensions', 'form settings', 'torro-forms' ),
				'rest_description' => _x( 'Torro Forms extension settings.', 'REST API description', 'torro-forms' ),
			),
		);

		/**
		 * Filters the form settings tabs.
		 *
		 * @since 1.0.0
		 *
		 * @param array $tabs Associative array of `$tab_slug => $tab_args` pairs.
		 */
		return apply_filters( "{$this->manager->get_prefix()}settings_tabs", $tabs );
	}

	/**
	 * Returns the available settings sub-tabs.
	 *
	 * @since 1.0.0
	 *
	 * @return array Associative array of `$subtab_slug => $subtab_args` pairs.
	 */
	protected function get_subtabs() {
		$subtabs = array(
			'general' => array(
				'tab'   => 'general_settings',
				'title' => _x( 'General', 'form settings', 'torro-forms' ),
			),
		);

		/**
		 * Filters the form settings sub-tabs.
		 *
		 * @since 1.0.0
		 *
		 * @param array $tabs Associative array of `$subtab_slug => $subtab_args` pairs.
		 */
		return apply_filters( "{$this->manager->get_prefix()}settings_subtabs", $subtabs );
	}

	/**
	 * Returns the available settings sections.
	 *
	 * @since 1.0.0
	 *
	 * @return array Associative array of `$section_slug => $section_args` pairs.
	 */
	protected function get_sections() {
		$sections = array(
			'modules'       => array(
				'subtab' => 'general',
				'title'  => _x( 'Modules', 'form settings', 'torro-forms' ),
			),
			'form_behavior' => array(
				'subtab' => 'general',
				'title'  => __( 'Form Behavior', 'torro-forms' ),
			),
			'advanced'      => array(
				'subtab' => 'general',
				'title'  => _x( 'Advanced', 'form settings', 'torro-forms' ),
			),
		);

		/**
		 * Filters the form settings sections.
		 *
		 * @since 1.0.0
		 *
		 * @param array $tabs Associative array of `$section_slug => $section_args` pairs.
		 */
		return apply_filters( "{$this->manager->get_prefix()}settings_sections", $sections );
	}

	/**
	 * Returns the available settings fields.
	 *
	 * @since 1.0.0
	 *
	 * @return array Associative array of `$field_slug => $field_args` pairs.
	 */
	protected function get_fields() {
		$options = $this->form_manager->options()->get( 'general_settings', array() );

		$modules = array();
		foreach ( torro()->modules()->get_all() as $slug => $module ) {
			$modules[ $slug ] = $module->get_title();
		}
		$default_modules = array_keys( $modules );

		$default_slug = _x( 'forms', 'default form rewrite slug', 'torro-forms' );

		$fields = array(
			'modules' => array(
				'section'     => 'modules',
				'type'        => 'multibox',
				'label'       => __( 'Active Modules', 'torro-forms' ),
				'description' => __( 'If you do not need all of these modules, you can disable them here.', 'torro-forms' ),
				'choices'     => $modules,
				'default'     => $default_modules,
			),
			'slug'    => array(
				'section'     => 'form_behavior',
				'type'        => 'text',
				'label'       => __( 'Slug', 'torro-forms' ),
				'description' => sprintf( __( 'The slug for permalinks (e.g. for a URL like %s).', 'torro-forms' ), home_url( '/' ) . '<strong id="torro-rewrite-slug-preview">' . ( ! empty( $options['slug'] ) ? $options['slug'] : $default_slug ) . '</strong>/my-contact-form/' ),
				'default'     => $default_slug,
				'required'    => true,
			),
		);

		$attachment_taxonomy_slug = torro()->taxonomies()->get_attachment_taxonomy_slug();
		if ( ! empty( $attachment_taxonomy_slug ) ) {
			$attachment_taxonomy = get_taxonomy( $attachment_taxonomy_slug );
			if ( $attachment_taxonomy ) {
				$term_choices = array( '0' => _x( 'None', 'term choices', 'torro-forms' ) );
				$terms = get_terms( array(
					'taxonomy'   => $attachment_taxonomy->name,
					'number'     => 0,
					'hide_empty' => false,
					'orderby'    => 'name',
					'order'      => 'ASC',
				) );
				if ( ! is_wp_error( $terms ) ) {
					foreach ( $terms as $term ) {
						$term_choices[ $term->term_id ] = $term->name;
					}
				}

				$fields['attachment_taxonomy_term_id'] = array(
					'section'     => 'form_behavior',
					'type'        => 'select',
					/* translators: %s: attachment taxonomy name */
					'label'       => sprintf( __( '%s Term', 'torro-forms' ), $attachment_taxonomy->labels->singular_name ),
					'description' => __( 'The default term to use for form uploads.', 'torro-forms' ),
					'default'     => '0',
					'choices'     => $term_choices,
				);
			}
		}

		$fields = array_merge( $fields, array(
			'frontend_css'            => array(
				'section' => 'advanced',
				'type'    => 'checkbox',
				'label'   => __( 'Include Torro Forms CSS on frontend?', 'torro-forms' ),
				'default' => true,
			),
			'delete_submissions'      => array(
				'section'     => 'advanced',
				'type'        => 'checkbox',
				'label'       => __( 'Delete submission that have not completed after a certain amount of time?', 'torro-forms' ),
				'description' => __( 'Enabling this setting can help keep your database cleaner by deleting submissions that have been started, but never completed.', 'torro-forms' ),
				'default'     => false,
			),
			'delete_submissions_days' => array(
				'section'       => 'advanced',
				'type'          => 'number',
				'label'         => __( 'Submission Deletion', 'torro-forms' ),
				'description'   => __( 'Specify the number of days after which incomplete submissions should be deleted.', 'torro-forms' ),
				'min'           => 1,
				'step'          => 1,
				'default'       => 1,
				'unit'          => _x( 'day/s', 'field unit', 'torro-forms' ),
				'input_classes' => array( 'small-text' ),
				'dependencies'  => array(
					array(
						'prop'     => 'display',
						'callback' => 'get_data_by_condition_true',
						'fields'   => array( 'delete_submissions' ),
						'args'     => array(),
					),
				),
			),
			'hard_uninstall'          => array(
				'section'     => 'advanced',
				'type'        => 'checkbox',
				'label'       => __( 'Perform a hard uninstall when the plugin is removed?', 'torro-forms' ),
				'description' => __( '<strong>Use this setting with extreme caution</strong> as, when it is enabled, removing the plugin will remove all form content from your site forever.', 'torro-forms' ),
				'default'     => false,
			),
		) );

		/**
		 * Filters the form settings fields.
		 *
		 * @since 1.0.0
		 *
		 * @param array $tabs Associative array of `$field_slug => $field_args` pairs.
		 */
		return apply_filters( "{$this->manager->get_prefix()}settings_fields", $fields );
	}
}

Changelog

Changelog
Version Description
1.0.0 Introduced.

Methods