1
0
mirror of https://github.com/flarum/core.git synced 2025-08-16 13:24:11 +02:00

Add view & frontend documents for tags & tag discussion list (#64)

Refs flarum/core#1820.
Fixes flarum/core#1134.
This commit is contained in:
David Sevilla Martín
2019-09-10 14:34:07 -04:00
committed by Franz Liedke
parent d403bedab3
commit ebf8345dba
5 changed files with 261 additions and 3 deletions

View File

@@ -14,15 +14,17 @@ use Flarum\Discussion\Event\Saving;
use Flarum\Extend;
use Flarum\Tags\Access;
use Flarum\Tags\Api\Controller;
use Flarum\Tags\Content;
use Flarum\Tags\Listener;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\View\Factory;
return [
(new Extend\Frontend('forum'))
->js(__DIR__.'/js/dist/forum.js')
->css(__DIR__.'/less/forum.less')
->route('/t/{slug}', 'tag')
->route('/tags', 'tags'),
->route('/t/{slug}', 'tag', Content\Tag::class)
->route('/tags', 'tags', Content\Tags::class),
(new Extend\Frontend('admin'))
->js(__DIR__.'/js/dist/admin.js')
@@ -35,7 +37,7 @@ return [
->patch('/tags/{id}', 'tags.update', Controller\UpdateTagController::class)
->delete('/tags/{id}', 'tags.delete', Controller\DeleteTagController::class),
function (Dispatcher $events) {
function (Dispatcher $events, Factory $view) {
$events->subscribe(Listener\AddDiscussionTagsRelationship::class);
$events->subscribe(Listener\AddForumTagsRelationship::class);
@@ -51,5 +53,7 @@ return [
$events->subscribe(Access\DiscussionPolicy::class);
$events->subscribe(Access\TagPolicy::class);
$events->subscribe(Access\FlagPolicy::class);
$view->addNamespace('tags', __DIR__.'/views');
},
];

View File

@@ -0,0 +1,108 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Tags\Content;
use Flarum\Api\Client;
use Flarum\Api\Controller\ListDiscussionsController;
use Flarum\Frontend\Document;
use Flarum\Tags\TagRepository;
use Flarum\User\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Arr;
use Psr\Http\Message\ServerRequestInterface as Request;
class Tag
{
/**
* @var Client
*/
protected $api;
/**
* @var Factory
*/
protected $view;
/**
* @var TagRepository
*/
protected $tags;
/**
* @param Client $api
* @param Factory $view
*/
public function __construct(Client $api, Factory $view, TagRepository $tags)
{
$this->api = $api;
$this->view = $view;
$this->tags = $tags;
}
public function __invoke(Document $document, Request $request)
{
$queryParams = $request->getQueryParams();
$actor = $request->getAttribute('actor');
$slug = Arr::pull($queryParams, 'slug');
$sort = Arr::pull($queryParams, 'sort');
$q = Arr::pull($queryParams, 'q', '');
$page = Arr::pull($queryParams, 'page', 1);
$sortMap = $this->getSortMap();
$tagId = $this->tags->getIdForSlug($slug);
$tag = $this->tags->findOrFail($tagId, $actor);
$params = [
'sort' => $sort && isset($sortMap[$sort]) ? $sortMap[$sort] : '',
'filter' => [
'q' => "$q tag:$slug"
],
'page' => ['offset' => ($page - 1) * 20, 'limit' => 20]
];
$apiDocument = $this->getApiDocument($actor, $params);
$document->content = $this->view->make('tags::frontend.content.tag', compact('apiDocument', 'page', 'tag'));
$document->payload['apiDocument'] = $apiDocument;
return $document;
}
/**
* Get a map of sort query param values and their API sort params.
*
* @return array
*/
private function getSortMap()
{
return [
'latest' => '-lastPostedAt',
'top' => '-commentCount',
'newest' => '-createdAt',
'oldest' => 'createdAt'
];
}
/**
* Get the result of an API request to list discussions.
*
* @param User $actor
* @param array $params
* @return object
*/
private function getApiDocument(User $actor, array $params)
{
return json_decode($this->api->send(ListDiscussionsController::class, $actor, $params)->getBody());
}
}

View File

@@ -0,0 +1,87 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Tags\Content;
use Flarum\Api\Client;
use Flarum\Frontend\Document;
use Flarum\Http\UrlGenerator;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\Tags\TagRepository;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Arr;
use Psr\Http\Message\ServerRequestInterface as Request;
class Tags
{
/**
* @var Client
*/
protected $api;
/**
* @var Factory
*/
protected $view;
/**
* @var TagRepository
*/
protected $tags;
/**
* @var SettingsRepositoryInterface
*/
protected $settings;
/**
* @var UrlGenerator
*/
protected $url;
/**
* @param Client $api
* @param Factory $view
* @param TagRepository $tags
* @param SettingsRepositoryInterface $settings
* @param UrlGenerator $url
*/
public function __construct(Client $api, Factory $view, TagRepository $tags, SettingsRepositoryInterface $settings, UrlGenerator $url)
{
$this->api = $api;
$this->view = $view;
$this->tags = $tags;
$this->settings = $settings;
$this->url = $url;
}
public function __invoke(Document $document, Request $request)
{
$tags = collect($document->payload['resources'])->where('type', 'tags');
$childTags = $tags->where('attributes.isChild', true);
$primaryTags = $tags->where('attributes.isChild', false)->where('attributes.position', '!==', null)->sortBy('attributes.position');
$secondaryTags = $tags->where('attributes.isChild', false)->where('attributes.position', '===', null)->sortBy('attributes.name');
$defaultRoute = $this->settings->get('default_route');
$children = $primaryTags->mapWithKeys(function ($tag) use ($childTags) {
$id = Arr::get($tag, 'id');
return [
$id => $childTags->where('relationships.parent.data.id', $id)->pluck('attributes')->sortBy('position')
];
});
$document->content = $this->view->make('tags::frontend.content.tags', compact('primaryTags', 'secondaryTags', 'children'));
$document->canonicalUrl = $defaultRoute === '/tags' ? $this->url->to('forum')->base() : $request->getUri()->withQuery('');
return $document;
}
}

View File

@@ -0,0 +1,26 @@
@inject('url', 'Flarum\Http\UrlGenerator')
<div class="container">
<h2>{{ $tag->name }}</h2>
<p>{{ $tag->description }}</p>
<ul>
@foreach ($apiDocument->data as $discussion)
<li>
<a href="{{ $url->to('forum')->route('discussion', [
'id' => $discussion->id . (trim($discussion->attributes->slug) ? '-' . $discussion->attributes->slug : '')
]) }}">
{{ $discussion->attributes->title }}
</a>
</li>
@endforeach
</ul>
@if (isset($apiDocument->links->prev))
<a href="{{ $url->to('forum')->route('tag', ['slug' => $tag->slug]) }}?page={{ $page - 1 }}">&laquo; {{ $translator->trans('core.views.index.previous_page_button') }}</a>
@endif
@if (isset($apiDocument->links->next))
<a href="{{ $url->to('forum')->route('tag', ['slug' => $tag->slug]) }}?page={{ $page + 1 }}">{{ $translator->trans('core.views.index.next_page_button') }} &raquo;</a>
@endif
</div>

View File

@@ -0,0 +1,33 @@
@inject('url', 'Flarum\Http\UrlGenerator')
<div class="container">
<h2>{{ $translator->trans('flarum-tags.forum.index.tags_link') }}</h2>
@foreach ([$primaryTags, $secondaryTags] as $category)
<ul>
@foreach ($category->pluck('attributes', 'id') as $id => $tag)
<li>
<a href="{{ $url->to('forum')->route('tag', [
'slug' => $tag['slug']
]) }}">
{{ $tag['name'] }}
</a>
@if ($children->has($id))
<ul>
@foreach ($children->get($id) as $child)
<li>
<a href="{{ $url->to('forum')->route('tag', [
'slug' => $child['slug']
]) }}">
{{ $child['name'] }}
</a>
</li>
@endforeach
</ul>
@endif
</li>
@endforeach
</ul>
@endforeach
</div>