Включить логическое для функции

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

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

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. CATA
2. CATA(1)
3. CATA(2)

Код не учитывает полный заголовок, только первые несколько букв – и как только он готов, он начинает автоматическую привязку.

Таким образом, поскольку у меня есть пост с названием “CATA”, во всех трех случаях только пост с названием “CATA” связан, что неправильно для CATA(2) и CATA(3).

Итак, мой вопрос:
Есть ли способ расширить код или изменить его, чтобы он распознавал полный заголовок? И если да, то как?

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

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

Вот обновлённая версия кода:

function auto_link_post_titles( $content, $post_id, $field ) {
    $excluded_ids = array(); // Укажите здесь ID страниц, которые хотите исключить
    $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 );

        // Сначала подготовим массив заголовков постов.
        $post_titles = array();
        foreach ( $posts as $post ) {
            $post_titles[$post->ID] = esc_html( $post->post_title ); // Получаем заголовок поста
        }

        // Сортируем заголовки по длине в убывающем порядке, чтобы длинные заголовки заменялись раньше
        usort($post_titles, function($a, $b) {
            return strlen($b) - strlen($a);
        });

        // Заменяем заголовки в контенте
        foreach ( $post_titles as $post_id => $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. Сохранение заголовков: Вместо прямой замены заголовков, мы сохраняем их в массив, чтобы избежать конфликта замены.
  2. Сортировка: Мы сортируем заголовки по длине в убывающем порядке с помощью функции usort. Это гарантирует, что более длинные заголовки будут заменены первыми, что минимизирует вероятность неправильной замены.
  3. Замена в контенте: Мы проходим по отсортированным заголовкам и заменяем каждый заголовок на ссылку в контенте.

Эти изменения должны решить проблему некорректного связывания заголовков постов и обеспечить, что каждый заголовок будет правильно распознан и заменён на соответствующую ссылку.

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

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