Advertisement
Guenni007

portfolio

Dec 2nd, 2024
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 52.29 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Portfolio Grid
  4.  *
  5.  * Creates a grid of portfolio excerpts
  6.  *
  7.  * This class does not support post css files
  8.  * ==========================================
  9.  *
  10.  *  * edited by Guenni007: lines 1040ff to add additional Infos as class to each article
  11.  *
  12.  *
  13.  */
  14. if( ! defined( 'ABSPATH' ) ) {  exit;  }    // Exit if accessed directly
  15.  
  16.  
  17. if( ! class_exists( 'avia_sc_portfolio', false ) )
  18. {
  19.     class avia_sc_portfolio extends aviaShortcodeTemplate
  20.     {
  21.         /**
  22.          * Needed for unique ID if no id specified
  23.          *
  24.          * @since 4.5.7.2
  25.          * @var int
  26.          */
  27.         static protected $portfolio_count = 0;
  28.  
  29.         /**
  30.          * Create the config array for the shortcode button
  31.          */
  32.         protected function shortcode_insert_button()
  33.         {
  34.             $this->config['version']        = '1.0';
  35.             $this->config['is_fullwidth']   = 'yes';
  36.             $this->config['self_closing']   = 'yes';
  37.             $this->config['base_element']   = 'yes';
  38.  
  39.             $this->config['name']           = __( 'Portfolio Grid', 'avia_framework' );
  40.             $this->config['tab']            = __( 'Content Elements', 'avia_framework' );
  41.             $this->config['icon']           = AviaBuilder::$path['imagesURL'] . 'sc-portfolio.png';
  42.             $this->config['order']          = 38;
  43.             $this->config['target']         = 'avia-target-insert';
  44.             $this->config['shortcode']      = 'av_portfolio';
  45.             $this->config['tooltip']        = __( 'Creates a grid of portfolio excerpts', 'avia_framework' );
  46.             $this->config['disabling_allowed'] = true;
  47.             $this->config['id_name']        = 'id';
  48.             $this->config['id_show']        = 'yes';
  49.             $this->config['alb_desc_id']    = 'alb_description';
  50.             $this->config['linkpickers']    = array( 'link' );      //needed when theme support avia_template_builder_custom_post_type_grid
  51.         }
  52.  
  53.         protected function extra_assets()
  54.         {
  55.             $ver = Avia_Builder()->get_theme_version();
  56.             $min_js = avia_minify_extension( 'js' );
  57.             $min_css = avia_minify_extension( 'css' );
  58.  
  59.             //load css
  60.             wp_enqueue_style( 'avia-module-portfolio', AviaBuilder::$path['pluginUrlRoot'] . "avia-shortcodes/portfolio/portfolio{$min_css}.css", array( 'avia-layout' ), $ver );
  61.  
  62.             //load js
  63.             wp_enqueue_script( 'avia-module-isotope', AviaBuilder::$path['pluginUrlRoot'] . 'avia-shortcodes/portfolio/isotope.min.js', array( 'avia-shortcodes' ), $ver , true );
  64.             wp_enqueue_script( 'avia-module-portfolio', AviaBuilder::$path['pluginUrlRoot'] . "avia-shortcodes/portfolio/portfolio{$min_js}.js", array( 'avia-shortcodes' ), $ver , true );
  65.  
  66.             //start sessions - only necessary for correct breadcrumb nav on single portfolio pages
  67.             if( ! is_admin() && ! current_theme_supports( 'avia_no_session_support' ) && ! session_id() )
  68.             {
  69.                 session_start();
  70.             }
  71.         }
  72.  
  73.         /**
  74.          * Popup Elements
  75.          *
  76.          * If this function is defined in a child class the element automatically gets an edit button, that, when pressed
  77.          * opens a modal window that allows to edit the element properties
  78.          *
  79.          * @return void
  80.          */
  81.         protected function popup_elements()
  82.         {
  83.             $this->elements = array(
  84.  
  85.                 array(
  86.                         'type'  => 'tab_container',
  87.                         'nodescription' => true
  88.                     ),
  89.  
  90.                 array(
  91.                         'type'  => 'tab',
  92.                         'name'  => __( 'Content', 'avia_framework' ),
  93.                         'nodescription' => true
  94.                     ),
  95.  
  96.                     array(
  97.                             'type'          => 'template',
  98.                             'template_id'   => 'toggle_container',
  99.                             'templates_include' => array(
  100.                                                     $this->popup_key( 'content_entries' ),
  101.                                                     $this->popup_key( 'content_filter' ),
  102.                                                     $this->popup_key( 'content_sorting' ),
  103.                                                     $this->popup_key( 'content_excerpt' )
  104.                                                 ),
  105.                             'nodescription' => true
  106.                         ),
  107.  
  108.                 array(
  109.                         'type'  => 'tab_close',
  110.                         'nodescription' => true
  111.                     ),
  112.  
  113.                 array(
  114.                         'type'  => 'tab',
  115.                         'name'  => __( 'Styling', 'avia_framework' ),
  116.                         'nodescription' => true
  117.                     ),
  118.  
  119.                     array(
  120.                             'type'          => 'template',
  121.                             'template_id'   => 'toggle_container',
  122.                             'templates_include' => array(
  123.                                                     $this->popup_key( 'styling_grid' ),
  124.                                                     $this->popup_key( 'styling_columns' ),
  125.                                                     $this->popup_key( 'styling_pagination' )
  126.                                                 ),
  127.                             'nodescription' => true
  128.                         ),
  129.  
  130.                 array(
  131.                         'type'  => 'tab_close',
  132.                         'nodescription' => true
  133.                     ),
  134.  
  135.                 array(
  136.                         'type'  => 'tab',
  137.                         'name'  => __( 'Advanced', 'avia_framework' ),
  138.                         'nodescription' => true
  139.                     ),
  140.  
  141.                     array(
  142.                             'type'  => 'toggle_container',
  143.                             'nodescription' => true
  144.                         ),
  145.  
  146.                         array(
  147.                                 'type'          => 'template',
  148.                                 'template_id'   => $this->popup_key( 'advanced_link' )
  149.                             ),
  150.  
  151.                         array(
  152.                                 'type'          => 'template',
  153.                                 'template_id'   => 'lazy_loading_toggle',
  154.                                 'lockable'      => true
  155.                             ),
  156.  
  157.                         array(
  158.                                 'type'          => 'template',
  159.                                 'template_id'   => 'screen_options_toggle',
  160.                                 'lockable'      => true
  161.                             ),
  162.  
  163.                         array(
  164.                                 'type'          => 'template',
  165.                                 'template_id'   => 'developer_options_toggle',
  166.                                 'args'          => array( 'sc' => $this )
  167.                             ),
  168.  
  169.                     array(
  170.                             'type'  => 'toggle_container_close',
  171.                             'nodescription' => true
  172.                         ),
  173.  
  174.                 array(
  175.                         'type'  => 'tab_close',
  176.                         'nodescription' => true
  177.                     ),
  178.  
  179.                 array(
  180.                         'type'          => 'template',
  181.                         'template_id'   => 'element_template_selection_tab',
  182.                         'args'          => array( 'sc' => $this )
  183.                     ),
  184.  
  185.                 array(
  186.                         'type'  => 'tab_container_close',
  187.                         'nodescription' => true
  188.                     )
  189.  
  190.                 );
  191.         }
  192.  
  193.         /**
  194.          * Create and register templates for easier maintainance
  195.          *
  196.          * @since 4.6.4
  197.          */
  198.         protected function register_dynamic_templates()
  199.         {
  200.  
  201.             /**
  202.              * Content Tab
  203.              * ===========
  204.              */
  205.  
  206.             if( ! current_theme_supports( 'avia_template_builder_custom_post_type_grid' ) )
  207.             {
  208.                 $c = array(
  209.                         array(
  210.                             'name'      => __( 'Which Categories Should Be Used For The Portfolio', 'avia_framework' ),
  211.                             'desc'      => __( 'You can select multiple categories here. The page will then show posts from only those categories', 'avia_framework' ),
  212.                             'id'        => 'categories',
  213.                             'type'      => 'select',
  214.                             'multiple'  => 6,
  215.                             'lockable'  => true,
  216.                             'taxonomy'  => 'portfolio_entries',
  217.                             'subtype'   => 'cat'
  218.                         )
  219.                 );
  220.             }
  221.             else
  222.             {
  223.                 $c = array(
  224.                         array(
  225.                             'name'  => __( 'Which Entries Should Be Used', 'avia_framework' ),
  226.                             'desc'  => __( 'Select which entries should be displayed by selecting a taxonomy', 'avia_framework' ),
  227.                             'id'    => 'link',
  228.                             'type'  => 'linkpicker',
  229.                             'multiple'  => 6,
  230.                             'fetchTMPL' => true,
  231.                             'std'       => 'category',
  232.                             'lockable'  => true,
  233.                             'subtype'   => array( __( 'Display Entries from:', 'avia_framework' ) => 'taxonomy' )
  234.                         )
  235.                     );
  236.  
  237.  
  238.                 if( current_theme_supports( 'add_avia_builder_post_type_option' ) )
  239.                 {
  240.                     $element = array(
  241.                                 'type'          => 'template',
  242.                                 'template_id'   => 'avia_builder_post_type_option',
  243.                                 'lockable'      => true,
  244.                             );
  245.  
  246.                     array_unshift( $c, $element );
  247.                 }
  248.             }
  249.  
  250.             $c[] = array(
  251.                             'name'      => __( 'Multiple Categories/Terms Relation', 'avia_framework' ),
  252.                             'desc'      => __( 'Select to use an OR or AND relation. In AND an entry must be in all selected categories/terms to be displayed. Defaults to OR', 'avia_framework' ),
  253.                             'id'        => 'term_rel',
  254.                             'type'      => 'select',
  255.                             'std'       => '',
  256.                             'lockable'  => true,
  257.                             'subtype'   => array(
  258.                                                 __( 'OR', 'avia_framework' )    => '',
  259.                                                 __( 'AND', 'avia_framework' )   => 'AND'
  260.                                             )
  261.                         );
  262.  
  263.  
  264.  
  265.             $template = array(
  266.                             array(
  267.                                 'type'          => 'template',
  268.                                 'template_id'   => 'toggle',
  269.                                 'title'         => __( 'Select Entries', 'avia_framework' ),
  270.                                 'content'       => $c
  271.                             ),
  272.                     );
  273.  
  274.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'content_entries' ), $template );
  275.  
  276.             $c = array(
  277.                         array(
  278.                             'type'          => 'template',
  279.                             'template_id'   => 'date_query',
  280.                             'lockable'      => true,
  281.                             'period'        => true
  282.                         ),
  283.  
  284.                         array(
  285.                             'type'          => 'template',
  286.                             'template_id'   => 'page_element_filter',
  287.                             'lockable'      => true
  288.                         )
  289.  
  290.                 );
  291.  
  292.             $template = array(
  293.                             array(
  294.                                 'type'          => 'template',
  295.                                 'template_id'   => 'toggle',
  296.                                 'title'         => __( 'Filter', 'avia_framework' ),
  297.                                 'content'       => $c
  298.                             ),
  299.                     );
  300.  
  301.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'content_filter' ), $template );
  302.  
  303.             $c = array(
  304.                         array(
  305.                             'name'  => __( 'Sortable?', 'avia_framework' ),
  306.                             'desc'  => __( 'Should the sorting options based on categories be displayed?', 'avia_framework' ),
  307.                             'id'    => 'sort',
  308.                             'type'  => 'select',
  309.                             'std'   => 'yes',
  310.                             'lockable'  => true,
  311.                             'subtype'   => array(
  312.                                                 __( 'Yes, display sort options', 'avia_framework' )         => 'yes',
  313.                                                 __( 'Yes, display sort options and currently active categories', 'avia_framework' ) => 'yes-tax',
  314.                                                 __( 'No, do not display sort options', 'avia_framework' )   => 'no'
  315.                                             )
  316.                         ),
  317.  
  318.                         array(
  319.                             'name'  => __( 'Order by', 'avia_framework' ),
  320.                             'desc'  => __( 'You can order the result by various attributes like creation date, title, author etc', 'avia_framework' ),
  321.                             'id'    => 'query_orderby',
  322.                             'type'  => 'select',
  323.                             'std'   => 'date',
  324.                             'lockable'  => true,
  325.                             'subtype'   => array(
  326.                                                 __( 'Date', 'avia_framework' )              => 'date',
  327.                                                 __( 'Title', 'avia_framework' )             => 'title',
  328.                                                 __( 'Random', 'avia_framework' )            => 'rand',
  329.                                                 __( 'Author', 'avia_framework' )            => 'author',
  330.                                                 __( 'Name (Post Slug)', 'avia_framework' )  => 'name',
  331.                                                 __( 'Last modified', 'avia_framework' )     => 'modified',
  332.                                                 __( 'Comment Count', 'avia_framework' )     => 'comment_count',
  333.                                                 __( 'Page Order', 'avia_framework' )        => 'menu_order'
  334.                                             )
  335.                         ),
  336.  
  337.                         array(
  338.                             'name'  => __( 'Display order', 'avia_framework' ),
  339.                             'desc'  => __( 'Display the results either in ascending or descending order', 'avia_framework' ),
  340.                             'id'    => 'query_order',
  341.                             'type'  => 'select',
  342.                             'std'   => 'DESC',
  343.                             'lockable'  => true,
  344.                             'subtype'   => array(
  345.                                                 __( 'Ascending Order', 'avia_framework' )   => 'ASC',
  346.                                                 __( 'Descending Order', 'avia_framework' )  => 'DESC'
  347.                                             )
  348.                         )
  349.                 );
  350.  
  351.             $template = array(
  352.                             array(
  353.                                 'type'          => 'template',
  354.                                 'template_id'   => 'toggle',
  355.                                 'title'         => __( 'Sorting', 'avia_framework' ),
  356.                                 'content'       => $c
  357.                             ),
  358.                     );
  359.  
  360.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'content_sorting' ), $template );
  361.  
  362.             $c = array(
  363.                         array(
  364.                             'name'  => __( 'Excerpt', 'avia_framework' ),
  365.                             'desc'  => __( 'Display Excerpt and Title below the preview image?', 'avia_framework' ),
  366.                             'id'    => 'contents',
  367.                             'type'  => 'select',
  368.                             'std'   => 'title',
  369.                             'lockable'  => true,
  370.                             'subtype'   => array(
  371.                                                 __( 'Title and Excerpt', 'avia_framework' )         => 'excerpt',
  372.                                                 __( 'Only Title', 'avia_framework' )                => 'title',
  373.                                                 __( 'Only excerpt', 'avia_framework' )              => 'only_excerpt',
  374.                                                 __( 'No Title and no excerpt', 'avia_framework' )   => 'no'
  375.                                             )
  376.                         )
  377.  
  378.                     );
  379.  
  380.             $template = array(
  381.                             array(
  382.                                 'type'          => 'template',
  383.                                 'template_id'   => 'toggle',
  384.                                 'title'         => __( 'Excerpt', 'avia_framework' ),
  385.                                 'content'       => $c
  386.                             ),
  387.                     );
  388.  
  389.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'content_excerpt' ), $template );
  390.  
  391.             /**
  392.              * Styling Tab
  393.              * ===========
  394.              */
  395.  
  396.             $c = array(
  397.  
  398. //
  399. //                  array(
  400. //                      'name'  => __( 'Style?', 'avia_framework' ),
  401. //                      'desc'  => __( 'Choose the style of the entries here', 'avia_framework' ),
  402. //                      'id'    => 'style',
  403. //                      'type'  => 'select',
  404. //                      'std'   => '',
  405. //                      'subtype'   => array(
  406. //                                          __( 'Default Style', 'avia_framework' )         => '',
  407. //                                          __( 'Circle Image Stlye', 'avia_framework' )    => 'grid-circle'
  408. //                                      )
  409. //                  ),
  410. //
  411.                     array(
  412.                         'name'  => __( 'Portfolio Grid Image Size', 'avia_framework' ),
  413.                         'desc'  => __( 'Set the image size of the Portfolio Grid images', 'avia_framework' ),
  414.                         'id'    => 'preview_mode',
  415.                         'type'  => 'select',
  416.                         'std'   => 'auto',
  417.                         'lockable'  => true,
  418.                         'subtype'   => array(
  419.                                             __( 'Set the Portfolio Grid image size automatically based on column or layout width', 'avia_framework' )   => 'auto',
  420.                                             __( 'Choose the Portfolio Grid image size manually (select thumbnail size)', 'avia_framework' )             => 'custom'
  421.                                         )
  422.                     ),
  423.  
  424.                     array(
  425.                         'name'  => __( 'Select custom image size', 'avia_framework' ),
  426.                         'desc'  => __( 'Choose image size for Portfolio Grid Images', 'avia_framework' ) . '<br/><small>' . __( '(Note: Images will be scaled to fit for the amount of columns chosen above)', 'avia_framework' ) . '</small>',
  427.                         'id'    => 'image_size',
  428.                         'type'  => 'select',
  429.                         'std'       => 'portfolio',
  430.                         'lockable'  => true,
  431.                         'required'  => array( 'preview_mode', 'equals', 'custom' ),
  432.                         'subtype'   =>  AviaHelper::get_registered_image_sizes( array( 'logo', 'thumbnail', 'widget' ) )
  433.                     )
  434.  
  435.                 );
  436.  
  437.             $template = array(
  438.                             array(
  439.                                 'type'          => 'template',
  440.                                 'template_id'   => 'toggle',
  441.                                 'title'         => __( 'Grid Settings', 'avia_framework' ),
  442.                                 'content'       => $c
  443.                             ),
  444.                     );
  445.  
  446.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'styling_grid' ), $template );
  447.  
  448.             $c = array(
  449.  
  450.                         array(
  451.                                 'type'          => 'template',
  452.                                 'template_id'   => 'columns_count_icon_switcher',
  453.                                 'lockable'      => true,
  454.                                 'subtype'       => array(
  455.                                                         'default'   => AviaHtmlHelper::number_array( 2, 6, 1, array( __( '1 column', 'avia_framework' ) => '1' ), ' ' . __( 'columns', 'avia_framework' ) ),
  456.                                                         'medium'    => AviaHtmlHelper::number_array( 2, 4, 1, array( __( 'Use theme default (3 columns)', 'avia_framework' )    => '', __( '1 column', 'avia_framework' ) => '1' ), ' ' . __( 'columns', 'avia_framework' ) ),
  457.                                                         'small'     => AviaHtmlHelper::number_array( 2, 4, 1, array( __( 'Use theme default (2 columns)', 'avia_framework' )    => '', __( '1 column', 'avia_framework' ) => '1' ), ' ' . __( 'columns', 'avia_framework' ) ),
  458.                                                         'mini'      => AviaHtmlHelper::number_array( 2, 4, 1, array( __( 'Use theme default (1 column)', 'avia_framework' ) => '', __( '1 column', 'avia_framework' ) => '1' ), ' ' . __( 'columns', 'avia_framework' ) )
  459.                                                     ),
  460.                                 'std'           => array(
  461.                                                         'default'   => '4',
  462.                                                         'medium'    => '',
  463.                                                         'small'     => '',
  464.                                                         'mini'      => ''
  465.                                                     ),
  466.                                 'id_sizes'      => array(
  467.                                                         'default'   => 'columns',
  468.                                                         'medium'    => 'av-medium-columns',
  469.                                                         'small'     => 'av-small-columns',
  470.                                                         'mini'      => 'av-mini-columns'
  471.                                                     )
  472.                             ),
  473.  
  474.                         array(
  475.                                 'name'  => __( '1 Column layout', 'avia_framework' ),
  476.                                 'desc'  => __( 'Choose the 1 column layout. This will ignore all responsive settings you make.', 'avia_framework' ),
  477.                                 'id'    => 'one_column_template',
  478.                                 'type'  => 'select',
  479.                                 'std'   => 'special',
  480.                                 'lockable'  => true,
  481.                                 'required'  => array( 'columns', 'equals', '1' ),
  482.                                 'subtype'   => array(
  483.                                                     __( 'Use special 1 column layout (side by side)', 'avia_framework' )    => 'special',
  484.                                                     __( 'Use default portfolio layout', 'avia_framework' )                  => 'default'
  485.                                                 )
  486.                             )
  487.                 );
  488.  
  489.             $template = array(
  490.                             array(
  491.                                 'type'          => 'template',
  492.                                 'template_id'   => 'toggle',
  493.                                 'title'         => __( 'Columns', 'avia_framework' ),
  494.                                 'content'       => $c
  495.                             ),
  496.                     );
  497.  
  498.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'styling_columns' ), $template );
  499.  
  500.             $c = array(
  501.                         array(
  502.                             'name'  => __( 'Post Number', 'avia_framework' ),
  503.                             'desc'  => __( 'How many items should be displayed per page?', 'avia_framework' ),
  504.                             'id'    => 'items',
  505.                             'type'  => 'select',
  506.                             'std'   => '16',
  507.                             'lockable'  => true,
  508.                             'subtype'   => AviaHtmlHelper::number_array( 1, 100, 1, array( 'All' => '-1' ) )
  509.                         ),
  510.  
  511.                         array(
  512.                             'name'  => __( 'Pagination', 'avia_framework' ),
  513.                             'desc'  => __( 'Should a pagination be displayed?', 'avia_framework' ),
  514.                             'id'    => 'paginate',
  515.                             'type'  => 'select',
  516.                             'std'   => 'yes',
  517.                             'lockable'  => true,
  518.                             'subtype'   => array(
  519.                                                 __( 'yes', 'avia_framework' )   => 'yes',
  520.                                                 __( 'no', 'avia_framework' )    => 'no'
  521.                                             )
  522.                         ),
  523.  
  524.                 );
  525.  
  526.             $template = array(
  527.                             array(
  528.                                 'type'          => 'template',
  529.                                 'template_id'   => 'toggle',
  530.                                 'title'         => __( 'Pagination', 'avia_framework' ),
  531.                                 'content'       => $c
  532.                             ),
  533.                     );
  534.  
  535.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'styling_pagination' ), $template );
  536.  
  537.             /**
  538.              * Advanced Tab
  539.              * ============
  540.              */
  541.  
  542.             $c = array(
  543.                         array(
  544.                             'name'  => __( 'Link Handling', 'avia_framework' ),
  545.                             'desc'  => __( 'When clicking on a portfolio item you can choose to open the link to the single entry, open a preview (aka AJAX Portfolio) or show a bigger version of the image in a lightbox overlay', 'avia_framework' ),
  546.                             'id'    => 'linking',
  547.                             'type'  => 'select',
  548.                             'std'   => '',
  549.                             'lockable'  => true,
  550.                             'subtype'   => array(
  551.                                                 __( 'Open the entry on a new page', 'avia_framework' )                          => '',
  552.                                                 __( 'Open a preview of the entry (known as AJAX Portfolio)', 'avia_framework' ) => 'ajax',
  553.                                                 __( 'Display the big image in a lightbox', 'avia_framework' )                   => 'lightbox'
  554.                                             )
  555.                         ),
  556.  
  557.                 );
  558.  
  559.             $template = array(
  560.                             array(
  561.                                 'type'          => 'template',
  562.                                 'template_id'   => 'toggle',
  563.                                 'title'         => __( 'Link Setting', 'avia_framework' ),
  564.                                 'content'       => $c
  565.                             ),
  566.                     );
  567.  
  568.             AviaPopupTemplates()->register_dynamic_template( $this->popup_key( 'advanced_link' ), $template );
  569.  
  570.  
  571.         }
  572.  
  573.         /**
  574.          * Editor Element - this function defines the visual appearance of an element on the AviaBuilder Canvas
  575.          * Most common usage is to define some markup in the $params['innerHtml'] which is then inserted into the drag and drop container
  576.          * Less often used: $params['data'] to add data attributes, $params['class'] to modify the className
  577.          *
  578.          * @param array $params         holds the default values for $content and $args.
  579.          * @return array                usually holds an innerHtml key that holds item specific markup.
  580.          */
  581.         public function editor_element( $params )
  582.         {
  583.             $params = parent::editor_element( $params );
  584.             $params['innerHtml'] .= AviaPopupTemplates()->get_html_template( 'alb_element_fullwidth_stretch' );
  585.  
  586.             $params['content']   = null; //remove to allow content elements
  587.  
  588.             return $params;
  589.         }
  590.  
  591.         /**
  592.          * Frontend Shortcode Handler
  593.          *
  594.          * @param array $atts array of attributes
  595.          * @param string $content text within enclosing form of shortcode element
  596.          * @param string $shortcodename the shortcode found, when == callback name
  597.          * @return string $output returns the modified html string
  598.          */
  599.         public function shortcode_handler( $atts, $content = '', $shortcodename = '', $meta = '' )
  600.         {
  601.             $default = avia_post_grid::get_defaults();
  602.  
  603.             $locked = array();
  604.             Avia_Element_Templates()->set_locked_attributes( $atts, $this, $shortcodename, $default, $locked, $content );
  605.             Avia_Element_Templates()->add_template_class( $meta, $atts, $default );
  606.  
  607.             extract( AviaHelper::av_mobile_sizes( $atts ) ); //return $av_font_classes, $av_title_font_classes and $av_display_classes
  608.  
  609.             $atts = array_merge( $default, $atts );
  610.  
  611.             if( 'disabled' == $atts['img_scrset'] )
  612.             {
  613.                 Av_Responsive_Images()->force_disable( 'disabled' );
  614.             }
  615.  
  616.             if( current_theme_supports( 'avia_template_builder_custom_post_type_grid' ) )
  617.             {
  618.                 if( isset( $atts['link'] ) )
  619.                 {
  620.                     $atts['link'] = explode( ',', $atts['link'], 2 );
  621.                     $atts['taxonomy'] = $atts['link'][0];
  622.  
  623.                     if( isset( $atts['link'][1] ) )
  624.                     {
  625.                         $atts['categories'] = $atts['link'][1];
  626.                     }
  627.                 }
  628.  
  629.                 if( empty( $atts['post_type'] ) || ! current_theme_supports( 'add_avia_builder_post_type_option' ) )
  630.                 {
  631.                     $atts['post_type'] = get_post_types();
  632.                 }
  633.  
  634.                 if( is_string( $atts['post_type'] ) )
  635.                 {
  636.                     $atts['post_type'] = explode( ',', $atts['post_type'] );
  637.                 }
  638.             }
  639.             else
  640.             {
  641.                 /**
  642.                  * @used_by             config-wpml\config.php      avia_wpml_translate_object_ids()
  643.                  * @since 4.6.4
  644.                  * @param string
  645.                  * @param string
  646.                  * @param avia_sc_portfolio $this
  647.                  * @return string
  648.                  */
  649.                 $atts['categories'] = apply_filters( 'avf_alb_taxonomy_values', $atts['categories'], 'portfolio_entries' );
  650.             }
  651.  
  652.             self::$portfolio_count ++;
  653.  
  654.             $el_id = ! empty( $meta['custom_el_id'] ) ? $meta['custom_el_id'] : ' id="av-sc-portfolio-' . self::$portfolio_count . '" ';
  655.             $atts['class'] = ! empty( $meta['custom_class'] ) ? $meta['custom_class'] : '';
  656.             $atts['el_id'] = '';
  657.             $atts['fullscreen'] = ShortcodeHelper::is_top_level();
  658.             if( ! $atts['fullscreen'] )
  659.             {
  660.                 $atts['el_id'] = $el_id;
  661.             }
  662.  
  663.             $grid = new avia_post_grid( $atts );
  664.             $grid->query_entries();
  665.             $portfolio_html = $grid->html();
  666.  
  667.             $portfolio_html = Av_Responsive_Images()->make_content_images_responsive( $portfolio_html );
  668.  
  669.             Av_Responsive_Images()->force_disable( 'reset' );
  670.  
  671.             if( ! ShortcodeHelper::is_top_level() )
  672.             {
  673.                 return $portfolio_html;
  674.             }
  675.  
  676.             $params['class'] = "main_color avia-no-border-styling avia-fullwidth-portfolio {$av_display_classes} {$meta['el_class']}";
  677.             $params['open_structure'] = false;
  678.             $params['id'] = AviaHelper::save_string( $meta['custom_id_val'] , '-', 'av-sc-portfolio-' . self::$portfolio_count );
  679.             $params['custom_markup'] = $meta['custom_markup'];
  680.  
  681.             //we dont need a closing structure if the element is the first one or if a previous fullwidth element was displayed before
  682.             if( isset( $meta['index'] ) && $meta['index'] == 0 )
  683.             {
  684.                 $params['close'] = false;
  685.             }
  686.  
  687.             if( ! empty( $meta['siblings']['prev']['tag'] ) && in_array( $meta['siblings']['prev']['tag'], AviaBuilder::$full_el_no_section ) )
  688.             {
  689.                 $params['close'] = false;
  690.             }
  691.  
  692.             $output  = avia_new_section( $params );
  693.             $output .= $portfolio_html;
  694.             $output .= avia_section_after_element_content( $meta , 'after_portfolio' );
  695.  
  696.             return $output;
  697.         }
  698.     }
  699. }
  700.  
  701.  
  702. if ( ! class_exists( 'avia_post_grid', false ) )
  703. {
  704.     /**
  705.      * This class does not support post css files
  706.      * ==========================================
  707.      */
  708.     class avia_post_grid
  709.     {
  710.         /**
  711.          *
  712.          * @var int
  713.          */
  714.         static protected $grid = 0;
  715.  
  716.         /**
  717.          *
  718.          * @var array
  719.          */
  720.         static protected $preview_template = array();
  721.  
  722.         /**
  723.          *
  724.          * @var array
  725.          */
  726.         protected $atts;
  727.  
  728.         /**
  729.          *
  730.          * @var WP_Query
  731.          */
  732.         protected $entries;
  733.  
  734.         /**
  735.          *
  736.          * @var array
  737.          */
  738.         protected $screen_options;
  739.  
  740.         /**
  741.          *
  742.          * @since 4.7.6.4
  743.          * @var int
  744.          */
  745.         protected $current_page;
  746.  
  747.         /**
  748.          *
  749.          * @param type $atts
  750.          */
  751.         public function __construct( $atts = array() )
  752.         {
  753.             $this->entries = null;
  754.             $this->screen_options = AviaHelper::av_mobile_sizes( $atts );
  755.             $this->current_page = 1;
  756.  
  757.             $this->atts = shortcode_atts( avia_post_grid::get_defaults(), $atts, 'av_portfolio' );
  758.  
  759.             if( $this->atts['linking'] == 'ajax' )
  760.             {
  761.                 add_action( 'wp_footer' , array( $this, 'print_preview_templates' ) );
  762.             }
  763.  
  764.             if( $this->atts['term_rel'] != 'AND' )
  765.             {
  766.                 $this->atts['term_rel'] = 'IN';
  767.             }
  768.  
  769.             if( $this->atts['items'] == -1 )
  770.             {
  771.                 $this->atts['paginate'] = 'no';
  772.             }
  773.         }
  774.  
  775.         /**
  776.          *
  777.          * @since 4.5.7.2
  778.          */
  779.         public function __destruct()
  780.         {
  781.             unset( $this->atts );
  782.             unset( $this->screen_options );
  783.             unset( $this->entries );
  784.         }
  785.  
  786.         /**
  787.          * Returns the default array for this class
  788.          *
  789.          * @since 4.8
  790.          * @return array
  791.          */
  792.         static public function get_defaults()
  793.         {
  794.             $default = array(
  795.                         'style'                 => '',
  796.                         'linking'               => '',
  797.                         'columns'               => '4',
  798.                         'items'                 => '16',
  799.                         'contents'              => 'title',
  800.                         'sort'                  => 'yes',
  801.                         'paginate'              => 'yes',
  802.                         'categories'            => '',
  803.                         'preview_mode'          => 'auto',
  804.                         'image_size'            => 'portfolio',
  805.                         'post_type'             => 'portfolio',
  806.                         'taxonomy'              => 'portfolio_entries',
  807.                         'term_rel'              => 'IN',
  808.                         'one_column_template'   => 'special',
  809.                         'set_breadcrumb'        => true, //no shortcode option for this, modifies the breadcrumb nav, must be false on taxonomy overview
  810.                         'class'                 => '',
  811.                         'el_id'                 => '',
  812.                         'custom_markup'         => '',
  813.                         'fullscreen'            => false,
  814.                         'query_orderby'         => 'date',
  815.                         'query_order'           => 'DESC',
  816.                         'date_filter'           => '',
  817.                         'date_filter_start'     => '',
  818.                         'date_filter_end'       => '',
  819.                         'date_filter_format'    => 'yy/mm/dd',      //  'yy/mm/dd' | 'dd-mm-yy' | yyyymmdd
  820.                         'period_filter_unit_1'  => '',
  821.                         'period_filter_unit_2'  => '',
  822.                         'page_element_filter'   => '',
  823.                         'lazy_loading'          => 'disabled',
  824.                         'img_scrset'            => ''
  825.             );
  826.  
  827.             return $default;
  828.         }
  829.  
  830.         /**
  831.          * generates the html of the post grid
  832.          *
  833.          * @since < 4.0
  834.          * @since 4.8               added $query_var_page
  835.          * @param string $query_var_page            set to '' to use stamdard WP pagination query var (e.g. from taxonomy-portfolio_entries.php)
  836.          * @return string
  837.          */
  838.         public function html( $query_var_page = 'avia-element-paging' )
  839.         {
  840.             if( empty( $this->entries ) || empty( $this->entries->posts ) )
  841.             {
  842.                 return '';
  843.             }
  844.  
  845.             avia_post_grid::$grid ++;
  846.  
  847.             extract( $this->screen_options ); //return $av_font_classes, $av_title_font_classes and $av_display_classes
  848.             extract( $this->atts );
  849.  
  850.  
  851.             $container_id = avia_post_grid::$grid;
  852.             $extraClass = 'first';
  853.             $grid = 'one_fourth';
  854.  
  855.             if( $preview_mode == 'auto' )
  856.             {
  857.                 $image_size = 'portfolio';
  858.             }
  859.  
  860.             $post_loop_count    = 1;
  861.             $loop_counter       = 1;
  862.             $output             = '';
  863.             $style_class        = empty( $style ) ? 'no_margin' : $style;
  864.             $total              = $this->entries->post_count % 2 ? 'odd' : 'even';
  865.             $post_type_paginate = array();
  866.  
  867.             if( $set_breadcrumb && is_page() )
  868.             {
  869.                 if( ! is_array( $post_type ) )
  870.                 {
  871.                     $_SESSION["avia_{$post_type}"] = get_the_ID();
  872.                     $post_type_paginate[] = $post_type;
  873.                 }
  874.                 else
  875.                 {
  876.                     $filtered = array();
  877.                     foreach( $this->entries->posts as $entry )
  878.                     {
  879.                         if( ! $entry instanceof WP_Post )
  880.                         {
  881.                             continue;
  882.                         }
  883.  
  884.                         if( ! in_array( $entry->post_type, $filtered ) )
  885.                         {
  886.                             $filtered[] = $entry->post_type;
  887.                         }
  888.                     }
  889.  
  890.                     foreach( $filtered as $pt )
  891.                     {
  892.                         $_SESSION[ "avia_{$pt}" ] = get_the_ID();
  893.                         $post_type_paginate[] = $pt;
  894.                     }
  895.                 }
  896.             }
  897.  
  898.             switch( $columns )
  899.             {
  900.                 case '1':
  901.                     $grid = 'av_fullwidth';
  902.                     if( $preview_mode == 'auto' )
  903.                     {
  904.                         $image_size = 'featured';
  905.                     }
  906.                     break;
  907.                 case '2':
  908.                     $grid = 'av_one_half';
  909.                     break;
  910.                 case '3':
  911.                     $grid = 'av_one_third';
  912.                     break;
  913.                 case '4':
  914.                     $grid = 'av_one_fourth';
  915.                     if( $preview_mode == 'auto' )
  916.                     {
  917.                         $image_size = 'portfolio_small';
  918.                     }
  919.                     break;
  920.                 case '5':
  921.                     $grid = 'av_one_fifth';
  922.                     if( $preview_mode == 'auto' )
  923.                     {
  924.                         $image_size = 'portfolio_small';
  925.                     }
  926.                     break;
  927.                 case '6':
  928.                     $grid = 'av_one_sixth';
  929.                     if( $preview_mode == 'auto' )
  930.                     {
  931.                         $image_size = 'portfolio_small';
  932.                     }
  933.                     break;
  934.             }
  935.  
  936.             if( $fullscreen && $preview_mode =='auto' && $image_size == 'portfolio_small' )
  937.             {
  938.                 $image_size = 'portfolio';
  939.             }
  940.  
  941.             if( $sort != 'no' )
  942.             {
  943.                 $output .= '<div ' . $el_id . ' class="av-portfolio-grid-sorting-container">';
  944.                 $el_id = '';
  945.             }
  946.  
  947.             $output .= $sort != 'no' ? $this->sort_buttons( $this->entries->posts, $this->atts ) : '';
  948.  
  949.             if( $linking == 'ajax' )
  950.             {
  951.                 $container_class = $fullscreen ? 'container' : '';
  952.  
  953.                 $output .= "<div class='portfolio_preview_container {$container_class}' data-portfolio-id='{$container_id}'>
  954.                                 <div class='ajax_controlls iconfont'>
  955.                                     <a href='#prev' class='ajax_previous'   " . av_icon_string('prev') . "></a>
  956.                                     <a href='#next' class='ajax_next'       " . av_icon_string('next') . "></a>
  957.                                     <a class='avia_close' href='#close'     " . av_icon_string('close') . "></a>
  958.                                 </div>
  959.                                 <div class='portfolio-details-inner'></div>
  960.                             </div>";
  961.             }
  962.  
  963.             $output .= "<div {$el_id} class='{$class} grid-sort-container isotope {$av_display_classes} {$av_column_classes} {$style_class}-container with-{$contents}-container grid-total-{$total} grid-col-{$columns} grid-links-{$linking}' data-portfolio-id='{$container_id}'>";
  964.  
  965.             foreach( $this->entries->posts as $index => $entry )
  966.             {
  967.                 $the_id = $entry->ID;
  968.                 $parity = $post_loop_count % 2 ? 'odd' : 'even';
  969.                 $last = $this->entries->post_count == $post_loop_count ? ' post-entry-last ' : '';
  970.                 $post_class = "post-entry post-entry-{$the_id} grid-entry-overview grid-loop-{$post_loop_count} grid-parity-{$parity} {$last}";
  971.                 $sort_class = $this->sort_cat_string( $the_id, $this->atts );
  972.                 $post_thumbnail_id = get_post_thumbnail_id( $the_id );
  973.  
  974.                 if( $lazy_loading != 'enabled' )
  975.                 {
  976.                     Av_Responsive_Images()->add_attachment_id_to_not_lazy_loading( $post_thumbnail_id );
  977.                 }
  978.  
  979.                 switch( $linking )
  980.                 {
  981.                     case 'lightbox':
  982.                         $link = AviaHelper::get_url( 'lightbox', $post_thumbnail_id, true );
  983.                         break;
  984.                     default:
  985.                         $link = get_permalink( $the_id );
  986.                         break;
  987.                 }
  988.  
  989.                 $title_link  = get_permalink( $the_id );
  990.                 $custom_link = get_post_meta( $the_id, '_portfolio_custom_link', true ) != '' ? get_post_meta( $the_id, '_portfolio_custom_link_url', true ) : false;
  991.  
  992.                 if( $custom_link )
  993.                 {
  994.                     $title_link = '';
  995.                     $link = $custom_link;
  996.                 }
  997.  
  998.                 $excerpt = '';
  999.                 $title = '';
  1000.  
  1001.                 switch( $contents )
  1002.                 {
  1003.                     case 'excerpt':
  1004.                         $excerpt = $entry->post_excerpt;
  1005.                         $title = avia_wp_get_the_title( $entry );
  1006.                         break;
  1007.                     case 'title':
  1008.                         $excerpt = '';
  1009.                         $title = avia_wp_get_the_title( $entry );
  1010.                         break;
  1011.                     case 'only_excerpt':
  1012.                         $excerpt = $entry->post_excerpt;
  1013.                         $title = '';
  1014.                         break;
  1015.                     case 'no':
  1016.                         $excerpt = '';
  1017.                         $title = '';
  1018.                         break;
  1019.                 }
  1020.  
  1021.                 $lightbox_attr = Av_Responsive_Images()->html_attr_image_src( $link, false );
  1022.  
  1023.                 $custom_overlay = apply_filters( 'avf_portfolio_custom_overlay', '', $entry );
  1024.                 $link_markup = apply_filters( 'avf_portfolio_custom_image_container', array( "a {$lightbox_attr} title='" . esc_attr( strip_tags( $title ) ) . "' ",'a'), $entry );
  1025.  
  1026.                 $title = apply_filters( 'avf_portfolio_title', $title, $entry );
  1027.                 $title_link = apply_filters( 'avf_portfolio_title_link', $title_link, $entry );
  1028.                 $image_attrs = apply_filters( 'avf_portfolio_image_attrs', array(), $entry );
  1029.  
  1030.                 /**
  1031.                  * @since 4.8
  1032.                  * @param string $excerpt
  1033.                  * @param WP_Post $entry
  1034.                  * @return string
  1035.                  */
  1036.                 $excerpt = apply_filters( 'avf_portfolio_grid_excerpt', $excerpt, $entry );
  1037.  
  1038.  
  1039.  
  1040. // add additional Infos as class to each article
  1041.  
  1042.                 $postterms = get_the_terms( $the_id, 'portfolio_entries' );
  1043.                 foreach($postterms as $postterm){  
  1044.                     $post_class .= 'taxonomy-' . strtolower($postterm->slug) . ' ';
  1045.                 }
  1046.  
  1047.                 $posttags = get_the_tags($the_id);
  1048.                 foreach($posttags as $posttag){  
  1049.                     $post_class .= 'tag-' . strtolower($posttag->name) . ' ';
  1050.                 }
  1051.  
  1052. // END: add additional Infos as class to each article
  1053.            
  1054.  
  1055.  
  1056.  
  1057.                 if( $columns == '1' && $one_column_template == 'special' )
  1058.                 {
  1059.                     $extraClass .= ' special_av_fullwidth ';
  1060.  
  1061.                     $output .= "<div data-ajax-id='{$the_id}' class='grid-entry flex_column isotope-item all_sort {$style_class} {$post_class} {$sort_class} {$grid} {$extraClass}'>";
  1062.                     $output .= "<article class='main_color inner-entry' " . avia_markup_helper( array( 'context' => 'entry', 'echo' => false, 'id' => $the_id, 'custom_markup' => $custom_markup ) ) . ">";
  1063.  
  1064.                     $output .= apply_filters( 'avf_portfolio_extra', '', $entry );
  1065.  
  1066.                     $output .= '<div class="av_table_col first portfolio-entry grid-content">';
  1067.  
  1068.                     if( ! empty( $title ) )
  1069.                     {
  1070.                         $markup = avia_markup_helper( array( 'context' => 'entry_title', 'echo' => false, 'id' => $the_id, 'custom_markup' => $custom_markup ) );
  1071.  
  1072.                         $default_heading = 'h2';
  1073.                         $args = array(
  1074.                                     'heading'       => $default_heading,
  1075.                                     'extra_class'   => ''
  1076.                                 );
  1077.  
  1078.                         $extra_args = array( $this, $index, 'one_column_template_special' );
  1079.  
  1080.                         /**
  1081.                          * @since 4.5.5
  1082.                          * @return array
  1083.                          */
  1084.                         $args = apply_filters( 'avf_customize_heading_settings', $args, __CLASS__, $extra_args );
  1085.  
  1086.                         $heading = ! empty( $args['heading'] ) ? $args['heading'] : $default_heading;
  1087.                         $css = ! empty( $args['extra_class'] ) ? $args['extra_class'] : '';
  1088.  
  1089.  
  1090.                         $aria_label = 'aria-label="' . __( 'Portfolio:', 'avia_framework' ) . ' ' . esc_attr( $title ) . '"';
  1091.  
  1092.                         /**
  1093.                          * @since 6.0.3
  1094.                          * @param string $aria_label
  1095.                          * @param string $context
  1096.                          * @param WP_Post $entry
  1097.                          * @return string
  1098.                          */
  1099.                         $aria_label = apply_filters( 'avf_aria_label_for_header', $aria_label, __CLASS__, $entry );
  1100.  
  1101.                         $output .= '<header class="entry-content-header" ' . $aria_label . '>';
  1102.                         $output .= "<{$heading} class='portfolio-grid-title entry-title {$css}' {$markup}>";
  1103.  
  1104.                         if( ! empty( $title_link ) )
  1105.                         {
  1106.                             $output .= "<a href='{$title_link}'>{$title}</a>";
  1107.                         }
  1108.                         else
  1109.                         {
  1110.                             $output .= $title;
  1111.                         }
  1112.                         $output .= "</{$heading}></header>";
  1113.                     }
  1114.  
  1115.                     if( ! empty( $excerpt ) )
  1116.                     {
  1117.                         $markup = avia_markup_helper( array( 'context' => 'entry_content', 'echo' => false, 'id' => $the_id, 'custom_markup' => $custom_markup ) );
  1118.  
  1119.                         $output .= '<div class="entry-content-wrapper">';
  1120.                         $output .=      "<div class='grid-entry-excerpt entry-content' {$markup}>{$excerpt}</div>";
  1121.                         $output .= '</div>';
  1122.                     }
  1123.                     $output .= '<div class="avia-arrow"></div>';
  1124.                     $output .= '</div>';
  1125.  
  1126.                     $image = get_the_post_thumbnail( $the_id, $image_size, $image_attrs );
  1127.                     if( ! empty( $image ) )
  1128.                     {
  1129.                         $output .= '<div class="av_table_col portfolio-grid-image">';
  1130.                         $output .= "<{$link_markup[0]} data-rel='grid-" . avia_post_grid::$grid . "' class='grid-image avia-hover-fx'>{$custom_overlay} {$image}</{$link_markup[1]}>";
  1131.                         $output .= '</div>';
  1132.                     }
  1133.                     $output .= '<footer class="entry-footer"></footer>';
  1134.                     $output .= '</article>';
  1135.                     $output .= '</div>';
  1136.                 }
  1137.                 else
  1138.                 {
  1139.                     $extraClass .= ' default_av_fullwidth ';
  1140.  
  1141.                     $output .= "<div data-ajax-id='{$the_id}' class=' grid-entry flex_column isotope-item all_sort {$style_class} {$post_class} {$sort_class} {$grid} {$extraClass}'>";
  1142.                     $output .= "<article class='main_color inner-entry' " . avia_markup_helper( array( 'context' => 'entry', 'echo' => false, 'id' => $the_id, 'custom_markup' => $custom_markup ) ) . '>';
  1143.                     $output .= apply_filters( 'avf_portfolio_extra', '', $entry );
  1144.                     $output .= "<{$link_markup[0]} data-rel='grid-" . avia_post_grid::$grid.  "' class='grid-image avia-hover-fx'>{$custom_overlay} " . get_the_post_thumbnail( $the_id, $image_size, $image_attrs ) . "</{$link_markup[1]}>";
  1145.                     $output .= ! empty( $title ) || ! empty( $excerpt ) ? "<div class='grid-content'><div class='avia-arrow'></div>" : '';
  1146.  
  1147.                     if( ! empty( $title ) )
  1148.                     {
  1149.                         $markup = avia_markup_helper( array( 'context' => 'entry_title', 'echo' => false, 'id' => $the_id, 'custom_markup' => $custom_markup ) );
  1150.  
  1151.                         $default_heading = 'h3';
  1152.                         $args = array(
  1153.                                     'heading'       => $default_heading,
  1154.                                     'extra_class'   => ''
  1155.                                 );
  1156.  
  1157.                         $extra_args = array( $this, $index, 'not_one_column_template_special' );
  1158.  
  1159.                         /**
  1160.                          * @since 4.5.5
  1161.                          * @return array
  1162.                          */
  1163.                         $args = apply_filters( 'avf_customize_heading_settings', $args, __CLASS__, $extra_args );
  1164.  
  1165.                         $heading = ! empty( $args['heading'] ) ? $args['heading'] : $default_heading;
  1166.                         $css = ! empty( $args['extra_class'] ) ? $args['extra_class'] : '';
  1167.  
  1168.                         $aria_label = 'aria-label="' . __( 'Portfolio:', 'avia_framework' ) . ' ' . esc_attr( $title ) . '"';
  1169.  
  1170.                         /**
  1171.                          * @since 6.0.3
  1172.                          * @param string $aria_label
  1173.                          * @param string $context
  1174.                          * @param WP_Post $entry
  1175.                          * @return string
  1176.                          */
  1177.                         $aria_label = apply_filters( 'avf_aria_label_for_header', $aria_label, __CLASS__, $entry );
  1178.  
  1179.                         $output .= '<header class="entry-content-header" ' . $aria_label . '>';
  1180.                         $output .= "<{$heading} class='grid-entry-title entry-title {$css}' $markup>";
  1181.  
  1182.                         if( ! empty( $title_link ) )
  1183.                         {
  1184.                             $output .= "<a href='{$title_link}' title='" . esc_attr( strip_tags( $title ) ) . "'>" . $title . "</a>";
  1185.                         }
  1186.                         else
  1187.                         {
  1188.                             $output .= $title;
  1189.                         }
  1190.  
  1191.                         $output .= "</{$heading}></header>";
  1192.                     }
  1193.  
  1194.                     $output .= ! empty( $excerpt ) ? "<div class='grid-entry-excerpt entry-content' " . avia_markup_helper( array( 'context' => 'entry_content', 'echo' => false, 'id' => $the_id, 'custom_markup' => $custom_markup ) ) . ">{$excerpt}</div>" : '';
  1195.                     $output .= ! empty( $title ) || ! empty( $excerpt ) ? '</div>' : '';
  1196.                     $output .= '<footer class="entry-footer"></footer>';
  1197.                     $output .= '</article>';
  1198.                     $output .= '</div>';
  1199.                 }
  1200.  
  1201.                 $loop_counter ++;
  1202.                 $post_loop_count ++;
  1203.                 $extraClass = '';
  1204.  
  1205.                 if( $loop_counter > $columns )
  1206.                 {
  1207.                     $loop_counter = 1;
  1208.                     $extraClass = 'first';
  1209.                 }
  1210.             }
  1211.  
  1212.             $output .= '</div>';
  1213.  
  1214.             if( $sort != 'no' )
  1215.             {
  1216.                 $output .= '</div>   <!--   class="av-portfolio-grid-sorting-container"  -->';
  1217.             }
  1218.  
  1219.             //append pagination
  1220.             if( $paginate == 'yes' && $avia_pagination = avia_pagination( $this->entries->max_num_pages, 'nav', $query_var_page, $this->current_page ) )
  1221.             {
  1222.                 $post_type_paginate = array_map( function( $value ) { return 'pagination-' . $value; }, $post_type_paginate );
  1223.                 $post_type_paginate = implode( ' ', $post_type_paginate );
  1224.  
  1225.                 $output .= "<div class='pagination-wrap {$post_type_paginate} {$av_display_classes}'>{$avia_pagination}</div>";
  1226.             }
  1227.  
  1228.             return $output;
  1229.         }
  1230.  
  1231.  
  1232.         /**
  1233.          * Generates the html for the sort buttons
  1234.          *
  1235.          * @param array $entries
  1236.          * @param array $params
  1237.          * @return string
  1238.          */
  1239.         protected function sort_buttons( $entries, $params )
  1240.         {
  1241.             //get all categories that are actually listed on the page
  1242.             $categories = get_categories( array(
  1243.                                 'taxonomy'      => $params['taxonomy'],
  1244.                                 'hide_empty'    => 0
  1245.                             ) );
  1246.  
  1247.             $current_page_cats  = array();
  1248.             $cat_count          = array();
  1249.             $display_cats       = is_array( $params['categories'] ) ? $params['categories'] : array_filter( explode( ',', $params['categories'] ) );
  1250.  
  1251.             foreach( $entries as $entry )
  1252.             {
  1253.                 $current_item_cats = get_the_terms( $entry->ID, $params['taxonomy'] );
  1254.  
  1255.                 if( is_array( $current_item_cats ) && ! empty( $current_item_cats ) )
  1256.                 {
  1257.                     foreach( $current_item_cats as $current_item_cat )
  1258.                     {
  1259.                         if( empty( $display_cats ) || in_array( $current_item_cat->term_id, $display_cats ) )
  1260.                         {
  1261.                             $current_page_cats[ $current_item_cat->term_id ] = $current_item_cat->term_id;
  1262.  
  1263.                             if( ! isset( $cat_count[ $current_item_cat->term_id ] ) )
  1264.                             {
  1265.                                 $cat_count[ $current_item_cat->term_id ] = 0;
  1266.                             }
  1267.  
  1268.                             $cat_count[ $current_item_cat->term_id ] ++;
  1269.                         }
  1270.                     }
  1271.                 }
  1272.             }
  1273.  
  1274.             extract( $this->screen_options ); //return $av_font_classes, $av_title_font_classes and $av_display_classes
  1275.  
  1276.             $output = "<div class='sort_width_container {$av_display_classes} av-sort-" . $this->atts['sort'] . "' data-portfolio-id='" . avia_post_grid::$grid . "' ><div id='js_sort_items' >";
  1277.             $hide = count( $current_page_cats ) <= 1 ? 'hidden' : '';
  1278.  
  1279.  
  1280.             $first_item_name = apply_filters( 'avf_portfolio_sort_first_label', __( 'All', 'avia_framework' ), $params );
  1281.             $first_item_html = '<span class="inner_sort_button"><span>' . $first_item_name . '</span><small class="av-cat-count"> ' . count( $entries ) . ' </small></span>';
  1282.  
  1283.  
  1284.             $output .= apply_filters( 'avf_portfolio_sort_heading', '', $params );
  1285.  
  1286.             if( strpos( $this->atts['sort'], 'tax' ) !== false )
  1287.             {
  1288.                 $output .= "<div class='av-current-sort-title'>{$first_item_html}</div>";
  1289.             }
  1290.  
  1291.             $output .= "<div class='sort_by_cat {$hide}'>";
  1292.             $output .= '<a href="#" data-filter="all_sort" class="all_sort_button active_sort">' . $first_item_html . '</a>';
  1293.  
  1294.  
  1295.             foreach( $categories as $category )
  1296.             {
  1297.                 if( in_array( $category->term_id, $current_page_cats ) )
  1298.                 {
  1299.                     //fix for cyrillic, etc. characters - isotope does not support the % char
  1300.                     $category->category_nicename = str_replace( '%', '', $category->category_nicename );
  1301.  
  1302.                     $output .=  '<span class="text-sep ' . $category->category_nicename . '_sort_sep">/</span>';
  1303.                     $output .=  '<a href="#" data-filter="' . $category->category_nicename . '_sort" class="' . $category->category_nicename . '_sort_button" >';
  1304.                     $output .=      '<span class="inner_sort_button">';
  1305.                     $output .=          '<span>' . esc_html( trim( $category->cat_name ) ) . '</span>';
  1306.                     $output .=          '<small class="av-cat-count"> ' . $cat_count[ $category->term_id ] . ' </small>';
  1307.                     $output .=      '</span>';
  1308.                     $output .=  '</a>';
  1309.                 }
  1310.             }
  1311.  
  1312.             $output .= '</div></div></div>';
  1313.  
  1314.             return $output;
  1315.         }
  1316.  
  1317.         /**
  1318.          * Get the categories for each post and create a string that serves as classes so the javascript can sort by those classes
  1319.          *
  1320.          * @param int $the_id
  1321.          * @param array $params
  1322.          * @return string
  1323.          */
  1324.         protected function sort_cat_string( $the_id, $params )
  1325.         {
  1326.             $sort_classes = '';
  1327.             $item_categories = get_the_terms( $the_id, $params['taxonomy'] );
  1328.  
  1329.             if( is_object( $item_categories ) || is_array( $item_categories ) )
  1330.             {
  1331.                 foreach( $item_categories as $cat )
  1332.                 {
  1333.                     //fix for cyrillic, etc. characters - isotope does not support the % char
  1334.                     $cat->slug = str_replace('%', '', $cat->slug );
  1335.  
  1336.                     $sort_classes .= $cat->slug . '_sort ';
  1337.                 }
  1338.             }
  1339.  
  1340.             return $sort_classes;
  1341.         }
  1342.  
  1343.         /**
  1344.          *
  1345.          * @param WP_Post $entry
  1346.          * @return string
  1347.          */
  1348.         protected function build_preview_template( $entry )
  1349.         {
  1350.             if( isset( avia_post_grid::$preview_template[ $entry->ID ] ) )
  1351.             {
  1352.                 return '';
  1353.             }
  1354.  
  1355.             avia_post_grid::$preview_template[ $entry->ID ] = true;
  1356.  
  1357.             $id                     = $entry->ID;
  1358.             $output                 = '';
  1359.             $defaults = array(
  1360.                             'ids'       => get_post_thumbnail_id( $id ),
  1361.                             'text'      => apply_filters( 'get_the_excerpt', $entry->post_excerpt ),
  1362.                             'method'    => 'gallery',
  1363.                             'auto'      => '',
  1364.                             'columns'   => 5
  1365.                         );
  1366.  
  1367.             $params['ids']          = get_post_meta( $id , '_preview_ids', true );
  1368.             $params['text']         = get_post_meta( $id , '_preview_text', true );
  1369.             $params['method']       = get_post_meta( $id , '_preview_display', true );
  1370.             $params['interval']     = get_post_meta( $id , '_preview_autorotation', true );
  1371.             $params['columns']      = get_post_meta( $id , '_preview_columns', true );
  1372.  
  1373.             $params['preview_size'] = apply_filters( 'avf_ajax_preview_image_size', 'gallery' );
  1374.             $params['autoplay']     = is_numeric( $params['interval'] ) ? 'true' : 'false';
  1375.  
  1376.             $link = get_post_meta( $id ,'_portfolio_custom_link', true ) != '' ? get_post_meta( $id , '_portfolio_custom_link_url', true ) : get_permalink( $id );
  1377.  
  1378.  
  1379.             //merge default and params array. remove empty params with array_filter
  1380.             $params = array_merge( $defaults, array_filter( $params ) );
  1381.  
  1382.             $params = apply_filters( 'avf_portfolio_preview_template_params', $params, $entry );
  1383.  
  1384.             global $avia_config;
  1385.  
  1386.             /**
  1387.              * Fullwidth shortcodes like "Fullwidth Button" will break layout because they create an own section.
  1388.              * This allows to return without creating new sections
  1389.              *
  1390.              * @since 4.7.6.4
  1391.              */
  1392.             if( ! isset( $avia_config['portfolio_preview_template'] ) )
  1393.             {
  1394.                 $avia_config['portfolio_preview_template'] = 0;
  1395.             }
  1396.  
  1397.             $avia_config['portfolio_preview_template'] ++;
  1398.  
  1399.             //set the content
  1400.             $content = str_replace( ']]>', ']]&gt;', apply_filters( 'the_content', $params['text'] ) );
  1401.             unset( $params['text'] );
  1402.  
  1403.             if( isset( $avia_config['portfolio_preview_template'] ) )
  1404.             {
  1405.                 $avia_config['portfolio_preview_template'] --;
  1406.  
  1407.                 if( $avia_config['portfolio_preview_template'] <= 0 )
  1408.                 {
  1409.                     unset( $avia_config['portfolio_preview_template'] );
  1410.                 }
  1411.             }
  1412.  
  1413.             //set images
  1414.             $string = '';
  1415.  
  1416.             //set first class if preview images are deactivated
  1417.             $nogalleryclass = '';
  1418.             $params['ajax_request'] = true;
  1419.  
  1420.             switch( $params['method'] )
  1421.             {
  1422.                 case 'gallery':
  1423.                     $params['style'] = 'big_thumb';
  1424.                     $params['thumb_size'] = 'square';
  1425.                     foreach( $params as $key => $param )
  1426.                     {
  1427.                         $string .= $key . "='" . $param . "' ";
  1428.                     }
  1429.                     $images = do_shortcode( "[av_gallery {$string}]" );
  1430.                 break;
  1431.  
  1432.                 case 'slideshow':
  1433.                     $params['size'] = $params['preview_size'];
  1434.                     foreach( $params as $key => $param )
  1435.                     {
  1436.                         $string .= $key . "='" . $param . "' ";
  1437.                     }
  1438.                     $images = do_shortcode( "[av_slideshow {$string}]" );
  1439.                 break;
  1440.  
  1441.                 case 'list':
  1442.                     $images = $this->post_images( $params['ids'] );
  1443.                 break;
  1444.  
  1445.                 case 'no':
  1446.                     $images = false;
  1447.                     $nogalleryclass = ' no_portfolio_preview_gallery ';
  1448.                 break;
  1449.             }
  1450.  
  1451.             $output .= "<div class='ajax_slide ajax_slide_{$id}' data-slide-id='{$id}' >";
  1452.  
  1453.                 $output .= "<article class='inner_slide {$nogalleryclass}' " . avia_markup_helper( array( 'context' => 'entry', 'echo' => false, 'id' => $id, 'custom_markup' => $this->atts['custom_markup'] ) ) . ">";
  1454.  
  1455.                 if( ! empty( $images ) )
  1456.                 {
  1457.                     $output .= "<div class='av_table_col first portfolio-preview-image'>";
  1458.                     $output .=      $images;
  1459.                     $output .= '</div>';
  1460.                 }
  1461.  
  1462.                 if( ! empty( $nogalleryclass ) )
  1463.                 {
  1464.                     $nogalleryclass .= ' first ';
  1465.                 }
  1466.  
  1467.                 $markup = avia_markup_helper( array( 'context' => 'entry_title', 'echo' => false, 'id' => $id, 'custom_markup' => $this->atts['custom_markup'] ) );
  1468.  
  1469.                 $default_heading = 'h2';
  1470.                 $args = array(
  1471.                             'heading'       => $default_heading,
  1472.                             'extra_class'   => ''
  1473.                         );
  1474.  
  1475.                 $extra_args = array( $this, $entry, __METHOD__ );
  1476.  
  1477.                 /**
  1478.                  * @since 4.5.5
  1479.                  * @return array
  1480.                  */
  1481.                 $args = apply_filters( 'avf_customize_heading_settings', $args, __CLASS__, $extra_args );
  1482.  
  1483.                 $heading = ! empty( $args['heading'] ) ? $args['heading'] : $default_heading;
  1484.                 $css = ! empty( $args['extra_class'] ) ? $args['extra_class'] : '';
  1485.  
  1486.                 $aria_label = 'aria-label="' . __( 'Portfolio:', 'avia_framework' ) . ' ' . esc_attr( $entry->post_title ) . '"';
  1487.  
  1488.                 /**
  1489.                  * @since 6.0.3
  1490.                  * @param string $aria_label
  1491.                  * @param string $context
  1492.                  * @param WP_Post $entry
  1493.                  * @return string
  1494.                  */
  1495.                 $aria_label = apply_filters( 'avf_aria_label_for_header', $aria_label, __CLASS__, $entry );
  1496.  
  1497.  
  1498.                 $output .=  "<div class='av_table_col $nogalleryclass portfolio-entry portfolio-preview-content'>";
  1499.  
  1500.                 $output .=      '<header class="entry-content-header" ' . $aria_label . '>';
  1501.                 $output .=          "<{$heading} class='portfolio-preview-title entry-title {$css}' {$markup}><a href='{$link}'>" . avia_wp_get_the_title( $entry ) . "</a></{$heading}>";
  1502.                 $output .=      '</header>';
  1503.  
  1504.                 $output .=      "<div class='entry-content-wrapper entry-content' " . avia_markup_helper( array( 'context' => 'entry_content', 'echo' => false, 'id' => $id, 'custom_markup' => $this->atts['custom_markup'] ) ) . ">";
  1505.                 $output .=          $content;
  1506.                 $output .=      '</div>';
  1507.                 $output .=      "<span class='avia-arrow'></span>";
  1508.  
  1509.                 $output .=  '</div>';
  1510.  
  1511.                 $output .=  '<footer class="entry-footer"></footer>';
  1512.                 $output .= '</article>';
  1513.  
  1514.             $output .= '</div>';
  1515.  
  1516.             return "<script type='text/html' id='avia-tmpl-portfolio-preview-{$id}'>\n{$output}\n</script>\n\n";
  1517.  
  1518.         }
  1519.  
  1520.         /**
  1521.          *
  1522.          * @param string $ids
  1523.          * @return string
  1524.          */
  1525.         protected function post_images( $ids )
  1526.         {
  1527.             if( empty( $ids ) )
  1528.             {
  1529.                 return;
  1530.             }
  1531.  
  1532.             $attachments = get_posts( array(
  1533.                                     'include'           => $ids,
  1534.                                     'post_status'       => 'inherit',
  1535.                                     'post_type'         => 'attachment',
  1536.                                     'post_mime_type'    => 'image',
  1537.                                     'order'             => 'ASC',
  1538.                                     'orderby'           => 'post__in'
  1539.                                 )
  1540.                             );
  1541.  
  1542.             $output = '';
  1543.  
  1544.             foreach( $attachments as $attachment )
  1545.             {
  1546.                 //  create array with responsive info for lightbox
  1547.                 $img = Av_Responsive_Images()->responsive_image_src( $attachment->ID, 'large' );
  1548.  
  1549.                 $alt = get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true );
  1550.                 $alt = ! empty( $alt ) ? esc_attr( $alt ) : '';
  1551.                 $title = trim( $attachment->post_title ) ? esc_attr( $attachment->post_title ) : '';
  1552.                 $description = trim( $attachment->post_content ) ? esc_attr( $attachment->post_content ) : '';
  1553.  
  1554.                 $img_tag = "<img src='{$img[0]}' title='{$title}' alt='{$alt}' />";
  1555.                 $img_tag = Av_Responsive_Images()->prepare_single_image( $img_tag, $attachment->ID, $this->atts['lazy_loading'] );
  1556.  
  1557.                 $lightbox_attr = Av_Responsive_Images()->html_attr_image_src( $img, false );
  1558.  
  1559.                 $output .= "<a {$lightbox_attr} class='portolio-preview-list-image' title='{$description}' >";
  1560.                 $output .=      $img_tag;
  1561.                 $output .= '</a>';
  1562.             }
  1563.  
  1564.             return $output;
  1565.         }
  1566.  
  1567.  
  1568.  
  1569.         /**
  1570.          * Output the preview templates in footer
  1571.          *
  1572.          */
  1573.         public function print_preview_templates()
  1574.         {
  1575.             foreach( $this->entries->posts as $entry )
  1576.             {
  1577.                 echo $this->build_preview_template( $entry );
  1578.             }
  1579.         }
  1580.  
  1581.         /**
  1582.          * Get the entries and add to local variable
  1583.          *
  1584.          * @param array $params
  1585.          */
  1586.         public function query_entries( $params = array() )
  1587.         {
  1588.  
  1589.             $query = array();
  1590.             if( empty( $params ) )
  1591.             {
  1592.                 $params = $this->atts;
  1593.             }
  1594.  
  1595.             if( ! empty( $params['categories'] ) )
  1596.             {
  1597.                 //get the portfolio categories
  1598.                 $terms = explode( ',', $params['categories'] );
  1599.             }
  1600.  
  1601.             $this->current_page = ( $params['paginate'] != 'no' ) ? avia_get_current_pagination_number( 'avia-element-paging' ) : 1;
  1602.  
  1603.             $date_query = AviaHelper::date_query( array(), $params );
  1604.  
  1605.             //if we find categories perform complex query, otherwise simple one
  1606.             if( isset( $terms[0] ) && ! empty( $terms[0] ) && ! is_null( $terms[0] ) && $terms[0] != 'null' )
  1607.             {
  1608.                 $query = array(
  1609.                                 'orderby'       => $params['query_orderby'],
  1610.                                 'order'         => $params['query_order'],
  1611.                                 'paged'         => $this->current_page,
  1612.                                 'posts_per_page' => $params['items'],
  1613.                                 'post_type'     => $params['post_type'],
  1614.                                 'date_query'    => $date_query,
  1615.                                 'tax_query'     => array(
  1616.                                                         array(
  1617.                                                                 'taxonomy'  => $params['taxonomy'],
  1618.                                                                 'field'     => 'id',
  1619.                                                                 'terms'     => $terms,
  1620.                                                                 'operator'  => count( $terms ) == 1 ? 'IN' : $params['term_rel']
  1621.                                                             )
  1622.                                                     )
  1623.                             );
  1624.             }
  1625.             else
  1626.             {
  1627.                 $query = array(
  1628.                                 'orderby'       => $params['query_orderby'],
  1629.                                 'order'         => $params['query_order'],
  1630.                                 'paged'         => $this->current_page,
  1631.                                 'posts_per_page' => $params['items'],
  1632.                                 'post_type'     => $params['post_type'],
  1633.                                 'date_query'    => $date_query,
  1634.                             );
  1635.             }
  1636.  
  1637.             if( 'skip_current' == $params['page_element_filter'] )
  1638.             {
  1639.                 $query['post__not_in'] = isset( $query['post__not_in'] ) ? $query['post__not_in'] : [];
  1640.                 $query['post__not_in'][] = get_the_ID();
  1641.             }
  1642.  
  1643.             /**
  1644.              *
  1645.              * @since < 4.0
  1646.              * @param array $query
  1647.              * @param array $params
  1648.              * @return array
  1649.              */
  1650.             $query = apply_filters( 'avia_post_grid_query', $query, $params );
  1651.  
  1652.             $this->entries = new WP_Query( $query );
  1653.  
  1654.         }
  1655.  
  1656.         /**
  1657.          * 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.
  1658.          * Shortcode uses the query_entries function above
  1659.          *
  1660.          */
  1661.         public function use_global_query()
  1662.         {
  1663.             global $wp_query;
  1664.  
  1665.             $this->entries = $wp_query;
  1666.         }
  1667.  
  1668.     }
  1669. }
  1670.  
  1671.  
  1672. /*
  1673. Example: how to order posts randomly on page load. put this into functions.php
  1674.  
  1675. add_filter('avia_post_grid_query','avia_order_by_random');
  1676. function avia_order_by_random($query)
  1677. {
  1678.     $query['orderby'] = 'rand';
  1679.     return $query;
  1680. }
  1681. */
  1682.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement