SlideShare a Scribd company logo
1 of 56
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
DECEMBER 2016
WORDPRESS 4.7
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;
}
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
ALWAYS ASSUME THERE IS MORE
NAMESPACES
NAMESPACES
{
"name": "A WP Site",
"description": "",
"URL": "https://www.a-wp-site.com",
"namespaces": [
"wp/v2",
"your_namespace"
],
"authentication": []
"routes": {
"/": { ... },
"/wp/v2/posts": { ... },
...
"/your_namespace/path": { ... }
}
}
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
20162016

More Related Content

What's hot

Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stackPaul Bearne
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkDirk Haun
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkVance Lucas
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutSlim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutVic Metcalfe
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Lar21
 
15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-search15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-searchRazvan Raducanu, PhD
 
Flask patterns
Flask patternsFlask patterns
Flask patternsit-people
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframeworkRadek Benkel
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Arc & Codementor
 
Silex: From nothing to an API
Silex: From nothing to an APISilex: From nothing to an API
Silex: From nothing to an APIchrisdkemper
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyAlessandro Cucci
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 

What's hot (20)

Kyiv.py #17 Flask talk
Kyiv.py #17 Flask talkKyiv.py #17 Flask talk
Kyiv.py #17 Flask talk
 
Phinx talk
Phinx talkPhinx talk
Phinx talk
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stack
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-Framework
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutSlim RedBeanPHP and Knockout
Slim RedBeanPHP and Knockout
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
 
15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-search15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-search
 
Flask patterns
Flask patternsFlask patterns
Flask patterns
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJS
 
Flask SQLAlchemy
Flask SQLAlchemy Flask SQLAlchemy
Flask SQLAlchemy
 
Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframework
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
 
Silex: From nothing to an API
Silex: From nothing to an APISilex: From nothing to an API
Silex: From nothing to an API
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 

Viewers also liked

Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
O DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTIL
O DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTILO DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTIL
O DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTILflaviotanabe
 
Design de Produto - Google Taxi
Design de Produto - Google TaxiDesign de Produto - Google Taxi
Design de Produto - Google TaxiAdriano Valadão
 
Automating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAutomating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAnderson Aguiar
 
JSON REST API for WordPress
JSON REST API for WordPressJSON REST API for WordPress
JSON REST API for WordPressTaylor Lovett
 
Aula 1 - Introdução à disciplina Design de Produto 1
Aula 1 - Introdução à disciplina Design de Produto 1Aula 1 - Introdução à disciplina Design de Produto 1
Aula 1 - Introdução à disciplina Design de Produto 1Tiago Cruz
 
Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Derek Willian Stavis
 
Beyond The Browser - Creating a RESTful Web Service With WordPress
Beyond The Browser - Creating a RESTful Web Service With WordPressBeyond The Browser - Creating a RESTful Web Service With WordPress
Beyond The Browser - Creating a RESTful Web Service With WordPressChristopher Reding
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockCaldera Labs
 
Faire la conception en équipe sans architecte, non mais allô quoi ?
Faire la conception en équipe sans architecte, non mais allô quoi ?Faire la conception en équipe sans architecte, non mais allô quoi ?
Faire la conception en équipe sans architecte, non mais allô quoi ?Ly-Jia Goldstein
 

Viewers also liked (12)

Design de Produto
Design de ProdutoDesign de Produto
Design de Produto
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
O DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTIL
O DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTILO DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTIL
O DESIGN DE PRODUTO NAS MÃOS DO CONSUMIDOR INFANTIL
 
Design de Produto - Google Taxi
Design de Produto - Google TaxiDesign de Produto - Google Taxi
Design de Produto - Google Taxi
 
Automating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAutomating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with Gulp
 
JSON REST API for WordPress
JSON REST API for WordPressJSON REST API for WordPress
JSON REST API for WordPress
 
Aula 1 - Introdução à disciplina Design de Produto 1
Aula 1 - Introdução à disciplina Design de Produto 1Aula 1 - Introdução à disciplina Design de Produto 1
Aula 1 - Introdução à disciplina Design de Produto 1
 
TDD with PhpSpec
TDD with PhpSpecTDD with PhpSpec
TDD with PhpSpec
 
Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!
 
Beyond The Browser - Creating a RESTful Web Service With WordPress
Beyond The Browser - Creating a RESTful Web Service With WordPressBeyond The Browser - Creating a RESTful Web Service With WordPress
Beyond The Browser - Creating a RESTful Web Service With WordPress
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
 
Faire la conception en équipe sans architecte, non mais allô quoi ?
Faire la conception en équipe sans architecte, non mais allô quoi ?Faire la conception en équipe sans architecte, non mais allô quoi ?
Faire la conception en équipe sans architecte, non mais allô quoi ?
 

Similar to WordPress REST API hacking

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
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
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
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your CodeAbbas Ali
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPMichael Francis
 
Apostrophe
ApostropheApostrophe
Apostrophetompunk
 
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
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Yevhen Kotelnytskyi
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 

Similar to WordPress REST API hacking (20)

Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
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
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
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
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTP
 
Apostrophe
ApostropheApostrophe
Apostrophe
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Add loop shortcode
Add loop shortcodeAdd loop shortcode
Add loop shortcode
 

More from Jeroen 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
 
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
 
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 (11)

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
 
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
 
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

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
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
 
#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
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 

Recently uploaded (20)

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
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...
 
#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
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 

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
  • 14. YOU KNOW HOW TO CREATE A PLUGIN? EXTENDING THE API
  • 15. 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();
  • 16. 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() { }
  • 18. LET’S START EASY! public function initServer() { add_filter( 'rest_enabled', [ $this, 'disableApi' ] ); } public function disableApi( $isEnabled ) { if ( $isEnabled == true ) { return false; } return $isEnabled; }
  • 19. LET’S START EASY! public function initServer() { add_filter( 'rest_enabled', [ $this, 'disableApi' ] ); } public function disableApi( $isEnabled ) { if ( $isEnabled == true ) { return false; } return $isEnabled; }
  • 20. /02 CHANGE THE ROOT URL
  • 21. 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; }
  • 23. register_post_type( $post_type, $args ); register_taxonomy( $taxonomy, $object_type, $args );
  • 24. 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; }
  • 25. /04 CHANGE CUSTOM POST TYPE HANDLING
  • 26. 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 {}
  • 27. 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 ); }
  • 28. 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 ); }
  • 29. 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 );
  • 30. /05 ROLL YOUR OWN ENDPOINT
  • 31. ALWAYS ASSUME THERE IS MORE NAMESPACES
  • 32. NAMESPACES { "name": "A WP Site", "description": "", "URL": "https://www.a-wp-site.com", "namespaces": [ "wp/v2", "your_namespace" ], "authentication": [] "routes": { "/": { ... }, "/wp/v2/posts": { ... }, ... "/your_namespace/path": { ... } } }
  • 35. 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
  • 37. ANNOTATE AND VALIDATE JSON DOCUMENTS JSON-SCHEMA.ORG
  • 38. 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
  • 40. 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
  • 41. /07 APPLY SOME FILTERING
  • 42. 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
  • 44. 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
  • 45. 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
  • 47. 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…
  • 49. 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…
  • 51. /11 CHANGE ALL OUTPUT!
  • 52. 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…
  • 53. 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…
  • 54. 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