<?php
/*
    VC basic extensions
    integrated in core theme
*/
namespace vc;

if( ! defined( 'ABSPATH' ) ) exit;

new shortcode_posts;
class shortcode_posts {

    /*
        General constructor
    */
    public function __construct() {
        // return if in backend
        if (is_admin()) return;

        /**
         * Register shortcodes
         */
        add_shortcode( 'vc_posts_links', array($this, 'posts_links_sc') );
        add_shortcode( 'vc_posts_overview', array($this, 'posts_overview_sc') );
        add_shortcode( 'vc_posts_tp', array($this, 'posts_template_sc') );

        // deprecated
        add_shortcode( 'vc_posts_details_tp', array($this, 'posts_details_sc') );
        add_shortcode( 'vc_post_tp', array($this, 'post_template_sc') );
    }

    /**
     * =================================================================
     *                          Shortcodes
     * =================================================================
     */

    /**
     * Post Archives
     * 
     * @shortcode 'vc_posts_links'
     */
    public static function posts_links_sc($atts, $content) {
        // debug($atts);

        //
        // get archive setup
        $type = isset($atts['archive_type']) ? esc_attr($atts['archive_type']) : 'yearly';
        if ($type != '') {
            $mode = isset($atts['mode']) ? esc_attr($atts['mode']) : 'list';
            if ($mode != '') {
                $archive = array(
                    'type' => $type,
                    'mode' => $mode,
                );
                if ($archive['type'] == 'post_tag') $archive['post_type'] = isset($atts['pt_by_tag']) ? esc_attr($atts['pt_by_tag']) : 'post';
                elseif ($archive['type'] == 'category') $archive['post_type'] = isset($atts['pt_by_cat']) ? esc_attr($atts['pt_by_cat']) : 'post';
                else $archive['post_type'] = isset($atts['pt']) ? esc_attr($atts['pt']) : 'post';
                $archive['width'] = isset($atts['content_width']) ? esc_attr($atts['content_width']) : '';
                if ($archive['width'] != '' && strpos($archive['width'], '%') == false && strpos($archive['width'], 'px') == false) $archive['width'] .= "%";
                $archive['pull'] = isset($atts['content_pull']) ? esc_attr($atts['content_pull']) : '';
                $archive['pull'] = str_replace("_", "", $archive['pull']);
                $sorting = isset($atts['content_sort']) ? esc_attr($atts['content_sort']) : 'name ASC';
                $sorting = explode(" ", $sorting);
                $archive['sort'] = $sorting[1];
                $archive['sort_by'] = $sorting[0];
                $archive['sort_date'] = isset($atts['content_sort_date']) ? esc_attr($atts['content_sort_date']) : 'DESC';

                $archive['count'] = isset($atts['option_count']) ? true : false;
                $archive['hierarchical'] = isset($atts['option_hierarchical']) ? true : false;
                if ($archive['type'] == 'yearly') $archive['date_format_yearly'] = isset($atts['date_format_yearly']) ? esc_attr($atts['date_format_yearly']) : "";
                if ($archive['type'] == 'monthly') $archive['date_format_monthly'] = isset($atts['date_format_monthly']) ? esc_attr($atts['date_format_monthly']) : "";
                if ($archive['type'] == 'daily') $archive['date_format_daily'] = isset($atts['date_format_daily']) ? esc_attr($atts['date_format_daily']) : "";
                
                if ($archive['mode'] == 'list') {
                    $archive['link_style'] = isset($atts['link_style']) ? esc_attr($atts['link_style']) : '_link';
                    $archive['link_style'] = str_replace("_", "", $archive['link_style']);
                }
                else if ($archive['mode'] == 'dropdown') {
                    $archive['link_style'] = isset($atts['dropdown_style']) ? esc_attr($atts['dropdown_style']) : '_dropdown';
                    $archive['link_style'] = str_replace("_", "", $archive['link_style']);
                }
                else if ($archive['mode'] == 'cloud') {
                    $archive['link_style'] = isset($atts['cloud_style']) ? esc_attr($atts['cloud_style']) : '_link';
                    $archive['link_style'] = str_replace("_", "", $archive['link_style']);
                    $archive['layout'] = isset($atts['content_layout']) ? esc_attr($atts['content_layout']) : 'inline';
                }

                // deprecated 'size', 'color' and 'color_active'
                $archive['size'] = isset($atts['content_size']) ? esc_attr($atts['content_size']) : ''; // 'normal';
                $archive['color'] = isset($atts['content_color']) ? esc_attr($atts['content_color']) : '';
                $archive['color_active'] = isset($atts['content_color_active']) ? esc_attr($atts['content_color_active']) : '';
                // convert deprecated values
                if ( !isset($atts['new_line_icon']) && ($archive['link_style'] == "" || $archive['link_style'] == "link" || $archive['link_style'] == "dropdown") )  {
                    if ($archive['size'] != "") {
                        $font_size = "";
                        $font_weight = "400";
                        if ($archive["size"] == "bold") $font_weight = "600";
                        if ($archive["size"] == "small") $font_size = "85%";
                        if ($archive["size"] == "smaller") $font_size = "70%";
                        if ($archive["size"] == "big") $font_size = "110%";
                        if ($archive["size"] == "bigger") $font_size = "120%";
                        if ($archive["size"] == "biggest") $font_size = "220%";

                        $archive['link_style'] = "custom";
                        if ($archive['mode'] == 'list') {
                            $atts['link_font_size'] = $font_size;
                            $atts['link_font_weight'] = $font_weight;
                        }
                        if ($archive['mode'] == 'dropdown') {
                            $atts['dropdown_font_size'] = $font_size;
                            $atts['dropdown_font_weight'] = $font_weight;
                        }
                        if ($archive['mode'] == 'cloud') {
                            $atts['cloud_font_size'] = $font_size;
                            $atts['cloud_font_weight'] = $font_weight;
                        }
                    }
                    if ($archive['color'] != "") {
                        $archive['link_style'] = "custom";
                        if ($archive['mode'] == 'list') $atts['link_color'] = $archive['color'];
                        if ($archive['mode'] == 'dropdown') $atts['dropdown_color'] = $archive['color'];
                        if ($archive['mode'] == 'cloud') $atts['cloud_color'] = $archive['color'];
                    }
                    if ($archive['color_active'] != "") {
                        $archive['link_style'] = "custom";
                        if ($archive['mode'] == 'list') $atts['link_color_hover'] = $archive['color_active'];
                        if ($archive['mode'] == 'dropdown') $atts['dropdown_color_hover'] = $archive['color_active'];
                        if ($archive['mode'] == 'cloud') $atts['cloud_color_hover'] = $archive['color_active'];
                    }
                }

            }
            else {
                return helper::make_message(__("Bitte stelle den Darstellungsmodus des Archivs ein.", 'core'));
            }
        }
        else {
            return helper::make_message(__("Bitte stelle den Archivtyp ein.", 'core'));
        }
        // debug($archive);
        
        //
        // get title setup
        $title = self::get_posts_title($atts);

        //
        // get items
        $items = self::get_posts_archives($archive);
        if (count($items) == 0) {
            return helper::make_message("No archive items found");
        }

        //
        // get current url
        global $wp;
        $url = trailingslashit( home_url( $wp->request ) );
        
        //
        // functions
        if (!function_exists(__NAMESPACE__.'\get_item_selected')) {
            function get_item_selected($archive, $item, $url) {
                $sel = false;
                if ($archive['type'] == 'category' || $archive['type'] == 'post_tag') {
                    if (is_single()) {
                        if ($archive['type'] == 'category') {
                            $cats = get_the_category();
                            if ($cats) { foreach ($cats as $cat) {
                                if ($cat->term_id == get_cat_ID($item["title"])) $sel = true;
                            } }
                        }
                        if ($archive['type'] == 'post_tag') {
                            $tags = get_the_tags();
                            if ($tags) { foreach ($tags as $tag) {
                                if ($tag->name == $item["title"]) $sel = true;
                            } }
                        }
                    }
                    if ( $item['link'] == $url ||  strpos($url, $item['link'].'page/') > -1 ) {
                        $sel = true;
                    }
                }
                else {
                    if (strpos($url, $item['link']) > -1) $sel = true;
                }
                return $sel;
            }
        }
        if (!function_exists(__NAMESPACE__.'\get_item_text_size')) {
            function get_item_text_size($archive) {
                $style = "";
                if ($archive["size"] == "normal") $style .= "font-weight:400; ";
                if ($archive["size"] == "bold") $style .= "font-weight:600; ";
                if ($archive["size"] == "small") $style .= "font-weight:400;font-size:0.85em; ";
                if ($archive["size"] == "smaller") $style .= "font-weight:400;font-size:0.7em; ";
                if ($archive["size"] == "big") $style .= "font-weight:400;font-size:1.1em; ";
                if ($archive["size"] == "bigger") $style .= "font-weight:400;font-size:1.2em; ";
                if ($archive["size"] == "biggest") $style .= "font-weight:400;font-size:2.2em; ";
                return $style;
            }
        }

        //
        // render
        ob_start();

        echo '<div class="posts_archives_wrapper">';

            // render title
            if ($title != '') {
                echo self::make_posts_title($title);
            }
            // render archive
            if ($archive['mode'] == 'list') {
                // make link style
                $style = "margin-bottom: 10px; ";
                if ($archive["width"] != "") $style .= "width: ".$archive["width"]."; ";
                // render archive as list
                echo "<ul class='".$archive["pull"]."'>";
                foreach ($items as $item) {
                    // style
                    $item_class = $archive['link_style'];
                    $item_style = $style;
                    if (get_item_selected($archive, $item, $url)) {
                        if ($item_class == "link") $item_class = "link sec";
                        else if ($item_class == "link sec") $item_class = "link";
                        else if ($item_class == "button") $item_class = "button sec";
                        else if ($item_class == "button sec") $item_class = "button";
                        if (isset($atts["link_color_hover"])) $item_style .= "color: ".$atts["link_color_hover"]." !important; ";
                    }
                    if ($item_class == 'custom') $item_style = helper::make_custom_element($atts, 'link_', $item_style);
                    // content
                    $item_count = ($archive['count']) ? " (".$item["count"].")" : "";
                    $item_content = helper::make_custom_icon($atts, 'link_', $item["title"].$item_count);
                    if ($item['depth'] > 0) {
                        $item_content = "<span style='padding: 0px ".($item['depth']*15)."px;'>".$item_content."</span>";
                    }
                    echo "<li>";
                    echo    "<a href='".$item["link"]."' class='animate_fast ".$item_class."' style='".$item_style."'>".$item_content."</a>";
                    echo "</li>";
                }
                echo "</ul>";
            }
            if ($archive['mode'] == 'dropdown') {
                // make link style
                $style = "";
                // make wrapper style
                $select_class = $archive['link_style'];
                $select_style = "margin-bottom: 0px; ";
                // if ($archive["width"] != "") $select_style .= "width: ".$archive["width"]."; ";
                if ($select_class == 'custom') $select_style = helper::make_custom_element($atts, 'dropdown_', $select_style);

                // render archive as dropdown
                $id = "cat_".substr(md5(microtime()),0,10);;
                echo "<form class='".$archive["pull"]."'>";
                echo "<div class='custom-select ".$select_class."' ".($archive["width"] != "" ? "style='width:".$archive["width"].";'" : "")."><select style='".$select_style."' required name='".$id."' id='".$id."'>";
                echo "<option value=''>".__("bitte auswählen", "core")."</option>";
                foreach ($items as $item) {
                    $count = ($archive['count']) ? " (".$item["count"].")" : "";
                    $sel = get_item_selected($archive, $item, $url);
                    $selected = ($sel) ? "selected='selected'" : "";
                    $item_before = "&nbsp;&nbsp;&nbsp;";
                    if ($item['depth'] > 0) {
                        for ($i=0; $i<$item['depth']; $i++)
                            $item_before .= "&nbsp;&nbsp;&nbsp;";
                    }
                    echo "<option value='".$item["link"]."' ".$selected.">";
                    echo $item_before.$item["title"].$count;
                    echo "</option>";
                }
                echo "</select></div>";
                echo "</form>";
                // render js form change
                echo "<script type='text/javascript'>
                    /* <![CDATA[ */
                    (function() {
                        var dropdown = document.getElementById('".$id."');
                        function onCatChange() {
                            if ( dropdown.options[ dropdown.selectedIndex ].value != '' ) {
                                location.href = dropdown.options[ dropdown.selectedIndex ].value;
                            }
                        }
                        dropdown.onchange = onCatChange;
                    })();
                    /* ]]> */
                    </script>";
            }
            if ($archive['mode'] == 'cloud') {
                // make link style
                $style = "white-space: nowrap; ";
                // make wrapper style
                $style_wrap = "";
                if (isset($atts["cloud_font_size"])) {
                    $style_wrap = "font-size: ".helper::force_units($atts["cloud_font_size"], ['%','px'], '%')."; ";
                    $atts["cloud_font_size"] = null;
                }
                // calculate font sizes
                $fmin = 0.85; $fmax = 2.0;
                $min = 999999999; $max = 0;
                foreach ($items as $item) {
                    if ($item["count"] > $max) $max = $item["count"];
                    if ($item["count"] < $min) $min = $item["count"];
                }
	            $font_step = ($fmax - $fmin) / ($max - $min);
                // render archive as wordcloud
                echo "<div class='wordcloud ".$archive["pull"]."' style='".$style_wrap."'>";
                $first = true;
                foreach ($items as $item) {
                    $count = ($archive['count']) ? " (".$item["count"].")" : "";
                    $item_class = $archive['link_style'];
                    $item_style = $style."font-size: ".($fmin + ($item["count"] - $min) * $font_step)."em !important; ";
                    if (get_item_selected($archive, $item, $url)) {
                        if ($item_class == "link") $item_class = "link sec";
                        else if ($item_class == "link sec") $item_class = "link";
                        if (isset($atts["cloud_color_hover"])) $item_style .= "color: ".$atts["cloud_color_hover"]." !important; ";
                    }
                    if ($item_class == 'custom') $item_style = helper::make_custom_element($atts, 'cloud_', $item_style);

                    if (!$first) echo ($archive['layout'] == 'stack') ? "<br>" : " ";
                    echo "<a href='".$item["link"]."' class='animate_fast ".$item_class."' style='".$item_style."'>".$item["title"].$count."</a>";
                    $first = false;
                }
                echo "</div>";
            }

        echo '</div>';

		$return = ob_get_contents();
		ob_end_clean();
		return $return;
    }

