Skip to content
wiki.fftac.org

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
}