Support » Developing with WordPress » WordPress REST API – custom route with custom fields

  • I am new to WP and just back to code after 7years break so.. I ask you some indulgence when responding as I know it’s far from perfection 🙂

    What I have done so far :
    1- I created a custom post type called “voyage”
    2- I created some custom fields with the ACF plugin for business purpose (it’s stored as post meta as I can see in the WP’s db)
    3- I need to be able get all posts from that type (“voyage”) and create/ update data in wordpress from an other system, so I created a new custom route

    What I struggle with : I don’t succeed in getting a good JSON result from the get part (the only one I implemented so far). The custom fields are not well linked with the post_id.. I always get the same data whatever the post id is. In addition, the JSON result is not really easy read. I tried an array_merge(classic post info array, my custom fields array) but it didn’t work.

    Thank you in advance for your help !

    
    <?php
    // Register REST API endpoints
    class GenerateWP_Custom_REST_API_Endpoints {
    
        /**
         * Register the routes for the objects of the controller.
         */
        public static function register_endpoints() {
            // endpoints will be registered here
    
            register_rest_route('voyageshop/v1', 'voyage',array(
            'methods' => WP_REST_Server::READABLE,
            'callback' => array( 'GenerateWP_Custom_REST_API_Endpoints', 'get_voyages' )
            ));
    
            register_rest_route('voyageshop/v1','voyage',array(
            'methods' => WP_REST_Server::EDITABLE, 
            'callback' =>  array( 'GenerateWP_Custom_REST_API_Endpoints', 'create_update_voyage' )
            ));
    
            //call the function to register the custom fields for the new endpoints
            register_custom_fields;
        }
    
        /**
         * register the custom fields I have defined into ACF for the new endpoints
         * 
         */
        public function register_custom_fields(){
            // my custom_fields as defined in ACF
            $my_custom_fields = array(
                'id_voyage', 
                'Token', 
                'type_voyage',
                'date_depart_sejour',
                'date_arrivee_sejour'           
            );
    
            // my custom_fields from ACF will be registered here
            for ($i=0; $i < count($my_custom_fields) ; $i++){
                register_rest_field('voyage',$my_custom_fields[$i]);
            }
    
        }
    
        /**
         * get all the published post with post_type = voyage
         * return data from the post + custom fields values as defined in ACF
         */
        public function get_voyages(){
    
            $voyages = new WP_Query(array(
                'post_type' => 'voyage',
                'post_status'    => 'publish',
                'posts_per_page' => 20,
            ));
    
            $custom_results= array();
            $final_results = array();
            $my_custom_fields = array(
                'id_voyage', 
                'Token', 
                'type_voyage',
                'date_depart_sejour',
                'date_arrivee_sejour'           
            );
    
            for ($i=0; $i < count($voyages->posts) ; $i++){
                $id= $voyages->posts[$i]->ID;
                // get all the ACF custom fields defined for that post type
                foreach ($my_custom_fields as $my_custom_field){
                    $item=  $my_custom_field;
                    $meta= get_post_meta($id, $item);
                    array_push($custom_results,array($item => $meta[0]));
                }
                // return push per post ID all the data from the post + the cyustom fields value related to that post ID
                array_push($final_results,$voyages->posts[$i],$custom_results);
            }
            return $final_results;
    
        //return $this->my_custom_fields;
        }
    
        /**
         * create a new post or edit an existing one
         * 
         */
        public static function create_update_voyage(){
            //TBD
        }
    
    }
    add_action( 'rest_api_init', array( 'GenerateWP_Custom_REST_API_Endpoints', 'register_endpoints') );
    
    ?>

    AND THE JSON RESULT :

    [
        {
            "ID": 2144,
            "post_author": "1",
            "post_date": "2018-03-16 11:52:58",
            "post_date_gmt": "2018-03-16 10:52:58",
            "post_content": "",
            "post_title": "mon quatrieme voyage",
            "post_excerpt": "",
            "post_status": "publish",
            "comment_status": "closed",
            "ping_status": "closed",
            "post_password": "",
            "post_name": "mon-quatrieme-voyage",
            "to_ping": "",
            "pinged": "",
            "post_modified": "2018-03-16 11:52:58",
            "post_modified_gmt": "2018-03-16 10:52:58",
            "post_content_filtered": "",
            "post_parent": 0,
            "guid": "https://***********.fr/?post_type=voyage&p=2144",
            "menu_order": 0,
            "post_type": "voyage",
            "post_mime_type": "",
            "comment_count": "0",
            "filter": "raw"
        },
        [
            {
                "id_voyage": "75"
            },
            {
                "Token": null
            },
            {
                "type_voyage": "avion"
            },
            {
                "date_depart_sejour": ""
            },
            {
                "date_arrivee_sejour": ""
            }
        ],
        {
            "ID": 2143,
            "post_author": "1",
            "post_date": "2018-03-15 18:14:59",
            "post_date_gmt": "2018-03-15 17:14:59",
            "post_content": "",
            "post_title": "mon troisieme voyage",
            "post_excerpt": "",
            "post_status": "publish",
            "comment_status": "closed",
            "ping_status": "closed",
            "post_password": "",
            "post_name": "mon-troisieme-voyage",
            "to_ping": "",
            "pinged": "",
            "post_modified": "2018-03-15 18:14:59",
            "post_modified_gmt": "2018-03-15 17:14:59",
            "post_content_filtered": "",
            "post_parent": 0,
            "guid": "https://*********.fr/?post_type=voyage&p=2143",
            "menu_order": 0,
            "post_type": "voyage",
            "post_mime_type": "",
            "comment_count": "0",
            "filter": "raw"
        },
        [
            {
                "id_voyage": "75"
            },
            {
                "Token": null
            },
            {
                "type_voyage": "avion"
            },
            {
                "date_depart_sejour": ""
            },
            {
                "date_arrivee_sejour": ""
            },
            {
                "id_voyage": "1"
            },
            {
                "Token": null
            },
            {
                "type_voyage": "avion"
            },
            {
                "date_depart_sejour": ""
            },
            {
                "date_arrivee_sejour": ""
            }
        ]
    ]
Viewing 1 replies (of 1 total)
  • Moderator bcworkz

    (@bcworkz)

    I think the reason for the same data is you are not re-initializing $custom_results for every post iteration.

    Your JSON appears to be an accurate representation of the array returned. If you want something different, your returned array structure needs to be different. For example, look at what’s involved in preparing a normal post response in WP_REST_Posts_Controller::prepare_item_for_response(). You are not required to follow the same structure. (thankfully!) It’s your endpoint to return data structured as you wish.

    Essentially, the array your return is run through json_encode() and sent out to the requesting app. If you want post meta to be part of every post’s data, the meta needs to be included within the post’s array of data. As it is, you are pushing the data behind the post at the same level, so that is how it appears in the JSON response.

    If it matters to you, also pay attention to whether you are pushing objects or arrays. You can add arbitrary data to arrays, but not necessarily objects.

Viewing 1 replies (of 1 total)
  • You must be logged in to reply to this topic.