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 .= '
';
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 ) . '
';
foreach ( $items as $it ) {
$out .= '- ' . esc_html( $it ) . '
';
}
return $out . '
';
};
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 ) . '' . $tag . '>';
}
$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;
}
}