diff --git a/client-js.php b/client-js.php index 213d200..274ffc2 100644 --- a/client-js.php +++ b/client-js.php @@ -13,31 +13,50 @@ function json_api_client_js() { wp_register_script( 'wp-api', $src, array( 'jquery', 'underscore', 'backbone' ), '1.0', true ); } - /** - * @var \WP_REST_Server $wp_rest_server - */ - global $wp_rest_server; - if ( empty( $wp_rest_server ) ) { - /** This filter is documented in wp-includes/rest-api.php */ - $wp_rest_server_class = apply_filters( 'wp_rest_server_class', 'WP_REST_Server' ); - $wp_rest_server = new $wp_rest_server_class(); - - /** This filter is documented in wp-includes/rest-api.php */ - do_action( 'rest_api_init', $wp_rest_server ); + + $client_has_schema = false; + if ( false !== ( $schema_hash = get_transient( 'api-schema-hash-cache' ) ) ) { + if ( isset( $_COOKIE['api-schema-hash'] ) && $schema_hash == $_COOKIE['api-schema-hash'] ) { + $client_has_schema = true; + } } - $schema_request = new WP_REST_Request( 'GET', '/wp/v2' ); - $schema_response = $wp_rest_server->dispatch( $schema_request ); $schema = null; - if ( ! $schema_response->is_error() ) { - $schema = $schema_response->get_data(); + + if ( ! $client_has_schema ) { + + /** + * @var \WP_REST_Server $wp_rest_server + */ + global $wp_rest_server; + if ( empty( $wp_rest_server ) ) { + /** This filter is documented in wp-includes/rest-api.php */ + $wp_rest_server_class = apply_filters( 'wp_rest_server_class', 'WP_REST_Server' ); + $wp_rest_server = new $wp_rest_server_class(); + + /** This filter is documented in wp-includes/rest-api.php */ + do_action( 'rest_api_init', $wp_rest_server ); + } + + $schema_request = new WP_REST_Request( 'GET', '/wp/v2' ); + $schema_response = $wp_rest_server->dispatch( $schema_request ); + + // Check to see if the request contains a schema hash cookie matching the cached hash. + if ( ! $schema_response->is_error() ) { + $schema = $schema_response->get_data(); + } + $schema_hash = md5( json_encode( $schema ) ); + + // Cache the schema hash for up to an hour. + set_transient( 'api-schema-hash-cache', $schema_hash, 60 * MINUTE_IN_SECONDS ); } $settings = array( - 'root' => esc_url_raw( get_rest_url() ), - 'nonce' => wp_create_nonce( 'wp_rest' ), + 'root' => esc_url_raw( get_rest_url() ), + 'nonce' => wp_create_nonce( 'wp_rest' ), 'versionString' => 'wp/v2/', - 'schema' => $schema, + 'schema' => $schema, + 'schemaHash' => $schema_hash, ); wp_localize_script( 'wp-api', 'wpApiSettings', $settings ); diff --git a/js/load.js b/js/load.js index 298648c..7b75788 100644 --- a/js/load.js +++ b/js/load.js @@ -39,6 +39,13 @@ // Use schema supplied as model attribute. model.schemaModel.set( model.schemaModel.parse( model.get( 'schema' ) ) ); + + // Store a copy of the schema model in the session cache if available. + if ( ! _.isUndefined( sessionStorage ) ) { + sessionStorage.setItem( 'wp-api-schema-model' + model.get( 'apiRoot' ) + model.get( 'versionString' ), JSON.stringify( model.schemaModel ) ); + document.cookie = 'api-schema-hash=' + wpApiSettings.schemaHash; + } + } else if ( ! _.isUndefined( sessionStorage ) && sessionStorage.getItem( 'wp-api-schema-model' + model.get( 'apiRoot' ) + model.get( 'versionString' ) ) ) { // Used a cached copy of the schema model if available. @@ -358,7 +365,7 @@ * @return {Object} user A backbone model representing the author user. */ getAuthorUser: function() { - var user, authorId, embeddeds, attributes, + var user, authorId, embeddeds, attributes; authorId = this.get( 'author' ); embeddeds = this.get( '_embedded' ) || {}; @@ -474,7 +481,7 @@ * @todo required arguments */ _.each( modelInstance.defaults, function( theDefault, index ) { - if ( _.isUndefined( theDefault['default'] ) ) { + if ( null === theDefault || _.isUndefined( theDefault['default'] ) ) { modelInstance.defaults[ index ] = null; } else { modelInstance.defaults[ index ] = theDefault['default'];