*/ public static function collect_section( $section_key, array $section, array $settings, $file ) { switch ( $section_key ) { case 'pages': return self::collect_pages( $section, $settings ); case 'products': return self::collect_products( $section, $settings, $file ); case 'posts': return self::collect_posts( $section, $settings ); case 'brands': return self::collect_brands( $section, $settings ); default: $cpts = $settings[ $file ]['cpts'] ?? $settings['cpts'] ?? array(); if ( isset( $cpts[ $section_key ] ) ) { return self::collect_cpt( $section_key, $cpts[ $section_key ], $settings ); } return array(); } } private static function collect_pages( array $section, array $settings ) { if ( empty( $section['enabled'] ) || ( $section['mode'] ?? '' ) === 'none' ) { return array(); } $mode = $section['mode'] ?? 'pinned'; $ids = array(); if ( in_array( $mode, array( 'pinned', 'selected' ), true ) ) { $ids = 'pinned' === $mode ? (array) ( $settings['pinned_page_ids'] ?? array() ) : (array) ( $section['ids'] ?? array() ); if ( ! empty( $settings['shop_page_id'] ) && 'pinned' === $mode ) { $ids[] = absint( $settings['shop_page_id'] ); } $ids = array_values( array_unique( array_filter( array_map( 'absint', $ids ) ) ) ); } $args = array( 'post_type' => 'page', 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => 'menu_order title', 'order' => 'ASC', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ); if ( 'all' === $mode ) { $args['posts_per_page'] = -1; } elseif ( ! empty( $ids ) ) { $args['post__in'] = $ids; $args['orderby'] = 'post__in'; } else { return array(); } $exclude_ids = ( 'all' === $mode ) ? self::get_bulk_excluded_ids( $settings, 'page' ) : array(); return self::query_to_items( new WP_Query( $args ), $settings, $exclude_ids ); } /** * IDs omitted from "All published" scans (structural dedupe + user opt-out). * * @return int[] */ private static function get_bulk_excluded_ids( array $settings, $post_type ) { $exclude = array(); if ( 'page' === $post_type ) { foreach ( array( 'shop_page_id', 'brands_parent_id' ) as $key ) { if ( ! empty( $settings[ $key ] ) ) { $exclude[] = absint( $settings[ $key ] ); } } $exclude = array_merge( $exclude, (array) ( $settings['excluded_page_ids'] ?? array() ) ); } elseif ( 'post' === $post_type ) { $exclude = (array) ( $settings['excluded_post_ids'] ?? array() ); } elseif ( 'product' === $post_type ) { $exclude = (array) ( $settings['excluded_product_ids'] ?? array() ); } return array_values( array_unique( array_filter( array_map( 'absint', $exclude ) ) ) ); } private static function should_skip_post( $post_id, array $settings ) { $post_id = absint( $post_id ); if ( $post_id <= 0 ) { return true; } if ( empty( $settings['skip_yoast_noindex'] ) ) { return false; } return self::is_yoast_noindex( $post_id ); } private static function is_yoast_noindex( $post_id ) { $meta = get_post_meta( absint( $post_id ), '_yoast_wpseo_meta-robots-noindex', true ); return '1' === (string) $meta; } private static function collect_products( array $section, array $settings, $file ) { if ( empty( $section['enabled'] ) || ! post_type_exists( 'product' ) ) { return array(); } $include_sold = ADCT_LLMS_Sold_Detector::should_include_sold( $settings, $file ); $mode = $section['mode'] ?? 'latest'; $limit = absint( $section['limit'] ?? 0 ); $exclude_ids = array(); $args = array( 'post_type' => 'product', 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', 'no_found_rows' => true, 'update_post_meta_cache' => false, ); if ( 'selected' === $mode ) { $ids = array_filter( array_map( 'absint', $section['ids'] ?? array() ) ); if ( empty( $ids ) ) { return array(); } $args['post__in'] = $ids; $args['orderby'] = 'post__in'; $args['posts_per_page'] = count( $ids ); } elseif ( 'all' === $mode ) { $args['posts_per_page'] = -1; $exclude_ids = self::get_bulk_excluded_ids( $settings, 'product' ); } else { $fetch = $limit > 0 ? $limit : 10; if ( ! $include_sold ) { $fetch = min( 100, max( $fetch * 4, $fetch + 10 ) ); } $args['posts_per_page'] = $fetch; } $query = new WP_Query( $args ); $items = array(); $exclude_lookup = array_fill_keys( array_map( 'absint', $exclude_ids ), true ); foreach ( $query->posts as $post ) { if ( isset( $exclude_lookup[ $post->ID ] ) ) { continue; } if ( self::should_skip_post( $post->ID, $settings ) ) { continue; } if ( ! $include_sold && ADCT_LLMS_Sold_Detector::is_sold( $post->ID, $settings ) ) { continue; } $items[] = self::post_to_item( $post ); if ( 'latest' === $mode && $limit > 0 && count( $items ) >= $limit ) { break; } } return $items; } private static function collect_posts( array $section, array $settings ) { if ( empty( $section['enabled'] ) ) { return array(); } $mode = $section['mode'] ?? 'latest'; $limit = absint( $section['limit'] ?? 5 ); $args = array( 'post_type' => 'post', 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', 'no_found_rows' => true, ); if ( 'selected' === $mode ) { $ids = array_filter( array_map( 'absint', $section['ids'] ?? array() ) ); if ( empty( $ids ) ) { return array(); } $args['post__in'] = $ids; $args['orderby'] = 'post__in'; $args['posts_per_page'] = count( $ids ); } elseif ( 'all' === $mode ) { $args['posts_per_page'] = -1; } else { $args['posts_per_page'] = $limit > 0 ? $limit : 5; } $exclude_ids = ( 'all' === $mode ) ? self::get_bulk_excluded_ids( $settings, 'post' ) : array(); return self::query_to_items( new WP_Query( $args ), $settings, $exclude_ids ); } private static function collect_brands( array $section, array $settings ) { if ( empty( $section['enabled'] ) ) { return array(); } $mode = $section['mode'] ?? 'taxonomy'; if ( 'taxonomy' === $mode ) { return self::collect_brand_terms( $section, $settings ); } $parent_id = absint( $settings['brands_parent_id'] ?? 0 ); if ( 'selected' === $mode ) { $ids = array_filter( array_map( 'absint', $section['ids'] ?? array() ) ); if ( empty( $ids ) ) { return array(); } $query = new WP_Query( array( 'post_type' => 'page', 'post_status' => 'publish', 'post__in' => $ids, 'orderby' => 'post__in', 'posts_per_page' => count( $ids ), 'no_found_rows' => true, ) ); return self::query_to_items( $query, $settings ); } if ( $parent_id <= 0 ) { return array(); } $query = new WP_Query( array( 'post_type' => 'page', 'post_status' => 'publish', 'post_parent' => $parent_id, 'posts_per_page' => -1, 'orderby' => 'menu_order title', 'order' => 'ASC', 'no_found_rows' => true, 'update_post_meta_cache' => false, ) ); return self::query_to_items( $query, $settings ); } private static function collect_brand_terms( array $section, array $settings ) { $taxonomy = sanitize_key( $settings['brands_taxonomy'] ?? 'product_brand' ); if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) ) { return array(); } $terms = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false, ) ); if ( is_wp_error( $terms ) || empty( $terms ) ) { return array(); } $items = array(); foreach ( $terms as $term ) { $link = get_term_link( $term ); if ( is_wp_error( $link ) ) { continue; } $items[] = array( 'title' => $term->name, 'url' => $link, 'description' => wp_strip_all_tags( $term->description ?? '' ), ); } usort( $items, static function ( $a, $b ) { return strcasecmp( $a['title'], $b['title'] ); } ); $limit = absint( $section['limit'] ?? 0 ); if ( $limit > 0 ) { $items = array_slice( $items, 0, $limit ); } return $items; } private static function collect_cpt( $post_type, array $section, array $settings = array() ) { if ( empty( $section['enabled'] ) ) { return array(); } $mode = $section['mode'] ?? 'latest'; $limit = absint( $section['limit'] ?? 5 ); $args = array( 'post_type' => sanitize_key( $post_type ), 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', 'no_found_rows' => true, ); if ( 'selected' === $mode ) { $ids = array_filter( array_map( 'absint', $section['ids'] ?? array() ) ); if ( empty( $ids ) ) { return array(); } $args['post__in'] = $ids; $args['orderby'] = 'post__in'; $args['posts_per_page'] = count( $ids ); } elseif ( 'all' === $mode ) { $args['posts_per_page'] = -1; } else { $args['posts_per_page'] = $limit > 0 ? $limit : 5; } return self::query_to_items( new WP_Query( $args ), $settings ); } private static function query_to_items( WP_Query $query, array $settings = array(), array $exclude_ids = array() ) { $items = array(); $exclude_lookup = array_fill_keys( array_map( 'absint', $exclude_ids ), true ); foreach ( $query->posts as $post ) { if ( isset( $exclude_lookup[ $post->ID ] ) ) { continue; } if ( ! empty( $settings ) && self::should_skip_post( $post->ID, $settings ) ) { continue; } $items[] = self::post_to_item( $post ); } return $items; } private static function post_to_item( WP_Post $post ) { return array( 'title' => get_the_title( $post ), 'url' => get_permalink( $post ), 'description' => self::build_description( $post ), ); } private static function build_description( WP_Post $post ) { if ( 'product' === $post->post_type && function_exists( 'wc_get_product' ) ) { $product = wc_get_product( $post->ID ); if ( $product ) { $parts = array_filter( array( wp_strip_all_tags( $product->get_short_description() ), self::product_specs_line( $product ), ) ); $text = trim( implode( ' | ', $parts ) ); if ( '' !== $text ) { return self::trim_description( $text ); } } } $excerpt = has_excerpt( $post ) ? $post->post_excerpt : $post->post_content; $text = wp_strip_all_tags( $excerpt ); return self::trim_description( $text ); } private static function product_specs_line( $product ) { $bits = array(); if ( $product->get_attribute( 'pa_year' ) ) { $bits[] = $product->get_attribute( 'pa_year' ) . ' Model'; } if ( $product->get_attribute( 'pa_mileage' ) ) { $bits[] = $product->get_attribute( 'pa_mileage' ); } return implode( ' ยท ', array_filter( $bits ) ); } private static function trim_description( $text ) { $text = strip_shortcodes( (string) $text ); $text = wp_strip_all_tags( $text ); $text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, 'UTF-8' ); $text = preg_replace( '/\s+/', ' ', trim( $text ) ); if ( strlen( $text ) > 220 ) { $text = substr( $text, 0, 217 ) . '...'; } return $text; } }