Advertisement
Guest User

masonry-entries.php

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