    /**
     * Post Overview
     * 
     * @shortcode 'vc_posts_overview'
     */
	public static function posts_overview_sc($atts, $content) {
        // debug($atts);
        
        /**
         * Get posts
         */
        $mode = isset($atts['mode']) ? esc_attr($atts['mode']) : 'latest';
        if ($mode == 'latest') {
            $ppp = isset($atts['ppp']) ? esc_attr($atts['ppp']) : -1;
            $pt = isset($atts['pt']) ? esc_attr($atts['pt']) : 'post';

            if ( !post_type_exists($pt) ) {
                return \vc\helper::make_message( sprintf(__("Der Post Type „%s“ existiert nicht auf dieser Seite.", "core"), $pt ) );
            }

            $args = array(
                'numberposts'       => $ppp,
                'post_type'         => $pt,
                'post_status'       => 'publish',
                'suppress_filters'  => false,
            );
            if ($pt == "post") {
                $cat = isset($atts['categoryid']) ? intval(esc_attr($atts['categoryid'])) : 0;
                $tag = isset($atts['tagid']) ? intval(esc_attr($atts['tagid'])) : 0;
                $args['category__and'] = $cat;
                $args['tag__in'] = $tag;
            }
            elseif ($pt != "page") {
                if ($pt == "product") {
                    $cat = isset($atts['woo_categoryid']) ? intval(esc_attr($atts['woo_categoryid'])) : 0;
                    $tag = isset($atts['woo_tagid']) ? intval(esc_attr($atts['woo_tagid'])) : 0;
                    $cat_slug = 'product_cat';
                    $tag_slug = 'product_tag';
                }
                else {
                    $cat = isset($atts[$pt.'_categoryid']) ? intval(esc_attr($atts[$pt.'_categoryid'])) : 0;
                    $tag = isset($atts[$pt.'_tagid']) ? intval(esc_attr($atts[$pt.'_tagid'])) : 0;
                    $cat_slug = $pt.'_category';
                    $tag_slug = $pt.'_tag';
                    
                }
                
                // filter query
                // https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
                $args['tax_query'] = array();
                // categories
                if ($cat != 0) {
                    $args['tax_query'][] = array(
                        'taxonomy'      => $cat_slug,
                        'terms'         => $cat,
                        'operator'      => 'IN'
                    );
                }
                // tags
                if ($tag != 0) {
                    $args['tax_query'][] = array(
                        'taxonomy'      => $tag_slug,
                        'terms'         => $tag,
                        'operator'      => 'IN'
                    );
                }   
                // custom taxonomies
                if ( $custom_taxonomies = self::preg_match_keys("/^customtax_".$pt."_.+/", $atts) ) {
                    foreach ( (array) $custom_taxonomies as $tax_name => $tax_id ) {
                        $tax_slug = str_replace( "customtax_", "", $tax_name );
                        $tax_id = intval(esc_attr($tax_id));
                        if ( $tax_id === 0 || !taxonomy_exists($tax_slug) ) continue;
                        $args['tax_query'][] = array(
                            'taxonomy'      => $tax_slug,
                            'terms'         => $tax_id,
                            'operator'      => 'IN'
                        );
                    }
                }
                // set relation
                if ( count($args['tax_query']) > 1 ) $args['tax_query']['relation'] = 'AND';
            }

            //get sorting options and merge initial sorting mode with args for get_posts()
            $sorting_atts = self::get_sorting($atts, "sorting_");
            if ( isset($sorting_atts['sorting_mode_initial']) ) {
                $args = array_merge($args, $sorting_atts['sorting_mode_initial']);
            }

            
            //debug($args);
            $posts_array = get_posts($args);
            //debug($posts_array);
            // if (count($posts_array) == 0) return helper::make_message("No Posts for this configuration");
        }
        else if ($mode == 'fixed') {
            $posts = isset($atts['posts']) ? vc_param_group_parse_atts($atts['posts']) : '';
            // debug($posts);
            if (count($posts) > 0) {
                $posts_array = array();
                $posts_ids = array();
                foreach ($posts as $post) {
                    $pt = $post["posts_pt"];
                    if ( isset($post["posts_".$pt."_id"]) ) {
                        $posts_array[]  = get_post($post["posts_".$pt."_id"]);
                        $posts_ids[]    = $post["posts_".$pt."_id"];
                    }
                }
            }
            else return \vc\helper::make_message( __("Bitte wähle mindestens einen Post für die Postübersicht aus.", "core") );
        }
        else {
            return \vc\helper::make_message( __("Bitte wähle mindestens einen Post für die Postübersicht aus.", "core") );
        }        
        // debug($posts_array);
        
        /**
         * Get post overview setup
         */
        $post_setup_array = $posts_layout_array = array();
        
        // get posts layout
        $posts_layout = self::get_posts_layout($atts);
        if (is_array($posts_layout)) $posts_layout_array = array_merge($posts_layout_array, $posts_layout);
        else return helper::make_message($posts_layout);
        
        // get post setup
        $post_setup = self::get_post_setup($atts);
        if (is_array($post_setup)) $post_setup_array = $post_setup;
        else return helper::make_message($post_setup);
        
        // get post layout
        $post_element_layout = self::get_post_layout($atts);
        if (is_array($post_element_layout)) $posts_layout_array = array_merge($posts_layout_array, $post_element_layout);
        else return helper::make_message($post_element_layout);
        
        // get pagination layout
        $pagination_layout = self::get_pagination($atts);
        if (is_array($pagination_layout))
            $posts_layout_array = array_merge($posts_layout_array, $pagination_layout);
        //else return helper::make_message($pagination_layout);
        
        // get table setup
        $table = $posts_layout_array['posts_layout'] === 'table' ? self::get_table_setup($atts) : false;
        if ( $table ) $posts_layout_array['posts_columns'] = 1;
        
        // get title setup
        $title = self::get_posts_title($atts);
        $page_title = self::get_posts_title($atts, "page");
        
        // debug
        // debug($post_setup_array);
        // debug($posts_layout_array);
        
        /**
         * Get post preview params
         */
        if ($mode == 'latest') {
            // debug($pt);
            // debug(get_post_type_object($pt));
            $get_posttype   = isset($pt) && get_post_type_object($pt) ? get_post_type_object($pt)->label : '';
            $get_category   = isset($cat) && $cat > 0 ? get_term($cat) : null;
            $get_category   = $get_category && !is_wp_error( $get_category ) ? $get_category : 'alle';
            $get_tag        = isset($tag) && $tag > 0 ? get_term($tag) : null;
            $get_tag        = $get_tag && !is_wp_error( $get_tag ) ? $get_tag : 'alle';
            $params = array(
                'get_posttype' => $get_posttype,
                'get_category' => $get_category,
                'get_tag' => $get_tag,
            );
        }
        else if ($mode == 'fixed') {
            $params = array(
                'get_posts' => $posts_ids,
            );
        }
        $postsperpage = intval($posts_layout_array['posts_rows']) * intval($posts_layout_array['posts_columns']);
        if ($postsperpage < 0) $postsperpage = -1;
        else if ($postsperpage === 0) $postsperpage = 1;
        $params = (object) array_merge($params, array(
            'post_num' => 1,
            'post_count' => count($posts_array),
            'posts_per_page' => $postsperpage,
            'page_num' => 1,
            'page_count' => $postsperpage > 0 ? ceil(count($posts_array) / $postsperpage) : 1,
            'pagination' => ($postsperpage > 0 && $postsperpage < count($posts_array)),
            'map' => (isset($atts['enable_map']) && $atts['enable_map'] == "show") ? true : false,
            'filter' => (isset($atts[$pt.'_filter']) && $atts[$pt.'_filter'] != "") ? $atts[$pt.'_filter'] : false
        ));
        // map
        if ($params->map) {
            $loc_lat = isset($atts[$pt.'_lat']) ? esc_attr($atts[$pt.'_lat']) : 'lat';
            $loc_lon = isset($atts[$pt.'_lon']) ? esc_attr($atts[$pt.'_lon']) : 'lon';
            $params->map = array( 'lat' => $loc_lat, 'lon' => $loc_lon );
        }
        if ($params->filter) {
            $params->filter_position = explode(' ', isset($atts['filter_position']) ? esc_attr($atts['filter_position']) : "flex-start top");
        }
        // debug($params);
        
        /**
         * Build custom styles & data attributes
         */
        $id     = (isset($atts['posts_id']) && $atts['posts_id'] != "") ? $atts['posts_id'] : "slider_".uniqid();
        $class  = "posts_wrapper js";
        $data   = "data-currentpage='1'";
        $style  = $wrapper_style = $style_mobile = $pagination_style ="";
        
        // animation data & classes (for slider)
        if (isset($atts['posts_animation'])) {
            $data .= " data-animation='".$atts['posts_animation']."'";
        }
        if (isset($atts['posts_autoplay']) && $atts['posts_autoplay'] == 'enable') {
            $class .= " autoplay";
            $interval = isset($atts['posts_interval']) ? esc_attr($atts['posts_interval']) : "5";
            $data .= " data-interval='".$interval."'";
        }
        if (isset($atts['posts_loop']) && $atts['posts_loop'] == 'enable') {
            $class .= " loop";
        }
        if (isset($atts['posts_scroll_top']) && $atts['posts_scroll_top'] == 'enable') {
            $class .= " slider_scroll_top";
        }

        // margins
        $margin = 0;
        if (isset($posts_layout_array['pagination_layout']) && strpos($posts_layout_array['pagination_layout'], '_side') > 0) {
            // debug($posts_layout_array);
            if ($posts_layout_array['arrows_overlap'] == "") {
                $margin = intval($posts_layout_array["arrows_size"]) + (2 * intval($posts_layout_array["arrows_padding_lr"]));
            }
        }
        if (isset($post_setup["mode"]) && $post_setup["mode"] === "template") {
            $ignore_gutter = isset($post_setup["atts"]["options"]) && $post_setup["atts"]["options"] === "ignore_gutter" ? true : false;
            if ($ignore_gutter && $posts_layout_array['posts_layout'] != 'vertical') {
                $m  = intval($posts_layout_array["posts_padding"]) / 2;
                $margin -= $m;
            }
        }
        if ($margin != 0) {
            $pagination_style = "margin-left: ".$margin."px; margin-right: ".$margin."px; ";
            $style .= $pagination_style;
        }
        
        // height
        $height = isset($atts['posts_height']) ? esc_attr($atts['posts_height']) : "auto";
        if ($height == 'custom') {
            $height = isset($atts['posts_height_custom']) ? helper::force_units( esc_attr($atts['posts_height_custom']), ['px','em','vh'], 'px') : "500px";
            $style .= "height: ".$height."; ";
            if ( isset($atts['posts_height_custom_mobile']) ) {
                $height_mobile = helper::force_units( esc_attr($atts['posts_height_custom_mobile']), ['px','em','vh'], 'px'); 
                $style_mobile .= "height: ".$height_mobile.";"; 
            }
        }
        $data .= " data-height='".$height."'";
        if ( isset($height_mobile) ) $data .= " data-height_mobile='".$height_mobile."'";
        
        // margin bottom
        $margin_bottom = isset($atts['posts_margin_bottom']) && !empty($atts['posts_margin_bottom']) ? $atts['posts_margin_bottom'] : '30px';
        $wrapper_style .= "margin-bottom: ".helper::force_units($margin_bottom);
        
        // table
        if ( $table ) {
            $class .= " posts_table";
            $data .= " data-rows='".$postsperpage."'";
        }
        
        /**
         * Custom css
         */
        $custom_css = "#".$id." { ".$wrapper_style." } #".$id." > .results_wrapper { ".$style." } ";
        if ( !empty($style_mobile) ) $custom_css .= "@media (max-width: var(grid_md)) { #".$id." > .results_wrapper { ".$style_mobile." } } ";
        \enqueue::add_custom_style( $custom_css );

        if ( !$table ) {
            self::make_post_preview_styles( "#$id", $posts_layout_array );
        }
        
        /**
         * Render
        */
        ob_start();
        
        // top sorting
        if (isset($sorting_atts) && $sorting_atts['sorting_dropdown_frontend'] == "show" && isset($sorting_atts['sorting_position']) && $sorting_atts['sorting_position'][1] == "top") {
            echo self::make_posts_sort_dropdown($sorting_atts, 'sorting');
        }
        
        // top filter
        if ($params->filter && $params->filter_position[1] == "top") {
            $dropdown = maps::makeFilterDropdown($atts, 'filter_');
            \enqueue::add_custom_style($dropdown["style"]);
            echo $dropdown["content"];
        }

        // top map
        if ($params->map && !isset($atts['position'])) {
            echo maps::maps_sc($atts, $posts_array);
        }

        // container
        echo "<div id='".$id."' class='".$class."' ".$data.">";
        // echo "<div id='".$id."' class='posts_wrapper js loop autoplay' data-currentpage='1' data-animation='slide' data-interval='5'>";
        
        // overall title
        if ($title != '') {
            echo self::make_posts_title($title, $params);
        }

        // top pagination
        if ($params->pagination && isset($posts_layout_array['pagination_layout'])) {
            if ($posts_layout_array['pagination_layout'] == 'top' || 
                $posts_layout_array['pagination_layout'] == 'top_side' || 
                $posts_layout_array['pagination_layout'] == 'only_top') {
                echo self::make_posts_pagination($posts_layout_array, $params->page_count, $pagination_style);
            }
        }
        
        // pages wrapper
        echo "<div class='results_wrapper ".( $table ? "table_wrapper" : "" )."' data-ppp='".$postsperpage."'>";
        
        // page
        echo "<div class='result_wrapper' data-page='".$params->page_num."'>";
        
        // page title
        if ($page_title != "" && $page_title['pos'] == 'top') echo self::make_posts_title($page_title, $params);
        
        // table head
        if ( $table ) echo $table['thead'];
        
        // cycle through posts
        $params->first_post = true;
        for ( $i = 0; $i < $params->post_count; $i++ ) {
            
            // new page
            if ( $i == ( $params->posts_per_page * $params->page_num ) ) {
                if ( $table ) echo $table['tfoot'];
                if ($page_title != "" && $page_title['pos'] == 'bottom') echo self::make_posts_title($page_title, $params);
                $params->page_num++;
                echo "</div><div class='result_wrapper' data-page='".$params->page_num."'>";
                if ($page_title != "" && $page_title['pos'] == 'top') echo self::make_posts_title($page_title, $params);
                if ( $table ) echo $table['thead'];
                $params->first_post = true;
            }
            
            // make post preview item
            $params->post_num = $i;
            
            if ( $table ) {
                echo self::make_post_table_row($posts_array[$i], $table['fields'], $params);
            }
            else {
                echo self::make_post_preview($posts_array[$i], $post_setup_array, $posts_layout_array, $params);
            }
            $params->first_post = false;
        }
        
        // table bottom
        if ( $table ) echo $table['tfoot'];
        
        // page bottom title
        if ($page_title != "" && $page_title['pos'] == 'bottom') echo self::make_posts_title($page_title, $params);
        
        // end of page
        echo "</div>";
        
        // end of pages wrapper
        echo "</div>";
        
        // bottom pagination
        if ($params->pagination && isset($posts_layout_array['pagination_layout'])) {
            if ($posts_layout_array['pagination_layout'] == 'bottom' || 
                $posts_layout_array['pagination_layout'] == 'bottom_side' ||
                $posts_layout_array['pagination_layout'] == 'none_side' ||
                $posts_layout_array['pagination_layout'] == 'only_bottom') {
                echo self::make_posts_pagination($posts_layout_array, $params->page_count, $pagination_style);
            }
        }

        // end of container
        echo "</div>";

        // bottom map
        if ($params->map && isset($atts['position']) && $atts['position'] == "bottom") {
            echo maps::maps_sc($atts, $posts_array);
        }

        // bottom filter
        if ($params->filter && $params->filter_position[1] == "bottom") {
            $dropdown = maps::makeFilterDropdown($atts, 'filter_');
            \enqueue::add_custom_style($dropdown["style"]);
            echo $dropdown["content"];
        }

        // bottom sorting
        if (isset($sorting_atts) && $sorting_atts['sorting_dropdown_frontend'] == "show" && isset($sorting_atts['sorting_position']) && $sorting_atts['sorting_position'][1] == "bottom") {
            echo self::make_posts_sort_dropdown($sorting_atts, 'sorting');
        }

		$return = ob_get_contents();
		ob_end_clean();
		return $return;
    }

    /**
     * Post Overview of found posts (archive- & search-template)
     * 
     * @shortcode 'vc_posts_tp'
     */
	public static function posts_template_sc($atts, $content) {
        // debug($content);
        
        global $wp_query;
    
        // Check advanced search settings
        $settings       = \basics::get_setting(array('site', 'advanced_search'));
        $live_search    = $settings['live_search'] === 'true' && is_search() ? true : false;
        $relevance      = $settings['relevance'] === 'true' && is_search() ? true : false;

        // fill the post array
        $posts_array = isset($wp_query->posts) ? (array) $wp_query->posts : (array) $wp_query->get_posts();

        // debug($posts_array);
        if ( count($posts_array) === 0 && !$live_search ) {
            return helper::make_message(
                is_search() ? (
                    sprintf(
                        __("Es konnten leider keine Suchergebnisse für „%s“ gefunden werden. Bitte versuche es mit einem anderen Begriff.", "core"),
                        get_search_query()
                    )
                ) : (
                    __("Es konnten leider keine Beiträge gefunden werden.", "core")
                )
            );
        }

        /**
         * @since 1.3.0: Default sorting
         */
        if (
            empty($wp_query->get('orderby'))
            && isset($atts['search_sorting_mode_initial'])
            && !empty($atts['search_sorting_mode_initial'])
        ) {

            list( $orderby, $order ) = explode( ' ', $atts['search_sorting_mode_initial'], 2 );
            
            $wp_query->set('orderby', $orderby);
            $wp_query->set('order', $order);

            $posts_array = (array) $wp_query->get_posts();
        }
        
        // deprecated
        // $show_empty_search = isset($atts['show_empty_search']) ? true : false;
        // if ( is_search() && empty(get_search_query()) && !$show_empty_search ) return false;
        
        /*
            get post overview setup
        */
        $post_setup_array = $posts_layout_array = array();
        
        // get posts layout
        $posts_layout = self::get_posts_layout($atts);
        if (is_array($posts_layout)) $posts_layout_array = array_merge($posts_layout_array, $posts_layout);
        else return helper::make_message($posts_layout);
        
        // debug($atts);
        // get post setup
        $post_setup = self::get_post_setup($atts);
        if (is_array($post_setup)) $post_setup_array = $post_setup;
        else return helper::make_message($post_setup);

        // get post layout
        $post_element_layout = self::get_post_layout($atts);
        if (is_array($post_element_layout)) $posts_layout_array = array_merge($posts_layout_array, $post_element_layout);
        else return helper::make_message($post_element_layout);
        
        // get pagination layout
        $pagination_layout = self::get_pagination($atts);
        if (is_array($pagination_layout))
            $posts_layout_array = array_merge($posts_layout_array, $pagination_layout);
        //else return helper::make_message($pagination_layout);
        
        // get table setup
        $table = $posts_layout_array['posts_layout'] === 'table' ? self::get_table_setup($atts, true) : false;
        if ( $table ) $posts_layout_array['posts_columns'] = 1;
        
        // get title setup
        $title = self::get_posts_title($atts);
        $page_title = self::get_posts_title($atts, "page");
        
        // get sorting setup
        $search_sorting_atts = self::get_sorting($atts, 'search_sorting_');
        

        /**
         * debug
         */
        // debug($atts);
        // debug($wp_query);
        // debug($post_setup_array);
        // debug($posts_layout_array);

        /**
         * make post preview params array
         */
        $params = (object)array(
            'search_query'      => get_search_query(),
            'get_posttype'      => helper::make_posttype_string($wp_query, null),
            'get_category'      => helper::make_category_string($wp_query, null),
            'get_tag'           => helper::make_tag_string($wp_query, null),
            'post_num'          => 1,
            'post_count'        => $wp_query->found_posts,
            'posts_per_page'    => $wp_query->query_vars['posts_per_page'],
            'page_num'          => $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1,
            'page_count'        => ($wp_query->max_num_pages > 0) ? $wp_query->max_num_pages : 1,
            'pagination'        => ($wp_query->query_vars['posts_per_page'] < $wp_query->found_posts)
        );

        $id = "posts_".uniqid();
        $style = $pagination_style = "";
        
        
        // margin
        $margin = 0;
        if (isset($posts_layout_array['pagination_layout']) && strpos($posts_layout_array['pagination_layout'], '_side') > 0) {
            // debug($posts_layout_array);
            if ($posts_layout_array['arrows_overlap'] == "") {
                $margin = intval($posts_layout_array["arrows_size"]) + (2 * intval($posts_layout_array["arrows_padding_lr"]));
            }
        }
        if (isset($post_setup["mode"]) && $post_setup["mode"] === "template") {
            $ignore_gutter = isset($post_setup["atts"]["options"]) && $post_setup["atts"]["options"] === "ignore_gutter" ? true : false;
            if ($ignore_gutter && $posts_layout_array['posts_layout'] != 'vertical') {
                $m  = intval($posts_layout_array["posts_padding"]) / 2;
                $margin -= $m;
            }
        }
        if ($margin != 0) {
            $pagination_style = "margin-left: ".$margin."px; margin-right: ".$margin."px; ";
            $style .= $pagination_style;
            $style .= "width: calc(100% - 2 * ".$margin."px);";
        }
        
        /**
         * Custom css
         */
        $custom_css = "#".$id." > .result_wrapper { ".$style." }";
        $custom_css .= "#".$id." > .pgn_arrows { height: 100%; } ";
        \enqueue::add_custom_style( $custom_css );

        if ( !$table ) {
            self::make_post_preview_styles( "#$id", $posts_layout_array );
        }

        $posts_atts = array();
        if ($live_search) {
            $posts_atts = array(
                "live-search='true'",
                "data-post-setup='".htmlentities(json_encode($post_setup_array, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE))."'", // set json encoding flags because html is messing up the data-attribute
                "data-post-layout='".htmlentities(json_encode($posts_layout_array))."'",
                "data-post-params='".htmlentities(json_encode($params))."'",
                "data-post-table='".htmlentities(json_encode(
                    isset($table['fields']) ? $table['fields'] : false
                ))."'",
                "data-livesearch-labels='".json_encode(
                    array(
                        'no_result' => isset($atts['live_search_label_no_result']) ? $atts['live_search_label_no_result'] : __("Es konnten leider keine Suchergebnisse gefunden werden. Bitte versuche es mit einem anderen Begriff.", 'core')
                    )
                )."'",
            );
        }
        

        /**
         * Render
         */
        ob_start();
        
        // top sorting dropdown
        if ($search_sorting_atts['search_sorting_dropdown_frontend'] === "show" && isset($search_sorting_atts['search_sorting_position']) && $search_sorting_atts['search_sorting_position'][1] == "top") {
            echo self::make_posts_sort_dropdown($search_sorting_atts, 'search_sorting_', true);
        }
        
        // container
        echo "<div id='$id' class='posts_wrapper ".( $table ? "table_wrapper" : "" ) ."' ".implode(" ", $posts_atts)."'>";

        // overall title
        if ($title != '') echo self::make_posts_title($title, $params);

        // top pagination
        if ($params->pagination && isset($posts_layout_array['pagination_layout'])) {
            if ($posts_layout_array['pagination_layout'] == 'top' || 
                $posts_layout_array['pagination_layout'] == 'top_side' || 
                $posts_layout_array['pagination_layout'] == 'only_top') {
                echo self::make_posts_pagination($posts_layout_array, -1, $pagination_style);
            }
        }
        // debug($atts);
        // wrapper
        echo "<div class='result_wrapper'>";
        
        // title top
        if ($page_title != "" && $page_title['pos'] == 'top') echo self::make_posts_title($page_title, $params);
        
        // table head
        if ( $table ) echo $table['thead'];
        
        // cycle through posts
        $params->first_post = true;
        if ( count($posts_array) > 0 ) {
            for ($i=0; $i<count($posts_array); $i++) {
    
                $params->post_num = (($params->page_num - 1) * $params->posts_per_page) + $i + 1;
                
                if ( $table ) {
                    echo self::make_post_table_row($posts_array[$i], $table['fields'], $params);
                }
                else {
                    echo self::make_post_preview($posts_array[$i], $post_setup_array, $posts_layout_array, $params);
                }
                $params->first_post = false;
            }
        }
        else {
            echo helper::make_message(sprintf(
                __("Es konnten leider keine Suchergebnisse für „%s“ gefunden werden. Bitte versuche es mit einem anderen Begriff.", "core"),
                esc_attr($params->search_query)
            ));
        }
        
        // table bottom
        if ( $table ) echo $table['tfoot'];
        
        // title bottom
        if ($page_title != "" && $page_title['pos'] == 'bottom') echo self::make_posts_title($page_title, $params);

        // end of wrapper
        echo "</div>";
        
        // bottom pagination
        if ($params->pagination && isset($posts_layout_array['pagination_layout'])) {
            if ($posts_layout_array['pagination_layout'] == 'bottom' || 
                $posts_layout_array['pagination_layout'] == 'bottom_side' ||
                $posts_layout_array['pagination_layout'] == 'none_side' ||
                $posts_layout_array['pagination_layout'] == 'only_bottom') {
                echo self::make_posts_pagination($posts_layout_array, -1, $pagination_style);
            }
        }
        
        // end of container
        echo "</div>";
        
        // load more button for live search
        if ($live_search) {
            echo self::make_load_more_button($atts, 'load_more_button');
        }

        // bottom sorting dropdown
        if ($search_sorting_atts['search_sorting_dropdown_frontend'] === "show" && isset($search_sorting_atts['search_sorting_position']) && $search_sorting_atts['search_sorting_position'][1] == "bottom") {
            echo self::make_posts_sort_dropdown($search_sorting_atts, 'search_sorting_', true);
        }

		$return = ob_get_contents();
		ob_end_clean();
		return $return;
    }

