Advertisement
Guest User

Untitled

a guest
Jul 1st, 2024
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 106.47 KB | None | 0 0
  1. <?php
  2. /**
  3. * WooCommerce Integration
  4. * =======================
  5. *
  6. * @since < 4.0
  7. * @since 4.5.6 modifications for sorting integrations with WC 3.5.7 (backwards comp. with config-356.php)
  8. * @since 5.3 removed global $woocommerce - replaced by WC()
  9. * wrapped functions in function_exists()
  10. *
  11. *
  12. */
  13. if( ! defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
  14.  
  15.  
  16. if( ! function_exists( 'avia_woocommerce_enabled' ) )
  17. {
  18. /**
  19. * @since ????
  20. * @since 5.3 modified to check for WC() also
  21. * @return boolean|string
  22. */
  23. function avia_woocommerce_enabled()
  24. {
  25. if( ! class_exists( 'WooCommerce', false ) )
  26. {
  27. return false;
  28. }
  29.  
  30. // exists since WC 2.1
  31. if( function_exists( 'WC' ) && function_exists( 'wc_get_template_part' ) )
  32. {
  33. return true;
  34. }
  35.  
  36. return 'deprecated';
  37. }
  38. }
  39.  
  40. if( ! function_exists( 'av_add_deprecated_notice' ) )
  41. {
  42. function av_add_deprecated_notice()
  43. {
  44. echo '<div class="notice notice-error">';
  45. echo '<p>' . __( 'Attention! Please update WooCommerce to the latest version to properly display your products', 'avia_framework' ) . '</p>';
  46. echo '</div>';
  47. }
  48. }
  49.  
  50. /**
  51. * check if the plugin is enabled, otherwise stop the script
  52. */
  53. if( avia_woocommerce_enabled() !== true )
  54. {
  55. if( avia_woocommerce_enabled() == 'deprecated' )
  56. {
  57. add_action( 'admin_notices', 'av_add_deprecated_notice' );
  58. }
  59.  
  60. return false;
  61. }
  62.  
  63. if( ! function_exists( 'avia_woocommerce_version_check' ) )
  64. {
  65. /**
  66. * Checks if WooCommerce version is >= $version
  67. *
  68. * @since < 4.0
  69. * @param string $version
  70. * @return boolean
  71. */
  72. function avia_woocommerce_version_check( $version )
  73. {
  74. if( version_compare( WC()->version, $version, '>=' ) )
  75. {
  76. return true;
  77. }
  78.  
  79. return false;
  80. }
  81. }
  82.  
  83. add_theme_support( 'woocommerce' );
  84.  
  85. global $avia_config;
  86.  
  87. /**
  88. * Product thumbnails
  89. *
  90. * @since WC 3.3.0 and 3.5.0 WC_Regenerate_Images regenerates the images and changes the sizes.
  91. * This leads to effect that customizer value for 'shop_catalog' overrides our setting in shop loop for product slider
  92. *
  93. */
  94. $avia_config['imgSize']['shop_thumbnail'] = array( 'width' => 120, 'height' => 120 );
  95. $avia_config['imgSize']['shop_catalog'] = array( 'width' => 450, 'height' => 450 );
  96. $avia_config['imgSize']['shop_single'] = array( 'width' => 450, 'height' => 999, 'crop' => false );
  97.  
  98. avia_backend_add_thumbnail_size( $avia_config );
  99.  
  100. include( 'admin-options.php' );
  101. include( 'admin-import.php' );
  102. include( 'woocommerce-mod-css-dynamic.php' );
  103.  
  104.  
  105. //register my own styles, remove wootheme stylesheet
  106. if( ! is_admin() )
  107. {
  108. add_action( 'wp_enqueue_scripts', 'avia_woocommerce_register_assets', 5 );
  109. }
  110.  
  111. if( ! function_exists( 'avia_woocommerce_add_body_classes' ) )
  112. {
  113. /**
  114. * Add info about WC version to body
  115. *
  116. * @since 4.7.6.4
  117. * @param array $classes
  118. * @param array $class
  119. * @return array
  120. */
  121. function avia_woocommerce_add_body_classes( $classes, $class )
  122. {
  123. if( avia_woocommerce_version_check( '3.0' ) )
  124. {
  125. $classes[] = 'avia-woocommerce-30';
  126. }
  127.  
  128. /**
  129. * Adds the product class name to the body tag when ALB is active, required by WC scripts such as add-to-cart-variation.js
  130. *
  131. * https://kriesi.at/support/topic/sku-on-product-page-disappeared-with-theme-update/
  132. * @since 4.9.1
  133. */
  134. if( is_product() )
  135. {
  136. $id = get_the_ID();
  137. if( false !== $id && 'active' == Avia_Builder()->get_alb_builder_status( $id ) )
  138. {
  139. $classes[] = 'product';
  140. }
  141. }
  142.  
  143. return $classes;
  144. }
  145. }
  146.  
  147. add_filter( 'body_class', 'avia_woocommerce_add_body_classes', 10, 2 );
  148.  
  149.  
  150. if( ! function_exists( 'avia_woocommerce_ignore_duplicate_post_types' ) )
  151. {
  152. /**
  153. * WooCommerce has its own duplicate product logic - remove Enfold link
  154. *
  155. * @since 5.6.9
  156. * @param array $post_types
  157. * @return array
  158. */
  159. function avia_woocommerce_ignore_duplicate_post_types( $post_types = [] )
  160. {
  161. if( ! is_array( $post_types ) )
  162. {
  163. $post_types = [];
  164. }
  165.  
  166. $post_types[] = 'product';
  167.  
  168. return $post_types;
  169. }
  170.  
  171. add_filter( 'avf_ignore_duplicate_post_types', 'avia_woocommerce_ignore_duplicate_post_types', 10, 1 );
  172. }
  173.  
  174.  
  175. if( ! function_exists( 'avia_get_woocommerce_term_meta' ) )
  176. {
  177. /**
  178. * Wrapper function as WC deprecated function get_woocommerce_term_meta with 3.6
  179. *
  180. * @since 4.5.6.1
  181. * @param int $term_id
  182. * @param string $key
  183. * @param bool $single
  184. * @return mixed
  185. */
  186. function avia_get_woocommerce_term_meta( $term_id, $key, $single = true )
  187. {
  188. if( ! avia_woocommerce_version_check( '3.6' ) )
  189. {
  190. return get_woocommerce_term_meta( $term_id, $key, $single );
  191. }
  192.  
  193. return function_exists( 'get_term_meta' ) ? get_term_meta( $term_id, $key, $single ) : get_metadata( 'woocommerce_term', $term_id, $key, $single );
  194. }
  195. }
  196.  
  197. if( ! function_exists( 'avia_woocommerce_register_assets' ) )
  198. {
  199. /**
  200. * @since ????
  201. */
  202. function avia_woocommerce_register_assets()
  203. {
  204. $vn = avia_get_theme_version();
  205. $min_js = avia_minify_extension( 'js' );
  206. $min_css = avia_minify_extension( 'css' );
  207.  
  208. wp_enqueue_style( 'avia-woocommerce-css', AVIA_BASE_URL . "config-woocommerce/woocommerce-mod{$min_css}.css", array( 'avia-scs' ), $vn );
  209.  
  210. if( version_compare( WC()->version, '2.7.0', '<' ) )
  211. {
  212. wp_enqueue_script( 'avia-woocommerce-js', AVIA_BASE_URL . 'config-woocommerce/woocommerce-mod-v26.js', array( 'jquery' ), $vn, true );
  213. }
  214. else
  215. {
  216. wp_enqueue_script( 'avia-woocommerce-js', AVIA_BASE_URL . "config-woocommerce/woocommerce-mod{$min_js}.js", array( 'jquery' ), $vn, true );
  217. }
  218.  
  219. if( avia_woocommerce_version_check( '7.8.0' ) )
  220. {
  221. /**
  222. * WC moved enqueue from frontend script to widget -> breaks our ajax cart
  223. *
  224. * @since 5.6.3
  225. */
  226. if ( ! apply_filters( 'woocommerce_widget_cart_is_hidden', is_cart() || is_checkout() ) )
  227. {
  228. wp_enqueue_script( 'wc-cart-fragments' );
  229. }
  230. }
  231. }
  232. }
  233.  
  234.  
  235. if( version_compare( WC()->version, '2.1', '<' ) )
  236. {
  237. define( 'WOOCOMMERCE_USE_CSS', false );
  238. }
  239. else
  240. {
  241. if( ! function_exists( 'avia_woocommerce_enqueue_styles' ) )
  242. {
  243. /**
  244. * @since ????
  245. * @param array $styles
  246. * @return array
  247. */
  248. function avia_woocommerce_enqueue_styles( $styles )
  249. {
  250. $styles = array();
  251.  
  252. return $styles;
  253. }
  254. }
  255.  
  256. add_filter( 'woocommerce_enqueue_styles', 'avia_woocommerce_enqueue_styles' );
  257. }
  258.  
  259. if( class_exists( 'WC_Bookings', false ) )
  260. {
  261. require_once( 'config-woocommerce-bookings/config.php' ); //compatibility with woocommerce plugin
  262. }
  263.  
  264.  
  265. ######################################################################
  266. # config
  267. ######################################################################
  268.  
  269. //add avia_framework config defaults
  270.  
  271. $avia_config['shop_overview_column'] = get_option( 'avia_woocommerce_column_count' ); // columns for the overview page
  272. $avia_config['shop_overview_products'] = get_option( 'avia_woocommerce_product_count' ); // products for the overview page
  273.  
  274. $avia_config['shop_single_column'] = 4; // columns for related products and upsells
  275. $avia_config['shop_single_column_items'] = 4; // number of items for related products and upsells
  276. $avia_config['shop_overview_excerpt'] = false; // display excerpt
  277.  
  278. if( ! $avia_config['shop_overview_column'] )
  279. {
  280. $avia_config['shop_overview_column'] = 3;
  281. }
  282.  
  283. /**
  284. * Setup product gallery support depending on user settings and available WooCommerce galleries
  285. */
  286. if( ! function_exists( 'avia_woocommerce_product_gallery_support_setup' ) )
  287. {
  288. /**
  289. *
  290. * @since ????
  291. */
  292. function avia_woocommerce_product_gallery_support_setup()
  293. {
  294. if( ! avia_woocommerce_version_check( '3.0.0' ) )
  295. {
  296. return;
  297. }
  298.  
  299. $options = avia_get_option();
  300.  
  301. // Fallback, if options have not been saved
  302. if( ! array_key_exists( 'product_gallery', $options ) || ( 'wc_30_gallery' != $options['product_gallery'] ) )
  303. {
  304. $options['product_gallery'] = '';
  305. }
  306.  
  307. if( 'wc_30_gallery' == $options['product_gallery'] )
  308. {
  309. add_theme_support( 'wc-product-gallery-zoom' );
  310. // uncomment the following line if you want default WooCommerce lightbox - else Enfold lightbox will be used
  311. // add_theme_support( 'wc-product-gallery-lightbox' );
  312. add_theme_support( 'wc-product-gallery-slider' );
  313. add_theme_support( 'avia-wc-30-product-gallery-feature' );
  314. }
  315.  
  316. return;
  317. }
  318. }
  319.  
  320. if( did_action( 'woocommerce_init' ) )
  321. {
  322. avia_woocommerce_product_gallery_support_setup();
  323. }
  324. else
  325. {
  326. add_action( 'woocommerce_init', 'avia_woocommerce_product_gallery_support_setup', 10 );
  327. }
  328.  
  329. ######################################################################
  330. # Allow to add WC structured data on template builder page
  331. ######################################################################
  332. #
  333. if( ! function_exists( 'avia_activate_wc_structured_data' ) )
  334. {
  335. /**
  336. * @since ????
  337. * @param string $name
  338. */
  339. function avia_activate_wc_structured_data( $name )
  340. {
  341. global $product;
  342.  
  343. if( ! avia_woocommerce_version_check( '3.0.0' ) )
  344. {
  345. return;
  346. }
  347.  
  348. // Currently only on single product page with template builder required
  349. if( ! is_product() || ! $product instanceof WC_Product )
  350. {
  351. return;
  352. }
  353.  
  354. /**
  355. * Check necessary data in \woocommerce\includes\class-wc-structured-data.php
  356. */
  357. if( ! did_action( 'woocommerce_before_main_content' ) )
  358. {
  359. WC()->structured_data->generate_website_data();
  360. }
  361.  
  362. if( ! ( did_action( 'woocommerce_shop_loop' ) || did_action( 'woocommerce_single_product_summary' ) ) )
  363. {
  364. WC()->structured_data->generate_product_data();
  365. }
  366.  
  367. // not needed on single product page
  368. if( ! did_action( 'woocommerce_breadcrumb' ) )
  369. {
  370. // WC()->structured_data->generate_breadcrumblist_data();
  371. }
  372. if( ! did_action( 'woocommerce_review_meta' ) )
  373. {
  374. // WC()->structured_data->generate_review_data();
  375. }
  376. if( ! did_action( 'woocommerce_email_order_details' ) )
  377. {
  378. // WC()->structured_data->generate_order_data();
  379. }
  380. }
  381. }
  382.  
  383. add_action( 'get_footer', 'avia_activate_wc_structured_data', 10, 1 );
  384.  
  385.  
  386.  
  387. if( ! function_exists( 'avia_woocommerce_lazy_load' ) )
  388. {
  389. /**
  390. * Remove default 'loading' attribute
  391. * We hook before Enfold to remove lazy attribute
  392. *
  393. * @since 4.8.6.3
  394. * @param array $attr
  395. * @param WP_Post $attachment
  396. * @param string|array $size
  397. * @return array
  398. */
  399. function avia_woocommerce_lazy_load( $attr, $attachment, $size )
  400. {
  401. global $product;
  402.  
  403. // Currently only on single product page
  404. if( ! is_product() || ! $product instanceof WC_Product )
  405. {
  406. return $attr;
  407. }
  408.  
  409. /**
  410. * Currently only for main image on product page because above the fold
  411. *
  412. * https://kriesi.at/support/topic/4-8-2-onwards-woocommerce-main-shop-image-is-being-lazy-loaded/
  413. */
  414. if( is_string( $size ) && 'shop_single' == $size )
  415. {
  416. unset( $attr['loading'] );
  417. }
  418.  
  419. return $attr;
  420. }
  421. }
  422.  
  423. add_filter( 'wp_get_attachment_image_attributes', 'avia_woocommerce_lazy_load', 90, 3 );
  424.  
  425.  
  426. if( ! function_exists( 'avia_woocommerce_page_content_post_types' ) )
  427. {
  428. /**
  429. * Add post type 'product' to display CPT in selectbox for ALB element custom layout
  430. *
  431. * @since 6.0
  432. * @param array $post_types
  433. * @return array
  434. */
  435. function avia_woocommerce_page_content_post_types( array $post_types )
  436. {
  437. if( ! avia_woocommerce_enabled() )
  438. {
  439. return $post_types;
  440. }
  441.  
  442. $post_types[] = 'product';
  443.  
  444. return $post_types;
  445. }
  446.  
  447. add_filter( 'avf_page_content_post_types', 'avia_woocommerce_page_content_post_types', 10, 1 );
  448. }
  449.  
  450.  
  451. ######################################################################
  452. # Create the correct template html structure
  453. ######################################################################
  454.  
  455. //remove woo defaults
  456. remove_action( 'woocommerce_sidebar', 'woocommerce_get_sidebar', 10 );
  457. remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
  458. remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );
  459. remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
  460. remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0 );
  461. remove_action( 'woocommerce_pagination', 'woocommerce_catalog_ordering', 20 );
  462. remove_action( 'woocommerce_pagination', 'woocommerce_pagination', 10 );
  463. remove_action( 'woocommerce_before_single_product', array( WC(), 'show_messages' ), 10 );
  464.  
  465.  
  466. //add theme actions && filter
  467. add_action( 'woocommerce_after_shop_loop_item_title', 'avia_woocommerce_overview_excerpt', 10 );
  468. add_filter( 'loop_shop_columns', 'avia_woocommerce_loop_columns' );
  469. add_filter( 'loop_shop_per_page', 'avia_woocommerce_product_count' );
  470.  
  471. //single page adds
  472. add_action( 'avia_add_to_cart', 'woocommerce_template_single_add_to_cart', 30, 2 );
  473.  
  474.  
  475. /*update woocommerce v2*/
  476. remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 ); /*remove result count above products*/
  477. remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 ); /*remove woocommerce ordering dropdown*/
  478. remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_rating', 5 ); //remove rating
  479. remove_action( 'woocommerce_after_shop_loop', 'woocommerce_pagination', 10 ); //remove woo pagination
  480.  
  481.  
  482.  
  483. ######################################################################
  484. # FUNCTIONS
  485. ######################################################################
  486.  
  487.  
  488. if( ! function_exists( 'avia_set_shop_page_id' ) )
  489. {
  490. /**
  491. * set the shop page id, otherwise avia_get_the_ID() can return a wrong id on the shop page
  492. *
  493. * @since ????
  494. * @param int $id
  495. * @return int
  496. */
  497. function avia_set_shop_page_id( $id )
  498. {
  499. if( is_shop() )
  500. {
  501. $id = function_exists( 'wc_get_page_id' ) ? wc_get_page_id( 'shop' ) : woocommerce_get_page_id( 'shop' );
  502. }
  503.  
  504. return $id;
  505. }
  506. }
  507.  
  508. add_filter( 'avf_avia_get_the_ID', 'avia_set_shop_page_id', 10, 1 );
  509.  
  510.  
  511. if( ! function_exists( 'avia_wc_force_posts_layout_settings' ) )
  512. {
  513. /**
  514. * Force to use "Layout" metabox settings for default shop page
  515. *
  516. * @since 5.6
  517. * @param boolean $force_posts_layout_settings
  518. * @param int $post_id
  519. * @return boolean
  520. */
  521. function avia_wc_force_posts_layout_settings( $force_posts_layout_settings, $post_id )
  522. {
  523. if( is_shop() )
  524. {
  525. $force_posts_layout_settings = true;
  526. }
  527.  
  528. return $force_posts_layout_settings;
  529. }
  530. }
  531.  
  532. add_filter( 'avf_force_posts_layout_settings', 'avia_wc_force_posts_layout_settings', 10, 2 );
  533.  
  534.  
  535.  
  536. if( ! function_exists( 'avia_woocommerce_thumbnail' ) )
  537. {
  538. /**
  539. * removes the default post image from shop overview pages and replaces it with this image
  540. *
  541. * @since ????
  542. */
  543. function avia_woocommerce_thumbnail()
  544. {
  545. global $product;
  546.  
  547. if( function_exists( 'wc_get_rating_html' ) )
  548. {
  549. $rating = wc_get_rating_html( $product->get_average_rating() );
  550. }
  551. else
  552. {
  553. $rating = $product->get_rating_html(); //get rating
  554. }
  555.  
  556. $id = get_the_ID();
  557.  
  558. /**
  559. * Filter image size in ALB elements productslider and product grid
  560. *
  561. * @used_by avia_product_slider::html() 10
  562. * @since 4.8
  563. * @param string
  564. * @return string
  565. */
  566. $size = apply_filters( 'avf_wc_before_shop_loop_item_title_img_size', 'shop_catalog' );
  567.  
  568. $image = get_the_post_thumbnail( $id , $size );
  569.  
  570. // try to get fallback image
  571. if( empty( $image ) )
  572. {
  573. $image_url = wc_placeholder_img_src( $size );
  574. if( ! empty( $image_url ) )
  575. {
  576. $image = '<img src="' . $image_url . '" height="450" width="450" loading="lazy" alt="' . __( 'Placeholder image', 'avia_framework' ) . '">';
  577. }
  578. }
  579.  
  580. $html = '<div class="thumbnail_container">';
  581. $html .= avia_woocommerce_gallery_first_thumbnail( $id , $size );
  582. $html .= $image;
  583.  
  584. if( ! empty( $rating ) )
  585. {
  586. $html .= "<span class='rating_container'>{$rating}</span>";
  587. }
  588. if( $product->get_type() == 'simple' )
  589. {
  590. $html .= '<span class="cart-loading"></span>';
  591. }
  592.  
  593. $html .= '</div>';
  594.  
  595. echo $html;
  596. }
  597. }
  598.  
  599. add_action( 'woocommerce_before_shop_loop_item_title', 'avia_woocommerce_thumbnail', 10 );
  600. remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
  601.  
  602.  
  603. if( ! function_exists( 'avia_woocommerce_gallery_first_thumbnail' ) )
  604. {
  605. /**
  606. *
  607. * @since ????
  608. * @param int $id
  609. * @param string $size
  610. * @param boolean $id_only
  611. * @return string|int
  612. */
  613. function avia_woocommerce_gallery_first_thumbnail( $id, $size, $id_only = false )
  614. {
  615. $image = '';
  616. $active_hover = get_post_meta( $id, '_product_hover', true );
  617.  
  618. if( ! empty( $active_hover ) )
  619. {
  620. $product_gallery = get_post_meta( $id, '_product_image_gallery', true );
  621.  
  622. if( ! empty( $product_gallery ) )
  623. {
  624. $gallery = explode( ',', $product_gallery );
  625. $image_id = $gallery[0];
  626.  
  627. //return id only
  628. if( ! empty( $id_only ) )
  629. {
  630. return $image_id;
  631. }
  632.  
  633. $image = wp_get_attachment_image( $image_id, $size, false, array( 'class' => "attachment-{$size} avia-product-hover" ) );
  634. }
  635.  
  636. return $image;
  637. }
  638. }
  639. }
  640.  
  641. if( ! function_exists( 'avia_add_cart_button' ) )
  642. {
  643. /**
  644. * add ajax cart / options buttons to the product
  645. *
  646. * @since ????
  647. */
  648. function avia_add_cart_button()
  649. {
  650. global $product, $avia_config;
  651.  
  652. if( $product->get_type() == 'bundle' )
  653. {
  654. $product = new WC_Product_Bundle( $product->get_id() );
  655. }
  656.  
  657. $extraClass = '';
  658.  
  659. ob_start();
  660. woocommerce_template_loop_add_to_cart();
  661. $output = ob_get_clean();
  662.  
  663. if( ! empty( $output ) )
  664. {
  665. $pos = strpos( $output, '>' );
  666.  
  667. if( $pos !== false )
  668. {
  669. $output = substr_replace( $output, '><span ' . av_icon_string( 'cart' ) . '></span> ', $pos , strlen( 1 ) );
  670. }
  671. }
  672.  
  673.  
  674. if( $product->get_type() == 'variable' && empty( $output ) )
  675. {
  676. $output = '<a class="add_to_cart_button button product_type_variable" href="' . get_permalink( $product->get_id() ) . '"><span ' . av_icon_string( 'details' ) . '></span> ' . __( 'Select options', 'avia_framework' ) . '</a>';
  677. }
  678.  
  679. if( in_array( $product->get_type(), array( 'subscription', 'simple', 'bundle' ) ) )
  680. {
  681. $output .= '<a class="button show_details_button" href="' . get_permalink( $product->get_id() ) . '"><span ' . av_icon_string( 'details' ) . '></span> ' . __( 'Show Details', 'avia_framework' ) . '</a>';
  682. }
  683. else
  684. {
  685. $extraClass = 'single_button';
  686. }
  687.  
  688. if( empty( $extraClass ) )
  689. {
  690. $output .= ' <span class="button-mini-delimiter"></span>';
  691. }
  692.  
  693. if( $output && ! post_password_required() && '' == avia_get_option( 'product_layout', '' ) )
  694. {
  695. echo "<div class='avia_cart_buttons {$extraClass}'>$output</div>";
  696. }
  697. }
  698. }
  699.  
  700. add_action( 'woocommerce_after_shop_loop_item', 'avia_add_cart_button', 16 );
  701.  
  702.  
  703. if( ! function_exists( 'avia_shop_overview_extra_div' ) )
  704. {
  705. /**
  706. * Wrap products on overview pages into an extra div for improved styling options.
  707. * Adds 'product_on_sale' class if prodct is on sale
  708. *
  709. * @since ????
  710. */
  711. function avia_shop_overview_extra_div()
  712. {
  713. global $product;
  714.  
  715. $product_class = $product->is_on_sale() ? 'product_on_sale' : '';
  716. $product_class.= ' av-product-class-' . avia_get_option( 'product_layout' );
  717.  
  718. echo "<div class='inner_product main_color wrapped_style noLightbox {$product_class}'>";
  719. }
  720. }
  721.  
  722. if( ! function_exists( 'avia_close_div' ) )
  723. {
  724. /**
  725. * @since ????
  726. */
  727. function avia_close_div()
  728. {
  729. echo '</div>';
  730. }
  731. }
  732.  
  733. if( ! function_exists( 'avia_shop_overview_extra_header_div' ) )
  734. {
  735. /**
  736. * wrap product titles and sale number on overview pages into an extra div for improved styling options
  737. *
  738. * @since ????
  739. */
  740. function avia_shop_overview_extra_header_div()
  741. {
  742. echo "<div class='inner_product_header'><div class='avia-arrow'></div>";
  743. echo "<div class='inner_product_header_table'>";
  744. echo "<div class='inner_product_header_cell'>";
  745. }
  746. }
  747.  
  748. add_action( 'woocommerce_before_shop_loop_item', 'avia_shop_overview_extra_div', 5 );
  749. add_action( 'woocommerce_after_shop_loop_item', 'avia_close_div', 1000 );
  750.  
  751. add_action( 'woocommerce_before_shop_loop_item_title', 'avia_shop_overview_extra_header_div', 20 );
  752. add_action( 'woocommerce_after_shop_loop_item_title', 'avia_close_div', 1000 );
  753. add_action( 'woocommerce_after_shop_loop_item_title', 'avia_close_div', 1001 );
  754. add_action( 'woocommerce_after_shop_loop_item_title', 'avia_close_div', 1002 );
  755.  
  756. /**
  757. * remove on sale badge from usual location and add it to the bottom of the product
  758. */
  759. remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10 );
  760. add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10 );
  761.  
  762.  
  763. if( ! function_exists( 'avia_shop_nav' ) )
  764. {
  765. /**
  766. * Create the shop navigation with account links, as well as cart and checkout,
  767. * Called as fallback function by the wp_nav_menu function in header.php
  768. *
  769. * @since ????
  770. * @param array $args
  771. * @return string
  772. */
  773. function avia_shop_nav( $args )
  774. {
  775. $output = '';
  776. $url = avia_collect_shop_urls();
  777.  
  778. $output .= '<ul>';
  779.  
  780. if( is_user_logged_in() )
  781. {
  782. $current = $sub1 = $sub2 = $sub3 = '';
  783.  
  784. if( is_account_page() )
  785. {
  786. $current = 'current-menu-item';
  787. }
  788.  
  789. if( is_page( get_option( 'woocommerce_change_password_page_id' ) ) )
  790. {
  791. $sub1 = 'current-menu-item';
  792. }
  793.  
  794. if( is_page( get_option( 'woocommerce_edit_address_page_id' ) ) )
  795. {
  796. $sub2 = 'current-menu-item';
  797. }
  798.  
  799. if( is_page( get_option( 'woocommerce_view_order_page_id' ) ) )
  800. {
  801. $sub3 = 'current-menu-item';
  802. }
  803.  
  804. $output .= "<li class='{$current} account_overview_link'><a href='" . $url['account_overview'] . "'>" . __( 'My Account', 'avia_framework' ) . '</a>';
  805. $output .= '<ul>';
  806. $output .= "<li class='{$sub1} account_change_pw_link'><a href='" . $url['account_change_pw'] . "'>" . __( 'Change Password', 'avia_framework' ) . '</a></li>';
  807. $output .= "<li class='{$sub2} account_edit_adress_link'><a href='" . $url['account_edit_adress'] . "'>" . __( 'Edit Address', 'avia_framework' ) . '</a></li>';
  808. $output .= "<li class='{$sub3} account_view_order_link'><a href='" . $url['account_view_order'] . "'>" . __( 'View Order', 'avia_framework' ) . '</a></li>';
  809. $output .= '</ul>';
  810. $output .= '</li>';
  811. $output .= "<li class='account_logout_link'><a href='" . $url['logout'] . "'>" . __( 'Log Out', 'avia_framework' ) . '</a></li>';
  812. }
  813. else
  814. {
  815. $sub1 = $sub2 = '';
  816.  
  817. if( is_page( get_option( 'woocommerce_myaccount_page_id' ) ) )
  818. {
  819. if( isset( $_GET['account_visible'] ) && $_GET['account_visible'] == 'register' )
  820. {
  821. $sub1 = 'current-menu-item';
  822. }
  823.  
  824. if( isset( $_GET['account_visible'] ) && $_GET['account_visible'] == 'login' )
  825. {
  826. $sub2 = 'current-menu-item';
  827. }
  828. }
  829.  
  830. $url_param = strpos( $url['account_overview'], '?' ) === false ? '?' : '&';
  831.  
  832. if( get_option( 'woocommerce_enable_myaccount_registration' ) =='yes' )
  833. {
  834. $output .= "<li class='register_link {$sub1}'><a href='" . $url['account_overview'] . $url_param . "account_visible=register'>" . __( 'Register', 'avia_framework' ) . '</a></li>';
  835. }
  836.  
  837. $output .= "<li class='login_link {$sub2}'><a href='" . $url['account_overview'] . $url_param . "account_visible=login'>" . __( 'Log In', 'avia_framework' ) . '</a></li>';
  838. }
  839.  
  840. $output .= '</ul>';
  841.  
  842. if( $args['echo'] == true )
  843. {
  844. echo $output;
  845. }
  846. else
  847. {
  848. return $output;
  849. }
  850.  
  851. }
  852. }
  853.  
  854. if( ! function_exists( 'avia_collect_shop_urls' ) )
  855. {
  856. /**
  857. * helper function that collects all the necessary urls for the shop navigation
  858. *
  859. * @since ????
  860. * @return array
  861. */
  862. function avia_collect_shop_urls()
  863. {
  864. $url = array(
  865. 'cart' => WC()->cart instanceof WC_Cart ? WC()->cart->get_cart_url() : '',
  866. 'checkout' => WC()->cart instanceof WC_Cart ? WC()->cart->get_checkout_url() : '',
  867. 'account_overview' => get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ),
  868. 'account_edit_adress' => get_permalink( get_option( 'woocommerce_edit_address_page_id' ) ),
  869. 'account_view_order' => get_permalink( get_option( 'woocommerce_view_order_page_id' ) ),
  870. 'account_change_pw' => get_permalink( get_option( 'woocommerce_change_password_page_id' ) ),
  871. 'logout' => wp_logout_url( home_url( '/' ) )
  872. );
  873.  
  874. return $url;
  875. }
  876. }
  877.  
  878.  
  879. if( ! function_exists( 'avia_woocommerce_sidebar_filter' ) )
  880. {
  881. /**
  882. * check which page is displayed and if the automatic sidebar menu for subpages should be prevented
  883. *
  884. * @since ????
  885. * @param string $menu
  886. * @return string
  887. */
  888. function avia_woocommerce_sidebar_filter( $menu )
  889. {
  890. $id = avia_get_the_ID();
  891.  
  892. if( is_cart() || is_checkout() || get_option( 'woocommerce_thanks_page_id' ) == $id )
  893. {
  894. $menu = '';
  895. }
  896.  
  897. return $menu;
  898. }
  899. }
  900.  
  901. add_filter( 'avf_sidebar_menu_filter', 'avia_woocommerce_sidebar_filter', 10, 1 );
  902.  
  903.  
  904.  
  905. if( ! function_exists( 'avia_woocommerce_sidebar_pos' ) )
  906. {
  907. /**
  908. * check if a single product is displayed and always set the sidebar styling to that of a right sidebar
  909. *
  910. * @since ????
  911. * @param string $sidebar
  912. * @return string
  913. */
  914. function avia_woocommerce_sidebar_pos( $sidebar )
  915. {
  916. if( is_product() )
  917. {
  918. $sidebar = 'sidebar_right';
  919. }
  920.  
  921. return $sidebar;
  922. }
  923. }
  924.  
  925. add_filter( 'avf_sidebar_position', 'avia_woocommerce_sidebar_pos', 10, 1 );
  926.  
  927.  
  928.  
  929. if( ! function_exists( 'avia_add_to_cart' ) )
  930. {
  931. /**
  932. * @since ????
  933. * @deprecated 5.3 seems to be unused
  934. * @param WP_Post $post
  935. * @param WC_Product $product
  936. */
  937. function avia_add_to_cart( $post, $product )
  938. {
  939. _deprecated_function( 'avia_add_to_cart', '5.3', 'will be removed in future - seems to be unused');
  940.  
  941. echo '<div class="avia_cart avia_cart_' . $product->get_type() . '">';
  942.  
  943. /**
  944. * @since ????
  945. * @param WP_Post $post
  946. * @param WC_Product $product
  947. */
  948. do_action( 'avia_add_to_cart', $post, $product );
  949.  
  950. echo '</div>';
  951. }
  952. }
  953.  
  954. /*
  955. add_filter( 'single_product_small_thumbnail_size', 'avia_woocommerce_thumb_size' );
  956. /**
  957. * replace thumbnail image size with full size image on single pages
  958. *
  959. * @deprecated ???? ( < 5.3 )
  960. * /
  961. function avia_woocommerce_thumb_size()
  962. {
  963. return 'shop_single';
  964. }
  965. */
  966.  
  967. if( ! function_exists( 'avia_woocommerce_breadcrumb' ) )
  968. {
  969. /**
  970. * if we are viewing a woocommerce page modify the breadcrumb nav
  971. *
  972. * @since ????
  973. * @param array $trail
  974. * @param array $args
  975. * @return array
  976. */
  977. function avia_woocommerce_breadcrumb( $trail, $args )
  978. {
  979. global $avia_config;
  980.  
  981. if( is_woocommerce() )
  982. {
  983. $front_id = avia_get_option( 'frontpage' );
  984. $home = isset( $trail[0] ) ? $trail[0] : '';
  985. $last = array_pop( $trail );
  986. $shop_id = function_exists( 'wc_get_page_id' ) ? wc_get_page_id( 'shop' ) : woocommerce_get_page_id( 'shop' );
  987. $taxonomy = 'product_cat';
  988.  
  989. // on the shop frontpage simply display the shop name, rather than shop name + 'All Products'
  990. if( is_shop() )
  991. {
  992. if( ! empty( $shop_id ) && $shop_id != -1 )
  993. {
  994. $trail = array_merge( $trail, Avia_Breadcrumb_Trail()->get_parents( $shop_id ) );
  995. }
  996.  
  997. $last = '';
  998.  
  999. if( is_search() )
  1000. {
  1001. $last = __( 'Search results for:', 'avia_framework' ) . ' ' . esc_attr( $_GET['s'] );
  1002. }
  1003. }
  1004.  
  1005. // on the product page single page modify the breadcrumb to read [home] [if available:parent shop pages] [shop] [if available:parent categories] [category] [title]
  1006. if( is_product() )
  1007. {
  1008. //fetch all product categories and search for the ones with parents. if none are avalaible use the first category found
  1009. $product_category = $parent_cat = array();
  1010.  
  1011. $temp_cats = get_the_terms( get_the_ID(), $taxonomy );
  1012.  
  1013. if( is_array( $temp_cats ) && ! empty( $temp_cats ) )
  1014. {
  1015. foreach( $temp_cats as $key => $cat )
  1016. {
  1017. if( $cat->parent != 0 && ! in_array( $cat->term_taxonomy_id, $parent_cat ) )
  1018. {
  1019. $product_category[] = $cat;
  1020. $parent_cat[] = $cat->parent;
  1021. }
  1022. }
  1023.  
  1024. //if no categories with parents use the first one
  1025. if( empty( $product_category ) )
  1026. {
  1027. $product_category[] = reset( $temp_cats );
  1028. }
  1029. }
  1030. //unset the trail and build our own
  1031. unset( $trail );
  1032.  
  1033. $trail = ( empty( $home ) ) ? array() : array( 0 => $home );
  1034.  
  1035. if( ! empty( $shop_id ) && $shop_id != -1 )
  1036. {
  1037. $trail = array_merge( $trail, Avia_Breadcrumb_Trail()->get_parents( $shop_id ) );
  1038. }
  1039.  
  1040. if( ! empty( $parent_cat ) )
  1041. {
  1042. $trail = array_merge( $trail, Avia_Breadcrumb_Trail()->get_term_parents( $parent_cat[0] , $taxonomy ) );
  1043. }
  1044.  
  1045. if( ! empty( $product_category ) )
  1046. {
  1047. $trail[] = '<a href="' . get_term_link( $product_category[0]->slug, $taxonomy ) . '" title="' . esc_attr( $product_category[0]->name ) . '">' . $product_category[0]->name . '</a>';
  1048. }
  1049. }
  1050.  
  1051.  
  1052. // add the [shop] trail to category/tag pages: [home] [if available:parent shop pages] [shop] [if available:parent categories] [category/tag]
  1053. if( is_product_category() || is_product_tag() )
  1054. {
  1055. if( ! empty( $shop_id ) && $shop_id != -1 )
  1056. {
  1057. $shop_trail = Avia_Breadcrumb_Trail()->get_parents( $shop_id ) ;
  1058. array_splice( $trail, 1, 0, $shop_trail );
  1059. }
  1060. }
  1061.  
  1062. if( is_product_tag() )
  1063. {
  1064. $last = __( 'Tag', 'avia_framework' ) . ': ' . $last;
  1065. }
  1066.  
  1067. if( ! empty( $last ) )
  1068. {
  1069. $trail['trail_end'] = $last;
  1070. }
  1071.  
  1072. /**
  1073. * Allow to remove 'Shop' in breadcrumb when shop page is frontpage
  1074. *
  1075. * @since 4.2.7
  1076. */
  1077. $trail_count = count( $trail );
  1078. if( ( $front_id == $shop_id ) && ! empty( $home ) && ( $trail_count > 1 ) )
  1079. {
  1080. /**
  1081. * Filter to show shop title in breadcrumb
  1082. *
  1083. * @since ????
  1084. * @param array $trail
  1085. * @param array $args
  1086. * @return string 'hide' | ......
  1087. */
  1088. $hide = apply_filters( 'avf_woocommerce_breadcrumb_hide_shop', 'hide', $trail, $args );
  1089. if( 'hide' == $hide )
  1090. {
  1091. $title = get_the_title( $shop_id );
  1092.  
  1093. for( $i = 1; $i < $trail_count; $i++ )
  1094. {
  1095. if( false !== strpos( $trail[ $i ], $title ) )
  1096. {
  1097. unset( $trail[ $i ] );
  1098. break;
  1099. }
  1100. }
  1101.  
  1102. $trail = array_merge( $trail );
  1103. }
  1104. }
  1105. }
  1106.  
  1107. return $trail;
  1108. }
  1109. }
  1110.  
  1111. add_filter( 'avia_breadcrumbs_trail', 'avia_woocommerce_breadcrumb', 10, 2 );
  1112.  
  1113.  
  1114. if( ! function_exists( 'avia_woocommerce_before_main_content' ) )
  1115. {
  1116. /**
  1117. * creates the avia framework container around the shop pages
  1118. *
  1119. * @since ????
  1120. */
  1121. function avia_woocommerce_before_main_content()
  1122. {
  1123. global $avia_config;
  1124.  
  1125. if( ! isset( $avia_config['shop_overview_column'] ) )
  1126. {
  1127. $avia_config['shop_overview_column'] = 'auto';
  1128. }
  1129.  
  1130. $id = get_option( 'woocommerce_shop_page_id' );
  1131. $layout = get_post_meta( $id, 'layout', true );
  1132.  
  1133. if( ! empty( $layout ) )
  1134. {
  1135. $avia_config['layout']['current'] = $avia_config['layout'][$layout];
  1136. $avia_config['layout']['current']['main'] = $layout;
  1137. }
  1138.  
  1139. /**
  1140. * @since ????
  1141. * @param string $avia_config['layout']
  1142. * @param int $id
  1143. * @return string
  1144. */
  1145. $avia_config['layout'] = apply_filters( 'avia_layout_filter', $avia_config['layout'], $id );
  1146.  
  1147. $title_args = array();
  1148.  
  1149. if( is_woocommerce() )
  1150. {
  1151. $t_link = '';
  1152.  
  1153. if( is_shop() )
  1154. {
  1155. $title = get_option( 'woocommerce_shop_page_title' );
  1156. }
  1157.  
  1158. $shop_id = function_exists( 'wc_get_page_id' ) ? wc_get_page_id( 'shop' ) : woocommerce_get_page_id( 'shop' );
  1159. if( $shop_id && $shop_id != -1 )
  1160. {
  1161. if( empty( $title ) )
  1162. {
  1163. $title = get_the_title( $shop_id );
  1164. }
  1165.  
  1166. $t_link = get_permalink( $shop_id );
  1167. }
  1168.  
  1169. if( empty( $title ) )
  1170. {
  1171. $title = __( 'Shop', 'avia_framework' );
  1172. }
  1173.  
  1174. if( is_product_category() || is_product_tag() )
  1175. {
  1176. global $wp_query;
  1177.  
  1178. $tax = $wp_query->get_queried_object();
  1179. $title = $tax->name;
  1180. $t_link = '';
  1181. }
  1182.  
  1183. $title_args = array(
  1184. 'title' => $title,
  1185. 'link' => $t_link
  1186. );
  1187. }
  1188.  
  1189. if( get_post_meta( get_the_ID(), 'header', true ) != 'no' )
  1190. {
  1191. echo avia_title( $title_args );
  1192. }
  1193.  
  1194. /**
  1195. * @since 6.0
  1196. */
  1197. do_action( 'ava_after_main_title' );
  1198.  
  1199. if( is_singular() )
  1200. {
  1201. $result = 'sidebar_right';
  1202. $avia_config['layout']['current'] = $avia_config['layout'][ $result ];
  1203. $avia_config['layout']['current']['main'] = $result;
  1204.  
  1205. }
  1206.  
  1207. $sidebar_setting = avia_layout_class( 'main' , false );
  1208.  
  1209. echo "<div class='container_wrap container_wrap_first main_color {$sidebar_setting} template-shop shop_columns_" . $avia_config['shop_overview_column'] . "'>";
  1210. echo '<div class="container">';
  1211.  
  1212. if( ! is_singular() )
  1213. {
  1214. $avia_config['overview'] = true;
  1215. }
  1216. }
  1217. }
  1218.  
  1219. add_action( 'woocommerce_before_main_content', 'avia_woocommerce_before_main_content', 10 );
  1220.  
  1221.  
  1222. if( ! function_exists( 'avia_woocommerce_after_main_content' ) )
  1223. {
  1224. /**
  1225. * closes the avia framework container around the shop pages
  1226. *
  1227. * @since ????
  1228. */
  1229. function avia_woocommerce_after_main_content()
  1230. {
  1231. global $avia_config;
  1232.  
  1233. $avia_config['currently_viewing'] = 'shop';
  1234.  
  1235. //reset all previous queries
  1236. wp_reset_query();
  1237.  
  1238. //get the sidebar
  1239. if( ! is_singular() )
  1240. {
  1241. get_sidebar();
  1242. }
  1243.  
  1244. // echo '</div>'; // end container - gets already closed at the top of footer.php
  1245. echo '</div>'; // end tempate-shop content
  1246. echo '</div>'; // close default .container_wrap element
  1247. }
  1248. }
  1249.  
  1250. add_action( 'woocommerce_after_main_content', 'avia_woocommerce_after_main_content', 10 );
  1251.  
  1252.  
  1253. if( ! function_exists( 'avia_woocommerce_custom_sidebar' ) )
  1254. {
  1255. /**
  1256. *
  1257. * @since ????
  1258. * @param string $sidebar
  1259. * @return string
  1260. */
  1261. function avia_woocommerce_custom_sidebar( $sidebar )
  1262. {
  1263. if( is_shop() )
  1264. {
  1265. $the_id = function_exists( 'wc_get_page_id' ) ? wc_get_page_id( 'shop' ) : woocommerce_get_page_id( 'shop' );
  1266. $sidebar = get_post_meta( $the_id, 'sidebar', true );
  1267. }
  1268.  
  1269. return $sidebar;
  1270. }
  1271. }
  1272.  
  1273. add_action( 'avf_custom_sidebar', 'avia_woocommerce_custom_sidebar', 10, 1 );
  1274.  
  1275.  
  1276. if( ! function_exists( 'avia_woocommerce_404_search' ) )
  1277. {
  1278. /**
  1279. * wrap an empty product search into extra div
  1280. *
  1281. * @since ????
  1282. */
  1283. function avia_woocommerce_404_search()
  1284. {
  1285. global $wp_query;
  1286.  
  1287. if( ( is_search() || is_archive() ) && empty( $wp_query->found_posts ) )
  1288. {
  1289. echo "<div class='template-page template-search template-search-none content " . avia_layout_class( 'content', false ) . " units'>";
  1290. echo '<div class="entry entry-content-wrapper" id="search-fail">';
  1291. }
  1292. }
  1293. }
  1294.  
  1295. add_action( 'woocommerce_before_main_content', 'avia_woocommerce_404_search', 9111, 1 );
  1296.  
  1297.  
  1298. if( ! function_exists( 'avia_woocommerce_404_search_close' ) )
  1299. {
  1300. /**
  1301. * @since ????
  1302. */
  1303. function avia_woocommerce_404_search_close()
  1304. {
  1305. global $wp_query;
  1306.  
  1307. if( ( is_search() || is_shop() || is_archive() ) && empty( $wp_query->found_posts ) )
  1308. {
  1309. get_template_part( 'includes/error404' );
  1310.  
  1311. echo '</div>';
  1312. echo '</div>'; // close default .container_wrap element
  1313. }
  1314. }
  1315. }
  1316.  
  1317. add_action( 'woocommerce_after_main_content', 'avia_woocommerce_404_search_close', 1 );
  1318.  
  1319.  
  1320. if( ! function_exists( 'avia_register_login_class' ) )
  1321. {
  1322. /**
  1323. * modifies the class of a page so we can display single login and single register
  1324. *
  1325. * @since ????
  1326. * @param string $layout
  1327. * @return string
  1328. */
  1329. function avia_register_login_class( $layout )
  1330. {
  1331. if( isset( $_GET['account_visible'] ) )
  1332. {
  1333. if( $_GET['account_visible'] == 'register' )
  1334. {
  1335. $layout .= ' template-register';
  1336. }
  1337.  
  1338. if( $_GET['account_visible'] == 'login' )
  1339. {
  1340. $layout .= ' template-login';
  1341. }
  1342. }
  1343.  
  1344. return $layout;
  1345. }
  1346. }
  1347.  
  1348. add_filter( 'avia_layout_class_filter_main', 'avia_register_login_class', 10, 1 );
  1349.  
  1350.  
  1351. if( ! function_exists( 'avia_woocommerce_before_shop_loop' ) )
  1352. {
  1353. /**
  1354. * creates the avia framework content container around the shop loop
  1355. *
  1356. * @since ????
  1357. */
  1358. function avia_woocommerce_before_shop_loop()
  1359. {
  1360. global $avia_config;
  1361.  
  1362. if( isset( $avia_config['dynamic_template'] ) )
  1363. {
  1364. return;
  1365. }
  1366.  
  1367. $markup = avia_markup_helper( array( 'context' => 'content', 'echo' => false, 'post_type' => 'products' ) );
  1368.  
  1369. echo "<main class='template-shop content " . avia_layout_class( 'content', false ) . " units' {$markup}><div class='entry-content-wrapper'>";
  1370. }
  1371. }
  1372.  
  1373. add_action( 'woocommerce_before_shop_loop', 'avia_woocommerce_before_shop_loop', 1 );
  1374.  
  1375.  
  1376. if( ! function_exists( 'avia_woocommerce_after_shop_loop' ) )
  1377. {
  1378. /**
  1379. * closes the avia framework content container around the shop loop
  1380. *
  1381. * @since ????
  1382. */
  1383. function avia_woocommerce_after_shop_loop()
  1384. {
  1385. global $avia_config;
  1386.  
  1387. if( isset( $avia_config['dynamic_template'] ) )
  1388. {
  1389. return;
  1390. }
  1391.  
  1392. if( isset( $avia_config['overview'] ) )
  1393. {
  1394. echo avia_pagination( '', 'nav' );
  1395. }
  1396.  
  1397. echo '</div></main>'; //end content
  1398. }
  1399. }
  1400.  
  1401. add_action( 'woocommerce_after_shop_loop', 'avia_woocommerce_after_shop_loop', 10 );
  1402.  
  1403.  
  1404. if( ! function_exists( 'avia_woocommerce_overview_excerpt' ) )
  1405. {
  1406. /**
  1407. * echo the excerpt
  1408. *
  1409. * @since ????
  1410. */
  1411. function avia_woocommerce_overview_excerpt()
  1412. {
  1413. global $avia_config;
  1414.  
  1415. if( ! empty( $avia_config['shop_overview_excerpt'] ) )
  1416. {
  1417. echo '<div class="product_excerpt">';
  1418. the_excerpt();
  1419. echo '</div>';
  1420. }
  1421. }
  1422. }
  1423.  
  1424. #
  1425. # creates the preview images based on page/category image
  1426. #
  1427. remove_action( 'woocommerce_archive_description', 'woocommerce_taxonomy_archive_description', 10 );
  1428. remove_action( 'woocommerce_product_archive_description', 'woocommerce_product_archive_description', 10 );
  1429.  
  1430. add_action( 'woocommerce_before_shop_loop', 'avia_woocommerce_overview_banner_image', 10 );
  1431. add_action( 'woocommerce_before_shop_loop', 'woocommerce_taxonomy_archive_description', 11 );
  1432. //add_action( 'woocommerce_before_shop_loop', 'woocommerce_product_archive_description', 12 ); //causes warning
  1433.  
  1434.  
  1435. if( ! function_exists( 'avia_woocommerce_overview_banner_image' ) )
  1436. {
  1437. /**
  1438. *
  1439. * @since ????
  1440. */
  1441. function avia_woocommerce_overview_banner_image()
  1442. {
  1443. global $avia_config;
  1444.  
  1445. // removed 4.9 avia_is_dynamic_template()
  1446. // if(avia_is_dynamic_template() || is_paged() || is_search() ) return false;
  1447.  
  1448. if( is_paged() || is_search() )
  1449. {
  1450. return;
  1451. }
  1452.  
  1453. $image_size = 'entry_with_sidebar';
  1454. $layout = avia_layout_class( 'main' , false );
  1455. if( $layout == 'fullsize' )
  1456. {
  1457. $image_size = 'entry_without_sidebar';
  1458. }
  1459.  
  1460. if( is_shop() )
  1461. {
  1462. $shop_id = function_exists( 'wc_get_page_id' ) ? wc_get_page_id( 'shop' ) : woocommerce_get_page_id( 'shop' );
  1463. if( $shop_id != -1 )
  1464. {
  1465. $image = get_the_post_thumbnail( $shop_id, $image_size );
  1466. if( $image )
  1467. {
  1468. echo "<div class='page-thumb'>{$image}</div>";
  1469. }
  1470. }
  1471. }
  1472.  
  1473. if( is_product_category() )
  1474. {
  1475. global $wp_query;
  1476.  
  1477. $image = '';
  1478. if( isset( $wp_query->query_vars['taxonomy'] ) )
  1479. {
  1480. $term = get_term_by( 'slug', get_query_var( $wp_query->query_vars['taxonomy'] ), $wp_query->query_vars['taxonomy'] );
  1481.  
  1482. if( ! empty( $term->term_id ) )
  1483. {
  1484. $attachment_id = avia_get_woocommerce_term_meta( $term->term_id, 'thumbnail_id' );
  1485. $style = avia_get_woocommerce_term_meta( $term->term_id, 'av_cat_styling' );
  1486.  
  1487. // display default WC thumbnail if banner image not selected
  1488. if( ! empty( $attachment_id ) && empty( $style ) )
  1489. {
  1490. $args = [
  1491. 'title' => trim( strip_tags(get_post_field( 'post_title', $attachment_id ) ) ),
  1492. 'class' => "category_thumb attachment-{$image_size} size-{$image_size}"
  1493. ];
  1494.  
  1495. $image = wp_get_attachment_image( $attachment_id, $image_size, false, $args );
  1496. if( $image )
  1497. {
  1498. echo "<div class='page-thumb'>{$image}</div>";
  1499. }
  1500. }
  1501. }
  1502. }
  1503. }
  1504. }
  1505. }
  1506.  
  1507.  
  1508. if( ! function_exists( 'avia_woocommerce_big_cat_banner' ) )
  1509. {
  1510. /**
  1511. *
  1512. * @since ????
  1513. */
  1514. function avia_woocommerce_big_cat_banner()
  1515. {
  1516. if( is_product_category() )
  1517. {
  1518. global $wp_query, $avia_config;
  1519.  
  1520. if( isset( $avia_config['woo-banner'] ) )
  1521. {
  1522. return;
  1523. }
  1524.  
  1525. if( isset( $wp_query->query_vars['taxonomy'] ) )
  1526. {
  1527. $term = get_term_by( 'slug', get_query_var( $wp_query->query_vars['taxonomy'] ), $wp_query->query_vars['taxonomy'] );
  1528. if( ! empty( $term->term_id ) )
  1529. {
  1530. $style = avia_get_woocommerce_term_meta( $term->term_id, 'av_cat_styling' );
  1531.  
  1532. if( empty( $style ) )
  1533. {
  1534. return;
  1535. }
  1536.  
  1537. $attachment_id = avia_get_woocommerce_term_meta( $term->term_id, 'thumbnail_id' );
  1538.  
  1539. // fallback to theme option if no attachment
  1540. if( empty( $attachment_id ) )
  1541. {
  1542. return;
  1543. }
  1544.  
  1545. // flag that we have a category image to display
  1546. $avia_config['woo-banner-cat'] = true;
  1547.  
  1548. remove_action( 'woocommerce_before_shop_loop', 'woocommerce_taxonomy_archive_description', 11 );
  1549.  
  1550. $title_bar = avia_get_option( 'header_title_bar', 'hidden_title_bar' );
  1551.  
  1552. switch( current_action() )
  1553. {
  1554. case 'ava_after_main_container':
  1555. if( false !== strpos( $style, 'cat_banner_below' ) )
  1556. {
  1557. if( 'hidden_title_bar' != $title_bar )
  1558. {
  1559. return;
  1560. }
  1561. }
  1562. break;
  1563. case 'ava_after_main_title':
  1564. // 'header_dark' is kept due to backwards comp with older sites
  1565. if( false !== strpos( $style, 'header_dark' ) )
  1566. {
  1567. return;
  1568. }
  1569. break;
  1570. default:
  1571. return;
  1572. }
  1573.  
  1574.  
  1575.  
  1576. $description = term_description();
  1577. $overlay = avia_get_woocommerce_term_meta( $term->term_id, 'av-banner-overlay' );
  1578. $font = avia_get_woocommerce_term_meta( $term->term_id, 'av-banner-font' );
  1579. $opacity = avia_get_woocommerce_term_meta( $term->term_id, 'av-banner-overlay-opacity' );
  1580.  
  1581. echo avia_woocommerce_parallax_banner( $attachment_id, $overlay, $opacity, $description, $font, $style );
  1582.  
  1583. $avia_config['woo-banner'] = true;
  1584. }
  1585. }
  1586. }
  1587. }
  1588.  
  1589. add_action( 'ava_after_main_container', 'avia_woocommerce_big_cat_banner', 11 );
  1590. add_action( 'ava_after_main_title', 'avia_woocommerce_big_cat_banner', 11 );
  1591. }
  1592.  
  1593. if( ! function_exists( 'avia_woocommerce_shop_banner' ) )
  1594. {
  1595. /**
  1596. *
  1597. * @since ????
  1598. */
  1599. function avia_woocommerce_shop_banner()
  1600. {
  1601. global $avia_config;
  1602.  
  1603. $banner = avia_get_option( 'shop_banner', '' );
  1604.  
  1605. if( empty( $banner ) || isset( $avia_config['woo-banner'] ) || isset( $avia_config['woo-banner-cat'] ) )
  1606. {
  1607. return;
  1608. }
  1609.  
  1610. $title_bar = avia_get_option( 'header_title_bar', 'hidden_title_bar' );
  1611. $location = avia_get_option( 'shop_banner_location', '' );
  1612.  
  1613. switch( current_action() )
  1614. {
  1615. case 'ava_after_main_container':
  1616. if( 'av-shop-banner-below' == $location )
  1617. {
  1618. if( 'hidden_title_bar' != $title_bar )
  1619. {
  1620. return;
  1621. }
  1622. }
  1623. break;
  1624. case 'ava_after_main_title':
  1625. if( '' == $location )
  1626. {
  1627. return;
  1628. }
  1629. break;
  1630. default:
  1631. return;
  1632. }
  1633.  
  1634. if( is_shop() || ( is_product_category() && avia_get_option( 'shop_banner_global' ) == 'shop_banner_global' ) && ! isset( $avia_config['woo-banner'] ) )
  1635. {
  1636. $options = avia_get_option();
  1637.  
  1638. if( isset( $options['shop_banner'] ) && ( false !== strpos( $options['shop_banner'], 'av-active-shop-banner' ) ) )
  1639. {
  1640. $bg = $options['shop_banner_image'];
  1641. $overlay = $options['shop_banner_overlay_color'];
  1642. $opacity = $options['shop_banner_overlay_opacity'];
  1643. $description = wpautop( $options['shop_banner_message'] );
  1644. $font = $options['shop_banner_message_color'];
  1645.  
  1646. echo avia_woocommerce_parallax_banner( $bg, $overlay, $opacity, $description, $font, $options['shop_banner'] );
  1647.  
  1648. $avia_config['woo-banner'] = true;
  1649. }
  1650. }
  1651. }
  1652.  
  1653. add_action( 'ava_after_main_container', 'avia_woocommerce_shop_banner', 12 );
  1654. add_action( 'ava_after_main_title', 'avia_woocommerce_shop_banner', 12 );
  1655. }
  1656.  
  1657.  
  1658. if( ! function_exists( 'avia_woocommerce_parallax_banner' ) )
  1659. {
  1660. /**
  1661. *
  1662. * @since ????
  1663. * @since 6.0 added $effect and responsive image support
  1664. * @param string|int $bg
  1665. * @param string $overlay
  1666. * @param float $opacity
  1667. * @param string $description
  1668. * @param string $font
  1669. * @param string $effect '...' | '... av-scroll' | '... av-responsive'
  1670. * @return string
  1671. */
  1672. function avia_woocommerce_parallax_banner( $bg, $overlay, $opacity, $description, $font, $effect = '' )
  1673. {
  1674. $is_scroll = false !== strpos( $effect, 'av-scroll' );
  1675. $is_responsive = false !== strpos( $effect, 'av-responsive' );
  1676. $is_parallax = ! $is_scroll && ! $is_responsive;
  1677. $bg_img = '';
  1678. $img_tag = '';
  1679.  
  1680. $title_attr = __( 'Shop Banner Image', 'avia_framework' );
  1681. $markup_url = avia_markup_helper( array( 'context' => 'image_url', 'echo' => false ) );
  1682.  
  1683. $image_size = $is_responsive ? 'featured' : 'extra_large';
  1684.  
  1685. /**
  1686. * Filter the default image size for banner image
  1687. *
  1688. * @since 6.0
  1689. * @param string $image_size
  1690. * @param string|int $bg
  1691. * @param string $effect
  1692. * @return string
  1693. */
  1694. $image_size = apply_filters( 'avf_woocommerce_default_banner_image_size', $image_size, $bg, $effect );
  1695.  
  1696. if( is_numeric( $bg ) )
  1697. {
  1698. if( ! $is_responsive )
  1699. {
  1700. //$bg = wp_get_attachment_image_src( $bg, $image_size );
  1701. $bg_image = wp_get_attachment_image_src($bg, $image_size);
  1702. if (is_array($bg_image) && isset($bg_image[0])) {
  1703. $bg = $bg_image[0];
  1704. } else {
  1705. $bg = '';
  1706. }
  1707.  
  1708.  
  1709. $bg_img = ( is_array( $bg ) && $bg[0] != '' ) ? $bg[0] : '';
  1710. }
  1711. else
  1712. {
  1713. $args = [
  1714. 'title' => trim( strip_tags(get_post_field( 'post_title', $bg ) ) )
  1715. ];
  1716.  
  1717. $img_tag = wp_get_attachment_image( $bg, $image_size, false, $args );
  1718. }
  1719. }
  1720. else
  1721. {
  1722. $bg_img = $bg;
  1723.  
  1724. if( $is_responsive )
  1725. {
  1726. // find attachment id - remove width and height
  1727. $full = preg_replace('/-\d+[Xx]\d+\./', ".", $bg );
  1728. $att_id = attachment_url_to_postid( esc_url( $full ) );
  1729.  
  1730. $size = [];
  1731. preg_match('/-\d+[Xx]\d+\./', $bg, $size );
  1732.  
  1733. if( $att_id <= 0 )
  1734. {
  1735. // fallback - we set an unresponsive default image
  1736. $img_tag = "<img class='avia_image' src='{$bg}' alt='{$title_attr}' title='{$title_attr}' decoding='async' {$markup_url} />";
  1737. }
  1738. else
  1739. {
  1740. if( ! empty( $size ) )
  1741. {
  1742. $size = str_replace( 'X', 'x', $size[0] );
  1743. $size = explode( 'x', $size );
  1744. $w = str_replace( '-', '', $size[0] );
  1745. $h = str_replace( '.', '', $size[1] );
  1746.  
  1747. $imagedata = wp_get_attachment_metadata( $att_id );
  1748.  
  1749. if( is_array( $imagedata ) && ! empty( $imagedata['sizes'] ) )
  1750. {
  1751. foreach( $imagedata['sizes'] as $_size => $data )
  1752. {
  1753. if( (int) $data['width'] === (int) $w && (int) $data['height'] === (int) $h )
  1754. {
  1755. $image_size = $_size;
  1756. break;
  1757. }
  1758. }
  1759. }
  1760. }
  1761.  
  1762. $args = [
  1763. 'title' => trim( strip_tags(get_post_field( 'post_title', $att_id ) ) )
  1764. ];
  1765.  
  1766. $img_tag = wp_get_attachment_image( $att_id, $image_size, false, $args );
  1767. }
  1768. }
  1769. }
  1770.  
  1771. if( $font )
  1772. {
  1773. $font = "style='color:{$font};'";
  1774. }
  1775.  
  1776. if( $bg )
  1777. {
  1778. $bg = "background-image: url({$bg});";
  1779. }
  1780.  
  1781. $parallax_class = $is_parallax ? 'av-parallax' : '';
  1782. $responsive_class = $is_responsive ? 'av-responsive-banner avia-section-small' : 'avia-section-large';
  1783. $desc_tag = $is_responsive ? 'div' : 'h1';
  1784.  
  1785. /**
  1786. * @since 5.6
  1787. * @param string $desc_tag
  1788. * @param string
  1789. */
  1790. $desc_tag = apply_filters( 'avf_wc_parallax_banner_tag', $desc_tag );
  1791.  
  1792. $output = '';
  1793. $output .= '<div id="av_product_description" class="avia-section main_color avia-no-border-styling avia-full-stretch av-parallax-section av-section-color-overlay-active avia-bg-style-parallax container_wrap fullsize ' . $responsive_class . '" data-section-bg-repeat="stretch" ' . $font . '>';
  1794.  
  1795. if( $is_parallax || $is_scroll )
  1796. {
  1797. $output .= '<div class="' . $parallax_class . ' avia-full-stretch" data-avia-parallax-ratio="0.3">';
  1798. $output .= '<div class="av-parallax-inner av-parallax-woo" style="' . $bg . ' background-attachment: scroll; background-position: 50% 50%; background-repeat: no-repeat;">';
  1799. $output .= '</div>';
  1800. $output .= '</div>';
  1801. }
  1802. else
  1803. {
  1804. $output .= $img_tag;
  1805. }
  1806.  
  1807. $output .= '<div class="av-section-color-overlay-wrap">';
  1808.  
  1809. if( ! $is_responsive && ! empty( $overlay ) )
  1810. {
  1811. $output .= '<div class="av-section-color-overlay" style="opacity: ' . $opacity . '; background-color: ' . $overlay . '; "></div>';
  1812. }
  1813.  
  1814. $output .= '<div class="container">';
  1815. $output .= '<main class="template-page content av-content-full alpha units">';
  1816.  
  1817. if( $description )
  1818. {
  1819. $output .= "<{$desc_tag} class='av-banner-description'>{$description}</{$desc_tag}>";
  1820. }
  1821.  
  1822. $output .= '</main>';
  1823. $output .= '</div>';
  1824. $output .= '</div>';
  1825. $output .= '</div>';
  1826.  
  1827. return $output;
  1828. }
  1829. }
  1830.  
  1831. if( ! function_exists( 'avia_woocommerce_advanced_title' ) )
  1832. {
  1833. /**
  1834. * creates the title + description for overview pages
  1835. *
  1836. * @since ????
  1837. */
  1838. function avia_woocommerce_advanced_title()
  1839. {
  1840. global $wp_query;
  1841.  
  1842. $titleClass = '';
  1843. $image = '';
  1844.  
  1845.  
  1846. if( ! empty( $attachment_id ) )
  1847. {
  1848. $titleClass .= 'title_container_image ';
  1849. $image = wp_get_attachment_image( $attachment_id, 'thumbnail', false, array( 'class' => 'category_thumb' ) );
  1850. }
  1851.  
  1852. echo "<div class='extralight-border title_container shop_title_container {$titleClass}'>";
  1853. //echo avia_breadcrumbs();
  1854. woocommerce_catalog_ordering();
  1855. echo $image;
  1856. }
  1857. }
  1858.  
  1859. if( ! function_exists( 'avia_woocommerce_loop_columns' ) )
  1860. {
  1861. /**
  1862. * modify shop overview column count
  1863. *
  1864. * @since ????
  1865. * @return array
  1866. */
  1867. function avia_woocommerce_loop_columns()
  1868. {
  1869. global $avia_config;
  1870.  
  1871. return $avia_config['shop_overview_column'];
  1872. }
  1873. }
  1874.  
  1875.  
  1876. if( ! function_exists( 'avia_woocommerce_product_count' ) )
  1877. {
  1878. /**
  1879. * modify shop overview product count
  1880. *
  1881. * @since ????
  1882. * @return array
  1883. */
  1884. function avia_woocommerce_product_count()
  1885. {
  1886. global $avia_config;
  1887.  
  1888. return $avia_config['shop_overview_products'];
  1889. }
  1890. }
  1891.  
  1892.  
  1893. if( ! function_exists( 'avia_woocommerce_cross_sale_count' ) )
  1894. {
  1895. /**
  1896. * filter cross sells on the cart page. display 4 on fullwidth pages and 3 on carts with sidebar
  1897. *
  1898. * @since ????
  1899. * @param int $count
  1900. * @return int
  1901. */
  1902. function avia_woocommerce_cross_sale_count( $count )
  1903. {
  1904. return 4;
  1905. }
  1906. }
  1907.  
  1908. add_filter( 'woocommerce_cross_sells_total', 'avia_woocommerce_cross_sale_count', 10, 1 );
  1909. add_filter( 'woocommerce_cross_sells_columns', 'avia_woocommerce_cross_sale_count', 10, 1 );
  1910.  
  1911.  
  1912. #
  1913. # move cross sells below the shipping
  1914. #
  1915. remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cross_sell_display' );
  1916. add_action( 'woocommerce_after_cart', 'woocommerce_cross_sell_display' , 10 );
  1917.  
  1918.  
  1919. #
  1920. # display tabs and related items within the summary wrapper
  1921. #
  1922. remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 10 );
  1923. add_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 1 );
  1924.  
  1925.  
  1926. if( ! function_exists( 'avia_woocommerce_output_related_products' ) )
  1927. {
  1928. /**
  1929. *
  1930. * @since ????
  1931. * @param int|false $items
  1932. * @param int|false $columns
  1933. * @return string
  1934. */
  1935. function avia_woocommerce_output_related_products( $items = false, $columns = false )
  1936. {
  1937. global $avia_config;
  1938.  
  1939. $output = '';
  1940.  
  1941. if( ! $items )
  1942. {
  1943. $items = $avia_config['shop_single_column_items'];
  1944. }
  1945.  
  1946. if( ! $columns )
  1947. {
  1948. $columns = $avia_config['shop_single_column'];
  1949. }
  1950.  
  1951. ob_start();
  1952. woocommerce_related_products(array( 'posts_per_page' => $items, 'columns' => $columns ) ); // X products, X columns
  1953. $content = ob_get_clean();
  1954.  
  1955. if( $content )
  1956. {
  1957. $output .= "<div class='product_column product_column_{$columns}'>";
  1958. // $output .= '<h3>'.( __( 'Related Products', 'avia_framework' ) ).'</h3>';
  1959. $output .= $content;
  1960. $output .= '</div>';
  1961. }
  1962.  
  1963. $avia_config['woo_related'] = $output;
  1964. return $output;
  1965. }
  1966. }
  1967.  
  1968. // display upsells and related products within dedicated div with different column and number of products
  1969. remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products',20 );
  1970. remove_action( 'woocommerce_after_single_product', 'woocommerce_output_related_products',10 );
  1971. add_action( 'woocommerce_after_single_product_summary', 'avia_woocommerce_output_related_products', 20 );
  1972.  
  1973.  
  1974. if( ! function_exists( 'avia_woocommerce_output_upsells' ) )
  1975. {
  1976. /**
  1977. *
  1978. * @since ????
  1979. * @param int|false $items
  1980. * @param int|false $columns
  1981. * @return string
  1982. */
  1983. function avia_woocommerce_output_upsells( $items = false, $columns = false )
  1984. {
  1985. global $avia_config;
  1986.  
  1987. $output = '';
  1988.  
  1989. if( ! $items )
  1990. {
  1991. $items = $avia_config['shop_single_column_items'];
  1992. }
  1993.  
  1994. if( ! $columns )
  1995. {
  1996. $columns = $avia_config['shop_single_column'];
  1997. }
  1998.  
  1999. ob_start();
  2000. woocommerce_upsell_display( $items,$columns); // 4 products, 4 columns
  2001. $content = ob_get_clean();
  2002.  
  2003. if( $content)
  2004. {
  2005. $output .= "<div class='product_column product_column_{$columns}'>";
  2006. // $output .= '<h3>'.( __( 'You may also like', 'avia_framework' ) ).'</h3>';
  2007. $output .= $content;
  2008. $output .= '</div>';
  2009. }
  2010.  
  2011. $avia_config['woo_upsells'] = $output;
  2012. return $output;
  2013. }
  2014. }
  2015.  
  2016. // display upsells and related products within dedicated div with different column and number of products
  2017. remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
  2018. remove_action( 'woocommerce_after_single_product', 'woocommerce_upsell_display',10 );
  2019. add_action( 'woocommerce_after_single_product_summary', 'avia_woocommerce_output_upsells', 21 ); // needs to be called after the 'related product' function to inherit columns and product count
  2020.  
  2021.  
  2022. if( ! function_exists( 'avia_woocommerce_display_output_upsells' ) )
  2023. {
  2024. /**
  2025. *
  2026. * @since ????
  2027. */
  2028. function avia_woocommerce_display_output_upsells()
  2029. {
  2030. global $avia_config;
  2031.  
  2032. $sells = isset( $avia_config['woo_upsells'] ) ? $avia_config['woo_upsells'] : '';
  2033. $related = isset( $avia_config['woo_related'] ) ? $avia_config['woo_related'] : '';
  2034.  
  2035. $products = $sells . $related;
  2036.  
  2037. if( ! empty( $products ) )
  2038. {
  2039. $output = '</div></div></div>';
  2040. $output .= '<div id="av_section_1" class="avia-section alternate_color avia-section-small container_wrap fullsize"><div class="container"><div class="template-page content twelve alpha units">';
  2041. $output .= $products;
  2042.  
  2043. echo $output;
  2044. }
  2045. }
  2046. }
  2047.  
  2048. add_action( 'woocommerce_after_single_product_summary', 'avia_woocommerce_display_output_upsells', 30 ); //display the related products and upsells
  2049.  
  2050.  
  2051. if( ! function_exists( 'avia_before_get_sidebar_template_builder' ) && avia_woocommerce_enabled() )
  2052. {
  2053. /**
  2054. * Single Product page on ALB: we need to change sidebar - otherwise we have blog or page resulting in a wrong output
  2055. *
  2056. * @since 4.5.5
  2057. */
  2058. function avia_before_get_sidebar_template_builder()
  2059. {
  2060. global $avia_config;
  2061.  
  2062. if( is_product() )
  2063. {
  2064. $avia_config['currently_viewing'] = 'shop_single';
  2065. }
  2066. else if( is_page ( wc_get_page_id( 'shop' ) ) )
  2067. {
  2068. $avia_config['currently_viewing'] = 'shop';
  2069. }
  2070. }
  2071. }
  2072.  
  2073. add_action( 'ava_before_get_sidebar_template_builder', 'avia_before_get_sidebar_template_builder', 10 );
  2074.  
  2075.  
  2076. if( ! function_exists( 'avia_add_image_div' ) )
  2077. {
  2078. /**
  2079. * wrap single product image in an extra div
  2080. *
  2081. * @since ????
  2082. */
  2083. function avia_add_image_div()
  2084. {
  2085. $nolightbox = '';
  2086. $icon = '';
  2087.  
  2088. if( avia_woocommerce_version_check( '3.0.0' ) )
  2089. {
  2090. if( current_theme_supports( 'wc-product-gallery-lightbox' ) )
  2091. {
  2092. $nolightbox = 'noLightbox';
  2093. }
  2094. else if( current_theme_supports( 'avia-wc-30-product-gallery-feature' ) )
  2095. {
  2096. $nolightbox = 'noHover';
  2097.  
  2098. /**
  2099. * WooCommerce limits sizes attribute to selected image size.
  2100. *
  2101. * @since 5.6
  2102. * @param boolean $use_max_image_size
  2103. * @return boolean
  2104. */
  2105. $ignore = true === apply_filters( 'avf_wc_30_gallery_lightbox_use_max_image_size', true ) ? 'av-remove-size-attr' : '';
  2106.  
  2107. $icon = "<div class='avia-wc-30-product-gallery-lightbox {$ignore}' " . av_icon_string( 'search' ) . "></div>";
  2108. }
  2109. }
  2110.  
  2111. echo '<div class="' . $nolightbox . ' single-product-main-image alpha">' . $icon;
  2112. }
  2113. }
  2114.  
  2115. add_action( 'woocommerce_before_single_product_summary', 'avia_add_image_div', 2 );
  2116.  
  2117.  
  2118. if( ! function_exists( 'avia_close_image_div' ) )
  2119. {
  2120. /**
  2121. * wrap single product image in an extra div
  2122. *
  2123. * @since ????
  2124. */
  2125. function avia_close_image_div()
  2126. {
  2127. global $avia_config;
  2128.  
  2129. if( is_product() )
  2130. {
  2131. $avia_config['currently_viewing'] = 'shop_single';
  2132. get_sidebar();
  2133. }
  2134.  
  2135. echo '</div>';
  2136. }
  2137. }
  2138.  
  2139. add_action( 'woocommerce_before_single_product_summary', 'avia_close_image_div', 20 );
  2140.  
  2141.  
  2142. if( ! function_exists( 'avia_add_summary_div' ) )
  2143. {
  2144. /**
  2145. * wrap single product summary in an extra div
  2146. *
  2147. * @since ????
  2148. */
  2149. function avia_add_summary_div()
  2150. {
  2151. echo '<div class="single-product-summary">';
  2152. }
  2153. }
  2154.  
  2155. add_action( 'woocommerce_before_single_product_summary', 'avia_add_summary_div', 25 );
  2156. add_action( 'woocommerce_after_single_product_summary', 'avia_close_div', 3 );
  2157.  
  2158.  
  2159. if( ! function_exists( 'avia_product_gallery_thumbnail_opener' ) )
  2160. {
  2161. /**
  2162. * @since ????
  2163. */
  2164. function avia_product_gallery_thumbnail_opener()
  2165. {
  2166. echo '<div class="thumbnails">';
  2167. }
  2168. }
  2169.  
  2170. if( avia_woocommerce_version_check( '3.0.0' ) ) // in woocommerce 3.0.0
  2171. {
  2172. add_action( 'woocommerce_product_thumbnails', 'avia_product_gallery_thumbnail_opener', 19 );
  2173. add_action( 'woocommerce_product_thumbnails', 'avia_close_div', 21 );
  2174. }
  2175.  
  2176.  
  2177. if( ! function_exists( 'avia_woocommerce_frontend_search_params' ) )
  2178. {
  2179. /**
  2180. * Displays a front end interface for modifying the shoplist query parameters like sorting order, product count etc
  2181. *
  2182. * @since < 4.0
  2183. */
  2184. function avia_woocommerce_frontend_search_params()
  2185. {
  2186. global $avia_config;
  2187.  
  2188. if( ! empty( $avia_config['woocommerce']['disable_sorting_options'] ) )
  2189. {
  2190. return;
  2191. }
  2192.  
  2193. $product_order = array();
  2194. $product_sort = array();
  2195. $params = array();
  2196.  
  2197. $product_order['default'] = __( 'Default', 'avia_framework' );
  2198. $product_order['menu_order'] = __( 'Custom', 'avia_framework' );
  2199. $product_order['title'] = __( 'Name', 'avia_framework' );
  2200. $product_order['price'] = __( 'Price', 'avia_framework' );
  2201. $product_order['date'] = __( 'Date', 'avia_framework' );
  2202. $product_order['popularity'] = __( 'Popularity (sales)', 'avia_framework' );
  2203. $product_order['rating'] = __( 'Average rating', 'avia_framework' );
  2204. $product_order['relevance'] = __( 'Relevance', 'avia_framework' );
  2205. $product_order['rand'] = __( 'Random', 'avia_framework' );
  2206. $product_order['id'] = __( 'Product ID', 'avia_framework' );
  2207.  
  2208. /**
  2209. *
  2210. * @since 4.5.6.2
  2211. * @param array $product_order
  2212. * @return array
  2213. */
  2214. $product_order = apply_filters( 'avf_wc_product_order_dropdown_frontend', $product_order );
  2215.  
  2216. $product_sort['asc'] = __( 'Click to order products ascending', 'avia_framework' );
  2217. $product_sort['desc'] = __( 'Click to order products descending', 'avia_framework' );
  2218.  
  2219. $per_page_string = __( 'Products per page', 'avia_framework' );
  2220.  
  2221. $per_page = get_option( 'avia_woocommerce_product_count' );
  2222. if( ! $per_page )
  2223. {
  2224. $per_page = get_option( 'posts_per_page' );
  2225. }
  2226.  
  2227. /**
  2228. * ALB elements can return all elements = -1
  2229. */
  2230. if( ! empty( $avia_config['woocommerce']['default_posts_per_page'] ) && is_numeric( $avia_config['woocommerce']['default_posts_per_page'] ) )
  2231. {
  2232. if( $avia_config['woocommerce']['default_posts_per_page'] > 0 )
  2233. {
  2234. $per_page = $avia_config['woocommerce']['default_posts_per_page'];
  2235. }
  2236. }
  2237.  
  2238. parse_str( $_SERVER['QUERY_STRING'], $params );
  2239.  
  2240. if( ! isset( $params['product_order'] ) )
  2241. {
  2242. $po_key = 'default';
  2243. }
  2244. else
  2245. {
  2246. $po_key = $params['product_order'];
  2247. }
  2248.  
  2249. if( ! isset( $params['product_sort'] ) )
  2250. {
  2251. $ps_key = ! empty( $avia_config['woocommerce']['product_sort'] ) ? $avia_config['woocommerce']['product_sort'] : 'asc';
  2252. }
  2253. else
  2254. {
  2255. $ps_key = $params['product_sort'];
  2256. }
  2257.  
  2258. if( 'default' == $po_key )
  2259. {
  2260. unset( $params['product_sort'] );
  2261. }
  2262.  
  2263. $params['avia_extended_shop_select'] = 'yes';
  2264.  
  2265. // $po_key = ! empty( $avia_config['woocommerce']['product_order'] ) ? $avia_config['woocommerce']['product_order'] : $params['product_order'];
  2266. // $ps_key = ! empty( $avia_config['woocommerce']['product_sort'] ) ? $avia_config['woocommerce']['product_sort'] : $params['product_sort'];
  2267. $pc_key = ! empty( $avia_config['woocommerce']['product_count'] ) ? $avia_config['woocommerce']['product_count'] : $per_page;
  2268.  
  2269. $ps_key = strtolower( $ps_key );
  2270.  
  2271. $show_sort = ! in_array( $po_key, array( 'rand', 'popularity', 'rating', 'default' ) );
  2272.  
  2273. $nofollow = 'rel="nofollow"';
  2274.  
  2275. //generate markup
  2276. $output = '';
  2277. $output .= '<div class="product-sorting">';
  2278. $output .= '<ul class="sort-param sort-param-order">';
  2279. $output .= "<li><span class='currently-selected'>" . __( 'Sort by', 'avia_framework' ) . " <strong>{$product_order[$po_key]}</strong></span>";
  2280. $output .= '<ul>';
  2281.  
  2282. foreach ( $product_order as $order_key => $order_text )
  2283. {
  2284. $query_string = 'default' == $order_key ? avia_woo_build_query_string( $params, 'product_order', $order_key, 'product_sort' ) : avia_woo_build_query_string( $params, 'product_order', $order_key );
  2285.  
  2286. $output .= '<li' . avia_woo_active_class( $po_key, $order_key ) . '>';
  2287. $output .= "<a href='{$query_string}' {$nofollow}>";
  2288. $output .= "<span class='avia-bullet'></span>{$order_text}";
  2289. $output .= '</a>';
  2290. $output .= '</li>';
  2291. }
  2292.  
  2293. $output .= '</ul>';
  2294. $output .= '</li>';
  2295. $output .= '</ul>';
  2296.  
  2297. if( $show_sort )
  2298. {
  2299. $output .= '<ul class="sort-param sort-param-sort">';
  2300. $output .= '<li>';
  2301.  
  2302. if( $ps_key == 'desc' )
  2303. {
  2304. $output .= "<a title='{$product_sort['asc']}' class='sort-param-asc' href='" . avia_woo_build_query_string( $params, 'product_sort', 'asc' ) . "' {$nofollow}>{$product_sort['desc']}</a>";
  2305. }
  2306. if( $ps_key == 'asc' )
  2307. {
  2308. $output .= "<a title='{$product_sort['desc']}' class='sort-param-desc' href='" . avia_woo_build_query_string( $params, 'product_sort', 'desc' ) . "' {$nofollow}>{$product_sort['asc']}</a>";
  2309. }
  2310.  
  2311. $output .= '</li>';
  2312. $output .= '</ul>';
  2313. }
  2314.  
  2315. if( ! isset( $avia_config['woocommerce']['default_posts_per_page'] ) || ( $avia_config['woocommerce']['default_posts_per_page'] > 0 ) )
  2316. {
  2317. $output .= "<ul class='sort-param sort-param-count'>";
  2318. $output .= "<li><span class='currently-selected'>" . __( 'Display', 'avia_framework' ) . " <strong>{$pc_key} {$per_page_string} </strong></span>";
  2319. $output .= '<ul>';
  2320. $output .= '<li' . avia_woo_active_class( $pc_key, $per_page ) . "><a href='" . avia_woo_build_query_string( $params, 'product_count', $per_page ) . "' {$nofollow}> <span class='avia-bullet'></span>{$per_page} {$per_page_string}</a></li>";
  2321. $output .= '<li' . avia_woo_active_class( $pc_key, $per_page * 2 ) . "><a href='" . avia_woo_build_query_string( $params, 'product_count', $per_page * 2 ) . "' {$nofollow}> <span class='avia-bullet'></span>" . ( $per_page * 2 ) . " {$per_page_string}</a></li>";
  2322. $output .= '<li' . avia_woo_active_class( $pc_key, $per_page * 3 ) . "><a href='" . avia_woo_build_query_string( $params, 'product_count', $per_page * 3 ) . "' {$nofollow}> <span class='avia-bullet'></span>" . ( $per_page * 3 ) . " {$per_page_string}</a></li>";
  2323. $output .= '</ul>';
  2324. $output .= '</li>';
  2325. $output .= '</ul>';
  2326. }
  2327.  
  2328. $output .= '</div>';
  2329.  
  2330. echo $output;
  2331. }
  2332. }
  2333.  
  2334. add_action( 'woocommerce_before_shop_loop', 'avia_woocommerce_frontend_search_params', 20 );
  2335.  
  2336.  
  2337. if( ! function_exists( 'avia_woocommerce_ajax_search_params' ) )
  2338. {
  2339. /**
  2340. * Add support for WC product display settings
  2341. *
  2342. * @since 4.7.3.1
  2343. * @param array|string $params
  2344. * @return array
  2345. */
  2346. function avia_woocommerce_ajax_search_params( $params = array() )
  2347. {
  2348. if( ! avia_woocommerce_enabled() )
  2349. {
  2350. return $params;
  2351. }
  2352.  
  2353. if( ! avia_woocommerce_version_check( '3.0.0' ) )
  2354. {
  2355. return $params;
  2356. }
  2357.  
  2358. /**
  2359. *
  2360. * @since 4.7.3.1
  2361. * @param string $visibility 'show'|'hide'|'' for WC default
  2362. * @param string $context
  2363. * @return string 'show'|'hide'|'' for WC default
  2364. */
  2365. $products_visibility = apply_filters( 'avf_ajax_search_woocommerce_params', '', 'out_of_stock' );
  2366.  
  2367. /**
  2368. *
  2369. * @since 4.7.3.1
  2370. * @param string $visibility 'show'|'hide'|'' for WC default
  2371. * @param string $context
  2372. * @return string 'show'|'hide'|'' for all
  2373. */
  2374. $prod_hidden = apply_filters( 'avf_ajax_search_woocommerce_params', '', 'hidden_products' );
  2375.  
  2376. /**
  2377. *
  2378. * @since 4.7.3.1
  2379. * @param string $visibility 'show'|'hide'|'' for WC default
  2380. * @param string $context
  2381. * @return string 'show'|'hide'|'' for all
  2382. */
  2383. $prod_featured = apply_filters( 'avf_ajax_search_woocommerce_params', '', 'featured_products' );
  2384.  
  2385. // Meta query - replaced by Tax query in WC 3.0.0
  2386. $meta_query = array();
  2387. $tax_query = array();
  2388.  
  2389. avia_wc_set_out_of_stock_query_params( $meta_query, $tax_query, $products_visibility );
  2390. avia_wc_set_hidden_prod_query_params( $meta_query, $tax_query, $prod_hidden );
  2391. avia_wc_set_featured_prod_query_params( $meta_query, $tax_query, $prod_featured );
  2392.  
  2393. if( empty( $tax_query ) || ! is_array( $tax_query ) )
  2394. {
  2395. return $params;
  2396. }
  2397.  
  2398. // Plugins might render a query string -> transform to array
  2399. $params = wp_parse_args( $params );
  2400.  
  2401. if( ! isset( $params['tax_query'] ) || ! is_array( $params['tax_query'] ) )
  2402. {
  2403. $params['tax_query'] = array();
  2404. }
  2405.  
  2406. foreach( $tax_query as $value )
  2407. {
  2408. $params['tax_query'][] = $value;
  2409. }
  2410.  
  2411. return $params;
  2412. }
  2413. }
  2414.  
  2415. add_filter( 'avf_ajax_search_query', 'avia_woocommerce_ajax_search_params', 20, 1 );
  2416.  
  2417.  
  2418. if( ! function_exists( 'avia_woo_active_class' ) )
  2419. {
  2420. /**
  2421. * Helper function to create the active list class
  2422. *
  2423. * @since ????
  2424. * @param string $key1
  2425. * @param string $key2
  2426. * @return string
  2427. */
  2428. function avia_woo_active_class( $key1, $key2 )
  2429. {
  2430. return ( $key1 == $key2 ) ? ' class="current-param"' : '';
  2431. }
  2432. }
  2433.  
  2434. if( ! function_exists( 'avia_woo_build_query_string' ) )
  2435. {
  2436. /**
  2437. * helper function to build the query strings for the catalog ordering menu
  2438. *
  2439. * @since < 4.0
  2440. * @param array $params
  2441. * @param string $overwrite_key
  2442. * @param string $overwrite_value
  2443. * @param string $remove_key
  2444. * @return string
  2445. */
  2446. function avia_woo_build_query_string( $params = array(), $overwrite_key = '', $overwrite_value = '', $remove_key = '' )
  2447. {
  2448. if( ! empty( $overwrite_key ) )
  2449. {
  2450. $params[ $overwrite_key ] = $overwrite_value;
  2451. }
  2452.  
  2453. if( ! empty( $remove_key ) )
  2454. {
  2455. unset( $params[ $remove_key ] );
  2456. }
  2457.  
  2458. $paged = ( array_key_exists( 'product_count', $params ) ) ? 'paged=1&' : '';
  2459.  
  2460. return '?' . $paged . http_build_query( $params );
  2461. }
  2462. }
  2463.  
  2464.  
  2465. if( ! function_exists( 'avia_woocommerce_overwrite_catalog_ordering' ) )
  2466. {
  2467. /**
  2468. * Overwrite the query parameters from WooCommerce
  2469. *
  2470. * @since < 4.0
  2471. * @param array $args
  2472. * @return string
  2473. */
  2474. function avia_woocommerce_overwrite_catalog_ordering( $args )
  2475. {
  2476. global $avia_config;
  2477.  
  2478. if( empty( $avia_config['woocommerce'] ) )
  2479. {
  2480. $avia_config['woocommerce'] = array();
  2481. }
  2482.  
  2483. if( ! empty( $avia_config['woocommerce']['disable_sorting_options'] ) )
  2484. {
  2485. return $args;
  2486. }
  2487.  
  2488. /**
  2489. * WC added shortcodes that use this filter (e.g. products).
  2490. * We only need to alter the query when we have our select boxes.
  2491. *
  2492. * LIMITATION: It is not possible to mix shop overview (= shop) and other shortcodes because we cannot distinguish when this filter is called !!!
  2493. */
  2494. if( ! isset( $_REQUEST['avia_extended_shop_select'] ) || ( 'yes' != $_REQUEST['avia_extended_shop_select'] ) )
  2495. {
  2496. $avia_config['woocommerce']['product_sort'] = strtolower( $args['order'] );
  2497. $avia_config['woocommerce']['product_order'] = strtolower( $args['orderby'] );
  2498.  
  2499. return $args;
  2500. }
  2501.  
  2502. //check the folllowing get parameters and session vars. if they are set overwrite the defaults
  2503. $check = array( 'product_order', 'product_count', 'product_sort' );
  2504.  
  2505. foreach( $check as $key )
  2506. {
  2507. if( isset( $_GET[ $key ] ) )
  2508. {
  2509. $_SESSION['avia_woocommerce'][ $key ] = esc_attr( $_GET[ $key ] );
  2510. }
  2511. if( isset( $_SESSION['avia_woocommerce'][ $key ] ) )
  2512. {
  2513. $avia_config['woocommerce'][ $key ] = $_SESSION['avia_woocommerce'][ $key ];
  2514. }
  2515. }
  2516.  
  2517. // if user wants to use new product order remove the old sorting parameter
  2518. if( isset( $_GET['product_order'] ) && ! isset( $_GET['product_sort'] ) && isset( $_SESSION['avia_woocommerce']['product_sort'] ) )
  2519. {
  2520. unset( $_SESSION['avia_woocommerce']['product_sort'], $avia_config['woocommerce']['product_sort'] );
  2521. }
  2522.  
  2523. $orderby = '';
  2524. $order = '';
  2525.  
  2526. /**
  2527. * Set the product sorting
  2528. */
  2529. $product_sort = '';
  2530. if( isset( $avia_config['woocommerce']['product_sort'] ) )
  2531. {
  2532. $product_sort = strtoupper( $avia_config['woocommerce']['product_sort'] );
  2533. switch ( $product_sort )
  2534. {
  2535. case 'DESC':
  2536. case 'ASC':
  2537. break;
  2538. default:
  2539. $product_sort = 'ASC';
  2540. break;
  2541. }
  2542. }
  2543.  
  2544. /**
  2545. * Set the product order with default sortings
  2546. */
  2547. $product_order = isset( $avia_config['woocommerce']['product_order'] ) ? $avia_config['woocommerce']['product_order'] :'';
  2548. switch ( $product_order )
  2549. {
  2550. case 'id':
  2551. case 'relevance':
  2552. case 'date':
  2553. $orderby = $product_order;
  2554. $order = ! empty( $product_sort ) ? $product_sort : 'DESC';
  2555. break;
  2556. case 'menu_order':
  2557. case 'title' :
  2558. case 'price' :
  2559. $orderby = $product_order;
  2560. $order = ! empty( $product_sort ) ? $product_sort : 'ASC';
  2561. break;
  2562. case 'rand':
  2563. case 'popularity':
  2564. case 'rating':
  2565. $orderby = $product_order;
  2566. break;
  2567. case 'default':
  2568. default:
  2569. $orderby = '';
  2570. break;
  2571. }
  2572.  
  2573. WC()->query->remove_ordering_args();
  2574.  
  2575. $old_disable_sorting_options = isset( $avia_config['woocommerce']['disable_sorting_options'] ) ? $avia_config['woocommerce']['disable_sorting_options'] : null;
  2576. $avia_config['woocommerce']['disable_sorting_options'] = true;
  2577.  
  2578. $new_args = WC()->query->get_catalog_ordering_args( $orderby, $order );
  2579.  
  2580. if( ! is_null( $old_disable_sorting_options) )
  2581. {
  2582. $avia_config['woocommerce']['disable_sorting_options'] = $old_disable_sorting_options;
  2583. }
  2584. else
  2585. {
  2586. unset( $avia_config['woocommerce']['disable_sorting_options'] );
  2587. }
  2588.  
  2589. /**
  2590. * set the product count
  2591. */
  2592. if( isset( $avia_config['woocommerce']['product_count'] ) && is_numeric( $avia_config['woocommerce']['product_count'] ) )
  2593. {
  2594. $avia_config['shop_overview_products_overwritten'] = true;
  2595. $avia_config['shop_overview_products'] = (int) $avia_config['woocommerce']['product_count'];
  2596. }
  2597.  
  2598. $avia_config['woocommerce']['product_order'] = strtolower( $new_args['orderby'] );
  2599. $avia_config['woocommerce']['product_sort'] = strtolower( $new_args['order'] );
  2600.  
  2601. return $new_args;
  2602. }
  2603. }
  2604.  
  2605. add_action( 'woocommerce_get_catalog_ordering_args', 'avia_woocommerce_overwrite_catalog_ordering', 20, 1 );
  2606.  
  2607.  
  2608. if( ! function_exists( 'avia_woocommerce_remove_hooks' ) )
  2609. {
  2610. /**
  2611. * remove product information on password protected products
  2612. *
  2613. * @since ????
  2614. */
  2615. function avia_woocommerce_remove_hooks()
  2616. {
  2617. /*remove content from password protected products*/
  2618. if( post_password_required() )
  2619. {
  2620. add_action( 'woocommerce_after_single_product_summary', 'avia_woocommerce_echo_password', 1 );
  2621.  
  2622. remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 1 );
  2623. remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
  2624. remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 20 );
  2625. remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_meta', 40 );
  2626. remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_sharing', 50 );
  2627. remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 20 );
  2628. remove_action( 'woocommerce_product_thumbnails', 'woocommerce_show_product_thumbnails', 20 );
  2629. remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 10 );
  2630. remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
  2631. remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 );
  2632. remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10 );
  2633. remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
  2634. remove_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
  2635. remove_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
  2636. remove_action( 'woocommerce_variable_add_to_cart', 'woocommerce_variable_add_to_cart', 30 );
  2637. remove_action( 'woocommerce_external_add_to_cart', 'woocommerce_external_add_to_cart', 30 );
  2638. remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
  2639. remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
  2640. remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10 );
  2641. remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_rating', 5 );
  2642. remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10 );
  2643. }
  2644. }
  2645. }
  2646.  
  2647. add_action( 'woocommerce_before_single_product', 'avia_woocommerce_remove_hooks' );
  2648.  
  2649.  
  2650. if( ! function_exists( 'avia_woocommerce_echo_password' ) )
  2651. {
  2652. /**
  2653. * remove content from password protected products
  2654. *
  2655. * @since ????
  2656. */
  2657. function avia_woocommerce_echo_password()
  2658. {
  2659. if( post_password_required() )
  2660. {
  2661. echo get_the_password_form();
  2662. }
  2663. }
  2664. }
  2665.  
  2666. add_action( 'ava_woocomemrce_password_protection_remove_hooks', 'avia_woocommerce_remove_hooks' );
  2667.  
  2668.  
  2669. if( ! function_exists( 'avia_woocommerce_product_gallery_support' ) )
  2670. {
  2671. /**
  2672. * @since ????
  2673. */
  2674. function avia_woocommerce_product_gallery_support()
  2675. {
  2676. if( avia_woocommerce_version_check( '3.0.0' ) && current_theme_supports( 'avia-wc-30-product-gallery-feature' ) )
  2677. {
  2678. remove_action( 'woocommerce_product_thumbnails', 'avia_product_gallery_thumbnail_opener', 19 );
  2679. remove_action( 'woocommerce_product_thumbnails', 'avia_close_div', 21 );
  2680. }
  2681. else
  2682. {
  2683. add_filter( 'woocommerce_single_product_image_thumbnail_html', 'avia_woocommerce_gallery_thumbnail_description', 10, 4 );
  2684. }
  2685. }
  2686. }
  2687.  
  2688. if( did_action( 'woocommerce_init' ) )
  2689. {
  2690. avia_woocommerce_product_gallery_support();
  2691. }
  2692. else
  2693. {
  2694. add_action( 'woocommerce_init', 'avia_woocommerce_product_gallery_support', 50 );
  2695. }
  2696.  
  2697.  
  2698. if( ! function_exists( 'avia_woocommerce_set_single_page_image_size' ) )
  2699. {
  2700. /**
  2701. * single page big image and thumbnails are using the same filter now.
  2702. * therefore we need to make sure that the images get the correct size by storing once the
  2703. * woocommerce_product_thumbnails action has been called
  2704. *
  2705. * @since ????
  2706. */
  2707. function avia_woocommerce_set_single_page_image_size()
  2708. {
  2709. global $avia_config;
  2710.  
  2711. if( ! isset( $avia_config['avwc-single-page-size'] ) )
  2712. {
  2713. $avia_config['avwc-single-page-size'] = 'shop_thumbnail';
  2714. }
  2715. }
  2716. }
  2717.  
  2718. add_action( 'woocommerce_product_thumbnails', 'avia_woocommerce_set_single_page_image_size' );
  2719.  
  2720.  
  2721. if( ! function_exists( 'avia_woocommerce_gallery_thumbnail_description' ) )
  2722. {
  2723. /**
  2724. * Wrap images for lightbox support
  2725. *
  2726. * @since ???
  2727. * @since 5.0.1 support responsive images for lightbox
  2728. * @param string $img
  2729. * @param int $attachment_id
  2730. * @param int $post_id
  2731. * @param string $image_class
  2732. * @return string
  2733. */
  2734. function avia_woocommerce_gallery_thumbnail_description( $img, $attachment_id, $post_id = '', $image_class = '' )
  2735. {
  2736. global $avia_config;
  2737.  
  2738. $image_size = isset( $avia_config['avwc-single-page-size'] ) ? $avia_config['avwc-single-page-size'] : 'shop_single';
  2739.  
  2740. $image = wp_get_attachment_image( $attachment_id, apply_filters( 'single_product_small_thumbnail_size', $image_size ) );
  2741.  
  2742. if( empty( $image ) )
  2743. {
  2744. return $img;
  2745. }
  2746.  
  2747. $image_title = esc_attr( get_post_field( 'post_content', $attachment_id ) );
  2748.  
  2749. // get responsive lightbox image
  2750. $link = AviaHelper::get_url( 'lightbox', $attachment_id, true );
  2751. $lightbox_attr = Av_Responsive_Images()->html_attr_image_src( $link, false );
  2752.  
  2753. $new_img = '';
  2754. $new_img .= "<a {$lightbox_attr} class='{$image_class}' title='{$image_title}' rel='prettyPhoto[product-gallery]'>";
  2755. $new_img .= $image;
  2756. $new_img .= '</a>';
  2757.  
  2758. return $new_img;
  2759. }
  2760. }
  2761.  
  2762.  
  2763. if( ! function_exists( 'avia_title_args_woopage' ) )
  2764. {
  2765. /**
  2766. *
  2767. * @since ????
  2768. * @param array $args
  2769. * @param int $id
  2770. * @return array
  2771. */
  2772. function avia_title_args_woopage( $args, $id )
  2773. {
  2774. if( is_single() && is_product() )
  2775. {
  2776. $args['heading'] = 'strong';
  2777. }
  2778.  
  2779. return $args;
  2780. }
  2781. }
  2782.  
  2783. add_filter( 'avf_title_args', 'avia_title_args_woopage', 10, 2 );
  2784.  
  2785.  
  2786. if( ! function_exists( 'avia_woocommerce_default_page' ) )
  2787. {
  2788. /**
  2789. * Function that is able to overwrite the default 'shop' page used by woocommerce so the template builder can be used
  2790. * Will only be executed if the user has switched the 'shop' page to advanced layout builder. Default products are no longer displayed
  2791. * and the user needs to add a product grid element
  2792. *
  2793. * Can be activated by adding to your functions.php file:
  2794. *
  2795. * add_theme_support( 'avia_custom_shop_page' );
  2796. *
  2797. * @since ????
  2798. * @param WP_Query $query
  2799. * @return WP_Query
  2800. */
  2801. function avia_woocommerce_default_page( $query )
  2802. {
  2803. if( current_theme_supports( 'avia_custom_shop_page' ) )
  2804. {
  2805. if( isset( $_REQUEST['s'] ) )
  2806. {
  2807. return $query;
  2808. }
  2809.  
  2810. if( ! $query->is_admin && $query->is_main_query() && ! $query->is_tax && $query->is_archive && $query->is_post_type_archive )
  2811. {
  2812. $vars = $query->query_vars;
  2813.  
  2814. if( isset( $vars['post_type'] ) && 'product' == $vars['post_type'] )
  2815. {
  2816. $shop_page_id = wc_get_page_id( 'shop' );
  2817. $builder_active = Avia_Builder()->get_alb_builder_status( $shop_page_id );
  2818.  
  2819. if( $builder_active == 'active' )
  2820. {
  2821. $query->set( 'post_type', 'page' );
  2822. $query->set( 'p', $shop_page_id );
  2823. $query->set( 'meta_query', array() );
  2824.  
  2825. $query->is_singular = true;
  2826. $query->is_page = true;
  2827. $query->is_archive = false;
  2828. $query->is_post_type_archive = false;
  2829. $query->query = array( 'p' => $shop_page_id, 'post_type' => 'page' );
  2830. }
  2831. }
  2832. }
  2833. }
  2834.  
  2835. return $query;
  2836. }
  2837. }
  2838.  
  2839. add_filter( 'pre_get_posts', 'avia_woocommerce_default_page' );
  2840.  
  2841.  
  2842. if( ! function_exists( 'avia_woocommerce_disable_editor' ) )
  2843. {
  2844. /**
  2845. * Add info to backend shop page and product edit page
  2846. *
  2847. * @since ????
  2848. * @param array $params
  2849. * @return array
  2850. */
  2851. function avia_woocommerce_disable_editor( $params )
  2852. {
  2853. if( ! current_theme_supports( 'avia_custom_shop_page' ) )
  2854. {
  2855. global $post_ID;
  2856.  
  2857. $shop_page_id = wc_get_page_id( 'shop' );
  2858.  
  2859. if( $post_ID == $shop_page_id )
  2860. {
  2861. $disabled = __( '(disabled)', 'avia_framework' );
  2862.  
  2863. $params['visual_label'] = $params['visual_label'] . ' ' . $disabled;
  2864. $params['default_label'] = $params['default_label'] . ' ' . $disabled;
  2865. $params['button_class'] = 'av-builder-button-disabled';
  2866. $params['disabled'] = true;
  2867. $params['note'] = __( 'This page is set as the default WooCommerce Shop Overview and therefore does not support the Enfold advanced layout editor', 'avia_framework' ) . " <br/><a href='https://kriesi.at/documentation/enfold/custom-woocommerce-shop-overview/' target='_blank' rel='noopener noreferrer'>(" . __( 'Learn more', 'avia_framework' ) . ')</a>';
  2868. }
  2869. }
  2870.  
  2871. if( avia_backend_get_post_type() == 'product' )
  2872. {
  2873. $params['noteclass'] = 'av-notice av-only-active';
  2874. $params['note'] = __( 'Please note that the Advanced Layout Builder for products will not work with all WooCommerce Extensions', 'avia_framework' );
  2875. }
  2876.  
  2877. return $params;
  2878. }
  2879. }
  2880.  
  2881. add_filter( 'avf_builder_button_params', 'avia_woocommerce_disable_editor' );
  2882.  
  2883.  
  2884. if( ! function_exists( 'avia_woocommerce_disable_editor_option' ) )
  2885. {
  2886. /**
  2887. *
  2888. * @since ????
  2889. * @param boolean $params
  2890. * @param int $post_id
  2891. * @return boolean
  2892. */
  2893. function avia_woocommerce_disable_editor_option( $params, $post_id )
  2894. {
  2895. if( ! current_theme_supports( 'avia_custom_shop_page' ) )
  2896. {
  2897. if( $post_id == wc_get_page_id( 'shop' ) )
  2898. {
  2899. $params = false;
  2900. }
  2901. }
  2902.  
  2903. return $params;
  2904. }
  2905. }
  2906.  
  2907. add_filter( 'avf_builder_active', 'avia_woocommerce_disable_editor_option', 10, 2 );
  2908.  
  2909.  
  2910. if( ! function_exists( 'avia_woocommerce_cart_placement' ) )
  2911. {
  2912. /**
  2913. * Place the cart button according to the header layout (top/sidebar)
  2914. *
  2915. * @since ????
  2916. */
  2917. function avia_woocommerce_cart_placement()
  2918. {
  2919. $cart_pos = avia_get_option( 'cart_icon', '' );
  2920.  
  2921. if( 'no_cart' == $cart_pos )
  2922. {
  2923. return;
  2924. }
  2925.  
  2926. $position = avia_get_option( 'header_position', 'header_top' ) == 'header_top' ? 'ava_main_header' : 'ava_inside_main_menu';
  2927.  
  2928. if( $cart_pos == 'always_display_menu' )
  2929. {
  2930. $position = 'ava_inside_main_menu';
  2931. if( strpos( avia_get_option( 'header_layout' ), 'bottom_nav_header' ) !== false && avia_get_option( 'header_position' ) == 'header_top' )
  2932. {
  2933. $position = 'ava_before_bottom_main_menu';
  2934. }
  2935. }
  2936.  
  2937. add_action( $position, 'avia_woocommerce_cart_dropdown', 10 );
  2938. }
  2939. }
  2940.  
  2941. add_action( 'init', 'avia_woocommerce_cart_placement', 10 );
  2942.  
  2943.  
  2944. if( ! function_exists( 'avia_woocommerce_cart_pos' ) )
  2945. {
  2946. /**
  2947. * Permanent display of cart button
  2948. *
  2949. * @since ????
  2950. * @param array $class
  2951. * @param array $necessary
  2952. * @param string $prefix
  2953. * @return array
  2954. */
  2955. function avia_woocommerce_cart_pos( $class, $necessary, $prefix )
  2956. {
  2957. $cart_pos = avia_get_option( 'cart_icon', '' );
  2958.  
  2959. if( 'no_cart' == $cart_pos )
  2960. {
  2961. return $class;
  2962. }
  2963.  
  2964. if( $prefix == 'html_' ) // only for the html tag
  2965. {
  2966. $cart = WC()->cart instanceof WC_Cart ? WC()->cart->get_cart() : null;
  2967.  
  2968. if( $cart_pos == 'always_display' || ( ! empty( $cart ) ) )
  2969. {
  2970. $class[] = 'visible_cart';
  2971. }
  2972.  
  2973. if( $cart_pos == 'always_display_menu' )
  2974. {
  2975. $class[] = 'cart_at_menu';
  2976. }
  2977. }
  2978.  
  2979. return $class;
  2980. }
  2981. }
  2982.  
  2983. add_filter( 'avf_header_classes', 'avia_woocommerce_cart_pos', 10, 3 );
  2984.  
  2985.  
  2986. if( ! function_exists( 'avia_woocommerce_account_icon' ) )
  2987. {
  2988. /**
  2989. * Appends a user account icon before search icon
  2990. *
  2991. * @since 5.3
  2992. * @param string $items
  2993. * @param array $args
  2994. * @return string
  2995. */
  2996. function avia_woocommerce_account_icon ( $items, $args )
  2997. {
  2998. if( avia_get_option( 'shop_account_icon' ) == '' )
  2999. {
  3000. return $items;
  3001. }
  3002.  
  3003. if( avia_get_option( 'header_position', 'header_top' ) != 'header_top' )
  3004. {
  3005. return $items;
  3006. }
  3007.  
  3008. if( ( is_object( $args ) && $args->theme_location == 'avia' ) || ( is_string( $args ) && $args = 'fallback_menu' ) )
  3009. {
  3010. if( is_user_logged_in() )
  3011. {
  3012. $hidden_text = __( 'My Account', 'avia_framework' );
  3013. $aria_label = __( 'Account Page Link', 'avia_framework' );
  3014. }
  3015. else
  3016. {
  3017. $hidden_text = __( 'Login / Register', 'avia_framework' );
  3018. $aria_label = __( 'Login / Register Page Link', 'avia_framework' );
  3019. }
  3020.  
  3021. /**
  3022. * @since 5.3
  3023. * @param string $aria_label
  3024. * @param array $items
  3025. * @param stdClass $args
  3026. * @return string
  3027. */
  3028. $aria_label = apply_filters( 'avf_woocommerce_account_icon_aria_label', $aria_label, $items, $args );
  3029.  
  3030. $items .= '<li id="menu-item-wc-account-icon" class="noMobile menu-item menu-item-account-icon menu-item-avia-special" role="menuitem">';
  3031. $items .= '<a aria-label="' . $aria_label . '" href="' . get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ) . ' " title="' . $hidden_text . '" ' . av_icon_string( 'account', false ) . '>';
  3032. $items .= '<span class="avia_hidden_link_text">' . $aria_label . '</span>';
  3033. $items .= '</a>';
  3034. $items .= '</li>';
  3035. }
  3036.  
  3037. return $items;
  3038. }
  3039. }
  3040.  
  3041. // hook before search icon in main menu
  3042. add_filter( 'wp_nav_menu_items', 'avia_woocommerce_account_icon', 9995, 2 );
  3043. add_filter( 'avf_fallback_menu_items', 'avia_woocommerce_account_icon', 9995, 2 );
  3044.  
  3045.  
  3046. if( ! function_exists( 'avia_woocommerce_cart_dropdown' ) )
  3047. {
  3048. /**
  3049. * @since ????
  3050. */
  3051. function avia_woocommerce_cart_dropdown()
  3052. {
  3053. $cart_items = WC()->cart instanceof WC_Cart ? WC()->cart->get_cart_contents_count() : 0;
  3054. $cart_subtotal = WC()->cart instanceof WC_Cart ? WC()->cart->get_cart_subtotal() : 0;
  3055.  
  3056. // cart->get_cart_url() deprecated
  3057. $link = function_exists( 'wc_get_cart_url' ) ? wc_get_cart_url() : WC()->cart->get_cart_url();
  3058.  
  3059. $id = '';
  3060. $added = wc_get_notices( 'success' );
  3061. $trigger = ! empty( $added ) ? 'av-display-cart-on-load' : '';
  3062. $active = $cart_items > 0 ? 'av-active-counter' : '';
  3063.  
  3064. if( avia_get_option( 'cart_icon' ) == 'always_display_menu' )
  3065. {
  3066. $id = 'id="menu-item-shop"';
  3067. }
  3068.  
  3069.  
  3070. $output = '';
  3071. $output .= "<ul {$id} class = 'menu-item cart_dropdown {$trigger}' data-success='" . __( 'was added to the cart', 'avia_framework' ). "'>";
  3072. $output .= '<li class="cart_dropdown_first">';
  3073. $output .= "<a class='cart_dropdown_link' href='{$link}'>";
  3074. $output .= '<span ' . av_icon_string( 'cart' ) . '></span>';
  3075. $output .= "<span class='av-cart-counter {$active}'>{$cart_items}</span>";
  3076. $output .= '<span class="avia_hidden_link_text">' . __( 'Shopping Cart', 'avia_framework' ) . '</span>';
  3077. $output .= '</a>';
  3078. $output .= "<!--<span class='cart_subtotal'>{$cart_subtotal}</span>-->";
  3079. $output .= '<div class="dropdown_widget dropdown_widget_cart">';
  3080. $output .= '<div class="avia-arrow"></div>';
  3081. $output .= '<div class="widget_shopping_cart_content"></div>';
  3082. $output .= '</div>';
  3083. $output .= '</li>';
  3084. $output .= '</ul>';
  3085.  
  3086. echo $output;
  3087. }
  3088. }
  3089.  
  3090. if( ! function_exists( 'avia_woocommerce_add_to_cart_fragments' ) )
  3091. {
  3092. /**
  3093. * @since 4.7.6.3
  3094. * @param array $fragments
  3095. * @return array
  3096. */
  3097. function avia_woocommerce_add_to_cart_fragments( $fragments )
  3098. {
  3099. $cart_items = WC()->cart instanceof WC_Cart ? WC()->cart->get_cart_contents_count() : 0;
  3100. $active = $cart_items > 0 ? 'av-active-counter' : '';
  3101.  
  3102. $fragments['span.av-cart-counter'] = "<span class='av-cart-counter {$active}'>{$cart_items}</span>";
  3103.  
  3104. return $fragments;
  3105. }
  3106. }
  3107.  
  3108. add_filter( 'woocommerce_add_to_cart_fragments', 'avia_woocommerce_add_to_cart_fragments' );
  3109.  
  3110.  
  3111. if( ! function_exists( 'avia_wc_print_single_product_notices' ) )
  3112. {
  3113. /**
  3114. * Print WC notices on single product pages
  3115. *
  3116. * @since 4.8.2
  3117. */
  3118. function avia_wc_print_single_product_notices()
  3119. {
  3120. if( ! is_single() || ! is_product() )
  3121. {
  3122. return;
  3123. }
  3124.  
  3125. $notices = wc_print_notices( true );
  3126.  
  3127. if( empty( $notices ) )
  3128. {
  3129. return;
  3130. }
  3131.  
  3132. $output = '';
  3133. $show_notice = avia_get_option( 'add_to_cart_message' );
  3134.  
  3135. if( ! empty( $show_notice ) )
  3136. {
  3137. $display = true;
  3138.  
  3139. if( 'display_errors' == $show_notice )
  3140. {
  3141. $display = false !== strpos( $notices, 'woocommerce-error' );
  3142. }
  3143.  
  3144. if( $display )
  3145. {
  3146. $output .= '<div class="avia-wc-notice-box main_color">';
  3147. $output .= $notices;
  3148. $output .= '</div>';
  3149. }
  3150. }
  3151.  
  3152. /**
  3153. * @since 4.8.2
  3154. * @param string $output
  3155. * @param string $output
  3156. * @return string
  3157. */
  3158. echo apply_filters( 'avf_wc_single_product_notice_box', $output, $notices );
  3159. }
  3160. }
  3161.  
  3162. add_action( 'ava_before_content_templatebuilder_page', 'avia_wc_print_single_product_notices', 10 );
  3163.  
  3164.  
  3165. if( ! function_exists( 'avia_woocommerce_set_pages' ) )
  3166. {
  3167. /**
  3168. * after importing demo pages make sure that if we got multiple shop/my account/etc pages (happens if the user used default woocommerce setup)
  3169. * to remove the duplicates and set the theme options properly
  3170. *
  3171. * @since ????
  3172. */
  3173. function avia_woocommerce_set_pages()
  3174. {
  3175. global $wpdb;
  3176.  
  3177. $pages = array(
  3178. 'shop' => array(
  3179. 'title' => 'Shop',
  3180. 'slug' => 'shop',
  3181. ),
  3182. 'cart' => array(
  3183. 'title' => 'Cart',
  3184. 'slug' => 'cart',
  3185. ),
  3186. 'checkout' => array(
  3187. 'title' => 'Checkout',
  3188. 'slug' => 'checkout',
  3189. ),
  3190. 'myaccount' => array(
  3191. 'title' => 'My Account',
  3192. 'slug' => 'my-account',
  3193. )
  3194. );
  3195.  
  3196. /*query string to get multiple posts with the same name*/
  3197. $pagequery = "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type='page'";
  3198.  
  3199.  
  3200. foreach( $pages as $page )
  3201. {
  3202. $entries = $wpdb->get_results( $wpdb->prepare( $pagequery , $page['title'] ) );
  3203.  
  3204. if( ! empty( $entries ) )
  3205. {
  3206. $keep = 0;
  3207. $delete = array();
  3208.  
  3209. //we got one post of that name. the user did not yet activate woocommerce setup or no page with that name was imported
  3210. if( count( $entries ) === 1 )
  3211. {
  3212. $keep = $entries[0]->ID;
  3213. }
  3214. else //we got 2 or more entries. keep the one with the highest id as woocommerce setting and delete the other ones
  3215. {
  3216. foreach( $entries as $entry )
  3217. {
  3218. if( $entry->ID > $keep )
  3219. {
  3220. if( $keep )
  3221. {
  3222. $delete[] = $keep;
  3223. }
  3224.  
  3225. $keep = $entry->ID;
  3226. }
  3227. else
  3228. {
  3229. $delete[] = $entry->ID;
  3230. }
  3231. }
  3232. }
  3233.  
  3234. //delete the not required posts
  3235. foreach( $delete as $delete_id )
  3236. {
  3237. wp_delete_post( $delete_id, true );
  3238. }
  3239.  
  3240. if( $keep > 0 )
  3241. {
  3242. //store the value of the $keep as the default woo setting
  3243. $setting = str_replace( '-', '', $page['slug'] );
  3244. update_option( 'woocommerce_' . $setting . '_page_id' , $keep );
  3245.  
  3246. //modify the page slug and remove any numbers if necessary
  3247. $update_post = array(
  3248. 'ID' => $keep,
  3249. 'post_name' => $page['slug']
  3250. );
  3251.  
  3252. wp_update_post( $update_post );
  3253. }
  3254. }
  3255. }
  3256. }
  3257. }
  3258.  
  3259. add_action( 'avia_after_import_hook', 'avia_woocommerce_set_pages' );
  3260. //add_action( 'ava_after_main_container', 'avia_woocommerce_set_pages' );
  3261.  
  3262.  
  3263. /**
  3264. * Helper functions for template builder elements - Product grids, slideshows, ......
  3265. * ==================================================================================
  3266. *
  3267. */
  3268. if( ! function_exists( 'avia_wc_set_out_of_stock_query_params' ) )
  3269. {
  3270. /**
  3271. * Returns the query parameters for the 'product out of stock' feature for selecting the products
  3272. *
  3273. * @since 4.1.3
  3274. * @param array $meta_query
  3275. * @param array $tax_query
  3276. * @param string $products_visibility 'show'|'hide'|'' for WC default
  3277. */
  3278. function avia_wc_set_out_of_stock_query_params( array &$meta_query, array &$tax_query, $products_visibility = '' )
  3279. {
  3280. /**
  3281. * Backwards compatibility WC < 3.0.0
  3282. */
  3283. if( ! avia_woocommerce_version_check( '3.0.0' ) )
  3284. {
  3285. $meta_query[] = WC()->query->visibility_meta_query();
  3286. $meta_query[] = WC()->query->stock_status_meta_query();
  3287.  
  3288. $meta_query = array_filter( $meta_query );
  3289. }
  3290. else
  3291. {
  3292. switch( $products_visibility )
  3293. {
  3294. case 'show':
  3295. $hide = 'no';
  3296. break;
  3297. case 'hide':
  3298. $hide = 'yes';
  3299. break;
  3300. default:
  3301. $hide = get_option( 'woocommerce_hide_out_of_stock_items', 'no' );
  3302. }
  3303.  
  3304. if( 'yes' == $hide )
  3305. {
  3306. $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' );
  3307. if( $outofstock_term instanceof WP_Term )
  3308. {
  3309. $tax_query[] = array(
  3310. 'taxonomy' => 'product_visibility',
  3311. 'field' => 'term_taxonomy_id',
  3312. 'terms' => array( $outofstock_term->term_taxonomy_id ),
  3313. 'operator' => 'NOT IN'
  3314. );
  3315. }
  3316. }
  3317. }
  3318. }
  3319. }
  3320.  
  3321. if( ! function_exists( 'avia_wc_set_hidden_prod_query_params' ) )
  3322. {
  3323. /**
  3324. * Returns the query parameters for the catalog visibility 'hidden' feature for selecting the products.
  3325. *
  3326. * @since 4.1.3
  3327. * @param array $meta_query
  3328. * @param array $tax_query
  3329. * @param string $catalog_visibility 'show'|'hide'|'' for all
  3330. */
  3331. function avia_wc_set_hidden_prod_query_params( array &$meta_query, array &$tax_query, $catalog_visibility = '' )
  3332. {
  3333. if( avia_woocommerce_version_check( '3.0.0' ) )
  3334. {
  3335. switch( $catalog_visibility )
  3336. {
  3337. case 'show':
  3338. $operator = 'IN';
  3339. break;
  3340. case 'hide':
  3341. $operator = 'NOT IN';
  3342. break;
  3343. default:
  3344. $operator = '';
  3345. }
  3346.  
  3347. if( in_array( $operator, array( 'IN', 'NOT IN' ) ) )
  3348. {
  3349. $hidden_term = get_term_by( 'name', 'exclude-from-catalog', 'product_visibility' );
  3350. if( $hidden_term instanceof WP_Term )
  3351. {
  3352. $tax_query[] = array(
  3353. 'taxonomy' => 'product_visibility',
  3354. 'field' => 'term_taxonomy_id',
  3355. 'terms' => array( $hidden_term->term_taxonomy_id ),
  3356. 'operator' => $operator
  3357. );
  3358. }
  3359. }
  3360. }
  3361. }
  3362. }
  3363.  
  3364. if( ! function_exists( 'avia_wc_set_featured_prod_query_params' ) )
  3365. {
  3366. /**
  3367. * Returns the query parameters for the catalog visibility 'hidden' feature for selecting the products.
  3368. *
  3369. * @since 4.1.3
  3370. * @param array $meta_query
  3371. * @param array $tax_query
  3372. * @param string $catalog_visibility 'show'|'hide'|'' for all
  3373. */
  3374. function avia_wc_set_featured_prod_query_params( array &$meta_query, array &$tax_query, $catalog_visibility = '' )
  3375. {
  3376. if( avia_woocommerce_version_check( '3.0.0' ) )
  3377. {
  3378. switch( $catalog_visibility )
  3379. {
  3380. case 'show':
  3381. $operator = 'IN';
  3382. break;
  3383. case 'hide':
  3384. $operator = 'NOT IN';
  3385. break;
  3386. default:
  3387. $operator = '';
  3388. }
  3389.  
  3390. if( in_array( $operator, array( 'IN', 'NOT IN' ) ) )
  3391. {
  3392. $featured_term = get_term_by( 'name', 'featured', 'product_visibility' );
  3393. if( $featured_term instanceof WP_Term )
  3394. {
  3395. $tax_query[] = array(
  3396. 'taxonomy' => 'product_visibility',
  3397. 'field' => 'term_taxonomy_id',
  3398. 'terms' => array( $featured_term->term_taxonomy_id ),
  3399. 'operator' => $operator
  3400. );
  3401. }
  3402. }
  3403. }
  3404. }
  3405. }
  3406.  
  3407. if( ! function_exists( 'avia_wc_set_additional_filter_args' ) )
  3408. {
  3409. /**
  3410. * Add additional filters from user selections in widget like
  3411. * - minimum / maximum price filter
  3412. *
  3413. * @since 4.5.5
  3414. * @param array $meta_query
  3415. * @param array $tax_query
  3416. */
  3417. function avia_wc_set_additional_filter_args( array &$meta_query, array &$tax_query )
  3418. {
  3419. /**
  3420. * Filter for Minimum / Maximum Price
  3421. */
  3422. $args = array();
  3423. if( isset( $_REQUEST['min_price'] ) && is_numeric( $_REQUEST['min_price'] ) )
  3424. {
  3425. $args['min_price'] = $_REQUEST['min_price'];
  3426. }
  3427. if( isset( $_REQUEST['max_price'] ) && is_numeric( $_REQUEST['max_price'] ) )
  3428. {
  3429. $args['max_price'] = $_REQUEST['max_price'];
  3430. }
  3431.  
  3432. if( ! empty( $args ) )
  3433. {
  3434. $meta_query[] = wc_get_min_max_price_meta_query( $args );
  3435. }
  3436.  
  3437. /**
  3438. * Additional filters - see woocommerce\includes\class-wc-query.php::get_tax_query()
  3439. * ==================
  3440. */
  3441. $product_visibility_terms = wc_get_product_visibility_term_ids();
  3442. $product_visibility_not_in = array( is_search() && $main_query ? $product_visibility_terms['exclude-from-search'] : $product_visibility_terms['exclude-from-catalog'] );
  3443.  
  3444. /**
  3445. * Filter for rating
  3446. */
  3447. if ( isset( $_REQUEST['rating_filter'] ) )
  3448. {
  3449. $rating_filter = array_filter( array_map( 'absint', explode( ',', $_REQUEST['rating_filter'] ) ) );
  3450. $rating_terms = array();
  3451. for ( $i = 1; $i <= 5; $i ++ )
  3452. {
  3453. if ( in_array( $i, $rating_filter, true ) && isset( $product_visibility_terms[ 'rated-' . $i ] ) )
  3454. {
  3455. $rating_terms[] = $product_visibility_terms[ 'rated-' . $i ];
  3456. }
  3457. }
  3458. if ( ! empty( $rating_terms ) )
  3459. {
  3460. $tax_query[] = array(
  3461. 'taxonomy' => 'product_visibility',
  3462. 'field' => 'term_taxonomy_id',
  3463. 'terms' => $rating_terms,
  3464. 'operator' => 'IN',
  3465. 'rating_filter' => true,
  3466. );
  3467. }
  3468. }
  3469.  
  3470. /**
  3471. * Filter for additional attribute filters
  3472. */
  3473. $layered_nav_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
  3474.  
  3475. foreach ( $layered_nav_chosen_attributes as $taxonomy => $data )
  3476. {
  3477. $tax_query[] = array(
  3478. 'taxonomy' => $taxonomy,
  3479. 'field' => 'slug',
  3480. 'terms' => $data['terms'],
  3481. 'operator' => 'and' === $data['query_type'] ? 'AND' : 'IN',
  3482. 'include_children' => false,
  3483. );
  3484. }
  3485. }
  3486. }
  3487.  
  3488.  
  3489. if( ! function_exists( 'avia_wc_get_product_query_order_args' ) )
  3490. {
  3491. /**
  3492. * Returns the ordering args, either the default catalog settings or the user selected.
  3493. * Calls standard WC function to set filter hooks for order by
  3494. * and removes previously set filter hooks
  3495. *
  3496. * @since < 4.0
  3497. * @modified 4.5.6
  3498. * @param string $order_by
  3499. * @param string $order
  3500. * @return array
  3501. */
  3502. function avia_wc_get_product_query_order_args( $order_by = '', $order = '' )
  3503. {
  3504. $def_orderby = avia_wc_get_default_catalog_order_by();
  3505.  
  3506. $order_by = empty( $order_by ) ? $def_orderby['orderby'] : $order_by;
  3507. $order = empty( $order ) ? $def_orderby['order'] : $order;
  3508.  
  3509. // remove and set filter hooks !!
  3510. WC()->query->remove_ordering_args();
  3511. $ordering_args = WC()->query->get_catalog_ordering_args( $order_by, $order );
  3512.  
  3513. return $ordering_args;
  3514. }
  3515. }
  3516.  
  3517.  
  3518. if( ! function_exists( 'avia_wc_get_default_catalog_order_by' ) )
  3519. {
  3520. /**
  3521. * Returns the default settings for catalog order by and clears any set filter hook by this function
  3522. *
  3523. * With Enfold 4.7.6.4 default $order extended to be equal to WC()->query->get_catalog_ordering_args()
  3524. *
  3525. * @since ????
  3526. * @return array
  3527. */
  3528. function avia_wc_get_default_catalog_order_by()
  3529. {
  3530. // does not always return correct values !!!
  3531. // $args = WC()->query->get_catalog_ordering_args();
  3532.  
  3533. /**
  3534. * @since ????
  3535. * @param string $orderby_value
  3536. * @return string
  3537. */
  3538. $orderby_value = apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
  3539.  
  3540. // Get order + orderby args from string
  3541. $orderby_value = explode( '-', $orderby_value );
  3542. $orderby = esc_attr( $orderby_value[0] );
  3543.  
  3544. if( ! empty( $orderby_value[1] ) )
  3545. {
  3546. $order = $orderby_value[1];
  3547. }
  3548. else
  3549. {
  3550. switch( $orderby )
  3551. {
  3552. case 'relevance':
  3553. case 'date':
  3554. $order = 'DESC';
  3555. break;
  3556. default:
  3557. $order = 'ASC';
  3558. break;
  3559. }
  3560. }
  3561.  
  3562. $args = array();
  3563.  
  3564. $args['orderby'] = strtolower( $orderby );
  3565. $args['order'] = ( 'DESC' === strtoupper( $order ) ) ? 'DESC' : 'ASC';
  3566. $args['meta_key'] = '';
  3567.  
  3568. return $args;
  3569. }
  3570. }
  3571.  
  3572.  
  3573. if( ! function_exists( 'avia_wc_clear_catalog_ordering_args_filters' ) )
  3574. {
  3575. /**
  3576. * Remove all filters set by a call to WC()->query->get_catalog_ordering_args();
  3577. *
  3578. * @since ????
  3579. */
  3580. function avia_wc_clear_catalog_ordering_args_filters()
  3581. {
  3582. WC()->query->remove_ordering_args();
  3583. }
  3584. }
  3585.  
  3586.  
  3587. if( ! function_exists( 'avia_wc_product_is_visible' ) )
  3588. {
  3589. /**
  3590. * Allows to change the default visibility for products in catalog.
  3591. *
  3592. * WC checks this in the loop when showing products on a catalog page - as we allow user to show/hide products out of stock in various
  3593. * builder elements we have to force the display even if visibility is false
  3594. *
  3595. * @since ????
  3596. * @param boolean $visible
  3597. * @param int $product_id
  3598. * @return boolean
  3599. */
  3600. function avia_wc_product_is_visible( $visible, $product_id )
  3601. {
  3602. global $avia_config;
  3603.  
  3604. if( ! isset( $avia_config['woocommerce']['catalog_product_visibility'] ) )
  3605. {
  3606. return $visible;
  3607. }
  3608.  
  3609. switch( $avia_config['woocommerce']['catalog_product_visibility'] )
  3610. {
  3611. case 'show_all':
  3612. return true;
  3613. case 'hide_out_of_stock':
  3614. $product = wc_get_product( $product_id );
  3615. if( ! $product instanceof WC_Product )
  3616. {
  3617. return $visible;
  3618. }
  3619. return $product->is_in_stock();
  3620. case 'use_default':
  3621. default:
  3622. return $visible;
  3623. }
  3624. }
  3625. }
  3626.  
  3627. add_filter( 'woocommerce_product_is_visible', 'avia_wc_product_is_visible', 10, 2 );
  3628.  
  3629.  
  3630. if( ! function_exists( 'avia_wc_remove_inline_terms' ) )
  3631. {
  3632. /**
  3633. * If a template builder page with a fullwidth el is used for terms and conditions
  3634. * the terms and conditions are not displayed properly. we need to filter that.
  3635. * in case the user uses a template builder page do not display the inline terms.
  3636. * Returning an empty string will just show the link to the TOS page
  3637. *
  3638. * @since ????
  3639. * @param string $apply_filters
  3640. * @param string $raw_string
  3641. * @return string
  3642. */
  3643. function avia_wc_remove_inline_terms( $apply_filters, $raw_string )
  3644. {
  3645. if( is_checkout() )
  3646. {
  3647. $id = wc_get_page_id( 'terms' );
  3648.  
  3649. if( get_post_meta( $id, '_aviaLayoutBuilder_active', true ) == 'active' )
  3650. {
  3651. return '';
  3652. }
  3653. }
  3654.  
  3655. return $apply_filters;
  3656. }
  3657. }
  3658.  
  3659. add_filter( 'woocommerce_format_content', 'avia_wc_remove_inline_terms', 10, 2 );
  3660.  
  3661.  
  3662. if( ! function_exists( 'avia_wc_filter_terms_page_selection' ) )
  3663. {
  3664. /**
  3665. * Filter the content description for TOS page selection
  3666. *
  3667. * @since ????
  3668. * @param array $settings
  3669. * @return array
  3670. */
  3671. function avia_wc_filter_terms_page_selection( $settings )
  3672. {
  3673. foreach( $settings as $key => $setting )
  3674. {
  3675. if( isset( $setting['id'] ) && ( $setting['id'] == 'woocommerce_terms_page_id' ) )
  3676. {
  3677. $settings[$key]['desc'] .= '<br><br>' . __( 'Attention! Pages built with the Enfold Advanced Template Builder will not be displayed at the bottom of the checkout page but only with a link.', 'avia_framework' );
  3678. break;
  3679. }
  3680. }
  3681.  
  3682. return $settings;
  3683. }
  3684. }
  3685.  
  3686. add_filter( 'woocommerce_get_settings_checkout' , 'avia_wc_filter_terms_page_selection', 10 , 2 );
  3687.  
  3688.  
  3689. /**
  3690. * Force WC images in widgets to have Enfold default image size
  3691. * ============================================================
  3692. *
  3693. * @since 4.4.2
  3694. * @added_by Günter
  3695. */
  3696. global $avia_wc_product_widget_active;
  3697. $avia_wc_product_widget_active = false;
  3698.  
  3699. if( ! function_exists( 'avia_wc_widget_product_item_start' ) )
  3700. {
  3701. /**
  3702. * Set a global variable to limit changeing to widget areas only
  3703. *
  3704. * @since 4.4.2
  3705. * @added_by Günter
  3706. * @param array $args
  3707. * @return array
  3708. */
  3709. function avia_wc_widget_product_item_start( $args )
  3710. {
  3711. global $avia_wc_product_widget_active;
  3712.  
  3713. /**
  3714. * @since 4.4.2
  3715. * @return boolean
  3716. */
  3717. if( false !== apply_filters( 'avf_wc_widget_product_image_size_ignore', false, $args ) )
  3718. {
  3719. return;
  3720. }
  3721.  
  3722. $avia_wc_product_widget_active = true;
  3723. }
  3724. }
  3725.  
  3726. add_action( 'woocommerce_widget_product_item_start', 'avia_wc_widget_product_item_start', 10, 1 );
  3727.  
  3728.  
  3729. if( ! function_exists( 'avia_wc_widget_product_image_size' ) )
  3730. {
  3731. /**
  3732. * Modify default WC behaviour.
  3733. * Based on the function WC_Product::get_image
  3734. *
  3735. * @since 4.4.2
  3736. * @param string $image
  3737. * @param WC_Product $product
  3738. * @param string $size
  3739. * @param array $attr
  3740. * @param boolean $placeholder
  3741. * @param string $image1
  3742. * @return string
  3743. */
  3744. function avia_wc_widget_product_image_size( $image, $product, $size, $attr, $placeholder, $image1 )
  3745. {
  3746. global $avia_wc_product_widget_active, $avia_config;
  3747.  
  3748. if( ! $avia_wc_product_widget_active )
  3749. {
  3750. return $image;
  3751. }
  3752.  
  3753. /**
  3754. * @since 4.4.2
  3755. * @return string
  3756. */
  3757. $size = apply_filters( 'avf_wc_widget_product_image_size', 'widget', $product, $size, $attr, $placeholder );
  3758.  
  3759. if( has_post_thumbnail( $product->get_id() ) )
  3760. {
  3761. $image = get_the_post_thumbnail( $product->get_id(), $size, $attr );
  3762. }
  3763. else if( ( $parent_id = wp_get_post_parent_id( $product->get_id() ) ) && has_post_thumbnail( $parent_id ) ) // @phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
  3764. {
  3765. $image = get_the_post_thumbnail( $parent_id, $size, $attr );
  3766. }
  3767. else if( $placeholder )
  3768. {
  3769. $image = wc_placeholder_img( $size );
  3770. }
  3771. else
  3772. {
  3773. $image = '';
  3774. }
  3775.  
  3776. return $image;
  3777. }
  3778. }
  3779.  
  3780. add_filter( 'woocommerce_product_get_image', 'avia_wc_widget_product_image_size', 10, 6 );
  3781.  
  3782.  
  3783. if( ! function_exists( 'avia_wc_widget_product_item_end' ) )
  3784. {
  3785. /**
  3786. * Reset a global variable to limit changeing to widget areas only
  3787. *
  3788. * @since 4.4.2
  3789. * @param array $args
  3790. */
  3791. function avia_wc_widget_product_item_end( $args )
  3792. {
  3793. global $avia_wc_product_widget_active;
  3794.  
  3795. $avia_wc_product_widget_active = false;
  3796. }
  3797. }
  3798.  
  3799. add_action( 'woocommerce_widget_product_item_end', 'avia_wc_widget_product_item_end', 10, 1 );
  3800.  
  3801.  
  3802. /**
  3803. * Fix problem with ALB pages used as 'Terms and Conditions' page on checkout.
  3804. * WC loads page content above the checkbox with js. With ALB this breaks and might also lead to styling problems.
  3805. * Therefore we link to an external page.
  3806. *
  3807. * Up to WC 3.4.5 no hooks are provided to fix this in php. Therefore we have to add a js snippet.
  3808. *
  3809. * @since 4.4.2
  3810. * @added_by Günter
  3811. */
  3812. if( ! is_admin() && avia_woocommerce_version_check( '3.4.0' ) )
  3813. {
  3814. if( ! function_exists( 'avia_wc_checkout_terms_and_conditions' ) )
  3815. {
  3816. /**
  3817. * @since 4.4.2
  3818. */
  3819. function avia_wc_checkout_terms_and_conditions()
  3820. {
  3821. $terms_id = wc_get_page_id( 'terms' );
  3822.  
  3823. if( 'active' == Avia_Builder()->get_alb_builder_status( $terms_id ) )
  3824. {
  3825. add_action( 'wp_footer', 'avia_woocommerce_fix_checkout_term_link', 5000 );
  3826. }
  3827. }
  3828. }
  3829.  
  3830. add_action( 'woocommerce_checkout_terms_and_conditions', 'avia_wc_checkout_terms_and_conditions' );
  3831.  
  3832.  
  3833. if( ! function_exists( 'avia_woocommerce_fix_checkout_term_link' ) )
  3834. {
  3835. /**
  3836. * Needed by avia_wc_checkout_terms_and_conditions()
  3837. * =================================================
  3838. *
  3839. * @since 4.4.2
  3840. */
  3841. function avia_woocommerce_fix_checkout_term_link()
  3842. {
  3843. ?>
  3844. <script>
  3845. (function($) {
  3846. // wait until everything completely loaded all assets
  3847. $(function() {
  3848. // remove the click event
  3849. $( document.body ).off( 'click', 'a.woocommerce-terms-and-conditions-link' );
  3850. });
  3851. }(jQuery));
  3852. </script>
  3853. <?php
  3854. }
  3855. }
  3856. }
  3857.  
  3858. if( ! function_exists( 'avia_woocommerce_shortcode_current_post' ) )
  3859. {
  3860. /**
  3861. * Shop page might have another query for products and global $post might be a product
  3862. *
  3863. * @since 4.5.6
  3864. * @param null|WP_Post $current_post
  3865. * @return null|WP_Post
  3866. */
  3867. function avia_woocommerce_shortcode_current_post( $current_post )
  3868. {
  3869. if( ! avia_woocommerce_enabled() )
  3870. {
  3871. return $current_post;
  3872. }
  3873.  
  3874. if( ! is_shop() )
  3875. {
  3876. return $current_post;
  3877. }
  3878.  
  3879. $post = get_post( wc_get_page_id( 'shop' ) );
  3880.  
  3881. return $post;
  3882. }
  3883. }
  3884.  
  3885. add_filter( 'avf_shortcode_handler_prepare_current_post', 'avia_woocommerce_shortcode_current_post', 10, 1 );
  3886.  
  3887.  
  3888. if( ! function_exists( 'avia_woocommerce_cpt_support_post_types' ) )
  3889. {
  3890. /**
  3891. * Remove CPT product from list to allow modify edit table and default term settings
  3892. *
  3893. * @since 6.0
  3894. * @param WP_Post_Type[] $pt_objs
  3895. * @return array
  3896. */
  3897. function avia_woocommerce_cpt_support_post_types( $pt_objs )
  3898. {
  3899. if( ! empty( $pt_objs ) )
  3900. {
  3901. unset( $pt_objs['product'] );
  3902. }
  3903.  
  3904. return $pt_objs;
  3905. }
  3906. }
  3907.  
  3908. add_filter( 'avf_cpt_support_post_types', 'avia_woocommerce_cpt_support_post_types', 10, 1 );
  3909.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement