in_same_term = $in_same_term; $this->excluded_terms = $excluded_terms; $this->taxonomy = $taxonomy; $this->previous = $previous; } /** * Get adjacent product or circle back to the first/last valid product. * * @since 2.4.3 * * @return WC_Product|false Product object if successful. False if no valid product is found. */ public function get_product() { global $post; $product = false; $this->current_product = $post->ID; // Try to get a valid product via `get_adjacent_post()`. while ( $adjacent = $this->get_adjacent() ) { $product = wc_get_product( $adjacent->ID ); if ( $product && $product->is_visible() ) { break; } $product = false; $this->current_product = $adjacent->ID; } if ( $product ) { return $product; } // No valid product found; Query WC for first/last product. $product = $this->query_wc(); if ( $product ) { return $product; } return false; } /** * Get adjacent post. * * @since 2.4.3 * * @return WP_POST|false Post object if successful. False if no valid post is found. */ private function get_adjacent() { global $post; $direction = $this->previous ? 'previous' : 'next'; add_filter( 'get_' . $direction . '_post_where', array( $this, 'filter_post_where' ) ); $adjacent = get_adjacent_post( $this->in_same_term, $this->excluded_terms, $this->previous, $this->taxonomy ); remove_filter( 'get_' . $direction . '_post_where', array( $this, 'filter_post_where' ) ); return $adjacent; } /** * Filters the WHERE clause in the SQL for an adjacent post query, replacing the * date with date of the next post to consider. * * @since 2.4.3 * * @param string $where The `WHERE` clause in the SQL. * @return WP_POST|false Post object if successful. False if no valid post is found. */ public function filter_post_where( $where ) { global $post; $new = get_post( $this->current_product ); $where = str_replace( $post->post_date, $new->post_date, $where ); return $where; } /** * Query WooCommerce for either the first or last products. * * @since 2.4.3 * * @return WC_Product|false Post object if successful. False if no valid post is found. */ private function query_wc() { global $post; $args = array( 'limit' => 2, 'visibility' => 'catalog', 'exclude' => array( $post->ID ), 'orderby' => 'date', 'status' => 'publish', ); if ( ! $this->previous ) { $args['order'] = 'ASC'; } if ( $this->in_same_term ) { $terms = get_the_terms( $post->ID, $this->taxonomy ); if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { $args['category'] = wp_list_pluck( $terms, 'slug' ); } } $products = wc_get_products( apply_filters( 'storefront_woocommerce_adjacent_query_args', $args ) ); // At least 2 results are required, otherwise previous/next will be the same. if ( ! empty( $products ) && count( $products ) >= 2 ) { return $products[0]; } return false; } } endif;