ID, '_aicitare_faq', true ); if ( ! $stored ) { return ''; } $arr = json_decode( $stored, true ); if ( ! is_array( $arr ) || empty( $arr ) ) { return ''; } $out = '
'; foreach ( $arr as $qa ) { if ( empty( $qa['q'] ) || empty( $qa['a'] ) ) { continue; } $out .= '
' . '
' . esc_html( $qa['q'] ) . '
' . '
' . esc_html( $qa['a'] ) . '
'; } return $out . '
'; } /** [aicitare_quick_answer] — render the auto quick-answer box. */ public function sc_quick() { $post = get_post(); return $post ? $this->quick_answer( $post, do_shortcode( $post->post_content ) ) : ''; } public function inject( $content ) { if ( ! is_singular( array( 'post', 'page' ) ) || ! in_the_loop() || ! is_main_query() ) { return $content; } $post = get_post(); if ( ! $post instanceof WP_Post ) { return $content; } $page = $this->find_page( $post->ID ); if ( ! $page ) { return $content; } $applied = $this->applied( $page, AICitare_Data::get_fixed() ); if ( empty( $applied ) ) { return $content; } $before = ''; $after = ''; if ( in_array( 'quick', $applied, true ) ) { $before .= $this->quick_answer( $post, $content ); } if ( in_array( 'proscons', $applied, true ) ) { $after .= $this->pros_cons( $post ); } if ( in_array( 'table', $applied, true ) ) { $after .= $this->comparison_table( $post ); } if ( $this->author_fixed( $page, AICitare_Data::get_fixed() ) ) { $after .= $this->author_box( $post ); } return $before . $content . $after; } /** Build the HTML fragment that WOULD be injected for a single issue (preview, not persisted). */ public function preview_html( $post, $cat, $title ) { $t = strtolower( $title ); if ( 'authority' === $cat && ( false !== strpos( $t, 'author' ) || false !== strpos( $t, 'person' ) || false !== strpos( $t, 'reviewer' ) || false !== strpos( $t, 'credential' ) ) ) { return $this->author_box( $post ); } if ( 'structure' === $cat ) { if ( false !== strpos( $t, 'quick' ) || false !== strpos( $t, 'summary' ) ) { return $this->quick_answer( $post, do_shortcode( $post->post_content ) ); } if ( false !== strpos( $t, 'pros' ) || false !== strpos( $t, 'cons' ) || false !== strpos( $t, 'list' ) ) { return $this->pros_cons( $post ); } if ( false !== strpos( $t, 'table' ) ) { return $this->comparison_table( $post ); } } return ''; } /** Whether an authority/author fix was applied for this page (task #3). */ private function author_fixed( $page, $fixed ) { foreach ( $page['issues'] as $is ) { if ( empty( $fixed[ $is['id'] ] ) || 'authority' !== $is['cat'] ) { continue; } $t = strtolower( $is['title'] ); if ( false !== strpos( $t, 'author' ) || false !== strpos( $t, 'reviewer' ) || false !== strpos( $t, 'person' ) || false !== strpos( $t, 'credential' ) ) { return true; } } return false; } /** Visual author box for E-E-A-T (pairs with the Person schema from AICitare_Schema). */ private function author_box( $post ) { $aid = $post->post_author; $name = get_the_author_meta( 'display_name', $aid ); if ( ! $name ) { return ''; } $bio = get_the_author_meta( 'description', $aid ); $url = get_author_posts_url( $aid ); $avatar = get_avatar( $aid, 56, '', $name, array( 'extra_attr' => 'style="border-radius:50%;"' ) ); $reviewer = trim( (string) get_post_meta( $post->ID, '_aicitare_reviewer', true ) ); $out = '
'; if ( $avatar ) { $out .= '
' . $avatar . '
'; // get_avatar output is already escaped markup. } $out .= '
'; $out .= '
' . esc_html__( 'About the author', 'aicitare' ) . '
'; $out .= '
'; $out .= $url ? '' . esc_html( $name ) . '' : esc_html( $name ); $out .= '
'; if ( $bio ) { $out .= '
' . esc_html( $bio ) . '
'; } if ( $reviewer ) { $out .= '
✓ ' . esc_html( sprintf( /* translators: %s: reviewer name */ __( 'Medically reviewed by %s', 'aicitare' ), $reviewer ) ) . '
'; } $out .= '
'; return $out; } /** Which structure blocks were fixed for this page. */ private function applied( $page, $fixed ) { $a = array(); foreach ( $page['issues'] as $is ) { if ( empty( $fixed[ $is['id'] ] ) || 'structure' !== $is['cat'] ) { continue; } $t = strtolower( $is['title'] ); if ( false !== strpos( $t, 'quick' ) || false !== strpos( $t, 'summary' ) ) { $a[] = 'quick'; } if ( false !== strpos( $t, 'table' ) ) { $a[] = 'table'; } if ( false !== strpos( $t, 'pros' ) || false !== strpos( $t, 'cons' ) ) { $a[] = 'proscons'; } } return array_unique( $a ); } /** Auto-generated quick-answer box (derived from excerpt/content; no recursion). */ private function quick_answer( $post, $content ) { $raw = trim( (string) $post->post_excerpt ); if ( '' === $raw ) { $raw = trim( wp_strip_all_tags( $content ) ); } $text = wp_trim_words( $raw, 55, '…' ); $text = apply_filters( 'aicitare_quick_answer', $text, $post ); if ( '' === $text ) { return ''; } return '
' . '
' . esc_html__( 'Quick answer', 'aicitare' ) . '
' . '
' . esc_html( $text ) . '
'; } /** Pros / cons columns from per-post meta (skipped when no data). */ private function pros_cons( $post ) { $pros = array_filter( array_map( 'trim', explode( "\n", (string) get_post_meta( $post->ID, '_aicitare_pros', true ) ) ) ); $cons = array_filter( array_map( 'trim', explode( "\n", (string) get_post_meta( $post->ID, '_aicitare_cons', true ) ) ) ); if ( ! $pros && ! $cons ) { return ''; } $col = function ( $title, $items, $color, $bg ) { $out = '
' . '
' . esc_html( $title ) . '
'; }; return '
' . $col( __( 'Pros', 'aicitare' ), $pros, '#16a34a', '#cdeed8' ) . $col( __( 'Cons', 'aicitare' ), $cons, '#dc2626', '#f3c9c9' ) . '
'; } /** HTML comparison table from per-post meta JSON (rows of cells; first row = header). */ private function comparison_table( $post ) { $json = get_post_meta( $post->ID, '_aicitare_table', true ); if ( ! $json ) { return ''; } $rows = json_decode( $json, true ); if ( ! is_array( $rows ) || empty( $rows ) ) { return ''; } $out = '
'; foreach ( $rows as $ri => $row ) { if ( ! is_array( $row ) ) { continue; } $tag = 0 === $ri ? 'th' : 'td'; $style = 0 === $ri ? 'background:#5b50e6;color:#fff;text-align:start;padding:9px 12px;' : 'border-bottom:1px solid #e7e9ee;padding:9px 12px;'; $out .= ''; foreach ( $row as $cell ) { $out .= '<' . $tag . ' style="' . esc_attr( $style ) . '">' . esc_html( (string) $cell ) . ''; } $out .= ''; } return $out . '
'; } private function find_page( $post_id ) { $rel = wp_make_link_relative( get_permalink( $post_id ) ); foreach ( AICitare_Data::get_pages() as $p ) { if ( $p['id'] === 'wp' . $post_id || untrailingslashit( $p['url'] ) === untrailingslashit( $rel ) ) { return $p; } } return null; } }