dongzhang1864 2015-09-22 22:25
浏览 275
已采纳

WordPress REST API插件开发 - 添加自定义端点

I'm almost certainly doing something stupid - or rather not doing something obvious that I should have done. I'm writing a plugin to expose a function via http POST so I can send JSON to my wordpress app and store it in the db. I'm using the WP REST API plugin and have followed the "Adding custom endpoints" guide here http://v2.wp-api.org/extending/adding/

My plugin is as follows:-

# Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

require_once(ABSPATH . 'wp-content/plugins/rest-api/plugin.php');
require_once(dirname(__FILE__) . '/classes/myPlugin.php');
require_once(dirname(__FILE__) . '/classes/myController.php');

// Action hook to initialize the plugin
add_action('rest_api_init', array('myPlugin_Class', 'init' ));

register_activation_hook(__FILE__, array('myPlugin_Class', 'on_activation'));
register_deactivation_hook(__FILE__, array('myPlugin_Class', 'on_deactivation'));
register_uninstall_hook(__FILE__, array('myPlugin_Class', 'on_uninstall'));

The myPlugin_Class is just an encapsulation of the main plugin bits... It holds a reference to a static class myController which extends WP_REST_Controller. The plugin class excerpt with its init method and constructor is as follows:-

class MyPlugin_Class
{
    private static $instance;
    private static $myController = null;

    public static function init()
    {
        if(self::$instance == null) {
           self::$instance = new MyPlugin_Class();
        }
        return self::$instance;
    }

    private function __construct()
    {
        Static::$myController = MyController::init();
        Static::$myController->register_routes();
        flush_rewrite_rules();
    }

    public static function on_activation()
    {
        Static::init();

        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
        check_admin_referer( "activate-plugin_{$plugin}" );

        //Register routes and don't forget to flush
        $this->myController->register_routes();
        flush_rewrite_rules();
    }
}

The Controller class excerpt is as follows:-

class MyController extends WP_REST_Controller {

    private static $instance;
    private $namespace = 'api/vendor/v1';
    private $base = 'default';

    private function __construct(){
    }

    public static function init() {
        if(self::$instance == null) {
            self::$instance = new MyController();
        }
        return self::$instance;
    }

    /**
    * Register the routes for the objects of the controller.
    */
    public function register_routes() {
        $base = $this->default-base;
        register_rest_route( $this->namespace, '/' . $base, array(
            array(
                'methods'         => WP_REST_Server::READABLE,
                'callback'        => array( $this, 'get_items' ),
                'permission_callback' => array( $this, 'get_items_permissions_check' ),
                'args'            => array(

                ),
            ),
            array(
                'methods'         => WP_REST_Server::CREATABLE,
                'callback'        => array( $this, 'create_item' ),
                'permission_callback' => array( $this, 'create_item_permissions_check' ),
                'args'            => $this->get_endpoint_args_for_item_schema( true ),
            ),
        ) );
    }
}

I cant get the routes to register. Upon activation, in the call to register_rest_route, I get the error:-

Fatal error: Call to a member function register_route() on null in .../wp-content/plugins/rest-api/plugin.php on line 92

The function register_route() from the REST API Plugin

function register_rest_route( $namespace, $route, $args = array(), $override = false ) {

    /** @var WP_REST_Server $wp_rest_server */
    global $wp_rest_server;

    if ( isset( $args['callback'] ) ) {
        // Upgrade a single set to multiple
        $args = array( $args );
    }

    $defaults = array(
        'methods'         => 'GET',
        'callback'        => null,
        'args'            => array(),
    );
    foreach ( $args as $key => &$arg_group ) {
        if ( ! is_numeric( $arg_group ) ) {
            // Route option, skip here
            continue;
        }

        $arg_group = array_merge( $defaults, $arg_group );
    }

    if ( $namespace ) {
        $full_route = '/' . trim( $namespace, '/' ) . '/' . trim( $route, '/' );
    } else {
        // Non-namespaced routes are not allowed, with the exception of the main
        // and namespace indexes. If you really need to register a
        // non-namespaced route, call `WP_REST_Server::register_route` directly.
        _doing_it_wrong( 'register_rest_route', 'Routes must be namespaced with plugin name and version', 'WPAPI-2.0' );

        $full_route = '/' . trim( $route, '/' );
    }

    $wp_rest_server->register_route( $namespace, $full_route, $args, $override );
}

Where does this global $wp_rest_server get created (or in my case not created)?

i.e. what did I forget to do?

Bonus question:-

Should I call the flush_rewrite_rules() in the rest_api_init hook, the register_activation_hook or both?

  • 写回答

1条回答 默认 最新

  • duannai5879 2015-09-30 09:58
    关注

    Your call to add_action('rest_api_init', array('myPlugin_Class', 'init' )); is very late and before that plugin activation hook

    register_activation_hook(__FILE__, array('myPlugin_Class', 'on_activation'));

    is gettting called. Hence null.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 关于#html5#的问题:H5页面用户手机返回的时候跳转到指定页面例如(语言-javascript)
  • ¥15 无法使用此凭据登录,因为你的域不可用,如何解决?(标签-Windows)
  • ¥15 yolov9的训练时间
  • ¥15 二叉树遍历没有报错但无法正常运行
  • ¥15 在linux系统下vscode运行robocup3d上场球员报错
  • ¥15 Python语言实验
  • ¥15 SAP HANA SQL 增加合计行
  • ¥20 用C#语言解决一个英文打字练习器,有偿
  • ¥15 srs-sip外部服务 webrtc支持H265格式
  • ¥15 在使用abaqus软件中,继承到assembly里的surfaces怎么使用python批量调动