true, 'site_title' => '', 'site_summary' => '', 'disable_yoast_llms' => true, 'auto_regenerate' => 'weekly', 'add_robots_comment' => false, 'shop_page_id' => 0, 'brands_parent_id' => 0, 'brands_taxonomy' => 'product_brand', 'pinned_page_ids' => array(), 'excluded_page_ids' => array(), 'excluded_post_ids' => array(), 'excluded_product_ids' => array(), 'skip_yoast_noindex' => false, 'sold_rules' => array( array( 'type' => 'product_tag', 'taxonomy' => 'product_tag', 'term' => 'sold-cars', ), ), 'include_sold_llms' => false, 'include_sold_full' => true, 'llms' => self::default_file_sections( 'llms' ), 'full' => self::default_file_sections( 'full' ), 'cpts' => array(), ); } private static function default_file_sections( $file ) { $is_full = ( 'full' === $file ); return array( 'pages' => array( 'enabled' => $is_full, 'mode' => $is_full ? 'all' : 'none', 'limit' => 0, 'ids' => array(), 'title' => __( 'Pages', 'adct-llm-index' ), ), 'products' => array( 'enabled' => true, 'mode' => $is_full ? 'all' : 'latest', 'limit' => $is_full ? 0 : 10, 'ids' => array(), 'title' => $is_full ? __( 'Products', 'adct-llm-index' ) : __( 'Featured inventory', 'adct-llm-index' ), ), 'posts' => array( 'enabled' => true, 'mode' => $is_full ? 'all' : 'latest', 'limit' => $is_full ? 0 : 5, 'ids' => array(), 'title' => __( 'Posts', 'adct-llm-index' ), ), 'brands' => array( 'enabled' => true, 'mode' => 'taxonomy', 'limit' => $is_full ? 0 : 0, 'ids' => array(), 'title' => __( 'Brands', 'adct-llm-index' ), ), 'cpts' => array(), ); } public static function get() { $stored = get_option( self::OPTION, array() ); if ( ! is_array( $stored ) ) { $stored = array(); } return self::sanitize( wp_parse_args( $stored, self::get_defaults() ) ); } public static function update( array $settings ) { update_option( self::OPTION, self::sanitize( self::preprocess_form( $settings ) ) ); } public static function preprocess_form( array $input ) { foreach ( array( 'llms', 'full' ) as $file ) { if ( empty( $input[ $file ] ) || ! is_array( $input[ $file ] ) ) { continue; } foreach ( $input[ $file ] as $key => $section ) { if ( ! is_array( $section ) ) { continue; } $input[ $file ][ $key ] = self::merge_ids_text( $section ); } } if ( ! empty( $input['cpts'] ) && is_array( $input['cpts'] ) ) { foreach ( $input['cpts'] as $post_type => $section ) { if ( is_array( $section ) ) { $input['cpts'][ $post_type ] = self::merge_ids_text( $section ); } } } foreach ( array( 'excluded_post_ids', 'excluded_product_ids' ) as $key ) { if ( isset( $input[ $key . '_text' ] ) ) { $parts = preg_split( '/[\s,]+/', (string) $input[ $key . '_text' ] ); $input[ $key ] = array_values( array_filter( array_map( 'absint', (array) $parts ) ) ); unset( $input[ $key . '_text' ] ); } } return $input; } private static function merge_ids_text( array $section ) { if ( array_key_exists( 'ids_text', $section ) ) { $text = trim( (string) ( $section['ids_text'] ?? '' ) ); if ( '' === $text ) { $section['ids'] = array(); } else { $parts = preg_split( '/[\s,]+/', $text ); $section['ids'] = array_values( array_filter( array_map( 'absint', (array) $parts ) ) ); } unset( $section['ids_text'] ); } return $section; } public static function sanitize( $input ) { $defaults = self::get_defaults(); $input = is_array( $input ) ? $input : array(); $clean = wp_parse_args( $input, $defaults ); $clean['enabled'] = ! empty( $input['enabled'] ); $clean['site_title'] = sanitize_text_field( $clean['site_title'] ?? '' ); $clean['site_summary'] = sanitize_textarea_field( $clean['site_summary'] ?? '' ); $clean['disable_yoast_llms'] = ! empty( $input['disable_yoast_llms'] ); $clean['add_robots_comment'] = ! empty( $input['add_robots_comment'] ); $clean['include_sold_llms'] = ! empty( $input['include_sold_llms'] ); $clean['include_sold_full'] = ! empty( $input['include_sold_full'] ); $auto = sanitize_key( $clean['auto_regenerate'] ?? 'weekly' ); $clean['auto_regenerate'] = in_array( $auto, array( 'manual', 'publish', 'daily', 'weekly' ), true ) ? $auto : 'weekly'; $clean['shop_page_id'] = absint( $clean['shop_page_id'] ?? 0 ); $clean['brands_parent_id'] = absint( $clean['brands_parent_id'] ?? 0 ); $clean['brands_taxonomy'] = sanitize_key( $clean['brands_taxonomy'] ?? 'product_brand' ); $clean['pinned_page_ids'] = self::sanitize_ids( $input['pinned_page_ids'] ?? array() ); $clean['excluded_page_ids'] = self::sanitize_ids( $input['excluded_page_ids'] ?? array() ); $clean['excluded_post_ids'] = self::sanitize_ids( $input['excluded_post_ids'] ?? array() ); $clean['excluded_product_ids'] = self::sanitize_ids( $input['excluded_product_ids'] ?? array() ); $clean['skip_yoast_noindex'] = ! empty( $input['skip_yoast_noindex'] ); $clean['sold_rules'] = self::sanitize_sold_rules( $input['sold_rules'] ?? array() ); $clean['llms'] = self::sanitize_file_sections( $input['llms'] ?? array(), 'llms' ); $clean['full'] = self::sanitize_file_sections( $input['full'] ?? array(), 'full' ); $clean['cpts'] = self::sanitize_cpts( $input['cpts'] ?? array() ); if ( ! empty( $clean['cpts'] ) ) { $clean['llms']['cpts'] = $clean['cpts']; $clean['full']['cpts'] = $clean['cpts']; } return $clean; } private static function sanitize_ids( $ids ) { if ( ! is_array( $ids ) ) { return array(); } return array_values( array_filter( array_map( 'absint', $ids ) ) ); } private static function sanitize_sold_rules( $rules ) { if ( ! is_array( $rules ) ) { return array(); } $clean = array(); foreach ( $rules as $rule ) { if ( ! is_array( $rule ) ) { continue; } $type = sanitize_key( $rule['type'] ?? '' ); if ( ! in_array( $type, array( 'product_tag', 'product_cat', 'taxonomy', 'stock_status', 'post_meta' ), true ) ) { continue; } $entry = array( 'type' => $type ); switch ( $type ) { case 'product_tag': $entry['taxonomy'] = 'product_tag'; $entry['term'] = sanitize_title( $rule['term'] ?? 'sold-cars' ); break; case 'product_cat': $entry['taxonomy'] = 'product_cat'; $entry['term'] = sanitize_title( $rule['term'] ?? 'sold' ); break; case 'taxonomy': $entry['taxonomy'] = sanitize_key( $rule['taxonomy'] ?? '' ); $entry['term'] = sanitize_title( $rule['term'] ?? '' ); if ( '' === $entry['taxonomy'] || '' === $entry['term'] ) { continue 2; } break; case 'stock_status': $entry['value'] = sanitize_key( $rule['value'] ?? 'outofstock' ); break; case 'post_meta': $entry['key'] = sanitize_key( $rule['key'] ?? '' ); $entry['value'] = sanitize_text_field( $rule['value'] ?? '' ); if ( '' === $entry['key'] ) { continue 2; } break; } $clean[] = $entry; } return $clean; } private static function sanitize_file_sections( $sections, $file ) { $defaults = self::default_file_sections( $file ); $sections = is_array( $sections ) ? $sections : array(); $clean = array(); foreach ( array( 'pages', 'products', 'posts', 'brands' ) as $key ) { $raw = $sections[ $key ] ?? array(); $raw = is_array( $raw ) ? $raw : array(); $section = wp_parse_args( $raw, $defaults[ $key ] ); $mode = sanitize_key( $section['mode'] ?? 'latest' ); $allowed_modes = array( 'all', 'latest', 'selected', 'pinned', 'children', 'taxonomy', 'none' ); if ( ! in_array( $mode, $allowed_modes, true ) ) { $mode = 'latest'; } $clean[ $key ] = array( 'enabled' => ! empty( $raw['enabled'] ), 'mode' => $mode, 'limit' => max( 0, absint( $section['limit'] ?? 0 ) ), 'ids' => self::sanitize_ids( $section['ids'] ?? array() ), 'title' => sanitize_text_field( $section['title'] ?? $defaults[ $key ]['title'] ), ); } return $clean; } private static function sanitize_cpts( $cpts ) { if ( ! is_array( $cpts ) ) { return array(); } $clean = array(); foreach ( $cpts as $post_type => $section ) { $post_type = sanitize_key( $post_type ); if ( '' === $post_type || ! post_type_exists( $post_type ) ) { continue; } $object = get_post_type_object( $post_type ); if ( ! $object || empty( $object->public ) ) { continue; } $raw = is_array( $section ) ? $section : array(); $merged = wp_parse_args( $raw, array( 'mode' => 'latest', 'limit' => 5, 'title' => $object->labels->name, ) ); $mode = sanitize_key( $merged['mode'] ?? 'latest' ); if ( ! in_array( $mode, array( 'all', 'latest', 'selected', 'none' ), true ) ) { $mode = 'latest'; } $clean[ $post_type ] = array( 'enabled' => ! empty( $raw['enabled'] ), 'mode' => $mode, 'limit' => max( 0, absint( $merged['limit'] ?? 5 ) ), 'ids' => self::sanitize_ids( $merged['ids'] ?? array() ), 'title' => sanitize_text_field( $merged['title'] ?? $object->labels->name ), ); } return $clean; } public static function is_yoast_active() { return ADCT_LLMS_Yoast::is_active(); } public static function get_site_title() { $settings = self::get(); $title = trim( (string) ( $settings['site_title'] ?? '' ) ); return '' !== $title ? $title : get_bloginfo( 'name' ); } public static function get_public_post_types() { $types = get_post_types( array( 'public' => true, ), 'objects' ); $skip = array( 'attachment', 'product', 'page', 'post' ); $list = array(); foreach ( $types as $name => $object ) { if ( in_array( $name, $skip, true ) ) { continue; } $list[ $name ] = $object; } return $list; } }