Skip to content

Newsletter Categories: add helper class #44537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 30, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ function NewsletterCategories( props ) {
dispatch,
} = props;

const checkedCategoriesIds = newsletterCategories.map( mapCategoriesIds );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was causing an error because it is possible for newsletterCategories to be undefined in the beginning

const checkedCategoriesIds = useMemo(
() => newsletterCategories?.map( mapCategoriesIds ) ?? [],
[ newsletterCategories ]
);

const mappedCategories = useMemo(
() =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* Contains utilities related to the Jetpack Newsletter Categories.
*
* @package automattic/jetpack
*/

/**
* Jetpack_Newsletter_Category_Helper class
*/
class Jetpack_Newsletter_Category_Helper {

const NEWSLETTER_CATEGORIES_OPTION = 'wpcom_newsletter_categories';

/**
* Return category ID's
*
* @return array An array of integers
*/
public static function get_category_ids() {
$newsletter_categories = maybe_unserialize( get_option( 'wpcom_newsletter_categories', array() ) );

if ( ! is_array( $newsletter_categories ) || empty( $newsletter_categories ) ) {
return array();
}

// Check if it is an array of integers.
// [123, 456]
if ( isset( $newsletter_categories[0] ) && is_int( $newsletter_categories[0] ) ) {
return $newsletter_categories;
}

// Check if it is an array of arrays with term_id keys.
// [{term_id: 123}, {term_id: 456}]
if ( isset( $newsletter_categories[0] ) && is_array( $newsletter_categories[0] ) && isset( $newsletter_categories[0]['term_id'] ) ) {
$ids = array();
foreach ( $newsletter_categories as $category ) {
if ( isset( $category['term_id'] ) && is_numeric( $category['term_id'] ) ) {
$ids[] = (int) $category['term_id'];
}
}
return $ids;
}

return array();
}

/**
* Handles category ID's ready to be saved as an option
*
* @param array $newsletter_categories An array of id's that could be in a few different forms.
* @return array|bool An associated array with term_id keys on success, or the boolean result from update_option.
* [{term_id: 123}, {term_id: 456}]
*/
public static function save_category_ids( $newsletter_categories ) {
if ( ! is_array( $newsletter_categories ) || empty( $newsletter_categories ) ) {
return false;
}

$formatted_categories = array();

// Check if it is an array of integers.
// [123, 456]
if ( isset( $newsletter_categories[0] ) && is_numeric( $newsletter_categories[0] ) ) {
foreach ( $newsletter_categories as $id ) {
if ( is_numeric( $id ) ) {
$formatted_categories[] = array( 'term_id' => (int) $id );
}
}
}

// Check if it is an array of arrays with term_id keys.
// [{term_id: 123}, {term_id: 456}]
if ( isset( $newsletter_categories[0] ) && is_array( $newsletter_categories[0] ) && isset( $newsletter_categories[0]['term_id'] ) ) {
foreach ( $newsletter_categories as $category ) {
if ( isset( $category['term_id'] ) && is_numeric( $category['term_id'] ) ) {
$formatted_categories[] = array( 'term_id' => (int) $category['term_id'] );
}
}
}

if ( empty( $formatted_categories ) ) {
return false;
}

return update_option( self::NEWSLETTER_CATEGORIES_OPTION, $formatted_categories )
? $formatted_categories
: false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,12 @@ public function get_all_options() {
$response['newsletter_has_active_plan'] = count( Jetpack_Memberships::get_all_newsletter_plan_ids( false ) ) > 0;
}

// Make sure we are returning a consistent type
if ( ! class_exists( 'Jetpack_Newsletter_Category_Helper' ) ) {
require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-newsletter-category-helper.php';
}
$response['wpcom_newsletter_categories'] = Jetpack_Newsletter_Category_Helper::get_category_ids();

return rest_ensure_response( $response );
}

Expand Down Expand Up @@ -650,6 +656,10 @@ public function update_data( $request ) {
}
}

if ( ! class_exists( 'Jetpack_Newsletter_Category_Helper' ) ) {
require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-newsletter-category-helper.php';
}

foreach ( $params as $option => $value ) {

// Used if there was an error. Can be overwritten with specific error messages.
Expand Down Expand Up @@ -1050,43 +1060,24 @@ function ( &$value ) {
}
break;

case 'wpcom_newsletter_categories':
$sanitized_category_ids = (array) $value;

array_walk_recursive(
$sanitized_category_ids,
function ( &$value ) {
if ( is_int( $value ) && $value > 0 ) {
return;
}

$value = (int) $value;
if ( $value <= 0 ) {
$value = null;
}
}
);

$sanitized_category_ids = array_unique(
array_filter(
$sanitized_category_ids,
function ( $category_id ) {
return $category_id !== null;
}
)
);
case Jetpack_Newsletter_Category_Helper::NEWSLETTER_CATEGORIES_OPTION:
if ( ! is_array( $value ) || empty( $value ) ) {
break;
}

$new_value = array_map(
function ( $category_id ) {
return array( 'term_id' => $category_id );
},
$sanitized_category_ids
);
// If we are already current, do nothing
$current_value = Jetpack_Newsletter_Category_Helper::get_category_ids();
if ( $value === $current_value ) {
break;
}

if ( ! update_option( $option, $new_value ) ) {
if ( Jetpack_Newsletter_Category_Helper::save_category_ids( $value ) ) {
$updated = true;
} else {
$updated = false;
$error = esc_html__( 'WPCOM Newsletter Categories failed to process.', 'jetpack' );
$error = esc_html__( 'Newsletter category did not update.', 'jetpack' );
}

break;

default:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: bugfix

Newsletter: fix bug in category settings
Original file line number Diff line number Diff line change
Expand Up @@ -374,22 +374,11 @@ public function get_settings_response() {
)
);

$newsletter_categories = maybe_unserialize( get_option( 'wpcom_newsletter_categories', array() ) );
$newsletter_category_ids = array_filter(
array_map(
function ( $newsletter_category ) {
if ( is_array( $newsletter_category ) && isset( $newsletter_category['term_id'] ) ) {
// This is the expected format.
return (int) $newsletter_category['term_id'];
} elseif ( is_numeric( $newsletter_category ) ) {
// This is a previous format caused by a bug.
return (int) $newsletter_category;
}
return null;
},
$newsletter_categories
)
);
// Make sure we are returning a consistent type
if ( ! class_exists( 'Jetpack_Newsletter_Category_Helper' ) ) {
require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-newsletter-category-helper.php';
}
$newsletter_category_ids = Jetpack_Newsletter_Category_Helper::get_category_ids();

$api_cache = $site->is_jetpack() ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true;

Expand Down Expand Up @@ -673,6 +662,10 @@ public function update_settings() {
$sharing_options = array();
$updated = array();

if ( ! class_exists( 'Jetpack_Newsletter_Category_Helper' ) ) {
require_once JETPACK__PLUGIN_DIR . '_inc/lib/class-jetpack-newsletter-category-helper.php';
}

foreach ( $input as $key => $value ) {

if ( ! is_array( $value ) ) {
Expand Down Expand Up @@ -1070,42 +1063,12 @@ function ( &$value ) {
$updated[ $key ] = (int) (bool) $value;
break;

case 'wpcom_newsletter_categories':
$sanitized_category_ids = (array) $value;

array_walk_recursive(
$sanitized_category_ids,
function ( &$value ) {
if ( is_int( $value ) && $value > 0 ) {
return;
}

$value = (int) $value;
if ( $value <= 0 ) {
$value = null;
}
}
);

$sanitized_category_ids = array_unique(
array_filter(
$sanitized_category_ids,
function ( $category_id ) {
return $category_id !== null;
}
)
);

$new_value = array_map(
function ( $category_id ) {
return array( 'term_id' => $category_id );
},
$sanitized_category_ids
);

if ( update_option( $key, $new_value ) ) {
$updated[ $key ] = $sanitized_category_ids;
case Jetpack_Newsletter_Category_Helper::NEWSLETTER_CATEGORIES_OPTION:
$update_newsletter_categories = Jetpack_Newsletter_Category_Helper::save_category_ids( (array) $value );
if ( $update_newsletter_categories ) {
$updated[ $key ] = $update_newsletter_categories;
}

break;

case 'wpcom_newsletter_categories_enabled':
Expand Down
Loading
Loading