From 2d7e857e96409dd40ec502c65669f19c7f08308c Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Wed, 18 Dec 2024 15:52:11 -0500 Subject: [PATCH 01/12] feat(corrections): add base code and feature flag --- includes/class-newspack.php | 1 + includes/corrections/class-corrections.php | 314 +++++++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 includes/corrections/class-corrections.php diff --git a/includes/class-newspack.php b/includes/class-newspack.php index 429d858e2f..f4e4bb8926 100644 --- a/includes/class-newspack.php +++ b/includes/class-newspack.php @@ -125,6 +125,7 @@ private function includes() { include_once NEWSPACK_ABSPATH . 'includes/tracking/class-twitter-pixel.php'; include_once NEWSPACK_ABSPATH . 'includes/revisions-control/class-revisions-control.php'; include_once NEWSPACK_ABSPATH . 'includes/authors/class-authors-custom-fields.php'; + include_once NEWSPACK_ABSPATH . 'includes/corrections/class-corrections.php'; include_once NEWSPACK_ABSPATH . 'includes/starter_content/class-starter-content-provider.php'; include_once NEWSPACK_ABSPATH . 'includes/starter_content/class-starter-content-generated.php'; diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php new file mode 100644 index 0000000000..032b01647a --- /dev/null +++ b/includes/corrections/class-corrections.php @@ -0,0 +1,314 @@ + -1, + 'meta_key' => self::CORRECTION_ACTIVE_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_value' => 1, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + 'fields' => 'ids', + 'orderby' => 'date', + 'order' => 'DESC', + ] + ); + + ob_start(); + foreach ( $post_ids as $post_id ) : + $corrections = get_post_meta( $post_id, self::CORRECTION_META, true ); + if ( empty( $corrections ) ) { + continue; + } + + ?> + +
+
+ + +
+ + +

+ : + +

+ +
+ +
+ + ID, self::CORRECTION_ACTIVE_META, true ); + $existing_corrections = get_post_meta( $post->ID, self::CORRECTION_META, true ); + if ( ! is_array( $existing_corrections ) ) { + $existing_corrections = []; + } + ?> + + +
+
+ + /> + Activate Corrections +
+
+
+ +
+

Article Correction

+
+

Date:

