SlideShare a Scribd company logo
1 of 52
Download to read offline
WORDPRESS REST API HACKING
WORDPRESS : IT’S A BLOG
LONG AGO
WORDPRESS : IT’S NOT JUST A BLOG
THE PAST
WORDPRESS : IT’S NOT JUST CMS
PRESENT
WORDPRESS : IT’S AN APPLICATION FRAMEWORK
FUTURE?
BECAUSE OF THE WP REST API
NO TODAY!
RESOURCE BASED STATELESS COMMUNICATION
REPRESENTATIONAL STATE TRANSFER
TO GAIN ACCESS TO (A COMPUTER) ILLEGALLY
TO ALTER (A COMPUTER PROGRAM)
/HĂK/·ING
/00 ALTER THE REST API
WHAT YOU NEED TO KNOW FIRST..
INFRASTRUCTURE IS IN CORE
IMPLEMENTATION IN THE REST-API PLUGIN
2 PARTS
IN CORE
├── rest-api
│   ├── class-wp-rest-request.php
│   ├── class-wp-rest-response.php
│   └── class-wp-rest-server.php
├── rest-api.php
IN PLUGIN
├── class-wp-rest-attachments-controller.php
├── class-wp-rest-comments-controller.php
├── class-wp-rest-controller.php
├── class-wp-rest-post-statuses-controller.php
├── class-wp-rest-post-types-controller.php
├── class-wp-rest-posts-controller.php
├── class-wp-rest-revisions-controller.php
├── class-wp-rest-settings-controller.php
├── class-wp-rest-taxonomies-controller.php
├── class-wp-rest-terms-controller.php
└── class-wp-rest-users-controller.php
YOU KNOW HOW TO CREATE A PLUGIN?
EXTENDING THE API
MY PLUGIN.PHP SETUP
<?php
/*
Plugin Name: My REST API extension
Plugin URI: https://www.a-wp-site.com/
Description: WordPress REST API extension
Version: 1.0.0
Author: Enrise
Author URI: https://www.enrise.com
*/
require_once('src/Bootstrap.php');
new Bootstrap::getInstance();
WHEN TO TRIGGER YOUR CODE
public static function getInstance() {
if ( ! ( self::$instance instanceof self ) ) {
self::$instance = new self();
}
return self::$instance;
}
protected function __construct() {
add_action( 'plugins_loaded', [ $this, 'initServer' ], 100 );
}
public function initServer() {
}
/01 DISABLE THE API
LET’S START EASY!
public function initServer() {
add_filter( 'rest_enabled', [ $this, 'disableApi' ] );
}
public function disableApi( $isEnabled ) {
if ( $isEnabled == true ) {
return false;
}
return $isEnabled;
}
/02 CHANGE THE ROOT URL
CHANGE WP-JSON INTO …
public function initServer() {
if ( ! defined( 'REST_API_VERSION' ) ) {
// return early if WP API versions do not exist
add_action( 'all_admin_notices', [ $this, 'showError' ] );
return;
}
add_filter( 'rest_url_prefix', [ $this, 'changeApiBase' ] );
}
public function changeApiBase( $prefix ) {
if ($prefix === 'wp-json') {
return 'api';
}
return $prefix;
}
/03 CHANGE EXPOSURE
register_post_type( $post_type, $args );
register_taxonomy( $taxonomy, $object_type, $args );
ACCESS POST TYPE & TAXONOMY
public function initServer() {
add_action( 'rest_api_init', [ $this, 'updateExposure' ], 12 );
}
public function updateExposure() {
global $wp_post_types, $wp_taxonomies;
$wp_post_types['customposttype']->show_in_rest = true;
$wp_taxonomies['customtaxonomy']->show_in_rest = true;
}
/04 CHANGE CUSTOM POST
TYPE HANDLING
EXTEND API CONTROLLERS
public function updateExposure() {
global $wp_post_types, $wp_taxonomies;
$wp_post_types['customposttype']->show_in_rest = true;
$wp_post_types['customposttype']->rest_base = 'customposttype';
$wp_post_types['customposttype']->rest_controller_class =
'EnriseApiEndpointCustomType';
$wp_taxonomies['customtaxonomy']->show_in_rest = true;
$wp_taxonomies['customtaxonomy']->rest_base = 'customtaxonomy';
$wp_taxonomies['customtaxonomy']->rest_controller_class =
'EnriseApiEndpointCustomTaxonomy';
}
class CustomType extends WP_REST_Posts_Controller {}
class CustomTaxonomy extends WP_REST_Terms_Controller {}
EXTEND THE INPUT / OUTPUT
register_rest_field( 'customposttype', 'custommetafield', [
'schema' => [
'type' => 'integer',
'context' => [ 'view', 'edit' ],
],
'get_callback' => [ $this, 'getMetaField' ],
'update_callback' => [ $this, 'saveMetaField' ]
] );
public function getMetaField( $post, $key, $request ) {
return get_post_meta( $post['id'], $key, true );
}
public function saveMetaField( $value, $post, $key ) {
return update_post_meta( $post->ID, $key, $value );
}
EXTEND THE INPUT / OUTPUT
register_rest_field( 'customposttype', 'custommetafield', [
'schema' => [
'type' => 'integer',
'context' => [ 'view', 'edit' ],
],
'get_callback' => [ $this, 'getMetaField' ],
'update_callback' => [ $this, 'saveMetaField' ]
] );
public function getMetaField( $post, $key, $request ) {
return get_post_meta( $post['id'], $key, true );
}
public function saveMetaField( $value, $post, $key ) {
return update_post_meta( $post->ID, $key, $value );
}
REST API 2.0 BETA 15
$args =[
'sanitize_callback' => 'sanitize_my_meta_key',
'auth_callback' => 'authorize_my_meta_key',
'type' => 'string',
'description' => 'My registered meta key',
'single' => true,
'show_in_rest' => true,
];
register_meta( 'post', 'my_meta_key', $args );
/05 ROLL YOUR OWN
ENDPOINT
WP_REST_Controller
WP_REST_Posts_Controller
STANDARD IMPLEMENTATION
WP_REST_Controller
Your_Extended_Controller
OPTION #1
register_rest_route( 'enrise', '/version/(?P<os>[a-z]{3,7})', [
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'getVersion' ],
'permission_callback' => [ $this, 'checkAccess' ],
'args' => [
'os' => [
'validate_callback' => [ $this, 'isOS' ],
'sanitize_callback' => [ $this, 'filterOS' ],
'required' => true,
],
],
],
] );
OPTION #2
/06 OVERRIDE DEFAULT
FUNCTIONALITY
ANNOTATE AND VALIDATE JSON DOCUMENTS
JSON-SCHEMA.ORG
public function get_item_schema() {
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => $this->post_type,
'type' => 'object',
/*
* Base properties for every Post.
*/
'properties' => [
'date' => [
'description' => __( "The date the object was published, in the
site's timezone." ),
'type' => 'string',
'format' => 'date-time',
'context' => [ 'view', 'edit', 'embed' ],
],
...
];
}
JSON SCHEMA DEFINITION
global $wp_rest_additional_fields;
GLOBAL AGAIN…
register_rest_field( 'user', 'first_name', [
'schema' => [
'description' => __( 'First name for the resource.' ),
'type' => 'string',
'context' => [ 'edit', 'embed', 'view' ],
'arg_options' => [
'sanitize_callback' => 'sanitize_text_field',
],
],
] );
register_rest_field( 'user', 'last_name', [
'schema' => [
'description' => __( 'Last name for the resource.' ),
'type' => 'string',
'context' => [ 'edit', 'embed', 'view' ],
'arg_options' => [
'sanitize_callback' => 'sanitize_text_field',
],
],
] );
OVERRIDE DEFAULT CONFIGURATION
/07 APPLY SOME FILTERING
public function initServer() {
add_filter('rest_customposttype_query', [ $this, 'filterbyMetaField' ], 10, 2);
}
/**
* @param $args
* @param $request WP_REST_Request
*/
public function filterByMetaField($args, $request) {
$filter = [];
$filter['meta_key'] = 'custommetafield';
$filter['meta_value'] = 1476896350;
$filter['meta_type'] = 'DECIMAL';
$filter['meta_compare'] = '>=';
return array_merge($args, $filter);
}
CHANGE THE QUERY BEHAVIOUR
/08 FILE UPLOADS
xhr.onload = function() {
var attachment = JSON.parse(this.responseText);
$.current.set('featured_image', attachment.id);
saveCustompost();
};
xhr.open('POST', '/wp-json/wp/v2/media');
xhr.setRequestHeader('Content-Type', 'image/jpeg');
xhr.setRequestHeader('Content-Disposition',
'attachment; filename=filename.jpg');
xhr.send(image.read());
UPLOAD A FILE
public function initServer() {
add_filter('wp_handle_sideload_prefilter', [ $this, 'autoRotate' ]);
add_filter('rest_insert_customposttype', [$this, 'saveAttachment'], 10, 3);
}
/**
* @param $post WP_Post
* @param $request WP_REST_Request
* @param $create bool
*/
public function saveAttachment($post, $request, $create) {
if ($create === true && isset( $request['featured_image'] )) {
set_post_thumbnail( $post->ID, $request['featured_image'] );
}
}
HANDLE THE ATTACHMENT
/09 CACHE REQUESTS
add_filter( 'rest_pre_dispatch', [ $this, 'lastUpdate' ], 10, 3 );
public function lastUpdate( $response, $server, $request ) {
$since = $request->get_header( 'if_modified_since' );
if ( $since === null ) {
return $response;
}
if ( $response !== null || $response->get_route() !==
'/wp/v2/customposttype' ) {
return $response;
}
$lastrequest = DateTime::createFromFormat( DateTime::RFC1123, $since );
$lastpost = DateTime::createFromFormat( 'Y-m-d H:i:s',
get_lastpostmodified( 'gmt', 'customposttype' ) );
if ( $lastrequest >= $lastpost ) {
return new WP_REST_Response( null, 304 );
}
return $response;
}
LET THE CLIENT CACHE…
/10 AUTHENTICATION
add_filter( 'determine_current_user', [ $this, 'authenticate' ] );
add_filter( 'rest_authentication_errors', [ $this, 'getErrors' ] );
public function authenticate( $user ) { | public function getErrors( $value ) {
// method run/used multiple times | // already overrided
if ($user instanceof WP_User) { | if ( $value !== null ) {
return $user; | return $value;
} | }
// roll your own authentication here | // WP_Error|null|bool(!?)
if (false) { | return $this->status;
$this->status = new WP_Error(); | }
return null; |
} |
$this->status = true; |
return $user->ID; |
} |
TRY TO DEBUG THIS…
IMPLEMENTATIONS
WORDPRESS.ORG/PLUGINS/OAUTH2-PROVIDER
WORDPRESS.ORG/PLUGINS/JWT-AUTHENTICATION-FOR-WP-REST-API
WORDPRESS.ORG/PLUGINS/REST-API-OAUTH1
/11 CHANGE ALL OUTPUT!
add_filter( 'rest_pre_serve_request', [ $this, 'changeResponse' ], 10, 4 );
public function changeResponse( $served, $response, $request, $server ) {
$route = $response->get_matched_route();
if ( $served || $route !== '/wp/v2/customposttype' ) {
return false;
}
if ( 'HEAD' === $request->get_method() ) {
return null;
}
$result = $server->response_to_data( $response, true );
$transform = new Transformer( $result );
echo wp_json_encode( iterator_to_array( $transform ) );
return true;
}
THIS SHOULDN’T BE NECESSARY…
class Transformer extends ArrayIterator {
public function current() {
$item = parent::current();
$item = $this->modify( $item );
return $item;
}
private function modify( array $data ) {
// modify the data in any way
return $data;
}
}
THIS SHOULDN’T BE NECESSARY…
add_filter('rest_prepare_customposttype', 'beforeOutput', 10, 3);
add_filter('rest_pre_insert_customposttype', 'beforeInsertInDb', 10, 2);
add_filter('rest_insert_customposttype', 'afterInsertInDb', 10, 3);
add_filter('rest_query_vars', 'filterQueryVars', 10, 1);
OTHER INTERESTING HOOKS
MORE HOOKS?
V2.WP-API.ORG/EXTENDING/HOOKS
WordPress REST API hacking

More Related Content

Viewers also liked

Webinar - Maximize Your Library Technology - 2016-05-24
Webinar - Maximize Your Library Technology - 2016-05-24Webinar - Maximize Your Library Technology - 2016-05-24
Webinar - Maximize Your Library Technology - 2016-05-24TechSoup
 
Designing Interactive Learning Spaces
Designing Interactive Learning Spaces Designing Interactive Learning Spaces
Designing Interactive Learning Spaces Brian Pichman
 
Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21
Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21
Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21TechSoup
 
Pgs 506 class-notes_
Pgs 506 class-notes_Pgs 506 class-notes_
Pgs 506 class-notes_Mahesh Kumar
 
Programming Ideas in Makerspaces
Programming Ideas in MakerspacesProgramming Ideas in Makerspaces
Programming Ideas in MakerspacesBrian Pichman
 
Día internacional de la mujer
Día internacional de la mujerDía internacional de la mujer
Día internacional de la mujerNicolas Rojas
 
Prezentacija Blog
Prezentacija BlogPrezentacija Blog
Prezentacija Blogfizicarke2
 
Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...
Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...
Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...Christian Heise
 
Dia internacional de la mujer
Dia internacional de la mujerDia internacional de la mujer
Dia internacional de la mujeralejandro serrano
 
Cписок сотрудников "Золотой ключик"
Cписок сотрудников "Золотой ключик"Cписок сотрудников "Золотой ключик"
Cписок сотрудников "Золотой ключик"Parusnik55
 
Презентация Центр ПМСС
Презентация Центр ПМССПрезентация Центр ПМСС
Презентация Центр ПМССParusnik55
 
Filmska umjetnost
Filmska umjetnostFilmska umjetnost
Filmska umjetnostaco bojic
 
PowerPoint 8 de marzo de 2016. Día Internacional de la Mujer
PowerPoint 8 de marzo de 2016. Día Internacional de la MujerPowerPoint 8 de marzo de 2016. Día Internacional de la Mujer
PowerPoint 8 de marzo de 2016. Día Internacional de la MujerMaría López
 
Likovna kultura 2
Likovna kultura 2Likovna kultura 2
Likovna kultura 2aco bojic
 
Likovna kultura 1
Likovna kultura 1Likovna kultura 1
Likovna kultura 1aco bojic
 

Viewers also liked (20)

Conduction
ConductionConduction
Conduction
 
Webinar - Maximize Your Library Technology - 2016-05-24
Webinar - Maximize Your Library Technology - 2016-05-24Webinar - Maximize Your Library Technology - 2016-05-24
Webinar - Maximize Your Library Technology - 2016-05-24
 
Designing Interactive Learning Spaces
Designing Interactive Learning Spaces Designing Interactive Learning Spaces
Designing Interactive Learning Spaces
 
Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21
Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21
Webinar - QuickBooks Online for Newer Nonprofit Users - 2016-07-21
 
Pgs 506 class-notes_
Pgs 506 class-notes_Pgs 506 class-notes_
Pgs 506 class-notes_
 
Programming Ideas in Makerspaces
Programming Ideas in MakerspacesProgramming Ideas in Makerspaces
Programming Ideas in Makerspaces
 
Día internacional de la mujer
Día internacional de la mujerDía internacional de la mujer
Día internacional de la mujer
 
Prezentacija Blog
Prezentacija BlogPrezentacija Blog
Prezentacija Blog
 
Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...
Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...
Disputation: Von Open Access zu Open Science: Zum Wandel digitaler Kulturen d...
 
Dia internacional de la mujer
Dia internacional de la mujerDia internacional de la mujer
Dia internacional de la mujer
 
Signal flow graph
Signal flow graphSignal flow graph
Signal flow graph
 
Programming ideas
Programming ideasProgramming ideas
Programming ideas
 
Cписок сотрудников "Золотой ключик"
Cписок сотрудников "Золотой ключик"Cписок сотрудников "Золотой ключик"
Cписок сотрудников "Золотой ключик"
 
Презентация Центр ПМСС
Презентация Центр ПМССПрезентация Центр ПМСС
Презентация Центр ПМСС
 
Carnaval
CarnavalCarnaval
Carnaval
 
Citylogistics in Amsterdam's Oude Pijp
Citylogistics in Amsterdam's Oude PijpCitylogistics in Amsterdam's Oude Pijp
Citylogistics in Amsterdam's Oude Pijp
 
Filmska umjetnost
Filmska umjetnostFilmska umjetnost
Filmska umjetnost
 
PowerPoint 8 de marzo de 2016. Día Internacional de la Mujer
PowerPoint 8 de marzo de 2016. Día Internacional de la MujerPowerPoint 8 de marzo de 2016. Día Internacional de la Mujer
PowerPoint 8 de marzo de 2016. Día Internacional de la Mujer
 
Likovna kultura 2
Likovna kultura 2Likovna kultura 2
Likovna kultura 2
 
Likovna kultura 1
Likovna kultura 1Likovna kultura 1
Likovna kultura 1
 

Similar to WordPress REST API hacking

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application frameworkDustin Filippini
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your CodeAbbas Ali
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection apiMatthieu Aubry
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsBastian Hofmann
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonKris Wallsmith
 

Similar to WordPress REST API hacking (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application framework
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
 

More from Jeroen van Dijk

The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
Beacons in Appcelerator Titanium
Beacons in Appcelerator TitaniumBeacons in Appcelerator Titanium
Beacons in Appcelerator TitaniumJeroen van Dijk
 
Teaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumTeaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumJeroen van Dijk
 
Teaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumTeaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumJeroen van Dijk
 
An app on the shoulders of giants
An app on the shoulders of giantsAn app on the shoulders of giants
An app on the shoulders of giantsJeroen van Dijk
 
Zend Server: Not just a PHP stack
Zend Server: Not just a PHP stackZend Server: Not just a PHP stack
Zend Server: Not just a PHP stackJeroen van Dijk
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
Liking Relevance - PHP North East 2014
Liking Relevance - PHP North East 2014Liking Relevance - PHP North East 2014
Liking Relevance - PHP North East 2014Jeroen van Dijk
 
To SQL or No(t)SQL - PHPNW12
To SQL or No(t)SQL - PHPNW12To SQL or No(t)SQL - PHPNW12
To SQL or No(t)SQL - PHPNW12Jeroen van Dijk
 
To SQL or No(t)SQL - PFCongres 2012
To SQL or No(t)SQL - PFCongres 2012To SQL or No(t)SQL - PFCongres 2012
To SQL or No(t)SQL - PFCongres 2012Jeroen van Dijk
 
Socializing a world of travel
Socializing a world of travelSocializing a world of travel
Socializing a world of travelJeroen van Dijk
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Jeroen van Dijk
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Jeroen van Dijk
 
Edge Side Includes in Zend Framework without Varnish
Edge Side Includes in Zend Framework without VarnishEdge Side Includes in Zend Framework without Varnish
Edge Side Includes in Zend Framework without VarnishJeroen van Dijk
 

More from Jeroen van Dijk (15)

The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
Beacons in Appcelerator Titanium
Beacons in Appcelerator TitaniumBeacons in Appcelerator Titanium
Beacons in Appcelerator Titanium
 
Teaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumTeaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in Titanium
 
Teaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in TitaniumTeaming up WordPress API with Backbone.js in Titanium
Teaming up WordPress API with Backbone.js in Titanium
 
An app on the shoulders of giants
An app on the shoulders of giantsAn app on the shoulders of giants
An app on the shoulders of giants
 
Zend Server: Not just a PHP stack
Zend Server: Not just a PHP stackZend Server: Not just a PHP stack
Zend Server: Not just a PHP stack
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
Liking Relevance - PHP North East 2014
Liking Relevance - PHP North East 2014Liking Relevance - PHP North East 2014
Liking Relevance - PHP North East 2014
 
To SQL or No(t)SQL - PHPNW12
To SQL or No(t)SQL - PHPNW12To SQL or No(t)SQL - PHPNW12
To SQL or No(t)SQL - PHPNW12
 
To SQL or No(t)SQL - PFCongres 2012
To SQL or No(t)SQL - PFCongres 2012To SQL or No(t)SQL - PFCongres 2012
To SQL or No(t)SQL - PFCongres 2012
 
Socializing a world of travel
Socializing a world of travelSocializing a world of travel
Socializing a world of travel
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?
 
Edge Side Includes in Zend Framework without Varnish
Edge Side Includes in Zend Framework without VarnishEdge Side Includes in Zend Framework without Varnish
Edge Side Includes in Zend Framework without Varnish
 

Recently uploaded

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 

Recently uploaded (20)

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 

WordPress REST API hacking

  • 2. WORDPRESS : IT’S A BLOG LONG AGO
  • 3. WORDPRESS : IT’S NOT JUST A BLOG THE PAST
  • 4. WORDPRESS : IT’S NOT JUST CMS PRESENT
  • 5. WORDPRESS : IT’S AN APPLICATION FRAMEWORK FUTURE?
  • 6. BECAUSE OF THE WP REST API NO TODAY!
  • 7. RESOURCE BASED STATELESS COMMUNICATION REPRESENTATIONAL STATE TRANSFER
  • 8. TO GAIN ACCESS TO (A COMPUTER) ILLEGALLY TO ALTER (A COMPUTER PROGRAM) /HĂK/·ING
  • 9. /00 ALTER THE REST API WHAT YOU NEED TO KNOW FIRST..
  • 10. INFRASTRUCTURE IS IN CORE IMPLEMENTATION IN THE REST-API PLUGIN 2 PARTS
  • 11. IN CORE ├── rest-api │   ├── class-wp-rest-request.php │   ├── class-wp-rest-response.php │   └── class-wp-rest-server.php ├── rest-api.php
  • 12. IN PLUGIN ├── class-wp-rest-attachments-controller.php ├── class-wp-rest-comments-controller.php ├── class-wp-rest-controller.php ├── class-wp-rest-post-statuses-controller.php ├── class-wp-rest-post-types-controller.php ├── class-wp-rest-posts-controller.php ├── class-wp-rest-revisions-controller.php ├── class-wp-rest-settings-controller.php ├── class-wp-rest-taxonomies-controller.php ├── class-wp-rest-terms-controller.php └── class-wp-rest-users-controller.php
  • 13. YOU KNOW HOW TO CREATE A PLUGIN? EXTENDING THE API
  • 14. MY PLUGIN.PHP SETUP <?php /* Plugin Name: My REST API extension Plugin URI: https://www.a-wp-site.com/ Description: WordPress REST API extension Version: 1.0.0 Author: Enrise Author URI: https://www.enrise.com */ require_once('src/Bootstrap.php'); new Bootstrap::getInstance();
  • 15. WHEN TO TRIGGER YOUR CODE public static function getInstance() { if ( ! ( self::$instance instanceof self ) ) { self::$instance = new self(); } return self::$instance; } protected function __construct() { add_action( 'plugins_loaded', [ $this, 'initServer' ], 100 ); } public function initServer() { }
  • 17. LET’S START EASY! public function initServer() { add_filter( 'rest_enabled', [ $this, 'disableApi' ] ); } public function disableApi( $isEnabled ) { if ( $isEnabled == true ) { return false; } return $isEnabled; }
  • 18. /02 CHANGE THE ROOT URL
  • 19. CHANGE WP-JSON INTO … public function initServer() { if ( ! defined( 'REST_API_VERSION' ) ) { // return early if WP API versions do not exist add_action( 'all_admin_notices', [ $this, 'showError' ] ); return; } add_filter( 'rest_url_prefix', [ $this, 'changeApiBase' ] ); } public function changeApiBase( $prefix ) { if ($prefix === 'wp-json') { return 'api'; } return $prefix; }
  • 21. register_post_type( $post_type, $args ); register_taxonomy( $taxonomy, $object_type, $args );
  • 22. ACCESS POST TYPE & TAXONOMY public function initServer() { add_action( 'rest_api_init', [ $this, 'updateExposure' ], 12 ); } public function updateExposure() { global $wp_post_types, $wp_taxonomies; $wp_post_types['customposttype']->show_in_rest = true; $wp_taxonomies['customtaxonomy']->show_in_rest = true; }
  • 23. /04 CHANGE CUSTOM POST TYPE HANDLING
  • 24. EXTEND API CONTROLLERS public function updateExposure() { global $wp_post_types, $wp_taxonomies; $wp_post_types['customposttype']->show_in_rest = true; $wp_post_types['customposttype']->rest_base = 'customposttype'; $wp_post_types['customposttype']->rest_controller_class = 'EnriseApiEndpointCustomType'; $wp_taxonomies['customtaxonomy']->show_in_rest = true; $wp_taxonomies['customtaxonomy']->rest_base = 'customtaxonomy'; $wp_taxonomies['customtaxonomy']->rest_controller_class = 'EnriseApiEndpointCustomTaxonomy'; } class CustomType extends WP_REST_Posts_Controller {} class CustomTaxonomy extends WP_REST_Terms_Controller {}
  • 25. EXTEND THE INPUT / OUTPUT register_rest_field( 'customposttype', 'custommetafield', [ 'schema' => [ 'type' => 'integer', 'context' => [ 'view', 'edit' ], ], 'get_callback' => [ $this, 'getMetaField' ], 'update_callback' => [ $this, 'saveMetaField' ] ] ); public function getMetaField( $post, $key, $request ) { return get_post_meta( $post['id'], $key, true ); } public function saveMetaField( $value, $post, $key ) { return update_post_meta( $post->ID, $key, $value ); }
  • 26. EXTEND THE INPUT / OUTPUT register_rest_field( 'customposttype', 'custommetafield', [ 'schema' => [ 'type' => 'integer', 'context' => [ 'view', 'edit' ], ], 'get_callback' => [ $this, 'getMetaField' ], 'update_callback' => [ $this, 'saveMetaField' ] ] ); public function getMetaField( $post, $key, $request ) { return get_post_meta( $post['id'], $key, true ); } public function saveMetaField( $value, $post, $key ) { return update_post_meta( $post->ID, $key, $value ); }
  • 27. REST API 2.0 BETA 15 $args =[ 'sanitize_callback' => 'sanitize_my_meta_key', 'auth_callback' => 'authorize_my_meta_key', 'type' => 'string', 'description' => 'My registered meta key', 'single' => true, 'show_in_rest' => true, ]; register_meta( 'post', 'my_meta_key', $args );
  • 28. /05 ROLL YOUR OWN ENDPOINT
  • 31. register_rest_route( 'enrise', '/version/(?P<os>[a-z]{3,7})', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'getVersion' ], 'permission_callback' => [ $this, 'checkAccess' ], 'args' => [ 'os' => [ 'validate_callback' => [ $this, 'isOS' ], 'sanitize_callback' => [ $this, 'filterOS' ], 'required' => true, ], ], ], ] ); OPTION #2
  • 33. ANNOTATE AND VALIDATE JSON DOCUMENTS JSON-SCHEMA.ORG
  • 34. public function get_item_schema() { $schema = [ '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', /* * Base properties for every Post. */ 'properties' => [ 'date' => [ 'description' => __( "The date the object was published, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => [ 'view', 'edit', 'embed' ], ], ... ]; } JSON SCHEMA DEFINITION
  • 36. register_rest_field( 'user', 'first_name', [ 'schema' => [ 'description' => __( 'First name for the resource.' ), 'type' => 'string', 'context' => [ 'edit', 'embed', 'view' ], 'arg_options' => [ 'sanitize_callback' => 'sanitize_text_field', ], ], ] ); register_rest_field( 'user', 'last_name', [ 'schema' => [ 'description' => __( 'Last name for the resource.' ), 'type' => 'string', 'context' => [ 'edit', 'embed', 'view' ], 'arg_options' => [ 'sanitize_callback' => 'sanitize_text_field', ], ], ] ); OVERRIDE DEFAULT CONFIGURATION
  • 37. /07 APPLY SOME FILTERING
  • 38. public function initServer() { add_filter('rest_customposttype_query', [ $this, 'filterbyMetaField' ], 10, 2); } /** * @param $args * @param $request WP_REST_Request */ public function filterByMetaField($args, $request) { $filter = []; $filter['meta_key'] = 'custommetafield'; $filter['meta_value'] = 1476896350; $filter['meta_type'] = 'DECIMAL'; $filter['meta_compare'] = '>='; return array_merge($args, $filter); } CHANGE THE QUERY BEHAVIOUR
  • 40. xhr.onload = function() { var attachment = JSON.parse(this.responseText); $.current.set('featured_image', attachment.id); saveCustompost(); }; xhr.open('POST', '/wp-json/wp/v2/media'); xhr.setRequestHeader('Content-Type', 'image/jpeg'); xhr.setRequestHeader('Content-Disposition', 'attachment; filename=filename.jpg'); xhr.send(image.read()); UPLOAD A FILE
  • 41. public function initServer() { add_filter('wp_handle_sideload_prefilter', [ $this, 'autoRotate' ]); add_filter('rest_insert_customposttype', [$this, 'saveAttachment'], 10, 3); } /** * @param $post WP_Post * @param $request WP_REST_Request * @param $create bool */ public function saveAttachment($post, $request, $create) { if ($create === true && isset( $request['featured_image'] )) { set_post_thumbnail( $post->ID, $request['featured_image'] ); } } HANDLE THE ATTACHMENT
  • 43. add_filter( 'rest_pre_dispatch', [ $this, 'lastUpdate' ], 10, 3 ); public function lastUpdate( $response, $server, $request ) { $since = $request->get_header( 'if_modified_since' ); if ( $since === null ) { return $response; } if ( $response !== null || $response->get_route() !== '/wp/v2/customposttype' ) { return $response; } $lastrequest = DateTime::createFromFormat( DateTime::RFC1123, $since ); $lastpost = DateTime::createFromFormat( 'Y-m-d H:i:s', get_lastpostmodified( 'gmt', 'customposttype' ) ); if ( $lastrequest >= $lastpost ) { return new WP_REST_Response( null, 304 ); } return $response; } LET THE CLIENT CACHE…
  • 45. add_filter( 'determine_current_user', [ $this, 'authenticate' ] ); add_filter( 'rest_authentication_errors', [ $this, 'getErrors' ] ); public function authenticate( $user ) { | public function getErrors( $value ) { // method run/used multiple times | // already overrided if ($user instanceof WP_User) { | if ( $value !== null ) { return $user; | return $value; } | } // roll your own authentication here | // WP_Error|null|bool(!?) if (false) { | return $this->status; $this->status = new WP_Error(); | } return null; | } | $this->status = true; | return $user->ID; | } | TRY TO DEBUG THIS…
  • 47. /11 CHANGE ALL OUTPUT!
  • 48. add_filter( 'rest_pre_serve_request', [ $this, 'changeResponse' ], 10, 4 ); public function changeResponse( $served, $response, $request, $server ) { $route = $response->get_matched_route(); if ( $served || $route !== '/wp/v2/customposttype' ) { return false; } if ( 'HEAD' === $request->get_method() ) { return null; } $result = $server->response_to_data( $response, true ); $transform = new Transformer( $result ); echo wp_json_encode( iterator_to_array( $transform ) ); return true; } THIS SHOULDN’T BE NECESSARY…
  • 49. class Transformer extends ArrayIterator { public function current() { $item = parent::current(); $item = $this->modify( $item ); return $item; } private function modify( array $data ) { // modify the data in any way return $data; } } THIS SHOULDN’T BE NECESSARY…
  • 50. add_filter('rest_prepare_customposttype', 'beforeOutput', 10, 3); add_filter('rest_pre_insert_customposttype', 'beforeInsertInDb', 10, 2); add_filter('rest_insert_customposttype', 'afterInsertInDb', 10, 3); add_filter('rest_query_vars', 'filterQueryVars', 10, 1); OTHER INTERESTING HOOKS