. * * @package Redux_Framework * @subpackage Core * @author Redux Framework Team * @version 3.2.9.13 */ // Exit if accessed directly if( !defined( 'ABSPATH' ) ) { exit; } // Fix for the GT3 page builder: http://www.gt3themes.com/wordpress-gt3-page-builder-plugin/ /** @global string $pagenow */ if(has_action('ecpt_field_options_')) { global $pagenow; if ( $pagenow === 'admin.php' ) { /** @noinspection PhpUndefinedCallbackInspection */ remove_action( 'admin_init', 'pb_admin_init' ); } } if ( !class_exists( 'ReduxFrameworkInstances' ) ) { // Instance Container include_once(dirname(__FILE__).'/inc/class.redux_instances.php'); include_once(dirname(__FILE__).'/inc/lib.redux_instances.php'); } if ( class_exists( 'ReduxFrameworkInstances' ) ) { add_action('redux/init', 'ReduxFrameworkInstances::get_instance'); } // Don't duplicate me! if( !class_exists( 'ReduxFramework' ) ) { // General helper functions include_once(dirname(__FILE__).'/inc/class.redux_helpers.php'); // General functions include_once(dirname(__FILE__).'/inc/class.redux_functions.php'); /** * Main ReduxFramework class * * @since 1.0.0 */ class ReduxFramework { // ATTENTION DEVS // Please update the build number with each push, no matter how small. // This will make for easier support when we ask users what version they are using. public static $_version = '3.2.9.15'; public static $_dir; public static $_url; public static $_upload_dir; public static $_upload_url; public static $wp_content_url; public static $base_wp_content_url; public static $_properties; public static $_is_plugin = true; public static $_as_plugin = false; static function init() { // Windows-proof constants: replace backward by forward slashes. Thanks to: @peterbouwmeester self::$_dir = trailingslashit( Redux_Helpers::cleanFilePath( dirname( __FILE__ ) ) ); $wp_content_dir = trailingslashit( Redux_Helpers::cleanFilePath( WP_CONTENT_DIR ) ); $wp_content_dir = trailingslashit( str_replace( '//', '/', $wp_content_dir ) ); $relative_url = str_replace( $wp_content_dir, '', self::$_dir ); self::$wp_content_url = trailingslashit( Redux_Helpers::cleanFilePath( ( is_ssl() ? str_replace( 'http://', 'https://', WP_CONTENT_URL ) : WP_CONTENT_URL ) ) ); self::$_url = self::$wp_content_url . $relative_url; // See if Redux is a plugin or not if ( strpos( Redux_Helpers::cleanFilePath( __FILE__ ), Redux_Helpers::cleanFilePath(get_stylesheet_directory()) ) !== false) { self::$_is_plugin = false; } // Create our private upload directory $upload = wp_upload_dir(); self::$_upload_dir = Redux_Helpers::cleanFilePath($upload['basedir']) . '/redux/'; self::$_upload_url = Redux_Helpers::cleanFilePath($upload['baseurl']) . '/redux/'; // Ensure it exists if (!is_dir(self::$_upload_dir)) { global $wp_filesystem; // Init wp_filesystem Redux_Functions::initWpFilesystem(); // Create the directory $wp_filesystem->mkdir(self::$_upload_dir); } }// ::init() public $framework_url = 'http://www.reduxframework.com/'; public $instance = null; public $admin_notices = array(); public $page = ''; public $saved = false; public $fields = array(); // Fields by type used in the panel public $current_tab = ''; // Current section to display, cookies public $extensions = array(); // Extensions by type used in the panel public $sections = array(); // Sections and fields public $errors = array(); // Errors public $warnings = array(); // Warnings public $options = array(); // Option values public $options_defaults = null; // Option defaults public $notices = array(); // Option defaults public $compiler_fields = array(); // Fields that trigger the compiler hook public $required = array(); // Information that needs to be localized public $required_child = array(); // Information that needs to be localized public $localize_data = array(); // Information that needs to be localized public $fonts = array(); // Information that needs to be localized public $folds = array(); // The itms that need to fold. public $path = ''; public $changed_values = array(); // Values that have been changed on save. Orig values. public $output = array(); // Fields with CSS output selectors public $outputCSS = null; // CSS that get auto-appended to the header public $compilerCSS = null; // CSS that get sent to the compiler hook public $customizerCSS = null; // CSS that goes to the customizer public $fieldsValues = array(); //all fields values in an id=>value array so we can check dependencies public $fieldsHidden = array(); //all fields that didn't pass the dependency test and are hidden public $toHide = array(); // Values to hide on page load public $typography = null; //values to generate google font CSS public $import_export = null; public $debug = null; private $show_hints = false; private $hidden_perm_fields = array(); // Hidden fields specified by 'permissions' arg. private $hidden_perm_sections = array(); // Hidden sections specified by 'permissions' arg. public $args = array( 'opt_name' => '', // Must be defined by theme/plugin 'google_api_key' => '', // Must be defined to add google fonts to the typography module 'last_tab' => '', // force a specific tab to always show on reload 'menu_icon' => '', // menu icon 'menu_title' => '', // menu title/text 'page_icon' => 'icon-themes', 'page_title' => '', // option page title 'page_slug' => '_options', 'page_permissions' => 'manage_options', 'menu_type' => 'menu', // ('menu'|'submenu') 'page_parent' => 'themes.php', // requires menu_type = 'submenu 'page_priority' => null, 'allow_sub_menu' => true, // allow submenus to be added if menu_type == menu 'save_defaults' => true, // Save defaults to the DB on it if empty 'footer_credit' => '', 'async_typography' => false, 'class' => '', // Class that gets appended to all redux-containers 'admin_bar' => true, // Show the panel pages on the admin bar 'help_tabs' => array(), 'help_sidebar' => '', // __( '', 'redux-framework' ); 'database' => '', // possible: options, theme_mods, theme_mods_expanded, transient, network 'customizer' => false, // setting to true forces get_theme_mod_expanded 'global_variable' => '', // Changes global variable from $GLOBALS['YOUR_OPT_NAME'] to whatever you set here. false disables the global variable 'output' => true, // Dynamically generate CSS 'compiler' => true, // Initiate the compiler hook 'output_tag' => true, // Print Output Tag 'transient_time' => '', 'default_show' => false, // If true, it shows the default value 'default_mark' => '', // What to print by the field's title if the value shown is default 'update_notice' => true, // Recieve an update notice of new commits when in dev mode 'disable_save_warn' => false, // Disable the save warn 'open_expanded' => false, // Start the panel fully expanded to start with 'network_admin' => false, // Enable network admin when using network database mode 'network_sites' => true, // Enable sites as well as admin when using network database mode 'hints' => array( 'icon' => 'icon-question-sign', 'icon_position' => 'right', 'icon_color' => 'lightgray', 'icon_size' => 'normal', 'tip_style' => array( 'color' => 'light', 'shadow' => true, 'rounded' => false, 'style' => '', ), 'tip_position' => array( 'my' => 'top_left', 'at' => 'bottom_right', ), 'tip_effect' => array( 'show' => array( 'effect' => 'slide', 'duration' => '500', 'event' => 'mouseover', ), 'hide' => array( 'effect' => 'fade', 'duration' => '500', 'event' => 'click mouseleave', ), ), ), 'show_import_export' => true, 'dev_mode' => false, /** * 'system_info' * @deprecated */ 'system_info' => false, // REMOVE ); /** * Class Constructor. Defines the args for the theme options class * @since 1.0.0 * @param array $sections Panel sections. * @param array $args Class constructor arguments. * @param array $extra_tabs Extra panel tabs. // REMOVE * @return \ReduxFramework */ public function __construct( $sections = array(), $args = array(), $extra_tabs = array() ) { global $wp_version; // Disregard WP AJAX 'heartbeat'call. Why waste resources? if (isset($_POST) && isset($_POST['action']) && $_POST['action'] == 'heartbeat' ) { // Hook, for purists. if ( !has_action('redux/ajax/heartbeat' ) ) { do_action( 'redux/ajax/heartbeat', $this ); } // Buh bye! return; } // Pass parent pointer to function helper. Redux_Functions::$_parent = $this; // Set values $this->args = wp_parse_args( $args, $this->args ); if ( empty( $this->args['transient_time'] ) ) { $this->args['transient_time'] = 60 * MINUTE_IN_SECONDS; } if ( empty( $this->args['footer_credit'] ) ) { $this->args['footer_credit'] = '' . sprintf( __( 'Options panel created using %1$s', 'redux-framework' ), ''.__( 'Redux Framework', 'redux-framework' ).' v'.self::$_version ) . ''; } if ( empty( $this->args['menu_title'] ) ) { $this->args['menu_title'] = __( 'Options', 'redux-framework' ); } if ( empty( $this->args['page_title'] ) ) { $this->args['page_title'] = __( 'Options', 'redux-framework' ); } /** * filter 'redux/args/{opt_name}' * @param array $args ReduxFramework configuration */ $this->args = apply_filters( "redux/args/{$this->args['opt_name']}", $this->args ); /** * filter 'redux/options/{opt_name}/args' * @param array $args ReduxFramework configuration */ $this->args = apply_filters( "redux/options/{$this->args['opt_name']}/args", $this->args ); if ( !empty( $this->args['opt_name'] ) ) { /** SHIM SECTION Old variables and ways of doing things that need correcting. ;) **/ // Variable name change if ( !empty( $this->args['page_cap'] ) ) { $this->args['page_permissions'] = $this->args['page_cap']; unset( $this->args['page_cap'] ); } if ( !empty( $this->args['page_position'] ) ) { $this->args['page_priority'] = $this->args['page_position']; unset( $this->args['page_position'] ); } if ( !empty( $this->args['page_type'] ) ) { $this->args['menu_type'] = $this->args['page_type']; unset( $this->args['page_type'] ); } // Get rid of extra_tabs! Not needed. if( is_array( $extra_tabs ) && !empty( $extra_tabs ) ) { foreach( $extra_tabs as $tab ) { array_push($this->sections, $tab); } } // Move to the first loop area! /** * filter 'redux-sections' * @deprecated * @param array $sections field option sections */ $this->sections = apply_filters('redux-sections', $sections); // REMOVE LATER /** * filter 'redux-sections-{opt_name}' * @deprecated * @param array $sections field option sections */ $this->sections = apply_filters("redux-sections-{$this->args['opt_name']}", $this->sections); // REMOVE LATER /** * filter 'redux/options/{opt_name}/sections' * @param array $sections field option sections */ $this->sections = apply_filters("redux/options/{$this->args['opt_name']}/sections", $this->sections); /** * Construct hook * action 'redux/construct' * @param object $this ReduxFramework */ do_action( 'redux/construct', $this ); // Set the default values $this->_default_cleanup(); // Internataionalization $this->_internationalization(); // Register extra extensions $this->_register_extensions(); // Grab database values $this->get_options(); // Tracking //$this->_tracking(); // Set option with defaults //add_action( 'init', array( &$this, '_set_default_options' ), 101 ); // Options page add_action( 'admin_menu', array( $this, '_options_page' ) ); // Add a network menu if ( $this->args['database'] == "network" && $this->args['network_admin'] ) { add_action( 'network_admin_menu', array( $this, '_options_page' ) ); } // Admin Bar menu add_action( 'admin_bar_menu', array( $this, '_admin_bar_menu' ) , 999 ); // Register setting add_action( 'admin_init', array( $this, '_register_settings' ) ); // Display admin notices in dev_mode if (true == $this->args['dev_mode']) { include_once(self::$_dir . 'inc/debug.php'); $this->debug = new ReduxDebugObject($this); if (true == $this->args['update_notice']) { add_action( 'admin_init', array( $this, '_update_check' ) ); } } // Display admin notices add_action( 'admin_notices', array( $this, '_admin_notices' ) ); // Check for dismissed admin notices. add_action( 'admin_init', array( $this, '_dismiss_admin_notice' ), 9 ); // Enqueue the admin page CSS and JS if ( isset( $_GET['page'] ) && $_GET['page'] == $this->args['page_slug'] ) { add_action( 'admin_enqueue_scripts', array( $this, '_enqueue' ) ); } // Output dynamic CSS add_action( 'wp_head', array( &$this, '_output_css' ), 150 ); // Enqueue dynamic CSS and Google fonts add_action( 'wp_enqueue_scripts', array( &$this, '_enqueue_output' ), 150 ); require_once(self::$_dir . 'inc/import_export.php'); $this->import_export = new Redux_import_export($this); if ( $this->args['database'] == "network" && $this->args['network_admin'] ) { add_action('network_admin_edit_redux_' . $this->args['opt_name'], array( $this, 'save_network_page' ), 10, 0); add_action( 'admin_bar_menu', array( $this, 'network_admin_bar'), 999 ); } // mod_rewrite check //Redux_Functions::modRewriteCheck(); } /** * Loaded hook * * action 'redux/loaded' * @param object $this ReduxFramework */ do_action( 'redux/loaded', $this ); } // __construct() public function network_admin_bar( $wp_admin_bar ) { $args = array( 'id' => $this->args['opt_name'].'_network_admin', 'title' => $this->args['menu_title'], 'parent'=> 'network-admin', 'href' => network_admin_url('settings.php').'?page='.$this->args['page_slug'], 'meta' => array( 'class' => 'redux-network-admin' ) ); $wp_admin_bar->add_node( $args ); } public function stripslashes_deep( $value ) { $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value); return $value; } public function save_network_page() { $data = $this->_validate_options( $_POST[$this->args['opt_name']] ); if (!empty($data)) { $this->set_options( $data ); } wp_redirect(add_query_arg(array('page' => $this->args['page_slug'], 'updated' => 'true'), network_admin_url('settings.php'))); exit(); } public function _update_check() { // Only one notice per instance please if ( !isset( $this->update_checked ) ) { Redux_Functions::updateCheck(self::$_version); $this->update_checked = 1; } } public function _admin_notices() { Redux_Functions::adminNotices(); } public function _dismiss_admin_notice() { Redux_Functions::dismissAdminNotice(); } /** * Load the plugin text domain for translation. * @param string $opt_name * @since 3.0.5 */ public function _internationalization() { /** * Locale for text domain * * filter 'redux/textdomain/{opt_name}' * @param string The locale of the blog or from the 'locale' hook * @param string 'redux-framework' text domain */ $locale = apply_filters( "redux/textdomain/{$this->args['opt_name']}", get_locale(), 'redux-framework' ); if (strpos($locale, '_') === false ) { if ( file_exists( dirname( __FILE__ ) . '/languages/' . strtolower($locale).'_'.strtoupper($locale) . '.mo' ) ) { $locale = strtolower($locale).'_'.strtoupper($locale); } } load_textdomain( 'redux-framework', dirname( __FILE__ ) . '/languages/' . $locale . '.mo' ); } // _internationalization() /** * @return ReduxFramework */ public function get_instance() { return self::$instance; } // get_instance() public function _tracking() { include_once( dirname( __FILE__ ) . '/inc/tracking.php' ); $tracking = Redux_Tracking::get_instance(); $tracking->load($this); } // _tracking() /** * ->_get_default(); This is used to return the default value if default_show is set * * @since 1.0.1 * @access public * @param string $opt_name The option name to return * @param mixed $default (null) The value to return if default not set * @return mixed $default */ public function _get_default( $opt_name, $default = null ) { if( $this->args['default_show'] == true ) { 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_default() /** * ->get(); This is used to return and option value from the options array * * @since 1.0.0 * @access public * @param string $opt_name The option name to return * @param mixed $default (null) The value to return if option not set * @return mixed */ public function get( $opt_name, $default = null ) { return ( !empty( $this->options[$opt_name] ) ) ? $this->options[$opt_name] : $this->_get_default( $opt_name, $default ); } // get() /** * ->set(); This is used to set an arbitrary option in the options array * * @since 1.0.0 * @access public * @param string $opt_name The name of the option being added * @param mixed $value The value of the option being added * @return void */ public function set( $opt_name = '', $value = '' ) { if( $opt_name != '' ) { $this->options[$opt_name] = $value; $this->set_options( $this->options ); } } // set() /** * Set a global variable by the global_variable argument * @since 3.1.5 * @return bool (global was set) */ function set_global_variable( ) { if ( $this->args['global_variable'] ) { $option_global = $this->args['global_variable']; /** * filter 'redux/options/{opt_name}/global_variable' * @param array $value option value to set global_variable with */ $GLOBALS[ $this->args['global_variable'] ] = apply_filters( "redux/options/{$this->args['opt_name']}/global_variable", $this->options ); if ( isset( $this->transients['last_save'] ) ) { // Deprecated $GLOBALS[ $this->args['global_variable'] ]['REDUX_last_saved'] = $this->transients['last_save']; // Last save key $GLOBALS[ $this->args['global_variable'] ]['REDUX_LAST_SAVE'] = $this->transients['last_save']; } if ( isset( $this->transients['last_compiler'] ) ) { // Deprecated $GLOBALS[ $this->args['global_variable'] ]['REDUX_COMPILER'] = $this->transients['last_compiler']; // Last compiler hook key $GLOBALS[ $this->args['global_variable'] ]['REDUX_LAST_COMPILER'] = $this->transients['last_compiler']; } return true; } return false; } // set_global_variable() /** * ->set_options(); This is used to set an arbitrary option in the options array * * @since ReduxFramework 3.0.0 * @param mixed $value the value of the option being added */ function set_options( $value = '' ) { $this->transients['last_save'] = time(); if( !empty($value) ) { $this->options = $value; if ( $this->args['database'] === 'transient' ) { set_transient( $this->args['opt_name'] . '-transient', $value, $this->args['transient_time'] ); } else if ( $this->args['database'] === 'theme_mods' ) { set_theme_mod( $this->args['opt_name'] . '-mods', $value ); } else if ( $this->args['database'] === 'theme_mods_expanded' ) { foreach ( $value as $k=>$v ) { set_theme_mod( $k, $v ); } } else if ( $this->args['database'] === 'network' ) { // Strip those slashes! $value = json_decode( stripslashes( json_encode( $value ) ), true); update_site_option( $this->args['opt_name'], $value ); } else { update_option( $this->args['opt_name'], $value ); } // Store the changed values in the transient if ( $value != $this->options ) { foreach ( $value as $k => $v ) { if ( !isset( $this->options[$k] ) ) { $this->options[$k] = ""; } else if ( $v == $this->options[$k] ) { unset( $this->options[$k] ); } } $this->transients['changed_values'] = $this->options; } $this->options = $value; // Set a global variable by the global_variable argument. $this->set_global_variable(); // Saving the transient values $this->set_transients(); //do_action( "redux-saved-{$this->args['opt_name']}", $value ); // REMOVE //do_action( "redux/options/{$this->args['opt_name']}/saved", $value, $this->transients['changed_values'] ); } } // set_options() /** * ->get_options(); This is used to get options from the database * * @since ReduxFramework 3.0.0 */ function get_options() { $defaults = false; if ( !empty( $this->defaults ) ) { $defaults = $this->defaults; } if ( $this->args['database'] === "transient" ) { $result = get_transient( $this->args['opt_name'] . '-transient' ); } else if ($this->args['database'] === "theme_mods" ) { $result = get_theme_mod( $this->args['opt_name'] . '-mods' ); } else if ( $this->args['database'] === 'theme_mods_expanded' ) { $result = get_theme_mods(); } else if ( $this->args['database'] === 'network' ) { $result = get_site_option( $this->args['opt_name'], array() ); $result = json_decode(stripslashes(json_encode($result)), true); } else { $result = get_option( $this->args['opt_name'], array() ); } if ( empty( $result ) && !empty( $defaults ) ) { $results = $defaults; $this->set_options( $results ); } else { $this->options = $result; } /** * action 'redux/options/{opt_name}/options' * @param mixed $value option values */ $this->options = apply_filters( "redux/options/{$this->args['opt_name']}/options", $this->options ); // Get transient values $this->get_transients(); // Set a global variable by the global_variable argument. $this->set_global_variable(); } // get_options() /** * ->get_wordpress_date() - Get Wordpress specific data from the DB and return in a usable array * * @since ReduxFramework 3.0.0 */ function get_wordpress_data($type = false, $args = array()) { $data = ""; /** * filter 'redux/options/{opt_name}/wordpress_data/{type}/' * @deprecated * @param string $data */ $data = apply_filters( "redux/options/{$this->args['opt_name']}/wordpress_data/$type/", $data ); // REMOVE LATER /** * filter 'redux/options/{opt_name}/data/{type}' * @param string $data */ $data = apply_filters( "redux/options/{$this->args['opt_name']}/data/$type", $data ); $argsKey = ""; foreach($args as $key => $value) { if (!is_array($value)) { $argsKey .= $value."-"; } else { $argsKey .= implode( "-", $value); } } if ( empty( $data ) && isset( $this->wp_data[$type.$argsKey] ) ) { $data = $this->wp_data[$type.$argsKey]; } if ( empty($data) && !empty($type) ) { /** Use data from Wordpress to populate options array **/ if (!empty($type) && empty($data)) { if (empty($args)) { $args = array(); } $data = array(); $args = wp_parse_args($args, array()); if ($type == "categories" || $type == "category") { $cats = get_categories($args); if (!empty($cats)) { foreach ( $cats as $cat ) { $data[$cat->term_id] = $cat->name; }//foreach } // If } else if ($type == "menus" || $type == "menu") { $menus = wp_get_nav_menus($args); if(!empty($menus)) { foreach ($menus as $item) { $data[$item->term_id] = $item->name; }//foreach }//if } else if ($type == "pages" || $type == "page") { if (!isset($args['posts_per_page'])) { $args['posts_per_page'] = 20; } $pages = get_pages($args); if (!empty($pages)) { foreach ( $pages as $page ) { $data[$page->ID] = $page->post_title; }//foreach }//if } else if ($type == "terms" || $type == "term") { $taxonomies = $args['taxonomies']; unset($args['taxonomies']); $terms = get_terms($taxonomies, $args); // this will get nothing if (!empty($terms)) { foreach ( $terms as $term ) { $data[$term->term_id] = $term->name; }//foreach } // If } else if ($type == "taxonomy" || $type == "taxonomies") { $taxonomies = get_taxonomies($args); if (!empty($taxonomies)) { foreach ( $taxonomies as $key => $taxonomy ) { $data[$key] = $taxonomy; }//foreach } // If } else if ($type == "posts" || $type == "post") { $posts = get_posts($args); if (!empty($posts)) { foreach ( $posts as $post ) { $data[$post->ID] = $post->post_title; }//foreach }//if } else if ($type == "post_type" || $type == "post_types") { global $wp_post_types; $defaults = array( 'public' => true, 'exclude_from_search' => false, ); $args = wp_parse_args( $args, $defaults ); $output = 'names'; $operator = 'and'; $post_types = get_post_types($args, $output, $operator); ksort($post_types); foreach ( $post_types as $name => $title ) { if ( isset($wp_post_types[$name]->labels->menu_name) ) { $data[$name] = $wp_post_types[$name]->labels->menu_name; } else { $data[$name] = ucfirst($name); } } } else if ($type == "tags" || $type == "tag") { // NOT WORKING! $tags = get_tags($args); if (!empty($tags)) { foreach ( $tags as $tag ) { $data[$tag->term_id] = $tag->name; }//foreach }//if } else if ($type == "menu_location" || $type == "menu_locations") { global $_wp_registered_nav_menus; foreach($_wp_registered_nav_menus as $k => $v) { $data[$k] = $v; } }//if else if ($type == "elusive-icons" || $type == "elusive-icon" || $type == "elusive" || $type == "font-icon" || $type == "font-icons" || $type == "icons") { /** * filter 'redux-font-icons' * @deprecated * @param array $font_icons array of elusive icon classes */ $font_icons = apply_filters( 'redux-font-icons', array() ); // REMOVE LATER /** * filter 'redux/font-icons' * @deprecated * @param array $font_icons array of elusive icon classes */ $font_icons = apply_filters( 'redux/font-icons', $font_icons ); /** * filter 'redux/{opt_name}/field/font/icons' * @deprecated * @param array $font_icons array of elusive icon classes */ $font_icons = apply_filters( "redux/{$this->args['opt_name']}/field/font/icons", $font_icons ); foreach($font_icons as $k) { $data[$k] = $k; } }else if ($type == "roles") { /** @global WP_Roles $wp_roles */ global $wp_roles; $data = $wp_roles->get_names(); }else if ($type == "sidebars" || $type == "sidebar") { /** @global array $wp_registered_sidebars */ global $wp_registered_sidebars; foreach ($wp_registered_sidebars as $key=>$value) { $data[$key] = $value['name']; } }else if ($type == "capabilities") { /** @global WP_Roles $wp_roles */ global $wp_roles; foreach( $wp_roles->roles as $role ){ foreach( $role['capabilities'] as $key => $cap ){ $data[$key] = ucwords(str_replace('_', ' ', $key)); } } }else if ($type == "callback") { if ( !is_array( $args ) ) { $args = array( $args ); } $data = call_user_func($args[0]); }//if }//if $this->wp_data[$type.$argsKey] = $data; }//if return $data; } // get_wordpress_data() /** * ->show(); This is used to echo and option value from the options array * * @since 1.0.0 * @access public * @param string $opt_name The name of the option being shown * @param mixed $default The value to show if $opt_name isn't set * @return void */ public function show( $opt_name, $default = '' ) { $option = $this->get( $opt_name ); if( !is_array( $option ) && $option != '' ) { echo $option; } elseif( $default != '' ) { echo $this->_get_default( $opt_name, $default ); } } // show() /** * 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() { if( !is_null( $this->sections ) && is_null( $this->options_defaults ) ) { // fill the cache foreach( $this->sections as $sk => $section ) { if (!isset($section['id'])) { if (!is_numeric($sk) || !isset($section['title'])) { $section['id'] = $sk; } else { $section['id'] = sanitize_title( $section['title'], $sk ); } $this->sections[$sk] = $section; } if( isset( $section['fields'] ) ) { foreach( $section['fields'] as $k => $field ) { if (empty($field['id']) && empty($field['type'])) { continue; } if ($field['type'] == "section" && isset( $field['indent'] ) && $field['indent'] == "true") { $field['class'] = isset($field['class']) ? $field['class'] : ''; $field['class'] .= "redux-section-indent-start"; $this->sections[$sk]['fields'][$k] = $field; } // Detect what field types are being used if ( !isset( $this->fields[$field['type']][$field['id']] ) ) { $this->fields[$field['type']][$field['id']] = 1; } else { $this->fields[$field['type']] = array($field['id'] => 1); } if( isset( $field['default'] ) ) { $this->options_defaults[$field['id']] = $field['default']; } elseif (isset($field['options'])) { // Sorter data filter if ($field['type'] == "sorter" && isset($field['data']) && !empty($field['data']) && is_array($field['data'])) { if (!isset($field['args'])) { $field['args'] = array(); } foreach ($field['data'] as $key => $data) { if (!isset($field['args'][$key])) { $field['args'][$key] = array(); } $field['options'][$key] = $this->get_wordpress_data($data, $field['args'][$key]); } } $this->options_defaults[$field['id']] = $field['options']; } } } } } /** * filter 'redux/options/{opt_name}/defaults' * @param array $defaults option default values */ $this->transients['changed_values'] = isset($this->transients['changed_values']) ? $this->transients['changed_values'] : array(); $this->options_defaults = apply_filters( "redux/options/{$this->args['opt_name']}/defaults", $this->options_defaults, $this->transients['changed_values'] ); return $this->options_defaults; } /** * Get fold values into an array suitable for setting folds * * @since ReduxFramework 1.0.0 */ function _fold_values() { /* Folds work by setting the folds value like so $this->folds['parentID']['parentValue'][] = 'childId' */ // $folds = array(); if( !is_null( $this->sections ) ) { foreach( $this->sections as $section ) { if( isset( $section['fields'] ) ) { foreach( $section['fields'] as $field ) { //if we have required option in group field if(isset($field['fields']) && is_array($field['fields'])){ foreach ($field['fields'] as $subfield) { if(isset($subfield['required'])) $this->get_fold($subfield); } } if( isset( $field['required'] ) ) { $this->get_fold($field); } } } } } $parents = array(); foreach ($this->folds as $k=>$fold) { // ParentFolds WITHOUT parents if ( empty( $fold['children'] ) || !empty( $fold['children']['parents'] ) ) { continue; } $fold['value'] = $this->options[$k]; foreach ($fold['children'] as $key =>$value) { if ($key == $fold['value']) { unset($fold['children'][$key]); } } if (empty($fold['children'])) { continue; } foreach ($fold['children'] as $key => $value) { foreach ($value as $k=> $hidden) { if ( !in_array( $hidden, $this->toHide ) ) { $this->toHide[] = $hidden; } } } $parents[] = $fold; } return $this->folds; } // _fold_values() /** * get_fold() - Get the fold values * * @param array $field * @return array */ function get_fold($field){ if ( !is_array( $field['required'] ) ) { /* Example variable: $var = array( 'fold' => 'id' ); */ $this->folds[$field['required']]['children'][1][] = $field['id']; $this->folds[$field['id']]['parent'] = $field['required']; } else { // $parent = $foldk = $field['required'][0]; $foldk = $field['required'][0]; // $comparison = $field['required'][1]; $value = $foldv = $field['required'][2]; //foreach( $field['required'] as $foldk=>$foldv ) { if ( is_array( $value ) ) { /* Example variable: $var = array( 'fold' => array( 'id' , '=', array(1, 5) ) ); */ foreach ($value as $foldvValue) { //echo 'id: '.$field['id']." key: ".$foldk.' f-val-'.print_r($foldv)." foldvValue".$foldvValue; $this->folds[$foldk]['children'][$foldvValue][] = $field['id']; $this->folds[$field['id']]['parent'] = $foldk; } } else { //!DOVY If there's a problem, this is where it's at. These two cases. //This may be able to solve this issue if these don't work //if (count($field['fold']) == count($field['fold'], COUNT_RECURSIVE)) { //} if (count($field['required']) === 1 && is_numeric($foldk)) { /* Example variable: $var = array( 'fold' => array( 'id' ) ); */ $this->folds[$field['id']]['parent'] = $foldk; $this->folds[$foldk]['children'][1][] = $field['id']; } else { /* Example variable: $var = array( 'fold' => array( 'id' => 1 ) ); */ if (empty($foldv)) { $foldv = 0; } $this->folds[$field['id']]['parent'] = $foldk; $this->folds[$foldk]['children'][$foldv][] = $field['id']; } } //} } return $this->folds; } // get_fold() /** * Set default options on admin_init if option doesn't exist * * @since 1.0.0 * @access public * @return void */ public function _default_cleanup() { // Fix the global variable name if ( $this->args['global_variable'] == "" && $this->args['global_variable'] !== false ) { $this->args['global_variable'] = str_replace('-', '_', $this->args['opt_name']); } } /** * Class Add Sub Menu Function, creates options submenu in Wordpress admin area. * @since 3.1.9 * @access private * @return void */ private function add_submenu($page_parent, $page_title, $menu_title, $page_permissions, $page_slug) { global $submenu; // Just in case. One never knows. $page_parent = strtolower($page_parent); $test = array( 'index.php' => 'dashboard', 'edit.php' => 'posts', 'upload.php' => 'media', 'link-manager.php' => 'links', 'edit.php?post_type=page' => 'pages', 'edit-comments.php' => 'comments', 'themes.php' => 'theme', 'plugins.php' => 'plugins', 'users.php' => 'users', 'tools.php' => 'management', 'options-general.php' => 'options', ); if (isset($test[$page_parent])) { $function = 'add_' . $test[$page_parent] . '_page'; $this->page = $function( $page_title, $menu_title, $page_permissions, $page_slug, array($this, '_options_page_html') ); } else { // Network settings and Post type menus. These do not have // wrappers and need to be appened to using add_submenu_page. // Okay, since we've left the post type menu appending // as default, we need to validate it, so anything that // isn't post_type= doesn't get through and mess // things up. $addMenu = false; if ('settings.php' != $page_parent) { // Establish the needle $needle = '?post_type='; // Check if it exists in the page_parent (how I miss instr) $needlePos = strrpos($page_parent, $needle); // It's there, so... if ($needlePos > 0) { // Get the post type. $postType = substr($page_parent, $needlePos + strlen($needle)); // Ensure it exists. if (post_type_exists($postType)) { // Set flag to add the menu page $addMenu = true; } // custom menu } elseif (isset($submenu[$this->args['page_parent']])) { $addMenu = true; } } else { // The page_parent was settings.php, so set menu add // flag to true. $addMenu = true; } } } /** * Class Options Page Function, creates main options page. * @since 1.0.0 * @access public * @return void */ function _options_page() { $this->import_export->in_field(); if( $this->args['menu_type'] == 'menu' ) { $this->add_submenu( $this->args['page_parent'], $this->args['page_title'], $this->args['menu_title'], $this->args['page_permissions'], $this->args['page_slug'] ); } add_action( "load-{$this->page}", array( &$this, '_load_page' ) ); } // _options_page() /** * Add admin bar menu * * @since 3.1.5.16 * @access public * @global $menu, $submenu, $wp_admin_bar * @return void */ function _admin_bar_menu() { global $menu, $submenu, $wp_admin_bar; $ct = wp_get_theme(); $theme_data = $ct; if ( !is_super_admin() || !is_admin_bar_showing() || !$this->args['admin_bar'] ) { return; } if($menu){ foreach($menu as $menu_item){ if(isset($menu_item[2]) && $menu_item[2]===$this->args["page_slug"]){ $nodeargs = array( 'id' => $menu_item[2], 'title' => "".$menu_item[0], 'href' => admin_url('admin.php?page='.$menu_item[2]), 'meta' => array( ) ); $wp_admin_bar->add_node( $nodeargs ); break; } } if ( isset( $submenu[$this->args["page_slug"]] ) && is_array( $submenu[$this->args["page_slug"]] ) ) { foreach($submenu[$this->args["page_slug"]] as $index => $redux_options_submenu){ $subnodeargs = array( 'id' => $this->args["page_slug"] . '_' . $index, 'title' => $redux_options_submenu[0], 'parent'=> $this->args["page_slug"], 'href' => admin_url('admin.php?page='.$redux_options_submenu[2]), ); $wp_admin_bar->add_node( $subnodeargs ); } } } else { $nodeargs = array( 'id' => $this->args["page_slug"], 'title' => "" . $theme_data->get('Name') . " " . __('Options', 'redux-framework-demo'), 'href' => admin_url('admin.php?page='.$this->args["page_slug"]), 'meta' => array() ); $wp_admin_bar->add_node( $nodeargs ); } } // _admin_bar_menu() /** * Output dynamic CSS at bottom of HEAD * * @since 3.2.8 * @access public * @return void */ public function _output_css() { if( $this->args[ 'output' ] == false && $this->args[ 'compiler' ] == false ) { return; } if ( isset( $this->no_output ) ) { return; } if ( !empty( $this->outputCSS ) && ( $this->args['output_tag'] == true || ( isset( $_POST['customized'] ) ) ) ) { echo ''; } } /** * Enqueue CSS and Google fonts for front end * * @since 1.0.0 * @access public * @return void */ public function _enqueue_output() { if( $this->args[ 'output' ] == false && $this->args[ 'compiler' ] == false ) { return; } /** @noinspection PhpUnusedLocalVariableInspection */ foreach( $this->sections as $k => $section ) { if( isset($section['type'] ) && ( $section['type'] == 'divide' ) ) { continue; } if( isset( $section['fields'] ) ) { /** @noinspection PhpUnusedLocalVariableInspection */ foreach( $section['fields'] as $fieldk => $field ) { if( isset( $field['type'] ) && $field['type'] != "callback" ) { $field_class = "ReduxFramework_{$field['type']}"; if( !class_exists( $field_class ) ) { if ( !isset( $field['compiler'] ) ) { $field['compiler'] = ""; } /** * Field class file * * filter 'redux/{opt_name}/field/class/{field.type} * @param string field class file * @param array $field field config data */ $class_file = apply_filters( "redux/{$this->args['opt_name']}/field/class/{$field['type']}", self::$_dir . "inc/fields/{$field['type']}/field_{$field['type']}.php", $field ); if( $class_file && file_exists($class_file) && !class_exists( $field_class ) ) { /** @noinspection PhpIncludeInspection */ require_once( $class_file ); } } if( !empty( $this->options[$field['id']] ) && class_exists( $field_class ) && method_exists( $field_class, 'output' ) && $this->_can_output_css($field) ) { $field = apply_filters( "redux/field/{$this->args['opt_name']}/output_css", $field ); if ( !empty($field['output']) && !is_array( $field['output'] ) ) { $field['output'] = array( $field['output'] ); } $value = isset($this->options[$field['id']]) ? $this->options[$field['id']] : ''; $enqueue = new $field_class( $field, $value, $this ); if ( ( ( isset( $field['output'] ) && !empty( $field['output'] ) ) || ( isset( $field['compiler'] ) && !empty( $field['compiler'] ) ) || $field['type'] == "typography" || $field['type'] == "icon_select" ) ) { $enqueue->output(); } } } } } } // For use like in the customizer. Stops the output, but passes the CSS in the variable for the compiler if ( isset( $this->no_output ) ) { return; } if ( !empty( $this->typography ) && !empty( $this->typography ) && filter_var( $this->args['output'], FILTER_VALIDATE_BOOLEAN ) ) { $version = !empty( $this->transients['last_save'] ) ? $this->transients['last_save'] : ''; $typography = new ReduxFramework_typography( null, null, $this ); if ( $this->args['async_typography'] && !empty($this->typography)) { $families = array(); foreach($this->typography as $key => $value) { $families[] = $key; } ?> makeGoogleWebfontLink( $this->typography ).'&v='.$version.'" type="text/css" media="all" />'; wp_register_style( 'redux-google-fonts', $protocol . $typography->makeGoogleWebfontLink( $this->typography ), '', $version ); wp_enqueue_style( 'redux-google-fonts' ); } } } // _enqueue_output() /** * Enqueue CSS/JS for options page * * @since 1.0.0 * @access public * @global $wp_styles * @return void */ public function _enqueue() { global $wp_styles; Redux_Functions::$_parent = $this; $min = Redux_Functions::isMin(); // Select2 business. Fields: Background, Border, Dimensions, Select, Slider, Typography if (Redux_Helpers::isFieldInUseByType($this->fields, array('background', 'border', 'dimensions', 'select', 'slider', 'typography'))) { // select2 CSS wp_register_style( 'select2-css', self::$_url . 'assets/js/vendor/select2/select2.css', array(), filemtime( self::$_dir . 'assets/js/vendor/select2/select2.css' ), 'all' ); wp_enqueue_style( 'select2-css' ); // JS wp_register_script( 'select2-sortable-js', self::$_url . 'assets/js/vendor/select2.sortable.min.js', array( 'jquery' ), filemtime( self::$_dir . 'assets/js/vendor/select2.sortable.min.js' ), true ); wp_register_script( 'select2-js', self::$_url . 'assets/js/vendor/select2/select2.min.js', array( 'jquery', 'select2-sortable-js' ), filemtime( self::$_dir . 'assets/js/vendor/select2/select2.min.js' ), true ); wp_enqueue_script('select2-js'); } wp_register_style( 'redux-css', self::$_url . 'assets/css/redux.css', array( 'farbtastic' ), filemtime( self::$_dir . 'assets/css/redux.css' ), 'all' ); wp_register_style( 'admin-css', self::$_url . 'assets/css/admin.css', array( 'farbtastic' ), filemtime( self::$_dir . 'assets/css/admin.css' ), 'all' ); wp_register_style( 'redux-elusive-icon', self::$_url . 'assets/css/vendor/elusive-icons/elusive-webfont.css', array(), filemtime( self::$_dir . 'assets/css/vendor/elusive-icons/elusive-webfont.css' ), 'all' ); wp_register_style( 'redux-elusive-icon-ie7', self::$_url . 'assets/css/vendor/elusive-icons/elusive-webfont-ie7.css', array(), filemtime( self::$_dir . 'assets/css/vendor/elusive-icons/elusive-webfont-ie7.css' ), 'all' ); wp_register_style( 'qtip-css', self::$_url . 'assets/css/vendor/qtip/jquery.qtip.css', array(), filemtime( self::$_dir . 'assets/css/vendor/qtip/jquery.qtip.css' ), 'all' ); $wp_styles->add_data( 'redux-elusive-icon-ie7', 'conditional', 'lte IE 7' ); /** * jQuery UI stylesheet src * filter 'redux/page/{opt_name}/enqueue/jquery-ui-css' * @param string bundled stylesheet src */ wp_register_style( 'jquery-ui-css', apply_filters( "redux/page/{$this->args['opt_name']}/enqueue/jquery-ui-css", self::$_url . 'assets/css/vendor/jquery-ui-bootstrap/jquery-ui-1.10.0.custom.css' ), '', filemtime( self::$_dir . 'assets/css/vendor/jquery-ui-bootstrap/jquery-ui-1.10.0.custom.css' ), // todo - version should be based on above post-filter src 'all' ); wp_enqueue_style( 'jquery-ui-css' ); wp_enqueue_style( 'redux-lte-ie8' ); wp_enqueue_style( 'qtip-css' ); wp_enqueue_style( 'redux-elusive-icon' ); wp_enqueue_style( 'redux-elusive-icon-ie7' ); if(is_rtl()){ wp_register_style( 'redux-rtl-css', self::$_url . 'assets/css/rtl.css', '', filemtime( self::$_dir . 'assets/css/rtl.css' ), 'all' ); wp_enqueue_style( 'redux-rtl-css' ); } wp_enqueue_script('jquery'); wp_enqueue_script('jquery-ui-core'); wp_enqueue_script('jquery-ui-dialog'); // Load jQuery sortable for slides, sorter, sortable and group if (Redux_Helpers::isFieldInUseByType($this->fields, array('slides', 'sorter', 'sortable', 'group'))) { wp_enqueue_script('jquery-ui-sortable'); wp_enqueue_style('jquery-ui-sortable'); } // Load jQuery UI Datepicker for date if (Redux_Helpers::isFieldInUseByType($this->fields, array('date'))) { wp_enqueue_script('jquery-ui-datepicker'); } // Load jQuery UI Accordion for slides and group if (Redux_Helpers::isFieldInUseByType($this->fields, array('slides', 'group'))) { wp_enqueue_script('jquery-ui-accordion'); } // Load wp-color-picker for color, color_gradient, link_color, border, and typography if (Redux_Helpers::isFieldInUseByType($this->fields, array('color', 'color_gradient', 'link_color', 'border', 'typography'))) { wp_enqueue_script('wp-color-picker'); wp_enqueue_style( 'wp-color-picker' ); } if ( function_exists( 'wp_enqueue_media' ) ) { wp_enqueue_media(); } else { wp_enqueue_script( 'media-upload' ); } add_thickbox(); wp_register_script( 'qtip-js', self::$_url . 'assets/js/vendor/qtip/jquery.qtip.js', array( 'jquery' ), '2.2.0', true ); wp_register_script( 'serializeForm-js', self::$_url . 'assets/js/vendor/jquery.serializeForm.js', array( 'jquery' ), '1.0.0', true ); // Embed the compress version unless in dev mode // dev_mode = true if ( isset($this->args['dev_mode'] ) && $this->args['dev_mode'] === true) { wp_enqueue_style( 'admin-css' ); wp_register_script( 'redux-vendor', self::$_url . 'assets/js/vendor.min.js', array( 'jquery'), filemtime( self::$_dir . 'assets/js/vendor.min.js' ), true ); // dev_mode - false } else { wp_enqueue_style( 'redux-css' ); } $depArray = array( 'jquery', 'qtip-js', 'serializeForm-js', ); if (true === $this->args['dev_mode']) { array_push($depArray, 'redux-vendor'); } wp_register_script( 'redux-js', self::$_url . 'assets/js/redux' . $min . '.js', $depArray, filemtime( self::$_dir . 'assets/js/redux' . $min . '.js' ), true ); foreach( $this->sections as $section ) { if( isset( $section['fields'] ) ) { foreach( $section['fields'] as $field ) { // TODO AFTER GROUP WORKS - Revert IF below // if( isset( $field['type'] ) && $field['type'] != 'callback' ) { if( isset( $field['type'] ) && $field['type'] != 'callback' && $field['type'] != 'group' ) { $field_class = 'ReduxFramework_' . $field['type']; /** * Field class file * * filter 'redux/{opt_name}/field/class/{field.type} * @param string field class file path * @param array $field field config data */ $class_file = apply_filters( "redux/{$this->args['opt_name']}/field/class/{$field['type']}", self::$_dir . "inc/fields/{$field['type']}/field_{$field['type']}.php", $field ); if( $class_file ) { if( !class_exists($field_class) ) { if (file_exists($class_file)) { require_once( $class_file ); } } if ( ( method_exists( $field_class, 'enqueue' ) ) || method_exists( $field_class, 'localize' ) ) { if ( !isset( $this->options[$field['id']] ) ) { $this->options[$field['id']] = ""; } $theField = new $field_class( $field, $this->options[$field['id']], $this ); // Move dev_mode check to a new if/then block if ( !wp_script_is( 'redux-field-'.$field['type'].'-js', 'enqueued' ) && class_exists($field_class) && method_exists( $field_class, 'enqueue' ) ) { // Checking for extension field AND dev_mode = false OR dev_mode = true // Since extension fields use 'extension_dir' exclusively, we can detect them here. // Also checking for dev_mode = true doesn't mess up the JS combinine. //if ( /*$this->args['dev_mode'] === false && */ isset($theField->extension_dir) && (!'' == $theField->extension_dir) /* || ($this->args['dev_mode'] === true) */) { $theField->enqueue(); //} } if ( method_exists( $field_class, 'localize' ) ) { $params = $theField->localize($field); if ( !isset( $this->localize_data[$field['type']] ) ) { $this->localize_data[$field['type']] = array(); } $this->localize_data[$field['type']][$field['id']] = $theField->localize($field); } unset($theField); } } } } } } $this->localize_data['required'] = $this->required; $this->localize_data['fonts'] = $this->fonts; $this->localize_data['required_child'] = $this->required_child; $this->localize_data['fields'] = $this->fields; $this->localize_data['fonts'] = $this->fonts; $this->localize_data['folds'] = $this->folds; // Make sure the children are all hidden properly. foreach($this->fields as $key => $value) { if ( in_array( $key, $this->fieldsHidden ) ) { foreach($value as $k => $v) { if (!in_array($k, $this->fieldsHidden)) { $this->fieldsHidden[] = $k; $this->folds[$k] = "hide"; } } } } $this->localize_data['fieldsHidden'] = $this->fieldsHidden; $this->localize_data['options'] = $this->options; $this->localize_data['defaults'] = $this->options_defaults; $this->localize_data['args'] = array( 'save_pending' => __( 'You have changes that are not saved. Would you like to save them now?', 'redux-framework' ), 'reset_confirm' => __( 'Are you sure? Resetting will lose all custom values.', 'redux-framework' ), 'reset_section_confirm' => __( 'Are you sure? Resetting will lose all custom values in this section.', 'redux-framework' ), 'preset_confirm' => __( 'Your current options will be replaced with the values of this preset. Would you like to proceed?', 'redux-framework' ), 'please_wait' => __( 'Please Wait', 'redux-framework' ), 'opt_name' => $this->args['opt_name'], 'slug' => $this->args['page_slug'], 'hints' => $this->args['hints'], 'disable_save_warn' => $this->args['disable_save_warn'], 'class' => $this->args['class'], ); // Construct the errors array. if( isset( $this->transients['last_save_mode'] ) && !empty( $this->transients['notices']['errors'] ) ) { $theTotal = 0; $theErrors = array(); foreach( $this->transients['notices']['errors'] as $error ) { $theErrors[$error['section_id']]['errors'][] = $error; if (!isset($theErrors[$error['section_id']]['total'])) { $theErrors[$error['section_id']]['total'] = 0; } $theErrors[$error['section_id']]['total']++; $theTotal++; } $this->localize_data['errors'] = array('total'=>$theTotal, 'errors'=>$theErrors); unset( $this->transients['notices']['errors'] ); } // Construct the warnings array. if( isset( $this->transients['last_save_mode'] ) && !empty( $this->transients['notices']['warnings'] ) ) { $theTotal = 0; $theWarnings = array(); foreach( $this->transients['notices']['warnings'] as $warning ) { $theWarnings[$warning['section_id']]['warnings'][] = $warning; if (!isset($theWarnings[$warning['section_id']]['total'])) { $theWarnings[$warning['section_id']]['total'] = 0; } $theWarnings[$warning['section_id']]['total']++; $theTotal++; } unset( $this->transients['notices']['warnings'] ); $this->localize_data['warnings'] = array('total'=>$theTotal, 'warnings'=>$theWarnings); } if (empty($this->transients['notices'])) { unset($this->transients['notices']); } // Values used by the javascript wp_localize_script( 'redux-js', 'redux', $this->localize_data ); wp_enqueue_script('redux-js'); // Enque the JS now wp_enqueue_script( 'webfontloader', 'https://ajax.googleapis.com/ajax/libs/webfont/1.5.0/webfont.js', array( 'jquery' ), '1.5.0', true ); /** * action 'redux-enqueue-{opt_name}' * @deprecated * @param object $this ReduxFramework */ do_action( "redux-enqueue-{$this->args['opt_name']}", $this ); // REMOVE /** * action 'redux/page/{opt_name}/enqueue' */ do_action( "redux/page/{$this->args['opt_name']}/enqueue" ); } // _enqueue() /** * Show page help * * @since 1.0.0 * @access public * @return void */ public function _load_page() { // Do admin head action for this page add_action( 'admin_head', array( &$this, 'admin_head' ) ); // Do admin footer text hook add_filter( 'admin_footer_text', array( &$this, 'admin_footer_text' ) ); $screen = get_current_screen(); if( is_array( $this->args['help_tabs'] ) ) { foreach( $this->args['help_tabs'] as $tab ) { $screen->add_help_tab( $tab ); } } // If hint argument is set, display hint tab if (true == $this->show_hints) { global $current_user; // Users enable/disable hint choice $hint_status = get_user_meta( $current_user->ID, 'ignore_hints' ) ? get_user_meta( $current_user->ID, 'ignore_hints', true ): 'true'; // current page parameters $curPage = $_GET['page']; $curTab = '0'; if (isset($_GET['tab'])) { $curTab = $_GET['tab']; } // Default url values for enabling hints. $dismiss = 'true'; $s = 'Enable'; // Values for disabling hints. if ('true' == $hint_status ) { $dismiss = 'false'; $s = 'Disable'; } // Make URL $url = '' . $s . ' hints'; $event = 'moving the mouse over'; if ('click' == $this->args['hints']['tip_effect']['show']['event']) { $event = 'clicking'; } // Construct message $msg = 'Hints are tooltips that popup when ' . $event . ' the hint icon, offering addition information about the field in which they appear. They can be ' . strtolower($s) . 'd by using the link below.

