prepare_theme_vars();
// ADD WPBakery Page Builder ADDONS
if ( defined( 'WPB_VC_VERSION' ) ){
//since VC 5.5.2 it should be load always
/** @noinspection PhpIncludeInspection */
get_template_part('advance/vc', 'extend');
}
//support for Elementor Pro locations
if ( defined( 'ELEMENTOR_PRO_VERSION' ) ){
/** @noinspection PhpIncludeInspection */
get_template_part('advance/elementor', 'pro');
}
// ADD SIDEBARS
/** @noinspection PhpIncludeInspection */
get_template_part('advance/sidebars');
// AFTER SETUP(supports for thumbnails, menus, languages, RSS etc.)
add_action('after_setup_theme', array(&$this, 'bicycleshop_setup'));
}
/**
* registers panels, sections & fields for customizer. Prepares default values for theme options
*
* @param $section array of panel details OR section details & fields
*/
function bicycleshop_set_sections($section){
/**
* @since 2.3.0
*/
do_action( 'bicycleshop_options_before_'.$section['id'] );
//we need whole structure only when customizer is used
if(is_customize_preview()){
//section
if(isset($section['subsection'])){
end($this->customizer_sections);
$key = key($this->customizer_sections);
$this->customizer_sections[$key]['sections'][] = $section;
}
//panel
else{
$this->customizer_sections[] = $section;
}
}
//collect default values
if(isset($section['fields']) && is_array($section['fields']) && ! empty( $section['fields'] )){
foreach($section['fields'] as $params ){
//if we don't have such default yet, use default defined in framework
if( !array_key_exists($params['id'], $this->theme_options_defaults) ){
$this->theme_options_defaults[$params['id']] = isset($params['default'])? $params['default'] : '';
}
}
}
/**
* @since 2.3.0
*/
do_action( 'bicycleshop_options_after_'.$section['id'] );
}
/**
* returns panels, sections & fields for customizer
*/
function bicycleshop_get_sections(){
return $this->customizer_sections;
}
/**
* Set predefined set of settings for later use
*
* @param $set string set name
* @param $values array array of set values
*
* @return array
*/
function bicycleshop_set_settings_set($set, $values){
return $this->settings_set[$set] = $values;
}
/**
* Returns predefined set of settings
* @since 2.3.0
*/
function bicycleshop_get_settings_set($set){
return $this->settings_set[$set];
}
/**
* used in customizer to prepare settings after refresh in customizer
*/
function bicycleshop_customizer_wp_loaded() {
$this->theme_options = get_option(BICYCLESHOP_OPTIONS_NAME);
$this->load_options();
}
/**
* What to do before saving in customizer
*/
function bicycleshop_customizer_customize_save_before()
{
//get old set of options
$this->theme_options = get_option(BICYCLESHOP_OPTIONS_NAME);
$this->load_options();
}
/**
* Refresh options and generate user.css file after save in customizer
*/
function bicycleshop_customizer_customize_save_after()
{
//get new set of options
$this->theme_options = get_option(BICYCLESHOP_OPTIONS_NAME);
$this->load_options();
do_action( 'bicycleshop_generate_user_css' );
//refresh cache
delete_option(BICYCLESHOP_CACHE);
}
/**
* Various setup actions for setting up theme for WordPress
*/
function bicycleshop_setup()
{
global $content_width;
//content width
if (!isset($content_width)) {
$content_width = BICYCLESHOP_CONTENT_WIDTH;
}
if (
//forced refresh
$this->reset_user_css ||
//on fresh theme install
( function_exists('bicycleshop-a13fe_user_css_name') && ! file_exists( bicycleshop-a13fe_user_css_name() ) ) ||
//or customizer update after giving creds to FTP
(is_admin() && get_option('a13_user_css_update') === 'on')
) {
do_action( 'bicycleshop_generate_user_css' );
}
//LANGUAGE
load_theme_textdomain( 'bicycleshop', get_theme_file_path( 'languages' ) );
//remove admin bar bump
add_theme_support( 'admin-bar', array( 'callback' => '__return_false' ) );
// Featured image support
add_theme_support('post-thumbnails');
// Add default posts and comments RSS feed links to head
add_theme_support('automatic-feed-links');
//Let WordPress manage the document title.
add_theme_support('title-tag');
// Add post formats
add_theme_support('post-formats', array(
'aside',
'chat',
'gallery',
'image',
'link',
'quote',
'status',
'video',
'audio'
));
// Switches default core markup for search form, comment form, and comments
// to output valid HTML5.
add_theme_support('html5', array('search-form', 'comment-form', 'comment-list', 'gallery', 'caption'));
// WooCommerce support
add_theme_support('woocommerce');
//new thumbs in WooCommerce 3.0.0
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
// Indicate widget sidebars can use selective refresh in the Customizer.
add_theme_support( 'customize-selective-refresh-widgets' );
//below thing doesn't exist, it is left here for reference
//our menu are NOT reloaded partially cause we use custom Walker, and then Customizer uses full refresh
add_theme_support( 'custom-logo', array(
'height' => 75,
'width' => 200,
'flex-height' => true,
'flex-width' => true
) );
//Header Footer Elementor Plugin support
add_theme_support( 'header-footer-elementor' );
// Register custom menu positions
register_nav_menus(array(
'header-menu' => __( 'Site Navigation', 'bicycleshop' ),
));
}
/**
* Function for warnings that should be displayed in admin area
*/
function bicycleshop_check_for_warnings()
{
$notices = array();
$valid_tags = array(
'a' => array(
'href' => array(),
),
);
// Notice if dir for user settings is no writable
wp_reset_postdata();
// Display all error notices
foreach ($notices as $id => $notice) {
//show notice only if it wasn't dismissed by user
if( !bicycleshop_is_admin_notice_active($id) ){
continue;
}
echo '
' . wp_kses( $notice, $valid_tags ) . '
';
}
do_action( 'bicycleshop_theme_notices' );
}
/**
* Prepare all theme settings to be ready for read
*/
public function load_options()
{
//prepare custom sidebars
if ( isset($this->theme_options['custom_sidebars']) && is_array($this->theme_options['custom_sidebars'])) {
$tmp = array();
foreach ($this->theme_options['custom_sidebars'] as $id => $sidebar) {
//skip if left empty or not set name
if($sidebar === NULL || strlen($sidebar) === 0){
continue;
}
array_push($tmp, array('id' => 'sktwb-sidebar_' . (1 + $id), 'name' => $sidebar));
}
$this->theme_options['custom_sidebars'] = $tmp;
}
else{
$this->theme_options['custom_sidebars'] = array();
}
//fill missing options with defaults
foreach($this->theme_options_defaults as $id => $value ){
if(!array_key_exists($id, $this->theme_options)){
$this->theme_options[$id] = $value;
}
}
//in customizer or importer we need defaults for longer
if( !is_admin() && !is_customize_preview() ){
//save memory
unset($this->theme_options_defaults );
}
//finally loaded options
}
/**
* Overwrite current theme settings
*
* @param array $overload_options options we want to set
*/
public function set_options( $overload_options = array() )
{
if( is_array($overload_options) && count($overload_options) > 0){
update_option(BICYCLESHOP_OPTIONS_NAME, $overload_options);
$this->theme_options = $overload_options;
//refresh
$this->load_options();
//refresh cache
delete_option(BICYCLESHOP_CACHE);
}
}
/**
* Get one of theme settings
*
* @param string $index setting id
*
* @param string $default default setting when option is not present
*
* @param bool $filter should filter be used
*
* @return mixed
*/
public function get_option($index, $default = '', $filter = true)
{
$option_to_return = $default;
if ($index != '' && isset($this->theme_options[$index])) {
$option_to_return = $this->theme_options[$index];
}
//for customizer we don't use filters as it mess controls behaviour.
//JavaScript can't know about changes in filters, so it hides/shows options, and PHP then reverts this cause of filter actions
//good and only example is vertical header in boxed layout
if(!$filter){
return $option_to_return;
}
//apply filters to returned value if some special treating is needed
return apply_filters('bicycleshop_a13_options_'.$index, $option_to_return );
}
/**
* Get url only from media type theme setting
*
* @param string $index setting id
*
* @return string URL
*/
public function get_option_media_url($index)
{
$option = $this->get_option($index);
if (is_array($option)) {
if (isset($option['url'])) {
return $option['url']; //we got URL
} else {
return ''; //empty string as it is probably not set yet
}
}
elseif( is_string($option) && ( strlen($option) > 0 ) ){
if(strncmp($option, "http", 4) !== 0){
//make absolute path of possibly relative path(used for starer data)
$option = BICYCLESHOP_TPL_URI . $option;
}
}
return $option;//not an array? then probably it is saved as string
}
/**
* Get rgba only from color type theme setting
*
* @param string $index setting_id
*
* @return string URL
*/
public function get_option_color_rgba( $index )
{
$option = $this->get_option( $index );
if ( is_array( $option ) ) {
if ( isset( $option['rgba'] ) ) {
return $option['rgba']; //we got RGBA
} elseif ( isset( $option['color'] ) && isset( $option['alpha'] ) ) {
return bicycleshop_hex2rgba( $option['color'], $option['alpha'] ); //we got RGBA
} else {
return ''; //empty string as it is probably not set yet
}
}
return $option;//not an array? then probably it is saved as string
}
/**
* Get all settings. Used for exporting theme options
*
* @return array
*/
public function get_options_array()
{
return $this->theme_options;
}
/**
* Get all settings. Used for exporting theme options
*
* @return array
*/
public function prepare_options_array()
{
//set defaults values for all fields from theme specific defaults
$file = get_theme_file_path( 'default-settings/default.php');
if(file_exists($file)){
/** @noinspection PhpIncludeInspection */
$file_contents = include $file; // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
$options = json_decode($file_contents, true);
//SET THEME OPTIONS without saving to database
$this->theme_options_defaults = $options;
}
//collect sections & framework defaults
/** @noinspection PhpIncludeInspection */
get_template_part('advance/theme', 'options');
//set default setting if there is none(fresh install)
if($this->theme_options === false){
$this->theme_options = $this->theme_options_defaults;
$this->load_options();
$this->reset_user_css = true;
}
//normal flow, setup options
else{
$this->load_options();
}
}
/**
* Prepares var $parents_of_meta
*/
private function collect_meta_parents()
{
/** @noinspection PhpIncludeInspection */
require_once get_template_directory() . '/advance/meta.php'; // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
$option_func = array(
'post',
'page',
'album',
'work',
'people',
// 'images_manager' //no parent options here
);
foreach ($option_func as $function) {
$function_to_call = 'bicycleshop_meta_boxes_' . $function;
$family = str_replace('_layout', '', $function); //for consistent families
if(function_exists($function_to_call)){
foreach ( $function_to_call() as $meta_tab ) {
foreach( $meta_tab as $meta ) {
if (isset($meta['global_value'])) {
$this->parents_of_meta[$family][$meta['id']]['global_value'] = $meta['global_value'];
}
if (isset($meta['parent_option'])) {
$this->parents_of_meta[$family][$meta['id']]['parent_option'] = $meta['parent_option'];
}
}
}
}
}
}
/**
* Prepares list off all meta fields that have visibility dependencies and second list of possible switches with dependent fields
*/
public function get_meta_required_array() {
global $pagenow;
$list_of_requirements = array();
$list_of_dependent = array();
$meta_boxes = array();
$post_type = '';
if ('post.php' == $pagenow && isset($_GET['post']) ) {
// Will occur only in this kind of screen: /wp-admin/post.php?post=285&action=edit
// and it can be a Post, a Page or a CPT
$post_type = get_post_type( sanitize_text_field( wp_unslash( $_GET['post'] ) ) );
}
//if it is "new post" page
elseif('post-new.php' == $pagenow ) {
$post_type = isset($_GET['post_type']) ? sanitize_text_field( wp_unslash( $_GET['post_type'] ) ) : 'post';
}
if(strlen($post_type)){
switch ( $post_type ) {
case 'post':
$meta_boxes = bicycleshop_meta_boxes_post();
break;
case 'page':
$meta_boxes = bicycleshop_meta_boxes_page();
break;
}
foreach ( $meta_boxes as $meta_tab ) {
foreach( $meta_tab as $meta ) {
//check is it prototype
if ( isset( $meta['required'] ) ) {
$required = $meta['required'];
//fill list of required condition for each control
$list_of_requirements[ $meta['id'] ] = $required;
//fill list of controls that activate/deactivate other
//we have more then one required condition
if(is_array($required[0]) ){
foreach($required as $dependency){
$list_of_dependent[$dependency[0]][] = $meta['id'];
}
}
//we have only one required condition
else{
$list_of_dependent[$required[0]][] = $meta['id'];
}
}
}
}
}
return array($list_of_requirements, $list_of_dependent);
}
public function prepare_theme_vars(){
$cache = get_option( BICYCLESHOP_CACHE );
if( is_customize_preview() ){
//load textdomain early as we optimize reading of options file
load_theme_textdomain( 'bicycleshop', get_theme_file_path( 'languages' ) );
$this->prepare_options_array();
$this->collect_meta_parents();
}
//cache miss or translation plugin is active(WPML or Polylang)
elseif( $cache === false || $cache['version'] !== BICYCLESHOP_THEME_VERSION || defined( 'ICL_SITEPRESS_VERSION') || defined( 'POLYLANG_BASENAME' ) ){
//get theme options from database
$this->theme_options = get_option(BICYCLESHOP_OPTIONS_NAME);
//fresh install
if($this->theme_options === false ){
$this->prepare_options_array();
$this->collect_meta_parents();
}
//normal flow
else{
$this->prepare_options_array();
$this->collect_meta_parents();
//cache collected values
$cache = array(
'options' => $this->theme_options,
'meta' => $this->parents_of_meta,
'version' => BICYCLESHOP_THEME_VERSION
);
//save cache
update_option( BICYCLESHOP_CACHE, $cache );
}
}
//cache hit
else{
$this->theme_options = $cache['options'];
$this->parents_of_meta = $cache['meta'];
}
}
/**
* Retrieves meta setting with checking for parent settings, and global settings
*
* @param string $field name of meta setting
* @param bool|false $id ID of post. If not passed it will try to get one for current loop
*
* @return bool|mixed|null|string field value
*/
function bicycleshop_get_meta($field, $id = false)
{
$family = '';
if (!$id && bicycleshop_is_no_property_page()) {
return null; //we can't get meta field for that page
} else {
if (!$id) {
$id = get_the_ID();
}
$meta = trim(get_post_meta($id, $field, true));
}
if ($id) {
$post_type = get_post_type($id);
//get family to check for parent option
if ($post_type === 'page' ) {
$family = 'page';
} elseif (is_single($id)) {
$family = 'post';
}
$field = substr($field, 1); //remove '_'
//if has any parent
if (isset($this->parents_of_meta[$family][$field])) {
$parent = $this->parents_of_meta[$family][$field];
//meta points to global setting
if (isset($parent['global_value']) && ($meta == $parent['global_value'] || strlen($meta) == 0)) {
if (isset($parent['parent_option'])) {
$meta = $this->get_option($parent['parent_option']);
}
}
}
return $meta;
}
return false;
}
/**
* Returns list of all available in theme social icons with need additional info
*
* @param string $what - what should array consist of:
* names : Readable names
* classes : CSS classes used on front-end
* empty : only IDs are returned
*
* @return array requested list of social icons
*/
function bicycleshop_get_social_icons_list($what = 'names'){
$icons = array(
/* id => array(class, label)*/
'500px' => array( 'fa fa-500px', '500px' ),
'behance' => array( 'fa fa-behance', 'Behance' ),
'bitbucket' => array( 'fa fa-bitbucket', 'Bitbucket' ),
'codepen' => array( 'fa fa-codepen', 'CodePen' ),
'delicious' => array( 'fa fa-delicious', 'Delicious' ),
'deviantart' => array( 'fa fa-deviantart', 'Deviantart' ),
'digg' => array( 'fa fa-digg', 'Digg' ),
'dribbble' => array( 'fa fa-dribbble', 'Dribbble' ),
'dropbox' => array( 'fa fa-dropbox', 'Dropbox' ),
'mailto' => array( 'fa fa-envelope-o', 'E-mail' ),
'facebook' => array( 'fa fa-facebook', 'Facebook' ),
'flickr' => array( 'fa fa-flickr', 'Flickr' ),
'foursquare' => array( 'fa fa-foursquare', 'Foursquare' ),
'github' => array( 'fa fa-git', 'Github' ),
'googleplus' => array( 'fa fa-google-plus', 'Google Plus' ),
'instagram' => array( 'fa fa-instagram', 'Instagram' ),
'lastfm' => array( 'fa fa-lastfm', 'Lastfm' ),
'linkedin' => array( 'fa fa-linkedin', 'Linkedin' ),
'messenger' => array( 'fab fa-facebook-messenger', 'Facebook Messenger' ),
'paypal' => array( 'fa fa-paypal', 'Paypal' ),
'pinterest' => array( 'fa fa-pinterest-p', 'Pinterest' ),
'reddit' => array( 'fa fa-reddit-alien', 'Reddit' ),
'rss' => array( 'fa fa-rss', 'RSS' ),
'sharethis' => array( 'fa fa-share-alt', 'Sharethis' ),
'skype' => array( 'fa fa-skype', 'Skype' ),
'slack' => array( 'fa fa-slack', 'Slack' ),
'snapchat' => array( 'fa fa-snapchat-ghost', 'Snapchat' ),
'spotify' => array( 'fa fa-spotify', 'Spotify' ),
'steam' => array( 'fa fa-steam', 'Steam' ),
'stumbleupon' => array( 'fa fa-stumbleupon', 'Stumbleupon' ),
'tripadvisor' => array( 'fa fa-tripadvisor', 'TripAdvisor' ),
'tumblr' => array( 'fa fa-tumblr', 'Tumblr' ),
'twitter' => array( 'fa fa-twitter', 'Twitter' ),
'viadeo' => array( 'fa fa-viadeo', 'Viadeo' ),
'vimeo' => array( 'fa fa-vimeo', 'Vimeo' ),
'vine' => array( 'fa fa-vine', 'Vine' ),
'vkontakte' => array( 'fa fa-vk', 'VKontakte' ),
'whatsapp' => array( 'fa fa-whatsapp', 'Whatsapp' ),
'wordpress' => array( 'fa fa-wordpress', 'WordPress' ),
'xing' => array( 'fa fa-xing', 'Xing' ),
'yahoo' => array( 'fa fa-yahoo', 'Yahoo' ),
'yelp' => array( 'fa fa-yelp', 'Yelp' ),
'youtube' => array( 'fa fa-youtube', 'YouTube' ),
);
$icons = apply_filters('bicycleshop_social_icons_list', $icons );
$result = array();
//return classes
if($what === 'classes'){
foreach( $icons as $id => $icon ){
$result[$id] = $icon[0];
}
}
//empty values
elseif($what === 'empty'){
foreach( $icons as $id => $icon ){
$result[$id] = '';
}
}
//return names
else{
foreach( $icons as $id => $icon ){
$result[$id] = $icon[1];
}
}
return $result;
}
function bicycleshop_get_standard_fonts_list(){
return array(
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" => "System Font(Native)",
"Arial, Helvetica, sans-serif" => "Arial",
"'Arial Black', Gadget, sans-serif" => "Arial Black",
"'Bookman Old Style', serif" => "Bookman Old Style",
"'Comic Sans MS', cursive" => "Comic Sans MS",
"Courier, monospace" => "Courier",
"Garamond, serif" => "Garamond",
"Georgia, serif" => "Georgia",
"Impact, Charcoal, sans-serif" => "Impact",
"'Lucida Console', Monaco, monospace" => "Lucida Console",
"'Lucida Sans Unicode', 'Lucida Grande', sans-serif" => "Lucida Sans Unicode",
"'MS Sans Serif', Geneva, sans-serif" => "MS Sans Serif",
"'MS Serif', 'New York', sans-serif" => "MS Serif",
"'Palatino Linotype', 'Book Antiqua', Palatino, serif" => "Palatino Linotype",
"Tahoma,Geneva, sans-serif" => "Tahoma",
"'Times New Roman', Times,serif" => "Times New Roman",
"'Trebuchet MS', Helvetica, sans-serif" => "Trebuchet MS",
"Verdana, Geneva, sans-serif" => "Verdana",
);
}
function bicycleshop_is_companion_plugin_ready($fail_message = false, $silent = false){
include_once ABSPATH . 'wp-admin/includes/plugin.php';// phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
//just in case have these files included
require_once ABSPATH . 'wp-admin/includes/file.php';// phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
require_once ABSPATH . 'wp-admin/includes/template.php';// phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
$plugin_slug = 'skt-templates';
$plugin_file = 'skt-templates.php';
$plugin_path = $plugin_slug.'/'.$plugin_file;
$plugins = get_plugins('/'.$plugin_slug);
$ready = true;
//not installed yet plugin
if ( empty( $plugins[$plugin_file] ) ) {
$ready = false;
//we can install it normally
if ( get_filesystem_method( array(), WP_PLUGIN_DIR ) === 'direct' ) {
wp_enqueue_script( 'updates' );
$classes = ' install-now';
$href = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin='.esc_attr($plugin_slug) ), 'install-plugin_'.esc_attr($plugin_slug) );
}
//we need data from user to install plugin
else{
$tgm = TGM_Plugin_Activation::get_instance();
$href = $tgm->get_tgmpa_url();
}
$label = __( 'Install', 'bicycleshop' ) . ' : ' . __( 'SKT Templates – Elementor & Gutenberg templates', 'bicycleshop' );
}
//not active
elseif ( is_plugin_inactive( $plugin_path ) ){
$ready = false;
wp_enqueue_script( 'updates' );
$classes = ' activate-now';
$href = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin='.esc_attr($plugin_path) ), 'activate-plugin_'.esc_attr($plugin_path) );
$label = __( 'Activate', 'bicycleshop' ) . ' : ' . __( 'SKT Templates – Elementor & Gutenberg templates', 'bicycleshop' );
}
//not up to date
elseif( version_compare( $plugins[$plugin_file]['Version'], BICYCLESHOP_MIN_COMPANION_VERSION, '<' ) ){
$ready = false;
wp_enqueue_script( 'updates' );
$classes = ' update-now';
$href = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin='.esc_attr($plugin_path) ), 'upgrade-plugin_'.esc_attr($plugin_path) );
$label = __( 'Update', 'bicycleshop' ) . ' : ' . __( 'SKT Templates – Elementor & Gutenberg templates', 'bicycleshop' );
}
if(!$ready && !$silent){
$message = $fail_message ? $fail_message : __( 'This feature requires SKT Templates plugin to be active and in the proper version.', 'bicycleshop' );
echo ''.esc_html($message).'
';
/** @noinspection PhpUndefinedVariableInspection */
echo '
';
}
return $ready;
}
}