WordPress.org

Make WordPress Core

Ticket #23099: jsonrpc.diff

File jsonrpc.diff, 14.1 KB (added by maxcutler, 7 years ago)
  • xmlrpc.php

     
    5252
    5353include_once(ABSPATH . 'wp-admin/includes/admin.php');
    5454include_once(ABSPATH . WPINC . '/class-IXR.php');
     55include_once(ABSPATH . WPINC . '/class-json-rpc.php');
    5556include_once(ABSPATH . WPINC . '/class-wp-xmlrpc-server.php');
    5657
    5758/**
     
    8384        _deprecated_function( __FUNCTION__, '3.4', 'error_log()' );
    8485        if ( ! empty( $GLOBALS['xmlrpc_logging'] ) )
    8586                error_log( $io . ' - ' . $msg );
    86 }
    87  No newline at end of file
     87}
  • wp-includes/class-wp-xmlrpc-server.php

     
    1919 * @subpackage Publishing
    2020 * @since 1.5.0
    2121 */
    22 class wp_xmlrpc_server extends IXR_Server {
     22class wp_xmlrpc_server {
    2323
    2424        /**
    2525         * Register all of the XMLRPC methods that XMLRPC server understands.
     
    3535        function __construct() {
    3636                $this->methods = array(
    3737                        // WordPress API
    38                         'wp.getUsersBlogs'              => 'this:wp_getUsersBlogs',
    39                         'wp.newPost'                    => 'this:wp_newPost',
    40                         'wp.editPost'                   => 'this:wp_editPost',
    41                         'wp.deletePost'                 => 'this:wp_deletePost',
    42                         'wp.getPost'                    => 'this:wp_getPost',
    43                         'wp.getPosts'                   => 'this:wp_getPosts',
    44                         'wp.newTerm'                    => 'this:wp_newTerm',
    45                         'wp.editTerm'                   => 'this:wp_editTerm',
    46                         'wp.deleteTerm'                 => 'this:wp_deleteTerm',
    47                         'wp.getTerm'                    => 'this:wp_getTerm',
    48                         'wp.getTerms'                   => 'this:wp_getTerms',
    49                         'wp.getTaxonomy'                => 'this:wp_getTaxonomy',
    50                         'wp.getTaxonomies'              => 'this:wp_getTaxonomies',
    51                         'wp.getUser'                    => 'this:wp_getUser',
    52                         'wp.getUsers'                   => 'this:wp_getUsers',
    53                         'wp.getProfile'                 => 'this:wp_getProfile',
    54                         'wp.editProfile'                => 'this:wp_editProfile',
    55                         'wp.getPage'                    => 'this:wp_getPage',
    56                         'wp.getPages'                   => 'this:wp_getPages',
    57                         'wp.newPage'                    => 'this:wp_newPage',
    58                         'wp.deletePage'                 => 'this:wp_deletePage',
    59                         'wp.editPage'                   => 'this:wp_editPage',
    60                         'wp.getPageList'                => 'this:wp_getPageList',
    61                         'wp.getAuthors'                 => 'this:wp_getAuthors',
    62                         'wp.getCategories'              => 'this:mw_getCategories',             // Alias
    63                         'wp.getTags'                    => 'this:wp_getTags',
    64                         'wp.newCategory'                => 'this:wp_newCategory',
    65                         'wp.deleteCategory'             => 'this:wp_deleteCategory',
    66                         'wp.suggestCategories'  => 'this:wp_suggestCategories',
    67                         'wp.uploadFile'                 => 'this:mw_newMediaObject',    // Alias
    68                         'wp.getCommentCount'    => 'this:wp_getCommentCount',
    69                         'wp.getPostStatusList'  => 'this:wp_getPostStatusList',
    70                         'wp.getPageStatusList'  => 'this:wp_getPageStatusList',
    71                         'wp.getPageTemplates'   => 'this:wp_getPageTemplates',
    72                         'wp.getOptions'                 => 'this:wp_getOptions',
    73                         'wp.setOptions'                 => 'this:wp_setOptions',
    74                         'wp.getComment'                 => 'this:wp_getComment',
    75                         'wp.getComments'                => 'this:wp_getComments',
    76                         'wp.deleteComment'              => 'this:wp_deleteComment',
    77                         'wp.editComment'                => 'this:wp_editComment',
    78                         'wp.newComment'                 => 'this:wp_newComment',
    79                         'wp.getCommentStatusList' => 'this:wp_getCommentStatusList',
    80                         'wp.getMediaItem'               => 'this:wp_getMediaItem',
    81                         'wp.getMediaLibrary'    => 'this:wp_getMediaLibrary',
    82                         'wp.getPostFormats'     => 'this:wp_getPostFormats',
    83                         'wp.getPostType'                => 'this:wp_getPostType',
    84                         'wp.getPostTypes'               => 'this:wp_getPostTypes',
    85                         'wp.getRevisions'               => 'this:wp_getRevisions',
    86                         'wp.restoreRevision'    => 'this:wp_restoreRevision',
     38                        'wp.getUsersBlogs'              => array( $this, 'wp_getUsersBlogs' ),
     39                        'wp.newPost'                    => array( $this, 'wp_newPost' ),
     40                        'wp.editPost'                   => array( $this, 'wp_editPost' ),
     41                        'wp.deletePost'                 => array( $this, 'wp_deletePost' ),
     42                        'wp.getPost'                    => array( $this, 'wp_getPost' ),
     43                        'wp.getPosts'                   => array( $this, 'wp_getPosts' ),
     44                        'wp.newTerm'                    => array( $this, 'wp_newTerm' ),
     45                        'wp.editTerm'                   => array( $this, 'wp_editTerm' ),
     46                        'wp.deleteTerm'                 => array( $this, 'wp_deleteTerm' ),
     47                        'wp.getTerm'                    => array( $this, 'wp_getTerm' ),
     48                        'wp.getTerms'                   => array( $this, 'wp_getTerms' ),
     49                        'wp.getTaxonomy'                => array( $this, 'wp_getTaxonomy' ),
     50                        'wp.getTaxonomies'              => array( $this, 'wp_getTaxonomies' ),
     51                        'wp.getUser'                    => array( $this, 'wp_getUser' ),
     52                        'wp.getUsers'                   => array( $this, 'wp_getUsers' ),
     53                        'wp.getProfile'                 => array( $this, 'wp_getProfile' ),
     54                        'wp.editProfile'                => array( $this, 'wp_editProfile' ),
     55                        'wp.getPage'                    => array( $this, 'wp_getPage' ),
     56                        'wp.getPages'                   => array( $this, 'wp_getPages' ),
     57                        'wp.newPage'                    => array( $this, 'wp_newPage' ),
     58                        'wp.deletePage'                 => array( $this, 'wp_deletePage' ),
     59                        'wp.editPage'                   => array( $this, 'wp_editPage' ),
     60                        'wp.getPageList'                => array( $this, 'wp_getPageList' ),
     61                        'wp.getAuthors'                 => array( $this, 'wp_getAuthors' ),
     62                        'wp.getCategories'              => array( $this, 'mw_getCategories' ),          // Alias
     63                        'wp.getTags'                    => array( $this, 'wp_getTags' ),
     64                        'wp.newCategory'                => array( $this, 'wp_newCategory' ),
     65                        'wp.deleteCategory'             => array( $this, 'wp_deleteCategory' ),
     66                        'wp.suggestCategories'  => array( $this, 'wp_suggestCategories' ),
     67                        'wp.uploadFile'                 => array( $this, 'mw_newMediaObject' ), // Alias
     68                        'wp.getCommentCount'    => array( $this, 'wp_getCommentCount' ),
     69                        'wp.getPostStatusList'  => array( $this, 'wp_getPostStatusList' ),
     70                        'wp.getPageStatusList'  => array( $this, 'wp_getPageStatusList' ),
     71                        'wp.getPageTemplates'   => array( $this, 'wp_getPageTemplates' ),
     72                        'wp.getOptions'                 => array( $this, 'wp_getOptions' ),
     73                        'wp.setOptions'                 => array( $this, 'wp_setOptions' ),
     74                        'wp.getComment'                 => array( $this, 'wp_getComment' ),
     75                        'wp.getComments'                => array( $this, 'wp_getComments' ),
     76                        'wp.deleteComment'              => array( $this, 'wp_deleteComment' ),
     77                        'wp.editComment'                => array( $this, 'wp_editComment' ),
     78                        'wp.newComment'                 => array( $this, 'wp_newComment' ),
     79                        'wp.getCommentStatusList' => array( $this, 'wp_getCommentStatusList' ),
     80                        'wp.getMediaItem'               => array( $this, 'wp_getMediaItem' ),
     81                        'wp.getMediaLibrary'    => array( $this, 'wp_getMediaLibrary' ),
     82                        'wp.getPostFormats'     => array( $this, 'wp_getPostFormats' ),
     83                        'wp.getPostType'                => array( $this, 'wp_getPostType' ),
     84                        'wp.getPostTypes'               => array( $this, 'wp_getPostTypes' ),
     85                        'wp.getRevisions'               => array( $this, 'wp_getRevisions' ),
     86                        'wp.restoreRevision'    => array( $this, 'wp_restoreRevision' ),
    8787
    8888                        // Blogger API
    89                         'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs',
    90                         'blogger.getUserInfo' => 'this:blogger_getUserInfo',
    91                         'blogger.getPost' => 'this:blogger_getPost',
    92                         'blogger.getRecentPosts' => 'this:blogger_getRecentPosts',
    93                         'blogger.newPost' => 'this:blogger_newPost',
    94                         'blogger.editPost' => 'this:blogger_editPost',
    95                         'blogger.deletePost' => 'this:blogger_deletePost',
     89                        'blogger.getUsersBlogs' => array( $this, 'blogger_getUsersBlogs' ),
     90                        'blogger.getUserInfo' => array( $this, 'blogger_getUserInfo' ),
     91                        'blogger.getPost' => array( $this, 'blogger_getPost' ),
     92                        'blogger.getRecentPosts' => array( $this, 'blogger_getRecentPosts' ),
     93                        'blogger.newPost' => array( $this, 'blogger_newPost' ),
     94                        'blogger.editPost' => array( $this, 'blogger_editPost' ),
     95                        'blogger.deletePost' => array( $this, 'blogger_deletePost' ),
    9696
    9797                        // MetaWeblog API (with MT extensions to structs)
    98                         'metaWeblog.newPost' => 'this:mw_newPost',
    99                         'metaWeblog.editPost' => 'this:mw_editPost',
    100                         'metaWeblog.getPost' => 'this:mw_getPost',
    101                         'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts',
    102                         'metaWeblog.getCategories' => 'this:mw_getCategories',
    103                         'metaWeblog.newMediaObject' => 'this:mw_newMediaObject',
     98                        'metaWeblog.newPost' => array( $this, 'mw_newPost' ),
     99                        'metaWeblog.editPost' => array( $this, 'mw_editPost' ),
     100                        'metaWeblog.getPost' => array( $this, 'mw_getPost' ),
     101                        'metaWeblog.getRecentPosts' => array( $this, 'mw_getRecentPosts' ),
     102                        'metaWeblog.getCategories' => array( $this, 'mw_getCategories' ),
     103                        'metaWeblog.newMediaObject' => array( $this, 'mw_newMediaObject' ),
    104104
    105105                        // MetaWeblog API aliases for Blogger API
    106106                        // see http://www.xmlrpc.com/stories/storyReader$2460
    107                         'metaWeblog.deletePost' => 'this:blogger_deletePost',
    108                         'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs',
     107                        'metaWeblog.deletePost' => array( $this, 'blogger_deletePost' ),
     108                        'metaWeblog.getUsersBlogs' => array( $this, 'blogger_getUsersBlogs' ),
    109109
    110110                        // MovableType API
    111                         'mt.getCategoryList' => 'this:mt_getCategoryList',
    112                         'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles',
    113                         'mt.getPostCategories' => 'this:mt_getPostCategories',
    114                         'mt.setPostCategories' => 'this:mt_setPostCategories',
    115                         'mt.supportedMethods' => 'this:mt_supportedMethods',
    116                         'mt.supportedTextFilters' => 'this:mt_supportedTextFilters',
    117                         'mt.getTrackbackPings' => 'this:mt_getTrackbackPings',
    118                         'mt.publishPost' => 'this:mt_publishPost',
     111                        'mt.getCategoryList' => array( $this, 'mt_getCategoryList' ),
     112                        'mt.getRecentPostTitles' => array( $this, 'mt_getRecentPostTitles' ),
     113                        'mt.getPostCategories' => array( $this, 'mt_getPostCategories' ),
     114                        'mt.setPostCategories' => array( $this, 'mt_setPostCategories' ),
     115                        'mt.supportedMethods' => array( $this, 'mt_supportedMethods' ),
     116                        'mt.supportedTextFilters' => array( $this, 'mt_supportedTextFilters' ),
     117                        'mt.getTrackbackPings' => array( $this, 'mt_getTrackbackPings' ),
     118                        'mt.publishPost' => array( $this, 'mt_publishPost' ),
    119119
    120120                        // PingBack
    121                         'pingback.ping' => 'this:pingback_ping',
    122                         'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks',
     121                        'pingback.ping' => array( $this, 'pingback_ping' ),
     122                        'pingback.extensions.getPingbacks' => array( $this, 'pingback_extensions_getPingbacks' ),
    123123
    124                         'demo.sayHello' => 'this:sayHello',
    125                         'demo.addTwoNumbers' => 'this:addTwoNumbers'
     124                        'demo.sayHello' => array( $this, 'sayHello' ),
     125                        'demo.addTwoNumbers' => array( $this, 'addTwoNumbers' )
    126126                );
    127127
    128128                $this->initialise_blog_option_info();
     
    130130        }
    131131
    132132        function serve_request() {
    133                 $this->IXR_Server($this->methods);
     133        // use XML-RPC unless the request is JSON
     134        $handler = 'IXR_Server';
     135        if ($_SERVER["CONTENT_TYPE"] && $_SERVER["CONTENT_TYPE"] == "application/json") {
     136            $handler = 'WP_Json_Rpc_Server';
     137        }
     138
     139        // allow plugin to insert different class to process the request
     140        $wp_rpc_request_handler_class = apply_filters( 'wp_rpc_request_handler_class', $handler );
     141
     142        // the handler class should handle the request, output the response, and exit
     143        $wp_rpc_request_handler = new $wp_rpc_request_handler_class($this->methods);
    134144        }
    135145
    136146        /**
  • wp-includes/class-IXR.php

     
    802802    var $minute;
    803803    var $second;
    804804    var $timezone;
     805    var $timestamp;
    805806
    806807    function IXR_Date($time)
    807808    {
     
    811812        } else {
    812813            $this->parseIso($time);
    813814        }
     815        $this->timestamp = $this->getTimestamp();
    814816    }
    815817
    816818    function parseTimestamp($timestamp)
  • wp-includes/class-json-rpc.php

     
     1<?php
     2
     3class WP_Json_Rpc_Server {
     4
     5    var $callbacks = array();
     6    var $id = null;
     7
     8    function __construct( $callbacks = false ) {
     9        if ($callbacks) {
     10            $this->callbacks = $callbacks;
     11        }
     12        $this->serve();
     13    }
     14
     15    function serve() {
     16        if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] !== 'POST' ) {
     17            $this->error( new IXR_Error( 405, 'JSON-RPC server accepts POST requests only.' ) );
     18        }
     19
     20        global $HTTP_RAW_POST_DATA;
     21        if (empty($HTTP_RAW_POST_DATA)) {
     22            // workaround for a bug in PHP 5.2.2 - http://bugs.php.net/bug.php?id=41293
     23            $data = file_get_contents('php://input');
     24        } else {
     25            $data =& $HTTP_RAW_POST_DATA;
     26        }
     27
     28        $request = json_decode( $data, true );
     29
     30        if ( $request == null ) {
     31            $this->error( new IXR_Error( -32700, 'Parse error' ) );
     32        }
     33
     34        if ( ! isset( $request['jsonrpc'] ) ||
     35             $request['jsonrpc'] != '2.0' ||
     36             ! isset( $request['method'] ) ) {
     37            $this->error( new IXR_Error( -32600, 'Invalid Request' ) );
     38        }
     39
     40        $method = $request['method'];
     41        if ( ! array_key_exists( $method, $this->callbacks ) ) {
     42            $this->error( new IXR_Error( -32601, 'Method not found' ) );
     43        }
     44
     45        if ( isset( $request['id'] ) ) {
     46            $this->id = $request['id'];
     47        }
     48
     49        if ( isset( $request['params'] ) ) {
     50            $params = $request['params'];
     51        }
     52        else {
     53            $params = array();
     54        }
     55
     56        $result = call_user_func( $this->callbacks[$method], $params );
     57
     58        $this->output( $result );
     59    }
     60
     61    function error( $error, $message = false ) {
     62        if ( $message && ! is_object( $error ) ) {
     63            $error = new IXR_Error($error, $message);
     64        }
     65
     66        $response = array( 'jsonrpc' => '2.0' );
     67        $response['error'] = array(
     68            'code' => $error->code,
     69            'message' => $error->message
     70        );
     71        $this->output( null, $error );
     72    }
     73
     74    function output( $result = false, $error = false ) {
     75        $response = array(
     76            'jsonrpc' => '2.0',
     77            'id' => $this->id
     78        );
     79
     80        if ( $error ) {
     81            $response['error'] = array(
     82                'code' => $error->code,
     83                'message' => $error->message
     84            );
     85        }
     86        else if ( $result ) {
     87            $response['result'] = $result;
     88        }
     89
     90        header( 'Content-Type: application/json' );
     91        echo json_encode( $response );
     92        exit;
     93    }
     94}