' . $url ; // Construct hint tab $tab = array ( 'id' => 'redux-hint-tab', 'title' => __('Hints', 'redux-framework-demo'), 'content' => __('

' . $msg . '

', 'redux-framework-demo') ); $screen->add_help_tab( $tab ); } // Sidebar text if( $this->args['help_sidebar'] != '' ) { // Specify users text from arguments $screen->set_help_sidebar( $this->args['help_sidebar'] ); } else { // If sidebar text is empty and hints are active, display text // about hints. if (true == $this->show_hints) { $screen->set_help_sidebar( '

Redux Framework

Hint Tooltip Preferences

' ); } } /** * action 'redux-load-page-{opt_name}' * @deprecated * @param object $screen WP_Screen */ do_action( "redux-load-page-{$this->args['opt_name']}", $screen ); // REMOVE /** * action 'redux/page/{opt_name}/load' * @param object $screen WP_Screen */ do_action( "redux/page/{$this->args['opt_name']}/load", $screen ); } // _load_page() /** * Do action redux-admin-head for options page * * @since 1.0.0 * @access public * @return void */ public function admin_head() { /** * action 'redux-admin-head-{opt_name}' * @deprecated * @param object $this ReduxFramework */ do_action( "redux-admin-head-{$this->args['opt_name']}", $this ); // REMOVE /** * action 'redux/page/{opt_name}/header' * @param object $this ReduxFramework */ do_action( "redux/page/{$this->args['opt_name']}/header", $this ); } // admin_head() /** * Return footer text * * @since 2.0.0 * @access public * @return string $this->args['footer_credit'] */ public function admin_footer_text( ) { return $this->args['footer_credit']; } // admin_footer_text() /** * Return default output string for use in panel * * @since 3.1.5 * @access public * @return string default_output */ public function get_default_output_string($field) { $default_output = ""; if ( !isset( $field['default'] ) ) { $field['default'] = ""; } if (!is_array($field['default'])) { if ( !empty( $field['options'][$field['default']] ) ) { if (!empty($field['options'][$field['default']]['alt'])) { $default_output .= $field['options'][$field['default']]['alt'] . ', '; } else { // TODO: This serialize fix may not be the best solution. Look into it. PHP 5.4 error without serialize if (!is_array($field['options'][$field['default']])) { $default_output .= $field['options'][$field['default']].", "; } else { $default_output .= serialize($field['options'][$field['default']]).", "; } } } else if ( !empty( $field['options'][$field['default']] ) ) { $default_output .= $field['options'][$field['default']].", "; } else if ( !empty( $field['default'] ) ) { $default_output .= $field['default'] . ', '; } } else { foreach( $field['default'] as $defaultk => $defaultv ) { if (!empty($field['options'][$defaultv]['alt'])) { $default_output .= $field['options'][$defaultv]['alt'] . ', '; } else if ( !empty( $field['options'][$defaultv] ) ) { $default_output .= $field['options'][$defaultv].", "; } else if ( !empty( $field['options'][$defaultk] ) ) { $default_output .= $field['options'][$defaultk].", "; } else if ( !empty( $defaultv ) ) { $default_output .= $defaultv.', '; } } } if ( !empty( $default_output ) ) { $default_output = __( 'Default', 'redux-framework' ) . ": " . substr($default_output, 0, -2); } if (!empty($default_output)) { $default_output = ''.$default_output.'
'; } return $default_output; } // get_default_output_string() public function get_header_html( $field ) { global $current_user; // Set to empty string to avoid wanrings. $hint = ''; $th = ""; if( isset( $field['title'] ) && isset( $field['type'] ) && $field['type'] !== "info" && $field['type'] !== "group" && $field['type'] !== "section" ) { $default_mark = ( !empty($field['default']) && isset($this->options[$field['id']]) && $this->options[$field['id']] == $field['default'] && !empty( $this->args['default_mark'] ) && isset( $field['default'] ) ) ? $this->args['default_mark'] : ''; // If a hint is specified in the field, process it. if (isset($field['hint']) && !'' == $field['hint']) { // Set show_hints flag to true, so helptab will be displayed. $this->show_hints = true; // Get user pref for displaying hints. $metaVal = get_user_meta( $current_user->ID, 'ignore_hints', true); if ('true' == $metaVal || empty($metaVal)) { // Set hand cursor for clickable hints $pointer = ''; if (isset($this->args['hints']['tip_effect']['show']['event']) && 'click' == $this->args['hints']['tip_effect']['show']['event']) { $pointer = 'pointer'; } $size = '16px'; if ('large' == $this->args['hints']['icon_size']) { $size = '18px'; } // In case docs are ignored. $titleParam = isset($field['hint']['title']) ? $field['hint']['title'] : ''; $contentParam = isset($field['hint']['content']) ? $field['hint']['content'] : ''; $hint_color = isset($this->args['hints']['icon_color']) ? $this->args['hints']['icon_color'] : '#d3d3d3'; // Set hint html with appropriate position css $hint = '
  
