render(); if ( '' === $html ) { return $content; } $position = isset( $settings['position'] ) ? (string) $settings['position'] : 'below'; if ( 'product' === $post_type ) { $position = isset( $settings['woo_position'] ) ? (string) $settings['woo_position'] : 'below'; } if ( 'above' === $position ) { return $html . $content; } return $content . $html; } /** * Render the navigation HTML. * * @param array $args Optional override args (used by shortcode). * @return string */ public function render( $args = array() ) { if ( ! is_singular() ) { return ''; } $post_id = get_queried_object_id(); if ( ! $post_id ) { return ''; } $settings = function_exists( 'aha_prev_next_get_settings' ) ? aha_prev_next_get_settings() : array(); $settings = is_array( $settings ) ? $settings : array(); $settings = array_merge( $settings, is_array( $args ) ? $args : array() ); $prev = get_previous_post(); $next = get_next_post(); $prev_id = ( $prev && isset( $prev->ID ) ) ? (int) $prev->ID : 0; $next_id = ( $next && isset( $next->ID ) ) ? (int) $next->ID : 0; /** * Filter adjacent post IDs (allowing custom post ordering or taxonomy selection rules). * * @since 0.1.0 * * @param array $ids Array with keys prev and next. * @param int $post_id Current post ID. */ $ids = apply_filters( 'aha_prev_next_adjacent_ids', array( 'prev' => $prev_id, 'next' => $next_id, ), $post_id ); $prev_id = isset( $ids['prev'] ) ? absint( $ids['prev'] ) : 0; $next_id = isset( $ids['next'] ) ? absint( $ids['next'] ) : 0; if ( ! $prev_id && ! $next_id ) { return ''; } $position = isset( $settings['position'] ) ? (string) $settings['position'] : 'below'; if ( 'product' === get_post_type() ) { $woo_pos = isset( $settings['woo_position'] ) ? (string) $settings['woo_position'] : 'woocommerce_after_single_product'; if ( in_array( $woo_pos, array( 'above', 'below' ), true ) ) { $position = $woo_pos; } else { $position = 'below'; } } $show_thumb = ! empty( $settings['show_thumbnail'] ); $title_len = ( isset( $settings['title_length'] ) && '' !== $settings['title_length'] ) ? absint( $settings['title_length'] ) : 40; $wrap_classes = array( 'aha-pn-wrap', 'aha-pn-pos-' . sanitize_html_class( $position ) ); ob_start(); /** * Action before render. * * @since 0.1.0 */ do_action( 'aha_prev_next_render_before' ); include AHA_PREV_NEXT_PATH . 'templates/frontend/nav.php'; /** * Action after render. * * @since 0.1.0 */ do_action( 'aha_prev_next_render_after' ); return (string) ob_get_clean(); } /** * Setup WooCommerce hooks if on singular product and WooCommerce enabled. * * @return void */ public function setup_woocommerce_hook() { if ( is_admin() ) { return; } $settings = function_exists( 'aha_prev_next_get_settings' ) ? aha_prev_next_get_settings() : array(); $post_type = get_post_type(); $enabled_post_types = isset( $settings['enabled_post_types'] ) && is_array( $settings['enabled_post_types'] ) ? $settings['enabled_post_types'] : array( 'post', 'page' ); if ( ! in_array( 'product', $enabled_post_types, true ) || ! is_singular( 'product' ) ) { return; } $woo_hook = isset( $settings['woo_position'] ) ? $settings['woo_position'] : 'woocommerce_after_single_product'; if ( in_array( $woo_hook, array( 'above', 'below' ), true ) ) { // Let the_content filter handle it. return; } // Disable default post content injection on WooCommerce products. remove_filter( 'the_content', array( $this, 'maybe_append_to_content' ), 25 ); if ( 'disable' !== $woo_hook && ! empty( $woo_hook ) ) { add_action( $woo_hook, array( $this, 'render_woo_navigation' ), 30 ); } } /** * Render WooCommerce navigation cards inside custom hook. * * @return void */ public function render_woo_navigation() { echo $this->render(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } }