Editorial Meta
**Site relevance:** 2IA.org
**Memory type:** theme source memory
**Source path:** 2IA.org/wp-content/themes/twoia-intelligence/inc/editorial-meta.php
**Size:** 8.2 KB
Summary
Editorial review metadata for research content.
Source Preview
This source file is short enough to preview directly on its source-memory page.
<?php
/**
* Editorial review metadata for research content.
*
* @package TwoIA
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Return editorial meta fields.
*
* @return array
*/
function twoia_editorial_meta_fields() {
return array(
'twoia_confidence_label' => array(
'label' => __( 'Confidence label', 'two-identities-anonymous' ),
'description' => __( 'How strongly the article supports its core claim.', 'two-identities-anonymous' ),
'type' => 'select',
'default' => 'not-labeled',
'options' => array(
'not-labeled' => __( 'Not labeled', 'two-identities-anonymous' ),
'confirmed' => __( 'Confirmed', 'two-identities-anonymous' ),
'corroborated' => __( 'Corroborated', 'two-identities-anonymous' ),
'inferred' => __( 'Inferred', 'two-identities-anonymous' ),
'disputed' => __( 'Disputed', 'two-identities-anonymous' ),
'stale' => __( 'Stale / needs refresh', 'two-identities-anonymous' ),
'unknown' => __( 'Unknown / developing', 'two-identities-anonymous' ),
),
),
'twoia_source_notes' => array(
'label' => __( 'Source notes', 'two-identities-anonymous' ),
'description' => __( 'Public source classes, records reviewed, archive notes, or provenance limits.', 'two-identities-anonymous' ),
'type' => 'textarea',
'default' => '',
),
'twoia_ai_use' => array(
'label' => __( 'AI use disclosure', 'two-identities-anonymous' ),
'description' => __( 'How AI assisted drafting, sorting, summarization, translation, or review.', 'two-identities-anonymous' ),
'type' => 'textarea',
'default' => '',
),
'twoia_reply_status' => array(
'label' => __( 'Right-of-reply status', 'two-identities-anonymous' ),
'description' => __( 'Whether named subjects were contacted, responded, declined, or were not applicable.', 'two-identities-anonymous' ),
'type' => 'textarea',
'default' => '',
),
'twoia_minimization' => array(
'label' => __( 'Minimization and redaction note', 'two-identities-anonymous' ),
'description' => __( 'What personal detail was removed, generalized, or intentionally not collected.', 'two-identities-anonymous' ),
'type' => 'textarea',
'default' => '',
),
'twoia_correction_log' => array(
'label' => __( 'Correction or update log', 'two-identities-anonymous' ),
'description' => __( 'Visible changes that affect facts, context, privacy exposure, or conclusions.', 'two-identities-anonymous' ),
'type' => 'textarea',
'default' => '',
),
);
}
/**
* Register editorial meta for public research content.
*/
function twoia_register_editorial_meta() {
$post_types = function_exists( 'twoia_article_post_types' ) ? twoia_article_post_types() : array( 'post' );
foreach ( $post_types as $post_type ) {
foreach ( twoia_editorial_meta_fields() as $meta_key => $field ) {
register_post_meta(
$post_type,
$meta_key,
array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'sanitize_textarea_field',
'auth_callback' => static function () {
return current_user_can( 'edit_posts' );
},
'default' => $field['default'],
)
);
}
}
}
add_action( 'init', 'twoia_register_editorial_meta' );
/**
* Add editorial review meta box.
*/
function twoia_add_editorial_review_meta_box() {
$post_types = function_exists( 'twoia_article_post_types' ) ? twoia_article_post_types() : array( 'post' );
add_meta_box(
'twoia-editorial-review',
__( '2IA Editorial Review', 'two-identities-anonymous' ),
'twoia_render_editorial_review_meta_box',
$post_types,
'normal',
'high'
);
}
add_action( 'add_meta_boxes', 'twoia_add_editorial_review_meta_box' );
/**
* Render editorial review meta box.
*
* @param WP_Post $post Post object.
*/
function twoia_render_editorial_review_meta_box( $post ) {
wp_nonce_field( 'twoia_save_editorial_review', 'twoia_editorial_review_nonce' );
?>
<p><?php esc_html_e( 'Use these fields to keep public research answerable: confidence, provenance, AI assistance, right of reply, minimization, and visible correction history.', 'two-identities-anonymous' ); ?></p>
<table class="form-table" role="presentation">
<tbody>
<?php foreach ( twoia_editorial_meta_fields() as $meta_key => $field ) : ?>
<?php $value = (string) get_post_meta( $post->ID, $meta_key, true ); ?>
<tr>
<th scope="row">
<label for="<?php echo esc_attr( $meta_key ); ?>"><?php echo esc_html( $field['label'] ); ?></label>
</th>
<td>
<?php if ( 'select' === $field['type'] ) : ?>
<select id="<?php echo esc_attr( $meta_key ); ?>" name="<?php echo esc_attr( $meta_key ); ?>">
<?php foreach ( $field['options'] as $option_value => $option_label ) : ?>
<option value="<?php echo esc_attr( $option_value ); ?>" <?php selected( $value ? $value : $field['default'], $option_value ); ?>><?php echo esc_html( $option_label ); ?></option>
<?php endforeach; ?>
</select>
<?php else : ?>
<textarea id="<?php echo esc_attr( $meta_key ); ?>" name="<?php echo esc_attr( $meta_key ); ?>" rows="4" class="large-text"><?php echo esc_textarea( $value ); ?></textarea>
<?php endif; ?>
<p class="description"><?php echo esc_html( $field['description'] ); ?></p>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php
}
/**
* Save editorial review meta fields.
*
* @param int $post_id Post ID.
*/
function twoia_save_editorial_review_meta( $post_id ) {
if ( ! isset( $_POST['twoia_editorial_review_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['twoia_editorial_review_nonce'] ) ), 'twoia_save_editorial_review' ) ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
foreach ( twoia_editorial_meta_fields() as $meta_key => $field ) {
$value = isset( $_POST[ $meta_key ] ) ? sanitize_textarea_field( wp_unslash( $_POST[ $meta_key ] ) ) : '';
if ( 'select' === $field['type'] && ! isset( $field['options'][ $value ] ) ) {
$value = $field['default'];
}
if ( '' === $value || $value === $field['default'] ) {
delete_post_meta( $post_id, $meta_key );
continue;
}
update_post_meta( $post_id, $meta_key, $value );
}
}
add_action( 'save_post', 'twoia_save_editorial_review_meta' );
/**
* Return a display value for editorial meta.
*
* @param int $post_id Post ID.
* @param string $meta_key Meta key.
* @return string
*/
function twoia_get_editorial_meta_display_value( $post_id, $meta_key ) {
$value = (string) get_post_meta( $post_id, $meta_key, true );
$fields = twoia_editorial_meta_fields();
if ( '' === $value || ! isset( $fields[ $meta_key ] ) ) {
return '';
}
if ( 'select' === $fields[ $meta_key ]['type'] ) {
return isset( $fields[ $meta_key ]['options'][ $value ] ) ? $fields[ $meta_key ]['options'][ $value ] : '';
}
return $value;
}
/**
* Render public editorial review metadata for articles.
*/
function twoia_render_editorial_review_panel() {
$post_id = get_the_ID();
if ( ! $post_id ) {
return;
}
$fields = twoia_editorial_meta_fields();
$items = array();
foreach ( $fields as $meta_key => $field ) {
$value = twoia_get_editorial_meta_display_value( $post_id, $meta_key );
if ( '' === $value ) {
continue;
}
$items[] = array(
'label' => $field['label'],
'value' => $value,
);
}
if ( empty( $items ) ) {
return;
}
?>
<section class="briefing-panel editorial-review-panel" aria-labelledby="twoia-editorial-review-title">
<p class="eyebrow"><?php esc_html_e( 'Editorial review ledger', 'two-identities-anonymous' ); ?></p>
<h2 id="twoia-editorial-review-title"><?php esc_html_e( 'Evidence, uncertainty, and correction', 'two-identities-anonymous' ); ?></h2>
<div class="editorial-review-grid">
<?php foreach ( $items as $item ) : ?>
<section class="editorial-review-item">
<h3><?php echo esc_html( $item['label'] ); ?></h3>
<p><?php echo nl2br( esc_html( $item['value'] ) ); ?></p>
</section>
<?php endforeach; ?>
</div>
</section>
<?php
}