Kimberlyjo

Masonry for Ismael

Mar 21st, 2014
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.78 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. if(current_theme_supports('add_avia_builder_post_type_option'))
  168. {
  169. $element = array(
  170. "name" => __("Select Post Type", 'avia_framework' ),
  171. "desc" => __("Select which post types should be used. Note that your taxonomy will be ignored if you do not select an assign post type.
  172. If yo don't select post type all registered post types will be used", 'avia_framework' ),
  173. "id" => "post_type",
  174. "type" => "select",
  175. "multiple" => 6,
  176. "std" => "",
  177. "subtype" => AviaHtmlHelper::get_registered_post_type_array()
  178. );
  179.  
  180. array_unshift($this->elements, $element);
  181. }
  182.  
  183. }
  184.  
  185. /**
  186. * Editor Element - this function defines the visual appearance of an element on the AviaBuilder Canvas
  187. * Most common usage is to define some markup in the $params['innerHtml'] which is then inserted into the drag and drop container
  188. * Less often used: $params['data'] to add data attributes, $params['class'] to modify the className
  189. *
  190. *
  191. * @param array $params this array holds the default values for $content and $args.
  192. * @return $params the return array usually holds an innerHtml key that holds item specific markup.
  193. */
  194. function editor_element($params)
  195. {
  196. $params['innerHtml'] = "<img src='".$this->config['icon']."' title='".$this->config['name']."' />";
  197. $params['innerHtml'].= "<div class='avia-element-label'>".$this->config['name']."</div>";
  198. return $params;
  199. }
  200.  
  201. /**
  202. * 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
  203. * Works in the same way as Editor Element
  204. * @param array $params this array holds the default values for $content and $args.
  205. * @return $params the return array usually holds an innerHtml key that holds item specific markup.
  206. */
  207. function editor_sub_element($params)
  208. {
  209. $img_template = $this->update_template("img_fakeArg", "{{img_fakeArg}}");
  210. $template = $this->update_template("title", "{{title}}");
  211. $content = $this->update_template("content", "{{content}}");
  212.  
  213. $thumbnail = isset($params['args']['id']) ? wp_get_attachment_image($params['args']['id']) : "";
  214.  
  215.  
  216. $params['innerHtml'] = "";
  217. $params['innerHtml'] .= "<div class='avia_title_container'>";
  218. $params['innerHtml'] .= " <span class='avia_slideshow_image' {$img_template} >{$thumbnail}</span>";
  219. $params['innerHtml'] .= " <div class='avia_slideshow_content'>";
  220. $params['innerHtml'] .= " <h4 class='avia_title_container_inner' {$template} >".$params['args']['title']."</h4>";
  221. $params['innerHtml'] .= " <p class='avia_content_container' {$content}>".stripslashes($params['content'])."</p>";
  222. $params['innerHtml'] .= " </div>";
  223. $params['innerHtml'] .= "</div>";
  224.  
  225.  
  226.  
  227. return $params;
  228. }
  229.  
  230.  
  231.  
  232. /**
  233. * Frontend Shortcode Handler
  234. *
  235. * @param array $atts array of attributes
  236. * @param string $content text within enclosing form of shortcode element
  237. * @param string $shortcodename the shortcode found, when == callback name
  238. * @return string $output returns the modified html string
  239. */
  240.  
  241. function shortcode_handler($atts, $content = "", $shortcodename = "", $meta = "")
  242. {
  243. $output = "";
  244.  
  245. $skipSecond = false;
  246.  
  247. //check if we got a layerslider
  248. global $wpdb;
  249.  
  250. $params['class'] = "main_color ".$meta['el_class'];
  251. $params['open_structure'] = false;
  252. $params['id'] = !empty($atts['id']) ? AviaHelper::save_string($atts['id'],'-') : "";
  253.  
  254. //we dont need a closing structure if the element is the first one or if a previous fullwidth element was displayed before
  255. if($meta['index'] == 0) $params['close'] = false;
  256. if(!empty($meta['siblings']['prev']['tag']) && in_array($meta['siblings']['prev']['tag'], AviaBuilder::$full_el_no_section )) $params['close'] = false;
  257.  
  258. if($meta['index'] != 0) $params['class'] .= " masonry-not-first";
  259. if($meta['index'] == 0 && get_post_meta(get_the_ID(), 'header', true) != "no") $params['class'] .= " masonry-not-first";
  260.  
  261. $masonry = new avia_masonry($atts);
  262. $masonry->extract_terms();
  263. $masonry->query_entries();
  264. $masonry_html = $masonry->html();
  265.  
  266.  
  267.  
  268.  
  269. // if(!ShortcodeHelper::is_top_level()) return $masonry_html; // todo: masonry within columns. doesnt quite work yet
  270.  
  271. $output .= avia_new_section($params);
  272. $output .= $masonry_html;
  273. $output .= "</div>"; //close section
  274.  
  275.  
  276. //if the next tag is a section dont create a new section from this shortcode
  277. if(!empty($meta['siblings']['next']['tag']) && in_array($meta['siblings']['next']['tag'], AviaBuilder::$full_el ))
  278. {
  279. $skipSecond = true;
  280. }
  281.  
  282. //if there is no next element dont create a new section.
  283. if(empty($meta['siblings']['next']['tag']))
  284. {
  285. $skipSecond = true;
  286. }
  287.  
  288. if(empty($skipSecond)) {
  289.  
  290. $output .= avia_new_section(array('close'=>false, 'id' => "after_masonry"));
  291.  
  292. }
  293.  
  294. return $output;
  295. }
  296.  
  297. }
  298. }
  299.  
  300.  
  301.  
  302.  
  303.  
  304. if ( !class_exists( 'avia_masonry' ) )
  305. {
  306. class avia_masonry
  307. {
  308. static $element = 0;
  309. protected $atts;
  310. protected $entries;
  311.  
  312. function __construct($atts = array())
  313. {
  314. self::$element += 1;
  315. $this->atts = shortcode_atts(array( 'ids' => false,
  316. 'action'=> false,
  317. 'link' => 'category',
  318. 'post_type'=> get_post_types(),
  319. 'items' => 24,
  320. 'size' => 'fixed',
  321. 'gap' => '1px',
  322. 'overlay_fx' => 'active',
  323. 'offset' => 0,
  324. 'container_links' => true,
  325. 'container_class' => "",
  326. 'paginate' => 'paginate',
  327. 'caption_elements' => 'title excerpt',
  328. 'caption_display' => 'always',
  329. 'sort' => 'no',
  330. 'auto_ratio' => 1.7, //equals a 16:9 ratio
  331. 'set_breadcrumb' => true //no shortcode option for this, modifies the breadcrumb nav, must be false on taxonomy overview
  332. ), $atts);
  333.  
  334. $this->atts = apply_filters('avf_masonry_settings', $this->atts, self::$element);
  335. }
  336.  
  337. //ajax function to load additional items
  338. static function load_more()
  339. {
  340. //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
  341. $_POST['items'] = $_POST['items'] + 1;
  342.  
  343. $masonry = new avia_masonry($_POST);
  344.  
  345. if(!empty($_POST['ids']))
  346. {
  347. $masonry->query_entries_by_id();
  348. }
  349. else
  350. {
  351. $masonry->extract_terms();
  352. $masonry->query_entries();
  353. }
  354.  
  355. $output = $masonry->html();
  356.  
  357. echo '{av-masonry-loaded}'.$output;
  358. exit();
  359. }
  360.  
  361.  
  362. function extract_terms()
  363. {
  364. if(isset($this->atts['link']))
  365. {
  366. $this->atts['link'] = explode(',', $this->atts['link'], 2 );
  367. $this->atts['taxonomy'] = $this->atts['link'][0];
  368.  
  369. if(isset($this->atts['link'][1]))
  370. {
  371. $this->atts['categories'] = $this->atts['link'][1];
  372. }
  373. else
  374. {
  375. $this->atts['categories'] = array();
  376. }
  377. }
  378. }
  379.  
  380. function sort_buttons()
  381. {
  382. $sort_terms = get_terms( $this->atts['taxonomy'] , array('hide_empty'=>true, 'orderby' => 'name',
  383. 'order' => 'ASC',) );
  384.  
  385. $current_page_terms = array();
  386. $term_count = array();
  387. $display_terms = is_array($this->atts['categories']) ? $this->atts['categories'] : array_filter(explode(',',$this->atts['categories']));
  388.  
  389. foreach ($this->loop as $entry)
  390. {
  391. if($current_item_terms = get_the_terms( $entry['ID'], $this->atts['taxonomy'] ))
  392. {
  393. if(!empty($current_item_terms))
  394. {
  395. foreach($current_item_terms as $current_item_term)
  396. {
  397. if(empty($display_terms) || in_array($current_item_term->term_id, $display_terms))
  398. {
  399. $current_page_terms[$current_item_term->term_id] = $current_item_term->term_id;
  400.  
  401. if(!isset($term_count[$current_item_term->term_id] ))
  402. {
  403. $term_count[$current_item_term->term_id] = 0;
  404. }
  405.  
  406. $term_count[$current_item_term->term_id] ++;
  407. }
  408. }
  409. }
  410. }
  411. }
  412.  
  413.  
  414. $hide = count($current_page_terms) <= 1 ? "hidden" : "";
  415. $output = "";
  416.  
  417. if(empty($hide))
  418. {
  419. $output = "<div class='av-masonry-sort main_color' data-masonry-id='".self::$element."' >";
  420.  
  421. $first_item_name = apply_filters('avf_masonry_sort_first_label', __('All','avia_framework' ), $this->atts);
  422. $output .= apply_filters('avf_masonry_sort_heading', "", $this->atts);
  423. $output .= "<div class='av-sort-by-term {$hide} '>";
  424. $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>';
  425.  
  426. foreach($sort_terms as $term)
  427. {
  428. $show_item = in_array($term->term_id, $current_page_terms) ? 'avia_show_sort' : 'avia_hide_sort';
  429. if(!isset($term_count[$term->term_id])) $term_count[$term->term_id] = 0;
  430. $term->slug = str_replace('%', '', $term->slug);
  431.  
  432. $output .= "<span class='text-sep {$term->slug}_sort_sep {$show_item}'>/</span>";
  433. $output .= '<a href="#" data-filter="'.$term->slug.'_sort" class="'.$term->slug.'_sort_button '.$show_item.'" ><span class="inner_sort_button">';
  434. $output .= "<span>".esc_html(trim($term->name))."</span>";
  435. $output .= "<small class='avia-term-count'> ".$term_count[$term->term_id]." </small></span>";
  436. $output .= "</a>";
  437. }
  438.  
  439. $output .= "</div></div>";
  440. }
  441.  
  442. return $output;
  443.  
  444.  
  445. }
  446.  
  447. //get the categories for each post and create a string that serves as classes so the javascript can sort by those classes
  448. function sort_array($the_id)
  449. {
  450. $sort_classes = array("all_sort");
  451. $item_terms = get_the_terms( $the_id, $this->atts['taxonomy']);
  452.  
  453. if(is_object($item_terms) || is_array($item_terms))
  454. {
  455. foreach ($item_terms as $term)
  456. {
  457. $term->slug = str_replace('%', '', $term->slug);
  458. $sort_classes[] = $term->slug.'_sort ';
  459. }
  460. }
  461.  
  462. return $sort_classes;
  463. }
  464.  
  465.  
  466.  
  467. function html()
  468. {
  469. if(empty($this->loop)) return;
  470.  
  471. $output = "";
  472. $items = "";
  473. $size = strpos($this->atts['size'], 'fixed') !== false ? 'fixed' : "flex";
  474. $auto = strpos($this->atts['size'], 'masonry') !== false ? true : false;
  475. $manually = strpos($this->atts['size'], 'manually') !== false ? true : false;
  476. $defaults = array('ID'=>'',
  477. 'thumb_ID'=>'',
  478. 'title' =>'',
  479. 'url' => '',
  480. 'class' => array(),
  481. 'date' => '',
  482. 'excerpt' => '',
  483. 'data' => '',
  484. 'attachment'=> array(),
  485. 'attachment_overlay' => array(),
  486. 'bg' => "",
  487. 'before_content'=>'', // if set replaces the whole bg part
  488. 'text_before'=>'',
  489. 'text_after'=>'',
  490. 'img_before'=>'');
  491.  
  492.  
  493. $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']}' >";
  494.  
  495. $output .= $this->atts['sort'] == "yes" ? $this->sort_buttons() : "";
  496.  
  497. $output .= "<div class='av-masonry-container isotope av-js-disabled ' >";
  498. $all_sorts = array();
  499. $sort_array = array();
  500. foreach($this->loop as $entry)
  501. {
  502. extract(array_merge($defaults, $entry));
  503. $img_html = "";
  504. $img_style = "";
  505. if($this->atts['sort'] == "yes")
  506. {
  507. $sort_array = $this->sort_array($entry['ID']);
  508. }
  509. $class_string = implode(' ', $class).' '.implode(' ', $sort_array);
  510. $all_sorts = array_merge($all_sorts, $sort_array);
  511.  
  512. if(!empty($attachment))
  513. {
  514. $alt = get_post_meta($thumb_ID, '_wp_attachment_image_alt', true);
  515. $alt = !empty($alt) ? esc_attr($alt) : '';
  516. $title = esc_attr(get_the_title($thumb_ID));
  517.  
  518. if(isset($attachment[0]))
  519. {
  520. $img_html = '<img src="'.$attachment[0].'" title="'.$title.'" alt="'.$alt.'" />';
  521. $img_style = 'style="background-image: url('.$attachment[0].');"';
  522. $class_string .= " av-masonry-item-with-image";
  523. }
  524.  
  525. if(isset($attachment_overlay[0]))
  526. {
  527. $over_html = '<img src="'.$attachment_overlay[0].'" title="'.$title.'" alt="'.$alt.'" />';
  528. $over_style = 'style="background-image: url('.$attachment_overlay[0].');"';
  529. $img_before = '<div class="av-masonry-image-container av-masonry-overlay" '.$over_style.'>'.$over_html.'</div>';
  530. }
  531.  
  532. $bg = '<div class="av-masonry-outerimage-container">'.$img_before.'<div class="av-masonry-image-container" '.$img_style.'>'.$img_html.'</div></div>';
  533.  
  534. }
  535. else
  536. {
  537. $class_string .= " av-masonry-item-no-image";
  538. }
  539.  
  540.  
  541. if($size == 'fixed')
  542. {
  543. if(!empty($attachment) || !empty($before_content))
  544. {
  545. if($auto)
  546. $class_string .= $this->ratio_check_by_image_size($attachment);
  547.  
  548. if($manually)
  549. $class_string .= $this->ratio_check_by_tag($entry['tags']);
  550. }
  551. }
  552.  
  553.  
  554. $linktitle = "";
  555.  
  556. if($post_type == 'attachment' && strpos($html_tags[0], 'a href=') !== false)
  557. {
  558. $linktitle = 'title="'.esc_attr($description).'"';
  559. }
  560. else if(strpos($html_tags[0], 'a href=') !== false)
  561. {
  562. $linktitle = 'title="'.esc_attr($the_title).'"';
  563. }
  564. $markup = ($post_type == 'attachment') ? avia_markup_helper(array('context' => 'image_url','echo'=>false)) : avia_markup_helper(array('context' => 'entry','echo'=>false));
  565.  
  566. $items .= "<{$html_tags[0]} class='{$class_string}' {$linktitle} {$markup}>";
  567. $items .= "<div class='av-inner-masonry-sizer'></div>"; //responsible for the size
  568. $items .= "<figure class='av-inner-masonry main_color'>";
  569. $items .= $bg;
  570.  
  571. //title and excerpt
  572. if($this->atts['caption_elements'] != 'none' || !empty($text_add))
  573. {
  574. $items .= "<figcaption class='av-inner-masonry-content site-background'><div class='av-inner-masonry-content-pos'><div class='avia-arrow'></div>".$text_before;
  575.  
  576. if(strpos($this->atts['caption_elements'], 'title') !== false){
  577. $markup = avia_markup_helper(array('context' => 'entry_title','echo'=>false));
  578. $items .= "<h3 class='av-masonry-entry-title entry-title' {$markup}>{$the_title}</h3>";
  579. }
  580.  
  581. if(strpos($this->atts['caption_elements'], 'excerpt') !== false && !empty($content)){
  582. $markup = avia_markup_helper(array('context' => 'entry_content','echo'=>false));
  583. $items .= "<div class='av-masonry-entry-content entry-content' {$markup}>{$content}</div>";
  584. }
  585. $items .= $text_after."</div></figcaption>";
  586. }
  587. $items .= "</figure>";
  588. $items .= "</{$html_tags[1]}><!--end av-masonry entry-->";
  589. }
  590.  
  591. //if its an ajax call return the items only without container
  592. if(isset($this->atts['action']) && $this->atts['action'] == 'avia_ajax_masonry_more')
  593. {
  594. return $items;
  595. }
  596.  
  597. // 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.
  598. // 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
  599.  
  600. $all_sort_string = implode(' ', array_unique($all_sorts));
  601. $items = "<div class='av-masonry-entry isotope-item av-masonry-item-no-image {$all_sort_string}'></div>".$items;
  602.  
  603. $output .= $items;
  604. $output .= "</div>";
  605.  
  606.  
  607. //append pagination
  608. if($this->atts['paginate'] == "pagination" && $avia_pagination = avia_pagination($this->entries->max_num_pages, 'nav'))
  609. {
  610. $output .= "<div class='av-masonry-pagination av-masonry-pagination-{$this->atts['paginate']}'>{$avia_pagination}</div>";
  611. }
  612. else if($this->atts['paginate'] == "load_more" && $this->entries->max_num_pages > count($this->entries))
  613. {
  614. $output .= $this->load_more_button();
  615. }
  616.  
  617. $output .= "</div>";
  618.  
  619. return $output;
  620. }
  621.  
  622.  
  623. function load_more_button()
  624. {
  625. $data_string = AviaHelper::create_data_string($this->atts);
  626.  
  627. $output = "";
  628. $output .= "<a class='av-masonry-pagination av-masonry-load-more' href='#load-more' {$data_string}>".__('Load more','avia_framework')."</a>";
  629.  
  630. return $output;
  631. }
  632.  
  633. function ratio_check_by_image_size($attachment)
  634. {
  635. $img_size = ' av-grid-img';
  636.  
  637. if(!empty($attachment[1]) && !empty($attachment[2]))
  638. {
  639. if($attachment[1] > $attachment[2]) //landscape
  640. {
  641. //only consider it landscape if its 1.7 times wider than high
  642. if($attachment[1] / $attachment[2] > $this->atts['auto_ratio']) $img_size = ' av-landscape-img';
  643. }
  644. else //same check with portrait
  645. {
  646. if($attachment[2] / $attachment[1] > $this->atts['auto_ratio']) $img_size = ' av-portrait-img';
  647. }
  648. }
  649.  
  650. return $img_size;
  651. }
  652.  
  653. function ratio_check_by_tag($tags)
  654. {
  655. $img_size = '';
  656.  
  657. if(is_array($tags))
  658. {
  659. if(in_array('portrait', $tags)) { $img_size .= ' av-portrait-img'; }
  660. if(in_array('landscape', $tags)){ $img_size .= ' av-landscape-img'; }
  661. }
  662.  
  663. if(empty($img_size)) $img_size = ' av-grid-img';
  664.  
  665. return $img_size;
  666.  
  667. }
  668.  
  669.  
  670. function prepare_loop_from_entries()
  671. {
  672. $this->loop = array();
  673. if(empty($this->entries) || empty($this->entries->posts)) return;
  674. $tagTax = "post_tag";
  675. $date_format = get_option('date_format');
  676.  
  677.  
  678. foreach($this->entries->posts as $key => $entry)
  679. {
  680. $overlay_img = $custom_url = false;
  681. $img_size = 'masonry';
  682. $author = get_the_author_meta('display_name', $entry->post_author);
  683.  
  684. $this->loop[$key]['text_before'] = "";
  685. $this->loop[$key]['text_after'] = "";
  686. $this->loop[$key]['ID'] = $id = $entry->ID;
  687. $this->loop[$key]['post_type'] = $entry->post_type;
  688. $this->loop[$key]['thumb_ID'] = get_post_thumbnail_id($id);
  689. $this->loop[$key]['the_title'] = get_the_title($id);
  690. $this->loop[$key]['url'] = get_permalink($id);
  691. $this->loop[$key]['date'] = "<span class='av-masonry-date meta-color updated'>".get_the_time($date_format, $id)."</span>";
  692. $this->loop[$key]['author'] = "<span class='av-masonry-author meta-color vcard author'><span class='fn'>". __('by','avia_framework') .' '. $author."</span></span>";
  693. $this->loop[$key]['class'] = get_post_class("av-masonry-entry isotope-item", $id);
  694. $this->loop[$key]['content'] = $entry->post_excerpt;
  695. $this->loop[$key]['description'] = !empty($entry->post_content) ? $entry->post_content : $entry->post_excerpt;
  696.  
  697. if(empty($this->loop[$key]['content']))
  698. {
  699. $this->loop[$key]['content'] = avia_backend_truncate($entry->post_content, apply_filters( 'avf_masonry_excerpt_length' , 60) , apply_filters( 'avf_masonry_excerpt_delimiter' , " "), "…", true, '');
  700. }
  701.  
  702. //post type specific
  703. switch($entry->post_type)
  704. {
  705. case 'post':
  706.  
  707. $post_format = get_post_format($id) ? get_post_format($id) : 'standard';
  708. $this->loop[$key] = apply_filters( 'post-format-'.$post_format, $this->loop[$key] );
  709. $this->loop[$key]['text_after'] .= $this->loop[$key]['date'];
  710. $this->loop[$key]['text_after'] .= '<span class="av-masonry-text-sep text-sep-author">/</span>';
  711. $this->loop[$key]['text_after'] .= $this->loop[$key]['author'];
  712.  
  713. switch($post_format)
  714. {
  715. case 'quote' :
  716. case 'link' :
  717. case 'image' :
  718. case 'gallery' :
  719. if(!$this->loop[$key]['thumb_ID'])
  720. {
  721. $this->loop[$key]['text_before'] = av_icon_display($post_format);
  722. }
  723. break;
  724.  
  725. case 'audio' :
  726. case 'video' :
  727. if(!$this->loop[$key]['thumb_ID'])
  728. {
  729. $this->loop[$key]['text_before'] = av_icon_display($post_format);
  730. }
  731. else
  732. {
  733. $this->loop[$key]['text_before'] = av_icon_display($post_format, 'av-masonry-media');
  734. }
  735. break;
  736. }
  737.  
  738.  
  739.  
  740. break;
  741.  
  742. case 'portfolio':
  743.  
  744. //set portfolio breadcrumb navigation
  745. if($this->atts['set_breadcrumb'] && is_page()) $_SESSION["avia_{$entry->post_type}"] = get_the_ID();
  746.  
  747. //check if the user has set up a custom link
  748. if(!post_password_required($id)){
  749. $custom_link = get_post_meta( $id ,'_portfolio_custom_link', true) != "" ? get_post_meta( $id ,'_portfolio_custom_link_url', true) : false;
  750. if($custom_link) $this->loop[$key]['url'] = $custom_link;
  751. }
  752. break;
  753.  
  754.  
  755. case 'attachment':
  756.  
  757. $custom_url = get_post_meta( $id, 'av-custom-link', true );
  758. $this->loop[$key]['thumb_ID'] = $id;
  759. $this->loop[$key]['content'] = $entry->post_excerpt;
  760.  
  761. if($custom_url)
  762. {
  763. $this->loop[$key]['url'] = $custom_url;
  764. }
  765. else
  766. {
  767. $this->loop[$key]['url'] = wp_get_attachment_image_src($id, apply_filters('avf_avia_builder_masonry_lightbox_img_size','large'));
  768. $this->loop[$key]['url'] = reset($this->loop[$key]['url']);
  769. }
  770.  
  771.  
  772. break;
  773.  
  774. case 'product':
  775. //check if woocommerce is enabled in the first place so we can use woocommerce functions
  776. if(function_exists('avia_woocommerce_enabled') && avia_woocommerce_enabled())
  777. {
  778. $tagTax = "product_tag";
  779. $product = get_product( $id );
  780. $overlay_img = avia_woocommerce_gallery_first_thumbnail($id, $img_size, true);
  781.  
  782. $this->loop[$key]['text_after'] .= '<span class="av-masonry-price price">'.$product->get_price_html()."</span>";
  783. if($product->is_on_sale( )) $this->loop[$key]['text_after'] .= '<span class="onsale">'.__( 'Sale!', 'avia_framework' ).'</span>';
  784. }
  785. break;
  786. }
  787.  
  788.  
  789. //check if post is password protected
  790. if(post_password_required($id))
  791. {
  792. $this->loop[$key]['content'] = "";
  793. $this->loop[$key]['class'][] = "entry-protected";
  794. $this->loop[$key]['thumb_ID'] = "";
  795. $this->loop[$key]['text_before'] = av_icon_display('closed');
  796. $this->loop[$key]['text_after'] = $this->loop[$key]['date'];
  797. }
  798.  
  799.  
  800.  
  801. //set the html tags. depending on the link settings use either an a tag or a div tag
  802. if(!empty($this->atts['container_links']) || !empty($custom_url))
  803. {
  804. $this->loop[$key]['html_tags'] = array('a href="'.$this->loop[$key]['url'].'"','a'); //opening and closing tag for the masonry container
  805. }
  806. else
  807. {
  808. $this->loop[$key]['html_tags'] = array('div','div');
  809. }
  810.  
  811.  
  812. //get post tags
  813. $this->loop[$key]['tags'] = wp_get_post_terms($id, $tagTax, array( 'fields' => 'slugs' ));
  814.  
  815. //check if the image got landscape as well as portrait class applied. in that case use a bigger image size
  816. if(strlen($this->ratio_check_by_tag($this->loop[$key]['tags'])) > 20) $img_size = 'extra_large';
  817.  
  818. //get attachment data
  819. $this->loop[$key]['attachment'] = !empty($this->loop[$key]['thumb_ID']) ? wp_get_attachment_image_src($this->loop[$key]['thumb_ID'], $img_size) : "";
  820.  
  821. //get overlay attachment in case the overlay is set
  822. $this->loop[$key]['attachment_overlay'] = !empty($overlay_img) ? wp_get_attachment_image_src($overlay_img, $img_size) : "";
  823.  
  824. //apply filter for other post types, in case we want to use them and display additional/different information
  825. $this->loop[$key] = apply_filters('avf_masonry_loop_prepare', $this->loop[$key], $this->entries);
  826. }
  827. }
  828.  
  829.  
  830. //fetch new entries
  831. public function query_entries($params = array())
  832. {
  833. global $avia_config;
  834.  
  835. if(empty($params)) $params = $this->atts;
  836.  
  837. if(empty($params['custom_query']))
  838. {
  839. $query = array();
  840.  
  841. if(!empty($params['categories']))
  842. {
  843. //get the portfolio categories
  844. $terms = explode(',', $params['categories']);
  845. }
  846.  
  847. $page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );
  848. if(!$page) $page = 1;
  849.  
  850. //if we find no terms for the taxonomy fetch all taxonomy terms
  851. if(empty($terms[0]) || is_null($terms[0]) || $terms[0] === "null")
  852. {
  853. $terms = array();
  854. $allTax = get_terms( $params['taxonomy']);
  855. foreach($allTax as $tax)
  856. {
  857. $terms[] = $tax->term_id;
  858. }
  859. }
  860.  
  861.  
  862. if(empty($params['post_type'])) $params['post_type'] = get_post_types();
  863. if(is_string($params['post_type'])) $params['post_type'] = explode(',', $params['post_type']);
  864.  
  865. $query = array( 'orderby' => 'date',
  866. 'order' => 'DESC',
  867. 'paged' => $page,
  868. 'post_type' => $params['post_type'],
  869. 'offset' => $params['offset'],
  870. 'posts_per_page' => $params['items'],
  871. 'tax_query' => array( array( 'taxonomy' => $params['taxonomy'],
  872. 'field' => 'id',
  873. 'terms' => $terms,
  874. 'operator' => 'IN')));
  875.  
  876.  
  877.  
  878.  
  879. }
  880. else
  881. {
  882. $query = $params['custom_query'];
  883. }
  884.  
  885.  
  886. $query = apply_filters('avia_masonry_entries_query', $query, $params);
  887.  
  888. $this->entries = new WP_Query( $query );
  889. $this->prepare_loop_from_entries();
  890. }
  891.  
  892.  
  893. public function query_entries_by_id($params = array())
  894. {
  895. global $avia_config;
  896.  
  897. if(empty($params)) $params = $this->atts;
  898.  
  899. $ids = is_array($this->atts['ids']) ? $this->atts['ids'] : array_filter(explode(',',$this->atts['ids']));
  900.  
  901. $page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );
  902. if(!$page) $page = 1;
  903.  
  904. $query = array(
  905. 'post__in' => $ids,
  906. 'post_status' => 'inherit',
  907. 'post_type' => 'attachment',
  908. 'post_mime_type' => 'image',
  909. 'paged' => $page,
  910. 'order' => 'ASC',
  911. 'offset' => $params['offset'],
  912. 'posts_per_page' => $params['items'],
  913. 'orderby' => 'post__in'
  914. );
  915.  
  916.  
  917. $query = apply_filters('avia_masonry_entries_query', $query, $params);
  918.  
  919. $this->entries = new WP_Query( $query );
  920. $this->prepare_loop_from_entries();
  921.  
  922.  
  923. }
  924. }
  925. }
Advertisement
Add Comment
Please, Sign In to add comment