/**
  * The pre-defined validation callback method.
  *
  * The following hooks are available:
  *	- validation_{instantiated class name}_{field id} – [3.0.0+] receives the form submission value of the field that does not have a section. The first parameter: ( string|array ) submitted input value. The second parameter: ( string|array ) the old value stored in the database.
  *	- validation_{instantiated class name}_{section_id}_{field id} – [3.0.0+] receives the form submission value of the field that has a section. The first parameter: ( string|array ) submitted input value. The second parameter: ( string|array ) the old value stored in the database.
  *	- validation_{instantiated class name}_{section id} – [3.0.0+] receives the form submission values that belongs to the section.. The first parameter: ( array ) the array of submitted input values that belong to the section. The second parameter: ( array ) the array of the old values stored in the database.
  *	- validation_{page slug}_{tab slug} – receives the form submission values as array. The first parameter: submitted input array. The second parameter: the original array stored in the database.
  *	- validation_{page slug} – receives the form submission values as array. The first parameter: submitted input array. The second parameter: the original array stored in the database.
  *	- validation_{instantiated class name} – receives the form submission values as array. The first parameter: submitted input array. The second parameter: the original array stored in the database.
  */
 public function validation_HW_Livechat_settings($aInput, $aOldInput)
 {
     if (isset($aInput['chat_skin']['skin_options'])) {
         //make sure exists current skin
         $options = $aInput['chat_skin']['skin_options'];
         //user skin options
         //resume hw_skin
         if (isset($aInput['chat_skin']['hash_skin']) && isset($aInput['chat_skin']['hwskin_config'])) {
             $skin = APF_hw_skin_Selector_hwskin::resume_hwskin_instance($aInput['chat_skin']);
             //
             if ($skin && isset($aInput['chat_skin']['hash_skin'])) {
                 $hash_skin = $aInput['chat_skin']['hash_skin'];
                 //current active skin
                 $skin_setting_file = $skin->instance->get_file_skin_setting($hash_skin);
                 //current skin setting
                 $skin_options = $skin->instance->get_file_skin_options();
                 //current skin options
                 if (file_exists($skin_setting_file)) {
                     include $skin_setting_file;
                 }
                 if (file_exists($skin_options)) {
                     include $skin_options;
                 }
                 if (isset($theme) && isset($theme['options'])) {
                     $default_options = $theme['options'];
                 } else {
                     $default_options = array();
                 }
                 if (isset($theme_options)) {
                     $options = HW_SKIN::merge_skin_options_values($options, $default_options, $theme_options);
                     //__save_session('y2',$options);
                     /*$_SESSION['y3']=$skin_setting;
                       $_SESSION['y4']=$default_options;*/
                 }
             }
         }
         //get demo live chat embed code
         if (isset($options['enable_demo_chat']) && strtolower($options['enable_demo_chat']) == 'on' && isset($options['demo_embedcode'])) {
             $aInput['chat_embed_code'] = $options['demo_embedcode'];
             //clear enable_demo_chat option to able to update 'enable_demo_chat' skin option in next time
             unset($aInput['chat_skin']['skin_options']['enable_demo_chat']);
         }
     }
     //save current skin for enqueue
     if (!empty($aInput['chat_skin'])) {
         HW_SKIN::save_enqueue_skin(array('type' => 'resume_skin', 'skin' => $aInput['chat_skin'], 'object' => 'livechat', 'status' => $aInput['enable_livechat']));
     }
     return $aInput;
 }
 /**
  * load widget template
  * @param array $instance: widget instance (optional)	 
  * @param array $data: array of data need to be extract to current context
  */
 private function load_widget_template(&$instance = array(), $data = array())
 {
     //extract data
     if (isset($this->shared) && is_array($this->shared)) {
         extract($this->shared);
     } else {
         if (is_array($data)) {
             extract($data);
         }
     }
     //extract variables from array $args that get from 'widget' method
     if (isset($args)) {
         extract($args);
     }
     if (!is_array($instance) || !count($instance)) {
         $instance = $this->hw_parse_data();
         $instance = $instance['instance'];
     } else {
         $this->get_widget_instance($instance);
     }
     //by hoangweb.com
     if ($this->skin) {
         //load skin
         $file = $this->skin->get_skin_file(empty($instance['skin']) ? 'default' : $instance['skin']);
         if (file_exists($file)) {
             /**
              * pagination skin
              */
             $paginav = $this->skin->get_skin_instance('pagination')->get_skin_file(empty($instance['pagination_skin']) ? 'default' : $instance['pagination_skin']);
             //skin settings
             /*
             $paginav_skin_setting = isset($instance['skin_setting'])? $instance['skin_setting'] : '';
             
             $skin_setting_file = $this->skin->get_file_skin_setting(); //current skin setting
             $skin_options = $this->skin->get_file_skin_options();      //current skin options
             
             if(file_exists($skin_setting_file)) include ($skin_setting_file);
             if(file_exists($skin_options)) include ($skin_options);
             
             if(isset($theme) && isset($theme['options'])) $default_options = $theme['options'];
             if(isset($default_options) && isset($theme_options)) {
                 $paginav_skin_setting = HW_SKIN::merge_skin_options_values($paginav_skin_setting, $default_options, $theme_options);
             }
             */
             /**
              * scrollbar skin
              */
             $scrollbar = $this->skin->get_skin_instance('scrollbar')->get_skin_file(empty($instance['scrollbar_skin']) ? 'default' : $instance['scrollbar_skin']);
             //widget feature: grid_posts
             $grid_posts = HW_AWC::get_widget_feature($this, 'grid_posts');
             $awc_enable_grid_posts = false;
             //disable by default
             if ($grid_posts && HW_AWC::check_widget_feature($this, 'grid_posts')) {
                 $awc_enable_grid_posts = $grid_posts->is_active($instance);
                 if ($awc_enable_grid_posts) {
                     $awc_grid_posts_cols = $grid_posts->get_field_value('awc_grid_posts_cols');
                 }
             }
             /**
              * init some variables
              */
             $theme = array();
             //declare stylesheets file
             //content wrapper ID
             $hwtpl_wrapper_id = $this->get_holder_id($instance['widget_id']);
             $hwtpl_scrollbar_wrapper_class = '';
             //scrollbar content wrapper css class
             $hwtpl_pagination_class = '';
             //for pagination
             /**
              * load pagination component
              */
             if (file_exists($paginav)) {
                 include $paginav;
                 //valid
                 if (!isset($theme['scripts'])) {
                     $theme['scripts'] = array();
                 }
                 if (!isset($theme['styles'])) {
                     $theme['styles'] = array();
                 }
                 //migrate skin from pagination module
                 if ($instance['use_default_pagenav_skin'] && hw_is_active_module('pagination')) {
                     $theme = HWPageNavi_Core::render_pagination_skin();
                 } elseif (count($theme['styles']) || count($theme['scripts'])) {
                     $this->skin->get_skin_instance('pagination')->enqueue_files_from_skin($theme['styles'], $theme['scripts']);
                     //enqueue stuff from skin
                     /*HW_SKIN::enqueue_skin_assets(array(
                           'instance' => $this->skin,
                           'hash_skin' => $instance['skin'],
                           'skin_file' => $file,
                           'skin_settings' => $theme,
                           'skin_options' => $skin_setting
                       ));*/
                 }
                 //parse template tags
                 $hwtpl_pagination_class = isset($theme['pagination_class']) ? $theme['pagination_class'] : '';
                 $this->share_data('pagination', $theme);
             }
             //_print($this->skin->get_active_skin()); //enqueue stuff from skin
             /**
              * load scrollbar component
              */
             if (isset($instance['enable_scrollbar']) && $instance['enable_scrollbar'] && file_exists($scrollbar)) {
                 //load skin resource
                 $scrollbar_options_config = $this->skin->get_skin_instance('scrollbar')->get_file_skin_options(empty($instance['scrollbar_skin']) ? 'default' : $instance['scrollbar_skin']);
                 //theme options configuration
                 $scrollbar_theme_setting = $this->skin->get_skin_instance('scrollbar')->get_file_skin_setting();
                 //load theme-setting.php
                 //theme options
                 $scrollbar_theme_options = isset($instance['scrollbar_skin_setting']) ? $instance['scrollbar_skin_setting'] : array();
                 //scrollbar skin options
                 //reset
                 $theme['styles'] = array();
                 //declare stylesheets file
                 $theme['scripts'] = array();
                 //declare js files
                 $theme['options'] = array();
                 if (!empty($scrollbar_options_config) && file_exists($scrollbar_options_config)) {
                     include $scrollbar_options_config;
                     //include define scrollbar theme options
                 }
                 if (!empty($scrollbar_theme_setting) && file_exists($scrollbar_theme_setting)) {
                     include $scrollbar_theme_setting;
                     //scrollbar theme setting
                 }
                 if (isset($theme_options) && isset($theme)) {
                     $default = isset($theme['options']) ? $theme['options'] : array();
                     $result = HW_SKIN::get_skin_options($scrollbar_theme_options, $default, $theme_options);
                     $scrollbar_theme_options = array_merge($scrollbar_theme_options, $result);
                 }
                 /*
                 //best way but use old way as above do
                 $scrollbar_skin_setting = isset($instance['scrollbar_skin_setting'])? $instance['scrollbar_skin_setting'] : '';
                 
                                    $scrollbarskin_setting_file = $this->skin->get_skin_instance('scrollbar')->get_file_skin_setting(); //current skin setting
                                    $scrollbar_skin_options = $this->skin->get_skin_instance('scrollbar')->get_file_skin_options();      //current skin options
                 
                                    if(file_exists($scrollbarskin_setting_file)) include ($scrollbarskin_setting_file);
                                    if(file_exists($scrollbar_skin_options)) include ($scrollbar_skin_options);
                 
                                    if(isset($theme) && isset($theme['options'])) $scrollbar_default_options = $theme['options'];
                                    if(isset($scrollbar_default_options) && isset($theme_options)) {
                 $scrollbar_skin_setting = HW_SKIN::merge_skin_options_values($scrollbar_skin_setting, $scrollbar_default_options, $theme_options);
                                    }
                 */
                 //parse template tags
                 $hwtpl_scrollbar_wrapper_class = isset($theme['scrollbar_css']) ? $theme['scrollbar_css'] : '';
                 include $scrollbar;
                 //valid
                 /*if(!isset($theme['scripts'])) $theme['scripts'] = array();
                                        if(!isset($theme['styles'])) $theme['styles'] = array();
                 
                                        if(count($theme['styles']) || count($theme['scripts'])) {
                                            $this->skin->get_skin_instance('scrollbar')->enqueue_files_from_skin($theme['styles'], $theme['scripts']);
                                        }*/
                 //enqueue stuff from skin
                 HW_SKIN::enqueue_skin_assets(array('instance' => $this->skin->get_skin_instance('scrollbar'), 'hash_skin' => $instance['scrollbar_skin'], 'skin_file' => $scrollbar, 'skin_settings' => $theme, 'skin_options' => $scrollbar_theme_options));
                 $this->init_scrollbar_options($scrollbar_theme_options, $theme);
             }
             /**
              * load main skin
              */
             $options_config = $this->skin->get_file_skin_options();
             $skin_setting = $this->skin->get_file_skin_setting();
             if (file_exists($skin_setting)) {
                 include $skin_setting;
             }
             //theme options
             $skin_options = isset($instance['skin_setting']) ? $instance['skin_setting'] : array();
             $skin_options = HW_SKIN::merge_skin_options_values($skin_options, $skin_setting, $options_config);
             //params
             if (empty($instance['intermediate_image_sizes']) && !empty($instance['thumb_w']) && !empty($instance['thumb_h'])) {
                 $image_size = array($instance['thumb_w'], $instance['thumb_h']);
             } elseif (!empty($instance['intermediate_image_sizes'])) {
                 $image_size = $instance['intermediate_image_sizes'];
             } else {
                 $image_size = 'thumbnail';
             }
             //reset
             $theme['styles'] = array();
             //declare stylesheets file
             $theme['scripts'] = array();
             //declare js files
             $theme['options'] = array();
             //refresh theme options
             //widget features
             $wfeatures = $this->init_widget_features(array('theme' => $theme, 'skin_options' => $skin_options, 'instance' => $instance));
             //render skin template power by twig
             $data = array('hwtpl_scrollbar_wrapper_class', 'cat_posts', 'full_image_src', 'fancy_group', 'fancybox_g1', 'arrExlpodeFields', 'image_size', 'wfeatures', 'hwtpl_wrapper_id', 'args', 'instance', 'open_title_link', 'close_title_link');
             $data = compact($data);
             $data['context'] = $this;
             //reference to this object
             $content = $this->skin->render_skin_template($data, false);
             if ($content !== false) {
                 echo $content;
             }
             include $file;
             //valid
             /*if(!isset($theme['scripts'])) $theme['scripts'] = array();
                                if(!isset($theme['styles'])) $theme['styles'] = array();
             
                                if(count($theme['styles']) || count($theme['scripts'])) {
                                    $this->skin->enqueue_files_from_skin($theme['styles'], $theme['scripts']); //enqueue stuff from skin
                                }*/
             //enqueue stuff from skin
             HW_SKIN::enqueue_skin_assets(array('instance' => $this->skin, 'hash_skin' => $instance['skin'], 'skin_file' => $file, 'skin_settings' => $theme, 'skin_options' => $skin_options));
             //init scrolling
             //add_action('wp_footer',array(&$this, 'init_content_options'),1000);	//don't use wp hook to setup scroll
             $this->init_content_options(array('theme' => $theme, 'skin_options' => $skin_options, 'instance' => $instance));
         }
     } else {
         echo __('not found class HW_SKIN.');
     }
 }
 /**
  * This is the Widget
  * @param $args
  * @param $instance
  */
 public function widget($args, $instance)
 {
     global $post;
     extract($args);
     // Widget options
     $title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base);
     // Title
     $this_taxonomy = $instance['taxonomy'];
     // Taxonomy to show
     $hierarchical = !empty($instance['hierarchical']) ? '1' : '0';
     $showcount = !empty($instance['count']) ? '1' : '0';
     $hide_empty = !empty($instance['hide_empty']) ? '1' : '0';
     $depth = !empty($instance['depth']) ? $instance['depth'] : 0;
     //skin
     $use_skin = !empty($instance['use_skin']) ? 1 : 0;
     $use_skin_options = !empty($instance['extend_skin_options']) ? 1 : 0;
     $skin = isset($instance['skin']) ? $instance['skin'] : '';
     //saved active hash skin
     //skin settings
     $skin_setting = isset($instance['skin_settings']) ? $instance['skin_settings'] : '';
     if ($skin) {
         $skin_setting_file = $this->skin->get_file_skin_setting($skin);
         //current skin setting
         $skin_options = $this->skin->get_file_skin_options();
         //current skin options
         if (file_exists($skin_setting_file)) {
             include $skin_setting_file;
         }
         if (file_exists($skin_options)) {
             include $skin_options;
         }
         if (isset($theme) && isset($theme['options'])) {
             $default_options = $theme['options'];
         }
         if (isset($default_options) && isset($theme_options)) {
             $skin_setting = HW_SKIN::merge_skin_options_values($skin_setting, $default_options, $theme_options);
         }
     }
     //widget feature field: grid_posts
     $grid_posts = HW_AWC::get_widget_feature($this, 'grid_posts');
     $awc_enable_grid_posts = false;
     //disable by default
     if ($grid_posts && HW_AWC::check_widget_feature($this, 'grid_posts')) {
         $awc_enable_grid_posts = $grid_posts->is_active($instance);
         if ($awc_enable_grid_posts) {
             $awc_grid_posts_cols = $grid_posts->get_field_value('awc_grid_posts_cols');
         }
     }
     $show_option_none = !empty($instance['show_option_none']) ? $instance['show_option_none'] : '';
     if (array_key_exists('orderby', $instance)) {
         $orderby = $instance['orderby'];
     } else {
         $orderby = 'count';
     }
     if (array_key_exists('ascdsc', $instance)) {
         $ascdsc = $instance['ascdsc'];
     } else {
         $ascdsc = 'desc';
     }
     if (array_key_exists('exclude', $instance)) {
         $exclude = join(',', (array) $instance['exclude']);
     } else {
         $exclude = '';
     }
     if (array_key_exists('dropdown', $instance)) {
         $dropdown = $instance['dropdown'];
     } else {
         $dropdown = false;
     }
     #child of arg
     if (array_key_exists('childof', $instance)) {
         $childof = $instance['childof'];
     } else {
         $childof = '';
     }
     //get current category/taxonomy
     if (isset($instance['childof_current_term']) && $instance['childof_current_term'] && (is_category() || is_tax())) {
         $obj = get_queried_object();
         //get current page data
         $childof = $obj->term_id;
         //get current term in template
     }
     $show_subcat_by_parent = isset($instance['show_subcat_by_parent']) ? (bool) $instance['show_subcat_by_parent'] : false;
     $categories_by_current_post = isset($instance['categories_by_current_post']) ? (bool) $instance['categories_by_current_post'] : false;
     $args['skin'] = $skin;
     $args['skin_setting'] = $skin_setting;
     $data = array('show_subcat_by_parent' => $show_subcat_by_parent, 'categories_by_current_post' => $categories_by_current_post, 'skin' => $skin, 'skin_setting' => $skin_setting);
     // Output
     $tax = $this_taxonomy;
     if ($dropdown) {
         $taxonomy_object = get_taxonomy($tax);
         $args = array('show_option_all' => false, 'show_option_none' => '', 'orderby' => $orderby, 'order' => $ascdsc, 'show_count' => $showcount, 'hide_empty' => $hide_empty, 'child_of' => $childof, 'exclude' => $exclude, 'echo' => 0, 'hierarchical' => $hierarchical, 'name' => $taxonomy_object->query_var, 'id' => 'hwlct-widget-' . $tax, 'depth' => $depth, 'taxonomy' => $tax, 'hide_if_empty' => (bool) $hide_empty, 'walker' => new hwlctwidget_Taxonomy_Dropdown_Walker(), 'mydata' => $data);
     } else {
         $args = array('show_option_all' => false, 'orderby' => $orderby, 'order' => $ascdsc, 'style' => 'list', 'show_count' => $showcount, 'hide_empty' => $hide_empty, 'use_desc_for_title' => 1, 'child_of' => $childof, 'exclude' => $exclude, 'hierarchical' => $hierarchical, 'title_li' => '', 'show_option_none' => apply_filters('hwlct_show_option_none', $show_option_none), 'number' => null, 'echo' => 0, 'depth' => $depth, 'taxonomy' => $tax, 'mydata' => $data);
         $args['walker'] = new hwlctwidget_Taxonomy_Walker($args);
     }
     $args = apply_filters('hwlct_wp_list_categories_args', $args, $instance);
     //filter args
     if ($use_skin && $this->skin) {
         //load skin
         $skin = $this->skin;
         //$file = $this->skin->get_skin_instance('x')->get_skin_link(empty($instance['skin1'])? 'default':$instance['skin1']);
         $file = $this->skin->get_skin_file(empty($instance['skin']) ? 'default' : $instance['skin']);
         if (file_exists($file)) {
             HW_POST::reset_item_counter();
             $terms_data = get_categories($args);
             //get terms data
             foreach ($terms_data as $id => &$term) {
                 //wrap with timber
                 $term = new HW_TimberTerm($term->term_id, $term->taxonomy);
                 //class
                 $classes = array('item-box');
                 if ($awc_enable_grid_posts && isset($awc_grid_posts_cols) && class_exists('HW_POST')) {
                     $classes = HW_POST::get_item_class($awc_grid_posts_cols, $classes);
                 }
                 if (class_exists('HW_POST')) {
                     $term->add_class(HW_POST::item_class($classes, false));
                 }
                 //term image custom field
                 /*if(function_exists('get_field')) $image = get_field('image',$term);
                   else $image = '';
                   if(!$image) $image = HW_SKIN::current()->get_skin_url('images/placeholder.png');*/
             }
             //skin template
             $content = $this->skin->render_skin_template(compact('terms_data', 'tax'), false);
             if ($content !== false) {
                 echo $content;
             }
             //init theme setting
             $theme['styles'] = array();
             //declare stylesheets file
             $theme['scripts'] = array();
             //declare js files
             if ($this->skin->allow_skin_file()) {
                 include $file;
             }
             //enqueue stuff from skin
             HW_SKIN::enqueue_skin_assets(array('instance' => $this->skin, 'hash_skin' => $instance['skin'], 'skin_file' => $file, 'skin_settings' => $theme, 'skin_options' => $skin_setting));
         }
     } else {
         echo $before_widget;
         if ($title) {
             echo $before_title . $title . $after_title;
         }
         if ($dropdown) {
             echo '<form action="' . get_bloginfo('url') . '" method="get">';
             echo apply_filters('hwlct_wp_dropdown_categories', wp_dropdown_categories($args), $args, $instance);
             echo '<input type="submit" value="go &raquo;" /></form>';
         } else {
             echo apply_filters('hwlct_wp_list_categories', wp_list_categories($args), $args, $instance);
         }
         echo $after_widget;
     }
     if ($use_skin && !class_exists('HW_SKIN')) {
         echo 'HW_SKIN class không tìm thấy.';
     }
     //notice
 }
 /**
  * get qtranslate switcher
  */
 public static function get_qtrans_switcher()
 {
     $mqtrans_skin = hw_option('mqtrans_skin');
     //get mqtrans skin
     $other_service = hw_option('enable_googletranslate');
     //use google translate?
     if (isset($mqtrans_skin['hash_skin']) && isset($mqtrans_skin['hwskin_config'])) {
         $skin = APF_hw_skin_Selector_hwskin::resume_hwskin_instance($mqtrans_skin);
         //skin options
         //$skin_options = $mqtrans_skin['skin_options'];
         $html = '';
         //output
         $file = $skin->instance->get_skin_file($skin->hash_skin);
         //load footer template
         if (file_exists($file)) {
             HW_HOANGWEB::load_class('HW_String');
             HW_HOANGWEB::load_class('HW_Twig_Template');
             HW_HOANGWEB::load_class('HW_mqtranslate');
             //get theme setting file
             $setting = $skin->instance->get_file_skin_setting();
             //(new HW_SKIN);
             if (file_exists($setting)) {
                 include $setting;
             }
             //skin options
             $skin_options_file = $skin->instance->get_file_skin_options();
             //(new HW_SKIN)->enqueue_files_from_skin()
             $skin_options = isset($mqtrans_skin['skin_options']) ? $mqtrans_skin['skin_options'] : array();
             //user options
             $skin_options = HW_SKIN::merge_skin_options_values($skin_options, $setting, $skin_options_file);
             $data = array();
             //data send to twig template
             /*active google translate*/
             if ($other_service) {
                 $TranslateElement_opts = array('pageLanguage' => 'vi');
                 //layout
                 $layout = self::get_googletrans_layout_param(isset($skin_options['display_mode']) ? $skin_options['display_mode'] : '');
                 if ($layout) {
                     $TranslateElement_opts['layout'] = $layout;
                 }
                 //include languages
                 if (!empty($skin_options['specific_langs']) && is_array($skin_options['specific_langs'])) {
                     $TranslateElement_opts['includedLanguages'] = join($skin_options['specific_langs'], ',');
                 }
                 $data['google_translate_ID'] = !empty($skin_options['google_translate_ID']) ? $skin_options['google_translate_ID'] : HW_String::generateRandomString();
             } else {
                 //prepare data for template
                 if (class_exists('HW_mqtranslate')) {
                     // make sure use __autoload
                     $data = HW_mqtranslate::generateLanguageSelectCode();
                 }
             }
             //get templates folder from skin
             if (isset($theme) && isset($theme['templates_folder'])) {
                 $tpl = $theme['templates_folder'];
             } else {
                 $tpl = '';
             }
             if (class_exists('HW_Twig_Template')) {
                 $twig = HW_Twig_Template::create($skin->instance->get_file_skin_resource($tpl));
                 if (isset($data)) {
                     $twig->set_template_data($data);
                 }
                 //inject data to current twig for skin using
             }
             ob_start();
             //google translate
             if (isset($TranslateElement_opts)) {
                 $json = HW_SKIN_Option::build_json_options($TranslateElement_opts, null, 'layout');
                 echo '<script type="text/javascript">
                 function googleTranslateElementInit() {
                     new google.translate.TranslateElement(' . $json . ', "' . $data['google_translate_ID'] . '");
                 }
                 </script>
                 ';
             }
             $content = $skin->instance->render_skin_template(compact('wrapper', 'active_langs', 'text'), false);
             //data, return=false
             if ($content !== false) {
                 echo $content;
             }
             if ($skin->instance->allow_skin_file()) {
                 include $file;
             }
             $html = ob_get_contents();
             if ($html && ob_get_length()) {
                 ob_end_clean();
             }
         }
         //valid
         if (!isset($theme['styles'])) {
             $theme['styles'] = array();
         }
         if (!isset($theme['scripts'])) {
             $theme['scripts'] = array();
         }
         //put stuff from skin
         if (count($theme['styles']) || count($theme['scripts'])) {
             $skin->instance->enqueue_files_from_skin($theme['styles'], $theme['scripts']);
         }
         return $html;
     }
 }
 /**
  * modify form class attribute display on website
  * @param $class
  */
 public function _hw_wpcf7_form_class_attr($class)
 {
     $form = $this->current;
     //current contact form object
     $wpcf_id = $this->current->id();
     //contact form id
     $form_class = $form->prop('hw_form_class_attr');
     //form class attr
     //$form = WPCF7_ContactForm::get_instance($this->current->id());  //get wpcf7 by id
     $class .= ' hw-wpcf7-' . $wpcf_id;
     //generate current form class
     //get current contact forn skin
     $skin = $form->prop('hw_wpcf7_skin');
     #$skin = $this->current->prop('hw_wpcf7_skin');
     $priority = 'hwcf7-' . $skin;
     //purpose of given priority for handler to hooks of current skin, (required)
     //
     global $wp_filter;
     $file = $this->setting->skin->get_skin_file($skin);
     if ($skin && file_exists($file)) {
         $theme_setting = $this->setting->skin->get_file_skin_setting();
         //extract theme setting from skin
         //current skin options
         $skin_setting = $form->prop('hw_wpcf7skin_setting');
         if ($skin_setting) {
             $options = $skin_setting['skin_options'];
         } else {
             $options = array();
         }
         $skin_options = $this->setting->skin->get_file_skin_options();
         if (file_exists($theme_setting)) {
             include $theme_setting;
         }
         if (file_exists($skin_options)) {
             include $skin_options;
         }
         //first load skin & init hooks
         include $file;
         //note add hook does't work if include statement inside a function with 2 level
         #$skin_data = HW_SKIN::include_skin_file($file);    //note that you need to include once to prevent duplicate function in skin file
         /*if(!empty($skin_data) && is_array($skin_data)) {
               extract($skin_data);
           }*/
         //parse theme options
         if (isset($theme) && isset($theme['options'])) {
             $default_options = $theme['options'];
         } else {
             $default_options = array();
         }
         if (isset($theme_options)) {
             $options = HW_SKIN::merge_skin_options_values($options, $default_options, $skin_options);
         }
         if (!empty($options['form_class_attr'])) {
             $class .= ' ' . $options['form_class_attr'];
         }
         /*
          *solution is: different skin use different function name, to prevent php error
          *
          * */
         //put each skin with each handle & stored in this context
         if (isset($wp_filter['hw_wpcf7_form_class_attr']) && count($wp_filter['hw_wpcf7_form_class_attr'])) {
             if (!isset($this->keep_filter_handles[$skin]) && isset($wp_filter['hw_wpcf7_form_class_attr']['hwcf7-' . $skin])) {
                 $this->keep_filter_handles[$skin] = $wp_filter['hw_wpcf7_form_class_attr']['hwcf7-' . $skin];
             }
         }
         remove_all_filters('hw_wpcf7_form_class_attr');
         //unbind all handles for the filter
         $wp_filter['hw_wpcf7_form_class_attr']['hwcf7-' . $skin] = $this->keep_filter_handles[$skin];
         //re-assign hook handle for this skin
         //finally call the hook
         $class .= ' ' . trim(apply_filters('hw_wpcf7_form_class_attr', null));
         //filter form class, don't pass & combine param to handle in return statement. It cause concat values by all handlers bind to this filter
     }
     if ($form_class) {
         $class .= " {$form_class}";
     }
     return $class;
 }
 /**
  * enqueue actived skins assets
  * @param $skin
  */
 public static function enqueue_skins($skin)
 {
     if (empty($skin->instance)) {
         return;
     }
     ob_start();
     $file = $skin->instance->get_skin_file($skin->hash_skin);
     //
     if (file_exists($file)) {
         $options = isset($skin->skin_options) ? $skin->skin_options : array();
         $theme_setting = $skin->instance->get_file_skin_setting();
         //extract theme setting from skin
         $skin_options = $skin->instance->get_file_skin_options();
         //current skin options
         //create skin data holder
         self::$skins_assets_manager[$file] = array('skin' => $skin);
         $skin_status =& self::$skins_assets_manager[$file];
         $skin_status['enqueued_css'] = false;
         $skin_status['enqueued_js'] = false;
         //load theme setting
         if (file_exists($theme_setting)) {
             include $theme_setting;
         }
         if (file_exists($skin_options)) {
             include $skin_options;
         }
         if (!isset($theme)) {
             // note add hook does't work if include statement inside a function with 2 level
             include $file;
             /*$skin_data = self::include_skin_file($file);
               if(!empty($skin_data) && is_array($skin_data)) {
                   extract($skin_data);
               }*/
         }
         //valid theme setting
         if (!isset($theme['styles']) || !is_array($theme['styles'])) {
             $theme['styles'] = array();
         }
         if (!isset($theme['scripts']) || !is_array($theme['scripts'])) {
             $theme['scripts'] = array();
         }
         if (!isset($theme['js-libs']) || !is_array($theme['js-libs'])) {
             $theme['js-libs'] = array();
         }
         $theme['styles'] = array_unique($theme['styles']);
         $theme['scripts'] = array_unique($theme['scripts']);
         $theme['js-libs'] = array_unique($theme['js-libs']);
         //parse theme options
         if (isset($theme) && isset($theme['options'])) {
             $default_options = $theme['options'];
         } else {
             $default_options = array();
         }
         if (isset($theme_options)) {
             $options = HW_SKIN::merge_skin_options_values($options, $default_options, $theme_options);
         }
         //save skin data
         $skin_status['theme_settings'] = $theme;
         if (isset($options)) {
             $skin_status['theme_options'] = $options;
         }
         #__save_session($file.'-options',$options);
         if (count($theme['styles']) || count($theme['scripts']) || count($theme['js-libs'])) {
             //only for stylesheets
             if (!isset($options['enqueue_js_position'])) {
                 $options['enqueue_js_position'] = 'footer';
             }
             //default put js files at bottom of page
             if (!isset($options['enqueue_css_position'])) {
                 $options['enqueue_css_position'] = 'footer';
             }
             //default put js files at bottom of page
             //alway enqueue stylesheet within head tag
             if ($options['enqueue_css_position'] == 'head' && count($theme['styles'])) {
                 $skin->instance->enqueue_files_from_skin(array_unique($theme['styles']), null, false);
                 $skin_status['enqueued_css'] = true;
             }
             //enqueue skin scripts
             if ($options['enqueue_js_position'] == 'head' && count($theme['scripts'])) {
                 $skin->instance->enqueue_files_from_skin(null, array_unique($theme['scripts']), false);
                 $skin_status['enqueued_js'] = true;
             }
             //enqueue jquery library
             if ($options['enqueue_js_position'] == 'head' && count($theme['js-libs'])) {
                 foreach ($theme['js-libs'] as $lib) {
                     HW_Libraries::enqueue_jquery_libs($lib);
                 }
                 $skin_status['enqueued_lib'] = true;
             }
         }
     }
     #ob_end_clean();
     ob_clean();
 }
 /**
  * add shortcode to display slider on website
  * @param array $attsa
  */
 public function _hwml_shortcode_slider($atts = array())
 {
     $default = array('id' => false, 'restrict_to' => false);
     extract(shortcode_atts($default, $atts, 'hwml_slider'));
     if (!$id) {
         return false;
     }
     // handle [hwml_slider id=123 restrict_to=home]
     if ($restrict_to && $restrict_to == 'home' && !is_front_page()) {
         //front page
         return;
     }
     if ($restrict_to && $restrict_to != 'home' && !is_page($restrict_to)) {
         //for page
         return;
     }
     $id = trim($id, '&quot;');
     $post = get_post($id);
     //_print(get_post_custom($id));
     $slider_id = get_post_meta($id, 'pick_slider', true);
     //meta slider id
     $slider_theme = get_post_meta($id, 'slider_theme', true);
     //slider theme
     $source = get_post_meta($id, 'slideshow_source', true);
     //choose slideshow source
     if (!$slider_id && !$slider_theme) {
         throw new Exception('Lỗi custom field (hwml-shortcode)?');
         return;
     }
     //instance HW_SKIN
     $skin = APF_hw_skin_Selector_hwskin::resume_hwskin_instance($slider_theme);
     //current skin file
     $file = $skin->instance->get_skin_file($skin->hash_skin);
     $skin_config = $skin->instance->get_config(false);
     $skin_info = $skin->instance->get_active_skin_info();
     $options_config = $skin->instance->get_file_skin_options($skin->hash_skin);
     //theme options configuration
     $theme_setting = $skin->instance->get_file_skin_setting();
     //(new HW_SKIN)->get_file_skin_setting()
     //theme options
     $user_theme_options = isset($slider_theme['skin_options']) && is_array($slider_theme['skin_options']) ? $slider_theme['skin_options'] : array();
     /*
     //load skin resource
     if(file_exists($options_config)) include($options_config);   //include define theme options
     if(file_exists($theme_setting)) include($theme_setting);        //theme setting
     
     if( isset($theme_options) && isset($theme)){
         $default = isset($theme['options']) ? $theme['options'] : array();
     
         $result = HW_SKIN::get_skin_options($user_theme_options, $default,$theme_options);
         $user_theme_options = array_merge($user_theme_options, $result);
     }
     */
     //new way
     $user_theme_options = HW_SKIN::merge_skin_options_values($user_theme_options, $theme_setting, $options_config);
     //get default template for this skin base slideshow source
     $default_template = $skin_info[0] . '/' . $skin_info[1] . trim($skin_config['skin_name'], '.php') . '_template_' . $source . '.php';
     //default template
     if (file_exists($default_template) && isset($user_theme_options['template_file']) && $user_theme_options['template_file'] == APF_hw_skin_Selector_hwskin::DEFAULT_TEMPLATE) {
         $file = $default_template;
         //change template file
     } elseif (isset($user_theme_options['template_file']) && $user_theme_options['template_file'] != APF_hw_skin_Selector_hwskin::DEFAULT_TEMPLATE) {
         $file = base64_decode($user_theme_options['template_file']);
     }
     if (file_exists($file)) {
         //get data
         $show_title = get_post_meta($id, 'show_title', true);
         $data = array();
         //valid data
         if (isset($user_theme_options['template_file'])) {
             unset($user_theme_options['template_file']);
         }
         //get sides from metaslider
         if ($source == 'metaslider') {
             $query = $this->get_mlslider_metaslides($slider_id);
             $data['posts'] = Timber::get_posts($query->query_vars);
         }
         //get sides from posts
         if ($source == 'posttype') {
             //get query post types
             $posttype = get_post_meta($id, 'source_posttype', true);
             //get active post types
             $current_post = get_post_meta($id, 'current_post', true);
             //get active post types
             $only_attachment = get_post_meta($id, 'only_attachments', true);
             //get only attachments
             $args = array('order' => 'ASC', 'posts_per_page' => -1);
             $query = null;
             $images = array();
             if ($current_post) {
                 global $post;
                 if (is_single()) {
                     $images = get_children(array('post_parent' => $post->ID, 'post_type' => 'attachment', 'post_mime_type' => 'image'));
                 }
             } else {
                 //get all selected terms assign to post type
                 $pt_terms = get_post_meta($id, 'post_type_terms', true);
                 $tax_query_relation = get_post_meta($id, 'tax_query_relation', true);
                 $terms_tax = array();
                 //prepare tax query
                 $tax_query = array();
                 //tax_query param
                 if ($tax_query_relation) {
                     $tax_query['relation'] = $tax_query_relation;
                 }
                 if (is_array($pt_terms)) {
                     foreach ($pt_terms as $t => $enable) {
                         if ($enable) {
                             $tax = base64_decode($t);
                             $tax = explode('|', $tax);
                             if (!isset($terms_tax[$tax[1]])) {
                                 $terms_tax[$tax[1]] = array();
                             }
                             $terms_tax[$tax[1]][] = $tax[0];
                         }
                     }
                 }
                 //build tax_query param
                 foreach ($terms_tax as $tax => $terms) {
                     $tax_query[] = array('taxonomy' => $tax, 'field' => 'slug', 'terms' => $terms, 'operator' => 'IN');
                 }
                 //$terms = wp_get_post_terms($id,'category',array("fields" => "ids"));
                 $args['post_type'] = $posttype;
                 $args['tax_query'] = $tax_query;
                 $query = new WP_Query($args);
                 $data['posts'] = Timber::get_posts($args);
                 //get only attachments image
                 if ($only_attachment) {
                     //refercence http://wordpress.stackexchange.com/questions/52315/get-attachments-for-all-posts-of-particular-post-type
                     if ($query->have_posts()) {
                         while ($query->have_posts()) {
                             $query->the_post();
                             // arguments for get_posts
                             $attachment_args = array('post_type' => 'attachment', 'post_mime_type' => 'image', 'post_status' => null, 'post_parent' => get_the_ID());
                             // get the posts
                             $this_posts_attachments = get_posts($attachment_args);
                             // append those posts onto the array
                             $images[get_the_ID()] = $this_posts_attachments;
                             // make an array with the post_id as the key, just in case that's useful
                         }
                     }
                 }
             }
         }
         //skin data
         $options = APF_hw_skin_Selector_hwskin::build_json_options($user_theme_options, 'template_file');
         $slider_theme = !empty($user_theme_options['theme']) ? $user_theme_options['theme'] : 'default';
         $data = compact('slider_id', 'options', 'slider_theme', 'show_title');
         $data['context'] = $this;
         /**
          * parse theme
          */
         $content = $skin->instance->render_skin_template($data, false);
         //implement skin template
         if ($content !== false) {
             echo $content;
         }
         $theme = array();
         //valid
         if ($skin->instance->allow_skin_file()) {
             include_once $file;
         }
         /*if(!isset($theme['styles'])) $theme['styles'] = array();
                     if(!isset($theme['scripts'])) $theme['scripts'] = array();
         
                     if(count($theme['styles']) || count($theme['scripts'])) {
                         $skin->instance->enqueue_files_from_skin($theme['styles'], $theme['scripts']);
                     }*/
         //enqueue stuff from skin
         HW_SKIN::enqueue_skin_assets(array('instance' => $skin->instance, 'hash_skin' => $skin->hash_skin, 'skin_file' => $file, 'theme_settings' => $theme, 'theme_options' => $user_theme_options));
     }
 }