    /**
     * Query details (archive- & search-template)
     * 
     * @shortcode 'vc_posts_details_tp'
     * @deprecated since 0.8.1
     */
    public static function posts_details_sc($atts, $content) {
        // debug($atts);

        // get setup
        $title = self::get_posts_title($atts, "details");
        $details_search = isset($atts['details_search']) ? true : false;
        $params = (object)array(
            'search_query' => "",
            'get_posttype' => "alle",
            'get_category' => "alle",
            'get_tag' => "alle",
            'post_num' => 1,
            'post_count' => 0,
            'posts_per_page' => -1,
            'page_num' => 1,
            'page_count' => 1,
        );

        //
        // make post preview params array
        global $wp_query;
        if (!empty($wp_query->query_vars)) {
            $params = (object)array(
                'search_query' => get_search_query(),
                'get_posttype' => helper::make_posttype_string($wp_query, null),
                'get_category' => helper::make_category_string($wp_query, null),
                'get_tag' => helper::make_tag_string($wp_query, null),
                'post_num' => 1,
                'post_count' => $wp_query->found_posts,
                'posts_per_page' => isset($wp_query->query_vars['posts_per_page']) ? $wp_query->query_vars['posts_per_page'] : -1,
                'page_num' => isset($wp_query->query_vars['paged']) ? $wp_query->query_vars['paged'] : 1,
                'page_count' => ($wp_query->max_num_pages > 0) ? $wp_query->max_num_pages : 1,
            );
        }
        // debug($params);

        //
        // render
        ob_start();

        echo "<div class='posts_wrapper'>";
        if (!$details_search || (is_search() && $details_search)) {
            // render title
            if ($title != '') {
                echo self::make_posts_title($title, $params);
            }
        }
        echo "</div>";

		$return = ob_get_contents();
		ob_end_clean();
		return $return;
        
    }

    /**
     * Post Elements (in single-templates)
     * 
     * @shortcode 'vc_post_tp'
     * @deprecated since 0.8.1
     */
    public static function post_template_sc($atts, $content) {
        // debug($atts);
        
        // get setup arrays
        $post_setup_array   = array();
        $posts_layout_array = array(
            'posts_layout' => 'vertical',
            'posts_padding' => 0,
            'posts_rows' => 1,
            'posts_columns' => 1,
        );
        // get $post_setup_array
        $post_setup = self::get_post_setup($atts);
        if (is_array($post_setup)) $post_setup_array = $post_setup;
        else return helper::make_message($post_setup);
        // get $posts_layout_array
        $post_element_layout = self::get_post_layout($atts);
        if (is_array($post_element_layout)) $posts_layout_array = array_merge($posts_layout_array, $post_element_layout);
        else return helper::make_message($post_element_layout);

        // debug($post_setup_array);
        // debug($posts_layout_array);
        
        $selector               = uniqid("post_");
        $wp_post                = get_post( get_the_ID() );
        $post_preview_params    = (object) array(
            'post_num' => 1,
            'post_count' => 1,
            'first_post' => true,
        );

        // enqueue stylesheet
        self::make_post_preview_styles( ".$selector", $posts_layout_array );

        // render
        ob_start();
        
        echo "<div class='post $selector'>".
            self::make_post_preview($wp_post, $post_setup_array, $posts_layout_array, $post_preview_params).
        "</div>";

		$return = ob_get_contents();
		ob_end_clean();
		return $return;
    }

    /**
     * =================================================================
     *                          Getter
     * =================================================================
     */
    public static function get_posts_archives($archive) {

        $result = array();

        if ($archive['type'] == 'category' || $archive['type'] == 'post_tag') {

            if (!function_exists(__NAMESPACE__.'\get_archives_items')) {
                function get_archives_items($archive, $cat=0, $depth=0) {
                    $parent = ($archive['hierarchical']) ? $cat : '';
                    $result = array();
                    $resultraw = get_terms( array(
                        'taxonomy' => $archive['tax'],
                        'order' => $archive['sort'],
                        'orderby' => $archive['sort_by'],
                        'hide_empty' => true,
                        'parent' => $parent,
                    ) );
                    if ($resultraw) {
                        foreach ($resultraw as $r) {
                            if ( is_object($r) ) {
                                $result[] = array(
                                    'title' => $r->name,
                                    'count' => $r->count,
                                    'link'  => get_tag_link($r->term_id),
                                    'depth' => $depth,
                                );
                                if ($archive['hierarchical']) $result = array_merge($result, get_archives_items($archive, $r->term_id, ($depth+1)));
                            }
                        }
                    }
                    return $result;
                }
            }
            $archive['tax'] = $archive['type'];
            if ($archive['post_type'] != 'post') {
                if ($archive['type'] == 'category') $archive['tax'] = helper::get_category_slug($archive['post_type']);
                if ($archive['type'] == 'post_tag') $archive['tax'] = helper::get_tag_slug($archive['post_type']);
            }
            $result = get_archives_items($archive, 0, 0);
            // debug($result);
        }
        else {
            $resultraw = wp_get_archives(array(
                'post_type' 	  => $archive['post_type'],
                'type'            => $archive['type'], 
                'order'           => $archive['sort_date'],
                'show_post_count' => true,
                'format'          => 'custom', 
                // 'before'          =>"|",
                'after'           => "|",
                'echo'            => false, 
            ));
            if ($resultraw) {
                $resultraw = explode('|', $resultraw);
                array_pop($resultraw);

                if (!function_exists(__NAMESPACE__.'\get_title_from_result')) {
                    function get_title_from_result($link) {
                        $clean_title = $link;
                        $clean_title = explode('>', $clean_title);
                        $clean_title = explode('<', $clean_title[1]);
                        return $clean_title[0];
                    }
                }
                if (!function_exists(__NAMESPACE__.'\get_date_from_title')) {
                    function get_date_from_title($title) {
                        global $wp_locale;                  
                        $d = "01"; $m = "01"; $y = $title;
                        foreach ($wp_locale->month as $key => $value) {
                            if (strpos($title, $value) > -1) {
                                $m = $key;
                                $tmp = explode($value, $title);
                                if (count($tmp) == 2) {
                                    $d = preg_replace("/[^0-9]/", "", $tmp[0]);
                                    if ($d == "") $d = "01";
                                    $y = preg_replace("/[^0-9]/", "", $tmp[1]);
                                }
                                break;
                            }
                        }
                        $clean_date = $y."-".$m."-".$d;
                        return $clean_date;
                    }
                }
                if (!function_exists(__NAMESPACE__.'\get_count_from_result')) {
                    function get_count_from_result($link) {
                        $clean_count = $link;
                        $clean_count = explode('</a>', $clean_count);
                        $clean_count = explode('(', $clean_count[1]);
                        $clean_count = explode(')', $clean_count[1]);
                        return $clean_count[0];
                    }
                }
                if (!function_exists(__NAMESPACE__.'\get_link_from_result')) {
                    function get_link_from_result($link) {
                        $clean_link = $link;
                        $clean_link = explode('href=', $clean_link);
                        $clean_link = explode('>', $clean_link[1]);
                        $clean_link = str_replace(array("'",'"'), '', $clean_link[0]);
                        $clean_link = explode(' ', $clean_link);
                        return $clean_link[0];
                    }
                }

                foreach ($resultraw as $r) {
                    $res = array(
                        'title' => get_title_from_result($r),
                        'count' => get_count_from_result($r),
                        'link'  => get_link_from_result($r),
                        'depth' => 0,
                    );
                    if ($archive['date_format_'.$archive['type']] != "") {
                        $res['title'] = mysql2date($archive['date_format_'.$archive['type']], get_date_from_title($res['title']));
                    }
                    $result[] = $res;
                }
            }
        }
        return $result;
    }
    public static function get_posts_title($atts, $pre="") {
        if ($pre != "" && !strpos($pre, "_")) $pre .= "_";
        $title = isset($atts[$pre.'title']) ? esc_attr($atts[$pre.'title']) : '';
        if ($title != '') {
            $title = array();
            // debug(str_replace(array('<br />','<br>'), '', $atts[$pre.'title']));
            $title['text'] = nl2br(str_replace(array('<br />','<br>'), '', $atts[$pre.'title']));
            $title['pos'] = isset($atts[$pre.'title_layout']) ? esc_attr($atts[$pre.'title_layout']) : 'top';
            $title['pull'] = isset($atts[$pre.'title_pull']) ? esc_attr($atts[$pre.'title_pull']) : '';
            $title['pull'] = str_replace("_", "", $title['pull']);
            $title['size'] = isset($atts[$pre.'title_size']) ? esc_attr($atts[$pre.'title_size']) : 'normal';
            $title['weight'] = isset($atts[$pre.'title_weight']) ? esc_attr($atts[$pre.'title_weight']) : '';
            $title['color'] = isset($atts[$pre.'title_color']) ? helper::process_color(helper::get_color($atts, $pre.'title_', '', false)) : '';
            // $title['color'] = isset($atts[$pre.'title_color']) ? esc_attr($atts[$pre.'title_color']) : '';
        }
        return $title;
    }
    public static function get_post_setup($atts) {
        $post_setup_mode = isset($atts['post_setup_mode']) ? $atts['post_setup_mode'] : 'manual';
        if ($post_setup_mode == 'template') {
            // debug($atts);
            $post_template = isset($atts['post_template']) ? $atts['post_template'] : '';
            if ($post_template != "") {
                return array(
                    'mode' => 'template',
                    'slug' => $post_template,
                    'atts' => array(
                        'dynamic_content' => isset($atts['dynamic_post_content']) ? $atts['dynamic_post_content'] : '',
                        'options' => isset($atts['post_template_options']) ? $atts['post_template_options'] : '',
                    ),
                );
            }
            else {
                return __("Bitte wähle das zu verwendene Template aus.", 'core');
            }
        }
        else if ($post_setup_mode == 'manual') {
            $post_setup = isset($atts['post_setup']) ? vc_param_group_parse_atts($atts['post_setup']) : '';
            // debug($post_setup);
            if (is_array($post_setup) && count($post_setup) > 0) {
                $post_setup_array = array();
                foreach ($post_setup as $post_element) {
                    // debug($post_element);
                    if (isset($post_element["post_element"]) && $post_element["post_element"] != '') {
                        $element_setup = array(
                            'post_element' => $post_element["post_element"],
                            'pull' => isset($post_element['pull']) ? esc_attr($post_element['pull']) : ''
                        );
                        $element_setup['pull'] = str_replace("_", "", $element_setup['pull']);
                        if ($post_element["post_element"] == 'title') {
                            $element_setup['title_size'] = isset($post_element['title_size']) ? esc_attr($post_element['title_size']) : 'normal';
                            $element_setup['text_color'] = isset($post_element['text_color']) ? helper::process_color(helper::get_color($post_element, 'text_', '', '')) : '';
                            // $element_setup['text_color'] = isset($post_element['text_color']) ? esc_attr($post_element['text_color']) : '';
                            $element_setup['title_versal'] = isset($post_element['title_versal']) ? esc_attr($post_element['title_versal']) : false;
                        }
                        if ($post_element["post_element"] == 'site_title') {
                            $element_setup['title_size'] = isset($post_element['title_size']) ? esc_attr($post_element['title_size']) : 'normal';
                            $element_setup['text_color'] = isset($post_element['text_color']) ? helper::process_color(helper::get_color($post_element, 'text_', '', '')) : '';
                            // $element_setup['text_color'] = isset($post_element['text_color']) ? esc_attr($post_element['text_color']) : '';
                            $element_setup['title_versal'] = isset($post_element['title_versal']) ? esc_attr($post_element['title_versal']) : false;
                        }
                        if ($post_element["post_element"] == 'image') {
                            $element_setup['content_width'] = isset($post_element['content_width']) ? helper::force_units(esc_attr($post_element['content_width']), ['px','%'], '%') : '100%';
                            $element_setup['link_to'] = isset($post_element['link_to']) ? esc_attr($post_element['link_to']) : false;
                        }
                        if ($post_element["post_element"] == 'content') {
                            $element_setup['text_size'] = isset($post_element['text_size']) ? esc_attr($post_element['text_size']) : 'normal';
                            $element_setup['text_color'] = isset($post_element['text_color']) ? helper::process_color(helper::get_color($post_element, 'text_', '', '')) : '';
                            // $element_setup['text_color'] = isset($post_element['text_color']) ? esc_attr($post_element['text_color']) : '';
                            $element_setup['content_length'] = isset($post_element['content_length']) ? esc_attr($post_element['content_length']) : 200;
                        }
                        if ($post_element["post_element"] == 'author' || 
                            $post_element["post_element"] == 'categories' ||
                            $post_element["post_element"] == 'tags' ||
                            $post_element["post_element"] == 'text') {
                            $element_setup['text_size'] = isset($post_element['text_size']) ? esc_attr($post_element['text_size']) : 'normal';
                            $element_setup['text_color'] = isset($post_element['text_color']) ? helper::process_color(helper::get_color($post_element, 'text_', '', '')) : '';
                            // $element_setup['text_color'] = isset($post_element['text_color']) ? esc_attr($post_element['text_color']) : '';
                            $element_setup['link_to'] = isset($post_element['link_to']) ? esc_attr($post_element['link_to']) : false;
                        }
                        if ($post_element["post_element"] == 'date') {
                            $element_setup['text_size'] = isset($post_element['text_size']) ? esc_attr($post_element['text_size']) : 'normal';
                            $element_setup['text_color'] = isset($post_element['text_color']) ? helper::process_color(helper::get_color($post_element, 'text_', '', '')) : '';
                            // $element_setup['text_color'] = isset($post_element['text_color']) ? esc_attr($post_element['text_color']) : '';
                            $element_setup['date_format'] = isset($post_element['date_format']) ? esc_attr($post_element['date_format']) : get_option('date_format');
                        }
                        if ($post_element["post_element"] == 'link' ||
                            $post_element["post_element"] == 'cart' ||
                            $post_element["post_element"] == 'woo_ajax') {
                            $element_setup['content_width'] = isset($post_element['content_width']) ? helper::force_units(esc_attr($post_element['content_width']), ['px','%'], '%') : '100%';
                            $pre = $post_element["post_element"];
                            $element_setup[$pre.'_style'] = isset($post_element[$pre.'_style']) ? esc_attr($post_element[$pre.'_style']) : '_link';
                            $element_setup[$pre.'_style'] = str_replace("_", "", $element_setup[$pre.'_style']);
                            if ($element_setup[$pre.'_style'] == 'custom') $element_setup['custom_style'] = helper::get_custom_element_setup($post_element, $pre.'_');
                            // make link content & icon
                            $link_text = isset($post_element[$pre.'_text']) ? nl2br($post_element[$pre.'_text']) : '';
                            $link_content = helper::make_custom_icon($post_element, $pre.'_', $link_text);
                            $element_setup[$pre.'_content'] = $link_content;
                            
                            if ($pre === 'woo_ajax') {
                                $element_setup[$pre.'_redirect'] = isset($post_element[$pre.'_redirect']) ? esc_attr($post_element[$pre.'_redirect']) : 'default';
                                $element_setup[$pre.'_not_twice'] = isset($post_element[$pre.'_not_twice']) ? esc_attr($post_element[$pre.'_not_twice']) : 'false';
                                $element_setup[$pre.'_clear'] = isset($post_element[$pre.'_clear']) ? esc_attr($post_element[$pre.'_clear']) : 'false';
                            }
                        }
                        if ($post_element["post_element"] == 'price') {
                            // debug();
                        }
                        if ($post_element["post_element"] == 'empty') {
                            $element_setup['empty_size'] = isset($post_element['empty_size']) ? esc_attr($post_element['empty_size']) : 20;
                            $element_setup['empty_size_lg'] = isset($post_element['empty_size_lg']) ? (int) str_replace('%', '', esc_attr($post_element['empty_size_lg']))/100 : 1;
                            $element_setup['empty_size_md'] = isset($post_element['empty_size_md']) ? (int) str_replace('%', '', esc_attr($post_element['empty_size_md']))/100 : 1;
                            $element_setup['empty_size_sm'] = isset($post_element['empty_size_sm']) ? (int) str_replace('%', '', esc_attr($post_element['empty_size_sm']))/100 : 1;
                            $element_setup['empty_size_xs'] = isset($post_element['empty_size_xs']) ? (int) str_replace('%', '', esc_attr($post_element['empty_size_xs']))/100 : 1;
                            $element_setup['empty_size'] = helper::force_units($element_setup['empty_size']);
                        }
                        if ($post_element["post_element"] == 'text') {
                            $element_setup['text_content'] = isset($post_element['text_content']) ? nl2br($post_element['text_content']) : '';
                        }
                        if ($post_element["post_element"] == 'seperator') {
                            $element_setup['sep_size'] = isset($post_element['sep_size']) ? helper::force_units(esc_attr($post_element['sep_size']), ['px','%'], '%') : '100%';
                            $element_setup['sep_width'] = isset($post_element['sep_width']) ? helper::force_units(esc_attr($post_element['sep_width'])) : '5px';

                            $element_setup['sep_color'] = isset($post_element['sep_color']) ? helper::process_color(helper::get_color($post_element, 'sep_', '', 'transparent')) : 'transparent';
                            // $element_setup['sep_color'] = isset($post_element['sep_color']) ? esc_attr($post_element['sep_color']) : '#444444';
                            $element_setup['sep_style'] = isset($post_element['sep_style']) ? esc_attr($post_element['sep_style']) : 'solid';
                        }

                        $post_setup_array[] = $element_setup;
                    }
                }
                if (count($post_setup_array) > 0) 
                    return $post_setup_array;
            }
        }
        
        if ( isset($atts['posts_layout']) && $atts['posts_layout'] === 'table' ) {
            return [];
        }   
        return __("Bitte stelle das Layout der Posts ein.", 'core');
    }
    public static function get_posts_layout($atts) {
        $posts_layout = isset($atts['posts_layout']) ? esc_attr($atts['posts_layout']) : 'grid';
        // early exit
        if ( empty($posts_layout) ) return __("Bitte stelle das Layout der Postübersicht ein.", 'core');
        
        $posts_layout_array = array();
        $posts_layout_array['posts_layout']     = $posts_layout;
        $posts_layout_array['posts_padding']    = isset($atts['posts_padding']) ? helper::force_units(esc_attr($atts['posts_padding'])) : '40px';
        $posts_layout_array['posts_rows']       = isset($atts['posts_rows']) ? intval(esc_attr($atts['posts_rows'])) : 5;
        $posts_layout_array['posts_columns']    = isset($atts['posts_columns']) ? intval(esc_attr($atts['posts_columns'])) : 5;

        if ($posts_layout_array['posts_layout'] == 'horizontal') {
            $posts_layout_array['posts_rows'] = 1;
        }
        else if ($posts_layout_array['posts_layout'] == 'vertical') {
            $posts_layout_array['posts_columns'] = 1;
        }
        else if ($posts_layout_array['posts_layout'] == 'single') {
            $posts_layout_array['posts_rows'] = 1;
            $posts_layout_array['posts_columns'] = 1;
            $posts_layout_array['posts_padding'] = "0px";
        }

        // min columns
        // if ($posts_layout_array['posts_rows'] < 1) $posts_layout_array['posts_rows'] = 1;
        if ($posts_layout_array['posts_columns'] < 1) $posts_layout_array['posts_columns'] = 1;

        // responsive columns
        if ( $posts_layout_array['posts_layout'] == 'vertical' || $posts_layout_array['posts_layout'] == 'single' ) {
            $posts_layout_array['posts_columns_lg'] = 1;
            $posts_layout_array['posts_columns_md'] = 1;
            $posts_layout_array['posts_columns_sm'] = 1;
        }
        else if ( isset($atts["responsive_breaks"]) && $atts["responsive_breaks"] === "manual" ) {
            $posts_layout_array['posts_columns_lg'] = isset($atts["post_columns_lg"]) ? intval(esc_attr($atts["post_columns_lg"])) : 3;
            $posts_layout_array['posts_columns_md'] = isset($atts["post_columns_md"]) ? intval(esc_attr($atts["post_columns_md"])) : 2;
            $posts_layout_array['posts_columns_sm'] = isset($atts["post_columns_sm"]) ? intval(esc_attr($atts["post_columns_sm"])) : 1;
            $posts_layout_array['posts_padding_lg'] = isset($atts['posts_padding_lg']) ? helper::force_units(esc_attr($atts['posts_padding_lg'])) : '20px';
            $posts_layout_array['posts_padding_md'] = isset($atts['posts_padding_md']) ? helper::force_units(esc_attr($atts['posts_padding_md'])) : '15px';
            $posts_layout_array['posts_padding_sm'] = isset($atts['posts_padding_sm']) ? helper::force_units(esc_attr($atts['posts_padding_sm'])) : '10px';
        }
        else {
            $posts_layout_array['posts_columns_lg'] = ceil($posts_layout_array['posts_columns']/2);
            $posts_layout_array['posts_columns_md'] = ceil($posts_layout_array['posts_columns']/3);
            $posts_layout_array['posts_columns_sm'] = 1;
        }

        return $posts_layout_array;
    }
    
