mirror of
https://gh.wpcy.net/https://github.com/presscustomizr/hueman.git
synced 2026-04-26 19:51:08 +08:00
474 lines
No EOL
19 KiB
PHP
474 lines
No EOL
19 KiB
PHP
<?php
|
|
/**
|
|
*
|
|
*
|
|
* @package Hueman
|
|
* @since 3.0.0
|
|
* @author Nicolas GUILLAUME <nicolas@presscustomizr.com>
|
|
* @copyright Copyright (c) 2016, Nicolas GUILLAUME
|
|
* @link http://presscustomizr.com/hueman
|
|
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
*/
|
|
if ( !class_exists( 'HU_utils' ) ) :
|
|
class HU_utils {
|
|
//Access any method or var of the class with classname::$instance -> var or method():
|
|
static $inst;
|
|
public $default_options;
|
|
public $db_options;
|
|
public $options;//not used in customizer context only
|
|
public $is_customizing;
|
|
public $hu_options_prefixes;
|
|
public static $_theme_setting_list;
|
|
|
|
function __construct () {
|
|
self::$inst =& $this;
|
|
|
|
//init properties
|
|
//when is_admin, the after_setup_theme is fired too late
|
|
if ( is_admin() && !hu_is_customizing() ) {
|
|
$this -> hu_init_properties();
|
|
} else {
|
|
add_action( 'after_setup_theme' , array( $this , 'hu_init_properties') );
|
|
}
|
|
|
|
//IMPORTANT : this callback needs to be ran AFTER hu_init_properties.
|
|
add_action( 'after_setup_theme', array( $this, 'hu_cache_theme_setting_list' ), 100 );
|
|
|
|
//Various WP filters for
|
|
//content
|
|
//thumbnails => parses image if smartload enabled
|
|
//title
|
|
add_action( 'wp_head' , array( $this , 'hu_wp_filters') );
|
|
|
|
//refresh the theme options right after the _preview_filter when previewing
|
|
add_action( 'customize_preview_init' , array( $this , 'hu_customize_refresh_db_opt' ) );
|
|
}//construct
|
|
|
|
|
|
|
|
/***************************
|
|
* EARLY HOOKS
|
|
****************************/
|
|
/**
|
|
* Init class properties after_setup_theme
|
|
* Fixes the bbpress bug : Notice: bbp_setup_current_user was called incorrectly. The current user is being initialized without using $wp->init()
|
|
* hu_get_default_options uses is_user_logged_in() => was causing the bug
|
|
* hook : after_setup_theme
|
|
*
|
|
*/
|
|
function hu_init_properties() {
|
|
//all theme options start by "hu_" by convention
|
|
//$this -> hu_options_prefixes = apply_filters('hu_options_prefixes', array('hu_') );
|
|
$this -> is_customizing = hu_is_customizing();
|
|
$this -> db_options = false === get_option( HU_THEME_OPTIONS ) ? array() : (array)get_option( HU_THEME_OPTIONS );
|
|
$this -> default_options = $this -> hu_get_default_options();
|
|
$_trans = HU_IS_PRO ? 'started_using_hueman_pro' : 'started_using_hueman';
|
|
|
|
//What was the theme version when the user started to use Hueman?
|
|
//new install = no options yet
|
|
//very high duration transient, this transient could actually be an option but as per the wordpress.org themes guidelines, only one option is allowed for the theme settings
|
|
if ( !hu_isprevdem() ) {
|
|
if ( !get_transient( $_trans ) ) {
|
|
set_transient(
|
|
$_trans,
|
|
sprintf('%s|%s' , count( $this -> db_options ) >= 1 ? 'before' : 'with' , HUEMAN_VER ),
|
|
60*60*24*3650
|
|
);
|
|
}
|
|
// Commented since https://github.com/presscustomizr/hueman/issues/775
|
|
// was not used anyway since the removal of the welcome note
|
|
// if ( !get_transient( 'hu_start_date' ) && class_exists( 'DateTime' ) ) {
|
|
// set_transient(
|
|
// 'hu_start_date',
|
|
// new DateTime("now"),
|
|
// 60*60*24*3650
|
|
// );
|
|
// }
|
|
}
|
|
//the db updates for retro compat can be done now.
|
|
//=> @see functions/init-retro-compat.php
|
|
do_action('hu_init_options_done');
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------- *
|
|
* CACHE THE LIST OF THEME SETTINGS ONLY
|
|
/* ------------------------------------------------------------------------- */
|
|
//Fired in __construct()
|
|
//Note : the 'sidebar-areas' setting is not listed in that list because registered specifically
|
|
function hu_cache_theme_setting_list() {
|
|
if ( is_array(self::$_theme_setting_list) && !empty( self::$_theme_setting_list ) )
|
|
return;
|
|
$_settings_map = HU_utils_settings_map::$instance -> hu_get_customizer_map( null, 'add_setting_control' );
|
|
$_settings = array();
|
|
foreach ( $_settings_map as $_id => $data ) {
|
|
$_settings[] = $_id;
|
|
}
|
|
//$default_options = HU_utils::$inst -> hu_get_default_options();
|
|
self::$_theme_setting_list = $_settings;
|
|
}
|
|
|
|
|
|
/***************************
|
|
* ON WP_HEAD
|
|
****************************/
|
|
/**
|
|
* hook : wp_head
|
|
*/
|
|
function hu_wp_filters() {
|
|
if ( apply_filters( 'hu_img_smart_load_enabled', !hu_is_ajax() && hu_is_checked('smart_load_img') ) ) {
|
|
add_filter( 'the_content' , array( $this , 'hu_parse_imgs' ), PHP_INT_MAX );
|
|
add_filter( 'hu_post_thumbnail_html' , array( $this , 'hu_parse_imgs' ) );
|
|
}
|
|
add_filter( 'wp_title' , array( $this , 'hu_wp_filter_title' ), 10, 2 );
|
|
}
|
|
|
|
|
|
/**
|
|
* hook : the_content
|
|
* Inspired from Unveil Lazy Load plugin : https://wordpress.org/plugins/unveil-lazy-load/ by @marubon
|
|
*
|
|
* @return string
|
|
*/
|
|
function hu_parse_imgs( $_html ) {
|
|
$_bool = is_feed() || is_preview() || ( wp_is_mobile() && apply_filters('hu_disable_img_smart_load_mobiles', false ) );
|
|
|
|
if ( apply_filters( 'hu_disable_img_smart_load', $_bool, current_filter() ) )
|
|
return $_html;
|
|
|
|
$allowed_image_extentions = apply_filters( 'hu_smartload_allowed_img_extensions', array(
|
|
'bmp',
|
|
'gif',
|
|
'jpeg',
|
|
'jpg',
|
|
'jpe',
|
|
'tif',
|
|
'tiff',
|
|
'ico',
|
|
'png',
|
|
'svg',
|
|
'svgz'
|
|
) );
|
|
|
|
if ( empty( $allowed_image_extentions ) || !is_array( $allowed_image_extentions ) ) {
|
|
return $_html;
|
|
}
|
|
|
|
$img_extensions_pattern = sprintf( "(?:%s)", implode( '|', $allowed_image_extentions ) );
|
|
$pattern = '#<img([^>]+?)src=[\'"]?([^\'"\s>]+\.'.$img_extensions_pattern.'[^\'"\s>]*)[\'"]?([^>]*)>#i';
|
|
|
|
return preg_replace_callback( $pattern, array( $this , 'hu_regex_callback' ) , $_html);
|
|
}
|
|
|
|
|
|
/**
|
|
* callback of preg_replace_callback in hu_parse_imgs
|
|
* Inspired from Unveil Lazy Load plugin : https://wordpress.org/plugins/unveil-lazy-load/ by @marubon
|
|
*
|
|
* @return string
|
|
*/
|
|
private function hu_regex_callback( $matches ) {
|
|
$_placeholder = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
|
|
|
if ( false !== strpos( $matches[0], 'data-src' ) || preg_match('/ data-smartload *= *"false" */', $matches[0]) ) {
|
|
return $matches[0];
|
|
} else {
|
|
return apply_filters( 'hu_img_smartloaded',
|
|
str_replace( array('srcset=', 'sizes='), array('data-srcset=', 'data-sizes='),
|
|
sprintf('<img %1$s src="%2$s" data-src="%3$s" %4$s>',
|
|
$matches[1],
|
|
$_placeholder,
|
|
$matches[2],
|
|
$matches[3]
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Title element formating
|
|
* Hook : wp_title
|
|
*
|
|
*/
|
|
function hu_wp_filter_title( $title, $sep ) {
|
|
if ( function_exists( '_wp_render_title_tag' ) )
|
|
return $title;
|
|
|
|
global $paged, $page;
|
|
|
|
if ( is_feed() )
|
|
return $title;
|
|
|
|
// Add the site name.
|
|
$title .= get_bloginfo( 'name' );
|
|
|
|
// Add the site description for the home/front page.
|
|
$site_description = get_bloginfo( 'description' , 'display' );
|
|
if ( $site_description && hu_is_home() )
|
|
$title = "$title $sep $site_description";
|
|
|
|
// Add a page number if necessary.
|
|
if ( $paged >= 2 || $page >= 2 )
|
|
$title = "$title $sep " . sprintf( __( 'Page %s' , 'hueman' ), max( $paged, $page ) );
|
|
|
|
return $title;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
****************************** OPTIONS **************************************
|
|
*****************************************************************************/
|
|
/**
|
|
* Returns the default options array
|
|
*
|
|
* @package Hueman
|
|
* @since Hueman 3.0.0
|
|
*/
|
|
function hu_get_default_options() {
|
|
$_db_opts = empty($this -> db_options) ? $this -> hu_cache_db_options() : $this -> db_options;
|
|
$def_options = isset($_db_opts['defaults']) ? $_db_opts['defaults'] : array();
|
|
|
|
//Don't update if default options are not empty + customizing context
|
|
//customizing out ? => we can assume that the user has at least refresh the default once (because logged in, see conditions below) before accessing the customizer
|
|
//customizing => takes into account if user has set a filter or added a new customizer setting
|
|
if ( !empty($def_options) && $this -> is_customizing )
|
|
return apply_filters( 'hu_default_options', $def_options );
|
|
|
|
//Never update the defaults when wp_installing()
|
|
//prevent issue https://github.com/presscustomizr/hueman/issues/571
|
|
//Always update/generate the default option when (OR) :
|
|
// 1) current user can edit theme options
|
|
// 2) they are not defined
|
|
// 3) theme version not defined
|
|
// 4) versions are different
|
|
if ( !wp_installing() ) {
|
|
if ( current_user_can('edit_theme_options') || empty($def_options) || !isset($def_options['ver']) || 0 != version_compare( $def_options['ver'] , HUEMAN_VER ) ) {
|
|
$def_options = $this -> hu_generate_default_options( HU_utils_settings_map::$instance -> hu_get_customizer_map( $get_default_option = 'true' ) , HU_THEME_OPTIONS );
|
|
//Adds the version in default
|
|
$def_options['ver'] = HUEMAN_VER;
|
|
|
|
//writes the new value in db (merging raw options with the new defaults )
|
|
//=> will abort when wp_cache_get() returns false
|
|
// => prevent issue https://github.com/presscustomizr/hueman/issues/571
|
|
$this -> hu_set_option( 'defaults', $def_options, HU_THEME_OPTIONS );
|
|
}
|
|
}
|
|
return apply_filters( 'hu_default_options', $def_options );
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Generates the default options array from a customizer map + add slider option
|
|
*
|
|
*/
|
|
function hu_generate_default_options( $map, $option_group = null ) {
|
|
//do we have to look in a specific group of option (plugin?)
|
|
$option_group = is_null($option_group) ? HU_THEME_OPTIONS : $option_group;
|
|
|
|
//initialize the default array with the sliders options
|
|
$defaults = array();
|
|
|
|
foreach ($map['add_setting_control'] as $key => $options) {
|
|
|
|
$option_name = $key;
|
|
//write default option in array
|
|
if( array_key_exists( 'default', $options ) ) {
|
|
// added check on 'nimblecheck' to fix https://github.com/presscustomizr/customizr/issues/1732
|
|
$defaults[$option_name] = in_array( $options['type'], array( 'checkbox', 'nimblecheck' ) ) ? (bool)$options['default'] : $options['default'];
|
|
} else {
|
|
$defaults[$option_name] = null;
|
|
}
|
|
}//end foreach
|
|
|
|
return $defaults;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns an option from the options array of the theme.
|
|
*
|
|
* @package Hueman
|
|
*/
|
|
function hu_opt( $option_name , $option_group = null, $use_default = true ) {
|
|
//do we have to look for a specific group of option (plugin?)
|
|
$option_group = is_null( $option_group ) ? HU_THEME_OPTIONS : $option_group;
|
|
//when customizing, the db_options property is refreshed each time the preview is refreshed in 'customize_preview_init'
|
|
$_db_options = empty($this -> db_options) ? $this -> hu_cache_db_options() : $this -> db_options;
|
|
|
|
//do we have to use the default ?
|
|
$__options = $_db_options;
|
|
$_default_val = false;
|
|
if ( $use_default ) {
|
|
$_defaults = $this -> default_options;
|
|
if ( is_array($_defaults) && isset($_defaults[$option_name]) )
|
|
$_default_val = $_defaults[$option_name];
|
|
$__options = wp_parse_args( $_db_options, $_defaults );
|
|
}
|
|
|
|
//assign false value if does not exist, just like WP does
|
|
$_single_opt = isset( $__options[$option_name] ) ? $__options[$option_name] : false;
|
|
|
|
//allow ctx filtering globally
|
|
$_single_opt = apply_filters( "hu_opt" , $_single_opt , $option_name , $option_group, $_default_val );
|
|
|
|
//allow single option filtering
|
|
return apply_filters( "hu_opt_{$option_name}" , $_single_opt , $option_name , $option_group, $_default_val );
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Get the saved options in customizer Screen, merge them with the default theme options array and return the updated global options array
|
|
*
|
|
*/
|
|
function hu_get_theme_options ( $option_group = null ) {
|
|
//do we have to look in a specific group of option (plugin?)
|
|
$option_group = is_null($option_group) ? HU_THEME_OPTIONS : $option_group;
|
|
$saved = empty($this -> db_options) ? $this -> hu_cache_db_options() : $this -> db_options;
|
|
$defaults = $this -> default_options;
|
|
$__options = wp_parse_args( $saved, $defaults );
|
|
//$__options = array_intersect_key( $__options, $defaults );
|
|
return $__options;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Set an option value in the theme option group
|
|
* @param $option_name : string
|
|
* @param $option_value : sanitized option value, can be a string, a boolean or an array
|
|
* @param $option_group : string ( like hu_theme_options )
|
|
* @return void
|
|
*
|
|
*/
|
|
function hu_set_option( $option_name , $option_value, $option_group = null ) {
|
|
$option_group = is_null($option_group) ? HU_THEME_OPTIONS : $option_group;
|
|
|
|
//Get raw to :
|
|
//avoid filtering
|
|
//avoid merging with defaults
|
|
//Reminder : hu_get_raw_option( $opt_name = null, $opt_group = null, $from_cache = true, $report_error = false )
|
|
//get the raw option and enabled the wp error report
|
|
//=> prevent issue https://github.com/presscustomizr/hueman/issues/571
|
|
$_options = $this -> hu_get_unfiltered_theme_options( $option_group );
|
|
|
|
//Always make sure that getting raw options returns valid data
|
|
//For example, when opening wp-activate.php, wp_cache_get( 'alloptions', 'options' ); returns false
|
|
//=> which might lead to reset all previous user theme options when using update_option()
|
|
// => prevent issue https://github.com/presscustomizr/hueman/issues/571
|
|
if ( is_wp_error( $_options ) ) {
|
|
error_log( $_options -> get_error_code() );
|
|
return;
|
|
} else {
|
|
$_options[$option_name] = $option_value;
|
|
update_option( $option_group, $_options );
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* The purpose of this callback is to refresh and store the theme options in a property on each customize preview refresh
|
|
* => preview performance improvement
|
|
* 'customize_preview_init' is fired on wp_loaded, once WordPress is fully loaded ( after 'init', before 'wp') and right after the call to 'customize_register'
|
|
* This method is fired just after the theme option has been filtered for each settings by the WP_Customize_Setting::_preview_filter() callback
|
|
* => if this method is fired before this hook when customizing, the user changes won't be taken into account on preview refresh
|
|
*
|
|
* hook : customize_preview_init
|
|
* @return void
|
|
*
|
|
*/
|
|
function hu_customize_refresh_db_opt(){
|
|
$this -> db_options = false === get_option( HU_THEME_OPTIONS ) ? array() : (array)get_option( HU_THEME_OPTIONS );
|
|
}
|
|
|
|
|
|
/**
|
|
* In live context (not customizing || admin) cache the theme options
|
|
*
|
|
*/
|
|
function hu_cache_db_options($opt_group = null) {
|
|
$opt_group = is_null( $opt_group ) ? HU_THEME_OPTIONS : $opt_group;
|
|
$this -> db_options = false === get_option( $opt_group ) ? array() : (array)get_option( $opt_group );
|
|
return $this -> db_options;
|
|
}
|
|
|
|
|
|
//@return an array of options
|
|
//This is mostly a copy of the built-in get_option with the difference that
|
|
//1) by default retrieves only the theme options
|
|
//2) removes the "pre_option_{$name}", "default_option_{$name}", "option_{$name}" filters
|
|
//3) doesn't care about the special case when $option in array array('siteurl', 'home', 'category_base', 'tag_base'),
|
|
// as they are out of scope here
|
|
//
|
|
// The filter suppression is specially needed due to:
|
|
// a) avoid plugins (qtranslate, other lang plugins) filtering the theme options value, which might mess theme options when we update the options on front
|
|
// (e.g. to set the defaults, or to perform our retro compat options updates, or either to set the user started before option)
|
|
// b) speed up the theme option retrieval when we are sure we don't need the theme options to be filtered in any case
|
|
function hu_get_unfiltered_theme_options( $option = null, $default = array() ) {
|
|
$option = is_null($option) ? HU_THEME_OPTIONS : $option;
|
|
|
|
global $wpdb;
|
|
|
|
$option_group = trim( $option);
|
|
|
|
if ( empty( $option ) )
|
|
return false;
|
|
|
|
if ( defined( 'WP_SETUP_CONFIG' ) )
|
|
return false;
|
|
|
|
if ( !wp_installing() ) {
|
|
// prevent non-existent options from triggering multiple queries
|
|
$notoptions = wp_cache_get( 'notoptions', 'options' );
|
|
if ( isset( $notoptions[ $option ] ) ) {
|
|
return $default;
|
|
}
|
|
|
|
$alloptions = wp_load_alloptions();
|
|
|
|
if ( isset( $alloptions[$option] ) ) {
|
|
$value = $alloptions[$option];
|
|
} else {
|
|
$value = wp_cache_get( $option, 'options' );
|
|
|
|
if ( false === $value ) {
|
|
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
|
|
|
|
// Has to be get_row instead of get_var because of funkiness with 0, false, null values
|
|
if ( is_object( $row ) ) {
|
|
$value = $row->option_value;
|
|
wp_cache_add( $option, $value, 'options' );
|
|
} else { // option does not exist, so we must cache its non-existence
|
|
if ( !is_array( $notoptions ) ) {
|
|
$notoptions = array();
|
|
}
|
|
$notoptions[$option] = true;
|
|
wp_cache_set( 'notoptions', $notoptions, 'options' );
|
|
|
|
return $default;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$suppress = $wpdb->suppress_errors();
|
|
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
|
|
$wpdb->suppress_errors( $suppress );
|
|
if ( is_object( $row ) ) {
|
|
$value = $row->option_value;
|
|
} else {
|
|
return $default;
|
|
}
|
|
}
|
|
|
|
return maybe_unserialize( $value );
|
|
}
|
|
}//end of class
|
|
endif; |