• I have a WP site, v 5.3.2, and there is a custom post type “Events” that has three custom fields for ‘date_of_event’, ‘event_time, and ‘event_address’, and this cpt also uses the native fields for title, featured image, and the content.

    Our company has an internal database that volunteers throughout the state use to create local events, I want to set this up so that we can POST/PUT/DELETE these events to our WP site into the “Events” cpt.

    I’ve worked with the WP REST API before but only to create a live search function for a site that queries its own database for results so I’m familiar with the REST API, but I’m a little confused for how to get started with this task at hand of being able to accept data from this other database. I know this database does have the ability to export these events in json format.

    I do want to point out that I do not have access to the company database, so I need to provide them with details of what I need and I think they will need to provide me with the different data field key:value pairs in order for me to properly grab the incoming data to process. Once I know how their event json data is formatted, I can then create my php file to accept the necessary key:value pairs?

    Will I need just a single endpoint for this CPT where the POST/PUT/DELETE requests will be sent to?

    Thanks.

Viewing 8 replies - 1 through 8 (of 8 total)
  • Moderator bcworkz

    (@bcworkz)

    Ideally, you should want to avoid creating redundant data like events in WP when the data is already available in another database. If possible, connect directly to the principal DB and get the data you need there instead of duplicating it on the WP DB.

    But if you must duplicate the data within WP, if your events post type was registered with the “show_in_rest” arg passed as true, you can access its data using the post type slug route, such as example.info/wp-json/wp/v2/events. Similarly, if its meta data has been exposed to the API, it’ll show up in the “meta” portion of the returned data.

    You could create your own custom API route that does whatever you wish, limited only by what PHP is capable of.

    FWIW, the term “endpoint” is frequently misused. I do so myself on occasion. A path like example.info/wp-json/wp/v2/my-route is an API route. The endpoints of that route are the associated request types such as POST, PUT, GET, etc. Thus your last question would be more accurately stated as “Will I need just a single route for this CPT where the POST/PUT/DELETE endpoints will be [requested]?”

    Thread Starter traveler

    (@visualeight)

    Hey bcworkz,
    You bring up a very good point – thank you. So are you saying it would be better and potentially easier to simply query this information on page load, with the page being loaded the “events” category feed, from the company’s database that contains this information?

    How would querying the events in this fashion affect page caching for load times? Fwiw, the site is hosted on WPengine.

    Thanks.

    • This reply was modified 6 years, 3 months ago by traveler.
    Moderator bcworkz

    (@bcworkz)

    I really despise redundant data. It should be avoided to the extent it’s at all practical. If nothing else, keeping the data synced is a PITA and enough reason to avoid it. If the DB server will accept external queries, you could connect directly to it using a new instance of the wpdb class. There’s a good chance the DB server would need its firewall and security modified to allow access from your WPengine server.

    Even if you are forced to access the data through an API, it’s better to do so dynamically from the page than to create redundant data. Depending on the nature of the queries, it could be beneficial to cache query results. Yes, this is also redundant data. But caching is not persistent like creating posts would be. The data expires at some point and is refreshed automatically.

    Page caching also depends on the nature of the page displaying query results. If every page load is potentially different content, it cannot be cached. If it stays the same during a longer interval, daily perhaps, the cache should expire before then, maybe every few hours.

    Thread Starter traveler

    (@visualeight)

    So I’ve been reading as much as possible on this, going over tuts, but most all that I’ve seen talks about using the rest api to query it’s own database, meaning in my theme I query my site’s database to fetch data and create posts from it. In all these, there is a javascript trigger that starts it.

    I’m now confused now though, about what triggers making/creating a post when JSON data is sent to an endpoint?

    I’ve created and deleted cpt’s using wp_insert_post() that creates a post with a title that matches an ID number attached to the end of a URL. In this case, if that ID exists, then I use ajax to send that ID to PHP and call a PHP function that then uses wp_insert_post() to create the post. To delete it, I use the same ID as a meta_value to query the correct post and then use wp_delete_post() to delete it. This is a very simple tracking mechanism to see who goes to a signup form and then doesn’t complete it.

    So what am I missing here, I have a small JSON object that will be sent to my route,
    example.info/wp-json/wp/v2/events
    and my JSON that will be sent is:

    {
        "eventID": 16924,
        "regions": "R1, R2, R3",
        "type": "Rally",
        "eventName": "Test Event Name",
        "eventLocation": "Test Location",
        "eventStartDate": "2/29/2020",
        "eventStartTime": "12:00",
        "eventStartAMPM": "pm",
        "eventEndTime": "2:00",
        "eventEndAMPM": "pm",
        "staffResponsible": "Staffname1",
        "notes": "",
        "counties": "Los Angeles, San Bernardino",
        "dept": "Information Technology"
    }

    So what will trigger my function to create a post from this?

    Thread Starter traveler

    (@visualeight)

    Quick follow-up to my question about what triggers this to create a post, do I need the URL that sends the POST request with the above json to go directly to the php file that creates the post?

    This site had something like this several years ago that posted to:
    example.com/wp-content/themes/SEIU/setup/events/add-event.php?auth=seiujLJ62x

    with a simple auth check function before processing the json to create the new custom post?

    Moderator bcworkz

    (@bcworkz)

    If the PHP page uses WP functions, then no, do not directly request it. If no WP functions, then WP doesn’t care and you can do anything PHP alone is capable of. If WP is involved, either make a proper WP Ajax request, or request through /wp-admin/admin-post.php or the REST API.

    If you send JSON through your custom route, the callback registered for the endpoint is what triggers anything that needs to be done for that endpoint.

    Thread Starter traveler

    (@visualeight)

    Ok, I was under the impression these routes were automatically generated when you “show in rest” for the CPT. Here’s how I’ve created these:

    <?php
    
    // second param is function name creating the routes
    add_action('rest_api_init', 'eventRestRoute');
    
    function eventRestRoute() {
    
        // first two args can be whatever
        register_rest_route('seiu-events/v1', 'seiuEventsRest', array(
            'methods'   =>  'POST',
            'callback'  =>  'createEvent'
        ));
        register_rest_route('seiu-events/v1', 'seiuEventsRest', array(
            'methods'   =>  'DELETE',
            'callback'  =>  'deleteEvent'
        ));
        register_rest_route('seiu-events/v1', 'seiuEventsRest', array(
            'methods'   =>  'PUT',
            'callback'  =>  'editEvent'
        ));
    }
    
    // create new event post
    function createEvent() {
    
        // create the event post
        wp_insert_post(array(
            'post_type'     =>  'events',
            'post_status'   =>  'publish',
            'post_title'    =>  'Rest Post',
            'post_content'  =>  'This is an amazing post.'
        ));
    }

    At this point I’m not attempting to capture any of the json data sent but just create a new Events post titled “Rest Post” to make sure I’m going in the correct direction.

    When I use Postman to make a POST request to example.com/wp-json/wp/v2/events, I get this error:

    {
        "code": "rest_cannot_create",
        "message": "Sorry, you are not allowed to create posts as this user.",
        "data": {
            "status": 401
        }
    }

    Reading up on the REST API documentation I see that the cookie authentication that uses nonce only works for using the REST API from within wordpress. My calls are coming from outside of WordPress. What is the workaround for this, assuming my code above should allow a simple post to be created just by sending data to my custom route?

    Last, am I wrong to assume I do not need to be using Ajax for this, since the request is not originating in a browser but instead from an outside system?

    Moderator bcworkz

    (@bcworkz)

    Yes, “show_in_rest” exposes standard post type routes and endpoints. Functionality could be extended through any hooks that fire as part of the request. Endpoints beyond GET do require authentication. For remote API requests, an API authentication plugin is required.

    My understanding is you created a custom route. In that case functionality is only limited by the capabilities of PHP.

    AFAIK Ajax requests can be made by any sort of HTTP[S] request from anything. A browser cookie is not necessarily required. However, not making adequate security checks in an Ajax callback would open huge security holes if that callback modifies data in any way. In that case the callback should be checking the user is logged in, has adequate WP capabilities, and that a proper nonce is supplied. A logged in user does require a browser cookie. Thus it’s impractical to update data via Ajax through an external app.

Viewing 8 replies - 1 through 8 (of 8 total)

The topic ‘Create/edit/delete CPT w/REST’ is closed to new replies.