    public static function get_table_setup($atts, $is_template=false) {
        
        // if this table sits in an achive- or search-template
        if ( $is_template ) {
            global $wp;
            $query_vars = $wp->query_vars;
            if ( isset($query_vars['paged']) ) unset( $query_vars['paged'] );
            $url = add_query_arg( $query_vars, preg_replace( "/page\/\d+/", "", home_url($wp->request) ) );
            // debug( $query_vars );
        }
        
        $fields     = isset( $atts['table_setup'] ) ? vc_param_group_parse_atts($atts['table_setup']) : array();
        $thead      = "";
        $empty_ths  = 0;
        
        foreach( $fields as $field ) {
            $type       = isset($field["type"]) ? $field["type"] : "text";
            $title      = isset($field["title"]) ? $field["title"] : "";
            $sortable   = isset($field["sortable"]) ? "sortable" : "";
            $mobile     = isset($field["hide_mobile"]) ? "hide-on-mobile" : "";
            $link       = "";
            
            if ( $is_template && !empty($sortable) && $type === 'post' ) {
                
                // get orderby
                $orderby = isset($field["post_value"]) ? $field["post_value"] : "title";
                if ( $orderby === 'taxonomy' ) {
                    $orderby = isset($field["post_taxonomy"]) ? "tax_".$field["post_taxonomy"] : "";
                }
                else if ( $orderby === 'category' || $orderby === 'tag' ) {
                    $posttype   = isset($query_vars['post_type']) ? $query_vars['post_type'] : 'post';
                    $orderby    = $orderby === 'category' ? "tax_".helper::get_category_slug($posttype) : "tax_".helper::get_tag_slug($posttype);;
                }
                
                // set link
                if ( !empty($orderby) ) {
                    $order = "asc";
                    // orderby is already set
                    if ( isset($query_vars['order']) && isset($query_vars['orderby']) && $query_vars['orderby'] == $orderby ) {
                        $current_order = $query_vars['order'];
                        $sortable .= " ".$current_order."ending";
                        $order = $current_order == 'asc' ? 'desc' : 'asc';
                    }
                    $args = array('orderby' => $orderby, 'order' => $order);
                    $link = "onclick='location.href=\"".add_query_arg( $args , $url )."\";'";
                }
            }
            $thead .= "<th class='$sortable $mobile' $link>$title<span class='icon'><span></span><span></span></span></th>";

            if ( empty($title) ) $empty_ths++;
        }
        
        // don't render <thead> if all <th>s are empty
        $thead = "<table>".( count($fields) === $empty_ths ? "" : "<thead><tr>$thead</tr></thead>" )."<tbody>";
        $tfoot = "</tbody></table>";
        
        return ['thead' => $thead, 'fields' => $fields, 'tfoot' => $tfoot];
    }
    
    public static function get_post_layout($atts) {
        $post_setup_mode = isset($atts['post_setup_mode']) ? $atts['post_setup_mode'] : 'manual';
        if ($post_setup_mode == 'template') {
            $posts_layout_array = array();
            $posts_layout_array['post_linkfull'] = 'no';
            // $posts_layout_array['post_background'] = isset($atts['post_background']) ? esc_attr($atts['post_background']) : '';
            // $post_border_radius = isset($atts['post_border_radius']) ? esc_attr($atts['post_border_radius']) : 0;
            // if (strpos($post_border_radius, 'px') == false) $post_border_radius .= "px";
            return $posts_layout_array;
        }
        else if ($post_setup_mode == 'manual') {
            $post_element_layout = isset($atts['post_element_layout']) ? esc_attr($atts['post_element_layout']) : 'vertical';
            // early exit
            if ( empty($post_element_layout) ) return __("Bitte stelle das Layout der Postelemente ein.", 'core');
            
            $posts_layout_array = array();
            $posts_layout_array['post_element_layout'] = $post_element_layout;
            $posts_layout_array['post_element_align'] = isset($atts['post_element_align']) ? esc_attr($atts['post_element_align']) : 'fs';
            $posts_layout_array['post_element_padding'] = isset($atts['post_element_padding']) ? helper::force_units(esc_attr($atts['post_element_padding'])) : '20px';

            $posts_layout_array['post_padding_top'] = isset($atts['post_padding_top']) ? helper::force_units(esc_attr($atts['post_padding_top'])) : '0px';
            $posts_layout_array['post_padding_right'] = isset($atts['post_padding_right']) ? helper::force_units(esc_attr($atts['post_padding_right'])) : '0px';

            $posts_layout_array['post_linkfull'] = isset($atts['post_linkfull']) ? esc_attr($atts['post_linkfull']) : '';
            $posts_layout_array['post_background'] = isset($atts['post_background']) ? helper::get_colorselect($atts, 'post_background', '') : '';
            // $posts_layout_array['post_background'] = isset($atts['post_background']) ? esc_attr($atts['post_background']) : '';

            // make border setup
            $post_border_color = isset($atts['post_border_color']) ? helper::process_color(helper::get_color($atts, 'post_border_', '', 'transparent')) : 'transparent';
            // $post_border_color = isset($atts['post_border_color']) ? esc_attr($atts['post_border_color']) : 'transparent';
            $post_border_width = isset($atts['post_border_width']) ? helper::force_units(esc_attr($atts['post_border_width'])) : 0;
            $post_border_radius = isset($atts['post_border_radius']) ? helper::force_units(esc_attr($atts['post_border_radius'])) : 0;
            $posts_layout_array['post_border'] = "border-radius:".$post_border_radius.";border: ".$post_border_width." none ".$post_border_color."; ";

            $posts_layout_array['post_border'] .= "border-left-style:".(isset($atts['post_border_left']) ? esc_attr($atts['post_border_left']) : 'none')."; ";
            $posts_layout_array['post_border'] .= "border-top-style:".(isset($atts['post_border_top']) ? esc_attr($atts['post_border_top']) : 'none')."; ";
            $posts_layout_array['post_border'] .= "border-right-style:".(isset($atts['post_border_right']) ? esc_attr($atts['post_border_right']) : 'none')."; ";
            $posts_layout_array['post_border'] .= "border-bottom-style:".(isset($atts['post_border_bottom']) ? esc_attr($atts['post_border_bottom']) : 'none')."; ";
            return $posts_layout_array;
        }
    }
    public static function get_pagination($atts) {
        $pagination_layout = isset($atts['pagination_layout']) ? esc_attr($atts['pagination_layout']) : 'bottom';
        if ($pagination_layout == 'top' || $pagination_layout == 'bottom') {
            $posts_layout_array = array();
            $posts_layout_array['pagination_layout'] = isset($atts['pagination_layout']) ? esc_attr($atts['pagination_layout']) : 'bottom';
            $posts_layout_array['pagination_pull'] = isset($atts['pagination_pull']) ? esc_attr($atts['pagination_pull']) : '_center';
            $posts_layout_array['pagination_pull'] = str_replace("_", "", $posts_layout_array['pagination_pull']);
            $posts_layout_array['pagination_overlap'] = isset($atts['pagination_overlap']) ? esc_attr($atts['pagination_overlap']) : '';
            $posts_layout_array['pagination_text_size'] = isset($atts['pagination_text_size']) ? esc_attr($atts['pagination_text_size']) : 'normal';

            $posts_layout_array['pagination_margin_top'] = isset($atts['pagination_margin_top']) ? helper::force_units(esc_attr($atts['pagination_margin_top'])) : '30px';
            $posts_layout_array['pagination_padding'] = isset($atts['pagination_padding']) ? helper::force_units(esc_attr($atts['pagination_padding'])) : '0px';
            $posts_layout_array['pagination_icon_padding'] = isset($atts['pagination_icon_padding']) ? helper::force_units(esc_attr($atts['pagination_icon_padding'])) : '5px';
            $posts_layout_array['pagination_numbers_padding'] = isset($atts['pagination_numbers_padding']) ? helper::force_units(esc_attr($atts['pagination_numbers_padding'])) : '10px';

            $posts_layout_array['pagination_icon_previous'] = isset($atts['pagination_icon_previous']) ? esc_attr($atts['pagination_icon_previous']) : 'arrow_left';
            $posts_layout_array['pagination_icon_next'] = isset($atts['pagination_icon_next']) ? esc_attr($atts['pagination_icon_next']) : 'arrow_right';
            $posts_layout_array['pagination_color'] = isset($atts['pagination_color']) ? helper::process_color(helper::get_color($atts, 'pagination_', '', false)) : '';
            $posts_layout_array['pagination_color_hover'] = isset($atts['pagination_color_hover']) ? helper::process_color(helper::get_color($atts, 'pagination_', '_hover', false)) : '';
            $posts_layout_array['pagination_color_active'] = isset($atts['pagination_color_active']) ? helper::process_color(helper::get_color($atts, 'pagination_', '_active', false)) : '';
            // $posts_layout_array['pagination_color'] = isset($atts['pagination_color']) ? esc_attr($atts['pagination_color']) : '';
            
            $posts_layout_array['pagination_numbers'] = isset($atts['pagination_numbers']) ? esc_attr($atts['pagination_numbers']) : '';
            if ($posts_layout_array['pagination_numbers'] === '') {
                $posts_layout_array['pagination_numbers_style'] = isset($atts['pagination_numbers_style']) ? esc_attr($atts['pagination_numbers_style']) : '';
            }
            else if ($posts_layout_array['pagination_numbers'] === 'icons') {
                $posts_layout_array['pagination_numbers_icon'] = isset($atts['pagination_numbers_icon']) ? esc_attr($atts['pagination_numbers_icon']) : 'icon_circle-empty';
                $posts_layout_array['pagination_numbers_icon_active'] = isset($atts['pagination_numbers_icon_active']) ? esc_attr($atts['pagination_numbers_icon_active']) : 'icon_circle-slelected';
            }
            else if ($posts_layout_array['pagination_numbers'] === 'custom') {
                $posts_layout_array['pagination_img_previous'] = isset($atts['pagination_img_previous']) ? esc_attr($atts['pagination_img_previous']) : -1;
                $posts_layout_array['pagination_numbers_img'] = isset($atts['pagination_numbers_img']) ? esc_attr($atts['pagination_numbers_img']) : -1;
                $posts_layout_array['pagination_numbers_img_active'] = isset($atts['pagination_numbers_img_active']) ? esc_attr($atts['pagination_numbers_img_active']) : -1;
                $posts_layout_array['pagination_img_next'] = isset($atts['pagination_img_next']) ? esc_attr($atts['pagination_img_next']) : -1;
                $posts_layout_array['pagination_opacity'] = isset($atts['pagination_opacity']) ? esc_attr($atts['pagination_opacity']) : 100;
                $posts_layout_array['pagination_opacity_hover'] = isset($atts['pagination_opacity_hover']) ? esc_attr($atts['pagination_opacity_hover']) : 70;
                $posts_layout_array['pagination_opacity_active'] = isset($atts['pagination_opacity_active']) ? esc_attr($atts['pagination_opacity_active']) : 70;
                $posts_layout_array['pagination_img_size'] = isset($atts['pagination_img_size']) ? helper::force_units(esc_attr($atts['pagination_img_size'])) : '20px';
            }
            return $posts_layout_array;
        }
        else if (strpos($pagination_layout, '_side') > 0 || strpos($pagination_layout, 'only_') !== false) {

            $posts_layout_array = array();
            $posts_layout_array['pagination_layout'] = $pagination_layout;
            
            
            if (strpos($pagination_layout, '_side') > 0) {
                // arrows
                $posts_layout_array['arrows_align'] = isset($atts['pagination2_arrows_align']) ? esc_attr($atts['pagination2_arrows_align']) : 'middle';
                $posts_layout_array['arrows_overlap'] = isset($atts['pagination2_arrows_overlap']) ? esc_attr($atts['pagination2_arrows_overlap']) : '';

                $posts_layout_array['arrows_padding_tb'] = isset($atts['pagination2_arrows_padding_tb']) ? helper::force_units(esc_attr($atts['pagination2_arrows_padding_tb'])) : '10px';
                $posts_layout_array['arrows_padding_lr'] = isset($atts['pagination2_arrows_padding_lr']) ? helper::force_units(esc_attr($atts['pagination2_arrows_padding_lr'])) : '10px';
                $posts_layout_array['arrows_size'] = isset($atts['pagination2_arrows_size']) ? helper::force_units(esc_attr($atts['pagination2_arrows_size'])) : '40px';
                
                $posts_layout_array['arrows_align_mobile'] = isset($atts['pagination2_arrows_align_mobile']) ? esc_attr($atts['pagination2_arrows_align_mobile']) : '';
                $posts_layout_array['arrows_size_mobile'] = isset($atts['pagination2_arrows_size_mobile']) ? helper::force_units(esc_attr($atts['pagination2_arrows_size_mobile'])) : '';

                $posts_layout_array['arrows_type'] = isset($atts['pagination2_arrows']) ? esc_attr($atts['pagination2_arrows']) : 'icons';
                if ($posts_layout_array['arrows_type'] == 'icons') {
                    $posts_layout_array['arrows_icon_previous'] = isset($atts['pagination2_arrows_icon_previous']) ? esc_attr($atts['pagination2_arrows_icon_previous']) : 'arrow_left';
                    $posts_layout_array['arrows_icon_next'] = isset($atts['pagination2_arrows_icon_next']) ? esc_attr($atts['pagination2_arrows_icon_next']) : 'arrow_right';
                    $posts_layout_array['arrows_color'] = isset($atts['pagination2_arrows_color']) ? helper::process_color(helper::get_color($atts, 'pagination2_arrows_', '', false)) : '';
                    $posts_layout_array['arrows_color_hover'] = isset($atts['pagination2_arrows_color_hover']) ? helper::process_color(helper::get_color($atts, 'pagination2_arrows_', '_hover', false)) : '';
                }
                else if ($posts_layout_array['arrows_type'] == 'custom') {
                    $posts_layout_array['arrows_img_previous'] = isset($atts['pagination2_arrows_img_previous']) ? esc_attr($atts['pagination2_arrows_img_previous']) : -1;
                    $posts_layout_array['arrows_img_next'] = isset($atts['pagination2_arrows_img_next']) ? esc_attr($atts['pagination2_arrows_img_next']) : -1;
                    $posts_layout_array['arrows_opacity'] = isset($atts['pagination2_arrows_opacity']) ? esc_attr($atts['pagination2_arrows_opacity']) : 100;
                    $posts_layout_array['arrows_opacity_hover'] = isset($atts['pagination2_arrows_opacity_hover']) ? esc_attr($atts['pagination2_arrows_opacity_hover']) : 70;
                }
            }
            
            // pagination2
            $posts_layout_array['pagination_pull'] = isset($atts['pagination2_numbers_align']) ? esc_attr($atts['pagination2_numbers_align']) : '_center';
            $posts_layout_array['pagination_pull'] = str_replace("_", "", $posts_layout_array['pagination_pull']);
            $posts_layout_array['pagination_overlap'] = isset($atts['pagination2_numbers_overlap']) ? esc_attr($atts['pagination2_numbers_overlap']) : '';

            $posts_layout_array['pagination_padding_tb'] = isset($atts['pagination2_numbers_padding_tb']) ? helper::force_units(esc_attr($atts['pagination2_numbers_padding_tb'])) : '10px';
            $posts_layout_array['pagination_padding_lr'] = isset($atts['pagination2_numbers_padding_lr']) ? helper::force_units(esc_attr($atts['pagination2_numbers_padding_lr'])) : '0px';
            $posts_layout_array['pagination_space'] = isset($atts['pagination2_numbers_space']) ? helper::force_units(esc_attr($atts['pagination2_numbers_space'])) : '10px';

            $posts_layout_array['pagination_numbers'] = isset($atts['pagination2_numbers']) ? esc_attr($atts['pagination2_numbers']) : '';
            $posts_layout_array['pagination_color'] = isset($atts['pagination2_numbers_color']) ? helper::process_color(helper::get_color($atts, 'pagination2_numbers_', '', false)) : '';
            $posts_layout_array['pagination_color_hover'] = isset($atts['pagination2_numbers_color_hover']) ? helper::process_color(helper::get_color($atts, 'pagination2_numbers_', '_hover', false)) : '';
            $posts_layout_array['pagination_color_active'] = isset($atts['pagination2_numbers_color_active']) ? helper::process_color(helper::get_color($atts, 'pagination2_numbers_', '_active', false)) : '';
            
            $posts_layout_array['pagination_text_size'] = isset($atts['pagination2_numbers_text_size']) ? helper::force_units(esc_attr($atts['pagination2_numbers_text_size']), ['px','em'], 'em') : '1em';
            $posts_layout_array['pagination_img_size'] = isset($atts['pagination2_numbers_img_size']) ? helper::force_units(esc_attr($atts['pagination2_numbers_img_size'])) : '20px';
            
            $posts_layout_array['pagination_img_size_mobile'] = isset($atts['pagination2_numbers_img_size_mobile']) ? helper::force_units(esc_attr($atts['pagination2_numbers_img_size_mobile'])) : '';
            $posts_layout_array['pagination_space_mobile'] = isset($atts['pagination2_numbers_space_mobile']) ? helper::force_units(esc_attr($atts['pagination2_numbers_space_mobile'])) : '';

            if ($posts_layout_array['pagination_numbers'] === '') {
                $posts_layout_array['pagination_numbers_style'] = isset($atts['pagination2_numbers_style']) ? esc_attr($atts['pagination2_numbers_style']) : '';
            }
            else if ($posts_layout_array['pagination_numbers'] === 'icons') {
                $posts_layout_array['pagination_numbers_icon'] = isset($atts['pagination2_numbers_icon']) ? esc_attr($atts['pagination2_numbers_icon']) : 'icon_circle-empty';
                $posts_layout_array['pagination_numbers_icon_active'] = isset($atts['pagination2_numbers_icon_active']) ? esc_attr($atts['pagination2_numbers_icon_active']) : 'icon_circle-slelected';
            }
            else if ($posts_layout_array['pagination_numbers'] === 'custom') {
                $posts_layout_array['pagination_numbers_img'] = isset($atts['pagination2_numbers_img']) ? esc_attr($atts['pagination2_numbers_img']) : -1;
                $posts_layout_array['pagination_numbers_img_active'] = isset($atts['pagination2_numbers_img_active']) ? esc_attr($atts['pagination2_numbers_img_active']) : -1;
                $posts_layout_array['pagination_opacity'] = isset($atts['pagination2_numbers_opacity']) ? esc_attr($atts['pagination2_numbers_opacity']) : 100;
                $posts_layout_array['pagination_opacity_hover'] = isset($atts['pagination2_numbers_opacity_hover']) ? esc_attr($atts['pagination2_numbers_opacity_hover']) : 70;
                $posts_layout_array['pagination_opacity_active'] = isset($atts['pagination2_numbers_opacity_active']) ? esc_attr($atts['pagination2_numbers_opacity_active']) : 70;
            }
            return $posts_layout_array;
        }
        else { // if ($pagination_layout == '' && $pagination_layout == 'none') {
            return "";
        }
    }

