Расширение функции

Вопрос или проблема

У меня есть следующий код:

function auto_link_post_titles( $content, $post_id, $field ) {
    $excluded_ids = array(); // Здесь укажите идентификаторы страниц, которые вы хотите исключить
    $excluded_field_names = array(); // Здесь укажите названия полей, которые вы хотите исключить
    
    if ( isset( $_GET['ntb'] ) || did_action( 'ninja_tables_loaded' ) ) {
    return $content;
}
    
    if(!in_array($post_id, $excluded_ids) && !in_array($field['name'], $excluded_field_names)) {
        // Устанавливаем тип(ы) постов, которые мы будем получать.
        $desired_post_types = array( 'my_post_type', 'my_other_post_type' );
        // Это для получения всех опубликованных постов из всех типов постов.
        $args = array(
            'post_type'      => $desired_post_types,
            'post_status'    => 'publish',
            'posts_per_page' => -1, // это для получения всех постов
        );

        $posts = get_posts( $args );

        // Здесь мы проходим через каждый пост и заменяем заголовок в контенте на ссылку.
        foreach ( $posts as $post ) {
            $post_title = esc_html( $post->post_title ); // Здесь мы получаем заголовок поста.
            $post_link  = esc_url( get_permalink( $post->ID ) ); // Здесь мы получаем ссылку на пост.

            // Создаем элемент ссылки
            $link = '<a href="' . $post_link . '" target="_blank">' . $post_title . '</a>';

            // Здесь мы заменяем обычный текст заголовка на ссылку.
            $content = str_replace( $post_title, $link, $content );
        }   
    }

    return $content;
}

// Мы применяем функцию к контенту постов.
// Обратите внимание, что количество параметров установлено на 3
add_filter( 'acf/load_value', 'auto_link_post_titles', 10, 3 );

Моя проблема в том, что код не учитывает полный заголовок.
Два разных заголовка постов:

  1. POA
  2. POA (+)

Для второго заголовка код связывает только запись, соответствующую “POA”, и не учитывает, что есть запись, соответствующая, т.е. POA (+).

Как можно решить эту проблему, чтобы учитывался полный заголовок и создавалась ссылка на пост с правильным заголовком?

Ответ или решение

Чтобы решить вашу задачу и гарантировать, что код учитывает полное название поста при создании ссылок, нам нужно изменить способ, которым мы выполняем замену текста. В текущем коде используется функция str_replace, которая заменяет строчки без учета порядка и длины текста, из-за чего возникает проблема с заменой частично совпадающих названий, таких как "POA" и "POA (+)".

Вместо этого я предложу использовать регулярные выражения, которые позволят сделать замену более точной. Вот как можно изменить вашу функцию auto_link_post_titles:

function auto_link_post_titles( $content, $post_id, $field ) {
    $excluded_ids = array(); // Введите здесь идентификаторы страниц, которые хотите исключить
    $excluded_field_names = array(); // Введите здесь названия полей, которые хотите исключить

    if ( isset( $_GET['ntb'] ) || did_action( 'ninja_tables_loaded' ) ) {
        return $content;
    }

    if (!in_array($post_id, $excluded_ids) && !in_array($field['name'], $excluded_field_names)) {
        // Устанавливаем типы постов, которые будем извлекать.
        $desired_post_types = array( 'my_post_type', 'my_other_post_type' );

        // Это для получения всех опубликованных постов из всех типов постов.
        $args = array(
            'post_type'      => $desired_post_types,
            'post_status'    => 'publish',
            'posts_per_page' => -1, // чтобы получить все посты
        );

        $posts = get_posts( $args );

        // Здесь мы проходим по каждому посту и заменяем заголовок в контенте на ссылку.
        foreach ( $posts as $post ) {
            $post_title = esc_html( $post->post_title ); // Получаем заголовок поста.
            $post_link  = esc_url( get_permalink( $post->ID ) ); // Получаем ссылку на пост.

            // Создаем элемент ссылки
            $link = '<a href="' . $post_link . '" target="_blank">' . $post_title . '</a>';

            // Используем регулярное выражение для точного преобразования названия.
            $pattern = '/\b' . preg_quote( $post_title, '/' ) . '\b/'; // Используем preg_quote для экранирования специальных символов

            // Заменяем полное название поста на ссылку.
            $content = preg_replace( $pattern, $link, $content );
        }   
    }

    return $content;
}

// Применяем функцию к контенту постов.
// Обратите внимание, что количество параметров установлено на 3 здесь
add_filter( 'acf/load_value', 'auto_link_post_titles', 10, 3 );

Объяснение изменений:

  1. Вместо str_replace используется preg_replace, что позволяет использовать регулярные выражения для более точного поиска.
  2. Я использовал \b в регулярном выражении, чтобы указать, что заменяются только полные слова, что предотвращает замену только части заголовка.
  3. Также использовал preg_quote, чтобы экранировать специальные символы в заголовках (например, +, ?, и другие), что обеспечивает корректное выполнение регулярного выражения.

Эти изменения позволят вашему коду правильно обрабатывать полные заголовки постов и избегать проблем с частичными совпадениями. Теперь, если у вас есть посты с заголовками "POA" и "POA (+)", они будут правильно заменены соответствующими ссылками.

Оцените материал
Добавить комментарий

Капча загружается...