Как исправить тайм-аут при добавлении записи CPT?
Здравствуйте!
Столкнулся в тайм-аутом при добавлении записи c произвольными полями кастомного типа
Даже переписывал функцию сохранения.. не помогло. Как поправить, что не так делаю?
save_profi_meta_data v 1.0
unction save_profi_meta_data($post_id) { if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; if (!isset($_POST['post_type'])) { return $post_id;} // Создаем массив данных для обновления $order_num = sanitize_text_field($_POST['order_num']); $order_title = sanitize_text_field($_POST['order_title']); // Создаем новый заголовок $new_title = "Заказ № {$order_num} - {$order_title}"; $new_permalink = "order_{$order_num}"; $post_data = array( 'ID' => $post_id, 'post_title' => $new_title, 'post_content' => sanitize_textarea_field($_POST['order_description']), 'post_name' => $new_permalink, ); // Добавляем произвольные поля в массив данных $post_data['meta_input'] = array( 'order_title' => sanitize_text_field($_POST['order_title']), 'order_num' => sanitize_text_field($_POST['order_num']), 'profi_link' => sanitize_text_field($_POST['profi_link']), 'incoming_date' => sanitize_text_field($_POST['incoming_date']), 'deadline' => sanitize_text_field($_POST['deadline']), 'order_description' => sanitize_textarea_field($_POST['order_description']), 'order_sources' => sanitize_text_field($_POST['order_sources']), 'client_name' => sanitize_textarea_field($_POST['client_name']), 'client_contacts' => sanitize_textarea_field($_POST['client_contacts']), 'order_status' => sanitize_text_field($_POST['order_status']), 'current_task' => sanitize_textarea_field($_POST['current_task']), 'order_price' => sanitize_text_field($_POST['order_price']), 'profi_commission' => sanitize_text_field($_POST['profi_commission']), 'self_employed' => isset($_POST['self_employed']) && $_POST['self_employed'] === 'on' ? true : false, ); wp_update_post($post_data); |
unction save_profi_meta_data($post_id) { if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; if (!isset($_POST['post_type'])) { return $post_id;} // Создаем массив данных для обновления $order_num = sanitize_text_field($_POST['order_num']); $order_title = sanitize_text_field($_POST['order_title']); // Создаем новый заголовок $new_title = "Заказ № {$order_num} - {$order_title}"; $new_permalink = "order_{$order_num}"; $post_data = array( 'ID' => $post_id, 'post_title' => $new_title, 'post_content' => sanitize_textarea_field($_POST['order_description']), 'post_name' => $new_permalink, ); // Добавляем произвольные поля в массив данных $post_data['meta_input'] = array( 'order_title' => sanitize_text_field($_POST['order_title']), 'order_num' => sanitize_text_field($_POST['order_num']), 'profi_link' => sanitize_text_field($_POST['profi_link']), 'incoming_date' => sanitize_text_field($_POST['incoming_date']), 'deadline' => sanitize_text_field($_POST['deadline']), 'order_description' => sanitize_textarea_field($_POST['order_description']), 'order_sources' => sanitize_text_field($_POST['order_sources']), 'client_name' => sanitize_textarea_field($_POST['client_name']), 'client_contacts' => sanitize_textarea_field($_POST['client_contacts']), 'order_status' => sanitize_text_field($_POST['order_status']), 'current_task' => sanitize_textarea_field($_POST['current_task']), 'order_price' => sanitize_text_field($_POST['order_price']), 'profi_commission' => sanitize_text_field($_POST['profi_commission']), 'self_employed' => isset($_POST['self_employed']) && $_POST['self_employed'] === 'on' ? true : false, ); wp_update_post($post_data);
save_profi_meta_data v 1.1
function save_profi_meta_data($post_id) { // Проверяем, что это не автосохранение и что тип записи - "profi" if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; if ('profi' !== get_post_type($post_id)) return $post_id; // Массив полей для сохранения $fields_to_save = array( 'order_title', 'order_num', 'profi_link', 'incoming_date', 'deadline', 'order_description', 'order_sources', 'client_name', 'client_contacts', 'order_status', 'current_task', 'order_price', 'profi_commission', ); $meta_input = array(); foreach ($fields_to_save as $field) { if (isset($_POST[$field])) { $meta_input[$field] = sanitize_text_field($_POST[$field]); } } // Обновляем заголовок и ссылку на запись $order_num = isset($_POST['order_num']) ? sanitize_text_field($_POST['order_num']) : ''; $order_title = isset($_POST['order_title']) ? sanitize_text_field($_POST['order_title']) : ''; $new_title = "Заказ № {$order_num} - {$order_title}"; $new_permalink = "order_{$order_num}"; // Обновляем данные записи $updated_post_data = array( 'ID' => $post_id, 'post_title' => $new_title, 'post_content' => sanitize_textarea_field($_POST['order_description']), 'post_name' => $new_permalink, ); // Добавляем произвольные поля в массив данных $updated_post_data['meta_input'] = $meta_input; // Обновляем запись wp_update_post($updated_post_data); } // Вызываем функцию сохранения мета-полей при сохранении поста add_action('save_post', 'save_profi_meta_data'); |
function save_profi_meta_data($post_id) { // Проверяем, что это не автосохранение и что тип записи - "profi" if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; if ('profi' !== get_post_type($post_id)) return $post_id; // Массив полей для сохранения $fields_to_save = array( 'order_title', 'order_num', 'profi_link', 'incoming_date', 'deadline', 'order_description', 'order_sources', 'client_name', 'client_contacts', 'order_status', 'current_task', 'order_price', 'profi_commission', ); $meta_input = array(); foreach ($fields_to_save as $field) { if (isset($_POST[$field])) { $meta_input[$field] = sanitize_text_field($_POST[$field]); } } // Обновляем заголовок и ссылку на запись $order_num = isset($_POST['order_num']) ? sanitize_text_field($_POST['order_num']) : ''; $order_title = isset($_POST['order_title']) ? sanitize_text_field($_POST['order_title']) : ''; $new_title = "Заказ № {$order_num} - {$order_title}"; $new_permalink = "order_{$order_num}"; // Обновляем данные записи $updated_post_data = array( 'ID' => $post_id, 'post_title' => $new_title, 'post_content' => sanitize_textarea_field($_POST['order_description']), 'post_name' => $new_permalink, ); // Добавляем произвольные поля в массив данных $updated_post_data['meta_input'] = $meta_input; // Обновляем запись wp_update_post($updated_post_data); } // Вызываем функцию сохранения мета-полей при сохранении поста add_action('save_post', 'save_profi_meta_data');
Дополнительно:
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Тайм-аут при сохранении CPT часто появляется из-за рекурсии в хуке сохранения. Если внутри
save_postВы вызываетеwp_update_post(), WordPress снова запускаетsave_post, функция снова вызываетwp_update_post(), и так по кругу до тайм-аута или превышения памяти.Если нужно менять заголовок/slug при сохранении, временно снимайте хук перед
wp_update_post(), а потом возвращайте:add_action('save_post_profi', 'save_profi_meta_data', 20, 2); function save_profi_meta_data($post_id, $post) { if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } if (!current_user_can('edit_post', $post_id)) { return; } $order_num = sanitize_text_field($_POST['order_num'] ?? ''); $order_title = sanitize_text_field($_POST['order_title'] ?? ''); if (!$order_num || !$order_title) { return; } update_post_meta($post_id, 'order_num', $order_num); update_post_meta($post_id, 'order_title', $order_title); remove_action('save_post_profi', 'save_profi_meta_data', 20); wp_update_post([ 'ID' => $post_id, 'post_title' => 'Заказ № ' . $order_num . ' - ' . $order_title, 'post_name' => 'order-' . sanitize_title($order_num), ]); add_action('save_post_profi', 'save_profi_meta_data', 20, 2); }
Также не забывайте nonce-проверку, если поля свои. И не обрабатывайте все post types через общий
save_post, если нужен только один CPT. Используйтеsave_post_{post_type}— это снижает риск конфликтов и лишних запусков.Ещё одна причина тайм-аута — тяжёлая обработка всех полей без проверки nonce и post type. WordPress вызывает сохранение при автосохранении, ревизиях, quick edit и других действиях. Если функция каждый раз пересчитывает заголовок, пишет десятки meta-полей или делает внешние запросы, админка начинает зависать.
Сделайте логирование времени и временно закомментируйте части функции. Если после удаления
wp_update_post()тайм-аут исчезает, причина почти точно в рекурсии. Если нет — смотрите медленные операции внутри сохранения: API-запросы, большие циклы, генерацию файлов, пересчёт связанных записей.Хорошая практика: в
save_postтолько сохранить данные, а тяжёлые действия складывать в очередь или запускать cron-задачей.