Moved post listing to API

This commit is contained in:
Marcin Kurczewski 2014-05-02 13:49:31 +02:00
parent c0a7fe5209
commit ffeefd06c6
13 changed files with 110 additions and 66 deletions

View file

@ -45,6 +45,28 @@ $context->simpleActionName = null;
$context->simpleActionName); $context->simpleActionName);
}); });
$postValidation =
[
'tag' => '[^\/]*',
'enable' => '0|1',
'source' => 'posts|mass-tag',
'query' => '[^\/]*',
'additionalInfo' => '[^\/]*',
'score' => '-1|0|1',
];
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}', $postValidation);
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{query}', $postValidation);
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{query}/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{additionalInfo}/{query}/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'randomView'], 'GET', '/random', $postValidation);
\Chibi\Router::register(['PostController', 'randomView'], 'GET', '/random/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'favoritesView'], 'GET', '/favorites', $postValidation);
\Chibi\Router::register(['PostController', 'favoritesView'], 'GET', '/favorites/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'upvotedView'], 'GET', '/upvoted', $postValidation);
\Chibi\Router::register(['PostController', 'upvotedView'], 'GET', '/upvoted/{page}', $postValidation);
\Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments'); \Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments');
\Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments/{page}', ['page' => '\d+']); \Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments/{page}', ['page' => '\d+']);
\Chibi\Router::register(['CommentController', 'addAction'], 'POST', '/comment/add'); \Chibi\Router::register(['CommentController', 'addAction'], 'POST', '/comment/add');
@ -67,28 +89,8 @@ foreach (['GET', 'POST'] as $method)
\Chibi\Router::register(['AuthController', 'loginAction'], 'POST', '/auth/login'); \Chibi\Router::register(['AuthController', 'loginAction'], 'POST', '/auth/login');
\Chibi\Router::register(['AuthController', 'logoutAction'], 'POST', '/auth/logout'); \Chibi\Router::register(['AuthController', 'logoutAction'], 'POST', '/auth/logout');
$postValidation =
[
'tag' => '[^\/]*',
'enable' => '0|1',
'source' => 'posts|mass-tag',
'query' => '[^\/]*',
'additionalInfo' => '[^\/]*',
'score' => '-1|0|1',
];
\Chibi\Router::register(['PostController', 'uploadAction'], $method, '/posts/upload', $postValidation); \Chibi\Router::register(['PostController', 'uploadAction'], $method, '/posts/upload', $postValidation);
\Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}', $postValidation);
\Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}/{query}', $postValidation);
\Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}/{query}/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'listAction'], $method, '/{source}/{additionalInfo}/{query}/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'toggleTagAction'], $method, '/post/{id}/toggle-tag/{tag}/{enable}', $postValidation); \Chibi\Router::register(['PostController', 'toggleTagAction'], $method, '/post/{id}/toggle-tag/{tag}/{enable}', $postValidation);
\Chibi\Router::register(['PostController', 'favoritesAction'], $method, '/favorites', $postValidation);
\Chibi\Router::register(['PostController', 'favoritesAction'], $method, '/favorites/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'upvotedAction'], $method, '/upvoted', $postValidation);
\Chibi\Router::register(['PostController', 'upvotedAction'], $method, '/upvoted/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'randomAction'], $method, '/random', $postValidation);
\Chibi\Router::register(['PostController', 'randomAction'], $method, '/random/{page}', $postValidation);
\Chibi\Router::register(['PostController', 'viewAction'], $method, '/post/{id}', $postValidation); \Chibi\Router::register(['PostController', 'viewAction'], $method, '/post/{id}', $postValidation);
\Chibi\Router::register(['PostController', 'retrieveAction'], $method, '/post/{name}/retrieve', $postValidation); \Chibi\Router::register(['PostController', 'retrieveAction'], $method, '/post/{name}/retrieve', $postValidation);
\Chibi\Router::register(['PostController', 'thumbAction'], $method, '/post/{name}/thumb', $postValidation); \Chibi\Router::register(['PostController', 'thumbAction'], $method, '/post/{name}/thumb', $postValidation);

View file

@ -1,7 +1,7 @@
<?php <?php
class PostController class PostController
{ {
public function listAction($query = null, $page = 1, $source = 'posts', $additionalInfo = null) public function listView($query = null, $page = 1, $source = 'posts', $additionalInfo = null)
{ {
$context = getContext(); $context = getContext();
$context->viewName = 'post-list-wrapper'; $context->viewName = 'post-list-wrapper';
@ -18,7 +18,7 @@ class PostController
if (strpos($formQuery, '/') !== false) if (strpos($formQuery, '/') !== false)
throw new SimpleException('Search query contains invalid characters'); throw new SimpleException('Search query contains invalid characters');
$url = \Chibi\Router::linkTo(['PostController', 'listAction'], [ $url = \Chibi\Router::linkTo(['PostController', 'listView'], [
'source' => $source, 'source' => $source,
'additionalInfo' => $additionalInfo, 'additionalInfo' => $additionalInfo,
'query' => $formQuery]); 'query' => $formQuery]);
@ -27,11 +27,8 @@ class PostController
} }
$query = trim($query); $query = trim($query);
$page = max(1, intval($page));
$postsPerPage = intval(getConfig()->browsing->postsPerPage);
$context->transport->searchQuery = $query; $context->transport->searchQuery = $query;
$context->transport->lastSearchQuery = $query; $context->transport->lastSearchQuery = $query;
Access::assert(Privilege::ListPosts);
if ($source == 'mass-tag') if ($source == 'mass-tag')
{ {
Access::assert(Privilege::MassTag); Access::assert(Privilege::MassTag);
@ -42,18 +39,34 @@ class PostController
$query = trim($query . ' submit:' . Auth::getCurrentUser()->name); $query = trim($query . ' submit:' . Auth::getCurrentUser()->name);
} }
$posts = PostSearchService::getEntities($query, $postsPerPage, $page); $ret = Api::run(
$postCount = PostSearchService::getEntityCount($query); new ListPostsJob(),
$pageCount = ceil($postCount / $postsPerPage); [
$page = min($pageCount, $page); JobArgs::PAGE_NUMBER => $page,
PostModel::preloadTags($posts); JobArgs::QUERY => $query
]);
$context->transport->posts = $ret->posts;
$context->transport->paginator = new StdClass; $context->transport->paginator = new StdClass;
$context->transport->paginator->page = $page; $context->transport->paginator->page = $ret->page;
$context->transport->paginator->pageCount = $pageCount; $context->transport->paginator->pageCount = $ret->pageCount;
$context->transport->paginator->entityCount = $postCount; $context->transport->paginator->entityCount = $ret->postCount;
$context->transport->paginator->entities = $posts; $context->transport->paginator->entities = $ret->posts;
$context->transport->posts = $posts; }
public function favoritesView($page = 1)
{
$this->listView('favmin:1', $page);
}
public function upvotedView($page = 1)
{
$this->listView('scoremin:1', $page);
}
public function randomView($page = 1)
{
$this->listView('order:random', $page);
} }
public function toggleTagAction($id, $tag, $enable) public function toggleTagAction($id, $tag, $enable)
@ -103,21 +116,6 @@ class PostController
PostModel::save($post); PostModel::save($post);
} }
public function favoritesAction($page = 1)
{
$this->listAction('favmin:1', $page);
}
public function upvotedAction($page = 1)
{
$this->listAction('scoremin:1', $page);
}
public function randomAction($page = 1)
{
$this->listAction('order:random', $page);
}
public function uploadAction() public function uploadAction()
{ {
$context = getContext(); $context = getContext();

View file

@ -154,6 +154,6 @@ class TagController
]; ];
if ($suppliedOldPage != 0 and $suppliedOldQuery == $suppliedQuery) if ($suppliedOldPage != 0 and $suppliedOldQuery == $suppliedQuery)
$params['page'] = $suppliedOldPage; $params['page'] = $suppliedOldPage;
\Chibi\Util\Url::forward(\Chibi\Router::linkTo(['PostController', 'listAction'], $params)); \Chibi\Util\Url::forward(\Chibi\Router::linkTo(['PostController', 'listView'], $params));
} }
} }

