: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$comment_args['number'] = $per_page;
$page = (int) get_query_var( 'cpage' );
$comment_args['paged'] = $page;
} elseif ( 'oldest' === $default_page ) {
$comment_args['paged'] = 1;
} elseif ( 'newest' === $default_page ) {
$max_num_pages = (int) ( new WP_Comment_Query( $comment_args ) )->max_num_pages;
if ( 0 !== $max_num_pages ) {
$comment_args['paged'] = $max_num_pages;
// Set the `cpage` query var to ensure the previous and next pagination links are correct
// when inheriting the Discussion Settings.
if ( 0 === $page && isset( $comment_args['paged'] ) && $comment_args['paged'] > 0 ) {
set_query_var( 'cpage', $comment_args['paged'] );
* Helper function that returns the proper pagination arrow HTML for
* `CommentsPaginationNext` and `CommentsPaginationPrevious` blocks based on the
* provided `paginationArrow` from `CommentsPagination` context.
* It's used in CommentsPaginationNext and CommentsPaginationPrevious blocks.
* @param WP_Block $block Block instance.
* @param string $pagination_type Optional. Type of the arrow we will be rendering.
* Accepts 'next' or 'previous'. Default 'next'.
* @return string|null The pagination arrow HTML or null if there is none.
function get_comments_pagination_arrow( $block, $pagination_type = 'next' ) {
if ( ! empty( $block->context['comments/paginationArrow'] ) && ! empty( $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ] ) ) {
$arrow_attribute = $block->context['comments/paginationArrow'];
$arrow = $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ];
$arrow_classes = "wp-block-comments-pagination-$pagination_type-arrow is-arrow-$arrow_attribute";
return "<span class='$arrow_classes' aria-hidden='true'>$arrow</span>";
* Strips all HTML from the content of footnotes, and sanitizes the ID.
* This function expects slashed data on the footnotes content.
* @param string $footnotes JSON-encoded string of an array containing the content and ID of each footnote.
* @return string Filtered content without any HTML on the footnote content and with the sanitized ID.
function _wp_filter_post_meta_footnotes( $footnotes ) {
$footnotes_decoded = json_decode( $footnotes, true );
if ( ! is_array( $footnotes_decoded ) ) {
$footnotes_sanitized = array();
foreach ( $footnotes_decoded as $footnote ) {
if ( ! empty( $footnote['content'] ) && ! empty( $footnote['id'] ) ) {
$footnotes_sanitized[] = array(
'id' => sanitize_key( $footnote['id'] ),
'content' => wp_unslash( wp_filter_post_kses( wp_slash( $footnote['content'] ) ) ),
return wp_json_encode( $footnotes_sanitized );
* Adds the filters for footnotes meta field.
function _wp_footnotes_kses_init_filters() {
add_filter( 'sanitize_post_meta_footnotes', '_wp_filter_post_meta_footnotes' );
* Removes the filters for footnotes meta field.
function _wp_footnotes_remove_filters() {
remove_filter( 'sanitize_post_meta_footnotes', '_wp_filter_post_meta_footnotes' );
* Registers the filter of footnotes meta field if the user does not have `unfiltered_html` capability.
function _wp_footnotes_kses_init() {
_wp_footnotes_remove_filters();
if ( ! current_user_can( 'unfiltered_html' ) ) {
_wp_footnotes_kses_init_filters();
* Initializes the filters for footnotes meta field when imported data should be filtered.
* This filter is the last one being executed on {@see 'force_filtered_html_on_import'}.
* If the input of the filter is true, it means we are in an import situation and should
* enable kses, independently of the user capabilities. So in that case we call
* _wp_footnotes_kses_init_filters().
* @param string $arg Input argument of the filter.
* @return string Input argument of the filter.
function _wp_footnotes_force_filtered_html_on_import_filter( $arg ) {
// If `force_filtered_html_on_import` is true, we need to init the global styles kses filters.
_wp_footnotes_kses_init_filters();