'; } } if (!empty($field['title'])) { if ('left' == $this->args['hints']['icon_position']) { $th = $hint . $field['title'] . $default_mark . ""; } else { $th = $field['title'] . $default_mark . "" . $hint; } } if( isset( $field['subtitle'] ) ) { $th .= '' . $field['subtitle'] . ''; } } if (!empty($th)) { $th = '
' . $th . '
'; } if ( $this->args['default_show'] === true && isset( $field['default'] ) && isset($this->options[$field['id']]) && $this->options[$field['id']] != $field['default'] && $field['type'] !== "info" && $field['type'] !== "group" && $field['type'] !== "section" && $field['type'] !== "editor" && $field['type'] !== "ace_editor" ) { $th .= $this->get_default_output_string($field); } return $th; } /** * Register Option for use * * @since 1.0.0 * @access public * @return void */ public function _register_settings() { // TODO - REMOVE // Not used by new sample-config, but in here for legacy builds // This is bad and can break things. Hehe. if( !function_exists( 'wp_get_current_user' ) ) { include(ABSPATH . "wp-includes/pluggable.php"); } register_setting( $this->args['opt_name'] . '_group', $this->args['opt_name'], array( $this,'_validate_options' ) ); if( is_null( $this->sections ) ) { return; } $this->options_defaults = $this->_default_values(); $runUpdate = false; foreach( $this->sections as $k => $section ) { if( isset($section['type'] ) && $section['type'] == 'divide' ) { continue; } $display = true; if ( isset( $_GET['page'] ) && $_GET['page'] == $this->args['page_slug'] ) { if ( isset($section['panel']) && $section['panel'] == false ) { $display = false; } } if (!$display) { continue; } // DOVY! Replace $k with $section['id'] when ready /** * filter 'redux-section-{index}-modifier-{opt_name}' * @param array $section section configuration */ $section = apply_filters( "redux-section-{$k}-modifier-{$this->args['opt_name']}", $section ); /** * filter 'redux/options/{opt_name}/section/{section.id}' * @param array $section section configuration */ if (isset($section['id'])) { $section = apply_filters( "redux/options/{$this->args['opt_name']}/section/{$section['id']}", $section ); } if (!isset($section['title'])) { $section['title'] = ""; } $heading = isset($section['heading']) ? $section['heading'] : $section['title']; if (isset($section['permissions'])) { if ( !current_user_can($section['permissions']) ) { $this->hidden_perm_sections[] = $section['title']; foreach($section['fields'] as $num => $field_data) { $field_type = $field_data['type']; if ($field_type != 'section' || $field_type != 'divide' || $field_type != 'info' || $field_type != 'raw' ) { $field_id = $field_data['id']; $default = isset($this->options_defaults[$field_id]) ? $this->options_defaults[$field_id] : ''; $data = isset($this->options[$field_id]) ? $this->options[$field_id] : $default; $this->hidden_perm_fields[$field_id] = $data; } } continue; } } add_settings_section( $this->args['opt_name'] . $k . '_section', $heading, array( &$this, '_section_desc' ), $this->args['opt_name'] . $k . '_section_group' ); $sectionIndent = false; if( isset( $section['fields'] ) ) { foreach( $section['fields'] as $fieldk => $field ) { if ( !isset( $field['type'] ) ) { continue; // You need a type! } /** * filter 'redux/options/{opt_name}/field/{field.id}' * @param array $field field config */ $field = apply_filters( "redux/options/{$this->args['opt_name']}/field/{$field['id']}/register", $field ); $display = true; if ( isset( $_GET['page'] ) && $_GET['page'] == $this->args['page_slug'] ) { if ( isset($field['panel']) && $field['panel'] == false ) { $display = false; } } if (!$display) { continue; } // TODO AFTER GROUP WORKS - Remove IF statement if ( $field['type'] == "group" && isset( $_GET['page'] ) && $_GET['page'] == $this->args['page_slug'] ) { if ( $this->args['dev_mode'] ) { $this->admin_notices[] = array( 'type' => 'error', 'msg' => 'The group field has been removed while we retool it for improved performance.', 'id' => 'group_err', 'dismiss' => true, ); } continue; // Disabled for now } if (isset($field['permissions'])) { if ( !current_user_can($field['permissions']) ) { $data = isset($this->options[$field['id']]) ? $this->options[$field['id']] : $this->options_defaults[$field['id']]; $this->hidden_perm_fields[$field['id']] = $data; continue; } } if (!isset($field['id'])) { echo '