    public static function get_sorting($atts, $pre="") {
        //debug($atts);
        $sorting_dropdown_atts = array();

        // initial order
        $sorting_dropdown_atts[$pre.'mode_value']        = isset($atts[$pre.'mode_initial']) ? esc_attr($atts[$pre.'mode_initial']) : "";
        $sorting_dropdown_atts[$pre.'mode']              = empty($sorting_dropdown_atts[$pre.'mode_value']) ? null : explode(' ', $sorting_dropdown_atts[$pre.'mode_value']);
        // frontend dropdown
        $sorting_dropdown_atts[$pre.'dropdown_frontend'] = isset($atts[$pre.'dropdown_frontend']) ? esc_attr($atts[$pre.'dropdown_frontend']) : 0;
        if ( $sorting_dropdown_atts[$pre.'dropdown_frontend'] === 'show' ) {
            $sorting_dropdown_atts[$pre.'position']          = isset($atts[$pre.'position']) ? esc_attr($atts[$pre.'position']) : "flex-start top";
            $sorting_dropdown_atts[$pre.'position']          = explode(' ', $sorting_dropdown_atts[$pre.'position']);
            $sorting_dropdown_atts[$pre.'style']             = isset($atts[$pre.'style']) ? esc_attr($atts[$pre.'style']) : "_input";
            $sorting_dropdown_atts[$pre.'width']             = isset($atts[$pre.'width']) ? esc_attr($atts[$pre.'width']) : "";
            $sorting_dropdown_atts[$pre.'margin_top']        = isset($atts[$pre.'margin_top']) ? esc_attr($atts[$pre.'margin_top']) : "30px";
            $sorting_dropdown_atts[$pre.'margin_bottom']     = isset($atts[$pre.'margin_bottom']) ? esc_attr($atts[$pre.'margin_bottom']) : "30px";
            $sorting_dropdown_atts[$pre.'inline_style']      = $sorting_dropdown_atts[$pre.'style'] === 'custom' ? helper::make_custom_element($atts, $pre."_") : "";

            // individual option names
            $sorting_dropdown_atts[$pre.'text_date_desc']   = isset($atts[$pre.'text_date_desc'])  ? $atts[$pre.'text_date_desc']  : null;
            $sorting_dropdown_atts[$pre.'text_date_asc']    = isset($atts[$pre.'text_date_asc'])   ? $atts[$pre.'text_date_asc']   : null;
            $sorting_dropdown_atts[$pre.'text_title_asc']   = isset($atts[$pre.'text_title_asc'])  ? $atts[$pre.'text_title_asc']  : null;
            $sorting_dropdown_atts[$pre.'text_title_desc']  = isset($atts[$pre.'text_title_desc']) ? $atts[$pre.'text_title_desc'] : null;
            $sorting_dropdown_atts[$pre.'text_views_desc']  = isset($atts[$pre.'text_views_desc'])  ? $atts[$pre.'text_views_desc']  : null;
            $sorting_dropdown_atts[$pre.'text_relevance_desc']  = isset($atts[$pre.'text_relevance_desc']) ? $atts[$pre.'text_relevance_desc'] : null;
        }

        // set get_post() $args
        if (isset($sorting_dropdown_atts[$pre.'mode'][0]) && $sorting_dropdown_atts[$pre.'mode'][0] == "views") {
            $sorting_dropdown_atts[$pre.'mode_initial'] = array(
                "orderby"  => 'meta_value_num',
                "order"    => $sorting_dropdown_atts[$pre.'mode'][1],
                'meta_query' => array(
                    'relation' => 'OR',
                    array(
                        'key' => 'postviews_count', 
                        'compare' => 'EXISTS',
                    ),
                    array(
                        'key' => 'postviews_count', 
                        'compare' => 'NOT EXISTS',
                    )
                ),
            );
        } else if (isset($sorting_dropdown_atts[$pre.'mode']) && $sorting_dropdown_atts[$pre.'mode']) {
            $sorting_dropdown_atts[$pre.'mode_initial'] = array(
                "orderby" => $sorting_dropdown_atts[$pre.'mode'][0],
                "order"   => $sorting_dropdown_atts[$pre.'mode'][1]
            );
        }
        return $sorting_dropdown_atts;
    }

    /**
     * =================================================================
     *                          Render helper
     * =================================================================
     */
    public static function make_posts_title($title, $params="") {
        
        if (!function_exists(__NAMESPACE__.'\replace_title_placeholders')) {
            function replace_title_placeholders($text_content, $params) {
                $search_query = isset($params->search_query) ? $params->search_query : '';
                $text_content = str_replace("_query_", $search_query, $text_content);
                $text_content = str_replace("_post-count_", $params->post_count, $text_content);
                $text_content = str_replace("_page-count_", $params->page_count, $text_content);
                $text_content = str_replace("_page-num_", $params->page_num, $text_content);
                $text_content = str_replace("_posttype_", $params->get_posttype, $text_content);
                $category = is_object($params->get_category) ? $params->get_category->name : $params->get_category;
                $text_content = str_replace("_category_", $category, $text_content);
                $tag = is_object($params->get_tag) ? $params->get_tag->name : $params->get_tag;
                $text_content = str_replace("_tag_", $tag, $text_content);
                return $text_content;
            }
        }

        $style = "";
        if ($title["color"] != "") $style .= "color:".$title["color"]."; ";
        $tag = "div";
        if ($title["size"] != 'normal') $tag = $title["size"];
        if ($title["weight"] != '') $style .= "font-weight:".$title["weight"]."; ";
        $content = $title["text"];
        if ($params != "") $content = replace_title_placeholders($content ,$params);
        // render
        return "<".$tag." class='".$title["pull"]."' style='".$style."'>".$content."</".$tag.">";
    }
    
    public static function make_post_table_row($wp_post, $fields, $params) {

        $singular_name = '';
        $permalink = '';
        $site_title = '';

        $is_external_post = isset($wp_post->is_external_post) && $wp_post->is_external_post;

        if (!$is_external_post) {
            $site_title = get_bloginfo();
            $permalink = get_the_permalink($wp_post);
            $singular_name = get_post_type_object($wp_post->post_type)->labels->singular_name;
        }

        ob_start();
        
        // get tags
        $dtags = helper::get_dynamic_posttype_tags($wp_post);
        $tags = helper::get_dynamic_tags('single');

        echo "<tr>";
        foreach( $fields as $atts ) {
            
            // vars
            $type           = isset($atts["type"]) ? $atts["type"] : "text";
            $value          = isset($atts[$type."_value"]) ? $atts[$type."_value"] : "";
            $align          = isset($atts["align"]) ? $atts["align"] : "";
            $mobile         = isset($atts["hide_mobile"]) ? "hide-on-mobile" : "";
            $before         = $after = "";
            $inline_style   = [];
            
            if ( !empty($value) )  {
                
                if ( $type !== 'post' ) {
                    $value = \dynamic::match_tags($wp_post, array_merge($dtags, $tags), $value);
                }
                
                // text
                if ( $type === 'text' ) {
                    
                    // text color
                    if ( isset($atts["text_color"]) ) $inline_style[] = "color: ".helper::process_color(helper::get_color($atts, "text_")).";";
                    
                    // format
                    $format = isset($atts["text_format"]) ? $atts["text_format"] : "";
                    if ( $format === 'bold' ) $inline_style[] = "font-weight:600;";
                    else if ( $format === 'italic' ) $inline_style[] = "font-style:italic;";
                    else if ( $format === 'small' ) $inline_style[] = "font-size: 0.85em;";
                    else if ( $format === 'big' ) $inline_style[] = "font-size: 1.1em;";
                    else if ( $format === 'bigger' ) $inline_style[] = "font-size: 1.2em;";
                    
                    // link
                    $before = isset($atts["text_link"]) ? "<a href='".isset($wp_post->permalink) ? $wp_post->permalink : $permalink."' %s >" : $before;
                    $after  = isset($atts["text_link"]) ? "</a>" : $after;
                }
                else if ( $type === 'img' ) {
                    
                    $value = \vc\shortcode::icons_sc( [ "icon"  => $value ], "" );
                            
                    if ( isset($atts['img_width']) )
                        $inline_style[] = "width: ".helper::force_units($atts["img_width"], ['px','%']).";";
                }
                else if ( $type === 'btn' ) {
                    
                    // atts
                    $pre        = 'btn_';
                    $link       = vc_build_link($value);
                    $icon       = isset($atts[$pre.'icon']) ? esc_attr($atts[$pre.'icon']) : '';
                    
                    // build link
                    $url        = isset($link['url'])       ? str_replace("http://http", "http", $link['url']) : ""; // Doppelung entfernen...
                    $content    = isset($link['title'])     ? $link['title'] : "";
                    $target     = isset($link['target'])    ? "target='".$link['target']."'" : "";
                    $rel        = isset($link['rel'])       ? "rel='".$link['rel']."'" : "";

                    // don't render if neither content nor icon are set
                    if ($content === "" && $icon === "") {
                        $value = "";
                    } else {
                        
                        $size       = isset($atts[$pre.'size']) ? str_replace( "_", "", esc_attr($atts[$pre.'size']) ) : '';
                        $class      = isset($atts[$pre.'mode']) ? str_replace( array("_".$type, "_link", "_"), "", esc_attr($atts[$pre.'mode']) ) : "button";
                        $width      = isset($atts[$pre.'width']) ? helper::force_units( esc_attr($atts[$pre.'width']), ['px','%'] ) : "";
                        $style      = !empty($width) ? "width: $width; " : "";
                        if ( $class === 'custom' ) {
                            $style = helper::make_custom_element($atts, $pre, $style);
                            $class .= ' button';
                        }
                        
                        // add icon to content
                        if (!empty($icon)) $content = helper::make_custom_icon($atts, $pre, $content);
                        
                        $value = "<a href='$url' $target $rel class='$class $size' style='$style'>$content</a>";

                        // ----------------------------------------
                        
                    }
                    
                }
                else if ( $type === 'post' ) {
                    
                    // individual atts
                    
                    $taxonomy = false;
                    switch ($value) {
                       case 'title':
                            $value = isset($wp_post->post_title) ? $wp_post->post_title : get_the_title($wp_post);
                            break;
                        case 'image':
                            $value = isset($wp_post->image) ? $wp_post->image : get_the_post_thumbnail_url($wp_post->ID);
                            if ( !$value ) $value = "";
                            else $value = \vc\shortcode::icons_sc( [ "icon"  => $value ], "" );
                            
                            if ( isset($atts['post_img_width']) )
                                $inline_style[] = "width: ".helper::force_units($atts["post_img_width"], ['px','%']).";";
                            break;
                        case 'content':
                            $length = isset($atts['post_content_length']) ? intval($atts['post_content_length']) : 100;
                            $content = isset($wp_post->content) ? $wp_post->content : $wp_post->post_content;
                            if ($length == -1) $value = do_shortcode(wpautop($content));
                            else $value = helper::make_clean_vc_string($content, $length);
                            
                            if ( isset($atts['post_content_width']) )
                                $inline_style[] = "width: ".helper::force_units($atts["post_content_width"], ['px','%']).";";
                            break;
                        case 'author':
                            $value  = isset($wp_post->author) ? $wp_post->author : get_the_author_meta('display_name', $wp_post->post_author);
                            $before = isset($atts["post_author_link"]) ? "<a href='".isset($wp_post->author_url) ? $wp_post->author_url : get_author_posts_url(get_the_author_meta('ID', $wp_post->post_author))."' %s >" : $before;
                            $after  = isset($atts["post_author_link"]) ? "</a>" : $after;
                            break;
                        case 'date':
                            $format = isset($atts['post_date_format']) ? $atts['post_date_format'] : "";
                            $value  = get_the_date($format, $wp_post);
                            
                            break;
                        case 'taxonomy':
                            $value = "";
                            $taxonomy = isset($atts["post_taxonomy"]) ? $atts["post_taxonomy"] : false;
                            break;
                        case 'category':
                            $value = "";
                            $taxonomy = helper::get_category_slug($wp_post->post_type);
                            break;
                        case 'tag':
                            $value = "";
                            $taxonomy = helper::get_tag_slug($wp_post->post_type);
                            break;
                        case 'site_title':
                            $value = isset($wp_post->site_title) ? $wp_post->site_title : $site_title;
                            break;
                    }
                    
                    // general atts
                    
                    // text color
                    if ( isset($atts["post_color"]) ) $inline_style[] = "color: ".helper::process_color(helper::get_color($atts, "post_")).";";
                    // format
                    $format = isset($atts["post_format"]) ? $atts["post_format"] : "";
                    if ( $format === 'bold' ) $inline_style[] = "font-weight:600;";
                    else if ( $format === 'italic' ) $inline_style[] = "font-style:italic;";
                    else if ( $format === 'small' ) $inline_style[] = "font-size: 0.85em;";
                    else if ( $format === 'big' ) $inline_style[] = "font-size: 1.1em;";
                    else if ( $format === 'bigger' ) $inline_style[] = "font-size: 1.2em;";
                    // link
                    $before = isset($atts["post_link"]) ? "<a href='".get_the_permalink($wp_post)."' %s >" : $before;
                    $after  = isset($atts["post_link"]) ? "</a>" : $after;
                    
                    // taxonomy atts
                    if ( $taxonomy && !empty($taxonomy) ) {
                        $terms = wp_get_post_terms($wp_post->ID, $taxonomy);
                        if ( !is_wp_error($terms) ) {
                            $sep    = isset($atts["post_tax_seperator"]) ? $atts["post_tax_seperator"] : "";
                            $link   = isset($atts["post_tax_link"]) ? "1" : "";
                            $atts   = [ 'slug' => '', 'sep' => $sep, 'link'=> $link ];
                            $value  = helper::make_terms_string( $terms, implode("|", $atts) );
                        }
                    }
                }
                
                // add styling to taxonomy links
                if ( $type !== 'btn' && count($inline_style) !== 0 && strpos($value, '<a href=') !== false )  {
                    $value = preg_replace( '/<a href=/', '<a style="'.implode(" ", $inline_style).'" href=', $value );
                    $inline_style = [];
                }
            }
            
            if ( !empty($before) ) {
                $before = sprintf($before, (count($inline_style) > 0 ?  "style='".implode(" ", $inline_style)."'" : "") );
                $inline_style = [];
            }
            
            // add text align to cell
            if ( !empty($align) && $align !== 'left' ) {
                $inline_style[] = "text-align: $align;";
            }
            
            $value = $before.$value.$after;
            
            echo "<td class='$mobile' ".( count($inline_style) > 0 ?  "style='".implode(" ", $inline_style)."'" : "" ).">".strval($value)."</td>";
        }
        echo "</tr>";

        $return = ob_get_contents();
		ob_end_clean();
		return $return;
    }

