Вопрос или проблема
Я хочу запускать пользовательскую функцию всякий раз, когда посты импортируются в мой пользовательский тип записи.
В настоящее время я использую этот код –
function on_post_import($post){
global $wpdb;
$results = $wpdb->get_results(
"SELECT ID FROM $wpdb->posts WHERE post_type="post" AND post_status="publish""
);
foreach ($results as $result) {
// выполнить пользовательскую функцию
}
$wpdb->flush();
}
add_action( 'wp_insert_post', 'on_post_import' );
Проблема, с которой я сталкиваюсь, заключается в том, что это не работает для последнего импортированного поста. Если импортируются 3 поста, то код работает для 2 из этих постов, но не для третьего (последнего импортированного).
ОБНОВЛЕНИЕ: Если импортирован только один пост, пользовательская функция не работает.
ОБНОВЛЕНИЕ2: Кажется, проблема в моей пользовательской функции, которая использует get_post_meta(), но, похоже, ничего не выводит.
ОБНОВЛЕНИЕ 3: Сейчас я просто использую запрос wpdb для выполнения пользовательской функции. Я хочу избежать этого, так как он будет постоянно выполняться в фоновом режиме. Если у кого-то есть лучшее решение, пожалуйста, дайте знать, спасибо!
global $wpdb;
$results = $wpdb->get_results(
"SELECT ID FROM $wpdb->posts WHERE post_type="post" AND post_status="publish""
);
foreach ($results as $result) {
// выполнить пользовательскую функцию
}
$wpdb->flush();
Что я делаю неправильно? Или есть другой способ заставить мою функцию работать для всех импортированных постов, включая последний импортированный?
Действие ‘wp_insert_post’ срабатывает для каждого поста, который вставляется, и передает ID вставленного поста в функцию обратного вызова, поэтому я думаю, что ваш запрос $wpdb не нужен – фактически, я думаю, что вы выполняете часть “пользовательской функции” для всех опубликованных постов, а не только для вставленного поста (что может привести к проблемам в зависимости от того, что вы делаете).
function on_post_import( $post_id ) {
// пользовательская функция, использующая $post_id
}
add_action( 'wp_insert_post', 'on_post_import' );
Ответ или решение
Когда вы работаете с импортом постов в WordPress, особенно когда хотите выполнить пользовательскую функцию во время вставки каждого поста, возникает множество нюансов. В вашем случае, возникла проблема с тем, что обработчик событий wp_insert_post
не обрабатывает последний импортированный пост. Давайте разберёмся, почему это происходит и как правильно настроить ваш код.
Теория
Во-первых, важно понимать, как работает хук wp_insert_post
. Этот хук вызывается во время вставки каждого поста и передаёт в вашу функцию идентификатор этого поста. Таким образом, у вас есть возможность выполнять какие-либо действия непосредственно с этим постом, избегая лишних запросов к базе данных.
Ваш исходный код использует глобальный объект $wpdb
для выборки всех постов определённого типа и статуса, и затем запускает пользовательскую функцию для всех этих постов. Однако такой подход может усложнить выполнение вашей задачи и привести к излишней нагрузке на сервер, потому что функция запускается для всех опубликованных постов, а не только для текущего импортированного поста.
Проблемы и примеры
-
Хук
wp_insert_post
и порядок выполнения функций:
Поскольку хукwp_insert_post
вызывается во время вставки поста, очень важно, чтобы ваша функция корректно обрабатывала передаваемые данные. Если функция зависит от мета-данных поста черезget_post_meta()
, они могут быть ещё не сохранены в тот момент, когда она вызывается. -
Использование мета-данных:
В вашем случае, похоже, проблема связана с использованием функцииget_post_meta()
. Когда вы импортируете несколько постов, последний пост, возможно, не получает свои мета-данные своевременно из-за особенностей порядка выполнения операций в WordPress.
Реализация
Давайте рассмотрим улучшенный подход к решению вашей проблемы. Вместо того, чтобы запускать одну функцию для всех постов, мы можем модифицировать обработчик, который будет корректно обрабатывать каждый импортируемый пост.
function on_post_import( $post_id ) {
// Проверьте, является ли пост вашим специализированным типом поста
if (get_post_type($post_id) !== 'ваш_тип_поста') {
return;
}
// Здесь можно работать с мета-данными
// Пост может ещё не иметь необходимых мета-данных
// Вы можете проверять и задерживать выполнение, если нужно
// Пример: Использование мета-данных
$custom_meta = get_post_meta($post_id, 'ключ_мета_данных', true);
if ($custom_meta) {
// Выполните вашу пользовательскую функцию
} else {
// Возможно, стоит добавить проверку или задержку
// для обеспечения того, чтобы мета-данные были доступны
}
}
add_action('wp_insert_post', 'on_post_import');
Применение
-
Оптимизация:
Убедитесь, что вы обрабатываете только те посты, которые вам действительно интересны, проверяяpost_type
. Это снизит количество лишних операций. -
Порядок операций:
Если проблема с мета-данными сохраняется, могут быть полезны хуки, такие какsave_post
, которые вызываются на более позднем этапе жизненного цикла записи. -
Асинхронное выполнение:
Третий вариант — запуск асинхронных функций или задержка выполнения, чтобы дать системе время на обработку мета-данных.
Кратко говоря, лучший подход для вашей задачи заключается в использовании непосредственного идентификатора поста, предоставляемого хуком wp_insert_post
, и в минимизации использования запросов к базе данных. Ваша основная задача — удостовериться, что ваши функции могут безопасно использовать информацию, связанную с постом, в частности мета-данные, которые могут быть актуальны не сразу после wp_insert_post
, а немного позже.