diff --git a/src/Api/Actions/ActionInterface.php b/src/Api/Actions/ActionInterface.php index db5b66ea2..537bb2740 100644 --- a/src/Api/Actions/ActionInterface.php +++ b/src/Api/Actions/ActionInterface.php @@ -8,7 +8,7 @@ interface ActionInterface * Handle a request to the API, returning an HTTP response. * * @param \Flarum\Api\Request $request - * @return \Illuminate\Http\Response + * @return \Psr\Http\Message\ResponseInterface */ public function handle(Request $request); } diff --git a/src/Api/Actions/Activity/IndexAction.php b/src/Api/Actions/Activity/IndexAction.php index dc9a42a70..52bf7354e 100644 --- a/src/Api/Actions/Activity/IndexAction.php +++ b/src/Api/Actions/Activity/IndexAction.php @@ -4,7 +4,7 @@ use Flarum\Core\Repositories\UserRepositoryInterface; use Flarum\Core\Repositories\ActivityRepositoryInterface; use Flarum\Api\Actions\SerializeCollectionAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class IndexAction extends SerializeCollectionAction { @@ -61,10 +61,10 @@ class IndexAction extends SerializeCollectionAction * document response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { $actor = $request->actor->getUser(); diff --git a/src/Api/Actions/CreateAction.php b/src/Api/Actions/CreateAction.php index 26b09c939..920e81f8f 100644 --- a/src/Api/Actions/CreateAction.php +++ b/src/Api/Actions/CreateAction.php @@ -1,29 +1,39 @@ withStatus(201); + } + + /** + * Get the newly created resource to be serialized and assigned to the response document. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Model + * @param \Tobscure\JsonApi\Document $document + * @return array */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { - $response->setStatusCode(201); - - return $this->create($request, $response); + return $this->create($request); } /** * Create the resource. * + * @param JsonApiRequest $request * @return \Flarum\Core\Models\Model */ - abstract protected function create(JsonApiRequest $request, JsonApiResponse $response); + abstract protected function create(JsonApiRequest $request); } diff --git a/src/Api/Actions/DeleteAction.php b/src/Api/Actions/DeleteAction.php index 2b9585512..dca4b9cc1 100644 --- a/src/Api/Actions/DeleteAction.php +++ b/src/Api/Actions/DeleteAction.php @@ -1,7 +1,7 @@ delete($request, $response = new Response('', 204)); + $this->delete($request); - return $response; + return new Response('', 204); } /** * Delete the resource. * * @param \Flarum\Api\Request $request - * @param \Flarum\Api\Response $response * @return void */ - abstract protected function delete(Request $request, Response $response); + abstract protected function delete(Request $request); } diff --git a/src/Api/Actions/Discussions/CreateAction.php b/src/Api/Actions/Discussions/CreateAction.php index e409df8cc..36b1815ec 100644 --- a/src/Api/Actions/Discussions/CreateAction.php +++ b/src/Api/Actions/Discussions/CreateAction.php @@ -5,7 +5,6 @@ use Flarum\Core\Commands\ReadDiscussionCommand; use Flarum\Core\Models\Forum; use Flarum\Api\Actions\CreateAction as BaseCreateAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; class CreateAction extends BaseCreateAction @@ -60,11 +59,10 @@ class CreateAction extends BaseCreateAction /** * Create a discussion according to input from the API request. * - * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Discussion + * @param JsonApiRequest $request + * @return \Flarum\Core\Models\Model */ - protected function create(JsonApiRequest $request, JsonApiResponse $response) + protected function create(JsonApiRequest $request) { $user = $request->actor->getUser(); diff --git a/src/Api/Actions/Discussions/DeleteAction.php b/src/Api/Actions/Discussions/DeleteAction.php index 95d6cbb0c..f96a2dc6b 100644 --- a/src/Api/Actions/Discussions/DeleteAction.php +++ b/src/Api/Actions/Discussions/DeleteAction.php @@ -3,7 +3,6 @@ use Flarum\Core\Commands\DeleteDiscussionCommand; use Flarum\Api\Actions\DeleteAction as BaseDeleteAction; use Flarum\Api\Request; -use Illuminate\Http\Response; use Illuminate\Contracts\Bus\Dispatcher; class DeleteAction extends BaseDeleteAction @@ -29,10 +28,9 @@ class DeleteAction extends BaseDeleteAction * Delete a discussion. * * @param \Flarum\Api\Request $request - * @param \Illuminate\Http\Response $response * @return void */ - protected function delete(Request $request, Response $response) + protected function delete(Request $request) { $this->bus->dispatch( new DeleteDiscussionCommand($request->get('id'), $request->actor->getUser()) diff --git a/src/Api/Actions/Discussions/IndexAction.php b/src/Api/Actions/Discussions/IndexAction.php index 65695afd7..29ccadcb4 100644 --- a/src/Api/Actions/Discussions/IndexAction.php +++ b/src/Api/Actions/Discussions/IndexAction.php @@ -4,7 +4,7 @@ use Flarum\Core\Search\Discussions\DiscussionSearchCriteria; use Flarum\Core\Search\Discussions\DiscussionSearcher; use Flarum\Api\Actions\SerializeCollectionAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class IndexAction extends SerializeCollectionAction { @@ -58,10 +58,10 @@ class IndexAction extends SerializeCollectionAction * document response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { $criteria = new DiscussionSearchCriteria( $request->actor->getUser(), @@ -73,10 +73,15 @@ class IndexAction extends SerializeCollectionAction $results = $this->searcher->search($criteria, $request->limit, $request->offset, $load); if (($total = $results->getTotal()) !== null) { - $response->content->addMeta('total', $total); + $document->addMeta('total', $total); } - static::addPaginationLinks($response, $request, route('flarum.api.discussions.index'), $total ?: $results->areMoreResults()); + static::addPaginationLinks( + $document, + $request, + route('flarum.api.discussions.index'), + $total ?: $results->areMoreResults() + ); return $results->getDiscussions(); } diff --git a/src/Api/Actions/Discussions/ShowAction.php b/src/Api/Actions/Discussions/ShowAction.php index dbbbc2302..657884088 100644 --- a/src/Api/Actions/Discussions/ShowAction.php +++ b/src/Api/Actions/Discussions/ShowAction.php @@ -5,7 +5,7 @@ use Flarum\Core\Repositories\PostRepositoryInterface; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\Actions\Posts\GetsPosts; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class ShowAction extends SerializeResourceAction { @@ -84,10 +84,10 @@ class ShowAction extends SerializeResourceAction * JsonApi response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Discussion + * @param \Tobscure\JsonApi\Document $document + * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { $user = $request->actor->getUser(); diff --git a/src/Api/Actions/Discussions/UpdateAction.php b/src/Api/Actions/Discussions/UpdateAction.php index aabd814d4..e47b87ad4 100644 --- a/src/Api/Actions/Discussions/UpdateAction.php +++ b/src/Api/Actions/Discussions/UpdateAction.php @@ -3,10 +3,9 @@ use Flarum\Core\Commands\EditDiscussionCommand; use Flarum\Core\Commands\ReadDiscussionCommand; use Flarum\Api\Actions\SerializeResourceAction; -use Flarum\Api\Actions\Posts\GetsPosts; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; +use Tobscure\JsonApi\Document; class UpdateAction extends SerializeResourceAction { @@ -47,10 +46,10 @@ class UpdateAction extends SerializeResourceAction * it ready to be serialized and assigned to the JsonApi response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Discussion + * @param \Tobscure\JsonApi\Document $document + * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { $user = $request->actor->getUser(); $discussionId = $request->get('id'); diff --git a/src/Api/Actions/Groups/IndexAction.php b/src/Api/Actions/Groups/IndexAction.php index d4989842d..445e9d79f 100644 --- a/src/Api/Actions/Groups/IndexAction.php +++ b/src/Api/Actions/Groups/IndexAction.php @@ -3,7 +3,7 @@ use Flarum\Core\Models\Group; use Flarum\Api\Actions\SerializeCollectionAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class IndexAction extends SerializeCollectionAction { @@ -19,10 +19,10 @@ class IndexAction extends SerializeCollectionAction * response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { return Group::get(); } diff --git a/src/Api/Actions/JsonApiAction.php b/src/Api/Actions/JsonApiAction.php index 4f3ea10a4..d8d4a140b 100644 --- a/src/Api/Actions/JsonApiAction.php +++ b/src/Api/Actions/JsonApiAction.php @@ -1,12 +1,10 @@ $field ]; } - return new JsonResponse(['errors' => $errors], 422); + return $this->json(['errors' => $errors], 422); } catch (PermissionDeniedException $e) { - return new Response(null, 401); + return $this->json(null, 401); } catch (ModelNotFoundException $e) { - return new Response(null, 404); + return $this->json(null, 404); } } + protected function json($data, $status = 200) + { + if ($data === null) $data = new \ArrayObject(); + + $data = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT); + + return new Response($data, $status); + } + /** * Handle an API request and return an API response. * * @param \Flarum\Api\Request $request - * @return \Flarum\Api\Response + * @return \Psr\Http\Message\ResponseInterface */ abstract protected function respond(Request $request); } diff --git a/src/Api/Actions/Notifications/IndexAction.php b/src/Api/Actions/Notifications/IndexAction.php index 4a23c05aa..536cb2b41 100644 --- a/src/Api/Actions/Notifications/IndexAction.php +++ b/src/Api/Actions/Notifications/IndexAction.php @@ -4,7 +4,7 @@ use Flarum\Core\Repositories\NotificationRepositoryInterface; use Flarum\Core\Exceptions\PermissionDeniedException; use Flarum\Api\Actions\SerializeCollectionAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class IndexAction extends SerializeCollectionAction { @@ -60,10 +60,11 @@ class IndexAction extends SerializeCollectionAction * document response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return \Illuminate\Database\Eloquent\Collection + * @throws PermissionDeniedException */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { if (! $request->actor->isAuthenticated()) { throw new PermissionDeniedException; diff --git a/src/Api/Actions/Notifications/UpdateAction.php b/src/Api/Actions/Notifications/UpdateAction.php index 836587309..bd86a70b1 100644 --- a/src/Api/Actions/Notifications/UpdateAction.php +++ b/src/Api/Actions/Notifications/UpdateAction.php @@ -3,8 +3,8 @@ use Flarum\Core\Commands\ReadNotificationCommand; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; +use Tobscure\JsonApi\Document; class UpdateAction extends SerializeResourceAction { @@ -35,10 +35,10 @@ class UpdateAction extends SerializeResourceAction * assigned to the JsonApi response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Notification + * @param \Tobscure\JsonApi\Document $document + * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { return $this->bus->dispatch( new ReadNotificationCommand($request->get('id'), $request->actor->getUser()) diff --git a/src/Api/Actions/Posts/CreateAction.php b/src/Api/Actions/Posts/CreateAction.php index 2ee4c8ce6..78b7094bc 100644 --- a/src/Api/Actions/Posts/CreateAction.php +++ b/src/Api/Actions/Posts/CreateAction.php @@ -4,7 +4,6 @@ use Flarum\Core\Commands\PostReplyCommand; use Flarum\Core\Commands\ReadDiscussionCommand; use Flarum\Api\Actions\CreateAction as BaseCreateAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; class CreateAction extends BaseCreateAction @@ -38,11 +37,10 @@ class CreateAction extends BaseCreateAction /** * Reply to a discussion according to input from the API request. * - * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Post + * @param JsonApiRequest $request + * @return \Flarum\Core\Models\Model */ - protected function create(JsonApiRequest $request, JsonApiResponse $response) + protected function create(JsonApiRequest $request) { $user = $request->actor->getUser(); diff --git a/src/Api/Actions/Posts/DeleteAction.php b/src/Api/Actions/Posts/DeleteAction.php index d703e5ae1..441d7f399 100644 --- a/src/Api/Actions/Posts/DeleteAction.php +++ b/src/Api/Actions/Posts/DeleteAction.php @@ -3,7 +3,6 @@ use Flarum\Core\Commands\DeletePostCommand; use Flarum\Api\Actions\DeleteAction as BaseDeleteAction; use Flarum\Api\Request; -use Illuminate\Http\Response; use Illuminate\Contracts\Bus\Dispatcher; class DeleteAction extends BaseDeleteAction @@ -27,10 +26,9 @@ class DeleteAction extends BaseDeleteAction * Delete a post. * * @param \Flarum\Api\Request $request - * @param \Illuminate\Http\Response $response * @return void */ - protected function delete(Request $request, Response $response) + protected function delete(Request $request) { $this->bus->dispatch( new DeletePostCommand($request->get('id'), $request->actor->getUser()) diff --git a/src/Api/Actions/Posts/IndexAction.php b/src/Api/Actions/Posts/IndexAction.php index 5dbb1842b..c5dcbb27f 100644 --- a/src/Api/Actions/Posts/IndexAction.php +++ b/src/Api/Actions/Posts/IndexAction.php @@ -3,7 +3,7 @@ use Flarum\Core\Repositories\PostRepositoryInterface; use Flarum\Api\Actions\SerializeCollectionAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class IndexAction extends SerializeCollectionAction { @@ -50,10 +50,10 @@ class IndexAction extends SerializeCollectionAction * document response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { $postIds = (array) $request->get('ids'); $user = $request->actor->getUser(); diff --git a/src/Api/Actions/Posts/ShowAction.php b/src/Api/Actions/Posts/ShowAction.php index 77344e1f1..104af500e 100644 --- a/src/Api/Actions/Posts/ShowAction.php +++ b/src/Api/Actions/Posts/ShowAction.php @@ -4,7 +4,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException; use Flarum\Core\Repositories\PostRepositoryInterface; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class ShowAction extends SerializeResourceAction { @@ -49,10 +49,10 @@ class ShowAction extends SerializeResourceAction * response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Discussion + * @param \Tobscure\JsonApi\Document $document + * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { return $this->posts->findOrFail($request->get('id'), $request->actor->getUser()); } diff --git a/src/Api/Actions/Posts/UpdateAction.php b/src/Api/Actions/Posts/UpdateAction.php index 7b88040a4..9df3d5b20 100644 --- a/src/Api/Actions/Posts/UpdateAction.php +++ b/src/Api/Actions/Posts/UpdateAction.php @@ -3,8 +3,8 @@ use Flarum\Core\Commands\EditPostCommand; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; +use Tobscure\JsonApi\Document; class UpdateAction extends SerializeResourceAction { @@ -35,10 +35,10 @@ class UpdateAction extends SerializeResourceAction * ready to be serialized and assigned to the JsonApi response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Post + * @param \Tobscure\JsonApi\Document $document + * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { return $this->bus->dispatch( new EditPostCommand($request->get('id'), $request->actor->getUser(), $request->get('data')) diff --git a/src/Api/Actions/SerializeAction.php b/src/Api/Actions/SerializeAction.php index fe26a45fd..d214e68c0 100644 --- a/src/Api/Actions/SerializeAction.php +++ b/src/Api/Actions/SerializeAction.php @@ -3,9 +3,9 @@ use Flarum\Api\Request; use Flarum\Api\JsonApiRequest; use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; use Tobscure\JsonApi\SerializerInterface; use Tobscure\JsonApi\Criteria; -use Illuminate\Http\Response; abstract class SerializeAction extends JsonApiAction { @@ -63,29 +63,30 @@ abstract class SerializeAction extends JsonApiAction * Handle an API request and return an API response. * * @param \Flarum\Api\Request $request - * @return \Flarum\Api\Response + * @return \Psr\Http\Message\ResponseInterface */ public function respond(Request $request) { $request = static::buildJsonApiRequest($request); - $data = $this->data($request, $response = new JsonApiResponse); + $document = new Document(); + $data = $this->data($request, $document); $serializer = new static::$serializer($request->actor, $request->include, $request->link); - $response->content->setData($this->serialize($serializer, $data)); + $document->setData($this->serialize($serializer, $data)); - return $response; + return new JsonApiResponse($document); } /** * Get the data to be serialized and assigned to the response document. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return array */ - abstract protected function data(JsonApiRequest $request, JsonApiResponse $response); + abstract protected function data(JsonApiRequest $request, Document $document); /** * Serialize the data as appropriate. @@ -157,7 +158,7 @@ abstract class SerializeAction extends JsonApiAction * Add pagination links to a JSON-API response, based on input parameters * and the default parameters of this action. * - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @param \Flarum\Api\JsonApiRequest $request * @param string $url The base URL to build pagination links with. * @param integer|boolean $total The total number of results (used to build @@ -165,28 +166,29 @@ abstract class SerializeAction extends JsonApiAction * is unknown ('last' link is ommitted). * @return void */ - protected static function addPaginationLinks(JsonApiResponse $response, JsonApiRequest $request, $url, $total = true) + protected static function addPaginationLinks(Document $document, JsonApiRequest $request, $url, $total = true) { + $input = []; if ($request->limit != static::$limit) { array_set($input, 'page.limit', $request->limit); } array_set($input, 'page.offset', 0); - $response->content->addLink('first', $url.'?'.http_build_query($input)); + $document->addLink('first', $url.'?'.http_build_query($input)); if ($request->offset > 0) { array_set($input, 'page.offset', max(0, $request->offset - $request->limit)); - $response->content->addLink('prev', $url.'?'.http_build_query($input)); + $document->addLink('prev', $url.'?'.http_build_query($input)); } if ($total === true || $request->offset + $request->limit < $total) { array_set($input, 'page.offset', $request->offset + $request->limit); - $response->content->addLink('next', $url.'?'.http_build_query($input)); + $document->addLink('next', $url.'?'.http_build_query($input)); } if ($total && $total !== true) { array_set($input, 'page.offset', $total - $request->limit); - $response->content->addLink('last', $url.'?'.http_build_query($input)); + $document->addLink('last', $url.'?'.http_build_query($input)); } } } diff --git a/src/Api/Actions/TokenAction.php b/src/Api/Actions/TokenAction.php index 1836b8cb2..183d3d8ec 100644 --- a/src/Api/Actions/TokenAction.php +++ b/src/Api/Actions/TokenAction.php @@ -4,7 +4,6 @@ use Flarum\Api\Request; use Flarum\Core\Commands\GenerateAccessTokenCommand; use Flarum\Core\Repositories\UserRepositoryInterface; use Flarum\Core\Exceptions\PermissionDeniedException; -use Illuminate\Http\JsonResponse; use Illuminate\Contracts\Bus\Dispatcher; class TokenAction extends JsonApiAction @@ -23,7 +22,8 @@ class TokenAction extends JsonApiAction * Log in and return a token. * * @param \Flarum\Api\Request $request - * @return \Flarum\Api\Response + * @return \Psr\Http\Message\ResponseInterface + * @throws PermissionDeniedException */ public function respond(Request $request) { @@ -40,7 +40,7 @@ class TokenAction extends JsonApiAction new GenerateAccessTokenCommand($user->id) ); - return new JsonResponse([ + return $this->json([ 'token' => $token->id, 'userId' => $user->id ]); diff --git a/src/Api/Actions/Users/CreateAction.php b/src/Api/Actions/Users/CreateAction.php index e7a36aa72..8682aabcc 100644 --- a/src/Api/Actions/Users/CreateAction.php +++ b/src/Api/Actions/Users/CreateAction.php @@ -4,7 +4,6 @@ use Flarum\Core\Models\Forum; use Flarum\Core\Commands\RegisterUserCommand; use Flarum\Api\Actions\CreateAction as BaseCreateAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; class CreateAction extends BaseCreateAction @@ -45,11 +44,10 @@ class CreateAction extends BaseCreateAction /** * Register a user according to input from the API request. * - * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\User + * @param JsonApiRequest $request + * @return \Flarum\Core\Models\Model */ - protected function create(JsonApiRequest $request, JsonApiResponse $response) + protected function create(JsonApiRequest $request) { return $this->bus->dispatch( new RegisterUserCommand($request->actor->getUser(), $this->forum, $request->get('data')) diff --git a/src/Api/Actions/Users/DeleteAction.php b/src/Api/Actions/Users/DeleteAction.php index c7a9c5efb..c236fdc9e 100644 --- a/src/Api/Actions/Users/DeleteAction.php +++ b/src/Api/Actions/Users/DeleteAction.php @@ -3,7 +3,6 @@ use Flarum\Core\Commands\DeleteUserCommand; use Flarum\Api\Actions\DeleteAction as BaseDeleteAction; use Flarum\Api\Request; -use Illuminate\Http\Response; use Illuminate\Contracts\Bus\Dispatcher; class DeleteAction extends BaseDeleteAction @@ -29,10 +28,9 @@ class DeleteAction extends BaseDeleteAction * Delete a user. * * @param \Flarum\Api\Request $request - * @param \Illuminate\Http\Response $response * @return void */ - protected function delete(Request $request, Response $response) + protected function delete(Request $request) { $this->bus->dispatch( new DeleteUserCommand($request->get('id'), $request->actor->getUser()) diff --git a/src/Api/Actions/Users/DeleteAvatarAction.php b/src/Api/Actions/Users/DeleteAvatarAction.php index 9e841e3c1..69f48eda4 100644 --- a/src/Api/Actions/Users/DeleteAvatarAction.php +++ b/src/Api/Actions/Users/DeleteAvatarAction.php @@ -3,8 +3,8 @@ use Flarum\Core\Commands\DeleteAvatarCommand; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; +use Tobscure\JsonApi\Document; class DeleteAvatarAction extends SerializeResourceAction { @@ -35,10 +35,10 @@ class DeleteAvatarAction extends SerializeResourceAction * assigned to the JsonApi response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\User + * @param \Tobscure\JsonApi\Document $document + * @return \Flarum\Core\Models\Discussion */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { return $this->bus->dispatch( new DeleteAvatarCommand($request->get('id'), $request->actor->getUser()) diff --git a/src/Api/Actions/Users/IndexAction.php b/src/Api/Actions/Users/IndexAction.php index b3d0975c2..fd8ef8ccd 100644 --- a/src/Api/Actions/Users/IndexAction.php +++ b/src/Api/Actions/Users/IndexAction.php @@ -4,21 +4,21 @@ use Flarum\Core\Search\Users\UserSearchCriteria; use Flarum\Core\Search\Users\UserSearcher; use Flarum\Api\Actions\SerializeCollectionAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class IndexAction extends SerializeCollectionAction { /** * The user searcher. * - * @var \Flarum\Core\Search\Discussions\UserSearcher + * @var \Flarum\Core\Search\Users\UserSearcher */ protected $searcher; /** * Instantiate the action. * - * @param \Flarum\Core\Search\Discussions\UserSearcher $searcher + * @param \Flarum\Core\Search\Users\UserSearcher $searcher */ public function __construct(UserSearcher $searcher) { @@ -54,10 +54,10 @@ class IndexAction extends SerializeCollectionAction * document response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return \Illuminate\Database\Eloquent\Collection */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { $criteria = new UserSearchCriteria( $request->actor->getUser(), @@ -68,10 +68,11 @@ class IndexAction extends SerializeCollectionAction $results = $this->searcher->search($criteria, $request->limit, $request->offset, $request->include); if (($total = $results->getTotal()) !== null) { - $response->content->addMeta('total', $total); + $document->addMeta('total', $total); } - static::addPaginationLinks($response, $request, route('flarum.api.users.index'), $total ?: $results->areMoreResults()); + // TODO: Add route() method! + static::addPaginationLinks($document, $request, 'flarum.api.users.index', $total ?: $results->areMoreResults()); return $results->getUsers(); } diff --git a/src/Api/Actions/Users/ShowAction.php b/src/Api/Actions/Users/ShowAction.php index 4350c5f6d..eef6f7cbf 100644 --- a/src/Api/Actions/Users/ShowAction.php +++ b/src/Api/Actions/Users/ShowAction.php @@ -3,7 +3,7 @@ use Flarum\Core\Repositories\UserRepositoryInterface; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; +use Tobscure\JsonApi\Document; class ShowAction extends SerializeResourceAction { @@ -44,10 +44,10 @@ class ShowAction extends SerializeResourceAction * response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response + * @param \Tobscure\JsonApi\Document $document * @return \Flarum\Core\Models\Discussion */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { $id = $request->get('id'); diff --git a/src/Api/Actions/Users/UpdateAction.php b/src/Api/Actions/Users/UpdateAction.php index de518824c..4e7b0911a 100644 --- a/src/Api/Actions/Users/UpdateAction.php +++ b/src/Api/Actions/Users/UpdateAction.php @@ -3,8 +3,8 @@ use Flarum\Core\Commands\EditUserCommand; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; +use Tobscure\JsonApi\Document; class UpdateAction extends SerializeResourceAction { @@ -35,10 +35,10 @@ class UpdateAction extends SerializeResourceAction * ready to be serialized and assigned to the JsonApi response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\Post + * @param \Tobscure\JsonApi\Document $document + * @return \Flarum\Core\Models\Discussion */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { return $this->bus->dispatch( new EditUserCommand($request->get('id'), $request->actor->getUser(), $request->get('data')) diff --git a/src/Api/Actions/Users/UploadAvatarAction.php b/src/Api/Actions/Users/UploadAvatarAction.php index 6b6dd7834..e17ba8faa 100644 --- a/src/Api/Actions/Users/UploadAvatarAction.php +++ b/src/Api/Actions/Users/UploadAvatarAction.php @@ -3,8 +3,8 @@ use Flarum\Core\Commands\UploadAvatarCommand; use Flarum\Api\Actions\SerializeResourceAction; use Flarum\Api\JsonApiRequest; -use Flarum\Api\JsonApiResponse; use Illuminate\Contracts\Bus\Dispatcher; +use Tobscure\JsonApi\Document; class UploadAvatarAction extends SerializeResourceAction { @@ -35,13 +35,17 @@ class UploadAvatarAction extends SerializeResourceAction * and assigned to the JsonApi response. * * @param \Flarum\Api\JsonApiRequest $request - * @param \Flarum\Api\JsonApiResponse $response - * @return \Flarum\Core\Models\User + * @param \Tobscure\JsonApi\Document $document + * @return \Flarum\Core\Models\Discussion */ - protected function data(JsonApiRequest $request, JsonApiResponse $response) + protected function data(JsonApiRequest $request, Document $document) { return $this->bus->dispatch( - new UploadAvatarCommand($request->get('id'), $request->http->file('avatar'), $request->actor->getUser()) + new UploadAvatarCommand( + $request->get('id'), + $request->http->getUploadedFiles()['avatar'], + $request->actor->getUser() + ) ); } } diff --git a/src/Api/ApiServiceProvider.php b/src/Api/ApiServiceProvider.php index c36217197..0f6fe8fa4 100644 --- a/src/Api/ApiServiceProvider.php +++ b/src/Api/ApiServiceProvider.php @@ -1,7 +1,7 @@ app->singleton('Flarum\Http\Router', function() { return new Router(); }); + include __DIR__.'/routes.php'; } diff --git a/src/Api/JsonApiResponse.php b/src/Api/JsonApiResponse.php index e800e52b6..2f7b74f21 100644 --- a/src/Api/JsonApiResponse.php +++ b/src/Api/JsonApiResponse.php @@ -1,19 +1,14 @@ 'application/vnd.api+json']); - $this->headers->set('Content-Type', 'application/vnd.api+json'); - - $this->content = new Document; - $this->content->setData($data); + $this->getBody()->write($document); } } diff --git a/src/Api/Middleware/LoginWithHeader.php b/src/Api/Middleware/LoginWithHeader.php index 8f2a3f4d9..3f0a83fd8 100644 --- a/src/Api/Middleware/LoginWithHeader.php +++ b/src/Api/Middleware/LoginWithHeader.php @@ -2,12 +2,20 @@ use Flarum\Core\Models\AccessToken; use Flarum\Support\Actor; -use Closure; +use Psr\Http\Message\ResponseInterface as Response; +use Psr\Http\Message\ServerRequestInterface as Request; +use Zend\Stratigility\MiddlewareInterface; -class LoginWithHeader +class LoginWithHeader implements MiddlewareInterface { + /** + * @var Actor + */ protected $actor; + /** + * @var string + */ protected $prefix = 'Token '; // @todo rather than using a singleton, we should have our own HTTP @@ -17,17 +25,21 @@ class LoginWithHeader $this->actor = $actor; } - public function handle($request, Closure $next) + /** + * {@inheritdoc} + */ + public function __invoke(Request $request, Response $response, callable $out = null) { - $header = $request->headers->get('authorization'); + $header = $request->getHeaderLine('authorization'); if (starts_with($header, $this->prefix) && ($token = substr($header, strlen($this->prefix))) && - ($accessToken = AccessToken::where('id', $token)->first())) { + ($accessToken = AccessToken::where('id', $token)->first()) + ) { $this->actor->setUser($user = $accessToken->user); $user->updateLastSeen()->save(); } - return $next($request); + return $out ? $out($request, $response) : $response; } } diff --git a/src/Api/Request.php b/src/Api/Request.php index 8f1b4bdfb..ff2d16590 100644 --- a/src/Api/Request.php +++ b/src/Api/Request.php @@ -1,7 +1,7 @@ input = $input; $this->actor = $actor; diff --git a/src/Api/routes.php b/src/Api/routes.php index f0b192af0..af64c7145 100644 --- a/src/Api/routes.php +++ b/src/Api/routes.php @@ -1,227 +1,140 @@ app->make($class); + $actor = $this->app->make('Flarum\Support\Actor'); - $httpRequest = $this->app['request']->instance(); - $routeParams = $this->app['router']->current()->parameters(); - $actor = $this->app['Flarum\Support\Actor']; - - if (str_contains($httpRequest->header('CONTENT_TYPE'), 'application/vnd.api+json')) { - $input = $httpRequest->json(); + if (str_contains($httpRequest->getHeaderLine('content-type'), 'application/vnd.api+json')) { + $input = json_decode($httpRequest->getBody(), true); } else { - $input = $httpRequest->all(); + $input = $httpRequest->getAttributes(); } $input = array_merge($input, $routeParams); - $request = new Request($input, $actor, $httpRequest); + $request = new ApiRequest($input, $actor, $httpRequest); return $action->handle($request); }; }; -Route::group(['prefix' => 'api', 'middleware' => 'Flarum\Api\Middleware\LoginWithHeader'], function () use ($action) { +/** @var Flarum\Http\Router $router */ +$router = $this->app->make('Flarum\Http\Router'); - // Get forum information - Route::get('forum', [ - 'as' => 'flarum.api.forum.show', - 'uses' => $action('Flarum\Api\Actions\Forum\ShowAction') - ]); +// Get forum information +$router->get('/api/forum', 'flarum.api.forum.show', $action('Flarum\Api\Actions\Forum\ShowAction')); - // Retrieve authentication token - Route::post('token', [ - 'as' => 'flarum.api.token', - 'uses' => $action('Flarum\Api\Actions\TokenAction') - ]); +// Retrieve authentication token +$router->post('/api/token', 'flarum.api.token', $action('Flarum\Api\Actions\TokenAction')); - // Send forgot password email - Route::post('forgot', [ - 'as' => 'flarum.api.forgot', - 'uses' => $action('Flarum\Api\Actions\Users\ForgotAction') - ]); +// Send forgot password email +$router->post('/forgot', 'flarum.api.forgot', $action('Flarum\Api\Actions\ForgotAction')); - /* - |-------------------------------------------------------------------------- - | Users - |-------------------------------------------------------------------------- - */ +/* +|-------------------------------------------------------------------------- +| Users +|-------------------------------------------------------------------------- +*/ - // List users - Route::get('users', [ - 'as' => 'flarum.api.users.index', - 'uses' => $action('Flarum\Api\Actions\Users\IndexAction') - ]); +// List users +$router->get('/api/users', 'flarum.api.users.index', $action('Flarum\Api\Actions\Users\IndexAction')); - // Register a user - Route::post('users', [ - 'as' => 'flarum.api.users.create', - 'uses' => $action('Flarum\Api\Actions\Users\CreateAction') - ]); +// Register a user +$router->post('/api/users', 'flarum.api.users.create', $action('Flarum\Api\Actions\Users\CreateAction')); - // Get a single user - Route::get('users/{id}', [ - 'as' => 'flarum.api.users.show', - 'uses' => $action('Flarum\Api\Actions\Users\ShowAction') - ]); +// Get a single user +$router->get('/api/users/{id}', 'flarum.api.users.show', $action('Flarum\Api\Actions\Users\ShowAction')); - // Edit a user - Route::put('users/{id}', [ - 'as' => 'flarum.api.users.update', - 'uses' => $action('Flarum\Api\Actions\Users\UpdateAction') - ]); +// Edit a user +$router->put('/api/users/{id}', 'flarum.api.users.update', $action('Flarum\Api\Actions\Users\UpdateAction')); - // Delete a user - Route::delete('users/{id}', [ - 'as' => 'flarum.api.users.delete', - 'uses' => $action('Flarum\Api\Actions\Users\DeleteAction') - ]); +// Delete a user +$router->delete('/api/users/{id}', 'flarum.api.users.delete', $action('Flarum\Api\Actions\Users\DeleteAction')); - // Upload avatar - Route::post('users/{id}/avatar', [ - 'as' => 'flarum.api.users.avatar.upload', - 'uses' => $action('Flarum\Api\Actions\Users\UploadAvatarAction') - ]); +// Upload avatar +$router->post('/api/users/{id}/avatar', 'flarum.api.users.avatar.upload', $action('Flarum\Api\Actions\Users\UploadAvatarAction')); - // Remove avatar - Route::delete('users/{id}/avatar', [ - 'as' => 'flarum.api.users.avatar.delete', - 'uses' => $action('Flarum\Api\Actions\Users\DeleteAvatarAction') - ]); +// Remove avatar +$router->delete('/api/users/{id}/avatar', 'flarum.api.users.avatar.delete', $action('Flarum\Api\Actions\Users\DeleteAvatarAction')); - /* - |-------------------------------------------------------------------------- - | Activity - |-------------------------------------------------------------------------- - */ +/* +|-------------------------------------------------------------------------- +| Activity +|-------------------------------------------------------------------------- +*/ - // List activity - Route::get('activity', [ - 'as' => 'flarum.api.activity.index', - 'uses' => $action('Flarum\Api\Actions\Activity\IndexAction') - ]); +// List activity +$router->get('/api/activity', 'flarum.api.activity.index', $action('Flarum\Api\Actions\Activity\IndexAction')); - // List notifications for the current user - Route::get('notifications', [ - 'as' => 'flarum.api.notifications.index', - 'uses' => $action('Flarum\Api\Actions\Notifications\IndexAction') - ]); +// List notifications for the current user +$router->get('/api/notifications', 'flarum.api.notifications.index', $action('Flarum\Api\Actions\Notifications\IndexAction')); - // Mark a single notification as read - Route::put('notifications/{id}', [ - 'as' => 'flarum.api.notifications.update', - 'uses' => $action('Flarum\Api\Actions\Notifications\UpdateAction') - ]); +// Mark a single notification as read +$router->put('/api/notifications/{id}', 'flarum.api.notifications.update', $action('Flarum\Api\Actions\Notifications\UpdateAction')); - /* - |-------------------------------------------------------------------------- - | Discussions - |-------------------------------------------------------------------------- - */ +/* +|-------------------------------------------------------------------------- +| Discussions +|-------------------------------------------------------------------------- +*/ - // List discussions - Route::get('discussions', [ - 'as' => 'flarum.api.discussions.index', - 'uses' => $action('Flarum\Api\Actions\Discussions\IndexAction') - ]); +// List discussions +$router->get('/api/discussions', 'flarum.api.discussions.index', $action('Flarum\Api\Actions\Discussions\IndexAction')); - // Create a discussion - Route::post('discussions', [ - 'as' => 'flarum.api.discussions.create', - 'uses' => $action('Flarum\Api\Actions\Discussions\CreateAction') - ]); +// Create a discussion +$router->post('/api/discussions', 'flarum.api.discussions.create', $action('Flarum\Api\Actions\Discussions\CreateAction')); - // Show a single discussion - Route::get('discussions/{id}', [ - 'as' => 'flarum.api.discussions.show', - 'uses' => $action('Flarum\Api\Actions\Discussions\ShowAction') - ]); +// Show a single discussion +$router->get('/api/discussions/{id}', 'flarum.api.discussions.show', $action('Flarum\Api\Actions\Discussions\ShowAction')); - // Edit a discussion - Route::put('discussions/{id}', [ - 'as' => 'flarum.api.discussions.update', - 'uses' => $action('Flarum\Api\Actions\Discussions\UpdateAction') - ]); +// Edit a discussion +$router->put('/api/discussions/{id}', 'flarum.api.discussions.update', $action('Flarum\Api\Actions\Discussions\UpdateAction')); - // Delete a discussion - Route::delete('discussions/{id}', [ - 'as' => 'flarum.api.discussions.delete', - 'uses' => $action('Flarum\Api\Actions\Discussions\DeleteAction') - ]); +// Delete a discussion +$router->delete('/api/discussions/{id}', 'flarum.api.discussions.delete', $action('Flarum\Api\Actions\Discussions\DeleteAction')); - /* - |-------------------------------------------------------------------------- - | Posts - |-------------------------------------------------------------------------- - */ +/* +|-------------------------------------------------------------------------- +| Posts +|-------------------------------------------------------------------------- +*/ - // List posts, usually for a discussion - Route::get('posts', [ - 'as' => 'flarum.api.posts.index', - 'uses' => $action('Flarum\Api\Actions\Posts\IndexAction') - ]); +// List posts, usually for a discussion +$router->get('/api/posts', 'flarum.api.posts.index', $action('Flarum\Api\Actions\Posts\IndexAction')); - // Create a post - // @todo consider 'discussions/{id}/links/posts'? - Route::post('posts', [ - 'as' => 'flarum.api.posts.create', - 'uses' => $action('Flarum\Api\Actions\Posts\CreateAction') - ]); +// Create a post +// @todo consider 'discussions/{id}/links/posts'? +$router->post('/api/posts', 'flarum.api.posts.create', $action('Flarum\Api\Actions\Posts\CreateAction')); - // Show a single or multiple posts by ID - Route::get('posts/{id}', [ - 'as' => 'flarum.api.posts.show', - 'uses' => $action('Flarum\Api\Actions\Posts\ShowAction') - ]); +// Show a single or multiple posts by ID +$router->get('/api/posts/{id}', 'flarum.api.posts.show', $action('Flarum\Api\Actions\Posts\ShowAction')); - // Edit a post - Route::put('posts/{id}', [ - 'as' => 'flarum.api.posts.update', - 'uses' => $action('Flarum\Api\Actions\Posts\UpdateAction') - ]); +// Edit a post +$router->put('/api/posts/{id}', 'flarum.api.posts.update', $action('Flarum\Api\Actions\Posts\UpdateAction')); - // Delete a post - Route::delete('posts/{id}', [ - 'as' => 'flarum.api.posts.delete', - 'uses' => $action('Flarum\Api\Actions\Posts\DeleteAction') - ]); +// Delete a post +$router->delete('/api/posts/{id}', 'flarum.api.posts.delete', $action('Flarum\Api\Actions\Posts\DeleteAction')); - /* - |-------------------------------------------------------------------------- - | Groups - |-------------------------------------------------------------------------- - */ +/* +|-------------------------------------------------------------------------- +| Groups +|-------------------------------------------------------------------------- +*/ - // List groups - Route::get('groups', [ - 'as' => 'flarum.api.groups.index', - 'uses' => $action('Flarum\Api\Actions\Groups\IndexAction') - ]); +// List groups +$router->get('/api/groups', 'flarum.api.groups.index', $action('Flarum\Api\Actions\Groups\IndexAction')); - // Create a group - Route::post('groups', [ - 'as' => 'flarum.api.groups.create', - 'uses' => $action('Flarum\Api\Actions\Groups\CreateAction') - ]); +// Create a group +$router->post('/api/groups', 'flarum.api.groups.create', $action('Flarum\Api\Actions\Groups\CreateAction')); - // Show a single group - Route::get('groups/{id}', [ - 'as' => 'flarum.api.groups.show', - 'uses' => $action('Flarum\Api\Actions\Groups\ShowAction') - ]); +// Show a single group +$router->get('/api/groups/{id}', 'flarum.api.groups.show', $action('Flarum\Api\Actions\Groups\ShowAction')); - // Edit a group - Route::put('groups/{id}', [ - 'as' => 'flarum.api.groups.update', - 'uses' => $action('Flarum\Api\Actions\Groups\UpdateAction') - ]); +// Edit a group +$router->put('/api/groups/{id}', 'flarum.api.groups.update', $action('Flarum\Api\Actions\Groups\UpdateAction')); - // Delete a group - Route::delete('groups/{id}', [ - 'as' => 'flarum.api.groups.delete', - 'uses' => $action('Flarum\Api\Actions\Groups\DeleteAction') - ]); - -}); +// Delete a group +$router->delete('/api/groups/{id}', 'flarum.api.groups.delete', $action('Flarum\Api\Actions\Groups\DeleteAction'));