    public static function make_post_preview_styles($parent_selector, $posts_layout_array) {

        /**
         * .search_result
         */
        $css = $style = $style_lg = $style_md = $style_sm = "";

        // vertical layout
        if ($posts_layout_array['posts_layout'] == "vertical") {
            $style = "margin-top:".$posts_layout_array['posts_padding']."; ";
        }

        // other layout types
        else {
            // default
            $padding    = $posts_layout_array['posts_padding'];
            $style     .= "margin: 0 calc( $padding / 2 ) $padding; ";
            $style     .= "width: calc(".( 100 / $posts_layout_array['posts_columns'] )."% - ".$padding."); ";

            // lg
            if ( isset($posts_layout_array['posts_padding_lg']) ) {
                $padding    = $posts_layout_array['posts_padding_lg'];
                $style_lg     .= "margin-bottom: $padding; margin-left: calc( $padding / 2 ); margin-right: calc( $padding / 2 ); ";
            }
            $style_lg  .= "width: calc(".( 100 / $posts_layout_array['posts_columns_lg'] )."% - ".$padding."); ";

            // md
            if ( isset($posts_layout_array['posts_padding_md']) ) {
                $padding    = $posts_layout_array['posts_padding_md'];
                $style_md     .= "margin-bottom: $padding; margin-left: calc( $padding / 2 ); margin-right: calc( $padding / 2 ); ";
            }
            $style_md  .= "width: calc(".( 100 / $posts_layout_array['posts_columns_md'] )."% - ".$padding."); ";

            // sm
            if ( isset($posts_layout_array['posts_padding_sm']) ) {
                $padding    = $posts_layout_array['posts_padding_sm'];
                $style_sm     .= "margin-bottom: $padding; margin-left: calc( $padding / 2 ); margin-right: calc( $padding / 2 ); ";
            }
            $style_sm  .= "width: calc(".( 100 / $posts_layout_array['posts_columns_sm'] )."% - ".$padding."); ";
        }
            
        $selector = "$parent_selector .search_result";
        $css .= "$selector { ".$style." }
            @media (max-width: var(grid_lg)) {
                $selector { ".$style_lg." }
            }
            @media (max-width: var(grid_md)) {
                $selector { ".$style_md." }
            }
            @media (max-width: var(grid_sm)) {
                $selector { ".$style_sm." }
            } ";

        /**
         * .posts_result
         */
        $padding_top    = isset($posts_layout_array['post_padding_top'])   ? $posts_layout_array['post_padding_top'] : '0';
        $padding_right  = isset($posts_layout_array['post_padding_right']) ? $posts_layout_array['post_padding_right'] : '0';

        $style = "padding: ".$padding_top." ".$padding_right."; ";
        if (isset($posts_layout_array["post_border"])) {
            $style .= $posts_layout_array['post_border'];
        }
        if (isset($posts_layout_array["post_background"]) && $posts_layout_array['post_background'] != "") {
            $style .= "background-color:".$posts_layout_array['post_background']."; ";
        }
        if ($posts_layout_array["post_linkfull"] !== "no") {
            $style .= "cursor: pointer; ";
        }

        $selector = "$parent_selector .posts_result";
        $css .= "$selector { ".$style." }";


        \enqueue::add_custom_style($css);
    }
    
    /**
     * Build a post preview tile
     * 
     * @param WP_Post $wp_post
     * @param array $post_setup_array
     * @param array $posts_layout_array
     * @param array $params
     * 
     * @return string full html code
     */
    public static function make_post_preview($wp_post, $post_setup_array, $posts_layout_array, $params) {

        if ( !$wp_post || !is_object($wp_post) || is_wp_error( $wp_post ) ) {
            return "";
        }
        
        // extend params
        $post = (object) array_merge(
            (array) $wp_post,
            array(
                'id'         => $wp_post->ID,
                'permalink'  => isset($wp_post->permalink) ? $wp_post->permalink : get_the_permalink($wp_post),
                'post_title' => isset($wp_post->post_title) ? $wp_post->post_title : get_the_title($wp_post),
                'image'      => isset($wp_post->image) ? $wp_post->image : get_the_post_thumbnail_url($wp_post->ID),
                'imageset'   => isset($wp_post->imageset) ? $wp_post->image : get_imageset(get_post_thumbnail_id($wp_post->ID)),
                'thumb'      => isset($wp_post->thumb) ? $wp_post->imageset : get_image(get_post_thumbnail_id($wp_post), 'medium'),
                'content'    => isset($wp_post->content) ? $wp_post->content : $wp_post->post_content,
                'excerpt'    => isset($wp_post->excerpt) ? $wp_post->excerpt : helper::get_the_excerpt($wp_post),
                'author'     => isset($wp_post->author) ? $wp_post->author : get_the_author_meta('display_name', $wp_post->post_author),
                'author_url' => isset($wp_post->author_url) ? $wp_post->author_url : get_author_posts_url(get_the_author_meta('ID', $wp_post->post_author)),
                'categories' => isset($wp_post->categories) ? $wp_post->categories : helper::get_categories($wp_post),
                'tags'       => isset($wp_post->tags) ? $wp_post->tags : helper::get_tags($wp_post),
                'date'       => isset($wp_post->date) ? $wp_post->date : $wp_post->post_date,
                'postviews'  => isset($wp_post->postviews) ? $wp_post->postviews : get_post_meta($wp_post->ID, 'postviews_count', true),
                'score'      => isset($wp_post->score) ? $wp_post->score : 0
            )
        );
        
        $params = (object) array_merge(
            (array) $params,
            array(
                'post_type' => isset($wp_post->singular_name) ? $wp_post->singular_name : (get_post_type_object($wp_post->post_type) ? get_post_type_object($wp_post->post_type)->labels->singular_name : $wp_post->post_type), 
                'post_title' => $post->post_title,
                'post_author' => $post->author,
                'post_date' => $post->date,
                'site_title' => isset($wp_post->site_title) ? $wp_post->site_title : get_bloginfo(),
                'site_url' => isset($wp_post->site_url) ? $wp_post->site_url : get_site_url(),
            )
        );

        $data_filter = array();
        if ( isset($params->filter) && $params->filter ) {
            $terms = get_the_terms($post->id, $params->filter);
            if ( $terms && is_array($terms) ) {
                foreach ($terms as $term) {
                    array_push($data_filter, $term->term_id);
                }
            }
        }
        $data_atts = array(
            "data-post='".$post->id."'",
            "data-title='".preg_replace('/[^a-z0-9\s]/', '', strtolower($post->post_title))."'",
            "data-date='".$post->date."'",
            "data-postviews='".intval($post->postviews)."'",
            "data-filter='".rawurlencode(json_encode($data_filter))."'"
        );

        ob_start();

        // .search_result
        echo "<div class='search_result' ".implode(" ", $data_atts).">";

        // .posts_result
        $classes    = array();
        $attributes = array();
        if (isset($posts_layout_array["post_element_layout"]) && $posts_layout_array["post_element_layout"] == "vertical") {
            $classes[] = "vert";
        }
        else if (isset($posts_layout_array["post_element_align"])) {
            $classes[] = $posts_layout_array['post_element_align'];
        }
        if ($posts_layout_array["post_linkfull"] !== "no") {
            $attributes[] = "onclick='".($posts_layout_array["post_linkfull"] === "blank" ? "window.open" : "location.href=")."\"".$post->permalink."\";'";
            $attributes[] = "title='".$post->post_title."'";
        }
        echo "<div class='posts_result ".implode(" ", $classes)."' ".implode(" ", $attributes).">";

        if (isset($post_setup_array['mode']) && $post_setup_array['mode'] == 'template') {
            $dtags = helper::get_dynamic_posttype_tags($wp_post);
            //debug($dtags);
            
            $tags = helper::get_dynamic_tags('single');
            // $tags = array_merge($tags, $dtags);
            $atts = explode('::', $post_setup_array['atts']['dynamic_content']);
            // debug($post_setup_array['slug']);
            if (count($atts) > 1) {
                for ($i=1; $i<count($atts); $i++) {
                    $dynamic_atts = explode('|', $atts[$i]);
                    $oldval = rawurldecode($dynamic_atts[3]);
                    // map tags
                    if ( isset($params->map) && $params->map) {
                        $oldval = maps::match_tags($wp_post, $params->map, $oldval);
                    }
                    // standard tags
                    $newval = \dynamic::match_tags($wp_post, $dtags, $oldval);
                    $newval = \dynamic::match_tags($wp_post, $tags, $newval);
                    if ($oldval != $newval) {
                        $dynamic_atts[3] = rawurlencode($newval);
                    }
                    $atts[$i] = implode('|', $dynamic_atts);
                }
            }
            $atts = implode('::', $atts);
            // echo "[dynamic template='".$post_setup_array['slug']."' dynamic_content='".$atts."' options='".$post_setup_array['atts']['options']."']";
            echo do_shortcode("[dynamic template='".$post_setup_array['slug']."' dynamic_content='".$atts."' options='".$post_setup_array['atts']['options']."']");
        }
        else {
            //
            // cycle through elements make post
            $params->first_element = true;
            foreach ($post_setup_array as $element_setup) {
                echo self::make_post_element($post, $element_setup, $posts_layout_array, $params);
                $params->first_element = false;
            }
        }
        // close .posts_result
        echo "</div>";

        // close .search_result
        echo "</div>";

        $return = ob_get_contents();
        ob_end_clean();

        //debug($return);
        return $return;
    }