View file

@ -136,7 +136,7 @@ class CustomMarkdown extends \Michelf\MarkdownExtra
protected function doTags($text) protected function doTags($text)
{ {
$link = \Chibi\Router::linkTo(['PostController', 'listAction'], ['query' => '_query_']); $link = \Chibi\Router::linkTo(['PostController', 'listView'], ['query' => '_query_']);
return preg_replace_callback('/(?:(?<![^\s\(\)\[\]]))#([()\[\]a-zA-Z0-9_.-]+)/', function($x) use ($link) return preg_replace_callback('/(?:(?<![^\s\(\)\[\]]))#([()\[\]a-zA-Z0-9_.-]+)/', function($x) use ($link)
{ {
return $this->hashPart('<a href="' . str_replace('_query_', $x[1], $link) . '">' . $x[0] . '</a>'); return $this->hashPart('<a href="' . str_replace('_query_', $x[1], $link) . '">' . $x[0] . '</a>');
@ -154,7 +154,7 @@ class CustomMarkdown extends \Michelf\MarkdownExtra
protected function doSearchPermalinks($text) protected function doSearchPermalinks($text)
{ {
$link = \Chibi\Router::linkTo(['PostController', 'listAction'], ['query' => '_query_']); $link = \Chibi\Router::linkTo(['PostController', 'listView'], ['query' => '_query_']);
return preg_replace_callback('{\[search\]((?:[^\[]|\[(?!\/?search\]))+)\[\/search\]}is', function($x) use ($link) return preg_replace_callback('{\[search\]((?:[^\[]|\[(?!\/?search\]))+)\[\/search\]}is', function($x) use ($link)
{ {
return $this->hashPart('<a href="' . str_replace('_query_', urlencode($x[1]), $link) . '">' . $x[1] . '</a>'); return $this->hashPart('<a href="' . str_replace('_query_', urlencode($x[1]), $link) . '">' . $x[1] . '</a>');

View file

@ -5,4 +5,5 @@ class JobArgs
const POST_ID = 'post-id'; const POST_ID = 'post-id';
const TEXT = 'text'; const TEXT = 'text';
const PAGE_NUMBER = 'page-number'; const PAGE_NUMBER = 'page-number';
const QUERY = 'query';
} }

View file

@ -12,6 +12,8 @@ class ListCommentsJob extends AbstractJob
$posts = PostSearchService::getEntities($searchQuery, $commentsPerPage, $page); $posts = PostSearchService::getEntities($searchQuery, $commentsPerPage, $page);
$postCount = PostSearchService::getEntityCount($searchQuery); $postCount = PostSearchService::getEntityCount($searchQuery);
$pageCount = ceil($postCount / $commentsPerPage); $pageCount = ceil($postCount / $commentsPerPage);
$page = min($pageCount, $page);
PostModel::preloadTags($posts); PostModel::preloadTags($posts);
PostModel::preloadComments($posts); PostModel::preloadComments($posts);
$comments = []; $comments = [];

41
src/Jobs/ListPostsJob.php Normal file
View file

@ -0,0 +1,41 @@
<?php
class ListPostsJob extends AbstractJob
{
public function execute()
{
$page = $this->getArgument(JobArgs::PAGE_NUMBER);
$query = $this->getArgument(JobArgs::QUERY);
$page = max(1, intval($page));
$postsPerPage = intval(getConfig()->browsing->postsPerPage);
$posts = PostSearchService::getEntities($query, $postsPerPage, $page);
$postCount = PostSearchService::getEntityCount($query);
$pageCount = ceil($postCount / $postsPerPage);
$page = min($pageCount, $page);
PostModel::preloadTags($posts);
$ret = new StdClass;
$ret->posts = $posts;
$ret->postCount = $postCount;
$ret->page = $page;
$ret->pageCount = $pageCount;
return $ret;
}
public function requiresPrivilege()
{
return Privilege::ListPosts;
}
public function requiresAuthentication()
{
return false;
}
public function requiresConfirmedEmail()
{
return false;
}
}

View file

@ -29,7 +29,7 @@ Assets::addStylesheet('index-index.css');
<?php uasort($tags, function($a, $b) { return strnatcasecmp($a->name, $b->name); }) ?> <?php uasort($tags, function($a, $b) { return strnatcasecmp($a->name, $b->name); }) ?>
<?php foreach ($tags as $tag): ?> <?php foreach ($tags as $tag): ?>
<li> <li>
<a href="<?= \Chibi\Router::linkTo(['PostController', 'listAction'], ['query' => $tag->name]) ?>"> <a href="<?= \Chibi\Router::linkTo(['PostController', 'listView'], ['query' => $tag->name]) ?>">
<?= $tag->name ?> <?= $tag->name ?>
</a> </a>
</li> </li>

View file

@ -4,32 +4,32 @@ Assets::setSubTitle('posts');
$tabs = []; $tabs = [];
$activeTab = 0; $activeTab = 0;
if (Access::check(Privilege::ListPosts)) if (Access::check(Privilege::ListPosts))
$tabs []= ['All posts', \Chibi\Router::linkTo(['PostController', 'listAction'])]; $tabs []= ['All posts', \Chibi\Router::linkTo(['PostController', 'listView'])];
if (Access::check(Privilege::ListPosts)) if (Access::check(Privilege::ListPosts))
{ {
$tabs []= ['Random', \Chibi\Router::linkTo(['PostController', 'randomAction'])]; $tabs []= ['Random', \Chibi\Router::linkTo(['PostController', 'randomView'])];
if ($this->context->simpleActionName == 'random') if ($this->context->simpleActionName == 'random')
$activeTab = count($tabs) - 1; $activeTab = count($tabs) - 1;
} }
if (Access::check(Privilege::ListPosts)) if (Access::check(Privilege::ListPosts))
{ {
$tabs []= ['Favorites', \Chibi\Router::linkTo(['PostController', 'favoritesAction'])]; $tabs []= ['Favorites', \Chibi\Router::linkTo(['PostController', 'favoritesView'])];
if ($this->context->simpleActionName == 'favorites') if ($this->context->simpleActionName == 'favorites')
$activeTab = count($tabs) - 1; $activeTab = count($tabs) - 1;
} }
if (Access::check(Privilege::ListPosts)) if (Access::check(Privilege::ListPosts))
{ {
$tabs []= ['Upvoted', \Chibi\Router::linkTo(['PostController', 'upvotedAction'])]; $tabs []= ['Upvoted', \Chibi\Router::linkTo(['PostController', 'upvotedView'])];
if ($this->context->simpleActionName == 'upvoted') if ($this->context->simpleActionName == 'upvoted')
$activeTab = count($tabs) - 1; $activeTab = count($tabs) - 1;
} }
if (Access::check(Privilege::MassTag)) if (Access::check(Privilege::MassTag))
{ {
$tabs []= ['Mass tag', \Chibi\Router::linkTo(['PostController', 'listAction'], [ $tabs []= ['Mass tag', \Chibi\Router::linkTo(['PostController', 'listView'], [
'source' => 'mass-tag', 'source' => 'mass-tag',
'query' => isset($this->context->transport->searchQuery) 'query' => isset($this->context->transport->searchQuery)
? htmlspecialchars($this->context->transport->searchQuery) ? htmlspecialchars($this->context->transport->searchQuery)

View file

@ -37,7 +37,7 @@ Assets::addScript('../lib/tagit/jquery.tagit.js');
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div id="upload-step2" data-redirect-url="<?= \Chibi\Router::linkTo(['PostController', 'listAction']) ?>"> <div id="upload-step2" data-redirect-url="<?= \Chibi\Router::linkTo(['PostController', 'listView']) ?>">
<hr> <hr>
<div class="posts"> <div class="posts">

View file

@ -60,7 +60,7 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
<div class="text"> <div class="text">
Current&nbsp;search:<br/> Current&nbsp;search:<br/>
<a href="<?= \Chibi\Router::linkTo( <a href="<?= \Chibi\Router::linkTo(
['PostController', 'listAction'], ['PostController', 'listView'],
['query' => $this->context->transport->lastSearchQuery]) ?>"> ['query' => $this->context->transport->lastSearchQuery]) ?>">
<?= $this->context->transport->lastSearchQuery ?> <?= $this->context->transport->lastSearchQuery ?>
</a> </a>
@ -76,7 +76,7 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
<?php foreach ($tags as $tag): ?> <?php foreach ($tags as $tag): ?>
<li title="<?= $tag->name ?>"> <li title="<?= $tag->name ?>">
<a href="<?= \Chibi\Router::linkTo( <a href="<?= \Chibi\Router::linkTo(
['PostController', 'listAction'], ['PostController', 'listView'],
['query' => $tag->name]) ?>" ['query' => $tag->name]) ?>"
><?= $tag->name ?> ><?= $tag->name ?>
</a> </a>
@ -354,7 +354,7 @@ $canEditAnything = count(array_filter($editPostPrivileges)) > 0;
['PostController', 'deleteAction'], ['PostController', 'deleteAction'],
['id' => $this->context->transport->post->id]), ['id' => $this->context->transport->post->id]),
'data-confirm-text' => 'Are you sure you want to delete this post?', 'data-confirm-text' => 'Are you sure you want to delete this post?',
'data-redirect-url' => \Chibi\Router::linkTo(['PostController', 'listAction']), 'data-redirect-url' => \Chibi\Router::linkTo(['PostController', 'listView']),
]; ];
} }

View file

@ -28,7 +28,7 @@
<?php $max = $this->context->highestUsage ?> <?php $max = $this->context->highestUsage ?>
<?php $add = 0. ?> <?php $add = 0. ?>
<?php $mul = 10. / max(1, log(max(1, $max))) ?> <?php $mul = 10. / max(1, log(max(1, $max))) ?>
<?php $url = \Chibi\Router::linkTo(['PostController', 'listAction'], ['query' => '_query_']) ?> <?php $url = \Chibi\Router::linkTo(['PostController', 'listView'], ['query' => '_query_']) ?>
<div class="tags paginator-content"> <div class="tags paginator-content">
<ul> <ul>
<?php foreach ($this->context->transport->tags as $tag): ?> <?php foreach ($this->context->transport->tags as $tag): ?>

View file

@ -22,7 +22,7 @@
{ {
$registerNavItem( $registerNavItem(
'Browse', 'Browse',
\Chibi\Router::linkTo(['PostController', 'listAction']), \Chibi\Router::linkTo(['PostController', 'listView']),
$activeController == 'post' and $activeAction != 'upload'); $activeController == 'post' and $activeAction != 'upload');
} }
@ -139,7 +139,7 @@
<?php endif ?> <?php endif ?>
<li class="search"> <li class="search">
<form name="search" action="<?= \Chibi\Router::linkTo(['PostController', 'listAction']) ?>" method="get"> <form name="search" action="<?= \Chibi\Router::linkTo(['PostController', 'listView']) ?>" method="get">
<input <input
class="autocomplete" class="autocomplete"