\\d+)/qa' => array( 'GET' ), '/discussions/(?P\\d+)/thread' => array( 'GET' ), ); protected function route( string $path, array $endpoints ): void { parent::route( $path, Args::strict( $path, $endpoints ) ); } public function register_routes(): void { $this->route( '/items/(?P\d+)/qa', array( array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'page' ), 'permission_callback' => array( $this, 'logged_in' ), 'args' => array( 'item' => Args::id( __( 'Curriculum item ID.', 'rooster-lms' ) ), 'page' => Args::page(), 'full' => Args::boolean( __( 'The whole tab instead of a page of questions.', 'rooster-lms' ), false ), ), ), ) ); $this->route( '/discussions/(?P\d+)/thread', array( array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'thread' ), 'permission_callback' => array( $this, 'logged_in' ), 'args' => array( 'id' => Args::id( __( 'Question ID.', 'rooster-lms' ) ) ), ), ) ); } public function page( \WP_REST_Request $request ) { return $this->run( $request, static function () use ( $request ) { $id = (int) $request['item']; $item = Services::curriculum_repo()->items( array( $id ) )[ $id ] ?? null; if ( null === $item || ! QaView::may_read( self::user(), $item ) ) { return Errors::not_found(); } $full = (bool) $request['full']; $page = $full ? 1 : max( 1, (int) $request['page'] ); $out = QaView::page( $item, self::user(), $page ); if ( $full ) { $out['html'] = QaView::tab( $item, self::user(), $out ); } return self::no_store( $out + array( 'page' => min( $page, $out['pages'] ) ) ); } ); } public function thread( \WP_REST_Request $request ) { return $this->run( $request, static function () use ( $request ) { $html = QaView::thread( self::user(), (int) $request['id'] ); return '' === $html ? Errors::not_found() : self::no_store( array( 'html' => $html ) ); } ); } }