Как добавить запись с пользовательской таксономией в WordPress

16 мар. 2012 г., 13:42:34
Просмотры: 16K
Голосов: 5

Я создал пользовательский тип записи в WordPress, связанный с пользовательской таксономией.

Записи собирают данные с фронтенда сайта с помощью функции wp_insert_post().

Вот мой код регистрации пользовательского типа записи:

$labels = array(
        'name' => 'Фильмы',
        'singular_name' => 'Фильм',
        'add_new' => 'Добавить новый',
        'add_new_item' => 'Добавить новый фильм',
        'edit_item' => 'Редактировать фильм',
        'new_item' => 'Новый фильм',
        'all_items' => 'Все фильмы',
        'view_item' => 'Просмотреть фильм',
        'search_items' => 'Искать фильмы',
        'not_found' =>  'Фильмы не найдены',
        'not_found_in_trash' => 'Фильмы не найдены в корзине', 
        'parent_item_colon' => '',
        'menu_name' => 'Фильмы'
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true, 
        'show_in_menu' => true, 
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'has_archive' => true, 
        'hierarchical' => false,
        'menu_position' => null,
        'taxonomies' => array('film_category'),
        'supports' => array(
            'title',
            'editor'
        )
    );

    register_post_type('film', $args);

А вот мой код регистрации пользовательской таксономии:

$labels = array(
        'name' => 'Категории',
        'singular_name' => 'Фильм',
        'search_items' =>  'Искать категории',
        'all_items' => 'Все категории',
        'parent_item' => 'Родительская категория',
        'parent_item_colon' => 'Родительская категория:',
        'edit_item' => 'Редактировать категорию', 
        'update_item' => 'Обновить категорию',
        'add_new_item' => 'Добавить новую категорию',
        'new_item_name' => 'Новое название категории',
        'menu_name' => 'Категории'
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'rewrite' => false,
        'capabilities' => array('manage_terms') 
    );

    register_taxonomy('film_category', array('film'), $args);

Оба кода выполняются на хуке init.

Когда пользователь отправляет форму с фронтенда, я выполняю следующий код:

$post = array(
            'comment_status' => 'closed',
            'ping_status' => 'closed',
            'post_author' => 2,
            'post_content' => $_POST['synopsis'],
            'post_name' => sanitize_title($_POST['title']),
            'post_status' => 'private',
            'post_title' => $_POST['title'],
            'post_type' => 'film',
            'tax_input' => array(
                'film_category' => array(
                    $_POST['category']
                )
            )
        );

        $new_film_id = wp_insert_post($post);

        wp_set_object_terms($new_film_id, $_POST['category'], 'film_category', true);

В моей фронтенд-форме есть поле выбора "category", содержащее категории фильмов. Я пробовал использовать в значениях options ID терминов, их названия и слаги, но это не работает.

Новая запись создается в моем пользовательском типе записи, но я не могу назначить категории фильмов.

Есть какие-то идеи?

2
Комментарии

Проверяли ли вы, что $_POST['category'] содержит корректные данные на этом этапе? Пробовали ли вы запустить ваш код в тестовом режиме с тестовыми данными, без фронтенд-части?

Rarst Rarst
16 мар. 2012 г. 13:53:29

Я проверяю свои данные с помощью print_r сразу после присваивания, и там правильные данные.

KodeFor.Me KodeFor.Me
16 мар. 2012 г. 13:57:17
Все ответы на вопрос 3
4

Вам не следует использовать:

wp_set_object_terms($new_film_id, $_POST['category'], 'film_category', true);

и значение массива tax_input. Первого (см. примечание в конце) должно быть достаточно.

Если $_POST['category'] содержит ID терминов, вам нужно привести их к целым числам, чтобы они не интерпретировались как слаги.

Также, если $_POST['category'] является массивом, то использование array($_POST['category']) может вызвать проблемы. Попробуйте:

// Приводим к массиву
$terms = isset($_POST['category']) ? (array) $_POST['category'] : array();

// Приводим значения массива к целым числам, если $_POST['category'] содержит ID
$terms = array_map('intval', $terms);

$post = array(
    // другие аргументы
    
    'tax_input' => array(
        'film_category' => $terms,
    )
);

$new_film_id = wp_insert_post($post);

Примечание

Rarst делает важное замечание в комментариях, которое стоит выделить:

wp_insert_post() проверяет права доступа для tax_input и завершится ошибкой, если пользователь не авторизован. Это плохой выбор для нетипичных вставок постов. Явное использование wp_set_object_terms() лучше подходит для случаев вроде миграций, отправки данных с фронтенда и т.д.

16 мар. 2012 г. 15:04:09
Комментарии

Здравствуйте, Стивен Харрис. Большое спасибо за вашу помощь, но, к сожалению, всё ещё не работает. Я действительно не понимаю, в чём проблема. Я убрал wp_set_object_terms и использую только ваш способ. Есть ещё какие-то идеи? С уважением, Мерианос Никос

KodeFor.Me KodeFor.Me
16 мар. 2012 г. 15:26:09

Обратите внимание, что wp_insert_post() проверяет права доступа для tax_input и завершается ошибкой, если пользователь не авторизован. Это плохой выбор для нетипичных случаев вставки записей. Явное использование wp_set_object_terms() лучше подходит для таких сценариев, как миграции, отправка данных с фронтенда и т.д.

Rarst Rarst
16 мар. 2012 г. 15:33:13

После тщательного поиска я заметил, что таксономия, похоже, не существует. Я вывел $wp_taxonomies, и таксономия присутствует в этой глобальной переменной. Но функция taxonomy_exists возвращает false :(

KodeFor.Me KodeFor.Me
16 мар. 2012 г. 15:51:49

@Rarst Думаю, это стоит опубликовать как отдельный ответ. Очень хорошо.

Christine Cooper Christine Cooper
8 авг. 2015 г. 16:47:17
1

Где находится код, который обрабатывает данные $_POST? Он в файле шаблона? Или это функция, запускаемая через хук? Если это последнее, и если taxonomy_exists() возвращает false, как вы упомянули здесь (http://wordpress.stackexchange.com/questions/45798/wp-insert-post-and-custom-taxonomy#comment58402_45810), возможно, вы проверяете до того, как выполнился register_taxonomy. Убедитесь, что ваша функция обработки формы подключена к хуку, который срабатывает позже, чем init:10.

16 мар. 2012 г. 15:58:28
Комментарии

Бун Горгес !!!! Ты просто идеален !!!!!! Это сработало для меня. До этого я вызывал функцию, которая сохраняет мои данные, сразу, а теперь привязал эту функцию к хуку init, и это сработало !! :) Огромное спасибо :)

KodeFor.Me KodeFor.Me
16 мар. 2012 г. 16:06:48
1

Я обнаружил, что использование isset() позволяет мне применять wp_insert_post() для пользовательских типов записей:

if ( !isset( $id ) ) {
    $id = wp_insert_post( $new, true ); 
}
10 мар. 2015 г. 21:58:19
Комментарии

Пожалуйста, объясните, почему это отвечает на вопрос.

kaiser kaiser
11 мар. 2015 г. 02:05:55