/** * Redux Options Class * * @class Redux_Options * @version 3.0.0 * @package Redux Framework/Classes */ defined( 'ABSPATH' ) || exit; if ( ! class_exists( 'Redux_Options_Constructor', false ) ) { /** * Class Redux_Options */ class Redux_Options_Constructor extends Redux_Class { /** * Array to hold single panel data. * * @var array */ public $no_panel = array(); /** * Array to hold single panel sections. * * @var array */ private $no_panel_section = array(); /** * Array to hold hidden fields. * * @var array */ private $hidden_perm_fields = array(); /** * Array to hold hidden sections. * * @var array */ public $hidden_perm_sections = array(); /** * Redux_Options constructor. * * @param object $parent ReduxFramework pointer. */ public function __construct( $parent ) { parent::__construct( $parent ); add_action( 'admin_init', array( $this, 'register' ) ); } /** * If we switch language in wpml the id of the post/page selected will be in the wrong language * So it won't appear as selected in the list of options and will be lost on next save, this fixes this by translating this id * Bonus it also gives the user the id of the post in the right language when they retrieve it * The recursion allows for it to work in a repeatable field. * * @param array $sections Sections array. * @param array $options_values Values array. */ private function translate_data_field_recursive( array $sections, array &$options_values ) { foreach ( $sections as $key => $section ) { if ( 'fields' === $key ) { foreach ( $section as $field ) { if ( ! empty( $field['id'] ) && ! empty( $field['data'] ) && ! empty( $options_values[ $field['id'] ] ) && \Redux_Helpers::is_integer( $options_values[ $field['id'] ] ) ) { $options_values[ $field['id'] ] = apply_filters( 'wpml_object_id', $options_values[ $field['id'] ], $field['data'], true ); } } } elseif ( is_array( $section ) && ! empty( $section ) ) { $this->translate_data_field_recursive( $section, $options_values ); } } } /** * Retrieves the options. */ public function get() { $core = $this->core(); $defaults = false; if ( ! empty( $core->defaults ) ) { $defaults = $core->defaults; } if ( empty( $core->args ) ) { return; } switch ( $core->args['database'] ) { case 'transient': $result = get_transient( $core->args['opt_name'] . '-transient' ); break; case 'theme_mods': $result = get_theme_mod( $core->args['opt_name'] . '-mods' ); break; case 'theme_mods_expanded': $result = get_theme_mods(); break; case 'network': $result = get_site_option( $core->args['opt_name'], array() ); break; default: $result = get_option( $core->args['opt_name'], array() ); } if ( empty( $result ) && empty( $defaults ) ) { return; } if ( empty( $result ) && ! empty( $defaults ) ) { $results = $defaults; $this->set( $results ); } else { $core->options = $result; } // Don't iterate unnecessarily. if ( has_filter( 'wpml_object_id' ) ) { $this->translate_data_field_recursive( $core->sections, $core->options ); } /** * Action 'redux/options/{opt_name}/options' * * @param mixed $value option values */ // phpcs:ignore WordPress.NamingConventions.ValidHookName $core->options = apply_filters( "redux/options/{$core->args['opt_name']}/options", $core->options, $core->sections ); // Get transient values. $core->transient_class->get(); // Set a global variable by the global_variable argument. $this->set_global_variable( $core ); } /** * ->set_options(); This is used to set an arbitrary option in the options array * * @since ReduxFramework 3.0.0 * * @param string|array $value the value of the option being added. */ public function set( $value = '' ) { $core = $this->core(); $core->transients['last_save'] = time(); if ( ! empty( $value ) ) { $core->options = $value; switch ( $core->args['database'] ) { case 'transient': set_transient( $core->args['opt_name'] . '-transient', $value, $core->args['transient_time'] ); break; case 'theme_mods': set_theme_mod( $core->args['opt_name'] . '-mods', $value ); break; case 'theme_mods_expanded': foreach ( $value as $k => $v ) { set_theme_mod( $k, $v ); } break; case 'network': update_site_option( $core->args['opt_name'], $value ); break; default: update_option( $core->args['opt_name'], $value ); } // Store the changed values in the transient. if ( $value !== $core->options ) { foreach ( $value as $k => $v ) { if ( ! isset( $core->options[ $k ] ) ) { $core->options[ $k ] = ''; } elseif ( $v === $core->options[ $k ] ) { unset( $core->options[ $k ] ); } } $core->transients['changed_values'] = $core->options; } $core->options = $value; // Set a global variable by the global_variable argument. $this->set_global_variable( $core ); // Saving the transient values. $core->transient_class->set(); } } /** * Set a global variable by the global_variable argument * * @param object $core ReduxFramework core object. * * @return void (global was set) * @since 3.1.5 */ private function set_global_variable( $core ): void { if ( ! empty( $core->args['global_variable'] ) ) { $options_global = $core->args['global_variable']; /** * Filter 'redux/options/{opt_name}/global_variable' * * @param array $value option value to set global_variable with */ // phpcs:ignore WordPress.NamingConventions.ValidHookName $GLOBALS[ $options_global ] = apply_filters( "redux/options/{$core->args['opt_name']}/global_variable", $core->options ); // Last save key. if ( isset( $core->transients['last_save'] ) ) { $GLOBALS[ $options_global ]['REDUX_LAST_SAVE'] = $core->transients['last_save']; } // Last compiler hook key. if ( isset( $core->transients['last_compiler'] ) ) { $GLOBALS[ $options_global ]['REDUX_LAST_COMPILER'] = $core->transients['last_compiler']; } } } /** * Register Option for use * * @since 1.0.0 * @access public * @return void */ public function register() { $core = $this->core(); if ( ! is_object( $core ) ) { return; } if ( true === $core->args['options_api'] ) { register_setting( $core->args['opt_name'] . '_group', $core->args['opt_name'], array( $this, 'validate_options', ) ); } if ( is_null( $core->sections ) ) { return; } if ( empty( $core->options_defaults ) ) { $core->options_defaults = $core->_default_values(); } $run_update = false; foreach ( $core->sections as $k => $section ) { if ( isset( $section['type'] ) && 'divide' === $section['type'] ) { continue; } $display = true; if ( isset( $_GET['page'] ) && $_GET['page'] === $core->args['page_slug'] ) { // phpcs:ignore WordPress.Security.NonceVerification if ( isset( $section['panel'] ) && false === $section['panel'] ) { $display = false; } } /** * Filter 'redux/options/{opt_name}/section/{section.id}' * * @param array $section section configuration */ if ( isset( $section['id'] ) ) { // phpcs:ignore WordPress.NamingConventions.ValidHookName $section = apply_filters( "redux/options/{$core->args['opt_name']}/section/{$section['id']}", $section ); } if ( empty( $section ) ) { unset( $core->sections[ $k ] ); continue; } if ( ! isset( $section['title'] ) ) { $section['title'] = ''; } if ( isset( $section['customizer_only'] ) && true === $section['customizer_only'] ) { $section['panel'] = false; $core->sections[ $k ] = $section; } $heading = $section['heading'] ?? $section['title']; if ( isset( $section['permissions'] ) && false !== $section['permissions'] ) { if ( ! Redux_Helpers::current_user_can( $section['permissions'] ) ) { $core->hidden_perm_sections[] = $section['title']; foreach ( $section['fields'] as $num => $field_data ) { $field_type = $field_data['type']; if ( 'section' !== $field_type || 'divide' !== $field_type || 'info' !== $field_type || 'raw' !== $field_type ) { $field_id = $field_data['id']; $default = $core->options_defaults[ $field_id ] ?? ''; $data = $core->options[ $field_id ] ?? $default; $this->hidden_perm_fields[ $field_id ] = $data; } } continue; } } if ( ! $display || ! function_exists( 'add_settings_section' ) ) { $this->no_panel_section[ $k ] = $section; } else { add_settings_section( $core->args['opt_name'] . $k . '_section', $heading, array( $core->render_class, 'section_desc', ), $core->args['opt_name'] . $k . '_section_group' ); } $section_ident = false; if ( isset( $section['fields'] ) ) { foreach ( $section['fields'] as $fieldk => $field ) { if ( ! isset( $field['type'] ) ) { continue; // You need a type! } if ( 'info' === $field['type'] && isset( $field['raw_html'] ) && true === $field['raw_html'] ) { $field['type'] = 'raw'; $field['content'] = $field['desc']; $field['desc'] = ''; $core->sections[ $k ]['fields'][ $fieldk ] = $field; } elseif ( 'info' === $field['type'] ) { if ( ! isset( $field['full_width'] ) ) { $field['full_width'] = true; $core->sections[ $k ]['fields'][ $fieldk ] = $field; } } if ( 'raw' === $field['type'] ) { if ( isset( $field['align'] ) ) { $field['full_width'] = ! $field['align']; unset( $field['align'] ); } elseif ( ! isset( $field['full_width'] ) ) { $field['full_width'] = true; } $core->sections[ $k ]['fields'][ $fieldk ] = $field; } /** * Filter 'redux/options/{opt_name}/field/{field.id}' * * @param array $field field config */ // phpcs:ignore WordPress.NamingConventions.ValidHookName $field = apply_filters( "redux/options/{$core->args['opt_name']}/field/{$field['id']}/register", $field ); $core->field_types[ $field['type'] ] = $core->field_types[ $field['type'] ] ?? array(); $core->field_sections[ $field['type'] ][ $field['id'] ] = $k; $display = true; if ( isset( $_GET['page'] ) && $core->args['page_slug'] === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification if ( isset( $field['panel'] ) && false === $field['panel'] ) { $display = false; } } if ( isset( $field['customizer_only'] ) && true === $field['customizer_only'] ) { $display = false; } if ( isset( $section['customizer'] ) ) { $field['customizer'] = $section['customizer']; $core->sections[ $k ]['fields'][ $fieldk ] = $field; } if ( isset( $field['permissions'] ) && false !== $field['permissions'] ) { if ( ! Redux_Helpers::current_user_can( $field['permissions'] ) ) { $data = $core->options[ $field['id'] ] ?? $core->options_defaults[ $field['id'] ]; $this->hidden_perm_fields[ $field['id'] ] = $data; continue; } } if ( ! isset( $field['id'] ) ) { echo '

No field ID is set.

';

							// phpcs:ignore WordPress.PHP.DevelopmentFunctions
							print_r( $field );

							echo '

'; continue; } if ( isset( $field['type'] ) && 'section' === $field['type'] ) { if ( isset( $field['indent'] ) && true === $field['indent'] ) { $section_ident = true; } else { $section_ident = false; } } if ( isset( $field['type'] ) && 'info' === $field['type'] && $section_ident ) { $field['indent'] = true; } $th = $core->render_class->get_header_html( $field ); $field['name'] = $core->args['opt_name'] . '[' . $field['id'] . ']'; // Set the default value if present. $core->options_defaults[ $field['id'] ] = $core->options_defaults[ $field['id'] ] ?? ''; // Set the defaults to the value if not present. $do_update = false; // Check fields for values in the default parameter. if ( ! isset( $core->options[ $field['id'] ] ) && isset( $field['default'] ) ) { $core->options_defaults[ $field['id'] ] = $field['default']; $core->options[ $field['id'] ] = $field['default']; $do_update = true; // Check fields that hae no default value, but an options value with settings to // be saved by default. } elseif ( ! isset( $core->options[ $field['id'] ] ) && isset( $field['options'] ) ) { // If sorter field, check for options and save them as defaults. if ( 'sorter' === $field['type'] || 'sortable' === $field['type'] ) { $core->options_defaults[ $field['id'] ] = $field['options']; $core->options[ $field['id'] ] = $field['options']; $do_update = true; } } // CORRECT URLS if media URLs are wrong, but attachment IDs are present. if ( 'media' === $field['type'] ) { if ( isset( $core->options[ $field['id'] ]['id'] ) && isset( $core->options[ $field['id'] ]['url'] ) && ! empty( $core->options[ $field['id'] ]['url'] ) && strpos( $core->options[ $field['id'] ]['url'], str_replace( 'http://', '', WP_CONTENT_URL ) ) === false ) { $data = wp_get_attachment_url( $core->options[ $field['id'] ]['id'] ); if ( isset( $data ) && ! empty( $data ) ) { $core->options[ $field['id'] ]['url'] = $data; $data = wp_get_attachment_image_src( $core->options[ $field['id'] ]['id'], array( 150, 150, ) ); $core->options[ $field['id'] ]['thumbnail'] = $data[0]; $do_update = true; } } } if ( 'background' === $field['type'] ) { if ( isset( $core->options[ $field['id'] ]['media']['id'] ) && isset( $core->options[ $field['id'] ]['background-image'] ) && ! empty( $core->options[ $field['id'] ]['background-image'] ) && strpos( $core->options[ $field['id'] ]['background-image'], str_replace( array( 'http://', 'https://' ), '', WP_CONTENT_URL ) ) === false ) { $data = wp_get_attachment_url( $core->options[ $field['id'] ]['media']['id'] ); if ( isset( $data ) && ! empty( $data ) ) { $core->options[ $field['id'] ]['background-image'] = $data; $data = wp_get_attachment_image_src( $core->options[ $field['id'] ]['media']['id'], array( 150, 150, ) ); $core->options[ $field['id'] ]['media']['thumbnail'] = $data[0]; $do_update = true; } } } if ( 'slides' === $field['type'] ) { if ( isset( $core->options[ $field['id'] ] ) && is_array( $core->options[ $field['id'] ] ) && isset( $core->options[ $field['id'] ][0]['attachment_id'] ) && isset( $core->options[ $field['id'] ][0]['image'] ) && ! empty( $core->options[ $field['id'] ][0]['image'] ) && strpos( $core->options[ $field['id'] ][0]['image'], str_replace( array( 'http://', 'https://' ), '', WP_CONTENT_URL ) ) === false ) { foreach ( $core->options[ $field['id'] ] as $key => $val ) { $data = wp_get_attachment_url( $val['attachment_id'] ); if ( isset( $data ) && ! empty( $data ) ) { $core->options[ $field['id'] ][ $key ]['image'] = $data; $data = wp_get_attachment_image_src( $val['attachment_id'], array( 150, 150, ) ); $core->options[ $field['id'] ][ $key ]['thumb'] = $data[0]; $do_update = true; } } } } // END -> CORRECT URLS if media URLs are wrong, but attachment IDs are present. if ( true === $do_update && ! isset( $core->never_save_to_db ) ) { if ( $core->args['save_defaults'] ) { // Only save that to the DB if allowed to. $run_update = true; } } if ( ! isset( $field['class'] ) ) { // No errors please. $field['class'] = ''; } $id = $field['id']; /** * Filter 'redux/options/{opt_name}/field/{field.id}'. * * @param array $field field config */ // phpcs:ignore WordPress.NamingConventions.ValidHookName $field = apply_filters( "redux/options/{$core->args['opt_name']}/field/{$field['id']}", $field ); if ( empty( $field ) || ! $field ) { unset( $core->sections[ $k ]['fields'][ $fieldk ] ); continue; } if ( ! empty( $core->folds[ $field['id'] ]['parent'] ) ) { // This has some fold items, hide it by default. $field['class'] .= ' fold'; } if ( ! empty( $core->folds[ $field['id'] ]['children'] ) ) { // Sets the values you shoe fold children on. $field['class'] .= ' fold-parent'; } if ( ! empty( $field['compiler'] ) ) { $field['class'] .= ' compiler'; $core->compiler_fields[ $field['id'] ] = 1; } if ( isset( $field['unit'] ) && ! isset( $field['units'] ) ) { $field['units'] = $field['unit']; unset( $field['unit'] ); } $core->sections[ $k ]['fields'][ $fieldk ] = $field; if ( isset( $core->args['display_source'] ) ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions $th .= ''; $th .= '
View Source'; } /** * Action 'redux/options/{opt_name}/field/{field.type}/register' */ // phpcs:ignore WordPress.NamingConventions.ValidHookName do_action( "redux/options/{$core->args['opt_name']}/field/{$field['type']}/register", $field ); $core->required_class->check_dependencies( $field ); $core->field_head[ $field['id'] ] = $th; if ( ! $display || isset( $this->no_panel_section[ $k ] ) ) { $this->no_panel[] = $field['id']; } else { if ( isset( $field['disabled'] ) && $field['disabled'] ) { $field['label_for'] = 'redux_disable_field'; } if ( isset( $field['hidden'] ) && $field['hidden'] ) { $field['label_for'] = 'redux_hide_field'; } if ( true === $core->args['options_api'] ) { add_settings_field( "{$fieldk}_field", $th, array( $core->render_class, 'field_input', ), "{$core->args['opt_name']}{$k}_section_group", "{$core->args['opt_name']}{$k}_section", $field ); } } } } } /** * Action 'redux/options/{opt_name}/register' * * @param array option sections */ // phpcs:ignore WordPress.NamingConventions.ValidHookName do_action( "redux/options/{$core->args['opt_name']}/register", $core->sections ); if ( $run_update && ! isset( $core->never_save_to_db ) ) { // Always update the DB with new fields. $this->set( $core->options ); } if ( isset( $core->transients['run_compiler'] ) && $core->transients['run_compiler'] ) { $core->no_output = true; $temp = $core->args['output_variables_prefix']; // Allow the override of variable's prefix for use by SCSS or LESS. if ( isset( $core->args['compiler_output_variables_prefix'] ) ) { $core->args['output_variables_prefix'] = $core->args['compiler_output_variables_prefix']; } $core->output_class->enqueue(); $core->args['output_variables_prefix'] = $temp; /** * Action 'redux/options/{opt_name}/compiler' * * @param array options * @param string CSS that get sent to the compiler hook */ // phpcs:ignore WordPress.NamingConventions.ValidVariableName $compiler_css = $core->compilerCSS; // phpcs:ignore WordPress.NamingConventions.ValidHookName do_action( "redux/options/{$core->args['opt_name']}/compiler", $core->options, $compiler_css, $core->transients['changed_values'], $core->output_variables ); /** * Action 'redux/options/{opt_name}/compiler/advanced' * * @param array options * @param string CSS that get sent to the compiler hook, which sends the full Redux object */ // phpcs:ignore WordPress.NamingConventions.ValidHookName do_action( "redux/options/{$core->args['opt_name']}/compiler/advanced", $core ); unset( $core->transients['run_compiler'] ); $core->transient_class->set(); } } /** * Get default options into an array suitable for the settings API * * @since 1.0.0 * @access public * @return array $this->options_defaults */ public function default_values(): array { $core = $this->core(); if ( ! is_null( $core->sections ) && is_null( $core->options_defaults ) ) { $core->options_defaults = $core->options_defaults_class->default_values( $core->args['opt_name'], $core->sections, $core->wordpress_data ); } /** * Filter 'redux/options/{opt_name}/defaults' * * @param array $defaults option default values */ $core->transients['changed_values'] = $core->transients['changed_values'] ?? array(); // phpcs:ignore WordPress.NamingConventions.ValidHookName $core->options_defaults = apply_filters( "redux/options/{$core->args['opt_name']}/defaults", $core->options_defaults, $core->transients['changed_values'] ); return $core->options_defaults; } /** * Validate the Options before insertion * * @param array $plugin_options The options array. * * @return array|mixed|string * @since 3.0.0 * @access public */ public function validate_options( array $plugin_options ) { $core = $this->core(); if ( isset( $core->validation_ran ) ) { return $plugin_options; } $core->validation_ran = 1; // Save the values not in the panel. if ( isset( $plugin_options['redux-no_panel'] ) ) { $keys = explode( '|', $plugin_options['redux-no_panel'] ); foreach ( $keys as $key ) { $plugin_options[ $key ] = $core->options[ $key ]; } if ( isset( $plugin_options['redux-no_panel'] ) ) { unset( $plugin_options['redux-no_panel'] ); } } if ( is_array( $this->hidden_perm_fields ) && ! empty( $this->hidden_perm_fields ) ) { foreach ( $this->hidden_perm_fields as $id => $data ) { $plugin_options[ $id ] = $data; } } if ( $plugin_options === $core->options ) { return $plugin_options; } $time = time(); // Sets last saved time. $core->transients['last_save'] = $time; $imported_options = array(); if ( isset( $plugin_options['import_link'] ) && '' !== $plugin_options['import_link'] && ! ! wp_http_validate_url( $plugin_options['import_link'] ) ) { $import = wp_remote_retrieve_body( wp_remote_get( $plugin_options['import_link'] ) ); $imported_options = json_decode( $import, true ); } if ( isset( $plugin_options['import_code'] ) && '' !== $plugin_options['import_code'] ) { $imported_options = json_decode( $plugin_options['import_code'], true ); } // Import. $core->transients['last_save_mode'] = 'import'; // Last save mode. $core->transients['last_compiler'] = $time; $core->transients['last_import'] = $time; $core->transients['run_compiler'] = 1; if ( is_array( $imported_options ) && ! empty( $imported_options ) && isset( $imported_options['redux-backup'] ) && ( 1 === $imported_options['redux-backup'] || '1' === $imported_options['redux-backup'] ) ) { $core->transients['changed_values'] = array(); foreach ( $plugin_options as $key => $value ) { if ( isset( $imported_options[ $key ] ) && $value !== $imported_options[ $key ] ) { $plugin_options[ $key ] = $value; $core->transients['changed_values'][ $key ] = $value; } } /** * Action 'redux/options/{opt_name}/import'. * * @param &array [&$plugin_options, redux_options] */ // phpcs:ignore WordPress.NamingConventions.ValidHookName do_action_ref_array( "redux/options/{$core->args['opt_name']}/import", // phpcs:ignore WordPress.NamingConventions.ValidHookName array( &$plugin_options, $imported_options, $core->transients['changed_values'], ) ); setcookie( 'redux_current_tab_' . $core->args['opt_name'], '', 1, '/', $time + 1000, '/' ); $_COOKIE[ 'redux_current_tab_' . $core->args['opt_name'] ] = 1; unset( $plugin_options['defaults'], $plugin_options['compiler'], $plugin_options['import'], $plugin_options['import_code'] ); if ( in_array( $core->args['database'], array( 'transient', 'theme_mods', 'theme_mods_expanded', 'network' ), true ) ) { $this->set( $plugin_options ); return; } $plugin_options = wp_parse_args( $imported_options, $plugin_options ); $core->transient_class->set(); return $plugin_options; } // Reset all to defaults. if ( ! empty( $plugin_options['defaults'] ) ) { if ( empty( $core->options_defaults ) ) { $core->options_defaults = $core->_default_values(); } /** * Filter: 'redux/validate/{opt_name}/defaults'. * * @param &array [ $this->options_defaults, $plugin_options] */ // phpcs:ignore WordPress.NamingConventions.ValidHookName $plugin_options = apply_filters( "redux/validate/{$core->args['opt_name']}/defaults", $core->options_defaults ); $core->transients['changed_values'] = array(); if ( empty( $core->options ) ) { $core->options = $core->options_defaults; } foreach ( $core->options as $key => $value ) { if ( isset( $plugin_options[ $key ] ) && $plugin_options[ $key ] !== $value ) { $core->transients['changed_values'][ $key ] = $value; } } $core->transients['run_compiler'] = 1; $core->transients['last_save_mode'] = 'defaults'; // Last save mode. $core->transient_class->set(); return $plugin_options; } // Section reset to defaults. if ( ! empty( $plugin_options['defaults-section'] ) ) { if ( isset( $plugin_options['redux-section'] ) && isset( $core->sections[ $plugin_options['redux-section'] ]['fields'] ) ) { if ( empty( $core->options_defaults ) ) { $core->options_defaults = $core->_default_values(); } foreach ( $core->sections[ $plugin_options['redux-section'] ]['fields'] as $field ) { if ( isset( $core->options_defaults[ $field['id'] ] ) ) { $plugin_options[ $field['id'] ] = $core->options_defaults[ $field['id'] ]; } else { $plugin_options[ $field['id'] ] = ''; } if ( isset( $field['compiler'] ) ) { $compiler = true; } } /** * Filter: 'redux/validate/{opt_name}/defaults_section'. * * @param &array [ $this->options_defaults, $plugin_options] */ // phpcs:ignore WordPress.NamingConventions.ValidHookName $plugin_options = apply_filters( "redux/validate/{$core->args['opt_name']}/defaults_section", $plugin_options ); } $core->transients['changed_values'] = array(); foreach ( $core->options as $key => $value ) { if ( isset( $plugin_options[ $key ] ) && $plugin_options[ $key ] !== $value ) { $core->transients['changed_values'][ $key ] = $value; } } if ( isset( $compiler ) ) { $core->transients['last_compiler'] = $time; $core->transients['run_compiler'] = 1; } $core->transients['last_save_mode'] = 'defaults_section'; // Last save mode. unset( $plugin_options['defaults'], $plugin_options['defaults_section'], $plugin_options['import'], $plugin_options['import_code'], $plugin_options['import_link'], $plugin_options['compiler'], $plugin_options['redux-section'] ); $core->transient_class->set(); return $plugin_options; } $core->transients['last_save_mode'] = 'normal'; // Last save mode. /** * Filter: 'redux/validate/{opt_name}/before_validation' * * @param &array [&$plugin_options, redux_options] */ // phpcs:ignore WordPress.NamingConventions.ValidHookName $plugin_options = apply_filters( "redux/validate/{$core->args['opt_name']}/before_validation", $plugin_options, $core->options ); // Validate fields (if needed). $plugin_options = $core->validate_class->validate( $plugin_options, $core->options, $core->sections ); // Sanitize options, if needed. $plugin_options = $core->sanitize_class->sanitize( $plugin_options, $core->options, $core->sections ); if ( ! empty( $core->errors ) || ! empty( $core->warnings ) || ! empty( $core->sanitize ) ) { $core->transients['notices'] = array( 'errors' => $core->errors, 'warnings' => $core->warnings, 'sanitize' => $core->sanitize, ); } if ( ! isset( $core->transients['changed_values'] ) ) { $core->transients['changed_values'] = array(); } /** * Action 'redux/options/{opt_name}/validate' * * @param &array [&$plugin_options, redux_options] */ // phpcs:ignore WordPress.NamingConventions.ValidHookName do_action_ref_array( // phpcs:ignore WordPress.NamingConventions.ValidHookName "redux/options/{$core->args['opt_name']}/validate", array( &$plugin_options, $core->options, $core->transients['changed_values'], ) ); if ( ! empty( $plugin_options['compiler'] ) ) { unset( $plugin_options['compiler'] ); $core->transients['last_compiler'] = $time; $core->transients['run_compiler'] = 1; } $core->transients['changed_values'] = array(); // Changed values since last save. if ( ! empty( $core->options ) ) { foreach ( $core->options as $key => $value ) { if ( isset( $plugin_options[ $key ] ) && $plugin_options[ $key ] !== $value ) { $core->transients['changed_values'][ $key ] = $value; } } } unset( $plugin_options['defaults'], $plugin_options['defaults_section'], $plugin_options['import'], $plugin_options['import_code'], $plugin_options['import_link'], $plugin_options['compiler'], $plugin_options['redux-section'] ); if ( in_array( $core->args['database'], array( 'transient', 'theme_mods', 'theme_mods_expanded' ), true ) ) { $core->set( $core->args['opt_name'], $plugin_options ); return; } if ( defined( 'WP_CACHE' ) && WP_CACHE && class_exists( 'W3_ObjectCache' ) && function_exists( 'w3_instance' ) ) { $w3_inst = w3_instance( 'W3_ObjectCache' ); $w3 = $w3_inst->instance(); $key = $w3->_get_cache_key( $core->args['opt_name'] . '-transients', 'transient' ); $w3->delete( $key, 'transient', true ); } $core->transient_class->set(); return $plugin_options; } /** * ->get_default(); This is used to return the default value if default_show is set. * * @param string $opt_name The option name to return. * @param mixed $default (null) The value to return if default not set. * * @return mixed $default * @since 1.0.1 * @access public */ public function get_default( string $opt_name, $default = null ) { if ( true === $this->args['default_show'] ) { if ( empty( $this->options_defaults ) ) { $this->default_values(); // fill cache. } $default = array_key_exists( $opt_name, $this->options_defaults ) ? $this->options_defaults[ $opt_name ] : $default; } return $default; } /** * Get the default value for an option * * @param string $key The option's ID. * @param string $array_key The key of the default's array. * * @return mixed * @since 3.3.6 * @access public */ public function get_default_value( string $key, $array_key = false ) { if ( empty( $this->options_defaults ) ) { $this->options_defaults = $this->default_values(); } $defaults = $this->options_defaults; $value = ''; if ( isset( $defaults[ $key ] ) ) { if ( false !== $array_key && isset( $defaults[ $key ][ $array_key ] ) ) { $value = $defaults[ $key ][ $array_key ]; } else { $value = $defaults[ $key ]; } } return $value; } } }