' . esc_html__( 'Redux Framework version 4 is activated but not loaded. Redux Framework version 3 is still installed and activated. Please deactivate Redux Framework version 3.', 'redux-framework' ) . '

'; // phpcs:ignore WordPress.Security.EscapeOutput return null; } } if ( ! self::$instance ) { self::$instance = new self(); if ( class_exists( 'ReduxFramework' ) ) { self::$instance->load_first(); } else { self::$instance->get_redux_options(); self::$instance->includes(); self::$instance->hooks(); } } return self::$instance; } /** * Shim for getting instance * * @access public * @since 4.0.1 * @return self::$instance The one true Redux_Framework_Plugin */ public static function get_instance(): ?Redux_Framework_Plugin { return self::instance(); } /** * Get Redux options * * @access public * @since 3.1.3 * @return void */ public function get_redux_options() { // Setup defaults. $defaults = array( 'demo' => false, ); // If multisite is enabled. if ( is_multisite() ) { // Get network activated plugins. $plugins = get_site_option( 'active_sitewide_plugins' ); foreach ( $plugins as $file => $plugin ) { if ( strpos( $file, 'redux-framework.php' ) !== false ) { $this->plugin_network_activated = true; $this->options = get_site_option( 'ReduxFrameworkPlugin', $defaults ); } } } // If options aren't set, grab them now! if ( empty( $this->options ) ) { $this->options = get_option( 'ReduxFrameworkPlugin', $defaults ); } } /** * Include necessary files * * @access public * @since 3.1.3 * @return void */ public function includes() { // Include Redux_Core. if ( file_exists( dirname( __FILE__ ) . '/redux-core/framework.php' ) ) { require_once dirname( __FILE__ ) . '/redux-core/framework.php'; } Redux_Core::$redux_templates_enabled = (bool) get_option( 'use_redux_templates' ); Redux_Core::$extendify_templates_enabled = (bool) get_option( 'use_extendify_templates', true ); // Including extendify sdk. if ( true === (bool) get_option( 'use_extendify_templates', true ) ) { if ( file_exists( dirname( __FILE__ ) . '/extendify-sdk/loader.php' ) ) { $GLOBALS['extendify_sdk_partner'] = 'Redux'; require_once dirname( __FILE__ ) . '/extendify-sdk/loader.php'; } } if ( file_exists( dirname( __FILE__ ) . '/redux-templates/redux-templates.php' ) ) { require_once dirname( __FILE__ ) . '/redux-templates/redux-templates.php'; } if ( isset( Redux_Core::$as_plugin ) ) { Redux_Core::$as_plugin = true; } add_action( 'setup_theme', array( $this, 'load_sample_config' ) ); } /** * Loads the sample config after everything is loaded. * * @access public * @since 4.0.2 * @return void */ public function load_sample_config() { // Include demo config, if demo mode is active. if ( $this->options['demo'] && file_exists( dirname( __FILE__ ) . '/sample/sample-config.php' ) ) { require_once dirname( __FILE__ ) . '/sample/sample-config.php'; } } /** * Run action and filter hooks * * @access private * @since 3.1.3 * @return void */ private function hooks() { add_action( 'activated_plugin', array( $this, 'load_first' ) ); add_action( 'wp_loaded', array( $this, 'options_toggle_check' ) ); // Activate plugin when new blog is added. add_action( 'wpmu_new_blog', array( $this, 'activate_new_site' ) ); // Display admin notices. add_action( 'admin_notices', array( $this, 'admin_notices' ) ); // Edit plugin metalinks. add_filter( 'plugin_row_meta', array( $this, 'plugin_metalinks' ), null, 2 ); add_filter( 'network_admin_plugin_action_links', array( $this, 'add_settings_link' ), 1, 2 ); add_filter( 'plugin_action_links', array( $this, 'add_settings_link' ), 1, 2 ); // phpcs:ignore WordPress.NamingConventions.ValidHookName do_action( 'redux/plugin/hooks', $this ); } /** * Pushes Redux to top of plugin load list, so it initializes before any plugin that may use it. */ public function load_first() { if ( ! class_exists( 'Redux_Functions_Ex' ) ) { require_once dirname( __FILE__ ) . '/redux-core/inc/classes/class-redux-functions-ex.php'; } $plugin_dir = Redux_Functions_Ex::wp_normalize_path( WP_PLUGIN_DIR ) . '/'; $self_file = Redux_Functions_Ex::wp_normalize_path( __FILE__ ); $path = str_replace( $plugin_dir, '', $self_file ); $path = str_replace( 'class-redux-framework-plugin.php', 'redux-framework.php', $path ); $plugins = get_option( 'active_plugins' ); if ( $plugins ) { $key = array_search( $path, $plugins, true ); if ( false !== $key ) { array_splice( $plugins, $key, 1 ); array_unshift( $plugins, $path ); update_option( 'active_plugins', $plugins ); } if ( class_exists( 'Redux_Pro' ) ) { $self_file = Redux_Functions_Ex::wp_normalize_path( Redux_Pro::$dir ); $path = str_replace( $plugin_dir, '', $self_file ); // phpcs:ignore WordPress.NamingConventions.ValidHookName $basename = apply_filters( 'redux/pro/basename', 'redux-pro.php' ); $key = array_search( $path . '/' . $basename, $plugins, true ); if ( false !== $key ) { array_splice( $plugins, $key, 1 ); array_unshift( $plugins, $path . '/' . $basename ); update_option( 'active_plugins', $plugins ); } } } } /** * Fired on plugin activation * * @access public * @return void * @since 3.0.0 */ public static function activate() { delete_site_transient( 'update_plugins' ); } /** * Fired when plugin is deactivated * * @access public * @since 3.0.0 * * @param boolean $network_wide True if plugin is network activated, false otherwise. * * @return void */ public static function deactivate( ?bool $network_wide ) { if ( function_exists( 'is_multisite' ) && is_multisite() ) { if ( $network_wide ) { // Get all blog IDs. $blog_ids = self::get_blog_ids(); foreach ( $blog_ids as $blog_id ) { switch_to_blog( $blog_id ); self::single_deactivate(); } restore_current_blog(); } else { self::single_deactivate(); } } else { self::single_deactivate(); } delete_option( 'ReduxFrameworkPlugin' ); Redux_Enable_Gutenberg::cleanup_options( 'redux-framework' ); // Auto disable Gutenberg and all that. } /** * Fired when a new WPMU site is activated * * @access public * * @param int $blog_id The ID of the new blog. * * @return void * @since 3.0.0 */ public function activate_new_site( int $blog_id ) { if ( 1 !== did_action( 'wpmu_new_blog' ) ) { return; } switch_to_blog( $blog_id ); self::single_activate(); restore_current_blog(); } /** * Get all IDs of blogs that are not activated, not spam, and not deleted * * @access private * @since 3.0.0 * @global object $wpdb * @return array|false Array of IDs or false if none are found */ private static function get_blog_ids() { global $wpdb; $var = '0'; // Get an array of IDs (We have to do it this way because WordPress says so, however redundant). $result = wp_cache_get( 'redux-blog-ids' ); if ( false === $result ) { // WordPress says get_col is discouraged? I found no alternative. So...ignore! - kp. // phpcs:ignore WordPress.DB.DirectDatabaseQuery $result = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE archived = %s AND spam = %s AND deleted = %s", $var, $var, $var ) ); wp_cache_set( 'redux-blog-ids', $result ); } return $result; } /** * Fired for each WPMS blog on plugin activation * * @access private * @since 3.0.0 * @return void */ private static function single_activate() { $nonce = wp_create_nonce( 'redux_framework_demo' ); $notices = get_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES', array() ); $notices[] = esc_html__( 'Redux Framework has an embedded demo.', 'redux-framework' ) . ' ' . esc_html__( 'Click here to activate the sample config file.', 'redux-framework' ) . ''; update_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES', $notices ); } /** * Display admin notices * * @access public * @since 3.0.0 * @return void */ public function admin_notices() { do_action( 'redux_framework_plugin_admin_notice' ); $notices = get_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES', '' ); if ( ! empty( $notices ) ) { foreach ( $notices as $notice ) { echo '

' . $notice . '

'; // phpcs:ignore WordPress.Security.EscapeOutput } delete_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES' ); } } /** * Fired for each blog when the plugin is deactivated * * @access private * @since 3.0.0 * @return void */ private static function single_deactivate() { delete_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES' ); } /** * Turn on or off * * @access public * @since 3.0.0 * @return void */ public function options_toggle_check() { if ( isset( $_GET['nonce'] ) && wp_verify_nonce( sanitize_key( $_GET['nonce'] ), 'redux_framework_demo' ) ) { if ( isset( $_GET['redux-framework-plugin'] ) && 'demo' === $_GET['redux-framework-plugin'] ) { $url = admin_url( add_query_arg( array( 'page' => 'redux-framework' ), 'options-general.php' ) ); if ( false === $this->options['demo'] ) { $this->options['demo'] = true; $url = admin_url( add_query_arg( array( 'page' => 'redux_demo' ), 'admin.php' ) ); } else { $this->options['demo'] = false; } if ( is_multisite() && $this->plugin_network_activated ) { update_site_option( 'ReduxFrameworkPlugin', $this->options ); } else { update_option( 'ReduxFrameworkPlugin', $this->options ); } wp_safe_redirect( esc_url( $url ) ); exit(); } } } /** * Add a settings link to the Redux entry in the plugin overview screen * * @param array $links Links array. * @param string $file Plugin filename/slug. * * @return array * @see filter:plugin_action_links * @since 1.0 */ public function add_settings_link( array $links, string $file ): array { if ( basename( plugin_dir_path( __FILE__ ) ) . '/redux-framework.php' !== $file ) { return $links; } $links[] = sprintf( '%2$s', esc_url( $this->get_site_utm_url( '', 'plugins-page','', 'go-pro' ) ), sprintf( '%s', __( 'Go Pro', 'redux-framework' ) ) ); return $links; } /** * Get the url where the Admin Columns website is hosted * * @param string $path Path to add to url. * * @return string */ private function get_site_url( string $path = '' ): string { $url = 'https://extendify.com/pricing/'; if ( ! empty( $path ) ) { $url .= '/' . trim( $path, '/' ) . '/'; } return $url; } /** * Url with utm tags * * @param string $path Path on site. * @param string $utm_medium Medium var. * @param string|null $utm_content Content var. * @param string|bool $utm_campaign Campaign var. * * @return string */ public function get_site_utm_url( string $path, string $utm_medium, string $utm_content = null, $utm_campaign = false ): string { $url = self::get_site_url( $path ); if ( ! $utm_campaign ) { $utm_campaign = 'plugin-installation'; } $args = array( // Referrer: plugin. 'utm_source' => 'redux', // Specific promotions or sales. 'utm_campaign' => $utm_campaign, // Marketing medium: banner, documentation or email. 'utm_medium' => $utm_medium, // Used for differentiation of medium. 'utm_content' => $utm_content, ); $args = array_map( 'sanitize_key', array_filter( $args ) ); return add_query_arg( $args, $url ); } /** * Edit plugin metalinks * * @access public * * @param array $links The current array of links. * @param string $file A specific plugin row. * * @return array The modified array of links * @since 3.0.0 */ public function plugin_metalinks( array $links, string $file ): array { /* if ( strpos( $file, 'redux-framework.php' ) !== false && is_plugin_active( $file ) ) { $links[] = '' . esc_html__( 'What is this?', 'redux-framework' ) . ''; if ( true === Redux_Core::$redux_templates_enabled ) { $links[] = '' . esc_html__( 'Template Library', 'redux-framework' ) . ''; } }*/ return $links; } } if ( ! class_exists( 'ReduxFrameworkPlugin' ) ) { class_alias( 'Redux_Framework_Plugin', 'ReduxFrameworkPlugin' ); } }