No field ID is set.

';
                            print_r($field);
                            echo "

"; continue; } if ( isset( $field['type'] ) && $field['type'] == "section" ) { if ( isset( $field['indent'] ) && $field['indent'] == true ) { $sectionIndent = true; } else { $sectionIndent = false; } } if ( isset( $field['type'] ) && $field['type'] == "info" && $sectionIndent ) { $field['sectionIndent'] = $sectionIndent; } $th = $this->get_header_html( $field ); $field['name'] = $this->args['opt_name'] . '[' . $field['id'] . ']'; // Set the default value if present $this->options_defaults[$field['id']] = isset( $this->options_defaults[$field['id']] ) ? $this->options_defaults[$field['id']] : ''; // Set the defaults to the value if not present $doUpdate = false; // Check fields for values in the default parameter if ( !isset( $this->options[$field['id']] ) && isset( $field['default'] )) { $this->options_defaults[$field['id']] = $this->options[$field['id']] = $field['default']; $doUpdate = true; // Check fields that hae no default value, but an options value with settings to // be saved by default } elseif ( !isset( $this->options[$field['id']] ) && isset( $field['options'] )) { // If sorter field, check for options as save them as defaults if ($field['type'] == 'sorter' || $field['type'] == 'sortable') { $this->options_defaults[$field['id']] = $this->options[$field['id']] = $field['options']; $doUpdate = true; } } // CORRECT URLS if media URLs are wrong, but attachment IDs are present. if ( $field['type'] == "media" ) { if (isset($this->options[$field['id']]['id']) && isset($this->options[$field['id']]['url']) && !empty($this->options[$field['id']]['url']) && strpos($this->options[$field['id']]['url'], str_replace( 'http://', '', WP_CONTENT_URL ) ) === FALSE) { $data = wp_get_attachment_url( $this->options[$field['id']]['id'] ); if ( isset( $data ) && !empty( $data ) ) { $this->options[$field['id']]['url'] = $data; $data = wp_get_attachment_image_src( $this->options[$field['id']]['id'], array(150,150) ); $this->options[$field['id']]['thumbnail'] = $data[0]; $doUpdate = true; } } } if ( $field['type'] == "background" ) { if (isset($this->options[$field['id']]['media']['id']) && isset($this->options[$field['id']]['background-image']) && !empty($this->options[$field['id']]['background-image']) && strpos($this->options[$field['id']]['background-image'], str_replace( 'http://', '', WP_CONTENT_URL ) ) === FALSE) { $data = wp_get_attachment_url( $this->options[$field['id']]['media']['id'] ); if ( isset( $data ) && !empty( $data ) ) { $this->options[$field['id']]['background-image'] = $data; $data = wp_get_attachment_image_src( $this->options[$field['id']]['media']['id'], array(150,150) ); $this->options[$field['id']]['media']['thumbnail'] = $data[0]; $doUpdate = true; } } } if ( $field['type'] == "slides" ) { if (isset($this->options[$field['id']][0]['attachment_id']) && isset($this->options[$field['id']][0]['image']) && !empty($this->options[$field['id']][0]['image']) && strpos($this->options[$field['id']][0]['image'], str_replace( 'http://', '', WP_CONTENT_URL ) ) === FALSE) { foreach($this->options[$field['id']] as $k => $v) { $data = wp_get_attachment_url( $v['attachment_id'] ); if ( isset( $data ) && !empty( $data ) ) { $this->options[$field['id']][$k]['image'] = $data; $data = wp_get_attachment_image_src( $v['attachment_id'], array(150,150) ); $this->options[$field['id']][$k]['thumb'] = $data[0]; $doUpdate = true; } } } } // END -> CORRECT URLS if media URLs are wrong, but attachment IDs are present. if (true == $doUpdate && !isset($this->never_save_to_db)) { if ( $this->args['save_defaults'] ) { // Only save that to the DB if allowed to $runUpdate = true; }// elseif($this->saved != '' && $this->saved != false) { // $runUpdate = true; //} } if (!isset($field['class'])) { // No errors please $field['class'] = ""; } $id = $field['id']; /** * filter 'redux-field-{field.id}modifier-{opt_name}' * @deprecated * @param array $field field config */ $field = apply_filters( "redux-field-{$field['id']}modifier-{$this->args['opt_name']}", $field ); // REMOVE LATER /** * filter 'redux/options/{opt_name}/field/{field.id}' * @param array $field field config */ $field = apply_filters( "redux/options/{$this->args['opt_name']}/field/{$field['id']}", $field ); if ( empty( $field ) || !$field || $field == false ) { unset( $this->sections[$k]['fields'][$fieldk] ); continue; } if ( !empty( $this->folds[$field['id']]['parent'] ) ) { // This has some fold items, hide it by default $field['class'] .= " fold"; } if ( !empty( $this->folds[$field['id']]['children'] ) ) { // Sets the values you shoe fold children on $field['class'] .= " foldParent"; } if ( !empty( $field['compiler'] ) ) { $field['class'] .= " compiler"; $this->compiler_fields[$field['id']] = 1; } if ( isset( $field['unit'] ) && !isset( $field['units'] ) ) { $field['units'] = $field['unit']; unset( $field['unit'] ); } $this->sections[$k]['fields'][$fieldk] = $field; if( isset( $this->args['display_source'] ) ) { $th .= ''; $th .= '
View Source'; } /** * action 'redux/options/{opt_name}/field/field.type}/register' */ do_action( "redux/options/{$this->args['opt_name']}/field/{$field['type']}/register", $field ); $this->check_dependencies($field); add_settings_field( "{$fieldk}_field", $th, array( &$this, '_field_input' ), "{$this->args['opt_name']}{$k}_section_group", "{$this->args['opt_name']}{$k}_section", $field ); // checkbox } } } /** * action 'redux-register-settings-{opt_name}' * @deprecated */ do_action( "redux-register-settings-{$this->args['opt_name']}" ); // REMOVE /** * action 'redux/options/{opt_name}/register' * @param array option sections */ do_action( "redux/options/{$this->args['opt_name']}/register", $this->sections); if ( $runUpdate && !isset( $this->never_save_to_db ) ) { // Always update the DB with new fields $this->set_options( $this->options ); } if ( isset( $this->transients['run_compiler'] ) && $this->transients['run_compiler'] ) { $this->args['output_tag'] = false; $this->_enqueue_output(); /** * action 'redux-compiler-{opt_name}' * @deprecated * @param array options * @param string CSS that get sent to the compiler hook */ do_action( "redux-compiler-{$this->args['opt_name']}", $this->options, $this->compilerCSS, $this->transients['changed_values'] ); // REMOVE /** * action 'redux/options/{opt_name}/compiler' * @param array options * @param string CSS that get sent to the compiler hook */ do_action( "redux/options/{$this->args['opt_name']}/compiler", $this->options, $this->compilerCSS, $this->transients['changed_values'] ); unset( $this->transients['run_compiler'] ); $this->set_transients(); } } // _register_settings() /** * Register Extensions for use * * @since 3.0.0 * @access public * @return void */ public function _register_extensions() { $path = dirname( __FILE__ ) . '/extensions/'; $folders = scandir( $path, 1 ); /** * action 'redux/extensions/{opt_name}/before' * @param object $this ReduxFramework */ do_action( "redux/extensions/{$this->args['opt_name']}/before", $this ); foreach($folders as $folder){ if ($folder === '.' || $folder === '..' || !is_dir($path . $folder) || substr($folder, 0, 1) === '.' ) { continue; } $extension_class = 'ReduxFramework_Extension_' . $folder; if( !class_exists( $extension_class ) ) { /** * filter 'redux-extensionclass-load' * @deprecated * @param string extension class file path * @param string $extension_class extension class name */ $class_file = apply_filters( "redux-extensionclass-load", "$path/$folder/extension_{$folder}.php", $extension_class ); // REMOVE LATER /** * filter 'redux/extension/{opt_name}/{folder}' * @param string extension class file path * @param string $extension_class extension class name */ $class_file = apply_filters( "redux/extension/{$this->args['opt_name']}/$folder", "$path/$folder/extension_{$folder}.php", $class_file ); if( $class_file ) { if (file_exists($class_file)) { require_once( $class_file ); } $this->extensions[$folder] = new $extension_class( $this ); } } } /** * action 'redux-register-extensions-{opt_name}' * @deprecated * @param object $this ReduxFramework */ do_action( "redux-register-extensions-{$this->args['opt_name']}", $this ); // REMOVE /** * action 'redux/extensions/{opt_name}' * @param object $this ReduxFramework */ do_action( "redux/extensions/{$this->args['opt_name']}", $this ); } public function get_transients() { if (!isset($this->transients)) { $this->transients = get_transient( $this->args['opt_name'] . '-transients', array() ); $this->transients_check = $this->transients; } } public function set_transients() { if ( !isset( $this->transients ) || !isset( $this->transients_check ) || $this->transients != $this->transients_check ) { set_transient( $this->args['opt_name'] . '-transients', $this->transients ); $this->transients_check = $this->transients; } } /** * Validate the Options options before insertion * @since 3.0.0 * @access public * @param array $plugin_options The options array * @return array|mixed|string|void */ public function _validate_options( $plugin_options ) { if (!empty($this->hidden_perm_fields) && is_array($this->hidden_perm_fields)) { foreach($this->hidden_perm_fields as $id => $data) { $plugin_options[$id] = $data; } } if ( $plugin_options == $this->options ) { return $plugin_options; } $time = time(); // Sets last saved time $this->transients['last_save'] = $time; // Import if( !empty( $plugin_options['import'] ) ) { $this->transients['last_save_mode'] = "import"; // Last save mode $this->transients['last_compiler'] = $time; $this->transients['last_import'] = $time; $this->transients['run_compiler'] = 1; if( $plugin_options['import_code'] != '' ) { $import = $plugin_options['import_code']; } elseif( $plugin_options['import_link'] != '' ) { $import = wp_remote_retrieve_body( wp_remote_get( $plugin_options['import_link'] ) ); } if ( !empty( $import ) ) { $imported_options = json_decode( $import, true ); } if( !empty( $imported_options ) && is_array( $imported_options ) && isset( $imported_options['redux-backup'] ) && $imported_options['redux-backup'] == '1' ) { $this->transients['changed_values'] = array(); foreach( $plugin_options as $key => $value) { if ( isset($imported_options[$key]) && $imported_options[$key] != $value ) { $this->transients['changed_values'][$key] = $value; $plugin_options[$key] = $value; } } /** * action 'redux/options/{opt_name}/import' * @param &array [&$plugin_options, redux_options] */ do_action_ref_array( "redux/options/{$this->args['opt_name']}/import", array(&$plugin_options, $imported_options, $this->transients['changed_values'])); // Remove the import/export tab cookie. if( $_COOKIE['redux_current_tab'] == 'import_export_default' ) { setcookie( 'redux_current_tab', '', 1, '/' ); $_COOKIE['redux_current_tab'] = 1; } setcookie( 'redux_current_tab', '', 1, '/', $time+1000, "/" ); $_COOKIE['redux_current_tab'] = 1; unset( $plugin_options['defaults'], $plugin_options['compiler'], $plugin_options['import'], $plugin_options['import_code'] ); if ( $this->args['database'] == 'transient' || $this->args['database'] == 'theme_mods' || $this->args['database'] == 'theme_mods_expanded' || $this->args['database'] == 'network' ) { $this->set_options( $plugin_options ); return; } $plugin_options = wp_parse_args( $imported_options, $plugin_options ); $this->set_transients(); // Update the transients return $plugin_options; } } // Reset all to defaults if( !empty( $plugin_options['defaults'] ) ) { if ( empty( $this->options_defaults ) ) { $this->options_defaults = $this->_default_values(); } // Section reset //setcookie('redux-compiler-' . $this->args['opt_name'], 1, time() + 3000, '/'); $plugin_options = $this->options_defaults; $this->transients['changed_values'] = array(); foreach($this->options as $key => $value) { if (isset($plugin_options[$key]) && $value != $plugin_options[$key]) { $this->transients['changed_values'][$key] = $value; } } $this->transients['run_compiler'] = 1; $this->transients['last_save_mode'] = "defaults"; // Last save mode //setcookie('redux-compiler-' . $this->args['opt_name'], 1, time() + 1000, "/"); //setcookie("redux-saved-{$this->args['opt_name']}", 'defaults', time() + 1000, "/"); $this->set_transients(); // Update the transients return $plugin_options; } // Section reset to defaults if ( !empty( $plugin_options['defaults-section'] ) ) { if (isset($plugin_options['redux-section']) && isset($this->sections[$plugin_options['redux-section']]['fields'])) { foreach ( $this->sections[$plugin_options['redux-section']]['fields'] as $field ) { if (isset($this->options_defaults[$field['id']])) { $plugin_options[$field['id']] = $this->options_defaults[$field['id']]; } else { $plugin_options[$field['id']] = ""; } if (isset($field['compiler'])) { $compiler = true; } } } $this->transients['changed_values'] = array(); foreach($this->options as $key => $value) { if (isset($plugin_options[$key]) && $value != $plugin_options[$key]) { $this->transients['changed_values'][$key] = $value; } } if ( isset( $compiler ) ) { //$this->run_compiler = true; //setcookie('redux-compiler-' . $this->args['opt_name'], 1, time()+1000, '/'); //$plugin_options['REDUX_COMPILER'] = time(); $this->transients['last_compiler'] = $time; $this->transients['run_compiler'] = 1; } $this->transients['last_save_mode'] = "defaults_section"; // Last save mode //setcookie("redux-saved-{$this->args['opt_name']}", 'defaults_section', time() + 1000, "/"); 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'] ); $this->set_transients(); return $plugin_options; } $this->transients['last_save_mode'] = "normal"; // Last save mode // Validate fields (if needed) $plugin_options = $this->_validate_values( $plugin_options, $this->options, $this->sections ); if( !empty( $this->errors ) || !empty( $this->warnings ) ) { $this->transients['notices'] = array( 'errors' => $this->errors, 'warnings' => $this->warnings ); } /** * action 'redux-validate-{opt_name}' * @deprecated * @param &array [&$plugin_options, redux_options] */ do_action_ref_array( "redux-validate-{$this->args['opt_name']}", array(&$plugin_options, $this->options)); // REMOVE /** * action 'redux/options/{opt_name}/validate' * @param &array [&$plugin_options, redux_options] */ do_action_ref_array( "redux/options/{$this->args['opt_name']}/validate", array(&$plugin_options, $this->options, $this->transients['changed_values'])); if( !empty( $plugin_options['compiler'] ) ) { unset($plugin_options['compiler']); $this->transients['last_compiler'] = $time; $this->transients['run_compiler'] = 1; } $this->transients['changed_values'] = array(); // Changed values since last save foreach($this->options as $key => $value) { if (isset($plugin_options[$key]) && $value != $plugin_options[$key]) { $this->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 ( $this->args['database'] == 'transient' || $this->args['database'] == 'theme_mods' || $this->args['database'] == 'theme_mods_expanded' ) { $this->set_options( $plugin_options ); return; } $this->set_transients(); return $plugin_options; } /** * Validate values from options form (used in settings api validate function) * calls the custom validation class for the field so authors can override with custom classes * * @since 1.0.0 * @access public * @param array $plugin_options * @param array $options * @return array $plugin_options */ public function _validate_values( $plugin_options, $options, $sections ) { foreach( $sections as $k => $section ) { if( isset( $section['fields'] ) ) { foreach( $section['fields'] as $fkey => $field ) { $field['section_id'] = $k; if( isset( $field['type'] ) && ( $field['type'] == 'checkbox' || $field['type'] == 'checkbox_hide_below' || $field['type'] == 'checkbox_hide_all' ) ) { if( !isset( $plugin_options[$field['id']] ) ) { $plugin_options[$field['id']] = 0; } } // Default 'not_empty 'flag to false. $isNotEmpty = false; // Make sure 'validate' field is set. if (isset($field['validate'])) { // Make sure 'validate field' is set to 'not_empty' or 'email_not_empty' if ($field['validate'] == 'not_empty' || $field['validate'] == 'email_not_empty') { // Set the flag. $isNotEmpty = true; } } // Check for empty id value if( !isset( $plugin_options[$field['id']] ) || $plugin_options[$field['id']] == '' ){ // If we are looking for an empty value, in the case of 'not_empty' // then we need to keep processing. if (!$isNotEmpty) { // Empoty id and not checking for 'not_empty. Bail out... continue; } } // Force validate of custom field types if( isset( $field['type'] ) && !isset( $field['validate'] ) ) { if( $field['type'] == 'color' || $field['type'] == 'color_gradient' ) { $field['validate'] = 'color'; } elseif( $field['type'] == 'date' ) { $field['validate'] = 'date'; } } if( isset( $field['validate'] ) ) { $validate = 'Redux_Validation_' . $field['validate']; if( !class_exists( $validate ) ) { /** * filter 'redux-validateclass-load' * @deprecated * @param string validation class file path * @param string $validate validation class name */ $class_file = apply_filters( "redux-validateclass-load", self::$_dir . "inc/validation/{$field['validate']}/validation_{$field['validate']}.php", $validate ); // REMOVE LATER /** * filter 'redux/validate/{opt_name}/class/{field.validate}' * @param string validation class file path * @param string $class_file validation class file path */ $class_file = apply_filters( "redux/validate/{$this->args['opt_name']}/class/{$field['validate']}", self::$_dir . "inc/validation/{$field['validate']}/validation_{$field['validate']}.php", $class_file ); if( $class_file ) { if ( file_exists( $class_file ) ) { require_once( $class_file ); } } } if( class_exists( $validate ) ) { //!DOVY - DB saving stuff. Is this right? if ( empty ( $options[$field['id']] ) ) { $options[$field['id']] = ''; } if ( isset( $plugin_options[$field['id']] ) && is_array( $plugin_options[$field['id']] ) && !empty( $plugin_options[$field['id']] ) ) { foreach ( $plugin_options[$field['id']] as $key => $value ) { $before = $after = null; if ( isset( $plugin_options[$field['id']][$key] ) && !empty( $plugin_options[$field['id']][$key] ) ) { if (is_array($plugin_options[$field['id']][$key])) { $before = $plugin_options[$field['id']][$key] ; } else { $before = trim( $plugin_options[$field['id']][$key] ); } } if ( isset( $options[$field['id']][$key] ) && !empty( $options[$field['id']][$key] ) ) { $after = $options[$field['id']][$key]; } $validation = new $validate($this, $field, $before, $after ); if ( !empty( $validation->value ) ) { $plugin_options[$field['id']][$key] = $validation->value; } else { unset( $plugin_options[$field['id']][$key] ); } if( isset( $validation->error ) ) { $this->errors[] = $validation->error; } if( isset( $validation->warning) ) { $this->warnings[] = $validation->warning; } } } else { if (is_array($plugin_options[$field['id']])) { $pofi = $plugin_options[$field['id']]; } else { $pofi = trim($plugin_options[$field['id']]); } $validation = new $validate( $this, $field, $pofi, $options[$field['id']] ); $plugin_options[$field['id']] = $validation->value; if( isset( $validation->error ) ) { $this->errors[] = $validation->error; } if( isset( $validation->warning) ) { $this->warnings[] = $validation->warning; } } continue; } } if( isset( $field['validate_callback'] ) && function_exists( $field['validate_callback'] ) ) { $callbackvalues = call_user_func( $field['validate_callback'], $field, $plugin_options[$field['id']], $options[$field['id']] ); $plugin_options[$field['id']] = $callbackvalues['value']; if( isset( $callbackvalues['error'] ) ) { $this->errors[] = $callbackvalues['error']; } if( isset( $callbackvalues['warning'] ) ) { $this->warnings[] = $callbackvalues['warning']; } } } } } return $plugin_options; } /** * Return Section Menu HTML * * @since 3.1.5 * @access public * @return void */ public function section_menu($k, $section, $suffix = "", $sections = array()) { $display = true; $section['class'] = isset( $section['class'] ) ? ' ' . $section['class'] : ''; if ( isset( $_GET['page'] ) && $_GET['page'] == $this->args['page_slug'] ) { if ( isset($section['panel']) && $section['panel'] == false ) { $display = false; } } if (!$display) { return ""; } if (empty($sections)) { $sections = $this->sections; } $string = ""; if( (isset($this->args['icon_type']) && $this->args['icon_type'] == 'image') || (isset($section['icon_type']) && $section['icon_type'] == 'image')) { //if( !empty( $this->args['icon_type'] ) && $this->args['icon_type'] == 'image' ) { $icon = ( !isset( $section['icon'] ) ) ? '' : ' '; } else { if ( ! empty( $section['icon_class'] ) ) { $icon_class = ' ' . $section['icon_class']; } elseif ( ! empty( $this->args['default_icon_class'] ) ) { $icon_class = ' ' . $this->args['default_icon_class']; } else { $icon_class = ''; } $icon = ( !isset( $section['icon'] ) ) ? ' ' : ' '; } $canBeSubSection = ($k > 0 && (!isset($sections[($k)]['type']) || $sections[($k)]['type'] != "divide")) ? true : false; if (!$canBeSubSection && isset($section['subsection']) && $section['subsection'] == true) { unset($section['subsection']); } if (isset($section['type']) && $section['type'] == "divide") { $string .= '
  •  
  • '; } else if (!isset($section['subsection']) || $section['subsection'] != true ) { // DOVY! REPLACE $k with $section['ID'] when used properly. //$active = ( ( is_numeric($this->current_tab) && $this->current_tab == $k ) || ( !is_numeric($this->current_tab) && $this->current_tab === $k ) ) ? ' active' : ''; $subsections = ( isset( $sections[($k+1)] ) && isset($sections[($k+1)]['subsection']) && $sections[($k+1)]['subsection'] == true ) ? true : false; $subsectionsClass = $subsections ? ' hasSubSections' : ''; $extra_icon = $subsections ? ' ' : ''; $string .= ''; } return $string; } // section_menu() /** * HTML OUTPUT. * * @since 1.0.0 * @access public * @return void */ public function _options_page_html() { echo '

    '; // Stupid hack for Wordpress alerts and warnings echo '
    '; echo '
    '; // Do we support JS? echo ''; // Security is vital! echo ''; /** * action 'redux-page-before-form-{opt_name}' * @deprecated */ do_action( "redux-page-before-form-{$this->args['opt_name']}" ); // Remove /** * action 'redux/page/{opt_name}/form/before' * @param object $this ReduxFramework */ do_action( "redux/page/{$this->args['opt_name']}/form/before", $this ); // Main container $expanded = ($this->args['open_expanded']) ? ' fully-expanded' : ''; echo '
    '; $url = './options.php'; if ( $this->args['database'] == "network" && $this->args['network_admin'] ) { if ( is_network_admin() ) { $url = './edit.php?action=redux_' . $this->args['opt_name']; } } echo '
    '; echo ''; echo ''; settings_fields( "{$this->args['opt_name']}_group" ); // Last tab? $this->options['last_tab'] = ( isset( $_GET['tab'] ) && !isset( $this->transients['last_save_mode'] ) ) ? $_GET['tab'] : ''; echo ''; // Header area echo '
    '; if( !empty( $this->args['display_name'] ) ) { echo '
    '; echo '

    ' . $this->args['display_name'] . '

    '; if( !empty( $this->args['display_version'] ) ) { echo '' . $this->args['display_version'] . ''; } echo '
    '; } // Page icon // DOVY! echo '
    '; echo '
    '; echo '
    '; // Intro text if( isset( $this->args['intro_text'] ) ) { echo '
    '; echo $this->args['intro_text']; echo '
    '; } // Stickybar echo '
    '; echo '
    '; $expanded = ($this->args['open_expanded']) ? ' expanded' : ''; echo '' . __( 'Expand', 'redux-framework' ) . ''; echo '
    '; submit_button( __( 'Save Changes', 'redux-framework'), 'primary', 'redux_save', false ); echo ' '; submit_button( __( 'Reset Section', 'redux-framework'), 'secondary', $this->args['opt_name'] . '[defaults-section]', false ); echo ' '; submit_button( __( 'Reset All', 'redux-framework' ), 'secondary', $this->args['opt_name'] . '[defaults]', false ); echo '
    '; echo '
     
    '; echo '
    '; echo '
    '; // Warning bar if( isset( $this->transients['last_save_mode'] ) ) { if( $this->transients['last_save_mode'] == "import" ) { /** * action 'redux/options/{opt_name}/import' * @param object $this ReduxFramework */ do_action( "redux/options/{$this->args['opt_name']}/import", $this, $this->transients['changed_values'] ); /** * filter 'redux-imported-text-{opt_name}' * @param string translated "settings imported" text */ echo '
    ' . apply_filters( "redux-imported-text-{$this->args['opt_name']}", __( 'Settings Imported!', 'redux-framework' ) ) . '
    '; //exit(); } else if( $this->transients['last_save_mode'] == "defaults" ) { /** * action 'redux/options/{opt_name}/reset' * @param object $this ReduxFramework */ do_action( "redux/options/{$this->args['opt_name']}/reset", $this ); /** * filter 'redux-defaults-text-{opt_name}' * @param string translated "settings imported" text */ echo '
    ' . apply_filters( "redux-defaults-text-{$this->args['opt_name']}", __( 'All Defaults Restored!', 'redux-framework' ) ) . '
    '; } else if( $this->transients['last_save_mode'] == "defaults_section" ) { /** * action 'redux/options/{opt_name}/section/reset' * @param object $this ReduxFramework */ do_action( "redux/options/{$this->args['opt_name']}/section/reset", $this ); /** * filter 'redux-defaults-section-text-{opt_name}' * @param string translated "settings imported" text */ echo '
    ' . apply_filters( "redux-defaults-section-text-{$this->args['opt_name']}", __( 'Section Defaults Restored!', 'redux-framework' ) ) . '
    '; } else { /** * action 'redux/options/{opt_name}/saved' * @param mixed $value set/saved option value */ do_action( "redux/options/{$this->args['opt_name']}/saved", $this->options, $this->transients['changed_values'] ); /** * filter 'redux-saved-text-{opt_name}' * @param string translated "settings saved" text */ echo '
    ' . apply_filters( "redux-saved-text-{$this->args['opt_name']}", __( 'Settings Saved!', 'redux-framework' ) ) . '
    '; } unset( $this->transients['last_save_mode'] ); } /** * action 'redux/options/{opt_name}/settings/changes' * @param mixed $value set/saved option value */ do_action( "redux/options/{$this->args['opt_name']}/settings/change", $this->options, $this->transients['changed_values'] ); /** * filter 'redux-changed-text-{opt_name}' * @param string translated "settings have changed" text */ echo '
    ' . apply_filters( "redux-changed-text-{$this->args['opt_name']}", __( 'Settings have changed, you should save them!', 'redux-framework' ) ) . '
    '; /** * action 'redux/options/{opt_name}/errors' * @param array $this->errors error information */ do_action( "redux/options/{$this->args['opt_name']}/errors", $this->errors ); echo '
    ' . __( 'error(s) were found!', 'redux-framework' ) . '
    '; /** * action 'redux/options/{opt_name}/warnings' * @param array $this->warnings warning information */ do_action( "redux/options/{$this->args['opt_name']}/warnings", $this->warnings ); echo '
    ' . __( 'warning(s) were found!', 'redux-framework' ) . '
    '; echo '
    '; echo '
    '; // Sidebar echo '
    '; echo '
      '; foreach( $this->sections as $k => $section ) { $title = isset($section['title']) ? $section['title'] : ''; $skip_sec = false; foreach($this->hidden_perm_sections as $num => $section_title) { if ($section_title == $title) { $skip_sec = true; } } if (false == $skip_sec) { echo $this->section_menu($k, $section); $skip_sec = false; } } echo '
    •  
    • '; /** * action 'redux-page-after-sections-menu-{opt_name}' * @param object $this ReduxFramework */ do_action( "redux-page-after-sections-menu-{$this->args['opt_name']}", $this ); /** * action 'redux/page/{opt_name}/menu/after' * @param object $this ReduxFramework */ do_action( "redux/page/{$this->args['opt_name']}/menu/after", $this ); // Import / Export tab if( true == $this->args['show_import_export'] && false == $this->import_export->is_field ) { $this->import_export->render_tab(); } // Debug tab if( $this->args['dev_mode'] === true ) { $this->debug->render_tab(); } if( $this->args['system_info'] === true ) { echo ''; } echo '
    '; echo '
    '; echo '
    '; foreach( $this->sections as $k => $section ) { //$active = ( ( is_numeric($this->current_tab) && $this->current_tab == $k ) || ( !is_numeric($this->current_tab) && $this->current_tab === $k ) ) ? ' style="display: block;"' : ''; $section['class'] = isset( $section['class'] ) ? ' ' . $section['class'] : ''; echo '
    '; //echo '
    '; echo ''; foreach ($section['tab'] as $subkey => $subsection) { echo '
    '; echo '
    '; echo "hello ".$subkey; do_settings_sections( $this->args['opt_name'] . $k . '_tab_' . $subkey . '_section_group' ); echo "
    "; echo "
    "; } echo "
    "; } else { */ // Don't display in the $display = true; if ( isset( $_GET['page'] ) && $_GET['page'] == $this->args['page_slug'] ) { if ( isset($section['panel']) && $section['panel'] == "false") { $display = false; } } if ( $display ) { do_settings_sections( $this->args['opt_name'] . $k . '_section_group' ); } //} echo "
    "; //echo '
    '; } // Import / Export output if( true == $this->args['show_import_export'] && false == $this->import_export->is_field ) { $this->import_export->enqueue(); $this->import_export->render(); } // Debug object output if( $this->args['dev_mode'] === true ) { $this->debug->render(); } if( $this->args['system_info'] === true ) { require_once 'inc/sysinfo.php'; $system_info = new Simple_System_Info(); echo '
    '; echo '

    ' . __( 'System Info', 'redux-framework' ) . '

    '; echo '
    '; echo $system_info->get( true ); echo '
    '; echo '
    '; } /** * action 'redux/page-after-sections-{opt_name}' * @deprecated * @param object $this ReduxFramework */ do_action( "redux/page-after-sections-{$this->args['opt_name']}", $this ); // REMOVE LATER /** * action 'redux/page/{opt_name}/sections/after' * @param object $this ReduxFramework */ do_action( "redux/page/{$this->args['opt_name']}/sections/after", $this ); echo '
    '; echo '
    '; echo '
    '; echo ''; echo '
    '; echo ( isset( $this->args['footer_text'] ) ) ? '' : ''; /** * action 'redux-page-after-form-{opt_name}' * @deprecated */ do_action( "redux-page-after-form-{$this->args['opt_name']}" ); // REMOVE /** * action 'redux/page/{opt_name}/form/after' * @param object $this ReduxFramework */ do_action( "redux/page/{$this->args['opt_name']}/form/after", $this ); echo '
    '; echo ''; if ( $this->args['dev_mode'] === true ) { if (current_user_can('administrator')){ global $wpdb; echo "
    ";
                        print_r($wpdb->queries);
                        echo "
    "; } echo '
    ' . get_num_queries() . ' queries in ' . timer_stop(0) . ' seconds
    Redux is currently set to developer mode.
    '; } $this->set_transients(); } /** * Section HTML OUTPUT. * * @since 1.0.0 * @access public * @param array $section * @return void */ public function _section_desc( $section ) { $id = trim( rtrim( $section['id'], '_section' ), $this->args['opt_name'] ); if( isset( $this->sections[$id]['desc'] ) && !empty( $this->sections[$id]['desc'] ) ) { echo '
    ' . $this->sections[$id]['desc'] . '
    '; } } /** * Field HTML OUTPUT. * Gets option from options array, then calls the specific field type class - allows extending by other devs * @since 1.0.0 * @param array $field * @param string $v * @return void */ public function _field_input( $field, $v = null ) { if( isset( $field['callback'] ) && function_exists( $field['callback'] ) ) { $value = ( isset( $this->options[$field['id']] ) ) ? $this->options[$field['id']] : ''; /** * action 'redux-before-field-{opt_name}' * @deprecated * @param array $field field data * @param string $value field.id */ do_action( "redux-before-field-{$this->args['opt_name']}", $field, $value ); // REMOVE /** * action 'redux/field/{opt_name}/{field.type}/callback/before' * @param array $field field data * @param string $value field.id */ do_action( "redux/field/{$this->args['opt_name']}/{$field['type']}/callback/before", $field, $value ); /** * action 'redux/field/{opt_name}/callback/before' * @param array $field field data * @param string $value field.id */ do_action( "redux/field/{$this->args['opt_name']}/callback/before", $field, $value ); call_user_func( $field['callback'], $field, $value ); /** * action 'redux-after-field-{opt_name}' * @deprecated * @param array $field field data * @param string $value field.id */ do_action( "redux-after-field-{$this->args['opt_name']}", $field, $value ); // REMOVE /** * action 'redux/field/{opt_name}/{field.type}/callback/after' * @param array $field field data * @param string $value field.id */ do_action( "redux/field/{$this->args['opt_name']}/{$field['type']}/callback/after", $field, $value ); /** * action 'redux/field/{opt_name}/callback/after' * @param array $field field data * @param string $value field.id */ do_action( "redux/field/{$this->args['opt_name']}/callback/after", $field, $value ); return; } if( isset( $field['type'] ) ) { // If the field is set not to display in the panel $display = true; if ( isset( $_GET['page'] ) && $_GET['page'] == $this->args['page_slug'] ) { if ( isset($field['panel']) && $field['panel'] == false ) { $display = false; } } if (!$display) { return; } $field_class = "ReduxFramework_{$field['type']}"; if( !class_exists( $field_class ) ) { // $class_file = apply_filters( 'redux/field/class/'.$field['type'], self::$_dir . 'inc/fields/' . $field['type'] . '/field_' . $field['type'] . '.php', $field ); // REMOVE /** * filter 'redux/{opt_name}/field/class/{field.type}' * @param string field class file path * @param array $field field data */ $class_file = apply_filters( "redux/{$this->args['opt_name']}/field/class/{$field['type']}", self::$_dir . "inc/fields/{$field['type']}/field_{$field['type']}.php", $field ); if( $class_file ) { if (file_exists($class_file)) { require_once($class_file); } } } if( class_exists( $field_class ) ) { $value = isset($this->options[$field['id']])?$this->options[$field['id']]:''; if ( $v !== null ) { $value = $v; } /** * action 'redux-before-field-{opt_name}' * @deprecated * @param array $field field data * @param string $value field id */ do_action( "redux-before-field-{$this->args['opt_name']}", $field, $value); // REMOVE /** * action 'redux/field/{opt_name}/{field.type}/render/before' * @param array $field field data * @param string $value field id */ do_action( "redux/field/{$this->args['opt_name']}/{$field['type']}/render/before", $field, $value ); /** * action 'redux/field/{$this->args['opt_name']}/render/before' * @param array $field field data * @param string $value field id */ do_action( "redux/field/{$this->args['opt_name']}/render/before", $field, $value ); if ( !isset( $field['name_suffix'] ) ) { $field['name_suffix'] = ""; } $render = new $field_class( $field, $value, $this ); ob_start(); $render->render(); /* echo "
    ";
                        print_r($value);
                        echo "
    "; */ /** * filter 'redux-field-{opt_name}' * @deprecated * @param string rendered field markup * @param array $field field data */ $_render = apply_filters( "redux-field-{$this->args['opt_name']}", ob_get_contents(), $field ); // REMOVE /** * filter 'redux/field/{opt_name}/{field.type}/render/after' * @param string rendered field markup * @param array $field field data */ $_render = apply_filters( "redux/field/{$this->args['opt_name']}/{$field['type']}/render/after", $_render, $field ); /** * filter 'redux/field/{opt_name}/render/after' * @param string rendered field markup * @param array $field field data */ $_render = apply_filters( "redux/field/{$this->args['opt_name']}/render/after", $_render, $field ); ob_end_clean(); //save the values into a unique array in case we need it for dependencies $this->fieldsValues[$field['id']] = (isset($value['url']) && is_array($value) )?$value['url']:$value; //create default data und class string and checks the dependencies of an object $class_string = ''; $data_string = ''; $this->check_dependencies($field); /** * action 'redux/field/{opt_name}/{field.type}/fieldset/before/{opt_name}' * @param array $field field data * @param string $value field id */ do_action( "redux/field/{$this->args['opt_name']}/{$field['type']}/fieldset/before/{$this->args['opt_name']}", $field, $value ); /** * action 'redux/field/{opt_name}/fieldset/before/{opt_name}' * @param array $field field data * @param string $value field id */ do_action( "redux/field/{$this->args['opt_name']}/fieldset/before/{$this->args['opt_name']}", $field, $value ); if (!isset($field['fields']) || empty($field['fields'])) { echo '
    '; } echo $_render; if (!empty($field['desc'])) { $field['description'] = $field['desc']; } echo ( isset( $field['description'] ) && $field['type'] != "info" && $field['type'] !== "section" && $field['type'] != "group" && !empty( $field['description'] ) ) ? '
    ' . $field['description'] . '
    ' : ''; if (!isset($field['fields']) || empty($field['fields'])) { echo '
    '; } /** * action 'redux-after-field-{opt_name}' * @deprecated * @param array $field field data * @param string $value field id */ do_action( "redux-after-field-{$this->args['opt_name']}", $field, $value ); // REMOVE /** * action 'redux/field/{opt_name}/{field.type}/fieldset/after/{opt_name}' * @param array $field field data * @param string $value field id */ do_action( "redux/field/{$this->args['opt_name']}/{$field['type']}/fieldset/after/{$this->args['opt_name']}", $field, $value ); /** * action 'redux/field/{opt_name}/fieldset/after/{opt_name}' * @param array $field field data * @param string $value field id */ do_action( "redux/field/{$this->args['opt_name']}/fieldset/after/{$this->args['opt_name']}", $field, $value ); } } } // _field_input() /** * Can Output CSS * Check if a field meets its requirements before outputting to CSS * @param $field * @return bool */ public function _can_output_css($field) { $return = true; $field = apply_filters( "redux/field/{$this->args['opt_name']}/_can_output_css", $field ); if( isset( $field['force_output'] ) && $field['force_output'] == true ){ return $return; } if (!empty($field['required'])) { if (isset($field['required'][0])) { if (!is_array($field['required'][0]) && count($field['required']) == 3) { $parentValue = $GLOBALS[$this->args['global_variable']][$field['required'][0]]; $checkValue = $field['required'][2]; $operation = $field['required'][1]; $return = $this->compareValueDependencies($parentValue, $checkValue, $operation); } else if ( is_array($field['required'][0] ) ) { foreach ($field['required'] as $required) { if (!is_array($required[0]) && count($required) == 3) { $parentValue = $GLOBALS[$this->args['global_variable']][$required[0]]; $checkValue = $required[2]; $operation = $required[1]; $return = $this->compareValueDependencies($parentValue, $checkValue, $operation); } if (!$return) { return $return; } } } } } return $return; } // _can_output_css /** * Checks dependencies between objects based on the $field['required'] array * * If the array is set it needs to have exactly 3 entries. * The first entry describes which field should be monitored by the current field. eg: "content" * The second entry describes the comparison parameter. eg: "equals, not, is_larger, is_smaller ,contains" * The third entry describes the value that we are comparing against. * * Example: if the required array is set to array('content','equals','Hello World'); then the current * field will only be displayed if the field with id "content" has exactly the value "Hello World" * * @param array $field * @return array $params */ public function check_dependencies($field) { //$params = array('data_string' => "", 'class_string' => ""); if (!empty($field['required'])) { //$this->folds[$field['id']] = $this->folds[$field['id']] ? $this->folds[$field['id']] : array(); if (!isset($this->required_child[$field['id']])) { $this->required_child[$field['id']] = array(); } if (!isset($this->required[$field['id']])) { $this->required[$field['id']] = array(); } if ( is_array( $field['required'][0] ) ) { foreach ( $field['required'] as $value ) { if (is_array($value) && count($value) == 3) { $data = array(); $data['parent'] = $value[0]; $data['operation'] = $value[1]; $data['checkValue'] = $value[2]; $this->required[$data['parent']][$field['id']][] = $data; if (!in_array($data['parent'], $this->required_child[$field['id']])) { $this->required_child[$field['id']][] = $data; } $this->checkRequiredDependencies($field, $data); } } } else { $data = array(); $data['parent'] = $field['required'][0]; $data['operation'] = $field['required'][1]; $data['checkValue'] = $field['required'][2]; $this->required[$data['parent']][$field['id']][] = $data; if (!in_array($data['parent'], $this->required_child[$field['id']])) { $this->required_child[$field['id']][] = $data; } $this->checkRequiredDependencies($field, $data); } } //return $params; } // Compare data for required field function compareValueDependencies($parentValue, $checkValue, $operation) { $return = false; switch ($operation) { case '=': case 'equals': $data['operation'] = "="; if(is_array($checkValue)){ if(in_array($parentValue, $checkValue)) { $return = true; } } else { if ($parentValue == $checkValue) { $return = true; } else if (is_array($parentValue)) { if (in_array($checkValue, $parentValue)) { $return = true; } } } break; case '!=': case 'not': $data['operation'] = "!=="; if(is_array($checkValue)){ if(!in_array($parentValue, $checkValue)) $return = true; } else { if ($parentValue != $checkValue) { $return = true; } else if (is_array($parentValue)) { if (!in_array($checkValue, $parentValue)) { $return = true; } } } break; case '>': case 'greater': case 'is_larger': $data['operation'] = ">"; if ($parentValue > $checkValue) $return = true; break; case '>=': case 'greater_equal': case 'is_larger_equal': $data['operation'] = ">="; if ($parentValue >= $checkValue) $return = true; break; case '<': case 'less': case 'is_smaller': $data['operation'] = "<"; if ($parentValue < $checkValue) $return = true; break; case '<=': case 'less_equal': case 'is_smaller_equal': $data['operation'] = "<="; if ($parentValue <= $checkValue) $return = true; break; case 'contains': if (strpos($parentValue, $checkValue) !== false) $return = true; break; case 'doesnt_contain': case 'not_contain': if (strpos($parentValue, $checkValue) === false) $return = true; break; case 'is_empty_or': if (empty($parentValue) || $parentValue == $checkValue) $return = true; break; case 'not_empty_and': if (!empty($parentValue) && $parentValue != $checkValue) $return = true; break; case 'is_empty': case 'empty': case '!isset': if (empty($parentValue) || $parentValue == "" || $parentValue == null) $return = true; break; case 'not_empty': case '!empty': case 'isset': if (!empty($parentValue) && $parentValue != "" && $parentValue != null) $return = true; break; } return $return; } function checkRequiredDependencies($field, $data) { //required field must not be hidden. otherwise hide this one by default if ( !in_array( $data['parent'], $this->fieldsHidden ) && ( !isset($this->folds[$field['id']]) || $this->folds[$field['id']] != "hide") ) { if (isset($this->options[$data['parent']])) { $return = $this->compareValueDependencies($this->options[$data['parent']], $data['checkValue'], $data['operation']); } } if ( (isset($return) && $return) && ( !isset($this->folds[$field['id']]) || $this->folds[$field['id']] != "hide") ) { $this->folds[$field['id']] = "show"; } else { $this->folds[$field['id']] = "hide"; if (!in_array($field['id'], $this->fieldsHidden)) { $this->fieldsHidden[] = $field['id']; } } } /** * converts an array into a html data string * * @param array $data example input: array('id'=>'true') * @return string $data_string example output: data-id='true' */ public function create_data_string($data = array()){ $data_string = ""; foreach($data as $key=>$value){ if(is_array($value)) $value = implode("|",$value); $data_string .= " data-$key='$value' "; } return $data_string; } } // ReduxFramework /** * action 'redux/init' * @param null */ do_action( 'redux/init', ReduxFramework::init() ); } // class_exists('ReduxFramework')