, 'title' => __( 'Link Setting', 'avia_framework' ), 'content' => $c ), ); AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'advanced_link' ), $template ); } /** * Editor Element - this function defines the visual appearance of an element on the AviaBuilder Canvas * Most common usage is to define some markup in the $params['innerHtml'] which is then inserted into the drag and drop container * Less often used: $params['data'] to add data attributes, $params['class'] to modify the className * * * @param array $params this array holds the default values for $content and $args. * @return $params the return array usually holds an innerHtml key that holds item specific markup. */ function editor_element( $params ) { $params = parent::editor_element( $params ); $params['innerHtml'] .= AviaPopupTemplates()->get_html_template( 'alb_element_fullwidth_stretch' ); $params['content'] = null; //remove to allow content elements return $params; } /** * Frontend Shortcode Handler * * @param array $atts array of attributes * @param string $content text within enclosing form of shortcode element * @param string $shortcodename the shortcode found, when == callback name * @return string $output returns the modified html string */ function shortcode_handler( $atts, $content = '', $shortcodename = '', $meta = '' ) { $default = avia_post_grid::get_defaults(); $locked = array(); Avia_Element_Templates()->set_locked_attributes( $atts, $this, $shortcodename, $default, $locked, $content ); Avia_Element_Templates()->add_template_class( $meta, $atts, $default ); extract( AviaHelper::av_mobile_sizes( $atts ) ); //return $av_font_classes, $av_title_font_classes and $av_display_classes $atts = array_merge( $default, $atts ); if( 'disabled' == $atts['img_scrset'] ) { Av_Responsive_Images()->force_disable( 'disabled' ); } if( current_theme_supports( 'avia_template_builder_custom_post_type_grid' ) ) { if( isset( $atts['link'] ) ) { $atts['link'] = explode( ',', $atts['link'], 2 ); $atts['taxonomy'] = $atts['link'][0]; if( isset( $atts['link'][1] ) ) { $atts['categories'] = $atts['link'][1]; } } if( empty( $atts['post_type'] ) || ! current_theme_supports( 'add_avia_builder_post_type_option' ) ) { $atts['post_type'] = get_post_types(); } if( is_string( $atts['post_type'] ) ) { $atts['post_type'] = explode( ',', $atts['post_type'] ); } } else { /** * @used_by config-wpml\config.php avia_wpml_translate_object_ids() * @since 4.6.4 * @param string * @param string * @param avia_sc_portfolio $this * @return string */ $atts['categories'] = apply_filters( 'avf_alb_taxonomy_values', $atts['categories'], 'portfolio_entries' ); } self::$portfolio_count ++; $el_id = ! empty( $meta['custom_el_id'] ) ? $meta['custom_el_id'] : ' id="av-sc-portfolio-' . self::$portfolio_count . '" '; $atts['class'] = ! empty( $meta['custom_class'] ) ? $meta['custom_class'] : ''; $atts['el_id'] = ''; $atts['fullscreen'] = ShortcodeHelper::is_top_level(); if( ! $atts['fullscreen'] ) { $atts['el_id'] = $el_id; } $grid = new avia_post_grid( $atts ); $grid->query_entries(); $portfolio_html = $grid->html(); $portfolio_html = Av_Responsive_Images()->make_content_images_responsive( $portfolio_html ); Av_Responsive_Images()->force_disable( 'reset' ); if( ! ShortcodeHelper::is_top_level() ) { return $portfolio_html; } $params['class'] = "main_color avia-no-border-styling avia-fullwidth-portfolio {$av_display_classes} {$meta['el_class']}"; $params['open_structure'] = false; $params['id'] = AviaHelper::save_string( $meta['custom_id_val'] , '-', 'av-sc-portfolio-' . self::$portfolio_count ); $params['custom_markup'] = $meta['custom_markup']; //we dont need a closing structure if the element is the first one or if a previous fullwidth element was displayed before if( isset( $meta['index'] ) && $meta['index'] == 0 ) { $params['close'] = false; } if( ! empty( $meta['siblings']['prev']['tag'] ) && in_array( $meta['siblings']['prev']['tag'], AviaBuilder::$full_el_no_section ) ) { $params['close'] = false; } $output = avia_new_section( $params ); $output .= $portfolio_html; $output .= avia_section_after_element_content( $meta , 'after_portfolio' ); return $output; } } } if ( ! class_exists( 'avia_post_grid' ) ) { class avia_post_grid { /** * * @var int */ static protected $grid = 0; /** * * @var array */ static protected $preview_template = array(); /** * * @var array */ protected $atts; /** * * @var WP_Query */ protected $entries; /** * * @var array */ protected $screen_options; /** * * @since 4.7.6.4 * @var int */ protected $current_page; /** * * @param type $atts */ public function __construct( $atts = array() ) { $this->entries = null; $this->screen_options = AviaHelper::av_mobile_sizes( $atts ); $this->current_page = 1; $this->atts = shortcode_atts( avia_post_grid::get_defaults(), $atts, 'av_portfolio' ); if( $this->atts['linking'] == 'ajax' ) { add_action( 'wp_footer' , array( $this, 'print_preview_templates' ) ); } } /** * * @since 4.5.7.2 */ public function __destruct() { unset( $this->atts ); unset( $this->screen_options ); unset( $this->entries ); } /** * Returns the default array for this class * * @since 4.8 * @return array */ static public function get_defaults() { $default = array( 'style' => '', 'linking' => '', 'columns' => '4', 'items' => '16', 'contents' => 'title', 'sort' => 'yes', 'paginate' => 'yes', 'categories' => '', 'preview_mode' => 'auto', 'image_size' => 'portfolio', 'post_type' => 'portfolio', 'taxonomy' => 'portfolio_entries', 'one_column_template' => 'special', 'set_breadcrumb' => true, //no shortcode option for this, modifies the breadcrumb nav, must be false on taxonomy overview 'class' => '', 'el_id' => '', 'custom_markup' => '', 'fullscreen' => false, 'query_orderby' => 'date', 'query_order' => 'DESC', 'date_filter' => '', 'date_filter_start' => '', 'date_filter_end' => '', 'date_filter_format' => 'yy/mm/dd', // 'yy/mm/dd' | 'dd-mm-yy' | yyyymmdd 'period_filter_unit_1' => '', 'period_filter_unit_2' => '', 'lazy_loading' => 'disabled', 'img_scrset' => '' ); return $default; } /** * enerates the html of the post grid * * @since < 4.0 * @since 4.8 added $query_var_page * @param string $query_var_page set to '' to use stamdard WP pagination query var (e.g. from taxonomy-portfolio_entries.php) * @return string */ public function html( $query_var_page = 'avia-element-paging' ) { if( empty( $this->entries ) || empty( $this->entries->posts ) ) { return ''; } avia_post_grid::$grid ++; extract( $this->screen_options ); //return $av_font_classes, $av_title_font_classes and $av_display_classes extract( $this->atts ); $container_id = avia_post_grid::$grid; $extraClass = 'first'; $grid = 'one_fourth'; if( $preview_mode == 'auto' ) { $image_size = 'portfolio'; } $post_loop_count = 1; $loop_counter = 1; $output = ''; $style_class = empty( $style ) ? 'no_margin' : $style; $total = $this->entries->post_count % 2 ? 'odd' : 'even'; $post_type_paginate = array(); if( $set_breadcrumb && is_page() ) { if( ! is_array( $post_type ) ) { $_SESSION["avia_{$post_type}"] = get_the_ID(); $post_type_paginate[] = $post_type; } else { $filtered = array(); foreach( $this->entries->posts as $entry ) { if( ! $entry instanceof WP_Post ) { continue; } if( ! in_array( $entry->post_type, $filtered ) ) { $filtered[] = $entry->post_type; } } foreach( $filtered as $pt ) { $_SESSION[ "avia_{$pt}" ] = get_the_ID(); $post_type_paginate[] = $pt; } } } switch( $columns ) { case '1': $grid = 'av_fullwidth'; if( $preview_mode == 'auto' ) { $image_size = 'featured'; } break; case '2': $grid = 'av_one_half'; break; case '3': $grid = 'av_one_third'; break; case '4': $grid = 'av_one_fourth'; if( $preview_mode == 'auto' ) { $image_size = 'portfolio_small'; } break; case '5': $grid = 'av_one_fifth'; if( $preview_mode == 'auto' ) { $image_size = 'portfolio_small'; } break; case '6': $grid = 'av_one_sixth'; if( $preview_mode == 'auto' ) { $image_size = 'portfolio_small'; } break; } if( $fullscreen && $preview_mode =='auto' && $image_size == 'portfolio_small' ) { $image_size = 'portfolio'; } if( $sort != 'no' ) { $output .= '
'; $el_id = ''; } $output .= $sort != 'no' ? $this->sort_buttons( $this->entries->posts, $this->atts ) : ''; if( $linking == 'ajax' ) { $container_class = $fullscreen ? 'container' : ''; $output .= "
"; } $output .= "'; if( $sort != 'no' ) { $output .= '
'; } //append pagination if( $paginate == 'yes' && $avia_pagination = avia_pagination( $this->entries->max_num_pages, 'nav', $query_var_page, $this->current_page ) ) { $post_type_paginate = array_map( function( $value ) { return 'pagination-' . $value; }, $post_type_paginate ); $post_type_paginate = implode( ' ', $post_type_paginate ); $output .= "
{$avia_pagination}
"; } return $output; } /** * Generates the html for the sort buttons * * @param array $entries * @param array $params * @return string */ protected function sort_buttons( $entries, $params ) { //get all categories that are actually listed on the page $categories = get_categories( array( 'taxonomy' => $params['taxonomy'], 'hide_empty' => 0 ) ); $current_page_cats = array(); $cat_count = array(); $display_cats = is_array( $params['categories'] ) ? $params['categories'] : array_filter( explode( ',', $params['categories'] ) ); foreach( $entries as $entry ) { $current_item_cats = get_the_terms( $entry->ID, $params['taxonomy'] ); if( is_array( $current_item_cats ) && ! empty( $current_item_cats ) ) { foreach( $current_item_cats as $current_item_cat ) { if( empty( $display_cats ) || in_array( $current_item_cat->term_id, $display_cats ) ) { $current_page_cats[ $current_item_cat->term_id ] = $current_item_cat->term_id; if( ! isset( $cat_count[ $current_item_cat->term_id ] ) ) { $cat_count[ $current_item_cat->term_id ] = 0; } $cat_count[ $current_item_cat->term_id ] ++; } } } } extract( $this->screen_options ); //return $av_font_classes, $av_title_font_classes and $av_display_classes $output = "
"; $hide = count( $current_page_cats ) <= 1 ? 'hidden' : ''; $first_item_name = apply_filters( 'avf_portfolio_sort_first_label', __( 'All', 'avia_framework' ), $params ); $first_item_html = '' . $first_item_name . ' ' . count( $entries ) . ' '; $output .= apply_filters( 'avf_portfolio_sort_heading', '', $params ); if( strpos( $this->atts['sort'], 'tax' ) !== false ) { $output .= "
{$first_item_html}
"; } $output .= "
"; $output .= '' . $first_item_html . ''; foreach( $categories as $category ) { if( in_array( $category->term_id, $current_page_cats ) ) { //fix for cyrillic, etc. characters - isotope does not support the % char $category->category_nicename = str_replace( '%', '', $category->category_nicename ); $output .= "/"; $output .= ''; $output .= "" . esc_html( trim( $category->cat_name ) ) . ""; $output .= " " . $cat_count[ $category->term_id ] . " "; $output .= ''; } } $output .= '
'; return $output; } // /** * Get the categories for each post and create a string that serves as classes so the javascript can sort by those classes * * @param int $the_id * @param array $params * @return string */ protected function sort_cat_string( $the_id, $params ) { $sort_classes = ''; $item_categories = get_the_terms( $the_id, $params['taxonomy'] ); if( is_object( $item_categories ) || is_array( $item_categories ) ) { foreach( $item_categories as $cat ) { //fix for cyrillic, etc. characters - isotope does not support the % char $cat->slug = str_replace('%', '', $cat->slug ); $sort_classes .= $cat->slug . '_sort '; } } return $sort_classes; } /** * * @param WP_Post $entry * @return string */ protected function build_preview_template( $entry ) { if( isset( avia_post_grid::$preview_template[ $entry->ID ] ) ) { return ''; } avia_post_grid::$preview_template[ $entry->ID ] = true; $id = $entry->ID; $output = ''; $defaults = array( 'ids' => get_post_thumbnail_id( $id ), 'text' => apply_filters( 'get_the_excerpt', $entry->post_excerpt ), 'method' => 'gallery', 'auto' => '', 'columns' => 5 ); $params['ids'] = get_post_meta( $id , '_preview_ids', true ); $params['text'] = get_post_meta( $id , '_preview_text', true ); $params['method'] = get_post_meta( $id , '_preview_display', true ); $params['interval'] = get_post_meta( $id , '_preview_autorotation', true ); $params['columns'] = get_post_meta( $id , '_preview_columns', true ); $params['preview_size'] = apply_filters( 'avf_ajax_preview_image_size', 'gallery' ); $params['autoplay'] = is_numeric( $params['interval'] ) ? 'true' : 'false'; $link = get_post_meta( $id ,'_portfolio_custom_link', true ) != '' ? get_post_meta( $id , '_portfolio_custom_link_url', true ) : get_permalink( $id ); //merge default and params array. remove empty params with array_filter $params = array_merge( $defaults, array_filter( $params ) ); $params = apply_filters( 'avf_portfolio_preview_template_params', $params, $entry ); global $avia_config; /** * Fullwidth shortcodes like "Fullwidth Button" will break layout because they create an own section. * This allows to return without creating new sections * * @since 4.7.6.4 */ if( ! isset( $avia_config['portfolio_preview_template'] ) ) { $avia_config['portfolio_preview_template'] = 0; } $avia_config['portfolio_preview_template'] ++; //set the content $content = str_replace( ']]>', ']]>', apply_filters( 'the_content', $params['text'] ) ); unset( $params['text'] ); if( isset( $avia_config['portfolio_preview_template'] ) ) { $avia_config['portfolio_preview_template'] --; if( $avia_config['portfolio_preview_template'] <= 0 ) { unset( $avia_config['portfolio_preview_template'] ); } } //set images $string = ''; //set first class if preview images are deactivated $nogalleryclass = ''; $params['ajax_request'] = true; switch( $params['method'] ) { case 'gallery': $params['style'] = 'big_thumb'; $params['thumb_size'] = 'square'; foreach( $params as $key => $param ) { $string .= $key . "='" . $param . "' "; } $images = do_shortcode( "[av_gallery {$string}]" ); break; case 'slideshow': $params['size'] = $params['preview_size']; foreach( $params as $key => $param ) { $string .= $key . "='" . $param . "' "; } $images = do_shortcode( "[av_slideshow {$string}]" ); break; case 'list': $images = $this->post_images( $params['ids'] ); break; case 'no': $images = false; $nogalleryclass = ' no_portfolio_preview_gallery '; break; } $output .= "
"; $output .= "
'entry', 'echo' => false, 'id' => $id, 'custom_markup' => $this->atts['custom_markup'] ) ) . ">"; if( ! empty( $images ) ) { $output .= "
"; $output .= $images; $output .= '
'; } if( ! empty( $nogalleryclass ) ) { $nogalleryclass .= ' first '; } $markup = avia_markup_helper( array( 'context' => 'entry_title', 'echo' => false, 'id' => $id, 'custom_markup' => $this->atts['custom_markup'] ) ); $default_heading = 'h2'; $args = array( 'heading' => $default_heading, 'extra_class' => '' ); $extra_args = array( $this, $entry, __METHOD__ ); /** * @since 4.5.5 * @return array */ $args = apply_filters( 'avf_customize_heading_settings', $args, __CLASS__, $extra_args ); $heading = ! empty( $args['heading'] ) ? $args['heading'] : $default_heading; $css = ! empty( $args['extra_class'] ) ? $args['extra_class'] : ''; $output .= "
"; $output .= '
'; $output .= "<{$heading} class='portfolio-preview-title entry-title {$css}' {$markup}>" . avia_wp_get_the_title( $entry ) . ""; $output .= '
'; $output .= "
'entry_content', 'echo' => false, 'id' => $id, 'custom_markup' => $this->atts['custom_markup'] ) ) . ">"; $output .= $content; $output .= '
'; $output .= ""; $output .= '
'; $output .= ''; $output .= '
'; $output .= '
'; return "\n\n"; } /** * * @param string $ids * @return string */ protected function post_images( $ids ) { if( empty( $ids ) ) { return; } $attachments = get_posts( array( 'include' => $ids, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'post__in' ) ); $output = ''; foreach( $attachments as $attachment ) { // create array with responsive info for lightbox $img = Av_Responsive_Images()->responsive_image_src( $attachment->ID, 'large' ); $alt = get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ); $alt = ! empty( $alt ) ? esc_attr( $alt ) : ''; $title = trim( $attachment->post_title ) ? esc_attr( $attachment->post_title ) : ''; $description = trim( $attachment->post_content ) ? esc_attr( $attachment->post_content ) : ''; $img_tag = "{$alt}"; $img_tag = Av_Responsive_Images()->prepare_single_image( $img_tag, $attachment->ID, $this->atts['lazy_loading'] ); $lightbox_attr = Av_Responsive_Images()->html_attr_image_src( $img, false ); $output .= ""; $output .= $img_tag; $output .= ''; } return $output; } /** * Output the preview templates in footer * */ public function print_preview_templates() { foreach( $this->entries->posts as $entry ) { echo $this->build_preview_template( $entry ); } } /** * Get the entries and add to local variable * * @param array $params */ public function query_entries( $params = array() ) { $query = array(); if( empty( $params ) ) { $params = $this->atts; } if( ! empty( $params['categories'] ) ) { //get the portfolio categories $terms = explode( ',', $params['categories'] ); } $this->current_page = ( $params['paginate'] != 'no' ) ? avia_get_current_pagination_number( 'avia-element-paging' ) : 1; $date_query = AviaHelper::date_query( array(), $params ); //if we find categories perform complex query, otherwise simple one if( isset( $terms[0] ) && ! empty( $terms[0] ) && ! is_null( $terms[0] ) && $terms[0] != 'null' ) { $query = array( 'orderby' => $params['query_orderby'], 'order' => $params['query_order'], 'paged' => $this->current_page, 'posts_per_page' => $params['items'], 'post_type' => $params['post_type'], 'date_query' => $date_query, 'tax_query' => array( array( 'taxonomy' => $params['taxonomy'], 'field' => 'id', 'terms' => $terms, 'operator' => 'IN' ) ) ); } else { $query = array( 'orderby' => $params['query_orderby'], 'order' => $params['query_order'], 'paged' => $this->current_page, 'posts_per_page' => $params['items'], 'post_type' => $params['post_type'], 'date_query' => $date_query, ); } /** * * @since < 4.0 * @param array $query * @param array $params * @return array */ $query = apply_filters( 'avia_post_grid_query', $query, $params ); $this->entries = new WP_Query( $query ); } /** * Allows to set the query to an existing post query. usually only needed on pages that already did a query for the entries, like taxonomy archive pages. * Shortcode uses the query_entries function above * */ public function use_global_query() { global $wp_query; $this->entries = $wp_query; } } } /* Example: how to order posts randomly on page load. put this into functions.php add_filter('avia_post_grid_query','avia_order_by_random'); function avia_order_by_random($query) { $query['orderby'] = 'rand'; return $query; } */