post_excerpt ?: wp_trim_words( $post->post_content, 30, '' ) ) ); $desc = $this->normalize_description( $desc ); $keywords = class_exists( 'AIT_AIPSEO_Keyword_Density' ) ? ( new AIT_AIPSEO_Keyword_Density() )->get_target_keywords( $post->ID ) : []; // Build a few variants $out = [ [ 'title' => $title, 'description' => $desc ], ]; if ( ! empty( $keywords ) ) { $k = $keywords[0]; $out[] = [ 'title' => $this->prepend_keyword( $title, $k ), 'description' => $desc ]; $out[] = [ 'title' => $title, 'description' => $this->append_cta( $desc ) ]; } return $out; } private function normalize_description( string $d ): string { $d = preg_replace( '/\s+/', ' ', $d ); $d = mb_substr( $d, 0, 160 ); return trim( $d ); } private function prepend_keyword( string $title, string $kw ): string { if ( false !== stripos( $title, $kw ) ) { return $title; } return trim( $kw . ': ' . $title ); } private function append_cta( string $desc ): string { if ( preg_match( '/[\.!?]$/', $desc ) ) { return $desc; } return rtrim( $desc, '. ' ) . '. ' . __( 'Learn more.', 'ai-powered-seo-suggestions' ); } /** * Get manual meta values for a post, if set. * * @param int $post_id * @return array{title:string, description:string} */ private function get_manual_meta( int $post_id ): array { $title = trim( (string) get_post_meta( $post_id, 'ait_aipseo_meta_title', true ) ); $desc = trim( (string) get_post_meta( $post_id, 'ait_aipseo_meta_description', true ) ); return [ 'title' => $title, 'description' => $desc, ]; } /** * Replace the WP document title with the manual meta title if present. */ public function filter_document_title( $title ) { if ( ! is_singular() ) { return $title; } $post_id = get_queried_object_id(); if ( ! $post_id ) { return $title; } $manual = $this->get_manual_meta( (int) $post_id ); if ( '' === $manual['title'] ) { return $title; } return $manual['title']; } /** * Some themes use document_title_parts. Ensure the manual meta title wins there too. */ public function filter_document_title_parts( $parts ) { if ( ! is_array( $parts ) ) { return $parts; } if ( ! is_singular() ) { return $parts; } $post_id = get_queried_object_id(); if ( ! $post_id ) { return $parts; } $manual = $this->get_manual_meta( (int) $post_id ); if ( '' === $manual['title'] ) { return $parts; } $parts['title'] = $manual['title']; return $parts; } /** * Output meta description tag using manual meta description if present. */ public function output_manual_meta_description() { if ( ! is_singular() ) { return; } $post_id = get_queried_object_id(); if ( ! $post_id ) { return; } $manual = $this->get_manual_meta( (int) $post_id ); if ( '' === $manual['description'] ) { return; } // Allow other integrations to disable this output if desired. if ( false === apply_filters( 'ait_aipseo_output_manual_meta_description', true, $post_id ) ) { return; } echo "\n" . '' . "\n"; } }