Guest User

Untitled

a guest
Feb 26th, 2015
357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.56 KB | None | 0 0
  1. <?php
  2. /**
  3. * Masonry
  4. * Shortcode that allows to display a fullwidth masonry of any post type
  5. */
  6.  
  7. if ( !class_exists( 'avia_sc_masonry_entries' ) )
  8. {
  9. class avia_sc_masonry_entries extends aviaShortcodeTemplate
  10. {
  11. /**
  12. * Create the config array for the shortcode button
  13. */
  14. function shortcode_insert_button()
  15. {
  16. $this->config['name'] = __('Masonry', 'avia_framework' );
  17. $this->config['tab'] = __('Content Elements', 'avia_framework' );
  18. $this->config['icon'] = AviaBuilder::$path['imagesURL']."sc-masonry.png";
  19. $this->config['order'] = 38;
  20. $this->config['target'] = 'avia-target-insert';
  21. $this->config['shortcode'] = 'av_masonry_entries';
  22. $this->config['tooltip'] = __('Display a fullwidth masonry/grid with blog entries', 'avia_framework' );
  23. $this->config['drag-level'] = 3;
  24. }
  25.  
  26.  
  27. function extra_assets()
  28. {
  29. add_action('wp_ajax_avia_ajax_masonry_more', array('avia_masonry','load_more'));
  30. add_action('wp_ajax_nopriv_avia_ajax_masonry_more', array('avia_masonry','load_more'));
  31.  
  32. if(!is_admin() && !current_theme_supports('avia_no_session_support') && !session_id()) session_start();
  33. }
  34.  
  35.  
  36. /**
  37. * Popup Elements
  38. *
  39. * If this function is defined in a child class the element automatically gets an edit button, that, when pressed
  40. * opens a modal window that allows to edit the element properties
  41. *
  42. * @return void
  43. */
  44. function popup_elements()
  45. {
  46. $this->elements = array(
  47.  
  48.  
  49. array(
  50. "name" => __("Which Entries?", 'avia_framework' ),
  51. "desc" => __("Select which entries should be displayed by selecting a taxonomy", 'avia_framework' ),
  52. "id" => "link",
  53. "fetchTMPL" => true,
  54. "type" => "linkpicker",
  55. "subtype" => array( __('Display Entries from:', 'avia_framework' )=>'taxonomy'),
  56. "multiple" => 6,
  57. "std" => "category"
  58. ),
  59.  
  60. array(
  61. "name" => __("Sortable?", 'avia_framework' ),
  62. "desc" => __("Should sorting options based on the taxonomies above be displayed?", 'avia_framework' ),
  63. "id" => "sort",
  64. "type" => "select",
  65. "std" => "yes",
  66. "subtype" => array(
  67. __('Yes, display sort options', 'avia_framework' ) => 'yes',
  68. __('Yes, display sort options and currently active taxonomy', 'avia_framework' ) => 'yes-tax',
  69. __('No, do not display sort options', 'avia_framework' ) => 'no')),
  70.  
  71. array(
  72. "name" => __("Post Number", 'avia_framework' ),
  73. "desc" => __("How many items should be displayed per page?", 'avia_framework' ),
  74. "id" => "items",
  75. "type" => "select",
  76. "std" => "12",
  77. "subtype" => AviaHtmlHelper::number_array(1,100,1, array('All'=>'-1'))),
  78.  
  79. array(
  80. "name" => __("Columns", 'avia_framework' ),
  81. "desc" => __("How many columns do you want to display?", 'avia_framework' ),
  82. "id" => "columns",
  83. "type" => "select",
  84. "std" => "flexible",
  85. "subtype" => array(
  86. __('Automatic, based on screen width', 'avia_framework' ) =>'flexible',
  87. __('2 Columns', 'avia_framework' ) =>'2',
  88. __('3 Columns', 'avia_framework' ) =>'3',
  89. __('4 Columns', 'avia_framework' ) =>'4',
  90. __('5 Columns', 'avia_framework' ) =>'5',
  91. __('6 Columns', 'avia_framework' ) =>'6',
  92.  
  93. )),
  94.  
  95.  
  96.  
  97. array(
  98. "name" => __("Pagination", 'avia_framework' ),
  99. "desc" => __("Should a pagination or load more option be displayed to view additional entries?", 'avia_framework' ),
  100. "id" => "paginate",
  101. "type" => "select",
  102. "std" => "yes",
  103. "required" => array('items','not','-1'),
  104. "subtype" => array(
  105. __('Display Pagination', 'avia_framework' ) =>'pagination',
  106. __('Display "Load More" Button', 'avia_framework' ) =>'load_more',
  107. __('No option to view additional entries', 'avia_framework' ) =>'none')),
  108.  
  109. array(
  110. "name" => __("Order by",'avia_framework' ),
  111. "desc" => __("You can order the result by various attributes like creation date, title, author etc", 'avia_framework' ),
  112. "id" => "query_orderby",
  113. "type" => "select",
  114. "std" => "date",
  115. "subtype" => array(
  116. __('Date', 'avia_framework' ) =>'date',
  117. __('Title', 'avia_framework' ) =>'title',
  118. __('Random', 'avia_framework' ) =>'rand',
  119. __('Author', 'avia_framework' ) =>'author',
  120. __('Name (Post Slug)', 'avia_framework' ) =>'name',
  121. __('Last modified', 'avia_framework' ) =>'modified',
  122. __('Comment Count', 'avia_framework' ) =>'comment_count',
  123. __('Page Order', 'avia_framework' ) =>'menu_order')
  124. ),
  125.  
  126. array(
  127. "name" => __("Display order",'avia_framework' ),
  128. "desc" => __("Display the results either in ascending or descending order", 'avia_framework' ),
  129. "id" => "query_order",
  130. "type" => "select",
  131. "std" => "DESC",
  132. "subtype" => array(
  133. __('Ascending Order', 'avia_framework' ) =>'ASC',
  134. __('Descending Order', 'avia_framework' ) =>'DESC')
  135. ),
  136.  
  137.  
  138. array(
  139. "name" => __("Size Settings", 'avia_framework' ),
  140. "desc" => __("Here you can select how the masonry should behave and handle all entries and the feature images of those entries", 'avia_framework' ),
  141. "id" => "size",
  142. "type" => "radio",
  143. "std" => "fixed masonry",
  144. "options" => array(
  145. 'flex' => __('Flexible Masonry: All entries get the same width but Images of each entry are displayed with their original height and width ratio', 'avia_framework' ),
  146. 'fixed' => __('Perfect Grid: Display a perfect grid where each element has exactly the same size. Images get cropped/stretched if they don\'t fit', 'avia_framework' ),
  147. 'fixed masonry' => __('Perfect Automatic Masonry: Display a grid where most elements get the same size, only elements with very wide images get twice the width and elements with very high images get twice the height. To qualify for "very wide" or "very high" the image must have a aspect ratio of 16:9 or higher', 'avia_framework' ),
  148. 'fixed manually' => __('Perfect Manual Masonry: Manually control the height and width of entries by adding either a "landscape" or "portrait" tag when creating the entry. Elements with no such tag use a fixed default size, elements with both tags will display extra large', 'avia_framework' ),
  149. )),
  150.  
  151.  
  152. array(
  153. "name" => __("Gap between elements", 'avia_framework' ),
  154. "desc" => __("Select the gap between the elements", 'avia_framework' ),
  155. "id" => "gap",
  156. "type" => "select",
  157. "std" => "1px",
  158. "subtype" => array(
  159. __('No Gap', 'avia_framework' ) =>'no',
  160. __('1 Pixel Gap', 'avia_framework' ) =>'1px',
  161. __('Large Gap', 'avia_framework' ) =>'large',
  162. )),
  163.  
  164. array(
  165. "name" => __("Image overlay effect", 'avia_framework' ),
  166. "desc" => __("Do you want to display the image overlay effect that gets removed on mouseover?", 'avia_framework' ),
  167. "id" => "overlay_fx",
  168. "type" => "select",
  169. "std" => "active",
  170. "subtype" => array(
  171. __('Overlay activated', 'avia_framework' ) =>'active',
  172. __('Overlay deactivated', 'avia_framework' ) =>'',
  173. )),
  174.  
  175.  
  176. array(
  177. "name" => __("Element Title and Excerpt", 'avia_framework' ),
  178. "desc" => __("You can choose if you want to display title and/or excerpt", 'avia_framework' ),
  179. "id" => "caption_elements",
  180. "type" => "select",
  181. "std" => "title excerpt",
  182. "subtype" => array(
  183. __('Display Title and Excerpt', 'avia_framework' ) =>'title excerpt',
  184. __('Display Title', 'avia_framework' ) =>'title',
  185. __('Display Excerpt', 'avia_framework' ) =>'excerpt',
  186. __('Display Neither', 'avia_framework' ) =>'none',
  187. )),
  188.  
  189.  
  190. array(
  191. "name" => __("Element Title and Excerpt", 'avia_framework' ),
  192. "desc" => __("You can choose whether to always display Title and Excerpt or only on hover", 'avia_framework' ),
  193. "id" => "caption_display",
  194. "type" => "select",
  195. "std" => "always",
  196. "required" => array('caption_elements','not','none'),
  197. "subtype" => array(
  198. __('Always Display', 'avia_framework' ) =>'always',
  199. __('Display on mouse hover', 'avia_framework' ) =>'on-hover',
  200. )),
  201.  
  202.  
  203. array( "name" => __("For Developers: Section ID", 'avia_framework' ),
  204. "desc" => __("Apply a custom ID Attribute to the section, so you can apply a unique style via CSS. This option is also helpful if you want to use anchor links to scroll to a sections when a link is clicked", 'avia_framework' )."<br/><br/>".
  205. __("Use with caution and make sure to only use allowed characters. No special characters can be used.", 'avia_framework' ),
  206. "id" => "id",
  207. "type" => "input",
  208. "std" => ""),
  209.  
  210. );
  211.  
  212.  
  213. if(current_theme_supports('add_avia_builder_post_type_option'))
  214. {
  215. $element = array(
  216. "name" => __("Select Post Type", 'avia_framework' ),
  217. "desc" => __("Select which post types should be used. Note that your taxonomy will be ignored if you do not select an assign post type.
  218. If yo don't select post type all registered post types will be used", 'avia_framework' ),
  219. "id" => "post_type",
  220. "type" => "select",
  221. "multiple" => 6,
  222. "std" => "",
  223. "subtype" => AviaHtmlHelper::get_registered_post_type_array()
  224. );
  225.  
  226. array_unshift($this->elements, $element);
  227. }
  228.  
  229. }
  230.  
  231. /**
  232. * Editor Element - this function defines the visual appearance of an element on the AviaBuilder Canvas
  233. * Most common usage is to define some markup in the $params['innerHtml'] which is then inserted into the drag and drop container
  234. * Less often used: $params['data'] to add data attributes, $params['class'] to modify the className
  235. *
  236. *
  237. * @param array $params this array holds the default values for $content and $args.
  238. * @return $params the return array usually holds an innerHtml key that holds item specific markup.
  239. */
  240. function editor_element($params)
  241. {
  242. $params['innerHtml'] = "<img src='".$this->config['icon']."' title='".$this->config['name']."' />";
  243. $params['innerHtml'].= "<div class='avia-element-label'>".$this->config['name']."</div>";
  244.  
  245. $params['innerHtml'].= "<div class='avia-flex-element'>";
  246. $params['innerHtml'].= __('This element will stretch across the whole screen by default.','avia_framework')."<br/>";
  247. $params['innerHtml'].= __('If you put it inside a color section or column it will only take up the available space','avia_framework');
  248. $params['innerHtml'].= " <div class='avia-flex-element-2nd'>".__('Currently:','avia_framework');
  249. $params['innerHtml'].= " <span class='avia-flex-element-stretched'>&laquo; ".__('Stretch fullwidth','avia_framework')." &raquo;</span>";
  250. $params['innerHtml'].= " <span class='avia-flex-element-content'>| ".__('Adjust to content width','avia_framework')." |</span>";
  251. $params['innerHtml'].= "</div></div>";
  252.  
  253. return $params;
  254. }
  255.  
  256. /**
  257. * Editor Sub Element - this function defines the visual appearance of an element that is displayed within a modal window and on click opens its own modal window
  258. * Works in the same way as Editor Element
  259. * @param array $params this array holds the default values for $content and $args.
  260. * @return $params the return array usually holds an innerHtml key that holds item specific markup.
  261. */
  262. function editor_sub_element($params)
  263. {
  264. $img_template = $this->update_template("img_fakeArg", "{{img_fakeArg}}");
  265. $template = $this->update_template("title", "{{title}}");
  266. $content = $this->update_template("content", "{{content}}");
  267.  
  268. $thumbnail = isset($params['args']['id']) ? wp_get_attachment_image($params['args']['id']) : "";
  269.  
  270.  
  271. $params['innerHtml'] = "";
  272. $params['innerHtml'] .= "<div class='avia_title_container'>";
  273. $params['innerHtml'] .= " <span class='avia_slideshow_image' {$img_template} >{$thumbnail}</span>";
  274. $params['innerHtml'] .= " <div class='avia_slideshow_content'>";
  275. $params['innerHtml'] .= " <h4 class='avia_title_container_inner' {$template} >".$params['args']['title']."</h4>";
  276. $params['innerHtml'] .= " <p class='avia_content_container' {$content}>".stripslashes($params['content'])."</p>";
  277. $params['innerHtml'] .= " </div>";
  278. $params['innerHtml'] .= "</div>";
  279.  
  280.  
  281.  
  282. return $params;
  283. }
  284.  
  285.  
  286.  
  287. /**
  288. * Frontend Shortcode Handler
  289. *
  290. * @param array $atts array of attributes
  291. * @param string $content text within enclosing form of shortcode element
  292. * @param string $shortcodename the shortcode found, when == callback name
  293. * @return string $output returns the modified html string
  294. */
  295.  
  296. function shortcode_handler($atts, $content = "", $shortcodename = "", $meta = "")
  297. {
  298. $output = "";
  299.  
  300. $params['class'] = "main_color ".$meta['el_class'];
  301. $params['open_structure'] = false;
  302. $params['id'] = !empty($atts['id']) ? AviaHelper::save_string($atts['id'],'-') : "";
  303. $params['custom_markup'] = $meta['custom_markup'];
  304. if( ($atts['gap'] == 'no' && $atts['sort'] == "no") || $meta['index'] == 0) $params['class'] .= " avia-no-border-styling";
  305.  
  306. //we dont need a closing structure if the element is the first one or if a previous fullwidth element was displayed before
  307. if($meta['index'] == 0) $params['close'] = false;
  308. if(!empty($meta['siblings']['prev']['tag']) && in_array($meta['siblings']['prev']['tag'], AviaBuilder::$full_el_no_section )) $params['close'] = false;
  309.  
  310. if($meta['index'] != 0) $params['class'] .= " masonry-not-first";
  311. if($meta['index'] == 0 && get_post_meta(get_the_ID(), 'header', true) != "no") $params['class'] .= " masonry-not-first";
  312.  
  313. $masonry = new avia_masonry($atts);
  314. $masonry->extract_terms();
  315. $masonry->query_entries();
  316. $masonry_html = $masonry->html();
  317.  
  318.  
  319.  
  320. if(!ShortcodeHelper::is_top_level()) return $masonry_html;
  321.  
  322. $output .= avia_new_section($params);
  323. $output .= $masonry_html;
  324. $output .= avia_section_after_element_content( $meta , 'after_masonry' );
  325.  
  326. return $output;
  327. }
  328.  
  329. }
  330. }
  331.  
  332.  
  333.  
  334.  
  335.  
  336. if ( !class_exists( 'avia_masonry' ) )
  337. {
  338. class avia_masonry
  339. {
  340. static $element = 0;
  341. protected $atts;
  342. protected $entries;
  343.  
  344. function __construct($atts = array())
  345. {
  346. self::$element += 1;
  347. $this->atts = shortcode_atts(array( 'ids' => false,
  348. 'action'=> false,
  349. 'link' => 'category',
  350. 'post_type'=> get_post_types(),
  351. 'items' => 24,
  352. 'size' => 'fixed',
  353. 'gap' => '1px',
  354. 'overlay_fx' => 'active',
  355. 'offset' => 0,
  356. 'container_links' => true,
  357. 'container_class' => "",
  358. 'paginate' => 'paginate',
  359. 'caption_elements' => 'title excerpt',
  360. 'caption_display' => 'always',
  361. 'sort' => 'no',
  362. 'columns' => 'automatic',
  363. 'auto_ratio' => 1.7, //equals a 16:9 ratio
  364. 'set_breadcrumb' => true, //no shortcode option for this, modifies the breadcrumb nav, must be false on taxonomy overview
  365. 'custom_markup' => '',
  366. 'query_orderby' => 'date',
  367. 'query_order' => 'DESC',
  368. ), $atts, 'av_masonry_entries');
  369.  
  370. $this->atts = apply_filters('avf_masonry_settings', $this->atts, self::$element);
  371. }
  372.  
  373. //ajax function to load additional items
  374. static function load_more()
  375. {
  376. //increase the post items by one to fetch an additional item. this item is later removed by the javascript but it tells the script if there are more items to load or not
  377. $_POST['items'] = $_POST['items'] + 1;
  378.  
  379. $masonry = new avia_masonry($_POST);
  380.  
  381. if(!empty($_POST['ids']))
  382. {
  383. $masonry->query_entries_by_id();
  384. }
  385. else
  386. {
  387. $masonry->extract_terms();
  388. $masonry->query_entries();
  389. }
  390.  
  391. $output = $masonry->html();
  392.  
  393. echo '{av-masonry-loaded}'.$output;
  394. exit();
  395. }
  396.  
  397.  
  398. function extract_terms()
  399. {
  400. if(isset($this->atts['link']))
  401. {
  402. $this->atts['link'] = explode(',', $this->atts['link'], 2 );
  403. $this->atts['taxonomy'] = $this->atts['link'][0];
  404.  
  405. if(isset($this->atts['link'][1]))
  406. {
  407. $this->atts['categories'] = $this->atts['link'][1];
  408. }
  409. else
  410. {
  411. $this->atts['categories'] = array();
  412. }
  413. }
  414. }
  415.  
  416. function sort_buttons()
  417. {
  418. $sort_terms = get_terms( $this->atts['taxonomy'] , array('hide_empty'=>true) );
  419.  
  420. $current_page_terms = array();
  421. $term_count = array();
  422. $display_terms = is_array($this->atts['categories']) ? $this->atts['categories'] : array_filter(explode(',',$this->atts['categories']));
  423.  
  424. foreach ($this->loop as $entry)
  425. {
  426. if($current_item_terms = get_the_terms( $entry['ID'], $this->atts['taxonomy'] ))
  427. {
  428. if(!empty($current_item_terms))
  429. {
  430. foreach($current_item_terms as $current_item_term)
  431. {
  432. if(empty($display_terms) || in_array($current_item_term->term_id, $display_terms))
  433. {
  434. $current_page_terms[$current_item_term->term_id] = $current_item_term->term_id;
  435.  
  436. if(!isset($term_count[$current_item_term->term_id] ))
  437. {
  438. $term_count[$current_item_term->term_id] = 0;
  439. }
  440.  
  441. $term_count[$current_item_term->term_id] ++;
  442. }
  443. }
  444. }
  445. }
  446. }
  447.  
  448.  
  449. $hide = count($current_page_terms) <= 1 ? "hidden" : "";
  450. $output = "";
  451.  
  452. if(empty($hide))
  453. {
  454. $output = "<div class='av-masonry-sort main_color av-sort-".$this->atts['sort']."' data-masonry-id='".self::$element."' >";
  455. //$output .= "<div class='container'>";
  456.  
  457. $first_item_name = apply_filters('avf_masonry_sort_first_label', __('All','avia_framework' ), $this->atts);
  458. $first_item_html = '<span class="inner_sort_button"><span>'.$first_item_name.'</span><small class="avia-term-count"> '.count($this->loop).' </small></span>';
  459.  
  460. $output .= apply_filters('avf_masonry_sort_heading', "", $this->atts);
  461.  
  462. if(strpos($this->atts['sort'], 'tax') !== false) $output .= "<div class='av-current-sort-title'>{$first_item_html}</div>";
  463.  
  464. $output .= "<div class='av-sort-by-term {$hide} '>";
  465. $output .= '<a href="#" data-filter="all_sort" class="all_sort_button active_sort">'.$first_item_html.'</a>';
  466.  
  467. foreach($sort_terms as $term)
  468. {
  469. $show_item = in_array($term->term_id, $current_page_terms) ? 'avia_show_sort' : 'avia_hide_sort';
  470. if(!isset($term_count[$term->term_id])) $term_count[$term->term_id] = 0;
  471. $term->slug = str_replace('%', '', $term->slug);
  472.  
  473. $output .= "<span class='text-sep {$term->slug}_sort_sep {$show_item}'>/</span>";
  474. $output .= '<a href="#" data-filter="'.$term->slug.'_sort" class="'.$term->slug.'_sort_button '.$show_item.'" ><span class="inner_sort_button">';
  475. $output .= "<span>".esc_html(trim($term->name))."</span>";
  476. $output .= "<small class='avia-term-count'> ".$term_count[$term->term_id]." </small></span>";
  477. $output .= "</a>";
  478. }
  479.  
  480. //$output .= "</div>";
  481. $output .= "</div></div>";
  482. }
  483.  
  484. return $output;
  485.  
  486.  
  487. }
  488.  
  489. //get the categories for each post and create a string that serves as classes so the javascript can sort by those classes
  490. function sort_array($the_id)
  491. {
  492. $sort_classes = array("all_sort");
  493. $item_terms = get_the_terms( $the_id, $this->atts['taxonomy']);
  494.  
  495. if(is_object($item_terms) || is_array($item_terms))
  496. {
  497. foreach ($item_terms as $term)
  498. {
  499. $term->slug = str_replace('%', '', $term->slug);
  500. $sort_classes[] = $term->slug.'_sort ';
  501. }
  502. }
  503.  
  504. return $sort_classes;
  505. }
  506.  
  507.  
  508.  
  509. function html()
  510. {
  511. if(empty($this->loop)) return;
  512.  
  513. $output = "";
  514. $items = "";
  515. $size = strpos($this->atts['size'], 'fixed') !== false ? 'fixed' : "flex";
  516. $auto = strpos($this->atts['size'], 'masonry') !== false ? true : false;
  517. $manually = strpos($this->atts['size'], 'manually') !== false ? true : false;
  518. $defaults = array('ID'=>'',
  519. 'thumb_ID'=>'',
  520. 'title' =>'',
  521. 'url' => '',
  522. 'class' => array(),
  523. 'date' => '',
  524. 'excerpt' => '',
  525. 'data' => '',
  526. 'attachment'=> array(),
  527. 'attachment_overlay' => array(),
  528. 'bg' => "",
  529. 'before_content'=>'', // if set replaces the whole bg part
  530. 'text_before'=>'',
  531. 'text_after'=>'',
  532. 'img_before'=>'');
  533.  
  534.  
  535. $output .= "<div id='av-masonry-".self::$element."' class='av-masonry noHover av-{$size}-size av-{$this->atts['gap']}-gap av-hover-overlay-{$this->atts['overlay_fx']} av-masonry-col-{$this->atts['columns']} av-caption-{$this->atts['caption_display']} {$this->atts['container_class']}' >";
  536.  
  537. $output .= $this->atts['sort'] != "no" ? $this->sort_buttons() : "";
  538.  
  539. $output .= "<div class='av-masonry-container isotope av-js-disabled ' >";
  540. $all_sorts = array();
  541. $sort_array = array();
  542. foreach($this->loop as $entry)
  543. {
  544. extract(array_merge($defaults, $entry));
  545. $img_html = "";
  546. $img_style = "";
  547. if($this->atts['sort'] != "no")
  548. {
  549. $sort_array = $this->sort_array($entry['ID']);
  550. }
  551. $class_string = implode(' ', $class).' '.implode(' ', $sort_array);
  552. $all_sorts = array_merge($all_sorts, $sort_array);
  553.  
  554. if(!empty($attachment))
  555. {
  556. $alt = get_post_meta($thumb_ID, '_wp_attachment_image_alt', true);
  557. $alt = !empty($alt) ? esc_attr($alt) : '';
  558. $title = esc_attr(get_the_title($thumb_ID));
  559.  
  560. if(isset($attachment[0]))
  561. {
  562. $img_html = '<img src="'.$attachment[0].'" title="'.$title.'" alt="'.$alt.'" />';
  563. $img_style = 'style="background-image: url('.$attachment[0].');"';
  564. $class_string .= " av-masonry-item-with-image";
  565. }
  566.  
  567. if(isset($attachment_overlay[0]))
  568. {
  569. $over_html = '<img src="'.$attachment_overlay[0].'" title="'.$title.'" alt="'.$alt.'" />';
  570. $over_style = 'style="background-image: url('.$attachment_overlay[0].');"';
  571. $img_before = '<div class="av-masonry-image-container av-masonry-overlay" '.$over_style.'>'.$over_html.'</div>';
  572. }
  573.  
  574. $bg = '<div class="av-masonry-outerimage-container">'.$img_before.'<div class="av-masonry-image-container" '.$img_style.'>'.$img_html.'</div></div>';
  575.  
  576. }
  577. else
  578. {
  579. $class_string .= " av-masonry-item-no-image";
  580. }
  581.  
  582.  
  583. if($size == 'fixed')
  584. {
  585. if(!empty($attachment) || !empty($before_content))
  586. {
  587. if($auto)
  588. $class_string .= $this->ratio_check_by_image_size($attachment);
  589.  
  590. if($manually)
  591. $class_string .= $this->ratio_check_by_tag($entry['tags']);
  592. }
  593. }
  594.  
  595.  
  596. $linktitle = "";
  597.  
  598. if($post_type == 'attachment' && strpos($html_tags[0], 'a href=') !== false)
  599. {
  600. $linktitle = 'title="'.esc_attr($description).'"';
  601. }
  602. else if(strpos($html_tags[0], 'a href=') !== false)
  603. {
  604. $linktitle = 'title="'.esc_attr($the_title).'"';
  605. }
  606. $markup = ($post_type == 'attachment') ? avia_markup_helper(array('context' => 'image_url','echo'=>false, 'id'=>$entry['ID'], 'custom_markup'=>$this->atts['custom_markup'])) : avia_markup_helper(array('context' => 'entry','echo'=>false, 'id'=>$entry['ID'], 'custom_markup'=>$this->atts['custom_markup']));
  607.  
  608. $items .= "<{$html_tags[0]} class='{$class_string}' {$linktitle} {$markup}>";
  609. $items .= "<div class='av-inner-masonry-sizer'></div>"; //responsible for the size
  610. $items .= "<figure class='av-inner-masonry main_color'>";
  611. $items .= $bg;
  612.  
  613. //title and excerpt
  614. if($this->atts['caption_elements'] != 'none' || !empty($text_add))
  615. {
  616. $items .= "<figcaption class='av-inner-masonry-content site-background'><div class='av-inner-masonry-content-pos'><div class='avia-arrow'></div>".$text_before;
  617.  
  618. if(strpos($this->atts['caption_elements'], 'title') !== false){
  619. $markup = avia_markup_helper(array('context' => 'entry_title','echo'=>false, 'id'=>$entry['ID'], 'custom_markup'=>$this->atts['custom_markup']));
  620. $items .= "<h3 class='av-masonry-entry-title entry-title' {$markup}>{$the_title}</h3>";
  621. }
  622.  
  623. if(strpos($this->atts['caption_elements'], 'excerpt') !== false && !empty($content)){
  624. $markup = avia_markup_helper(array('context' => 'entry_content','echo'=>false, 'id'=>$entry['ID'], 'custom_markup'=>$this->atts['custom_markup']));
  625. $items .= "<div class='av-masonry-entry-content entry-content' {$markup}>{$content}</div>";
  626. }
  627. $items .= $text_after."</div></figcaption>";
  628. }
  629. $items .= "</figure>";
  630. $items .= "</{$html_tags[1]}><!--end av-masonry entry-->";
  631. }
  632.  
  633. //if its an ajax call return the items only without container
  634. if(isset($this->atts['action']) && $this->atts['action'] == 'avia_ajax_masonry_more')
  635. {
  636. return $items;
  637. }
  638.  
  639. // if its no ajax load prepend an empty invisible element as the first element. this is used for calculating the correct width of a default element.
  640. // in theory this is not necessary because the masonry can detect that with an extra js parameter but sorting becomes slugish if that param is set
  641.  
  642. $all_sort_string = implode(' ', array_unique($all_sorts));
  643. $items = "<div class='av-masonry-entry isotope-item av-masonry-item-no-image {$all_sort_string}'></div>".$items;
  644.  
  645. $output .= $items;
  646. $output .= "</div>";
  647.  
  648.  
  649. //append pagination
  650. if($this->atts['paginate'] == "pagination" && $avia_pagination = avia_pagination($this->entries->max_num_pages, 'nav'))
  651. {
  652. $output .= "<div class='av-masonry-pagination av-masonry-pagination-{$this->atts['paginate']}'>{$avia_pagination}</div>";
  653. }
  654. else if($this->atts['paginate'] == "load_more" && $this->entries->max_num_pages > count($this->entries))
  655. {
  656. $output .= $this->load_more_button();
  657. }
  658.  
  659. $output .= "</div>";
  660.  
  661. return $output;
  662. }
  663.  
  664.  
  665. function load_more_button()
  666. {
  667. $data_string = AviaHelper::create_data_string($this->atts);
  668.  
  669. $output = "";
  670. $output .= "<a class='av-masonry-pagination av-masonry-load-more' href='#load-more' {$data_string}>".__('Load more','avia_framework')."</a>";
  671.  
  672. return $output;
  673. }
  674.  
  675. function ratio_check_by_image_size($attachment)
  676. {
  677. $img_size = ' av-grid-img';
  678.  
  679. if(!empty($attachment[1]) && !empty($attachment[2]))
  680. {
  681. if($attachment[1] > $attachment[2]) //landscape
  682. {
  683. //only consider it landscape if its 1.7 times wider than high
  684. if($attachment[1] / $attachment[2] > $this->atts['auto_ratio']) $img_size = ' av-landscape-img';
  685. }
  686. else //same check with portrait
  687. {
  688. if($attachment[2] / $attachment[1] > $this->atts['auto_ratio']) $img_size = ' av-portrait-img';
  689. }
  690. }
  691.  
  692. return $img_size;
  693. }
  694.  
  695. function ratio_check_by_tag($tags)
  696. {
  697. $img_size = '';
  698.  
  699. if(is_array($tags))
  700. {
  701. $tag_values = apply_filters('avf_ratio_check_by_tag_values', array('portrait' => 'portrait', 'landscape' => 'landscape'));
  702.  
  703. if(in_array($tag_values['portrait'], $tags)) { $img_size .= ' av-portrait-img'; }
  704. if(in_array($tag_values['landscape'], $tags)){ $img_size .= ' av-landscape-img'; }
  705. }
  706.  
  707. if(empty($img_size)) $img_size = ' av-grid-img';
  708.  
  709. return $img_size;
  710.  
  711. }
  712.  
  713.  
  714. function prepare_loop_from_entries()
  715. {
  716. $this->loop = array();
  717. if(empty($this->entries) || empty($this->entries->posts)) return;
  718. $tagTax = "post_tag";
  719. $date_format = get_option('date_format');
  720.  
  721.  
  722. foreach($this->entries->posts as $key => $entry)
  723. {
  724. $overlay_img = $custom_url = false;
  725. $img_size = 'masonry';
  726. $author = apply_filters('avf_author_name', get_the_author_meta('display_name', $entry->post_author), $entry->post_author);
  727.  
  728. $this->loop[$key]['text_before'] = "";
  729. $this->loop[$key]['text_after'] = "";
  730. $this->loop[$key]['ID'] = $id = $entry->ID;
  731. $this->loop[$key]['post_type'] = $entry->post_type;
  732. $this->loop[$key]['thumb_ID'] = get_post_thumbnail_id($id);
  733. $this->loop[$key]['the_title'] = get_the_title($id);
  734. $this->loop[$key]['url'] = get_permalink($id);
  735. $commentCount = get_comments_number($entry->ID);
  736. $this->loop[$key]['comment'] = "<div class='av-masonry-comment meta-color'>Comments: {$commentCount}</div>";
  737. $this->loop[$key]['date'] = "<span class='av-masonry-date meta-color updated'>".get_the_time($date_format, $id)."</span>";
  738. $this->loop[$key]['author'] = "<span class='av-masonry-author meta-color vcard author'><span class='fn'>". __('by','avia_framework') .' '. $author."</span></span>";
  739. $this->loop[$key]['class'] = get_post_class("av-masonry-entry isotope-item", $id);
  740. $this->loop[$key]['content'] = $entry->post_excerpt;
  741. $this->loop[$key]['description'] = !empty($entry->post_content) ? $entry->post_content : $entry->post_excerpt;
  742.  
  743. if(empty($this->loop[$key]['content']))
  744. {
  745. $this->loop[$key]['content'] = avia_backend_truncate($entry->post_content, apply_filters( 'avf_masonry_excerpt_length' , 60) , apply_filters( 'avf_masonry_excerpt_delimiter' , " "), "…", true, '');
  746. }
  747.  
  748. //post type specific
  749. switch($entry->post_type)
  750. {
  751. case 'post':
  752.  
  753. $post_format = get_post_format($id) ? get_post_format($id) : 'standard';
  754. $this->loop[$key] = apply_filters( 'post-format-'.$post_format, $this->loop[$key] );
  755. $this->loop[$key]['text_after'] .= $this->loop[$key]['date'];
  756. $this->loop[$key]['text_after'] .= $this->loop[$key]['comment'];
  757. $this->loop[$key]['text_after'] .= '<span class="av-masonry-text-sep text-sep-author">/</span>';
  758. $this->loop[$key]['text_after'] .= $this->loop[$key]['author'];
  759.  
  760. switch($post_format)
  761. {
  762. case 'quote' :
  763. case 'link' :
  764. case 'image' :
  765. case 'gallery' :
  766. if(!$this->loop[$key]['thumb_ID'])
  767. {
  768. $this->loop[$key]['text_before'] = av_icon_display($post_format);
  769. }
  770. break;
  771.  
  772. case 'audio' :
  773. case 'video' :
  774. if(!$this->loop[$key]['thumb_ID'])
  775. {
  776. $this->loop[$key]['text_before'] = av_icon_display($post_format);
  777. }
  778. else
  779. {
  780. $this->loop[$key]['text_before'] = av_icon_display($post_format, 'av-masonry-media');
  781. }
  782. break;
  783. }
  784.  
  785.  
  786.  
  787. break;
  788.  
  789. case 'portfolio':
  790.  
  791. //set portfolio breadcrumb navigation
  792. if($this->atts['set_breadcrumb'] && is_page()) $_SESSION["avia_{$entry->post_type}"] = get_the_ID();
  793.  
  794. //check if the user has set up a custom link
  795. if(!post_password_required($id)){
  796. $custom_link = get_post_meta( $id ,'_portfolio_custom_link', true) != "" ? get_post_meta( $id ,'_portfolio_custom_link_url', true) : false;
  797. if($custom_link) $this->loop[$key]['url'] = $custom_link;
  798. }
  799. break;
  800.  
  801.  
  802. case 'attachment':
  803.  
  804. $custom_url = get_post_meta( $id, 'av-custom-link', true );
  805. $this->loop[$key]['thumb_ID'] = $id;
  806. $this->loop[$key]['content'] = $entry->post_excerpt;
  807.  
  808. if($custom_url)
  809. {
  810. $this->loop[$key]['url'] = $custom_url;
  811. }
  812. else
  813. {
  814. $this->loop[$key]['url'] = wp_get_attachment_image_src($id, apply_filters('avf_avia_builder_masonry_lightbox_img_size','large'));
  815. $this->loop[$key]['url'] = reset($this->loop[$key]['url']);
  816. }
  817.  
  818.  
  819. break;
  820.  
  821. case 'product':
  822. //check if woocommerce is enabled in the first place so we can use woocommerce functions
  823. if(function_exists('avia_woocommerce_enabled') && avia_woocommerce_enabled())
  824. {
  825. $tagTax = "product_tag";
  826. $product = get_product( $id );
  827. $overlay_img = avia_woocommerce_gallery_first_thumbnail($id, $img_size, true);
  828.  
  829. $this->loop[$key]['text_after'] .= '<span class="av-masonry-price price">'.$product->get_price_html()."</span>";
  830. if($product->is_on_sale( )) $this->loop[$key]['text_after'] .= '<span class="onsale">'.__( 'Sale!', 'avia_framework' ).'</span>';
  831. }
  832. break;
  833. }
  834.  
  835.  
  836. //check if post is password protected
  837. if(post_password_required($id))
  838. {
  839. $this->loop[$key]['content'] = "";
  840. $this->loop[$key]['class'][] = "entry-protected";
  841. $this->loop[$key]['thumb_ID'] = "";
  842. $this->loop[$key]['text_before'] = av_icon_display('closed');
  843. $this->loop[$key]['text_after'] = $this->loop[$key]['date'];
  844. }
  845.  
  846.  
  847.  
  848. //set the html tags. depending on the link settings use either an a tag or a div tag
  849. if(!empty($this->atts['container_links']) || !empty($custom_url))
  850. {
  851. $this->loop[$key]['html_tags'] = array('a href="'.$this->loop[$key]['url'].'"','a'); //opening and closing tag for the masonry container
  852. }
  853. else
  854. {
  855. $this->loop[$key]['html_tags'] = array('div','div');
  856. }
  857.  
  858.  
  859. //get post tags
  860. $this->loop[$key]['tags'] = wp_get_post_terms($id, $tagTax, array( 'fields' => 'slugs' ));
  861.  
  862. //check if the image got landscape as well as portrait class applied. in that case use a bigger image size
  863. if(strlen($this->ratio_check_by_tag($this->loop[$key]['tags'])) > 20) $img_size = 'extra_large';
  864.  
  865. //get attachment data
  866. $this->loop[$key]['attachment'] = !empty($this->loop[$key]['thumb_ID']) ? wp_get_attachment_image_src($this->loop[$key]['thumb_ID'], $img_size) : "";
  867.  
  868. //get overlay attachment in case the overlay is set
  869. $this->loop[$key]['attachment_overlay'] = !empty($overlay_img) ? wp_get_attachment_image_src($overlay_img, $img_size) : "";
  870.  
  871. //apply filter for other post types, in case we want to use them and display additional/different information
  872. $this->loop[$key] = apply_filters('avf_masonry_loop_prepare', $this->loop[$key], $this->entries);
  873. }
  874. }
  875.  
  876.  
  877. //fetch new entries
  878. public function query_entries($params = array())
  879. {
  880. global $avia_config;
  881.  
  882. if(empty($params)) $params = $this->atts;
  883.  
  884. if(empty($params['custom_query']))
  885. {
  886. $query = array();
  887.  
  888. if(!empty($params['categories']))
  889. {
  890. //get the portfolio categories
  891. $terms = explode(',', $params['categories']);
  892. }
  893.  
  894. $page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );
  895. if(!$page || $params['paginate'] == 'no') $page = 1;
  896.  
  897. //if we find no terms for the taxonomy fetch all taxonomy terms
  898. if(empty($terms[0]) || is_null($terms[0]) || $terms[0] === "null")
  899. {
  900. $terms = array();
  901. $allTax = get_terms( $params['taxonomy']);
  902. foreach($allTax as $tax)
  903. {
  904. $terms[] = $tax->term_id;
  905. }
  906. }
  907.  
  908.  
  909. if(empty($params['post_type'])) $params['post_type'] = get_post_types();
  910. if(is_string($params['post_type'])) $params['post_type'] = explode(',', $params['post_type']);
  911.  
  912. $query = array( 'orderby' => $params['query_orderby'],
  913. 'order' => $params['query_order'],
  914. 'paged' => $page,
  915. 'post_type' => $params['post_type'],
  916. 'post_status' => 'publish',
  917. 'offset' => $params['offset'],
  918. 'posts_per_page' => $params['items'],
  919. 'tax_query' => array( array( 'taxonomy' => $params['taxonomy'],
  920. 'field' => 'id',
  921. 'terms' => $terms,
  922. 'operator' => 'IN')));
  923.  
  924.  
  925.  
  926.  
  927. }
  928. else
  929. {
  930. $query = $params['custom_query'];
  931. }
  932.  
  933.  
  934. $query = apply_filters('avia_masonry_entries_query', $query, $params);
  935.  
  936. $this->entries = new WP_Query( $query );
  937. $this->prepare_loop_from_entries();
  938. }
  939.  
  940.  
  941. public function query_entries_by_id($params = array())
  942. {
  943. global $avia_config;
  944.  
  945. if(empty($params)) $params = $this->atts;
  946.  
  947. $ids = is_array($this->atts['ids']) ? $this->atts['ids'] : array_filter(explode(',',$this->atts['ids']));
  948.  
  949. $page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );
  950. if(!$page) $page = 1;
  951.  
  952. $query = array(
  953. 'post__in' => $ids,
  954. 'post_status' => 'inherit',
  955. 'post_type' => 'attachment',
  956. 'post_mime_type' => 'image',
  957. 'paged' => $page,
  958. 'order' => 'ASC',
  959. 'offset' => $params['offset'],
  960. 'posts_per_page' => $params['items'],
  961. 'orderby' => 'post__in'
  962. );
  963.  
  964.  
  965. $query = apply_filters('avia_masonry_entries_query', $query, $params);
  966.  
  967. $this->entries = new WP_Query( $query );
  968. $this->prepare_loop_from_entries();
  969.  
  970.  
  971. }
  972. }
  973. }
Advertisement
Add Comment
Please, Sign In to add comment