    public static function make_post_element($post, $element_setup, $posts_layout_array, $params) {

        //
        // element style
        $style = "padding:0px;margin:0px; ";
        if ($posts_layout_array["post_element_layout"] == "vertical") {
            if (!$params->first_element) $style .= "margin-top:".$posts_layout_array["post_element_padding"]."; ";
        }
        else {
            if (!$params->first_element) $style .= "margin-left:".($posts_layout_array["post_element_padding"])."; ";
            if ($element_setup["pull"] == "right") $style .= "flex:1!important; ";
        }
        $style_text = "";
        if (isset($element_setup["text_color"]) && $element_setup["text_color"] != "") {
            // $style .= "color:".$element_setup["text_color"]."; ";
            $style_text .= "color:".$element_setup["text_color"]."; ";
        }
        if ($element_setup["post_element"] == 'content' || 
            $element_setup["post_element"] == 'author' || 
            $element_setup["post_element"] == 'categories' ||
            $element_setup["post_element"] == 'tags' ||
            $element_setup["post_element"] == 'date' ||
            $element_setup["post_element"] == 'text') {
            if ($element_setup["text_size"] == "normal") $style_text .= "font-weight:400; ";
            if ($element_setup["text_size"] == "bold") $style_text .= "font-weight:600; ";
            if ($element_setup["text_size"] == "small") $style_text .= "font-weight:400;font-size:0.85em; ";
            if ($element_setup["text_size"] == "bigger") $style_text .= "font-weight:400;font-size:1.1em; ";
            if ($element_setup["text_size"] == "big") $style_text .= "font-weight:400;font-size:1.2em; ";
        }

        if (!function_exists(__NAMESPACE__.'\replace_placeholders')) {
            function replace_placeholders($text_content, $params) {
                $text_content = str_replace("_num_", $params->post_num, $text_content);
                $text_content = str_replace("_count_", $params->post_count, $text_content);
                $text_content = str_replace("_posttype_", $params->post_type, $text_content);
                $text_content = str_replace("_title_", $params->post_title, $text_content);
                $text_content = str_replace("_author_", $params->post_author, $text_content);
                $text_content = str_replace("_date_", $params->post_date, $text_content);
                $text_content = str_replace("_site-title_", $params->site_title, $text_content);
                return $text_content;
            }
        }

        ob_start();

        //
        // element types
        if ($element_setup["post_element"] == 'title') {
            $tag = "div";
            if ($element_setup["title_size"] != 'normal') $tag = $element_setup["title_size"];
            if ($element_setup['title_versal']) $style .= 'text-transform:uppercase;';
            // render
            echo "<".$tag." class='".$element_setup["pull"]."' style='".$style.$style_text."'>".$post->post_title."</".$tag.">";
        }
        if ($element_setup["post_element"] == 'site_title') {
            $tag = "div";
            if ($element_setup["title_size"] != 'normal') $tag = $element_setup["title_size"];
            if ($element_setup['title_versal']) $style .= 'text-transform:uppercase;';
            // render
            echo "<".$tag." class='".$element_setup["pull"]."' style='".$style.$style_text."'>".$params->site_title."</".$tag.">";
        }
        if ($element_setup["post_element"] == 'image') {
            if ($post->image) {
                $style_img = "width:".$element_setup["content_width"]."; ";
                $img_before = ""; $img_after = "";
                if ($element_setup["link_to"] && $posts_layout_array["post_linkfull"] == "no") {
                    $img_before = "<a href='".$post->permalink."' title='".$post->post_title."'>";
                    $img_after = "</a>";
                }
                // render
                $thumb = (\basics::get_setting(array('site', 'lazyload')) == 'true') ? $post->thumb : $post->image;
                $imageset = " data-srcset='".json_encode($post->imageset)."'";
                echo "<div class='".$element_setup["pull"]."' style='".$style."'>".$img_before."<img class='vc_icon' style='".$style_img."' src='".$thumb."' $imageset>".$img_after."</div>";
            }
        }
        if ($element_setup["post_element"] == 'content') {
            // if ($params->get_posttype == "Seiten") debug($post->content);
            if ($element_setup['content_length'] == -1) $content = do_shortcode(wpautop($post->content));
            else $content = helper::make_clean_vc_string($post->content, $element_setup['content_length']);
            // render
            echo "<div class='".$element_setup["pull"]."' style='".$style.$style_text."'>".$content."</div>";
        }
        if ($element_setup["post_element"] == 'author') {
            $author_before = "<span style='".$style_text."'>"; $author_after = "</span>";
            if ($element_setup["link_to"] && $posts_layout_array["post_linkfull"] == "no") {
                $author_before = "<a href='".$post->author_url."' title='All Posts by &quot;".$post->author."&quot;' style='".$style_text."'>";
                $author_after = "</a>";
            }
            // render
            echo "<div class='".$element_setup["pull"]."' style='".$style."' title='author'>".$author_before.$post->author.$author_after."</div>";
        }
        if ($element_setup["post_element"] == 'categories') {
            if ($post->categories && is_array($post->categories)) {
                $result = "";
                foreach ($post->categories as $term) {
                    if ($result != "") $result .= ", ";
                    $title = $term->name;
                    $url = get_term_link($term->slug, $term->taxonomy);
                    if ($element_setup["link_to"]) 
                        $result .= "<a href='".$url."' title='Alle &quot;".$title."&quot;' style='".$style_text."'>".$title."</a>";
                    else
                        $result .= "<span style='".$style_text."'>".$title."</span>";
                }
                // render
                echo "<div class='".$element_setup["pull"]."' style='".$style."' title='categories'>".$result."</div>";
            }
        }
        if ($element_setup["post_element"] == 'tags') {
            if ($post->tags && is_array($post->tags)) {
                $result = "";
                foreach ($post->tags as $term) {
                    if ($result != "") $result .= ", ";
                    $title = $term->name;
                    $url = get_term_link($term->slug, $term->taxonomy);
                    if ($element_setup["link_to"]) 
                        $result .= "<a href='".$url."' title='Alle &quot;".$title."&quot;' style='".$style_text."'>".$title."</a>";
                    else
                        $result .= "<span style='".$style_text."'>".$title."</span>";
                }
                // render
                echo "<div class='".$element_setup["pull"]."' style='".$style."' title='tags'>".$result."</div>";
            }
        }
        if ($element_setup["post_element"] == 'date') {
            // render
            echo "<div class='".$element_setup["pull"]."' style='".$style.$style_text."' title='date'>".mysql2date($element_setup["date_format"], $post->date)."</div>";
        }
        if ($element_setup["post_element"] == 'link' ||
            $element_setup["post_element"] == 'cart' ||
            $element_setup["post_element"] == 'woo_ajax') {
            //debug($element_setup);
            $style_btn = "margin:0px;width:".$element_setup["content_width"]."; ";
            $pre = $element_setup["post_element"];
            if ($element_setup[$pre.'_style'] == "link" || $element_setup[$pre.'_style'] == "link sec") $style_btn .= "padding-left:0px; ";
            if ($element_setup[$pre.'_style'] == 'custom') $style_btn = helper::make_custom_element($element_setup['custom_style'], $pre.'_', $style_btn);

            $tag_before = "div"; $tag_after = "div";
            if ($posts_layout_array["post_linkfull"] == "no") {
                $tag_before = "a href='".$post->permalink."' title='".$post->post_title."'";
                $tag_after = "a";
            }
            // render
            $link_content = replace_placeholders($element_setup[$pre.'_content'], $params);
            echo "<div class='".$element_setup["pull"]."' style='".$style."'>";
            if ($element_setup["post_element"] == 'link')
                echo "<".$tag_before." class='animate_fast ".$element_setup[$pre.'_style']."' style='".$style_btn."'>".$link_content."</".$tag_after.">";
            else {
                $sets = array(
                    'id' => $post->id,                          // Product ID
                    'qty' => '1',                               // Product quantity
                    'text' => $link_content,                    // Text of the button
                    'class' => $element_setup[$pre.'_style'],   // Additional classes
                    'style' => $style_btn,                      // Additional style
                );
                if ($element_setup["post_element"] == 'cart')
                    echo helper::custom_ajax_add_to_cart_button($sets);
                else if ($element_setup["post_element"] == 'woo_ajax') {
                    $sets['redirect'] = $element_setup[$pre.'_redirect'];
                    $sets['not_twice'] = $element_setup[$pre.'_not_twice'];
                    $sets['clear'] = $element_setup[$pre.'_clear'];
                    do_action('render_new_add_to_cart_ajax', $sets);
                }
            }
            echo "</div>";
        }
        if ($element_setup["post_element"] == 'cart-excerpt') {
            $product = wc_get_product($post->id);
            $description = wc_gzd_get_gzd_product($product)->get_mini_desc();
            echo "<div class='".$element_setup["pull"]."' style='".$style."'>".$description."</div>";
        }
        if ($element_setup["post_element"] == 'price') {
            // if(!is_callable('wc_get_product')) return;
            $product = wc_get_product($post->id);
            if ($post->id > 0 && get_post_type($post->id) == 'product' && $product) {
                $price = number_format(wc_get_price_to_display($product), 2, ',', '');
                $symbol = get_woocommerce_currency_symbol();
                $print = sprintf(get_woocommerce_price_format(), $symbol, $price);
                // debug($print);
                echo "<div class='woo-product ".$element_setup["pull"]."' style='".$style."'>
                        <div class='price'>
                            <span class='woocommerce-Price-amount amount'>".$print."</span>
                        </div>";
                if (wc_gzd_get_gzd_product($product)->get_tax_info())
                    echo '<p class="wc-gzd-additional-info tax-info">'.wc_gzd_get_gzd_product($product)->get_tax_info().'</p>';
                else if (get_option('woocommerce_gzd_small_enterprise') == 'yes')
                    echo '<p class="wc-gzd-additional-info small-business-info">'.wc_gzd_get_small_business_product_notice().'</p>';
                echo "</div>";
            }
        }
        if ($element_setup["post_element"] == 'empty') {
            
            $css = '';
            if ($posts_layout_array["post_element_layout"] == "vertical") {
                $attr = "height:";
            } else {
                $attr = "height:10px;width:";
                $css = "style='width:auto;'";
            }
            $intheight = (int) str_replace('px', '', $element_setup['empty_size']);
            // debug($intheight);
            $height_xs = $element_setup['empty_size_xs'] * $intheight;
            $height_sm = $element_setup['empty_size_sm'] * $intheight;
            $height_md = $element_setup['empty_size_md'] * $intheight;
            $height_lg = $element_setup['empty_size_lg'] * $intheight;
            
            // render
            echo "<div class='vc_blank_space ".$element_setup["pull"]."' $css>
                    <div class='vc_blank_space_inner_sm' style='".$attr.$height_xs."px;'></div>
                    <div class='vc_blank_space_inner_md' style='".$attr.$height_sm."px;'></div>
                    <div class='vc_blank_space_inner_lg' style='".$attr.$height_md."px;'></div>
                    <div class='vc_blank_space_inner_xl' style='".$attr.$height_lg."px;'></div>
                </div>";
        }
        if ($element_setup["post_element"] == 'text') {
            // render
            $text_content = replace_placeholders($element_setup["text_content"], $params);
            echo "<div class='".$element_setup["pull"]."' style='".$style.$style_text."'>".$text_content."</div>";
        }
        if ($element_setup["post_element"] == 'seperator') {
            $style_sep = "border: 0px ".$element_setup['sep_style']." ".$element_setup['sep_color']."; ";
            if ($posts_layout_array["post_element_layout"] == "vertical") {
                $style_sep .= "border-bottom-width: ".$element_setup['sep_width']."; ";
                $style_sep .= "width:".$element_setup["sep_size"]."; ";
                if ($element_setup["pull"] == 'center') $style_sep .= "margin: 0 auto; ";
                if ($element_setup["pull"] == 'right') $style_sep .= "margin: 0 0 0 auto; ";
            }
            else {
                $style_sep .= "border-right-width: ".$element_setup['sep_width']."; ";
                $style_sep .= "height:100%; ";
                $style .= "height:".$element_setup["sep_size"]."; ";
                if ($element_setup["pull"] == 'center') $style .= "align-self:center; ";
                if ($element_setup["pull"] == 'right') $style .= "align-self:flex-end; ";
            }
            // render
            echo "<div class='".$element_setup["pull"]."' style='".$style."'><div style='".$style_sep."'></div></div>";
        }
        
		$return = ob_get_contents();
		ob_end_clean();
		return $return;
    }

    public static function make_posts_pagination($posts_layout_array, $count=-1, $extra_style='') {
        
        // default style
        $style = empty($extra_style) ? '' : $extra_style;
        
        // default classes
        $class = "pagination ".$posts_layout_array['pagination_pull'];
        
        // overlap
        if ($posts_layout_array["pagination_overlap"] != "") $class .= " overlap ".$posts_layout_array["pagination_layout"];
        
        // margin top
        if (isset($posts_layout_array["pagination_margin_top"]))
            $style .= "margin-top: ".$posts_layout_array["pagination_margin_top"]."; ";
        
        $inline_arrows = true;
        $side_arrows = false;
        
        // custom arrows
        $numbers = $posts_layout_array["pagination_numbers"];
        if (strpos($posts_layout_array['pagination_layout'], '_side') > 0) {
            // debug($posts_layout_array);
            
            $inline_arrows = false;
            $side_arrows = true;
            
            if ($posts_layout_array['pagination_layout'] == 'none_side') $numbers = 'none';

            $style_arrows = "width: ".$posts_layout_array['arrows_size']."; font-size: ".$posts_layout_array['arrows_size']."; ";
            $style_arrows .= "padding: ".$posts_layout_array['arrows_padding_tb']." 0px; ";
            $style_arrows .= "margin: 0px ".$posts_layout_array['arrows_padding_lr']."; ";
            if ( !empty($posts_layout_array['arrows_size_mobile']) ) {
                $style_arrows_mobile = "width: ".$posts_layout_array['arrows_size_mobile']."; font-size: ".$posts_layout_array['arrows_size_mobile'].";";
            }

            $arrows_type = $posts_layout_array["arrows_type"];
            if ($arrows_type == '' || $arrows_type == 'icons') {
                if ($posts_layout_array["arrows_color"] != "") $style_arrows .= "color: ".$posts_layout_array["arrows_color"]."; ";
                $style_arrows_hover = ($posts_layout_array["arrows_color_hover"] != "") ? "color: ".$posts_layout_array["arrows_color_hover"].";" : "";
                $icon_arrows_previous   = isset($posts_layout_array['arrows_icon_previous']) ? $posts_layout_array['arrows_icon_previous'] : '';
                $icon_arrows_next       = isset($posts_layout_array['arrows_icon_next']) ? $posts_layout_array['arrows_icon_next'] : '';
            }
            else if ($arrows_type == 'custom') {
                $img_arrows_previous = wp_get_attachment_url($posts_layout_array['arrows_img_previous']);
                $img_arrows_next = wp_get_attachment_url($posts_layout_array['arrows_img_next']);
                $style_arrows .= "opacity: ".($posts_layout_array['arrows_opacity']/100.0)."; ";
                $style_arrows_hover = "opacity: ".($posts_layout_array['arrows_opacity_hover']/100.0)."; ";
            }
        }
        
        // only pagination
        if ( strpos($posts_layout_array['pagination_layout'], 'only_') !== false ) {
            $inline_arrows = false;
        }
        
        $style_icon = $style_nmbr = $style_hover = $style_active = $style_nmbr_mobile = $style_icon_mobile = "";
        
        if ( $numbers == '' || $numbers == 'icons' || $numbers == 'none' ) {
            if (isset($posts_layout_array['pagination_space'])) {
                $style .= "padding: ".$posts_layout_array['pagination_padding_tb']." ".$posts_layout_array['pagination_padding_lr']."; ";
                $style_icon .= "margin: 0px; ";
                $style_nmbr .= "margin: 0px calc(".$posts_layout_array['pagination_space']." / 2); ";
            }
            else {
                $style .= "padding: ".$posts_layout_array['pagination_padding']." 0px; ";
                $style_icon .= "padding: 0px ".$posts_layout_array['pagination_icon_padding']."; ";
                $style_nmbr .= "padding: 0px ".$posts_layout_array['pagination_numbers_padding']."; ";
            }

            if ($posts_layout_array["pagination_color"] != "") {
                $style_icon .= "color: ".$posts_layout_array["pagination_color"]."; ";
                $style_nmbr .= "color: ".$posts_layout_array["pagination_color"]."; ";
            }
            $style_hover .= ($posts_layout_array["pagination_color_hover"] != "") ? "color: ".$posts_layout_array["pagination_color_hover"].";" : '';
            $style_active .= ($posts_layout_array["pagination_color_active"] != "") ? "color: ".$posts_layout_array["pagination_color_active"].";" : '';
    
            $sze = "";
            if ($posts_layout_array["pagination_text_size"] == "normal") $sze .= "font-weight: 400; ";
            elseif ($posts_layout_array["pagination_text_size"] == "bold") $sze .= "font-weight: 600; ";
            elseif ($posts_layout_array["pagination_text_size"] == "small") $sze .= "font-weight: 400; font-size: 0.85em; ";
            elseif ($posts_layout_array["pagination_text_size"] == "smaller") $sze .= "font-weight: 400; font-size: 0.7em; ";
            elseif ($posts_layout_array["pagination_text_size"] == "big") $sze .= "font-weight: 400; font-size: 1.1em; ";
            elseif ($posts_layout_array["pagination_text_size"] == "bigger") $sze .= "font-weight: 400; font-size: 1.2em; ";
            elseif ($posts_layout_array["pagination_text_size"] == "biggest") $sze .= "font-weight: 600; font-size: 2.2em; ";
            else $sze .= "font-size: ".$posts_layout_array["pagination_text_size"]."; ";
            $style_icon .= $sze;
            $style_nmbr .= $sze;

            $icon_previous  = isset($posts_layout_array['pagination_icon_previous']) ? $posts_layout_array['pagination_icon_previous'] : '';
            $icon_next      = isset($posts_layout_array['pagination_icon_next']) ? $posts_layout_array['pagination_icon_next'] : '';
            $numbers_style  = isset($posts_layout_array["pagination_numbers_style"]) ? $posts_layout_array["pagination_numbers_style"] : '';
            $icon_normal    = isset($posts_layout_array['pagination_numbers_icon']) ? $posts_layout_array['pagination_numbers_icon'] : '';
            $icon_active    = isset($posts_layout_array['pagination_numbers_icon_active']) ? $posts_layout_array['pagination_numbers_icon_active'] : '';
            
        }
        else if ($numbers == 'dots' || $numbers == 'blocks') {
            if (isset($posts_layout_array['pagination_space'])) {
                $style .= "padding: ".$posts_layout_array['pagination_padding_tb']." ".$posts_layout_array['pagination_padding_lr']."; ";
                $style_nmbr .= "margin: 0px calc(".$posts_layout_array['pagination_space']." / 2); ";
                if (isset($posts_layout_array['pagination_space_mobile'])) {
                    $style_nmbr_mobile .= "margin: 0px calc(".$posts_layout_array['pagination_space_mobile']." / 2); ";
                }
            }
            else {
                $style .= "padding: ".$posts_layout_array['pagination_padding']." 0px; ";
                $style_nmbr .= "margin: 0px ".$posts_layout_array['pagination_numbers_padding']."; ";
            }

            $style_nmbr .= "width: ".$posts_layout_array['pagination_img_size']."; height: ".$posts_layout_array['pagination_img_size']."; ";
            if ($numbers == 'dots') $style_nmbr .= "border-radius: ".$posts_layout_array['pagination_img_size']."; ";
            if ( !empty($posts_layout_array['pagination_img_size_mobile']) ) {
                $style_nmbr_mobile .= "width: ".$posts_layout_array['pagination_img_size_mobile']."; height: ".$posts_layout_array['pagination_img_size_mobile']."; ";
                if ($numbers == 'dots') $style_nmbr_mobile .= "border-radius: ".$posts_layout_array['pagination_img_size_mobile']."; ";
            }
            $style_nmbr .= "background: ".($posts_layout_array["pagination_color"] != "" ? $posts_layout_array["pagination_color"] : 'lightgray')."; ";
            $style_hover .= "background: ".($posts_layout_array["pagination_color_hover"] != "" ? $posts_layout_array["pagination_color_hover"] : 'lightgray')."; ";
            $style_active .= "background: ".($posts_layout_array["pagination_color_active"] != "" ? $posts_layout_array["pagination_color_active"] : 'gray')."; ";
        }
        else if ($numbers == 'custom') {
            $img_previous = wp_get_attachment_url($posts_layout_array['pagination_img_previous']);
            $img_normal = wp_get_attachment_url($posts_layout_array['pagination_numbers_img']);
            $img_active = wp_get_attachment_url($posts_layout_array['pagination_numbers_img_active']);
            $img_next = wp_get_attachment_url($posts_layout_array['pagination_img_next']);

            if (isset($posts_layout_array['pagination_space'])) {
                $style .= "padding: ".$posts_layout_array['pagination_padding_tb']." ".$posts_layout_array['pagination_padding_lr']."; ";
                $style_icon .= "margin: 0px; ";
                $style_nmbr .= "margin: 0px calc(".$posts_layout_array['pagination_space']." / 2); ";
                if (isset($posts_layout_array['pagination_space_mobile'])) {
                    $style_nmbr_mobile .= "margin: 0px calc(".$posts_layout_array['pagination_space_mobile']." / 2); ";
                }
            }
            else {
                $style .= "padding: ".$posts_layout_array['pagination_padding']." 0px; ";
                $style_icon .= "margin: 0px ".$posts_layout_array['pagination_icon_padding']."; ";
                $style_nmbr .= "margin: 0px ".$posts_layout_array['pagination_numbers_padding']."; ";
            }

            $opacity = "opacity: ".($posts_layout_array['pagination_opacity']/100.0)."; ";
            $style_hover .= "opacity: ".($posts_layout_array['pagination_opacity_hover']/100.0)."; ";
            $style_active .= "opacity: ".($posts_layout_array['pagination_opacity_active']/100.0)."; ";
            $img_size = "width: ".$posts_layout_array['pagination_img_size']."; height: ".$posts_layout_array['pagination_img_size']."; ";
            $style_icon .= $img_size.$opacity;
            $style_nmbr .= $img_size.$opacity;
            if ( !empty($posts_layout_array['pagination_img_size_mobile']) ) {
                $style_nmbr_mobile .= "width: ".$posts_layout_array['pagination_img_size_mobile']."; height: ".$posts_layout_array['pagination_img_size_mobile']."; ";
                $style_icon_mobile .= "width: ".$posts_layout_array['pagination_img_size_mobile']."; height: ".$posts_layout_array['pagination_img_size_mobile']."; ";
            }
        }

        // get wp pagination links
        if ($count == -1) {
            $props = array(
                'current' => 0,
                'previous_link' => '',
                'next_link' => '',
                'pages' => array()
            );

            $paged = get_query_var('paged');
            if ( !$paged ) {
                global $wp_query;
                $paged = $wp_query->paged;
            }
            $pagination_array = paginate_links( array(
                'prev_text' => 'x',
                'next_text' => 'x',
                'type' => 'array',
                'current' => $paged ? $paged : 1
            ) );
            
            if (!$pagination_array) return;

            foreach ($pagination_array as $link) {
                // debug( esc_attr($link) );
                // <span aria-current="page" class="page-numbers current">2</span>

                // get href
                $href = "";
                preg_match( '/href="([^"])+?"/', $link, $matches );
                if ( $matches && count($matches) ) {
                    $href = str_replace( array('href="', '"'), "", $matches[0] );
                }

                // prev
                if (strpos($link, 'prev')) {
                    $props['previous_link'] = $href;
                }

                // next
                else if (strpos($link, 'next')) {
                    $props['next_link'] = $href;
                }

                // page numbers
                else {
                    // get page number (either a number or the filler "…")
                    $num = null;
                    preg_match( '/>([^<])+?</', $link, $matches );
                    if ( $matches && count($matches) ) {
                        $num = str_replace( array('>', '<'), "", $matches[0] );
                    }

                    // current page
                    if (strpos($link, 'current')) {
                        $props['current'] = $num;
                        $href = "";
                    }
                    
                    if ( isset($props['pages'][$num]) ) $num = "&#8230;"; // filler "…" could be set twice on long paginations

                    $props['pages'][$num] = $href;
                }
            }
        }
        // make js pagination
        else {
            // $class .= " js";
            $props = array(
                'current' => 1,
                'previous_link' => '',
                'next_link' => '',
                'pages' => array()
            );
            if ( is_numeric($count) && $count > 0 && $count < 100 ) {
                for ($i=1; $i<=$count; $i++) {
                    $props['pages'][$i] = "";
                }
            }
        }
        // debug($pages);

        // render
        ob_start();

        // inline style
        $id = "pgn_".uniqid();
        $style = "#".$id." { ".$style." } ";
        $style_mobile = "";
        if (isset($posts_layout_array['pagination_space'])) {
            $style .= "#".$id." .pgn_numbers a:first-child .pgn_number { margin-left: 0px !important; } ";
            $style .= "#".$id." .pgn_numbers a:last-child .pgn_number { margin-right: 0px !important; } ";
        }
        if ($inline_arrows) {
            $style .= "#".$id." .pgn_previous, #".$id." .pgn_next { ".$style_icon." } ";
            if ( !empty($style_icon_mobile) ) $style_mobile .= "#".$id." .pgn_number { ".$style_icon_mobile." } ";
            if ($numbers == 'custom') {
                $style .= "#".$id." .pgn_previous { background: ".($img_previous ? "url(".$img_previous.")" : "lightgray")."; } ";
                $style .= "#".$id." .pgn_next { background: ".($img_next ? "url(".$img_next.")" : "lightgray")."; } ";
            }
            $style .= "#".$id." .pgn_previous:hover, #".$id." .pgn_next:hover { ".$style_hover." } ";
        }
        if ($numbers != 'none') {
            $style .= "#".$id." .pgn_number { ".$style_nmbr." } ";
            if ( !empty($style_nmbr_mobile) ) $style_mobile .= "#".$id." .pgn_number { ".$style_nmbr_mobile." } ";
            if ($numbers == 'custom') {
                $style .= "#".$id." .pgn_number { background: ".($img_normal ? "url(".$img_normal.")" : "lightgray")."; } ";
                $style .= "#".$id." .pgn_number.pgn_current { background: ".($img_active ? "url(".$img_active.")" : "lightgray")."; } ";
            }
            $style .= "#".$id." .pgn_number:hover { ".$style_hover." } ";
            $style .= "#".$id." .pgn_number.pgn_current { ".$style_active." } ";
        }
        if ($side_arrows) {
            $style .= "#".$id."_next { right: 0px; } ";
            $style .= "#".$id."_previous.pgn_arrows, #".$id."_next.pgn_arrows { ".$style_arrows." } ";
            if ( !empty($style_arrows_mobile) ) $style_mobile .= "#".$id."_previous.pgn_arrows, #".$id."_next.pgn_arrows { ".$style_arrows_mobile." } ";
            if ($arrows_type == 'custom') {
                $sze = "width: ".$posts_layout_array['arrows_size']."; height: ".$posts_layout_array['arrows_size']."; ";
                $style .= "#".$id."_previous .pgn_previous { ".$sze." background: ".($img_arrows_previous ? "url(".$img_arrows_previous.")" : "lightgray")."; } ";
                $style .= "#".$id."_next .pgn_next { ".$sze." background: ".($img_arrows_next ? "url(".$img_arrows_next.")" : "lightgray")."; } ";
                if ( !empty($posts_layout_array['arrows_size_mobile']) ) {
                    $style_mobile .= "#".$id."_next .pgn_next, #".$id."_previous .pgn_previous { width: ".$posts_layout_array['arrows_size_mobile']."; height: ".$posts_layout_array['arrows_size_mobile']."; } ";
                }
            }
            $style .= "#".$id."_previous .pgn_previous:hover, #".$id."_next .pgn_next:hover { ".$style_arrows_hover." } ";
        }
        if ( !empty($style_mobile) ) $style .= "@media (max-width: var(grid_md)) { ".$style_mobile." }";
        \enqueue::add_custom_style($style);
        
        /**
         * Render side arrows (for sliders)
         */
        if ( $side_arrows ) {
            
            $href = $props['previous_link'] != "" ? "href='".$props['previous_link']."'" : "";

            // arrow classes
            $side_arrow_classes     = array(
                "pgn_arrows",
                strpos($posts_layout_array['pagination_layout'], 'bottom') === 0 ? 'top' : 'bottom',
                "align".$posts_layout_array["arrows_align"]
            );
            if ( !empty($posts_layout_array["arrows_align_mobile"]) ) {
                $side_arrow_classes[] = "alignmobile".$posts_layout_array["arrows_align_mobile"];
            }

            // icon classes
            $side_icon_classes     = array("animate_fast", "pgn_previous");
            if ( isset($icon_arrows_previous) ) {
                $side_icon_classes[] = $icon_arrows_previous;
            }
            if ( $props['current'] == 1 ) {
                $side_icon_classes[] = "pgn_current";
            }

            // render the left arrow
            echo "<a id='".$id."_previous' $href class='".implode(" ", $side_arrow_classes)."' data-pagelink='prev' aria-label='".__("zum vorherigen Slide", "core")."'>
                <span class='".implode(" ", $side_icon_classes)."' aria-hidden='true'></span>
            </a>";

            $href = $props['next_link'] != "" ? "href='".$props['next_link']."'" : "";

            // icon classes
            $side_icon_classes     = array("animate_fast", "pgn_next");
            if ( isset($icon_arrows_next) ) {
                $side_icon_classes[] = $icon_arrows_next;
            }
            if ( $count == -1 && empty($href) ) {
                $side_icon_classes[] = "pgn_current";
            }

            echo "<a id='".$id."_next' $href class='".implode(" ", $side_arrow_classes)."' data-pagelink='next' aria-label='".__("zum nächsten Slide", "core")."'>
                <span class='".implode(" ", $side_icon_classes)."' aria-hidden='true'></span>
            </a>";
        }

        /**
         * Render the normal pagination bar
         */
        if ( $inline_arrows || $numbers != 'none' ) {

            // wrapper start
            echo "<div id='".$id."' class='".$class."'".( isset($icon_normal) ? " data-iconnormal='".$icon_normal."'" : "").( isset($icon_active) ? " data-iconactive='".$icon_active."'" : "").">";

            // previous link
            if ($inline_arrows) {
                $class = (isset($icon_previous) ? $icon_previous : "")." pgn_previous";
                $href = !empty($props['previous_link']) ? "href='".$props['previous_link']."'" : "";
                if ($props['current'] == 1) $class .= " pgn_current";

                echo    "<a ".$href." data-pagelink='prev' aria-label='".__("zum vorherigen Slide", "core")."'><span class='animate_fast ".$class."' aria-hidden='true'></span></a>";
            }

            // numbers
            if ($numbers != 'none' && count($props['pages'])) {

                echo "<span class='pgn_numbers'>";

                foreach ( $props['pages'] as $num => $href ) {

                    $classes = ["animate_fast", "pgn_number"];
                    if ($props['current'] == $num) $classes[] = "pgn_current";
                    
                    if (!empty($href)) $href = "href='".$href."'";

                    if ( is_numeric($num) ) {
                        $inner_content = '';
                        if ($numbers == '') {
                            $inner_content = helper::make_pagination_number_style(intval($num), $numbers_style);
                        }
                        else if ($numbers == 'icons') {
                            $classes[] = $props['current'] == $num ? $icon_active : $icon_normal;
                        }

                        echo "<a ".$href." data-pagelink='".$num."' aria-label='".sprintf(__("zu Slide %s", "core"), strval($num) )."'><span class='".implode(" ", $classes)."' >".$inner_content."</span></a>";
                    }

                    // ellipsis
                    else {
                        echo "<span class='".implode(" ", $classes)."' style='cursor: default;' >$num</span>";
                    }
                }

                echo "</span>";
            }

            // next link
            if ($inline_arrows) {
                $class = (isset($icon_next) ? $icon_next : "")." pgn_next";
                $href = !empty($props['next_link']) ? "href='".$props['next_link']."'" : "";
                if ( $count == -1 && empty($href) ) $class .= " pgn_current"; // hide when last page

                echo    "<a ".$href." data-pagelink='next' aria-label='".__("zum nächsten Slide", "core")."'><span class='animate_fast ".$class."' aria-hidden='true'></span></a>";
            }

            // wrapper end
            echo "</div>";
        }

        $return = ob_get_contents();
        ob_end_clean();
        return $return;
    }

