Вопрос или проблема
Как триггер для сохранения поста при обновлении мета данных поста
У меня очень запутанная ситуация. Я добавил посты и все метаданные постов из одной базы данных сайта в другую, все в порядке, изображения, заголовки, описания постов на месте.
Но метаданные постов не отображаются на веб-странице (img1), хотя они существуют, когда я перехожу на страницу редактирования поста в wp-admin (img2), я вижу данные поста, но они не отображаются, пока я сам не нажму на кнопку 'Обновить'
.
После этого все данные поста отображаются. (img3, img4)
Постов слишком много (около 4000 рецептов), так что я не могу сделать это вручную, это займет много времени.
Поэтому мне нужно что-то, что будет автоматически обновлять каждый пост.
Я пытался обновить метаданные поста, но это не сработало, все равно необходимо обновлять пост вручную.
$metas = get_post_meta(get_the_ID());
foreach($metas as $meta_key => $meta_value){
foreach( $meta_value as $val ){
update_post_meta( get_the_ID(), $meta_key, $val);
}
}
Есть ли способ это сделать?
Я использовал это для успешного вставки постов с данными ACF/postmeta, но, пожалуйста, протестируйте это на тестовом сайте перед развертыванием в реальных условиях, могут быть некоторые ужасные предположения. В общем, предполагается, что у вас есть каждое имя только один раз, то есть “myfield” не существует в двух группах полей с разными значениями.
$mycustomvalue = 123;
$f_mycustomfield = get_acf_key_by_name("mycustomfield");
update_post_meta( $postid, "mycustomfield", $mycustomvalue );
update_post_meta( $postid, "_mycustomfield", $f_mycustomfield["key"] );
function load_acf_names2key() {
global $acf_names2key;
$acf_names2key = array();
$posts = get_posts(array(
'numberposts' => -1,
'post_type' => 'acf',
'orderby' => 'menu_order title',
'order' => 'asc',
'suppress_filters' => false,
));
foreach($posts as $fieldgroup) {
$fields = get_post_meta( $fieldgroup->ID );
foreach($fields as $fieldkey => $fieldmeta) {
if(substr($fieldkey, 0, 6) == "field_") {
$field = get_post_meta( $fieldgroup->ID, $fieldkey);
foreach($field as $subfield) {
if(!array_key_exists($subfield["name"], $acf_names2key)) $acf_names2key[ $subfield["name"] ] = array();
$subfield[ "group" ] = $fieldgroup->post_name;
array_push( $acf_names2key[ $subfield["name"] ], $subfield );
}
}
}
}
}
function get_acf_key_by_name($name, $options = array()) {
global $acf_names2key;
if(!$acf_names2key || !is_array($acf_names2key) || count($acf_names2key) == 0) {
load_acf_names2key();
}
if(!array_key_exists($name, $acf_names2key))
return false;
foreach($acf_names2key[ $name ] as $possible) {
foreach($options as $key => $val) {
if(preg_match("!^/.*/i?$!", $val)) {
if(!preg_match($val, $possible[ $key ])) {
continue 2;
}
}
else if($possible[ $key ] != $val) {
continue 2;
}
}
# нет опций? это вернет первый
# есть опции? вернет первый элемент, который
# удовлетворяет всем опциям
return $possible;
}
return false;
}
Прошло довольно много времени с тех пор, как я написал это, и память подводит меня, что именно я хотел сделать с этими $options, которые можно передать в get_acf_key_by_name
(или если я просто скопировал этот код откуда-то), но это всегда работало для меня. Я не пробовал работать с повторяющимися полями, так что это может быть вызовом, но дайте этому шанс.
Ответ или решение
К сожалению, проблема, с которой вы столкнулись, связана с отсутствием обновления метаданных постов после миграции данных на новый сайт. Вы уже отметили, что метаданные видны на странице редактирования поста в админке, но не отображаются на основном сайте, пока вы не нажмете кнопку "Обновить". Это может происходить из-за того, что WordPress не "знает" о новых или обновленных данных до тех пор, пока вы не подтвердите изменения.
Решение
Для автоматического обновления всех постов и метаданных вы можете воспользоваться следующими шагами. Это позволит вам избежать ручного обновления каждого поста.
-
Используйте WP_Query для получения всех постов:
Используйте цикл для получения всех постов, а затем обновите каждый пост. - Вызов функции обновления поста:
Внутри цикла вызовите функциюwp_update_post
для каждого поста, чтобы триггерить обновление.
Вот пример кода, который вы можете использовать:
function обновить_все_посты() {
$args = array(
'post_type' => 'your_post_type', // Укажите тип поста
'numberposts' => -1, // Получить все посты
);
$posts = get_posts($args);
foreach ($posts as $post) {
// Обновим пост, чтобы триггерить обновление
wp_update_post(array(
'ID' => $post->ID,
'post_modified' => current_time('mysql'), // Обновляем дату модификации
'post_modified_gmt' => current_time('mysql', 1), // Обновляем дату модификации GMT
));
}
}
// Запустите функцию
обновить_все_посты();
Объяснение кода
get_posts($args)
: Получает все посты указанного типа.wp_update_post(array(...))
: Обновляет пост с новой датой модификации, что заставляет WordPress пересчитать и восстановить метаданные.current_time('mysql')
: Получает текущее время для обновления поста.
Важно
- Резервное копирование: Перед тем как выполнять данную функцию, убедитесь, что у вас есть резервная копия базы данных, чтобы избежать потери данных в случае ошибки.
- Тестирование: Лучше всего протестировать код на тестовом или локальном сервере перед запуском на живом сайте.
- Выполнение через WP CLI: Если у вас есть доступ к WP CLI, вы также можете выполнить эту задачу через консоль, что может быть более эффективно, особенно с большим количеством постов.
Заключение
Следуя этим шагам, вы сможете автоматически обновить все посты и их метаданные, чтобы они корректно отображались на сайте. Это позволит сэкономить время и ресурсы, избегая ручного обновления каждого элемента отдельно.