1
0
mirror of https://github.com/flarum/core.git synced 2025-10-11 15:04:25 +02:00
Files
php-flarum/src/Api/Controller/ListPostsController.php
Sami Mazouz 3cc18c1da2 Eager load ListPostsController needed relations (#2717)
* Eager load ListPostsController needed relations
* Add comment explaining the reason for eagerloading
2021-03-22 09:54:18 +01:00

136 lines
3.5 KiB
PHP

<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Api\Controller;
use Flarum\Api\Serializer\PostSerializer;
use Flarum\Http\UrlGenerator;
use Flarum\Post\Filter\PostFilterer;
use Flarum\Post\PostRepository;
use Flarum\Query\QueryCriteria;
use Illuminate\Support\Arr;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document;
use Tobscure\JsonApi\Exception\InvalidParameterException;
class ListPostsController extends AbstractListController
{
/**
* {@inheritdoc}
*/
public $serializer = PostSerializer::class;
/**
* {@inheritdoc}
*/
public $include = [
'user',
'user.groups',
'editedUser',
'hiddenUser',
'discussion'
];
/**
* {@inheritdoc}
*/
public $sortFields = ['createdAt'];
/**
* @var PostFilterer
*/
protected $filterer;
/**
* @var PostRepository
*/
protected $posts;
/**
* @var UrlGenerator
*/
protected $url;
/**
* @param PostFilterer $filterer
* @param PostRepository $posts
* @param UrlGenerator $url
*/
public function __construct(PostFilterer $filterer, PostRepository $posts, UrlGenerator $url)
{
$this->filterer = $filterer;
$this->posts = $posts;
$this->url = $url;
}
/**
* {@inheritdoc}
*/
protected function data(ServerRequestInterface $request, Document $document)
{
$actor = $request->getAttribute('actor');
$filters = $this->extractFilter($request);
$sort = $this->extractSort($request);
$limit = $this->extractLimit($request);
$offset = $this->extractOffset($request);
$include = $this->extractInclude($request);
$results = $this->filterer->filter(new QueryCriteria($actor, $filters, $sort), $limit, $offset);
$document->addPaginationLinks(
$this->url->to('api')->route('posts.index'),
$request->getQueryParams(),
$offset,
$limit,
$results->areMoreResults() ? null : 0
);
// Eager load discussion for use in the policies,
// eager loading does not affect the JSON response,
// the response only includes relations included in the request.
if (! in_array('discussion', $include)) {
$include[] = 'discussion';
}
if (in_array('user', $include)) {
$include[] = 'user.groups';
}
return $results->getResults()->load($include);
}
/**
* {@inheritdoc}
*/
protected function extractOffset(ServerRequestInterface $request)
{
$actor = $request->getAttribute('actor');
$queryParams = $request->getQueryParams();
$sort = $this->extractSort($request);
$limit = $this->extractLimit($request);
$filter = $this->extractFilter($request);
if (($near = Arr::get($queryParams, 'page.near')) > 1) {
if (count($filter) > 1 || ! isset($filter['discussion']) || $sort) {
throw new InvalidParameterException(
'You can only use page[near] with filter[discussion] and the default sort order'
);
}
$offset = $this->posts->getIndexForNumber($filter['discussion'], $near, $actor);
return max(0, $offset - $limit / 2);
}
return parent::extractOffset($request);
}
}