Как сделать автоинкрементный счетчик пользовательских типов постов в WordPress?
Есть пользовательский тип постов с идентификатором doc. Надо сделать добавляющийся автоматом при сохранении такого поста уникальный номер в поле title перед самим названием.
Пытаюсь сделать так:
Создал страницу id = 100 с контентом в виде числа, первоначальное значение "1". И при wp_insert_post_data считываю из нее контент, увеличиваю, записываю обратно, добавляю в название.
Это как я думаю оно должно работать. )На деле при добавлении кода в functions.php при попытке создать doc номер в странице не меняется, тайтл у нового поста не меняется.
add_filter('wp_insert_post_data', 'add_doc_num', 10, 2); function add_doc_num($data, $postarr) { if ($data['post_type'] == 'doc' && $data['post_status'] != 'publish') { $source_post_id = 100; $source_post = get_post($source_post_id); $current_content = $source_post->post_content; $current_number = intval($current_content); $new_number = $current_number + 1; $updated_content = strval($new_number); $source_post->post_content = $updated_content; wp_update_post($source_post); // Обновляем заголовок создаваемого поста $data['post_title'] = $updated_content . ' ' . $data['post_title']; } return $data; } |
add_filter('wp_insert_post_data', 'add_doc_num', 10, 2); function add_doc_num($data, $postarr) { if ($data['post_type'] == 'doc' && $data['post_status'] != 'publish') { $source_post_id = 100; $source_post = get_post($source_post_id); $current_content = $source_post->post_content; $current_number = intval($current_content); $new_number = $current_number + 1; $updated_content = strval($new_number); $source_post->post_content = $updated_content; wp_update_post($source_post); // Обновляем заголовок создаваемого поста $data['post_title'] = $updated_content . ' ' . $data['post_title']; } return $data; }
Где проблема, подскажите, пжлст.
Дополнительно:
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Хранить счётчик в контенте отдельной страницы — плохая идея. Это неочевидно, может ломаться при автосохранениях, ревизиях и параллельных сохранениях. Для таких задач используйте option или отдельное meta-поле у самой записи.
Также в вашем условии есть логическая проблема: вы проверяете
$data['post_status'] != 'publish'. То есть код срабатывает не для публикации, а для черновиков/автосохранений. При создании записи WordPress может несколько раз вызывать сохранение, поэтому номер легко получить не там, где ожидаете.Безопаснее делать номер один раз на
save_post_doc, пропускать автосохранения и проверять, что номер ещё не назначен.add_action('save_post_doc', function ($post_id, $post, $update) { if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) { return; } if (get_post_meta($post_id, '_doc_number', true)) { return; } $number = (int) get_option('site_doc_counter', 0) + 1; update_option('site_doc_counter', $number, false); update_post_meta($post_id, '_doc_number', $number); remove_action('save_post_doc', __FUNCTION__, 10); wp_update_post([ 'ID' => $post_id, 'post_title' => $number . ' ' . $post->post_title, ]); }, 10, 3);
Но в этом примере есть нюанс:
__FUNCTION__внутри анонимной функции не поможет корректно снять хук. Поэтому для боевого кода лучше использовать именованную функцию:add_action('save_post_doc', 'site_add_doc_number', 10, 3); function site_add_doc_number($post_id, $post, $update) { if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) { return; } if (get_post_meta($post_id, '_doc_number', true)) { return; } $number = (int) get_option('site_doc_counter', 0) + 1; update_option('site_doc_counter', $number, false); update_post_meta($post_id, '_doc_number', $number); remove_action('save_post_doc', 'site_add_doc_number', 10); wp_update_post([ 'ID' => $post_id, 'post_title' => $number . ' ' . $post->post_title, ]); add_action('save_post_doc', 'site_add_doc_number', 10, 3); }
Если номера юридически важные и не должны пропускаться, нужен более строгий механизм с отдельной таблицей и блокировкой. Для обычной нумерации документов в админке option + post meta обычно достаточно.