array( 'type' => 'integer', 'required' => true, 'sanitize_callback' => 'absint', ), ); register_rest_route( self::NS, '/events', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'list_events' ), 'permission_callback' => $admin, ) ); register_rest_route( self::NS, '/endpoints', array( array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'list_endpoints' ), 'permission_callback' => $admin, ), array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_endpoint' ), 'permission_callback' => $admin, ), ) ); register_rest_route( self::NS, '/endpoints/(?P\d+)', array( 'args' => $id, array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_endpoint' ), 'permission_callback' => $admin, ), array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_endpoint' ), 'permission_callback' => $admin, ), array( 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_endpoint' ), 'permission_callback' => $admin, ), ) ); register_rest_route( self::NS, '/endpoints/(?P\d+)/test', array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'test_endpoint' ), 'permission_callback' => $admin, 'args' => $id + array( 'event' => array( 'type' => 'string', 'sanitize_callback' => array( 'Hookbird\\Endpoints', 'sanitize_event_key' ), ), ), ) ); register_rest_route( self::NS, '/endpoints/(?P\d+)/rotate-secret', array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'rotate_secret' ), 'permission_callback' => $admin, 'args' => $id, ) ); register_rest_route( self::NS, '/deliveries', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'list_deliveries' ), 'permission_callback' => $admin, 'args' => array( 'endpoint_id' => array( 'type' => 'integer', 'sanitize_callback' => 'absint', ), 'event' => array( 'type' => 'string', 'sanitize_callback' => array( 'Hookbird\\Endpoints', 'sanitize_event_key' ), ), 'status' => array( 'type' => 'string', 'enum' => Deliveries::STATUSES, ), 'page' => array( 'type' => 'integer', 'default' => 1, 'minimum' => 1, ), 'per_page' => array( 'type' => 'integer', 'default' => 25, 'minimum' => 1, 'maximum' => 100, ), ), ) ); register_rest_route( self::NS, '/deliveries/(?P\d+)', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_delivery' ), 'permission_callback' => $admin, 'args' => $id, ) ); register_rest_route( self::NS, '/deliveries/(?P\d+)/retry', array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'retry_delivery' ), 'permission_callback' => $admin, 'args' => $id, ) ); } /** * Permission check. * * @return bool */ public function can_manage() { return current_user_can( 'manage_options' ); } /** * Endpoint fields accepted from requests. * * @param \WP_REST_Request $request Request. * @return array */ private function endpoint_input( \WP_REST_Request $request ) { $params = $request->get_json_params(); if ( ! is_array( $params ) || ! $params ) { $params = $request->get_body_params(); } return array_intersect_key( (array) $params, array_flip( array( 'name', 'url', 'events', 'format', 'headers', 'conditions', 'options', 'active' ) ) ); } /** * GET /events. * * @return \WP_REST_Response */ public function list_events() { $out = array(); foreach ( Registry::events() as $key => $definition ) { $out[] = array( 'key' => $key, 'label' => $definition['label'], 'group' => $definition['group'], 'sample' => Registry::sample( $key ), ); } return rest_ensure_response( $out ); } /** * GET /endpoints. * * @return \WP_REST_Response */ public function list_endpoints() { $stats = Deliveries::stats(); $out = array(); foreach ( Endpoints::all() as $endpoint ) { $item = Endpoints::to_public( $endpoint ); $item['stats'] = isset( $stats[ $endpoint['id'] ] ) ? $stats[ $endpoint['id'] ] : null; $out[] = $item; } return rest_ensure_response( $out ); } /** * POST /endpoints. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function create_endpoint( \WP_REST_Request $request ) { $input = $this->endpoint_input( $request ); if ( ! isset( $input['active'] ) ) { $input['active'] = true; } $id = Endpoints::create( $input ); if ( is_wp_error( $id ) ) { $id->add_data( array( 'status' => 400 ) ); return $id; } $response = rest_ensure_response( Endpoints::to_public( Endpoints::get( $id ), true ) ); $response->set_status( 201 ); return $response; } /** * GET /endpoints/. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function get_endpoint( \WP_REST_Request $request ) { $endpoint = Endpoints::get( (int) $request['id'] ); if ( ! $endpoint ) { return new \WP_Error( 'hookbird_not_found', __( 'Endpoint not found.', 'hookbird' ), array( 'status' => 404 ) ); } return rest_ensure_response( Endpoints::to_public( $endpoint, true ) ); } /** * PUT/PATCH /endpoints/. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function update_endpoint( \WP_REST_Request $request ) { $result = Endpoints::update( (int) $request['id'], $this->endpoint_input( $request ) ); if ( is_wp_error( $result ) ) { $result->add_data( array( 'status' => 'hookbird_not_found' === $result->get_error_code() ? 404 : 400 ) ); return $result; } return rest_ensure_response( Endpoints::to_public( Endpoints::get( (int) $request['id'] ), true ) ); } /** * DELETE /endpoints/. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function delete_endpoint( \WP_REST_Request $request ) { $endpoint = Endpoints::get( (int) $request['id'] ); if ( ! $endpoint ) { return new \WP_Error( 'hookbird_not_found', __( 'Endpoint not found.', 'hookbird' ), array( 'status' => 404 ) ); } Endpoints::delete( $endpoint['id'] ); return rest_ensure_response( array( 'deleted' => true, 'id' => $endpoint['id'], ) ); } /** * POST /endpoints//test. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function test_endpoint( \WP_REST_Request $request ) { $result = Dispatcher::instance()->send_test( (int) $request['id'], (string) $request['event'] ); if ( is_wp_error( $result ) ) { $result->add_data( array( 'status' => 404 ) ); } return rest_ensure_response( $result ); } /** * POST /endpoints//rotate-secret. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function rotate_secret( \WP_REST_Request $request ) { if ( ! Endpoints::get( (int) $request['id'] ) ) { return new \WP_Error( 'hookbird_not_found', __( 'Endpoint not found.', 'hookbird' ), array( 'status' => 404 ) ); } return rest_ensure_response( array( 'secret' => Endpoints::rotate_secret( (int) $request['id'] ) ) ); } /** * GET /deliveries. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response */ public function list_deliveries( \WP_REST_Request $request ) { $result = Deliveries::query( array( 'endpoint_id' => (int) $request['endpoint_id'], 'event' => (string) $request['event'], 'status' => (string) $request['status'], 'page' => (int) $request['page'], 'per_page' => (int) $request['per_page'], ) ); $response = rest_ensure_response( $result['items'] ); $response->header( 'X-WP-Total', (string) $result['total'] ); $response->header( 'X-WP-TotalPages', (string) max( 1, (int) ceil( $result['total'] / max( 1, (int) $request['per_page'] ) ) ) ); return $response; } /** * GET /deliveries/. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function get_delivery( \WP_REST_Request $request ) { $delivery = Deliveries::get( (int) $request['id'] ); if ( ! $delivery ) { return new \WP_Error( 'hookbird_not_found', __( 'Delivery not found.', 'hookbird' ), array( 'status' => 404 ) ); } return rest_ensure_response( $delivery ); } /** * POST /deliveries//retry. * * @param \WP_REST_Request $request Request. * @return \WP_REST_Response|\WP_Error */ public function retry_delivery( \WP_REST_Request $request ) { $result = Dispatcher::instance()->resend( (int) $request['id'] ); if ( is_wp_error( $result ) ) { $result->add_data( array( 'status' => 404 ) ); } return rest_ensure_response( $result ); } }