authorise( 'read', $request ); } /** * @param WP_REST_Request $request The request. */ public function can_edit( WP_REST_Request $request ): bool|WP_Error { return $this->authorise( 'edit', $request ); } /** * @param string $action read|edit. * @param WP_REST_Request $request The request. */ private function authorise( string $action, WP_REST_Request $request ): bool|WP_Error { $entity_type = (string) $request['entity_type']; if ( ! $this->entities->has( $entity_type ) || ! $this->stream->streams( $entity_type ) ) { return $this->fail( 'plugixa_crm_no_stream', __( 'That record type has no stream.', 'plugixa-crm' ), 404 ); } $record = $this->records->load( $entity_type, (int) $request['entity_id'] ); if ( null === $record ) { return $this->fail( 'plugixa_crm_not_found', __( 'That record does not exist.', 'plugixa-crm' ), 404 ); } return Capabilities::user_can( $action, $entity_type, $record ) ? true : $this->forbidden(); } public function register_routes(): void { register_rest_route( $this->namespace, '/stream/(?P[a-z_]+)/(?P\d+)', array( array( 'methods' => 'GET', 'callback' => array( $this, 'index' ), 'permission_callback' => array( $this, 'can_read' ), ), array( 'methods' => 'POST', 'callback' => array( $this, 'store' ), 'permission_callback' => array( $this, 'can_edit' ), ), ) ); // Own scope: following subscribes only the signed-in user to a record's stream and changes nothing // on the record, so it needs read on that record. register_rest_route( $this->namespace, '/stream/(?P[a-z_]+)/(?P\d+)/follow', array( array( 'methods' => 'POST', 'callback' => array( $this, 'follow' ), 'permission_callback' => array( $this, 'can_read' ), ), array( 'methods' => 'DELETE', 'callback' => array( $this, 'unfollow' ), 'permission_callback' => array( $this, 'can_read' ), ), ) ); } /** * @param WP_REST_Request $request The request. */ public function index( WP_REST_Request $request ): WP_REST_Response { $entity_type = (string) $request['entity_type']; $entity_id = (int) $request['entity_id']; return $this->ok( array( 'entries' => $this->stream->for_record( $entity_type, $entity_id ), 'followers' => $this->stream->followers( $entity_type, $entity_id ), 'following' => $this->stream->is_following( $entity_type, $entity_id, get_current_user_id() ), ) ); } /** * @param WP_REST_Request $request The request. */ public function store( WP_REST_Request $request ): WP_REST_Response|WP_Error { $body = (array) $request->get_json_params(); $entry = $this->stream->post( (string) $request['entity_type'], (int) $request['entity_id'], (string) ( $body['body'] ?? '' ) ); if ( $entry instanceof WP_Error ) { return $entry; } return $this->index( $request ); } /** * @param WP_REST_Request $request The request. */ public function follow( WP_REST_Request $request ): WP_REST_Response { $this->stream->follow( (string) $request['entity_type'], (int) $request['entity_id'], get_current_user_id() ); return $this->index( $request ); } /** * @param WP_REST_Request $request The request. */ public function unfollow( WP_REST_Request $request ): WP_REST_Response { $this->stream->unfollow( (string) $request['entity_type'], (int) $request['entity_id'], get_current_user_id() ); return $this->index( $request ); } }