    public static function make_posts_sort_dropdown($atts=[], $pre='', $is_template=false) {
        // basic atts
        $type           = "sorting";
        $content        = "";
        $id             = uniqid($type."_");
        $pre            = preg_replace("/_$/", "", $pre);
        $width          = isset($atts[$pre.'_width']) ? helper::force_units( esc_attr($atts[$pre.'_width']), ['px','%'] ) : "";
        $margin_bottom  = isset($atts[$pre.'_margin_bottom']) ? helper::force_units( esc_attr($atts[$pre.'_margin_bottom']), ['px','%'] ) : "";
        $margin_top     = isset($atts[$pre.'_margin_top']) ? helper::force_units( esc_attr($atts[$pre.'_margin_top']), ['px','%'] ) : "";
        $class          = isset($atts[$pre.'_style']) ? str_replace( array("_".$type, "_input", "_"), "", esc_attr($atts[$pre.'_style']) ) : "";

        $inline_style   = isset($atts[$pre.'_inline_style']) ? $atts[$pre.'_inline_style'] : "";
        $align          = isset($atts[$pre.'_position'][0]) ? esc_attr($atts[$pre.'_position'][0]) : "";
        $value          = isset($atts[$pre.'_mode_value']) ? esc_attr($atts[$pre.'_mode_value']) : "";



        // individual names for dropdown options. if not set use the default names
        $option_name_text_date_desc  = isset($atts[$pre.'_text_date_desc'])  ? $atts[$pre.'_text_date_desc']  : _x('chronologisch (Neueste zuerst)', 'small', 'core');
        $option_name_text_date_asc   = isset($atts[$pre.'_text_date_asc'])   ? $atts[$pre.'_text_date_asc']   : _x('chronologisch (Älteste zuerst)', 'small', 'core');
        $option_name_text_title_asc  = isset($atts[$pre.'_text_title_asc'])  ? $atts[$pre.'_text_title_asc']  : _x('alphabetisch (aufsteigend)', 'small', 'core');
        $option_name_text_title_desc = isset($atts[$pre.'_text_title_desc']) ? $atts[$pre.'_text_title_desc'] : _x('alphabetisch (absteigend)', 'small', 'core');

        $option_name_text_views_desc = isset($atts[$pre.'_text_views_desc'])  ? $atts[$pre.'_text_views_desc']  : _x('meist gelesen', 'small', 'core');
        $option_name_text_relevance_desc = isset($atts[$pre.'_text_relevance_desc'])  ? $atts[$pre.'_text_relevance_desc']  : _x('Relevanz', 'small', 'core');

        //debug($atts);
        
        // standard options
        $options = array(
            _x('sortieren nach', 'small', 'core') => '',
            $option_name_text_relevance_desc => 'relevance DESC',
            $option_name_text_views_desc => 'views DESC',
            $option_name_text_date_desc  => 'date DESC',
            $option_name_text_date_asc => 'date ASC',
            $option_name_text_title_asc  => 'title ASC',
            $option_name_text_title_desc => 'title DESC',
        );

        // get advanced search settings
        $settings           = \basics::get_setting(array('site', 'advanced_search'));

        // check if postviews_counter enabled
        $postviews_counter  = $settings['postviews_counter'] === 'true' ? true : false;
        if ( !$postviews_counter ) unset( $options[$option_name_text_views_desc] );

        // check if relevance enabled
        $relevance_search   = $settings['relevance'] === 'true' && is_search() ? true : false;
        if ( !$relevance_search || !$is_template ) unset( $options[$option_name_text_relevance_desc] );

        // check if live_search enabled
        $live_search        = $settings['live_search'] === 'true' && is_search() ? true : false;

        if (empty($value) && $is_template && $relevance_search) {
            $value = "relevance DESC";
        }

        // if this dropdown sits in an achive- or search-template
        if ($is_template && !$live_search) {
            global $wp;
            $query_vars = $wp->query_vars;
            if ( isset($query_vars['paged']) ) unset( $query_vars['paged'] );
            $url = add_query_arg( $query_vars, preg_replace( "/page\/\d+/", "", home_url($wp->request) ) );
            $url = remove_query_arg(array('meta_query', 'orderby', 'order'), $url); // remove our query vars by default

            //generate query_urls
            $query_url = array();
            foreach ($options as $option => $value) {
                $options[$option] = array(
                    'value'     => $value,
                    'query_url' => $url
                );
                if ( !empty($value) ) {
                    list($orderby, $order) = !empty($value) ? explode(' ', $value) : array("","");
                    $options[$option]['query_url'] = esc_url(add_query_arg(array('orderby' => $orderby, 'order'   => $order), $url));
                }
            }

            // add postview-count query if enabled
            if($postviews_counter) {
                $postviews_query = array(
                    "orderby"  => 'meta_value_num',
                    "order"    => 'DESC',
                    'meta_query' => array(
                        'relation' => 'OR',
                        array(
                            'key' => 'postviews_count', 
                            'compare' => 'EXISTS',
                        ),
                        array(
                            'key' => 'postviews_count', 
                            'compare' => 'NOT EXISTS',
                        )
                    ),
                );
                $options[_x('meist gelesen', 'small', 'core')]['query_url'] = esc_url(add_query_arg($postviews_query, $url));
            }
            
            if (isset($query_vars['orderby']) && isset($query_vars['order'])) {
                if ($query_vars['orderby'] == 'meta_value_num' && $postviews_counter) {
                    $value = "views DESC";
                } else {
                    $value = $query_vars['orderby']." ".$query_vars['order'];
                }
            } else if ($relevance_search) {
                $value = 'relevance DESC';
            } else {
                $value = '';
            }
        } 

        
        // basic styles
        $styles = array( '' => '' );
        if ( !empty($align)) $styles['']         .= "display: flex; justify-content: $align; ";
        if ( !empty($margin_top)) $styles['']    .= "margin-top: $margin_top; ";
        if ( !empty($margin_bottom)) $styles[''] .= "margin-bottom: $margin_bottom; ";
        if ( !empty($width)) {
            $styles['.custom-select'] = "max-width: $width; ";
        } else {
            $styles['.custom-select'] = "max-width: 300px; "; //set default max-width
        }
        
        // make custom select
        $content =
        "<div class='custom-select $class' style='$inline_style'>
            <select name='sorting'>";
                foreach( $options as $label => $val ) {
                
                    if (empty($value) && !$relevance_search) {
                        $value = 'date DESC';
                    }

                    if ($is_template && !$live_search) {
                        $selected = (isset($val['value']) && $val['value'] === $value) ? "selected='selected'" : "";
                        $val = $val['query_url'];
                    } else {
                        $selected = ($val === $value) ? "selected='selected'" : "";
                    }
                    
                    $content .= "<option value='$val' ".$selected.">$label</option>";
                }
        $content .= "</select></div>";

        // enqueue custom css
        $style = "";
        foreach ( $styles as $selector => $css ) {
            if ( !empty($css) ) $style .= "#".$id." $selector { ".$css.( strpos($css, ";") === false ? ";" : "" )." } ";
        }
        // stretch the dropdown to 100% on mobile
        $style .= "@media (max-width: var(grid_sm)) { #".$id." .custom-select { max-width: 100%; } }"; 
        \enqueue::add_custom_style($style);

        
        // return html
        return "<div id='$id' class='input-wrapper'>$content</div>";
    }
    
    public static function make_load_more_button($atts=[], $pre='') {
        $content        = "";
        $width          = isset($atts[$pre.'_width']) ? helper::force_units( esc_attr($atts[$pre.'_width']), ['px','%'] ) : "";
        $align          = isset($atts[$pre.'_align']) ? esc_attr($atts[$pre.'_align']) : "";
        $class          = isset($atts[$pre.'_style']) ? trim(str_replace( "_", "", esc_attr($atts[$pre.'_style']) )) : "button";
        $inline_style   = $class === 'custom' ? helper::make_custom_element($atts, $pre."_") : "";

        // vars
        $text   = isset($atts[$pre.'_text']) ? esc_attr($atts[$pre.'_text']) : __("mehr laden", "core");
        $text   = \vc\helper::make_custom_icon($atts, $pre, $text);
        $size   = isset($atts[$pre.'_size']) ? str_replace( "_", "", esc_attr($atts[$pre.'_size']) ) : '';
        
        // html  padding-top: 0.8em; 
        $content = "<div class='load_more_wrapper'><div class='$class $size load_more' style='display:none; $inline_style'>$text</div></div>";
        return $content;
    }

    /**
     * =================================================================
     *                          Helper
     * =================================================================
     */
    public static function preg_match_keys($pattern, $input, $flags = 0) {
        return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags)));
    }
}