+ X +
+ +
+ +
+
+ + + + [ + 'flags' => FILTER_REQUIRE_ARRAY, + 'filter' => FILTER_SANITIZE_STRING, + ], + 'reveal_correction_date' => [ + 'flags' => FILTER_REQUIRE_ARRAY, + 'filter' => FILTER_SANITIZE_STRING, + ], + ] + ); + + $corrections = []; + foreach ( $corrections_data['reveal_correction'] as $index => $correction_text ) { + $corrections[] = [ + 'correction' => sanitize_textarea_field( $correction_text ), + 'date' => ! empty( $corrections_data['reveal_correction_date'][ $index ] ) ? sanitize_text_field( $corrections_data['reveal_correction_date'][ $index ] ) : gmdate( 'Y-m-d' ), + ]; + } + + update_post_meta( $post_id, self::CORRECTION_ACTIVE_META, $is_active ); + update_post_meta( $post_id, self::CORRECTION_META, $corrections ); + } + + /** + * Outputs corrections on the post content. + * + * @param string $content The post content. + * + * @return string The post content with corrections. + */ + public static function output_corrections_on_post( $content ) { + if ( is_admin() || ! is_single() ) { + return $content; + } + + $corrections_active = get_post_meta( get_the_ID(), self::CORRECTION_ACTIVE_META, true ); + if ( ! $corrections_active ) { + return $content; + } + + $corrections = get_post_meta( get_the_ID(), self::CORRECTION_META ) ?? []; + $has_valid_correction = false; + foreach ( $corrections as $correction ) { + if ( ! empty( trim( $correction['correction'] ) ) ) { + $has_valid_correction = true; + break; + } + } + + if ( ! $has_valid_correction ) { + return $content; + } + + ob_start(); + ?> + +
+
+ + +

+ + + +

+ + +
+
+ + Date: Wed, 18 Dec 2024 16:28:34 -0500 Subject: [PATCH 02/12] feat: add corrections custom post type --- includes/corrections/class-corrections.php | 74 +++++++++++++++++++++- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 032b01647a..651eed1ff0 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -11,6 +11,11 @@ * Class to handle Corrections and Clarifications. */ class Corrections { + /** + * Post type for corrections. + */ + const POST_TYPE = 'np_correction'; + /** * Meta key for storing corrections. */ @@ -28,10 +33,11 @@ public static function init() { if ( ! self::is_enabled() ) { return; } + add_action( 'init', [ __CLASS__, 'register_post_type' ] ); + add_action( 'init', [ __CLASS__, 'add_corrections_shortcode' ] ); add_action( 'add_meta_boxes', [ __CLASS__, 'add_corrections_metabox' ] ); add_action( 'save_post', [ __CLASS__, 'save_corrections_metabox' ] ); add_filter( 'the_content', [ __CLASS__, 'output_corrections_on_post' ] ); - add_action( 'init', [ __CLASS__, 'add_corrections_shortcode' ] ); } /** @@ -46,6 +52,68 @@ public static function is_enabled() { return defined( 'NEWSPACK_CORRECTIONS_ENABLED' ) && NEWSPACK_CORRECTIONS_ENABLED; } + /** + * Registers the corrections post type. + * + * @return void + */ + public static function register_post_type() { + $supports = [ + 'author', + 'editor', + 'title', + 'revisions', + ]; + + $labels = [ + 'name' => _x( 'Corrections', 'post type general name', 'newspack-plugin' ), + 'singular_name' => _x( 'Correction', 'post type singular name', 'newspack-plugin' ), + 'menu_name' => _x( 'Corrections', 'admin menu', 'newspack-plugin' ), + 'name_admin_bar' => _x( 'Correction', 'add new on admin bar', 'newspack-plugin' ), + 'add_new' => _x( 'Add New', 'correction', 'newspack-plugin' ), + 'add_new_item' => __( 'Add New Correction', 'newspack-plugin' ), + 'new_item' => __( 'New Correction', 'newspack-plugin' ), + 'edit_item' => __( 'Edit Correction', 'newspack-plugin' ), + 'view_item' => __( 'View Correction', 'newspack-plugin' ), + 'view_items' => __( 'View Correction', 'newspack-plugin' ), + 'all_items' => __( 'All Corrections', 'newspack-plugin' ), + 'search_items' => __( 'Search Corrections', 'newspack-plugin' ), + 'parent_item_colon' => __( 'Parent Correction:', 'newspack-plugin' ), + 'not_found' => __( 'No corrections found.', 'newspack-plugin' ), + 'not_found_in_trash' => __( 'No corrections found in Trash.', 'newspack-plugin' ), + 'archives' => __( 'Correction Archives', 'newspack-plugin' ), + 'attributes' => __( 'Correction Attributes', 'newspack-plugin' ), + 'insert_into_item' => __( 'Insert into correction', 'newspack-plugin' ), + 'uploaded_to_this_item' => __( 'Uploaded to this correction', 'newspack-plugin' ), + 'filter_items_list' => __( 'Filter corrections list', 'newspack-plugin' ), + 'items_list_navigation' => __( 'Corrections list navigation', 'newspack-plugin' ), + 'items_list' => __( 'Corrections list', 'newspack-plugin' ), + 'item_published' => __( 'Correction published.', 'newspack-plugin' ), + 'item_published_privately' => __( 'Correction published privately.', 'newspack-plugin' ), + 'item_reverted_to_draft' => __( 'Correction reverted to draft.', 'newspack-plugin' ), + 'item_scheduled' => __( 'Correction scheduled.', 'newspack-plugin' ), + 'item_updated' => __( 'Correction updated.', 'newspack-plugin' ), + 'item_link' => __( 'Correction Link', 'newspack-plugin' ), + 'item_link_description' => __( 'A link to a correction.', 'newspack-plugin' ), + ]; + + $args = array( + 'labels' => $labels, + 'description' => 'Post type used to store corrections and clarifications.', + 'has_archive' => true, + 'public' => true, + 'public_queryable' => true, + 'query_var' => true, + 'rewrite' => [ 'slug' => 'correction' ], + 'show_ui' => true, + 'show_in_rest' => true, + 'supports' => $supports, + 'taxonomies' => [], + 'menu_icon' => 'dashicons-edit', + ); + \register_post_type( self::POST_TYPE, $args ); + } + /** * Adds the corrections shortcode. */ @@ -94,8 +162,8 @@ public static function handle_corrections_shortcode() {

- - + + Date: Wed, 18 Dec 2024 17:44:43 -0500 Subject: [PATCH 03/12] fix: refactor scripts and styles --- includes/corrections/class-corrections.php | 166 +++++++++++---------- src/other-scripts/corrections/index.js | 34 +++++ src/other-scripts/corrections/style.scss | 37 +++++ 3 files changed, 158 insertions(+), 79 deletions(-) create mode 100644 src/other-scripts/corrections/index.js create mode 100644 src/other-scripts/corrections/style.scss diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 651eed1ff0..9ea69b9281 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -14,17 +14,17 @@ class Corrections { /** * Post type for corrections. */ - const POST_TYPE = 'np_correction'; + const POST_TYPE = 'newspack_correction'; /** * Meta key for storing corrections. */ - const CORRECTION_META = 'article-corrections'; + const POST_ID_META = 'newspack_correction-post-id'; /** - * Meta key for storing whether corrections are active. + * Meta key for corrections active postmeta. */ - const CORRECTION_ACTIVE_META = 'has_corrections'; + const CORRECTIONS_ACTIVE_META = 'newspack_corrections_active'; /** * Initializes the class. @@ -38,6 +38,8 @@ public static function init() { add_action( 'add_meta_boxes', [ __CLASS__, 'add_corrections_metabox' ] ); add_action( 'save_post', [ __CLASS__, 'save_corrections_metabox' ] ); add_filter( 'the_content', [ __CLASS__, 'output_corrections_on_post' ] ); + add_action( 'wp_enqueue_scripts', [ __CLASS__, 'wp_enqueue_scripts' ] ); + add_action( 'admin_enqueue_scripts', [ __CLASS__, 'wp_enqueue_scripts' ] ); } /** @@ -52,6 +54,29 @@ public static function is_enabled() { return defined( 'NEWSPACK_CORRECTIONS_ENABLED' ) && NEWSPACK_CORRECTIONS_ENABLED; } + + /** + * Enqueue scripts and styles. + */ + public static function wp_enqueue_scripts() { + if ( ! is_admin() || ! isset( $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification + return; + } + \wp_enqueue_script( + 'newspack-corrections', + Newspack::plugin_url() . '/dist/other-scripts/corrections.js', + [], + NEWSPACK_PLUGIN_VERSION, + true + ); + \wp_enqueue_style( + 'newspack-corrections', + Newspack::plugin_url() . '/dist/other-scripts/corrections.css', + [], + NEWSPACK_PLUGIN_VERSION + ); + } + /** * Registers the corrections post type. * @@ -63,6 +88,7 @@ public static function register_post_type() { 'editor', 'title', 'revisions', + 'custom-fields', ]; $labels = [ @@ -114,6 +140,48 @@ public static function register_post_type() { \register_post_type( self::POST_TYPE, $args ); } + /** + * Get corrections for post. + * + * @param int $post_id The post ID. + * + * @return array The corrections. + */ + public static function get_corrections( $post_id ) { + return get_posts( + [ + 'posts_per_page' => -1, + 'post_type' => self::POST_TYPE, + 'meta_key' => self::POST_ID_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_value' => $post_id, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + 'orderby' => 'date', + 'order' => 'DESC', + ] + ); + } + + /** + * Save corrections for post. + * + * @param int $post_id The post ID. + * @param array $corrections The corrections. + */ + public static function save_corrections( $post_id, $corrections ) { + foreach ( $corrections as $correction ) { + $post_id = wp_insert_post( + [ + 'post_title' => 'Correction for ' . get_the_title( $post_id ), + 'post_content' => $correction, + 'post_type' => self::POST_TYPE, + 'post_status' => 'publish', + 'meta_input' => [ + self::POST_ID_META => $post_id, + ], + ] + ); + } + } + /** * Adds the corrections shortcode. */ @@ -132,7 +200,7 @@ public static function handle_corrections_shortcode() { $post_ids = get_posts( [ 'posts_per_page' => -1, - 'meta_key' => self::CORRECTION_ACTIVE_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_key' => self::CORRECTIONS_ACTIVE_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key 'meta_value' => 1, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value 'fields' => 'ids', 'orderby' => 'date', @@ -142,7 +210,7 @@ public static function handle_corrections_shortcode() { ob_start(); foreach ( $post_ids as $post_id ) : - $corrections = get_post_meta( $post_id, self::CORRECTION_META, true ); + $corrections = self::get_corrections( $post_id ); if ( empty( $corrections ) ) { continue; } @@ -195,53 +263,13 @@ public static function add_corrections_metabox( $post_type ) { * @param \WP_Post $post The post object. */ public static function render_corrections_metabox( $post ) { - $is_active = (bool) get_post_meta( $post->ID, self::CORRECTION_ACTIVE_META, true ); - $existing_corrections = get_post_meta( $post->ID, self::CORRECTION_META, true ); - if ( ! is_array( $existing_corrections ) ) { - $existing_corrections = []; - } + $is_active = (bool) get_post_meta( $post->ID, self::CORRECTIONS_ACTIVE_META, true ); + $existing_corrections = self::get_corrections( $post->ID ); ?> - -
- - /> + + /> Activate Corrections
@@ -257,28 +285,9 @@ public static function render_corrections_metabox( $post ) {
- + - - - [ + 'correction' => [ 'flags' => FILTER_REQUIRE_ARRAY, 'filter' => FILTER_SANITIZE_STRING, ], - 'reveal_correction_date' => [ + 'correction_date' => [ 'flags' => FILTER_REQUIRE_ARRAY, 'filter' => FILTER_SANITIZE_STRING, ], @@ -316,8 +324,8 @@ public static function save_corrections_metabox( $post_id ) { ]; } - update_post_meta( $post_id, self::CORRECTION_ACTIVE_META, $is_active ); - update_post_meta( $post_id, self::CORRECTION_META, $corrections ); + self::save_corrections( $post_id, $corrections ); + update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, true ); } /** @@ -332,12 +340,12 @@ public static function output_corrections_on_post( $content ) { return $content; } - $corrections_active = get_post_meta( get_the_ID(), self::CORRECTION_ACTIVE_META, true ); + $corrections_active = get_post_meta( get_the_ID(), self::CORRECTIONS_ACTIVE_META, true ); if ( ! $corrections_active ) { return $content; } - $corrections = get_post_meta( get_the_ID(), self::CORRECTION_META ) ?? []; + $corrections = self::get_corrections( get_the_ID() ); $has_valid_correction = false; foreach ( $corrections as $correction ) { if ( ! empty( trim( $correction['correction'] ) ) ) { diff --git a/src/other-scripts/corrections/index.js b/src/other-scripts/corrections/index.js new file mode 100644 index 0000000000..b101ee27dd --- /dev/null +++ b/src/other-scripts/corrections/index.js @@ -0,0 +1,34 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { domReady } from '../../utils'; +import './style.scss'; + +domReady( () => { + // Handle admin metabox for article corrections. + const metaboxContainer = document.querySelector( '.corrections-metabox-container' ); + if ( metaboxContainer ) { + metaboxContainer.querySelector( 'button.add-correction' ).addEventListener( 'click', () => { + const existingCorrections = metaboxContainer.querySelector( '.existing-corrections' ); + const newCorrection = document.createElement( 'div' ); + newCorrection.classList.add( 'reveal-correction' ); + newCorrection.innerHTML = ` +

${ __( 'Article Correction', 'newspack-plugin' ) }

+ +
+

${ __( 'Date:', 'newspack-plugin' ) }

+ X + `; + existingCorrections.appendChild( newCorrection ); + newCorrection.querySelector( 'span.delete-correction' ).addEventListener( 'click', () => { + newCorrection.remove(); + } ); + } ); + } +} ); + diff --git a/src/other-scripts/corrections/style.scss b/src/other-scripts/corrections/style.scss new file mode 100644 index 0000000000..0e02b6602e --- /dev/null +++ b/src/other-scripts/corrections/style.scss @@ -0,0 +1,37 @@ +// Admin metabox styles +.corrections-metabox-container { + .activate-corrections { + padding-top: 1em; + padding-bottom: 1em; + border-bottom: 2px solid silver; + margin-bottom: 1em; + } + + .reveal-correction { + position: relative; + border-bottom: 1px solid silver; + padding-top: 1em; + padding-bottom: 1em; + } + + .add-correction { + margin-top: 2em; + cursor: pointer; + } + + .delete-correction { + position: absolute; + top: 2em; + right: 2em; + font-weight: bold; + color: silver; + border: 1px solid silver; + padding-left: 0.25em; + padding-right: 0.25em; + cursor: pointer; + } + + .delete-correction:hover { + color: red; + } +} From efdc46c2af3e4c402be429cbc876638a20db26d2 Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Tue, 7 Jan 2025 17:36:39 -0500 Subject: [PATCH 04/12] feat(corrections): render on frontend --- includes/corrections/class-corrections.php | 146 +++++++++++++-------- src/other-scripts/corrections/index.js | 39 +++++- src/other-scripts/corrections/style.scss | 6 +- 3 files changed, 128 insertions(+), 63 deletions(-) diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 9ea69b9281..a5f6ea5fab 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -17,12 +17,17 @@ class Corrections { const POST_TYPE = 'newspack_correction'; /** - * Meta key for storing corrections. + * Meta key for correction date meta. */ - const POST_ID_META = 'newspack_correction-post-id'; + const CORRECTION_DATE_META = 'newspack_correction_date'; /** - * Meta key for corrections active postmeta. + * Meta key for correction post ID meta. + */ + const CORRECTION_POST_ID_META = 'newspack_correction-post-id'; + + /** + * Meta key for post corrections active meta. */ const CORRECTIONS_ACTIVE_META = 'newspack_corrections_active'; @@ -152,7 +157,7 @@ public static function get_corrections( $post_id ) { [ 'posts_per_page' => -1, 'post_type' => self::POST_TYPE, - 'meta_key' => self::POST_ID_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_key' => self::CORRECTION_POST_ID_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key 'meta_value' => $post_id, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value 'orderby' => 'date', 'order' => 'DESC', @@ -171,17 +176,29 @@ public static function save_corrections( $post_id, $corrections ) { $post_id = wp_insert_post( [ 'post_title' => 'Correction for ' . get_the_title( $post_id ), - 'post_content' => $correction, + 'post_content' => $correction['content'], 'post_type' => self::POST_TYPE, 'post_status' => 'publish', 'meta_input' => [ - self::POST_ID_META => $post_id, + self::CORRECTION_POST_ID_META => $post_id, + self::CORRECTION_DATE_META => $correction['date'], ], ] ); } } + /** + * Delete corrections for post. + * + * @param array $correction_ids Correction IDs. + */ + public static function delete_corrections( $correction_ids ) { + foreach ( $correction_ids as $id ) { + wp_delete_post( $id, true ); + } + } + /** * Adds the corrections shortcode. */ @@ -247,7 +264,7 @@ public static function add_corrections_metabox( $post_type ) { $valid_post_types = [ 'article_legacy', 'content_type_blog', 'post', 'press_release' ]; if ( in_array( $post_type, $valid_post_types, true ) ) { add_meta_box( - 'reveal_corrections', + 'corrections', 'Corrections', [ __CLASS__, 'render_corrections_metabox' ], $post_type, @@ -263,29 +280,37 @@ public static function add_corrections_metabox( $post_type ) { * @param \WP_Post $post The post object. */ public static function render_corrections_metabox( $post ) { - $is_active = (bool) get_post_meta( $post->ID, self::CORRECTIONS_ACTIVE_META, true ); - $existing_corrections = self::get_corrections( $post->ID ); + $is_active = (bool) get_post_meta( $post->ID, self::CORRECTIONS_ACTIVE_META, true ); + $corrections = self::get_corrections( $post->ID ); ?>
/> - Activate Corrections +
-
- -
-

Article Correction

-
-

Date:

- X -
+
+ post_content; + $correction_date = get_post_meta( $correction->ID, self::CORRECTION_DATE_META, true ); + ?> +
+

+ +
+

+ + +

+ +
-
- + +
+
+
[ + 'new-corrections' => [ 'flags' => FILTER_REQUIRE_ARRAY, 'filter' => FILTER_SANITIZE_STRING, ], - 'correction_date' => [ + 'deleted-corrections' => [ 'flags' => FILTER_REQUIRE_ARRAY, - 'filter' => FILTER_SANITIZE_STRING, + 'filter' => FILTER_SANITIZE_NUMBER_INT, ], + self::CORRECTIONS_ACTIVE_META => FILTER_SANITIZE_NUMBER_INT, ] ); - - $corrections = []; - foreach ( $corrections_data['reveal_correction'] as $index => $correction_text ) { - $corrections[] = [ - 'correction' => sanitize_textarea_field( $correction_text ), - 'date' => ! empty( $corrections_data['reveal_correction_date'][ $index ] ) ? sanitize_text_field( $corrections_data['reveal_correction_date'][ $index ] ) : gmdate( 'Y-m-d' ), - ]; + // Return early if there is no corrections data. + if ( ! $corrections_data ) { + return; + } + // Save new corrections if present. + if ( ! empty( $corrections_data['new-corrections'] ) ) { + $corrections = []; + foreach ( $corrections_data['new-corrections'] as $correction ) { + // Don't save empty corrections. + if ( empty( trim( $correction['content'] ) ) ) { + continue; + } + $corrections[] = [ + 'content' => sanitize_textarea_field( $correction['content'] ), + 'date' => ! empty( $correction['date'] ) ? sanitize_text_field( $correction['date'] ) : gmdate( 'Y-m-d' ), + ]; + } + self::save_corrections( $post_id, $corrections ); + } + // Delete corrections if present. + if ( ! empty( $corrections_data['deleted-corrections'] ) ) { + $correction_ids = array_map( 'intval', $corrections_data['deleted-corrections'] ); + self::delete_corrections( $correction_ids ); + } + // Update active flag if present. + if ( isset( $corrections_data[ self::CORRECTIONS_ACTIVE_META ] ) ) { + update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, (bool) $corrections_data[ self::CORRECTIONS_ACTIVE_META ] ); } - - self::save_corrections( $post_id, $corrections ); - update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, true ); } /** @@ -340,21 +383,12 @@ public static function output_corrections_on_post( $content ) { return $content; } - $corrections_active = get_post_meta( get_the_ID(), self::CORRECTIONS_ACTIVE_META, true ); - if ( ! $corrections_active ) { + if ( ! (bool) get_post_meta( get_the_ID(), self::CORRECTIONS_ACTIVE_META, true ) ) { return $content; } - $corrections = self::get_corrections( get_the_ID() ); - $has_valid_correction = false; - foreach ( $corrections as $correction ) { - if ( ! empty( trim( $correction['correction'] ) ) ) { - $has_valid_correction = true; - break; - } - } - - if ( ! $has_valid_correction ) { + $corrections = self::get_corrections( get_the_ID() ); + if ( empty( $corrections ) ) { return $content; } @@ -365,18 +399,20 @@ public static function output_corrections_on_post( $content ) {
post_content; + $correction_date = get_post_meta( $correction->ID, self::CORRECTION_DATE_META, true ); + $correction_heading = sprintf( + // translators: %s: correction date. + __( 'Correction on %s', 'newspack-plugin' ), + gmdate( 'M j, Y', strtotime( $correction_date ) ) + ); ?>

-

+

diff --git a/src/other-scripts/corrections/index.js b/src/other-scripts/corrections/index.js index b101ee27dd..adb1688919 100644 --- a/src/other-scripts/corrections/index.js +++ b/src/other-scripts/corrections/index.js @@ -13,21 +13,46 @@ domReady( () => { // Handle admin metabox for article corrections. const metaboxContainer = document.querySelector( '.corrections-metabox-container' ); if ( metaboxContainer ) { + // Handle deletion of existing corrections. + metaboxContainer.querySelectorAll( '.existing-corrections button.delete-correction' ) + .forEach( button => { + button.addEventListener( 'click', e => { + // Get the partent .correction element. + const correction = e.target.closest( '.correction' ); + if ( correction ) { + correction.remove(); + const correctionId = correction.getAttribute( 'name' ).replace( 'existing-corrections[', '' ).replace( ']', '' ); + if ( correctionId ) { + const deletedCorrections = metaboxContainer.querySelector( '.deleted-corrections' ); + const deletedCorrection = document.createElement( 'input' ); + deletedCorrection.type = 'hidden'; + deletedCorrection.name = 'deleted-corrections[]'; + deletedCorrection.value = correctionId; + deletedCorrections.appendChild( deletedCorrection ); + } + } + } ); + } ); + // Handle addition of new corrections. + let newCorrectionsCount = 0; metaboxContainer.querySelector( 'button.add-correction' ).addEventListener( 'click', () => { - const existingCorrections = metaboxContainer.querySelector( '.existing-corrections' ); + const newCorrections = metaboxContainer.querySelector( '.new-corrections' ); const newCorrection = document.createElement( 'div' ); - newCorrection.classList.add( 'reveal-correction' ); + newCorrection.classList.add( 'correction' ); newCorrection.innerHTML = ` +

${ __( 'Article Correction', 'newspack-plugin' ) }

- +
-

${ __( 'Date:', 'newspack-plugin' ) }

- X +

${ __( 'Date:', 'newspack-plugin' ) }

+ +
`; - existingCorrections.appendChild( newCorrection ); - newCorrection.querySelector( 'span.delete-correction' ).addEventListener( 'click', () => { + newCorrections.appendChild( newCorrection ); + newCorrection.querySelector( 'button.delete-correction' ).addEventListener( 'click', () => { newCorrection.remove(); } ); + newCorrectionsCount++; } ); } } ); diff --git a/src/other-scripts/corrections/style.scss b/src/other-scripts/corrections/style.scss index 0e02b6602e..f47740bbf4 100644 --- a/src/other-scripts/corrections/style.scss +++ b/src/other-scripts/corrections/style.scss @@ -7,7 +7,11 @@ margin-bottom: 1em; } - .reveal-correction { + .deleted-corrections { + visibility: hidden; + } + + .correction { position: relative; border-bottom: 1px solid silver; padding-top: 1em; From af063302b840cdfc0451890d8338df1dae4eb611 Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Tue, 7 Jan 2025 17:45:08 -0500 Subject: [PATCH 05/12] fix(corrections): handle shortcode --- includes/corrections/class-corrections.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index a5f6ea5fab..63aaaa8f12 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -239,11 +239,19 @@ public static function handle_corrections_shortcode() {
- - + post_content; + $correction_date = get_post_meta( $correction->ID, self::CORRECTION_DATE_META, true ); + $correction_heading = sprintf( + // translators: %s: correction date. + __( 'Correction on %s', 'newspack-plugin' ), + gmdate( 'M j, Y', strtotime( $correction_date ) ) + ); + ?>

: - +

From 0208f5de8acc8a01fb929c55b466e4f397397145 Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Tue, 7 Jan 2025 17:53:48 -0500 Subject: [PATCH 06/12] fix: filter get input --- includes/corrections/class-corrections.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 63aaaa8f12..90994e7e4e 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -64,9 +64,10 @@ public static function is_enabled() { * Enqueue scripts and styles. */ public static function wp_enqueue_scripts() { - if ( ! is_admin() || ! isset( $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification + if ( ! is_admin() || ! filter_input( INPUT_GET, 'post', FILTER_VALIDATE_INT ) ) { return; } + \wp_enqueue_script( 'newspack-corrections', Newspack::plugin_url() . '/dist/other-scripts/corrections.js', From 4bae5aa6457a2f3b4b23a5bfa8c9bce5fa8231ed Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Wed, 8 Jan 2025 14:43:21 -0500 Subject: [PATCH 07/12] feat: update corrections --- includes/corrections/class-corrections.php | 80 ++++++++++++++++++---- 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 90994e7e4e..8c4c242489 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -31,6 +31,11 @@ class Corrections { */ const CORRECTIONS_ACTIVE_META = 'newspack_corrections_active'; + /** + * Meta key for post corrections ids meta. + */ + const CORRECTIONS_IDS_META = 'newspack_corrections_ids'; + /** * Initializes the class. */ @@ -154,14 +159,15 @@ public static function register_post_type() { * @return array The corrections. */ public static function get_corrections( $post_id ) { + $correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); + if ( ! is_array( $correction_ids ) ) { + return []; + } return get_posts( [ 'posts_per_page' => -1, 'post_type' => self::POST_TYPE, - 'meta_key' => self::CORRECTION_POST_ID_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key - 'meta_value' => $post_id, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value - 'orderby' => 'date', - 'order' => 'DESC', + 'include' => $correction_ids, ] ); } @@ -173,8 +179,12 @@ public static function get_corrections( $post_id ) { * @param array $corrections The corrections. */ public static function save_corrections( $post_id, $corrections ) { + $correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); + if ( ! is_array( $correction_ids ) ) { + $correction_ids = []; + } foreach ( $corrections as $correction ) { - $post_id = wp_insert_post( + $id = wp_insert_post( [ 'post_title' => 'Correction for ' . get_the_title( $post_id ), 'post_content' => $correction['content'], @@ -186,7 +196,27 @@ public static function save_corrections( $post_id, $corrections ) { ], ] ); + if ( ! \is_wp_error( $id ) ) { + $correction_ids[] = $id; + } } + update_post_meta( $post_id, self::CORRECTIONS_IDS_META, $correction_ids ); + } + + /** + * Update correction. + * + * @param int $correction_id The post ID. + * @param array $correction The correction. + */ + public static function update_correction( $correction_id, $correction ) { + wp_update_post( + [ + 'ID' => $correction_id, + 'post_content' => sanitize_textarea_field( $correction['content'] ), + ] + ); + update_post_meta( $correction_id, self::CORRECTION_DATE_META, sanitize_text_field( $correction['date'] ) ); } /** @@ -195,9 +225,17 @@ public static function save_corrections( $post_id, $corrections ) { * @param array $correction_ids Correction IDs. */ public static function delete_corrections( $correction_ids ) { + $stored_correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); + if ( ! is_array( $stored_correction_ids ) ) { + $stored_correction_ids = []; + } foreach ( $correction_ids as $id ) { wp_delete_post( $id, true ); + if ( isset( $stored_correction_ids[ $id ] ) ) { + unset( $stored_correction_ids[ $id ] ); + } } + update_post_meta( $post_id, self::CORRECTIONS_IDS_META, $stored_correction_ids ); } /** @@ -336,24 +374,42 @@ public static function save_corrections_metabox( $post_id ) { return; } - $corrections_data = filter_input_array( + $corrections_active = filter_input( INPUT_POST, self::CORRECTIONS_ACTIVE_META, FILTER_VALIDATE_BOOLEAN ); + $corrections_data = filter_input_array( INPUT_POST, [ - 'new-corrections' => [ + 'existing-corrections' => [ + 'flags' => FILTER_REQUIRE_ARRAY, + 'filter' => FILTER_SANITIZE_STRING, + ], + 'new-corrections' => [ 'flags' => FILTER_REQUIRE_ARRAY, 'filter' => FILTER_SANITIZE_STRING, ], - 'deleted-corrections' => [ + 'deleted-corrections' => [ 'flags' => FILTER_REQUIRE_ARRAY, 'filter' => FILTER_SANITIZE_NUMBER_INT, ], - self::CORRECTIONS_ACTIVE_META => FILTER_SANITIZE_NUMBER_INT, ] ); // Return early if there is no corrections data. - if ( ! $corrections_data ) { + if ( false === $corrections_active && empty( $corrections_data ) ) { return; } + // Update active flag if present. + if ( (bool) $corrections_active !== (bool) get_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, true ) ) { + update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, (bool) $corrections_active ); + } + // Update existing corrections if present. + if ( ! empty( $corrections_data['existing-corrections'] ) ) { + foreach ( $corrections_data['existing-corrections'] as $correction_id => $correction ) { + // Don't save empty corrections. + if ( empty( trim( $correction['content'] ) ) ) { + continue; + } + self::update_correction( $correction_id, $correction ); + } + } // Save new corrections if present. if ( ! empty( $corrections_data['new-corrections'] ) ) { $corrections = []; @@ -374,10 +430,6 @@ public static function save_corrections_metabox( $post_id ) { $correction_ids = array_map( 'intval', $corrections_data['deleted-corrections'] ); self::delete_corrections( $correction_ids ); } - // Update active flag if present. - if ( isset( $corrections_data[ self::CORRECTIONS_ACTIVE_META ] ) ) { - update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, (bool) $corrections_data[ self::CORRECTIONS_ACTIVE_META ] ); - } } /** From 94659b0f97fb9954cd38934c9529ed4f2ea571c8 Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Wed, 8 Jan 2025 16:00:50 -0500 Subject: [PATCH 08/12] feat: add location --- includes/corrections/class-corrections.php | 72 +++++++++++++--------- src/other-scripts/corrections/index.js | 12 ++++ 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 8c4c242489..4b00262f14 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -31,6 +31,11 @@ class Corrections { */ const CORRECTIONS_ACTIVE_META = 'newspack_corrections_active'; + /** + * Meta key for post corrections location meta. + */ + const CORRECTIONS_LOCATION_META = 'newspack_corrections_location'; + /** * Meta key for post corrections ids meta. */ @@ -101,7 +106,6 @@ public static function register_post_type() { 'revisions', 'custom-fields', ]; - $labels = [ 'name' => _x( 'Corrections', 'post type general name', 'newspack-plugin' ), 'singular_name' => _x( 'Correction', 'post type singular name', 'newspack-plugin' ), @@ -133,7 +137,6 @@ public static function register_post_type() { 'item_link' => __( 'Correction Link', 'newspack-plugin' ), 'item_link_description' => __( 'A link to a correction.', 'newspack-plugin' ), ]; - $args = array( 'labels' => $labels, 'description' => 'Post type used to store corrections and clarifications.', @@ -206,8 +209,8 @@ public static function save_corrections( $post_id, $corrections ) { /** * Update correction. * - * @param int $correction_id The post ID. - * @param array $correction The correction. + * @param int $correction_id the post id. + * @param array $correction the correction. */ public static function update_correction( $correction_id, $correction ) { wp_update_post( @@ -222,7 +225,7 @@ public static function update_correction( $correction_id, $correction ) { /** * Delete corrections for post. * - * @param array $correction_ids Correction IDs. + * @param array $correction_ids correction ids. */ public static function delete_corrections( $correction_ids ) { $stored_correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); @@ -248,7 +251,7 @@ public static function add_corrections_shortcode() { /** * Handles the corrections shortcode. * - * @return string The shortcode output. + * @return string the shortcode output. */ public static function handle_corrections_shortcode() { global $wpdb; @@ -256,7 +259,7 @@ public static function handle_corrections_shortcode() { $post_ids = get_posts( [ 'posts_per_page' => -1, - 'meta_key' => self::CORRECTIONS_ACTIVE_META, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_key' => self::CORRECTIONS_ACTIVE_META, 'meta_value' => 1, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value 'fields' => 'ids', 'orderby' => 'date', @@ -305,7 +308,7 @@ public static function handle_corrections_shortcode() { /** * Adds the corrections metabox. * - * @param string $post_type The post type. + * @param string $post_type the post type. */ public static function add_corrections_metabox( $post_type ) { $valid_post_types = [ 'article_legacy', 'content_type_blog', 'post', 'press_release' ]; @@ -324,17 +327,25 @@ public static function add_corrections_metabox( $post_type ) { /** * Renders the corrections metabox. * - * @param \WP_Post $post The post object. + * @param \WP_Post $post the post object. */ public static function render_corrections_metabox( $post ) { $is_active = (bool) get_post_meta( $post->ID, self::CORRECTIONS_ACTIVE_META, true ); + $location = get_post_meta( $post->ID, self::CORRECTIONS_LOCATION_META, true ); $corrections = self::get_corrections( $post->ID ); ?>
- /> - + /> + +
+
+
@@ -366,25 +377,26 @@ public static function render_corrections_metabox( $post ) { /** * Saves the corrections metabox. * - * @param int $post_id The post ID. + * @param int $post_id the post id. */ public static function save_corrections_metabox( $post_id ) { - // Return early if we are saving a correction. + // return early if we are saving a correction. if ( self::POST_TYPE === get_post_type( $post_id ) ) { return; } - $corrections_active = filter_input( INPUT_POST, self::CORRECTIONS_ACTIVE_META, FILTER_VALIDATE_BOOLEAN ); - $corrections_data = filter_input_array( + $corrections_active = filter_input( INPUT_POST, self::CORRECTIONS_ACTIVE_META, FILTER_VALIDATE_BOOLEAN ); + $corrections_location = filter_input( INPUT_POST, self::CORRECTIONS_LOCATION_META, FILTER_SANITIZE_STRING ); + $corrections_data = filter_input_array( INPUT_POST, [ 'existing-corrections' => [ 'flags' => FILTER_REQUIRE_ARRAY, - 'filter' => FILTER_SANITIZE_STRING, + 'filter' => FILTER_DEFAULT, ], 'new-corrections' => [ 'flags' => FILTER_REQUIRE_ARRAY, - 'filter' => FILTER_SANITIZE_STRING, + 'filter' => FILTER_DEFAULT, ], 'deleted-corrections' => [ 'flags' => FILTER_REQUIRE_ARRAY, @@ -392,29 +404,33 @@ public static function save_corrections_metabox( $post_id ) { ], ] ); - // Return early if there is no corrections data. - if ( false === $corrections_active && empty( $corrections_data ) ) { + // return early if there is no corrections data. + if ( false === $corrections_active && false === $corrections_location && empty( $corrections_data ) ) { return; } - // Update active flag if present. + // update active flag if present. if ( (bool) $corrections_active !== (bool) get_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, true ) ) { update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, (bool) $corrections_active ); } - // Update existing corrections if present. + // update location flag if present. + if ( $corrections_location !== get_post_meta( $post_id, self::CORRECTIONS_LOCATION_META, true ) ) { + update_post_meta( $post_id, self::CORRECTIONS_LOCATION_META, sanitize_text_field( $corrections_location ) ); + } + // update existing corrections if present. if ( ! empty( $corrections_data['existing-corrections'] ) ) { foreach ( $corrections_data['existing-corrections'] as $correction_id => $correction ) { - // Don't save empty corrections. + // don't save empty corrections. if ( empty( trim( $correction['content'] ) ) ) { continue; } self::update_correction( $correction_id, $correction ); } } - // Save new corrections if present. + // save new corrections if present. if ( ! empty( $corrections_data['new-corrections'] ) ) { $corrections = []; foreach ( $corrections_data['new-corrections'] as $correction ) { - // Don't save empty corrections. + // don't save empty corrections. if ( empty( trim( $correction['content'] ) ) ) { continue; } @@ -425,7 +441,7 @@ public static function save_corrections_metabox( $post_id ) { } self::save_corrections( $post_id, $corrections ); } - // Delete corrections if present. + // delete corrections if present. if ( ! empty( $corrections_data['deleted-corrections'] ) ) { $correction_ids = array_map( 'intval', $corrections_data['deleted-corrections'] ); self::delete_corrections( $correction_ids ); @@ -435,9 +451,9 @@ public static function save_corrections_metabox( $post_id ) { /** * Outputs corrections on the post content. * - * @param string $content The post content. + * @param string $content the post content. * - * @return string The post content with corrections. + * @return string the post content with corrections. */ public static function output_corrections_on_post( $content ) { if ( is_admin() || ! is_single() ) { @@ -481,7 +497,7 @@ public static function output_corrections_on_post( $content ) { { // Handle admin metabox for article corrections. const metaboxContainer = document.querySelector( '.corrections-metabox-container' ); if ( metaboxContainer ) { + // Handle displaying location select. + const activateCorrections = metaboxContainer.querySelector( 'input.activate-corrections-checkbox' ); + const locationSelect = metaboxContainer.querySelector( '.display-corrections' ); + locationSelect.style.display = activateCorrections.checked ? 'block' : 'none'; + activateCorrections.addEventListener( 'change', () => { + if ( activateCorrections.checked ) { + locationSelect.style.display = 'block'; + } else { + locationSelect.style.display = 'none'; + } + } ); + // Handle deletion of existing corrections. metaboxContainer.querySelectorAll( '.existing-corrections button.delete-correction' ) .forEach( button => { From 6aed1c0e69ffcfc18bfa4c3e98f262c252b9b80d Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Wed, 8 Jan 2025 17:25:33 -0500 Subject: [PATCH 09/12] fix: reload on new correction --- src/other-scripts/corrections/index.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/other-scripts/corrections/index.js b/src/other-scripts/corrections/index.js index 6b712e73ed..f721c2da3a 100644 --- a/src/other-scripts/corrections/index.js +++ b/src/other-scripts/corrections/index.js @@ -2,6 +2,7 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; +import { select, subscribe } from '@wordpress/data'; /** * Internal dependencies @@ -24,7 +25,6 @@ domReady( () => { locationSelect.style.display = 'none'; } } ); - // Handle deletion of existing corrections. metaboxContainer.querySelectorAll( '.existing-corrections button.delete-correction' ) .forEach( button => { @@ -66,6 +66,26 @@ domReady( () => { } ); newCorrectionsCount++; } ); + // Handle saving the post. + let hasSavedPost = false; + const unsubscribe = subscribe( () => { + // Return early if no new corrections have been added. + if ( ! newCorrectionsCount ) { + return; + } + const isSavingPost = select( 'core/editor' ).isSavingPost(); + const isAutosavingPost = select('core/editor').isAutosavingPost(); + + if ( isSavingPost && ! isAutosavingPost && ! hasSavedPost ) { + hasSavedPost = true; + } + + if ( ! isSavingPost && hasSavedPost ) { + // Unsubscribe from the store. + unsubscribe(); + window.location.href = window.location.href; + } + } ); } } ); From fea98909ba23a62584c9f97bd3a2adc97bf1be2e Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Thu, 9 Jan 2025 11:43:31 -0500 Subject: [PATCH 10/12] fix: add readme and fix errors --- includes/corrections/README.md | 34 ++++++++++++++ includes/corrections/class-corrections.php | 53 +++++++++++----------- 2 files changed, 61 insertions(+), 26 deletions(-) create mode 100644 includes/corrections/README.md diff --git a/includes/corrections/README.md b/includes/corrections/README.md new file mode 100644 index 0000000000..b878c37ce8 --- /dev/null +++ b/includes/corrections/README.md @@ -0,0 +1,34 @@ +# Corrections + +This feature allows authors to add article corrections to the top or bottom of a post. + +## How it works + +When you enable this feature, a new meta box will be added to the post editor screen. You can use this meta box to add a correction to the post. The correction will be displayed at the top or bottom of the post, depending on the settings. + +## Usage + +This feature can be enabled by adding the following constant to your `wp-config.php`: + +```php +define( 'NEWSPACK_CORRECTIONS_ENABLED', true ); +``` + +## Data + +Corrections are stored as `newspack_correction` custom post type. A correction consists of the following fields: + +| Name | Type | Stored As | Description | +| ----------------------------- | -------- | -------------- | --------------------------------------------------------------- | +| `title` | `string` | `post_title` | The correction title. Defaults to 'Correction for [post title]' | +| `content` | `string` | `post_content` | The correction text. | +| `newspack_correction_date` | `string` | `post_meta` | Correction date. Note this is different from the post date. | +| `newspack_correction-post-id` | `int` | `post_meta` | The ID of the post to which the correction is associated. | + +In addition, some correction data is stored in the associated post as post meta: + +| Name | Type | Stored As | Description | +| ------------------------------- | ----------------------- | ----------- | ------------------------------------------------------------- | +| `newspack_corrections_active` | `bool` | `post_meta` | Whether the feature is enabled for the post. | +| `newspack_corrections_location` | `string` | `post_meta` | Where the correction should be displayed. (`top` or `bottom`) | +| `newspack_corrections_ids` | `array` | `post_meta` | An array of IDs of the corrections associated with the post. | diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 4b00262f14..775677487e 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -145,7 +145,7 @@ public static function register_post_type() { 'public_queryable' => true, 'query_var' => true, 'rewrite' => [ 'slug' => 'correction' ], - 'show_ui' => true, + 'show_ui' => false, 'show_in_rest' => true, 'supports' => $supports, 'taxonomies' => [], @@ -154,34 +154,13 @@ public static function register_post_type() { \register_post_type( self::POST_TYPE, $args ); } - /** - * Get corrections for post. - * - * @param int $post_id The post ID. - * - * @return array The corrections. - */ - public static function get_corrections( $post_id ) { - $correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); - if ( ! is_array( $correction_ids ) ) { - return []; - } - return get_posts( - [ - 'posts_per_page' => -1, - 'post_type' => self::POST_TYPE, - 'include' => $correction_ids, - ] - ); - } - /** * Save corrections for post. * * @param int $post_id The post ID. * @param array $corrections The corrections. */ - public static function save_corrections( $post_id, $corrections ) { + public static function add_corrections( $post_id, $corrections ) { $correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); if ( ! is_array( $correction_ids ) ) { $correction_ids = []; @@ -206,6 +185,27 @@ public static function save_corrections( $post_id, $corrections ) { update_post_meta( $post_id, self::CORRECTIONS_IDS_META, $correction_ids ); } + /** + * Get corrections for post. + * + * @param int $post_id The post ID. + * + * @return array The corrections. + */ + public static function get_corrections( $post_id ) { + $correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); + if ( ! is_array( $correction_ids ) ) { + return []; + } + return get_posts( + [ + 'posts_per_page' => -1, + 'post_type' => self::POST_TYPE, + 'include' => $correction_ids, + ] + ); + } + /** * Update correction. * @@ -225,9 +225,10 @@ public static function update_correction( $correction_id, $correction ) { /** * Delete corrections for post. * + * @param int $post_id the post id. * @param array $correction_ids correction ids. */ - public static function delete_corrections( $correction_ids ) { + public static function delete_corrections( $post_id, $correction_ids ) { $stored_correction_ids = get_post_meta( $post_id, self::CORRECTIONS_IDS_META, true ); if ( ! is_array( $stored_correction_ids ) ) { $stored_correction_ids = []; @@ -439,12 +440,12 @@ public static function save_corrections_metabox( $post_id ) { 'date' => ! empty( $correction['date'] ) ? sanitize_text_field( $correction['date'] ) : gmdate( 'Y-m-d' ), ]; } - self::save_corrections( $post_id, $corrections ); + self::add_corrections( $post_id, $corrections ); } // delete corrections if present. if ( ! empty( $corrections_data['deleted-corrections'] ) ) { $correction_ids = array_map( 'intval', $corrections_data['deleted-corrections'] ); - self::delete_corrections( $correction_ids ); + self::delete_corrections( $post_id, $correction_ids ); } } From 13dbe298c90b8fd99b6766138d43d8a3cb91179d Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Thu, 9 Jan 2025 12:48:30 -0500 Subject: [PATCH 11/12] fix: use post_date to store correction date --- includes/corrections/README.md | 2 +- includes/corrections/class-corrections.php | 19 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/includes/corrections/README.md b/includes/corrections/README.md index b878c37ce8..101094a4df 100644 --- a/includes/corrections/README.md +++ b/includes/corrections/README.md @@ -22,7 +22,7 @@ Corrections are stored as `newspack_correction` custom post type. A correction c | ----------------------------- | -------- | -------------- | --------------------------------------------------------------- | | `title` | `string` | `post_title` | The correction title. Defaults to 'Correction for [post title]' | | `content` | `string` | `post_content` | The correction text. | -| `newspack_correction_date` | `string` | `post_meta` | Correction date. Note this is different from the post date. | +| `date` | `string` | `post_date` | The date assigned to the correction. | | `newspack_correction-post-id` | `int` | `post_meta` | The ID of the post to which the correction is associated. | In addition, some correction data is stored in the associated post as post meta: diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index 775677487e..e71e4b5bbe 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -16,11 +16,6 @@ class Corrections { */ const POST_TYPE = 'newspack_correction'; - /** - * Meta key for correction date meta. - */ - const CORRECTION_DATE_META = 'newspack_correction_date'; - /** * Meta key for correction post ID meta. */ @@ -170,11 +165,11 @@ public static function add_corrections( $post_id, $corrections ) { [ 'post_title' => 'Correction for ' . get_the_title( $post_id ), 'post_content' => $correction['content'], + 'post_date' => $correction['date'], 'post_type' => self::POST_TYPE, 'post_status' => 'publish', 'meta_input' => [ self::CORRECTION_POST_ID_META => $post_id, - self::CORRECTION_DATE_META => $correction['date'], ], ] ); @@ -217,9 +212,9 @@ public static function update_correction( $correction_id, $correction ) { [ 'ID' => $correction_id, 'post_content' => sanitize_textarea_field( $correction['content'] ), + 'post_date' => sanitize_text_field( $correction['date'] ), ] ); - update_post_meta( $correction_id, self::CORRECTION_DATE_META, sanitize_text_field( $correction['date'] ) ); } /** @@ -285,11 +280,11 @@ public static function handle_corrections_shortcode() { post_content; - $correction_date = get_post_meta( $correction->ID, self::CORRECTION_DATE_META, true ); + $correction_date = \get_the_date( 'M j, Y', $correction->ID ); $correction_heading = sprintf( // translators: %s: correction date. __( 'Correction on %s', 'newspack-plugin' ), - gmdate( 'M j, Y', strtotime( $correction_date ) ) + $correction_date ); ?>

@@ -353,7 +348,7 @@ public static function render_corrections_metabox( $post ) { post_content; - $correction_date = get_post_meta( $correction->ID, self::CORRECTION_DATE_META, true ); + $correction_date = \get_the_date( 'Y-m-d', $correction->ID ); ?>

@@ -478,11 +473,11 @@ public static function output_corrections_on_post( $content ) { post_content; - $correction_date = get_post_meta( $correction->ID, self::CORRECTION_DATE_META, true ); + $correction_date = \get_the_date( 'M j, Y', $correction->ID ); $correction_heading = sprintf( // translators: %s: correction date. __( 'Correction on %s', 'newspack-plugin' ), - gmdate( 'M j, Y', strtotime( $correction_date ) ) + $correction_date ); ?> From 0017f165072eeff547e70d7efd5fc08893749b88 Mon Sep 17 00:00:00 2001 From: Rasmy Nguyen Date: Thu, 9 Jan 2025 13:29:27 -0500 Subject: [PATCH 12/12] fix: make corrections active by default --- includes/corrections/class-corrections.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/corrections/class-corrections.php b/includes/corrections/class-corrections.php index e71e4b5bbe..3e234a7866 100644 --- a/includes/corrections/class-corrections.php +++ b/includes/corrections/class-corrections.php @@ -326,14 +326,14 @@ public static function add_corrections_metabox( $post_type ) { * @param \WP_Post $post the post object. */ public static function render_corrections_metabox( $post ) { - $is_active = (bool) get_post_meta( $post->ID, self::CORRECTIONS_ACTIVE_META, true ); + $is_active = get_post_meta( $post->ID, self::CORRECTIONS_ACTIVE_META, true ); $location = get_post_meta( $post->ID, self::CORRECTIONS_LOCATION_META, true ); $corrections = self::get_corrections( $post->ID ); ?>
- /> + />
@@ -381,7 +381,7 @@ public static function save_corrections_metabox( $post_id ) { return; } - $corrections_active = filter_input( INPUT_POST, self::CORRECTIONS_ACTIVE_META, FILTER_VALIDATE_BOOLEAN ); + $corrections_active = filter_input( INPUT_POST, self::CORRECTIONS_ACTIVE_META, FILTER_SANITIZE_NUMBER_INT ); $corrections_location = filter_input( INPUT_POST, self::CORRECTIONS_LOCATION_META, FILTER_SANITIZE_STRING ); $corrections_data = filter_input_array( INPUT_POST, @@ -405,8 +405,8 @@ public static function save_corrections_metabox( $post_id ) { return; } // update active flag if present. - if ( (bool) $corrections_active !== (bool) get_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, true ) ) { - update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, (bool) $corrections_active ); + if ( $corrections_active != get_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, true ) ) { + update_post_meta( $post_id, self::CORRECTIONS_ACTIVE_META, $corrections_active ); } // update location flag if present. if ( $corrections_location !== get_post_meta( $post_id, self::CORRECTIONS_LOCATION_META, true ) ) { @@ -456,7 +456,7 @@ public static function output_corrections_on_post( $content ) { return $content; } - if ( ! (bool) get_post_meta( get_the_ID(), self::CORRECTIONS_ACTIVE_META, true ) ) { + if ( 0 == get_post_meta( get_the_ID(), self::CORRECTIONS_ACTIVE_META, true ) ) { return $content; }