: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
namespace ReduxCore\ReduxFramework;
* Redux Framework is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* Redux Framework is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Redux Framework. If not, see <http://www.gnu.org/licenses/>.
* @package Redux_Framework
* @author Redux Framework Team
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
if ( ! class_exists( 'ReduxCore\\ReduxFramework\\ReduxFrameworkInstances' ) ) {
require_once dirname( __FILE__ ) . '/inc/class.redux_instances.php';
require_once dirname( __FILE__ ) . '/inc/lib.redux_instances.php';
if ( class_exists( 'ReduxCore\\ReduxFramework\\ReduxFrameworkInstances' ) ) {
add_action( 'redux/init', 'ReduxCore\\ReduxFramework\\ReduxFrameworkInstances::get_instance' );
if ( ! class_exists( 'ReduxCore\\ReduxFramework\\ReduxFramework' ) ) {
require_once dirname( __FILE__ ) . '/inc/class.redux_cdn.php';
require_once dirname( __FILE__ ) . '/inc/class.redux_api.php';
// General helper functions
require_once dirname( __FILE__ ) . '/inc/class.redux_helpers.php';
require_once dirname( __FILE__ ) . '/inc/class.redux_functions.php';
require_once dirname( __FILE__ ) . '/inc/class.p.php';
require_once dirname( __FILE__ ) . '/inc/class.thirdparty.fixes.php';
require_once dirname( __FILE__ ) . '/inc/class.redux_filesystem.php';
require_once dirname( __FILE__ ) . '/inc/class.redux_admin_notices.php';
require_once dirname( __FILE__ ) . '/inc/themecheck/class.redux_themecheck.php';
// Welcome page removed #1526
// require_once dirname( __FILE__ ) . '/inc/welcome/welcome.php';
* Main ReduxFramework class
// 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.6.2';
public static $_upload_dir;
public static $_upload_url;
public static $wp_content_url;
public static $base_wp_content_url;
public static $_is_plugin = true;
public static $_as_plugin = false;
public $transients = array();
public $wp_data = array();
public $field_types = array();
public $field_head = array();
public $transients_check;
public static function init() {
$dir = Redux_Helpers::cleanFilePath( dirname( __FILE__ ) );
// Windows-proof constants: replace backward by forward slashes. Thanks to: @peterbouwmeester
self::$_dir = trailingslashit( $dir );
self::$wp_content_url = trailingslashit( Redux_Helpers::cleanFilePath( ( is_ssl() ? str_replace( 'http://', 'https://', WP_CONTENT_URL ) : WP_CONTENT_URL ) ) );
// See if Redux is a plugin or not
if ( strpos( Redux_Helpers::cleanFilePath( __FILE__ ), Redux_Helpers::cleanFilePath( get_stylesheet_directory() ) ) !== false || strpos( Redux_Helpers::cleanFilePath( __FILE__ ), Redux_Helpers::cleanFilePath( get_template_directory_uri() ) ) !== false || strpos( Redux_Helpers::cleanFilePath( __FILE__ ), Redux_Helpers::cleanFilePath( WP_CONTENT_DIR . '/themes/' ) ) !== false ) {
self::$_is_plugin = false;
// Check if plugin is a symbolic link, see if it's a plugin. If embedded, we can't do a thing.
if ( strpos( self::$_dir, ABSPATH ) === false ) {
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
foreach ( get_plugins() as $key => $value ) {
if ( is_plugin_active( $key ) && strpos( $key, 'redux-framework.php' ) !== false ) {
self::$_dir = trailingslashit( Redux_Helpers::cleanFilePath( WP_CONTENT_DIR . '/plugins/' . plugin_dir_path( $key ) . 'ReduxCore/' ) );
self::$_is_plugin = false;
if ( self::$_is_plugin == true || self::$_as_plugin == true ) {
self::$_url = plugin_dir_url( __FILE__ );
if ( strpos( Redux_Helpers::cleanFilePath( __FILE__ ), Redux_Helpers::cleanFilePath( get_template_directory() ) ) !== false ) {
$relative_url = str_replace( Redux_Helpers::cleanFilePath( get_template_directory() ), '', self::$_dir );
self::$_url = trailingslashit( get_template_directory_uri() . $relative_url );
} else if ( strpos( Redux_Helpers::cleanFilePath( __FILE__ ), Redux_Helpers::cleanFilePath( get_stylesheet_directory() ) ) !== false ) {
$relative_url = str_replace( Redux_Helpers::cleanFilePath( get_stylesheet_directory() ), '', self::$_dir );
self::$_url = trailingslashit( get_stylesheet_directory_uri() . $relative_url );
$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::$_url = trailingslashit( self::$wp_content_url . $relative_url );
self::$_url = apply_filters( "redux/_url", self::$_url );
self::$_dir = apply_filters( "redux/_dir", self::$_dir );
self::$_is_plugin = apply_filters( "redux/_is_plugin", self::$_is_plugin );
public $framework_url = 'http://www.reduxframework.com/';
public static $instance = null;
public $admin_notices = array();
public $fields = array(); // Fields by type used in the panel
public $field_sections = array(); // Section id's by field type, then field ID
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 $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 $no_panel = array(); // Fields that are not visible in the panel
private $show_hints = false;
public $hidden_perm_fields = array(); // Hidden fields specified by 'permissions' arg.
public $hidden_perm_sections = array(); // Hidden sections specified by 'permissions' arg.
public $typography_preview = array();
public $filesystem = null;
public $font_groups = array();
public $dev_mode_forced = false;
public $reload_fields = array();
public $omit_share_icons = false;
public $omit_admin_items = false;
* Class Constructor. Defines the args for the theme options class
* @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() ) {
// Disregard WP AJAX 'heartbeat'call. Why waste resources?
if ( isset ( $_POST ) && isset ( $_POST['action'] ) && $_POST['action'] == 'heartbeat' ) {
if ( ! has_action( 'redux/ajax/heartbeat' ) ) {
do_action( 'redux/ajax/heartbeat', $this );
// Pass parent pointer to function helper.
Redux_Functions::$_parent = $this;
Redux_CDN::$_parent = $this;
Redux_Admin_Notices::$_parent = $this;
$this->set_default_args();
$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'] = '<span id="footer-thankyou">' . sprintf( __( 'Options panel created using %1$s', 'accelerated-mobile-pages' ), '<a href="' . esc_url( $this->framework_url ) . '" target="_blank">' . __( 'Redux Framework', 'accelerated-mobile-pages' ) . '</a> v' . self::$_version ) . '</span>';
if ( empty ( $this->args['menu_title'] ) ) {
$this->args['menu_title'] = __( 'Options', 'accelerated-mobile-pages' );
if ( empty ( $this->args['page_title'] ) ) {
$this->args['page_title'] = __( 'Options', 'accelerated-mobile-pages' );
$this->old_opt_name = $this->args['opt_name'];
* 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 ( $this->args['opt_name'] == $this->old_opt_name ) {
unset( $this->old_opt_name );
// Do not save the defaults if we're on a live preview!
if ( $GLOBALS['pagenow'] == "customize" && isset( $_GET['theme'] ) && ! empty( $_GET['theme'] ) ) {
$this->args['save_defaults'] = false;
$this->change_demo_defaults();
if ( ! empty ( $this->args['opt_name'] ) ) {
* Old variables and ways of doing things that need correcting. ;)
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'
* @param array $sections field option sections
$this->sections = apply_filters( 'redux-sections', $sections ); // REMOVE LATER
* filter 'redux-sections-{opt_name}'
* @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 );
* action 'redux/construct'
* @param object $this ReduxFramework
do_action( 'redux/construct', $this );
// Set the default values
$this->_default_cleanup();
$this->_internationalization();
$this->filesystem = Redux_Filesystem::get_instance( $this );
//set redux upload folder
$this->set_redux_content();
// Register extra extensions
$this->_register_extensions();
add_action( 'admin_menu', array( $this, '_options_page' ) );
if ( $this->args['database'] == "network" && $this->args['network_admin'] ) {
add_action( 'network_admin_menu', array( $this, '_options_page' ) );
add_action( 'admin_bar_menu', array(
), $this->args['admin_bar_priority'] );
add_action( 'admin_init', array( $this, '_register_settings' ) );
// Display admin notices in dev_mode
if ( true == $this->args['dev_mode'] ) {
if ( true == $this->args['update_notice'] ) {
add_action( 'admin_init', array( $this, '_update_check' ) );
add_action( 'admin_notices', array( $this, '_admin_notices' ), 99 );
// 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' ), 1 );
// Frontend: Maybe enqueue dynamic CSS and Google fonts
if ( empty ( $this->args['output_location'] ) || in_array( 'frontend', $this->args['output_location'] ) ) {
add_action( 'wp_head', array( $this, '_output_css'), 150 );
add_action( 'wp_enqueue_scripts', array($this, '_enqueue_output'), 150 );
// Login page: Maybe enqueue dynamic CSS and Google fonts
if ( in_array( 'login', $this->args['output_location'] ) ) {
add_action( 'login_head', array( $this, '_output_css'), 150 );
add_action( 'login_enqueue_scripts',array( $this, '_enqueue_output'), 150 );
// Admin area: Maybe enqueue dynamic CSS and Google fonts
if ( in_array( 'admin', $this->args['output_location'] ) ) {
add_action( 'admin_head', array( $this, '_output_css'), 150 );
add_action( 'admin_enqueue_scripts',array( $this, '_enqueue_output'), 150 );
add_action( 'wp_print_scripts', array( $this, 'vc_fixes' ), 100 );
add_action( 'admin_enqueue_scripts', array( $this, 'vc_fixes' ), 100 );
if ( $this->args['database'] == "network" && $this->args['network_admin'] ) {
add_action( 'network_admin_edit_redux_' . $this->args['opt_name'], array(
add_action( 'admin_bar_menu', array( $this, 'network_admin_bar' ), 999 );
add_action( "wp_ajax_" . $this->args['opt_name'] . '_ajax_save', array( $this, "ajax_save" ) );
if ( $this->args['dev_mode'] == true || Redux_Helpers::isLocalHost() == true ) {
// require_once 'core/dashboard.php';
// new reduxDashboardWidget( $this );
// if ( ! isset ( $GLOBALS['redux_notice_check'] ) ) {
// require_once 'core/newsflash.php';
// 'dir_name' => 'notice',
// 'server_file' => 'http://reduxframework.com/wp-content/uploads/redux/redux_notice.json',
// 'cookie_id' => 'redux_blast',
// new reduxNewsflash( $this, $params );
// $GLOBALS['redux_notice_check'] = 1;
* @param object $this ReduxFramework
do_action( 'redux/loaded', $this );
private function set_redux_content() {
$upload_dir = wp_upload_dir();
self::$_upload_dir = $upload_dir['basedir'] . '/redux/';
self::$_upload_url = str_replace( array(
), '//', $upload_dir['baseurl'] . '/redux/' );
private function set_default_args() {
// Must be defined by theme/plugin
// Must be defined to update the google fonts cache for the typography module
'google_update_weekly' => false,
// Set to keep your google fonts updated weekly
// force a specific tab to always show on reload
'page_permissions' => 'manage_options',
'page_parent' => 'themes.php',
// requires menu_type = 'submenu
'allow_sub_menu' => true,
// allow submenus to be added if menu_type == menu
// Save defaults to the DB on it if empty
'async_typography' => false,
'disable_google_fonts_link' => false,
// Class that gets appended to all redux-containers
'admin_bar_priority' => 999,
// Show the panel pages on the admin bar
// possible: options, theme_mods, theme_mods_expanded, transient, network
// setting to true forces get_theme_mod_expanded
// Changes global variable from $GLOBALS['YOUR_OPT_NAME'] to whatever you set here. false disables the global variable
// Dynamically generate CSS