> $aggregated Aggregated FAQ data.
*/
private static function sync_faq_posts( $aggregated ) {
$existing_ids = get_posts(
[
'post_type' => Settings::get_post_type(),
'post_status' => 'any',
'fields' => 'ids',
'posts_per_page' => -1,
]
);
$existing_map = [];
foreach ( $existing_ids as $faq_id ) {
$faq = get_post( $faq_id );
if ( $faq instanceof \WP_Post ) {
$existing_map[ self::normalize_question_key( $faq->post_title ) ] = $faq_id;
}
}
$handled_ids = [];
foreach ( $aggregated as $key => $data ) {
$post_id = $existing_map[ $key ] ?? 0;
$post_args = [
'post_title' => $data['question'],
'post_type' => Settings::get_post_type(),
'post_status' => 'publish',
];
if ( $post_id ) {
$post_args['ID'] = $post_id;
$result = wp_update_post( $post_args, true );
} else {
$result = wp_insert_post( $post_args, true );
}
if ( is_wp_error( $result ) ) {
continue;
}
$post_id = (int) $result;
update_post_meta( $post_id, 'answers', $data['answers'] );
update_post_meta( $post_id, 'answers_html', $data['answers_html'] );
update_post_meta( $post_id, 'source_titles', $data['source_titles'] );
update_post_meta( $post_id, 'source_urls', $data['source_urls'] ?? [] );
update_post_meta( $post_id, 'original_question', $data['question'] );
update_post_meta( $post_id, 'used_in_posts', $data['used_in_posts'] );
update_post_meta( $post_id, 'used_in_post_types', $data['used_in_post_types'] );
update_post_meta( $post_id, 'count_usage', $data['count_usage'] );
self::sync_registry_categories( $post_id, $data );
$handled_ids[] = $post_id;
}
foreach ( $existing_ids as $faq_id ) {
if ( ! in_array( $faq_id, $handled_ids, true ) ) {
wp_delete_post( $faq_id, true );
}
}
}
/**
* Add admin columns for FAQ CPT list table.
*
* @param array $columns Columns.
* @return array
*/
public static function add_admin_columns( $columns ) {
$columns['answers'] = __( 'Answers', '4wp-faq' );
$columns['answers_html'] = __( 'Answers (HTML)', '4wp-faq' );
$columns['usage'] = __( 'Usage', '4wp-faq' );
return $columns;
}
/**
* Render admin column values.
*
* @param string $column Column key.
* @param int $post_id Post ID.
*/
public static function render_admin_column( $column, $post_id ) {
if ( 'answers' === $column ) {
$answers = get_post_meta( $post_id, 'answers', true );
$answers = is_array( $answers ) ? $answers : [];
if ( empty( $answers ) ) {
echo '—';
return;
}
$sample = wp_trim_words( (string) $answers[0], 16, '…' );
echo esc_html( count( $answers ) . ' • ' . $sample );
return;
}
if ( 'answers_html' === $column ) {
$answers_html = get_post_meta( $post_id, 'answers_html', true );
$answers_html = is_array( $answers_html ) ? $answers_html : [];
if ( empty( $answers_html ) ) {
echo '—';
return;
}
$sample = wp_trim_words( wp_strip_all_tags( (string) $answers_html[0] ), 16, '…' );
echo esc_html( count( $answers_html ) . ' • ' . $sample );
return;
}
if ( 'usage' === $column ) {
$count = (int) get_post_meta( $post_id, 'count_usage', true );
echo esc_html( $count );
}
}
/**
* Register meta boxes for FAQ CPT edit screen.
*
* @param \WP_Post $post Post object.
*/
public static function register_meta_boxes( $post ) {
add_meta_box(
'forwp_faq_details',
__( 'FAQ Details', '4wp-faq' ),
[ __CLASS__, 'render_meta_box' ],
Settings::get_post_type(),
'normal',
'default'
);
add_meta_box(
'forwp_faq_usage',
__( 'Used In', '4wp-faq' ),
[ __CLASS__, 'render_usage_meta_box' ],
Settings::get_post_type(),
'side',
'default'
);
}
/**
* Render FAQ meta box content.
*
* @param \WP_Post $post Post object.
*/
public static function render_meta_box( $post ) {
$answers = get_post_meta( $post->ID, 'answers', true );
$answers = is_array( $answers ) ? $answers : [];
$answers_html = get_post_meta( $post->ID, 'answers_html', true );
$answers_html = is_array( $answers_html ) ? $answers_html : [];
$original_question = get_post_meta( $post->ID, 'original_question', true );
$editable_html = isset( $answers_html[0] ) ? (string) $answers_html[0] : '';
wp_nonce_field( Registry_Push::NONCE_ACTION, Registry_Push::NONCE_FIELD );
?>
ID, 'used_in_posts', true );
$used_in_posts = is_array( $used_in_posts ) ? array_values( $used_in_posts ) : [];
$groups = [];
foreach ( $used_in_posts as $post_id ) {
$source_post = get_post( (int) $post_id );
if ( ! $source_post instanceof \WP_Post ) {
continue;
}
$post_type = $source_post->post_type;
if ( ! isset( $groups[ $post_type ] ) ) {
$groups[ $post_type ] = [];
}
$groups[ $post_type ][] = $source_post;
}
$count_usage = (int) get_post_meta( $post->ID, 'count_usage', true );
?>
—
$items ) : ?>
labels->name )
? $type_object->labels->name
: $post_type;
?>
:
ID );
$status = get_post_status( $source_post );
$status_obj = $status ? get_post_status_object( $status ) : null;
$status_label = $status_obj && ! empty( $status_obj->label ) ? $status_obj->label : $status;
$title = $source_post->post_title ? $source_post->post_title : $source_post->ID;
?>
-