SlideShare una empresa de Scribd logo
1 de 56
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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
 

Destacado

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
 

Destacado (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 a 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 a 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
 

Más de 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
 

Más de 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
 

Último

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 

Último (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 

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