Browse Source

Added API to query users by location (only for users who have defined their location)

main
Youen 1 year ago
parent
commit
a106bddc0e
  1. 23
      extend.php
  2. 100
      src/Api/Controller/ListUserLocationsController.php
  3. 39
      src/Api/Serializer/UserLocationSerializer.php

23
extend.php

@ -18,7 +18,20 @@ use Flarum\Api\Serializer\UserSerializer;
use Flarum\Extend; use Flarum\Extend;
use Flarum\User\Event\Saving; use Flarum\User\Event\Saving;
use Flarum\Api\Event\Serializing; use Flarum\Api\Event\Serializing;
use Flarum\User\Filter\UserFilterer;
use Flarum\Filter\FilterState;
use Flarum\Query\QueryCriteria;
class UserLocationFilterMutator
{
public function __invoke(FilterState $filterState, QueryCriteria $queryCriteria)
{
if($queryCriteria->mustHaveLocation)
{
$filterState->getQuery()->where('location_latitude', '!=', 'null');
}
}
}
return [ return [
(new Extend\Frontend('forum')) (new Extend\Frontend('forum'))
@ -37,5 +50,11 @@ return [
(new Extend\Settings)->serializeToForum('justoverclock-users-map-location.mapBox-api-key', 'justoverclock-users-map-location.mapBox-api-key'), (new Extend\Settings)->serializeToForum('justoverclock-users-map-location.mapBox-api-key', 'justoverclock-users-map-location.mapBox-api-key'),
(new Extend\Frontend('forum')) (new Extend\Frontend('forum'))
->route('/global-map', 'justoverclock.global-map') ->route('/global-map', 'justoverclock.global-map'),
(new Extend\Filter(UserFilterer::class))
->addFilterMutator(UserLocationFilterMutator::class),
(new Extend\Routes('api'))
->get('/user-locations', 'user-locations.index', Api\Controller\ListUserLocationsController::class)
]; ];

100
src/Api/Controller/ListUserLocationsController.php

@ -0,0 +1,100 @@
<?php
namespace Justoverclock\UsersMapLocation\Api\Controller;
use Flarum\Api\Controller\AbstractListController;
use Flarum\Http\RequestUtil;
use Flarum\Http\UrlGenerator;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document;
use Justoverclock\UsersMapLocation\Api\Serializer\UserLocationSerializer;
use Flarum\User\User;
use Flarum\Query\QueryCriteria;
use Flarum\User\Filter\UserFilterer;
use Flarum\User\Search\UserSearcher;
use Illuminate\Database\Eloquent\Builder;
class ListUserLocationsController extends AbstractListController
{
/**
* {@inheritdoc}
*/
public $serializer = UserLocationSerializer::class;
/**
* @var UserFilterer
*/
protected $filterer;
/**
* @var UserSearcher
*/
protected $searcher;
/**
* @var UrlGenerator
*/
protected $url;
/**
* @param UserLocationFilterer $filterer
* @param UserSearcher $searcher
* @param UrlGenerator $url
*/
public function __construct(UserFilterer $filterer, UserSearcher $searcher, UrlGenerator $url)
{
$this->filterer = $filterer;
$this->searcher = $searcher;
$this->url = $url;
}
/**
* {@inheritdoc}
*/
protected function data(ServerRequestInterface $request, Document $document)
{
// See https://docs.flarum.org/extend/api.html#api-endpoints for more information.
$actor = RequestUtil::getActor($request);
$actor->assertCan('searchUsers');
if (! $actor->hasPermission('user.viewLastSeenAt')) {
// If a user cannot see everyone's last online date, we prevent them from sorting by it
// Otherwise this sort field would defeat the privacy setting discloseOnline
// We use remove instead of add so that extensions can still completely disable the sort using the extender
$this->removeSortField('lastSeenAt');
}
$filters = $this->extractFilter($request);
$sort = $this->extractSort($request);
$sortIsDefault = $this->sortIsDefault($request);
$limit = $this->extractLimit($request);
$offset = $this->extractOffset($request);
$include = $this->extractInclude($request);
$criteria = new QueryCriteria($actor, $filters, $sort, $sortIsDefault);
$criteria->mustHaveLocation = true;
if (array_key_exists('q', $filters)) {
$results = $this->searcher->search($criteria, $limit, $offset);
} else {
$results = $this->filterer->filter($criteria, $limit, $offset);
}
$document->addPaginationLinks(
$this->url->to('api')->route('user-locations.index'),
$request->getQueryParams(),
$offset,
$limit,
$results->areMoreResults() ? null : 0
);
$results = $results->getResults();
$this->loadRelations($results, $include, $request);
return $results;
}
}

39
src/Api/Serializer/UserLocationSerializer.php

@ -0,0 +1,39 @@
<?php
namespace Justoverclock\UsersMapLocation\Api\Serializer;
use Flarum\Api\Serializer\AbstractSerializer;
use Flarum\User\User;
use InvalidArgumentException;
class UserLocationSerializer extends AbstractSerializer
{
/**
* {@inheritdoc}
*/
protected $type = 'users';
/**
* {@inheritdoc}
*
* @param User $model
* @throws InvalidArgumentException
*/
protected function getDefaultAttributes($model)
{
if (! ($model instanceof User)) {
throw new InvalidArgumentException(
get_class($this).' can only serialize instances of '.User::class
);
}
// See https://docs.flarum.org/extend/api.html#serializers for more information.
return [
'username' => $model->username,
'displayName' => $model->display_name,
'location_longitude' => $model->location_longitude,
'location_latitude' => $model->location_latitude,
];
}
}
Loading…
Cancel
Save