A talk by @thorstenfrommen
(For the same reasons as almost any other PSR.)
AccessLog
: Generate access logs for each request.
BasicAuthentication
: Implement basic HTTP authentication.
DetectDevice
: Detect the client device.
Firewall
: Provide IP filtering.
Geolocate
: Geolocate the client using the IP.
namespace Psr\Http\Message;
interface MessageInterface { /* ... */ }
interface RequestInterface extends MessageInterface { /* ... */ }
interface ServerRequestInterface extends RequestInterface { /* ... */ }
interface ResponseInterface extends MessageInterface { /* ... */ }
class WP_REST_Request implements \ArrayAccess { /* ... */ }
class WP_HTTP_Response { /* ... */ }
class WP_REST_Response extends \WP_HTTP_Response { /* ... */ }
getHeaders()
Method
/**
* Retrieves all message header values.
*
* ...
*
* @return string[][] Returns an associative array of the message's headers. Each
* key MUST be a header name, and each value MUST be an array of strings
* for that header.
*/
public function getHeaders();
get_headers()
Method
/** @return string[][] */
public function get_headers() {
return [ 'k' => [ 'v1', 'v2' ] ];
}
/** @return string[] */
public function get_headers() {
return [ 'k' => 'v1, v2' ];
}
use Psr\Http\Message\ServerRequestInterface;
class Request extends \WP_REST_Request implements ServerRequestInterface {
// ...
}
use Psr\Http\Message\ResponseInterface;
class Response extends \WP_REST_Response implements ResponseInterface {
// ...
}
use Inpsyde\WPRESTStarter\Core\Request\Request;
$request = Request::from_wp_request( $request );
use Inpsyde\WPRESTStarter\Core\Response\Response;
$response = Response::from_wp_response( $response );
parent
method.
public function getHeaders() {
return $this->message->getHeaders();
}
No need to do anything at all.
You actually call the method on the parent
(i.e., WordPress) class.
public function withCookieParams( array $cookies ) {
$clone = clone $this;
$clone->message = $this->message->withCookieParams( $cookies );
return $clone;
}
public function withQueryParams( array $query ) {
$clone = clone $this;
$clone->message = $this->message->withQueryParams( $query );
$clone->set_wp_query_params_from_http_message();
return $clone;
}
private function set_wp_query_params_from_http_message() {
parent::set_query_params( $this->message->getQueryParams() );
}
public function withHeader( $name, $value ) {
// Similar to withQueryParams()...
}
private function set_wp_headers_from_http_message() {
$headers = $this->message->getHeaders();
$headers = array_map( [ $this, 'header_as_string' ], $headers );
parent::set_headers( $headers );
}
private function header_as_string( array $values ) {
return implode( ', ', $values );
}
public function set_method( $method ) {
parent::set_method( $method );
$this->message = $this->message->withMethod( $this->get_method() );
}
public function set_header( $name, $value ) {
parent::set_header( $name, $value );
$this->set_http_message_with_wp_headers();
}
private function set_http_message_with_wp_headers() {
$message = $this->message;
// No withHeaders() in PSR-7, so create a new HTTP message.
$this->message = new PSR7Request(
$message->getMethod(),
$message->getUri(),
(array) ( $this->get_headers() ?? [] ), // <- WordPress data.
$message->getBody(),
$message->getProtocolVersion(),
(array) ( $message->getServerParams() ?? [] )
);
}
Well, this is no big deal:
\WP_REST_Server
) offers several filters to use:
rest_pre_dispatch
;
rest_request_before_callbacks
;
rest_dispatch_request
;
rest_request_after_callbacks
;
rest_post_dispatch
;
rest_envelope_response
;
rest_pre_serve_request
;
rest_pre_echo_response
.
What you need to do:
add_filter( 'rest_post_dispatch', function (
\WP_HTTP_Response $response,
\WP_REST_Server $server,
\WP_REST_Request $request
) {
// ...
}, 0, 3 );
// ...
$logger = ( new Logger( 'access' ) )->pushHandler( new ErrorLogHandler() );
$middlewares = [
Middleware::ResponseTime(),
Middleware::ClientIp()->remote(),
Middleware::Uuid(),
Middleware::AccessLog( $logger )->combined(),
];
// ...
// ...
$dispatcher = ( new RelayBuilder() )->newInstance( $middlewares );
// ...
// ...
return $dispatcher(
Request::from_wp_request( $request ),
Response::from_wp_response( $response )
);
// ...
add_filter( 'rest_post_dispatch', function (
\WP_HTTP_Response $response,
\WP_REST_Server $server,
\WP_REST_Request $request
) {
$logger = ( new Logger( 'access' ) )->pushHandler( new ErrorLogHandler() );
$middlewares = [
Middleware::ResponseTime(),
Middleware::ClientIp()->remote(),
Middleware::Uuid(),
Middleware::AccessLog( $logger )->combined(),
];
$dispatcher = ( new RelayBuilder() )->newInstance( $middlewares );
return $dispatcher(
Request::from_wp_request( $request ),
Response::from_wp_response( $response )
);
}, 0, 3 );