* @copyright Copyright (c) 2013-2015, Nicolas GUILLAUME
* @link http://presscustomizr.com/customizr
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
if ( ! class_exists( 'TC_utils' ) ) :
class TC_utils {
//Access any method or var of the class with classname::$instance -> var or method():
static $inst;
static $instance;
public $default_options;
public $db_options;
public $options;//not used in customizer context only
public $is_customizing;
public $tc_options_prefixes;
function __construct () {
self::$inst =& $this;
self::$instance =& $this;
//init properties
add_action( 'after_setup_theme' , array( $this , 'tc_init_properties') );
//Various WP filters for
//content
//thumbnails => parses image if smartload enabled
//title
add_action( 'wp_head' , array( $this , 'tc_wp_filters') );
//get all options
add_filter( '__options' , array( $this , 'tc_get_theme_options' ), 10, 1);
//get single option
add_filter( '__get_option' , array( $this , 'tc_opt' ), 10, 2 );//deprecated
//some useful filters
add_filter( '__ID' , array( $this , 'tc_id' ));//deprecated
add_filter( '__screen_layout' , array( $this , 'tc_get_layout' ) , 10 , 2 );//deprecated
add_filter( '__is_home' , array( $this , 'tc_is_home' ) );
add_filter( '__is_home_empty' , array( $this , 'tc_is_home_empty' ) );
add_filter( '__post_type' , array( $this , 'tc_get_post_type' ) );
add_filter( '__is_no_results' , array( $this , 'tc_is_no_results') );
add_filter( '__article_selectors' , array( $this , 'tc_article_selectors' ) );
//social networks
add_filter( '__get_socials' , array( $this , 'tc_get_social_networks' ) );
//refresh the theme options right after the _preview_filter when previewing
add_action( 'customize_preview_init' , array( $this , 'tc_customize_refresh_db_opt' ) );
}
/***************************
* EARLY HOOKS
****************************/
/**
* Init TC_utils 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()
* tc_get_default_options uses is_user_logged_in() => was causing the bug
* hook : after_setup_theme
*
* @package Customizr
* @since Customizr 3.2.3
*/
function tc_init_properties() {
//all customizr theme options start by "tc_" by convention
$this -> tc_options_prefixes = apply_filters('tc_options_prefixes', array('tc_') );
$this -> is_customizing = TC___::$instance -> tc_is_customizing();
$this -> db_options = false === get_option( TC___::$tc_option_group ) ? array() : (array)get_option( TC___::$tc_option_group );
$this -> default_options = $this -> tc_get_default_options();
$_trans = TC___::tc_is_pro() ? 'started_using_customizr_pro' : 'started_using_customizr';
//What was the theme version when the user started to use Customizr?
//new install = no options yet
//very high duration transient, this transient could actually be an option but as per the themes guidelines, too much options are not allowed.
if ( 1 >= count( $this -> db_options ) || ! esc_attr( get_transient( $_trans ) ) ) {
set_transient(
$_trans,
sprintf('%s|%s' , 1 >= count( $this -> db_options ) ? 'with' : 'before', CUSTOMIZR_VER ),
60*60*24*9999
);
}
}
/**
* hook : after_setup_theme
* @package Customizr
* @since Customizr 3.3.0
*/
function tc_wp_filters() {
add_filter( 'the_content' , array( $this , 'tc_fancybox_content_filter' ) );
if ( esc_attr( TC_utils::$inst->tc_opt( 'tc_img_smart_load' ) ) ) {
add_filter( 'the_content' , array( $this , 'tc_parse_imgs' ), PHP_INT_MAX );
add_filter( 'tc_thumb_html' , array( $this , 'tc_parse_imgs' ) );
}
add_filter( 'wp_title' , array( $this , 'tc_wp_title' ), 10, 2 );
}
/**
* hook : the_content
* Inspired from Unveil Lazy Load plugin : https://wordpress.org/plugins/unveil-lazy-load/ by @marubon
*
* @return string
* @package Customizr
* @since Customizr 3.3.0
*/
function tc_parse_imgs( $_html ) {
if( is_feed() || is_preview() || ( wp_is_mobile() && apply_filters('tc_disable_img_smart_load_mobiles', false ) ) )
return $_html;
return preg_replace_callback('#
]+?)src=[\'"]?([^\'"\s>]+)[\'"]?([^>]*)>#', array( $this , 'tc_regex_callback' ) , $_html);
}
/**
* callback of preg_replace_callback in tc_parse_imgs
* Inspired from Unveil Lazy Load plugin : https://wordpress.org/plugins/unveil-lazy-load/ by @marubon
*
* @return string
* @package Customizr
* @since Customizr 3.3.0
*/
private function tc_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( 'tc_img_smartloaded',
str_replace( 'srcset=', 'data-srcset=',
sprintf('
',
$matches[1],
$_placeholder,
$matches[2],
$matches[3]
)
)
);
}
/**
* Returns the current skin's primary color
*
* @package Customizr
* @since Customizr 3.1.23
*/
function tc_get_skin_color( $_what = null ) {
$_color_map = TC_init::$instance -> skin_color_map;
$_color_map = ( is_array($_color_map) ) ? $_color_map : array();
$_active_skin = str_replace('.min.', '.', basename( TC_init::$instance -> tc_get_style_src() ) );
//falls back to blue3 ( default #27CDA5 ) if not defined
$_to_return = array( '#27CDA5', '#1b8d71' );
switch ($_what) {
case 'all':
$_to_return = $_color_map;
break;
case 'pair':
$_to_return = ( false != $_active_skin && array_key_exists( $_active_skin, $_color_map ) && is_array( $_color_map[$_active_skin] ) ) ? $_color_map[$_active_skin] : $_to_return;
break;
default:
$_to_return = ( false != $_active_skin && isset($_color_map[$_active_skin][0]) ) ? $_color_map[$_active_skin][0] : $_to_return[0];
break;
}
return apply_filters( 'tc_get_skin_color' , $_to_return , $_what );
}
/**
* Helper
* Returns whether or not the option is a theme/addon option
*
* @return bool
*
* @package Customizr
* @since Customizr 3.4.9
*/
function tc_is_customizr_option( $option_key ) {
$_is_tc_option = in_array( substr( $option_key, 0, 3 ), $this -> tc_options_prefixes );
return apply_filters( 'tc_is_customizr_option', $_is_tc_option , $option_key );
}
/**
* Returns the default options array
*
* @package Customizr
* @since Customizr 3.1.11
*/
function tc_get_default_options() {
$_db_opts = empty($this -> db_options) ? $this -> tc_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
//customzing => 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( 'tc_default_options', $def_options );
//Always update/generate the default option when (OR) :
// 1) user is logged in
// 2) they are not defined
// 3) theme version not defined
// 4) versions are different
if ( is_user_logged_in() || empty($def_options) || ! isset($def_options['ver']) || 0 != version_compare( $def_options['ver'] , CUSTOMIZR_VER ) ) {
$def_options = $this -> tc_generate_default_options( TC_utils_settings_map::$instance -> tc_get_customizer_map( $get_default_option = 'true' ) , 'tc_theme_options' );
//Adds the version in default
$def_options['ver'] = CUSTOMIZR_VER;
$_db_opts['defaults'] = $def_options;
//writes the new value in db
update_option( "tc_theme_options" , $_db_opts );
}
return apply_filters( 'tc_default_options', $def_options );
}
/**
* Generates the default options array from a customizer map + add slider option
*
* @package Customizr
* @since Customizr 3.0.3
*/
function tc_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) ? 'tc_theme_options' : $option_group;
//initialize the default array with the sliders options
$defaults = array();
foreach ($map['add_setting_control'] as $key => $options) {
//check it is a customizr option
if( ! $this -> tc_is_customizr_option( $key ) )
continue;
$option_name = $key;
//write default option in array
if( isset($options['default']) )
$defaults[$option_name] = ( 'checkbox' == $options['type'] ) ? (bool) $options['default'] : $options['default'];
else
$defaults[$option_name] = null;
}//end foreach
return $defaults;
}
/**
* Get the saved options in Customizer Screen, merge them with the default theme options array and return the updated global options array
* @package Customizr
* @since Customizr 1.0
*
*/
function tc_get_theme_options ( $option_group = null ) {
//do we have to look in a specific group of option (plugin?)
$option_group = is_null($option_group) ? TC___::$tc_option_group : $option_group;
$saved = empty($this -> db_options) ? $this -> tc_cache_db_options() : $this -> db_options;
$defaults = $this -> default_options;
$__options = wp_parse_args( $saved, $defaults );
//$__options = array_intersect_key( $__options, $defaults );
return $__options;
}
/**
* Returns an option from the options array of the theme.
*
* @package Customizr
* @since Customizr 1.0
*/
function tc_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) ? TC___::$tc_option_group : $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 -> tc_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 ( 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;
//ctx retro compat => falls back to default val if ctx like option detected
//important note : some options like tc_slider are not concerned by ctx
if ( ! $this -> tc_is_option_excluded_from_ctx( $option_name ) ) {
if ( is_array( $_single_opt ) && ! class_exists( 'TC_contx' ) )
$_single_opt = $_default_val;
}
//allow contx filtering globally
$_single_opt = apply_filters( "tc_opt" , $_single_opt , $option_name , $option_group, $_default_val );
//allow single option filtering
return apply_filters( "tc_opt_{$option_name}" , $_single_opt , $option_name , $option_group, $_default_val );
}
/**
* 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
*
* @since v3.4+
*/
function tc_customize_refresh_db_opt(){
$this -> db_options = false === get_option( TC___::$tc_option_group ) ? array() : (array)get_option( TC___::$tc_option_group );
}
/**
* Set an option value in the theme option group
* @param $option_name : string ( like tc_skin )
* @param $option_value : sanitized option value, can be a string, a boolean or an array
* @param $option_group : string ( like tc_theme_options )
* @return void
*
* @package Customizr
* @since Customizr 3.4+
*/
function tc_set_option( $option_name , $option_value, $option_group = null ) {
$option_group = is_null($option_group) ? TC___::$tc_option_group : $option_group;
$_options = $this -> tc_get_theme_options( $option_group );
$_options[$option_name] = $option_value;
update_option( $option_group, $_options );
}
/**
* In live context (not customizing || admin) cache the theme options
*
* @package Customizr
* @since Customizr 3.2.0
*/
function tc_cache_db_options($opt_group = null) {
$opts_group = is_null($opt_group) ? TC___::$tc_option_group : $opt_group;
$this -> db_options = false === get_option( $opt_group ) ? array() : (array)get_option( $opt_group );
return $this -> db_options;
}
/**
* Returns the "real" queried post ID or if !isset, get_the_ID()
* Checks some contextual booleans
*
* @package Customizr
* @since Customizr 1.0
*/
public static function tc_id() {
if ( in_the_loop() ) {
$tc_id = get_the_ID();
} else {
global $post;
$queried_object = get_queried_object();
$tc_id = ( ! empty ( $post ) && isset($post -> ID) ) ? $post -> ID : null;
$tc_id = ( isset ($queried_object -> ID) ) ? $queried_object -> ID : $tc_id;
}
return ( is_404() || is_search() || is_archive() ) ? null : $tc_id;
}
/**
* This function returns the layout (sidebar(s), or full width) to apply to a context
*
* @package Customizr
* @since Customizr 1.0
*/
public static function tc_get_layout( $post_id , $sidebar_or_class = 'class' ) {
$__options = tc__f ( '__options' );
global $post;
//Article wrapper class definition
$global_layout = apply_filters( 'tc_global_layout' , TC_init::$instance -> global_layout );
/* DEFAULT LAYOUTS */
//what is the default layout we want to apply? By default we apply the global default layout
$tc_sidebar_default_layout = esc_attr( $__options['tc_sidebar_global_layout'] );
//checks if the 'force default layout' option is checked and return the default layout before any specific layout
if( isset($__options['tc_sidebar_force_layout']) && 1 == $__options['tc_sidebar_force_layout'] ) {
$class_tab = $global_layout[$tc_sidebar_default_layout];
$class_tab = $class_tab['content'];
$tc_screen_layout = array(
'sidebar' => $tc_sidebar_default_layout,
'class' => $class_tab
);
return $tc_screen_layout[$sidebar_or_class];
}
if ( is_single() )
$tc_sidebar_default_layout = esc_attr( $__options['tc_sidebar_post_layout'] );
if ( is_page() )
$tc_sidebar_default_layout = esc_attr( $__options['tc_sidebar_page_layout'] );
//builds the default layout option array including layout and article class
$class_tab = $global_layout[$tc_sidebar_default_layout];
$class_tab = $class_tab['content'];
$tc_screen_layout = array(
'sidebar' => $tc_sidebar_default_layout,
'class' => $class_tab
);
//The following lines set the post specific layout if any, and if not keeps the default layout previously defined
$tc_specific_post_layout = false;
global $wp_query;
//if we are displaying an attachement, we use the parent post/page layout
if ( $post && 'attachment' == $post -> post_type ) {
$tc_specific_post_layout = esc_attr( get_post_meta( $post->post_parent , $key = 'layout_key' , $single = true ) );
}
//for a singular post or page OR for the posts page
elseif ( is_singular() || $wp_query -> is_posts_page ) {
$tc_specific_post_layout = esc_attr( get_post_meta( $post_id, $key = 'layout_key' , $single = true ) );
}
//checks if we display home page, either posts or static page and apply the customizer option
if( (is_home() && 'posts' == get_option( 'show_on_front' ) ) || is_front_page()) {
$tc_specific_post_layout = $__options['tc_front_layout'];
}
if( $tc_specific_post_layout ) {
$class_tab = $global_layout[$tc_specific_post_layout];
$class_tab = $class_tab['content'];
$tc_screen_layout = array(
'sidebar' => $tc_specific_post_layout,
'class' => $class_tab
);
}
return apply_filters( 'tc_screen_layout' , $tc_screen_layout[$sidebar_or_class], $post_id , $sidebar_or_class );
}
/**
* Add an optional rel="tc-fancybox[]" attribute to all images embedded in a post.
*
* @package Customizr
* @since Customizr 2.0.7
*/
function tc_fancybox_content_filter( $content) {
$tc_fancybox = esc_attr( TC_utils::$inst->tc_opt( 'tc_fancybox' ) );
if ( 1 != $tc_fancybox )
return $content;
global $post;
if ( ! isset($post) )
return $content;
$pattern ="//i";
$replacement = '';
$r_content = preg_replace( $pattern, $replacement, $content);
$content = $r_content ? $r_content : $content;
return apply_filters( 'tc_fancybox_content_filter', $content );
}
/**
* Title element formating
*
* @since Customizr 2.1.6
*
*/
function tc_wp_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 && tc__f('__is_home') )
$title = "$title $sep $site_description";
// Add a page number if necessary.
if ( $paged >= 2 || $page >= 2 )
$title = "$title $sep " . sprintf( __( 'Page %s' , 'customizr' ), max( $paged, $page ) );
return $title;
}
/**
* Check if we are displaying posts lists or front page
*
* @since Customizr 3.0.6
*
*/
function tc_is_home() {
//get info whether the front page is a list of last posts or a page
return ( is_home() && ( 'posts' == get_option( 'show_on_front' ) || 'nothing' == get_option( 'show_on_front' ) ) ) || is_front_page();
}
/**
* Check if we show posts or page content on home page
*
* @since Customizr 3.0.6
*
*/
function tc_is_home_empty() {
//check if the users has choosen the "no posts or page" option for home page
return ( ( is_home() || is_front_page() ) && 'nothing' == get_option( 'show_on_front' ) ) ? true : false;
}
/**
* Return object post type
*
* @since Customizr 3.0.10
*
*/
function tc_get_post_type() {
global $post;
if ( ! isset($post) )
return;
return $post -> post_type;
}
/**
* Returns the classes for the post div.
*
* @param string|array $class One or more classes to add to the class list.
* @param int $post_id An optional post ID.
* @package Customizr
* @since 3.0.10
*/
function tc_get_post_class( $class = '', $post_id = null ) {
//Separates classes with a single space, collates classes for post DIV
return 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
}
/**
* Boolean : check if we are in the no search results case
*
* @package Customizr
* @since 3.0.10
*/
function tc_is_no_results() {
global $wp_query;
return ( is_search() && 0 == $wp_query -> post_count ) ? true : false;
}
/**
* Displays the selectors of the article depending on the context
*
* @package Customizr
* @since 3.1.0
*/
function tc_article_selectors() {
//gets global vars
global $post;
global $wp_query;
//declares selector var
$selectors = '';
// SINGLE POST
$single_post_selector_bool = isset($post) && 'page' != $post -> post_type && 'attachment' != $post -> post_type && is_singular();
$selectors = $single_post_selector_bool ? apply_filters( 'tc_single_post_selectors' ,'id="post-'.get_the_ID().'" '.$this -> tc_get_post_class('row-fluid') ) : $selectors;
// POST LIST
$post_list_selector_bool = ( isset($post) && !is_singular() && !is_404() && !tc__f( '__is_home_empty') ) || ( is_search() && 0 != $wp_query -> post_count );
$selectors = $post_list_selector_bool ? apply_filters( 'tc_post_list_selectors' , 'id="post-'.get_the_ID().'" '.$this -> tc_get_post_class('row-fluid') ) : $selectors;
// PAGE
$page_selector_bool = isset($post) && 'page' == tc__f('__post_type') && is_singular() && !tc__f( '__is_home_empty');
$selectors = $page_selector_bool ? apply_filters( 'tc_page_selectors' , 'id="page-'.get_the_ID().'" '.$this -> tc_get_post_class('row-fluid') ) : $selectors;
// ATTACHMENT
//checks if attachement is image and add a selector
$format_image = wp_attachment_is_image() ? 'format-image' : '';
$selectors = ( isset($post) && 'attachment' == $post -> post_type && is_singular() ) ? apply_filters( 'tc_attachment_selectors' , 'id="post-'.get_the_ID().'" '.$this -> tc_get_post_class(array('row-fluid', $format_image) ) ) : $selectors;
// NO SEARCH RESULTS
$selectors = ( is_search() && 0 == $wp_query -> post_count ) ? apply_filters( 'tc_no_results_selectors' , 'id="post-0" class="post error404 no-results not-found row-fluid"' ) : $selectors;
// 404
$selectors = is_404() ? apply_filters( 'tc_404_selectors' , 'id="post-0" class="post error404 no-results not-found row-fluid"' ) : $selectors;
echo apply_filters( 'tc_article_selectors', $selectors );
}//end of function
/**
* Gets the social networks list defined in customizer options
*
* @package Customizr
* @since Customizr 3.0.10
*/
function tc_get_social_networks() {
$__options = tc__f( '__options' );
//gets the social network array
$socials = apply_filters( 'tc_default_socials' , TC_init::$instance -> socials );
//declares some vars
$html = '';
foreach ( $socials as $key => $data ) {
if ( $__options[$key] != '' ) {
//gets height and width from image, we check if getimagesize can be used first with the error control operator
$width = $height = '';
if ( isset($data['custom_icon_url']) && @getimagesize($data['custom_icon_url']) ) { list( $width, $height ) = getimagesize($data['custom_icon_url']); }
$type = isset( $data['type'] ) && ! empty( $data['type'] ) ? $data['type'] : 'url';
$link = 'email' == $type ? 'mailto:' : '';
$link .= call_user_func( array( TC_utils_settings_map::$instance, 'tc_sanitize_'.$type ), $__options[$key] );
//there is one exception : rss feed has no target _blank and special icon title
$html .= sprintf('%6$s',
apply_filters( 'tc_social_link_class',
sprintf('social-icon icon-%1$s' ,
( $key == 'tc_rss' ) ? 'feed' : str_replace('tc_', '', $key)
),
$key
),
$link,
isset($data['link_title']) ? call_user_func( '__' , $data['link_title'] , 'customizr' ) : '' ,
( in_array( $key, array('tc_rss', 'tc_email') ) ) ? '' : apply_filters( 'tc_socials_target', 'target=_blank', $key ),
apply_filters( 'tc_additional_social_attributes', '' , $key),
( isset($data['custom_icon_url']) && !empty($data['custom_icon_url']) ) ? sprintf('
',
$data['custom_icon_url'],
$width,
$height,
isset($data['link_title']) ? call_user_func( '__' , $data['link_title'] , 'customizr' ) : ''
) : ''
);
}
}
return $html;
}
/**
* Retrieve the file type from the file name
* Even when it's not at the end of the file
* copy of wp_check_filetype() in wp-includes/functions.php
*
* @since 3.2.3
*
* @param string $filename File name or path.
* @param array $mimes Optional. Key is the file extension with value as the mime type.
* @return array Values with extension first and mime type.
*/
function tc_check_filetype( $filename, $mimes = null ) {
$filename = basename( $filename );
if ( empty($mimes) )
$mimes = get_allowed_mime_types();
$type = false;
$ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')!i';
//was ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
$ext = $ext_matches[1];
break;
}
}
return compact( 'ext', 'type' );
}
/**
* Check whether a category exists.
* (wp category_exists isn't available in pre_get_posts)
* @since 3.4.10
*
* @see term_exists()
*
* @param int $cat_id.
* @return bool
*/
public function tc_category_id_exists( $cat_id ) {
return term_exists( (int) $cat_id, 'category');
}
/**
* @return a date diff object
* @uses date_diff if php version >=5.3.0, instantiates a fallback class if not
*
* @since 3.2.8
*
* @param date one object.
* @param date two object.
*/
private function tc_date_diff( $_date_one , $_date_two ) {
//if version is at least 5.3.0, use date_diff function
if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0) {
return date_diff( $_date_one , $_date_two );
} else {
$_date_one_timestamp = $_date_one->format("U");
$_date_two_timestamp = $_date_two->format("U");
return new TC_DateInterval( $_date_two_timestamp - $_date_one_timestamp );
}
}
/**
* Return boolean OR number of days since last update OR PHP version < 5.2
*
* @package Customizr
* @since Customizr 3.2.6
*/
function tc_post_has_update( $_bool = false) {
//php version check for DateTime
//http://php.net/manual/fr/class.datetime.php
if ( version_compare( PHP_VERSION, '5.2.0' ) < 0 )
return false;
//first proceed to a date check
$dates_to_check = array(
'created' => get_the_date('Y-m-d g:i:s'),
'updated' => get_the_modified_date('Y-m-d g:i:s'),
'current' => date('Y-m-d g:i:s')
);
//ALL dates must be valid
if ( 1 != array_product( array_map( array($this , 'tc_is_date_valid') , $dates_to_check ) ) )
return false;
//Import variables into the current symbol table
extract($dates_to_check);
//Instantiate the different date objects
$created = new DateTime( $created );
$updated = new DateTime( $updated );
$current = new DateTime( $current );
$created_to_updated = $this -> tc_date_diff( $created , $updated );
$updated_to_today = $this -> tc_date_diff( $updated, $current );
if ( true === $_bool )
//return ( 0 == $created_to_updated -> days && 0 == $created_to_updated -> s ) ? false : true;
return ( $created_to_updated -> s > 0 || $created_to_updated -> i > 0 ) ? true : false;
else
//return ( 0 == $created_to_updated -> days && 0 == $created_to_updated -> s ) ? false : $updated_to_today -> days;
return ( $created_to_updated -> s > 0 || $created_to_updated -> i > 0 ) ? $updated_to_today -> days : false;
}
/*
* @return boolean
* http://stackoverflow.com/questions/11343403/php-exception-handling-on-datetime-object
*/
private function tc_is_date_valid($str) {
if ( ! is_string($str) )
return false;
$stamp = strtotime($str);
if ( ! is_numeric($stamp) )
return false;
if ( checkdate(date('m', $stamp), date('d', $stamp), date('Y', $stamp)) )
return true;
return false;
}
/**
* @return an array of font name / code OR a string of the font css code
* @parameter string name or google compliant suffix for href link
*
* @package Customizr
* @since Customizr 3.2.9
*/
function tc_get_font( $_what = 'list' , $_requested = null ) {
$_to_return = ( 'list' == $_what ) ? array() : false;
$_font_groups = apply_filters(
'tc_font_pairs',
TC_init::$instance -> font_pairs
);
foreach ( $_font_groups as $_group_slug => $_font_list ) {
if ( 'list' == $_what ) {
$_to_return[$_group_slug] = array();
$_to_return[$_group_slug]['list'] = array();
$_to_return[$_group_slug]['name'] = $_font_list['name'];
}
foreach ( $_font_list['list'] as $slug => $data ) {
switch ($_requested) {
case 'name':
if ( 'list' == $_what )
$_to_return[$_group_slug]['list'][$slug] = $data[0];
break;
case 'code':
if ( 'list' == $_what )
$_to_return[$_group_slug]['list'][$slug] = $data[1];
break;
default:
if ( 'list' == $_what )
$_to_return[$_group_slug]['list'][$slug] = $data;
else if ( $slug == $_requested ) {
return $data[1];
}
break;
}
}
}
return $_to_return;
}
/**
* Returns a boolean
* check if user started to use the theme before ( strictly < ) the requested version
*
* @package Customizr
* @since Customizr 3.2.9
*/
function tc_user_started_before_version( $_czr_ver, $_pro_ver = null ) {
$_ispro = TC___::tc_is_pro();
if ( $_ispro && ! get_transient( 'started_using_customizr_pro' ) )
return false;
if ( ! $_ispro && ! get_transient( 'started_using_customizr' ) )
return false;
$_trans = $_ispro ? 'started_using_customizr_pro' : 'started_using_customizr';
$_ver = $_ispro ? $_pro_ver : $_czr_ver;
if ( ! $_ver )
return false;
$_start_version_infos = explode('|', esc_attr( get_transient( $_trans ) ) );
if ( ! is_array( $_start_version_infos ) )
return false;
switch ( $_start_version_infos[0] ) {
//in this case with now exactly what was the starting version (most common case)
case 'with':
return version_compare( $_start_version_infos[1] , $_ver, '<' );
break;
//here the user started to use the theme before, we don't know when.
//but this was actually before this check was created
case 'before':
return true;
break;
default :
return false;
break;
}
}
/**
* Boolean helper to check if the secondary menu is enabled
* since v3.4+
*/
function tc_is_secondary_menu_enabled() {
return (bool) esc_attr( TC_utils::$inst->tc_opt( 'tc_display_second_menu' ) ) && 'aside' == esc_attr( TC_utils::$inst->tc_opt( 'tc_menu_style' ) );
}
/***************************
* CTX COMPAT
****************************/
/**
* Helper : define a set of options not impacted by ctx like tc_slider, last_update_notice.
* @return array of excluded option names
*/
function tc_get_ctx_excluded_options() {
return apply_filters(
'tc_get_ctx_excluded_options',
array(
'defaults',
'tc_sliders',
'tc_blog_restrict_by_cat',
'last_update_notice',
'last_update_notice_pro'
)
);
}
/**
* Boolean helper : tells if this option is excluded from the ctx treatments.
* @return bool
*/
function tc_is_option_excluded_from_ctx( $opt_name ) {
return in_array( $opt_name, $this -> tc_get_ctx_excluded_options() );
}
/**
* Returns the url of the customizer with the current url arguments + an optional customizer section args
*
* @param $autofocus(optional) is an array indicating the elements to focus on ( control,section,panel).
* Ex : array( 'control' => 'tc_front_slider', 'section' => 'frontpage_sec').
* Wordpress will cycle among autofocus keys focusing the existing element - See wp-admin/customize.php.
* The actual focused element depends on its type according to this priority scale: control, section, panel.
* In this sense when specifying a control, additional section and panel could be considered as fall-back.
*
* @param $control_wrapper(optional) is a string indicating the wrapper to apply to the passed control. By default is "tc_theme_options".
* Ex: passing $aufocus = array('control' => 'tc_front_slider') will produce the query arg 'autofocus'=>array('control' => 'tc_theme_options[tc_front_slider]'
*
* @return url string
* @since Customizr 3.4+
*/
static function tc_get_customizer_url( $autofocus = null, $control_wrapper = 'tc_theme_options' ) {
$_current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$_customize_url = add_query_arg( 'url', urlencode( $_current_url ), wp_customize_url() );
$autofocus = ( ! is_array($autofocus) || empty($autofocus) ) ? null : $autofocus;
if ( is_null($autofocus) )
return $_customize_url;
// $autofocus must contain at least one key among (control,section,panel)
if ( ! count( array_intersect( array_keys($autofocus), array( 'control', 'section', 'panel') ) ) )
return $_customize_url;
// wrap the control in the $control_wrapper if neded
if ( array_key_exists( 'control', $autofocus ) && ! empty( $autofocus['control'] ) && $control_wrapper ){
$autofocus['control'] = $control_wrapper . '[' . $autofocus['control'] . ']';
}
// We don't really have to care for not existent autofocus keys, wordpress will stash them when passing the values to the customize js
return add_query_arg( array( 'autofocus' => $autofocus ), $_customize_url );
}
/**
* Is there a menu assigned to a given location ?
* Used in class-header-menu and class-fire-placeholders
* @return bool
* @since v3.4+
*/
function tc_has_location_menu( $_location ) {
$_all_locations = get_nav_menu_locations();
return isset($_all_locations[$_location]) && is_object( wp_get_nav_menu_object( $_all_locations[$_location] ) );
}
}//end of class
endif;
//Helper class to build a simple date diff object
//Alternative to date_diff for php version < 5.3.0
//http://stackoverflow.com/questions/9373718/php-5-3-date-diff-equivalent-for-php-5-2-on-own-function
if ( ! class_exists( 'TC_DateInterval' ) ) :
Class TC_DateInterval {
/* Properties */
public $y = 0;
public $m = 0;
public $d = 0;
public $h = 0;
public $i = 0;
public $s = 0;
/* Methods */
public function __construct ( $time_to_convert ) {
$FULL_YEAR = 60*60*24*365.25;
$FULL_MONTH = 60*60*24*(365.25/12);
$FULL_DAY = 60*60*24;
$FULL_HOUR = 60*60;
$FULL_MINUTE = 60;
$FULL_SECOND = 1;
//$time_to_convert = 176559;
$seconds = 0;
$minutes = 0;
$hours = 0;
$days = 0;
$months = 0;
$years = 0;
while($time_to_convert >= $FULL_YEAR) {
$years ++;
$time_to_convert = $time_to_convert - $FULL_YEAR;
}
while($time_to_convert >= $FULL_MONTH) {
$months ++;
$time_to_convert = $time_to_convert - $FULL_MONTH;
}
while($time_to_convert >= $FULL_DAY) {
$days ++;
$time_to_convert = $time_to_convert - $FULL_DAY;
}
while($time_to_convert >= $FULL_HOUR) {
$hours++;
$time_to_convert = $time_to_convert - $FULL_HOUR;
}
while($time_to_convert >= $FULL_MINUTE) {
$minutes++;
$time_to_convert = $time_to_convert - $FULL_MINUTE;
}
$seconds = $time_to_convert; // remaining seconds
$this->y = $years;
$this->m = $months;
$this->d = $days;
$this->h = $hours;
$this->i = $minutes;
$this->s = $seconds;
$this->days = ( 0 == $years ) ? $days : ( $years * 365 + $months * 30 + $days );
}
}
endif;