Как обновить/добавить данные произвольного поля (метаданные записи) с помощью WordPress REST API?

11 янв. 2018 г., 08:10:31
Просмотры: 18.1K
Голосов: 4

Пытаюсь добавить произвольные метаданные записи через WordPress API, но возникают сложности с обновлением/добавлением данных. Ниже мой текущий код.

Код в файле function.php

    add_action( 'rest_api_init', 'create_api_posts_meta_field' );

function create_api_posts_meta_field() {

 // register_rest_field ( 'тип-записи', 'название-поля', массив-колбэков-и-схем )
 register_rest_field( 'experience', 'subtitle', array(
 'get_callback' => 'get_post_meta_for_api',
 'update_callback'   => 'update_post_meta_for_exp',
 'schema' => null,
 )
 );
}


function update_post_meta_for_exp($object, $meta_value ) {
                $havemetafield  = get_post_meta($object['id'], 'experience', false);
                if ($havemetafield) {
                    $ret = update_post_meta($object['id'], 'subtitle', $meta_value );
                    return true;
                } else {
                    $ret = add_post_meta( $object['id'], 'subtitle', $meta_value ,true );
                    return true;
                }
            }

function get_post_meta_for_api( $object ) {
 // Получаем ID записи из объекта
 $post_id = $object['id'];

 // Возвращаем метаданные
 return get_post_meta( $post_id )["Subtitle"][0];
}

 function create_api_posts_meta_field_time() {

 // register_rest_field ( 'тип-записи', 'название-поля', массив-колбэков-и-схем )
 register_rest_field( 'experience', 'timing_of_experience', array(
 'get_callback' => 'get_post_meta_for_api_time',
 'update_callback'   => function($meta_value ) {
                $havemetafield  = get_post_meta(1, 'experience', false);
                if ($havemetafield) {
                    $ret = update_post_meta(1, 'timing_of_experience', $meta_value );
                    return true;
                } else {
                    $ret = add_post_meta( 1, 'timing_of_experience', $meta_value ,true );
                    return true;
                }
            },
 'schema' => null,
 )
 );
}

function get_post_meta_for_api_time( $object ) {
 // Получаем ID записи из объекта
 $post_id = $object['id'];

 // Возвращаем метаданные
 return get_post_meta( $post_id )["timing_of_experience"][0];
}

JS-файл на странице

var quickAddExperience = document.querySelector("#quick-add-experience");

  if (quickAddExperience) {

        quickAddExperience.addEventListener("click",function() {

                var ourPostData = {
                    'title'                  : document.getElementById('title').value,
                    'content'                : document.getElementById('content').value,
                    'subtitle'               : document.getElementById('company_name').value,
                    'timing_of_experience'   : document.getElementById('time_period').value,
                    'status'                 : 'publish'
                }

                console.log(ourPostData);
                var createPost = new XMLHttpRequest();
                createPost.open("POST", magicalData.siteURL + "/wp-json/wp/v2/experience-api");
                createPost.setRequestHeader("X-WP-Nonce", magicalData.nonce);
                createPost.setRequestHeader("Content-Type","application/json;charset=UTF-8");
                createPost.send(JSON.stringify(ourPostData));
                createPost.onreadystatechange = function(){
                    if (createPost.readystate == 4) {
                        if (createPost.status == 201) {
                                document.querySelector('.data-api-post-1 [name="title"]').value ='';
                                document.querySelector('.data-api-post-1 [name="content"]').value ='';
                                document.querySelector('.data-api-post-1 [name="company_name"]').value ='';
                                document.querySelector('.data-api-post-1 [name="time_period"]').value ='';
                        }else{
                            alert("Ошибка - попробуйте снова");
                        }
                    }
                }
        });
    }

Код работает для стандартных полей (создает новую запись), но сохраняет только title и content.

Примечание: При отладке обнаружил, что update_callback не выполняется, хотя get_callback работает нормально.

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

где именно вы не получаете значения? Минимальная отладка заключается в выводе содержимого переменных, которые не содержат ожидаемого значения.

mmm mmm
11 янв. 2018 г. 20:31:43

извините, не понимаю, о чем вы спрашиваете

Varun Naharia Varun Naharia
12 янв. 2018 г. 04:50:03

Можете сократить код до минимального, необходимого для воспроизведения проблемы? Слишком много лишнего кода, который усложняет чтение.

janh janh
15 янв. 2018 г. 16:49:00

@janh это минимальный код.

Varun Naharia Varun Naharia
16 янв. 2018 г. 06:58:59
Все ответы на вопрос 2
0

Я только что проверил ваш код и, на мой взгляд, он не работает из-за ошибки в функции get_callback.

При первом вызове она попытается получить subtitle (или timing_of_experience), но вызовет ошибку, так как этого поля изначально не существует, и эта ошибка заблокирует регистрацию update_callback.

Проблема в том, что в get_callback ключ Subtitle написан с заглавной буквы S, а так он не сохраняется.

Во-вторых, следует соблюдать общее правило валидации данных и проверять наличие значения перед попыткой доступа к нему. Вот так:

function get_post_meta_for_api( $object ) {
    // Получаем ID из массива объекта записи
    $post_id = $object['id'];

    $meta = get_post_meta( $post_id );

    if ( isset( $meta['subtitle' ] ) && isset( $meta['subtitle' ][0] ) ) {
        // Возвращаем метаданные записи
        return $meta['subtitle' ][0];
    }

    // Метаданные не найдены
    return false;
}

Как я уже сказал, я проверил, заменив ваш тип записи experience на post, и все работает.

Бонусный совет: постарайтесь лучше организовать код, так как его сложно читать из-за такой индексации и порядка функций. Также для update_callback достаточно простого return true.

function update_post_meta_for_exp($object, $meta_value ) {
    $havemetafield  = get_post_meta($object['id'], 'experience', false);
    if ($havemetafield) {
        $ret = update_post_meta($object['id'], 'subtitle', $meta_value );
    } else {
        $ret = add_post_meta( $object['id'], 'subtitle', $meta_value ,true );
    }
    return true;
}
20 янв. 2018 г. 18:00:01
1

Вы можете записывать пользовательские данные записей с помощью приведенного ниже кода. Я записываю категории пользовательского типа записи "ad_portfolio" и изображение записи в WordPress API, используя этот код. Надеюсь, это поможет. Спасибо.

    function prepare_rest($data, $post, $request){
    $_data = $data->data;

    $thumbnail_id = get_post_thumbnail_id( $post->ID );
    $featured_media_url = wp_get_attachment_image_src( $thumbnail_id, 'large' );

    $post_categories = wp_get_post_terms( $post->ID, 'ad_portfolios' , array("fields" => "all") );
    $cats = array();

    foreach($post_categories as $cat){
        $cats[] = ['slug' => $cat->slug, 'name' => $cat->name ];
    }

    $_data['featured_media_url'] = $featured_media_url[0];
    $_data['portfolio_cats'] = $cats;
    $data->data = $_data;

    return $data;
}
add_filter('rest_prepare_ad_portfolio', 'prepare_rest', 10, 3);
//тип записи - "ad_portfolio"
16 янв. 2018 г. 19:28:01
Комментарии

Спасибо за ответ, но это не похоже на решение, которое я просил. Не могли бы вы объяснить, как это должно работать и почему мой код не работает?

Varun Naharia Varun Naharia
17 янв. 2018 г. 07:04:36