This repository has been archived on 2025-02-26. You can view files and clone it, but cannot push or open issues or pull requests.
szurubooru/src/Controllers/PostController.php
Marcin Kurczewski b97726f6ff Changed behavior of post list tabs
Before: each one linked to separate page that contained "static" search.
After: each one links to generic search that is aware of current search.

Example: if you searched for "snow" and clicked "upvoted", you would see
all upvoted posts ever regardless of what you just searched for. After
this change, you will see upvoted posts that have tag "snow". Now, if
you go back to "all posts", you will see again all posts tagged with
"snow" with or without the upvotes. Similarly if you click favorites,
favmin:1 will be appended to your search. In order to totally reset your
search, click "browse".

Additionally, typing favmin:1 and scoremin:1 manually now selects proper
tab.  Previously tabs were marked only if you clicked the tab.

Unfortunately, all of this had to happen at expense of URLs like
/upvoted and /random - now everything is represented with plain /posts/.
2014-08-04 22:15:10 +02:00

390 lines
11 KiB
PHP

<?php
class PostController extends AbstractController
{
public function listView($query = null, $page = 1, $source = 'posts', $additionalInfo = null)
{
$context = Core::getContext();
$context->source = $source;
$context->additionalInfo = $additionalInfo;
$this->interceptErrors(function() use ($context, $query, $page, $source, $additionalInfo)
{
$query = trim($query);
$context->transport->searchQuery = $query;
$context->transport->lastSearchQuery = $query;
if ($source == 'mass-tag')
{
Access::assert(new Privilege(Privilege::MassTag));
$context->massTagTag = $additionalInfo;
$context->massTagQuery = $query;
if (!Access::check(new Privilege(Privilege::MassTag, 'all')))
$query = trim($query . ' submit:' . Auth::getCurrentUser()->getName());
}
$ret = Api::run(
new ListPostsJob(),
[
JobArgs::ARG_PAGE_NUMBER => $page,
JobArgs::ARG_QUERY => $query
]);
$context->transport->posts = $ret->entities;
$context->transport->paginator = $ret;
});
$this->renderView('post-list-wrapper');
}
public function listRedirectAction($source = 'posts')
{
$context = Core::getContext();
if ($source == 'mass-tag')
Access::assert(new Privilege(Privilege::MassTag));
$oldPage = intval(InputHelper::get('old-page'));
$oldQuery = trim(InputHelper::get('old-query'));
$query = trim(InputHelper::get('query'));
$additionalInfo = trim(InputHelper::get('tag'));
$context->transport->searchQuery = $query;
$context->transport->lastSearchQuery = $query;
if (strpos($query, '/') !== false)
throw new SimpleException('Search query contains invalid characters');
$params = [];
$params['source'] = $source;
if ($query)
$params['query'] = $query;
if ($additionalInfo)
$params['additionalInfo'] = $additionalInfo;
if ($oldPage != 0 and $oldQuery == $query)
$params['page'] = $oldPage;
else
$params['page'] = 1;
$url = Core::getRouter()->linkTo(['PostController', 'listView'], $params);
$this->redirect($url);
}
public function toggleTagAction($identifier, $tag, $enable)
{
Access::assert(new Privilege(
Privilege::MassTag,
Access::getIdentity(PostModel::getByIdOrName($identifier)->getUploader())));
$jobArgs =
[
JobArgs::ARG_TAG_NAME => $tag,
JobArgs::ARG_NEW_STATE => $enable,
];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new TogglePostTagJob(), $jobArgs);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToLastVisitedUrl();
}
public function uploadView()
{
$this->renderView('post-upload');
}
public function uploadAction()
{
$jobArgs =
[
JobArgs::ARG_ANONYMOUS => InputHelper::get('anonymous'),
JobArgs::ARG_NEW_SAFETY => InputHelper::get('safety'),
JobArgs::ARG_NEW_TAG_NAMES => $this->splitTags(InputHelper::get('tags')),
JobArgs::ARG_NEW_SOURCE => InputHelper::get('source'),
];
if (!empty(InputHelper::get('url')))
{
$jobArgs[JobArgs::ARG_NEW_POST_CONTENT_URL] = InputHelper::get('url');
}
elseif (!empty($_FILES['file']['name']))
{
$file = $_FILES['file'];
TransferHelper::handleUploadErrors($file);
$jobArgs[JobArgs::ARG_NEW_POST_CONTENT] = new ApiFileInput(
$file['tmp_name'],
$file['name']);
}
Api::run(new AddPostJob(), $jobArgs);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToPostList();
}
public function uploadThumbnailView($url)
{
$url = base64_decode($url);
if (!Core::getConfig()->misc->proxyThumbsInUpload)
{
$this->redirect($url);
return;
}
$tmpPath = Core::getConfig()->main->cachePath . DS . md5($url) . '.upload-cache';
if (!file_exists($tmpPath))
TransferHelper::download($url, $tmpPath);
$options = new FileRendererOptions();
$options->lastModified = time() - 3600;
$options->cacheDaysToLive = 0.5;
$options->mimeType = mime_content_type($tmpPath);
if (strpos($options->mimeType, 'image/') !== 0) //not an image
{
$options->mimeType = 'image/jpeg';
$options->fileHash = 'thumb.jpg';
$options->fileContent = file_get_contents(Core::getConfig()->main->mediaPath . DS . 'img' . DS . 'thumb.jpg');
}
else
{
$options->fileHash = md5($url);
$options->fileContent = file_get_contents($tmpPath);
}
$this->renderFile($options);
}
public function editView($identifier)
{
$jobArgs = [];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
$post = Api::run(new GetPostJob(), $jobArgs);
$context = Core::getContext()->transport->post = $post;
$this->renderView('post-edit');
}
public function editAction($identifier)
{
$post = PostModel::getByIdOrName($identifier);
$jobArgs =
[
JobArgs::ARG_NEW_SAFETY => InputHelper::get('safety'),
JobArgs::ARG_NEW_TAG_NAMES => $this->splitTags(InputHelper::get('tags')),
JobArgs::ARG_NEW_SOURCE => InputHelper::get('source'),
JobArgs::ARG_NEW_RELATED_POST_IDS => $this->splitPostIds(InputHelper::get('relations')),
JobArgs::ARG_POST_REVISION => InputHelper::get('revision'),
];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
if (!empty(InputHelper::get('url')))
{
$jobArgs[JobArgs::ARG_NEW_POST_CONTENT_URL] = InputHelper::get('url');
}
elseif (!empty($_FILES['file']['name']))
{
$file = $_FILES['file'];
TransferHelper::handleUploadErrors($file);
$jobArgs[JobArgs::ARG_NEW_POST_CONTENT] = new ApiFileInput(
$file['tmp_name'],
$file['name']);
}
if (!empty($_FILES['thumbnail']['name']))
{
$file = $_FILES['thumbnail'];
TransferHelper::handleUploadErrors($file);
$jobArgs[JobArgs::ARG_NEW_THUMBNAIL_CONTENT] = new ApiFileInput(
$file['tmp_name'],
$file['name']);
}
Api::run(new EditPostJob(), $jobArgs);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToGenericView($identifier);
}
public function flagAction($identifier)
{
$jobArgs = [];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new FlagPostJob(), $jobArgs);
if ($this->isAjax())
$this->renderAjax();
else
$this->redirectToGenericView($identifier);
}
public function hideAction($identifier)
{
$jobArgs = [JobArgs::ARG_NEW_STATE => false];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new TogglePostVisibilityJob(), $jobArgs);
$this->redirectToGenericView($identifier);
}
public function unhideAction($identifier)
{
$jobArgs = [JobArgs::ARG_NEW_STATE => true];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new TogglePostVisibilityJob(), $jobArgs);
$this->redirectToGenericView($identifier);
}
public function deleteAction($identifier)
{
$jobArgs = [];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new DeletePostJob(), $jobArgs);
$this->redirectToPostList();
}
public function addFavoriteAction($identifier)
{
$jobArgs = [JobArgs::ARG_NEW_STATE => true];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new TogglePostFavoriteJob(), $jobArgs);
$this->redirectToGenericView($identifier);
}
public function removeFavoriteAction($identifier)
{
$jobArgs = [JobArgs::ARG_NEW_STATE => false];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new TogglePostFavoriteJob(), $jobArgs);
$this->redirectToGenericView($identifier);
}
public function scoreAction($identifier, $score)
{
$jobArgs = [JobArgs::ARG_NEW_POST_SCORE => $score];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new ScorePostJob(), $jobArgs);
$this->redirectToGenericView($identifier);
}
public function featureAction($identifier)
{
$jobArgs = [];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
Api::run(new FeaturePostJob(), $jobArgs);
$this->redirectToGenericView($identifier);
}
public function genericView($identifier)
{
$context = Core::getContext();
$jobArgs = [];
$jobArgs = $this->appendPostIdentifierArgument($jobArgs, $identifier);
$post = Api::run(new GetPostJob(), $jobArgs);
try
{
$context->transport->lastSearchQuery = InputHelper::get('last-search-query');
list ($prevPostId, $nextPostId) =
PostSearchService::getPostIdsAround(
$context->transport->lastSearchQuery, $identifier);
}
#search for some reason was invalid, e.g. tag was deleted in the meantime
catch (Exception $e)
{
$context->transport->lastSearchQuery = '';
list ($prevPostId, $nextPostId) =
PostSearchService::getPostIdsAround($context->transport->lastSearchQuery, $identifier);
}
$isUserFavorite = Auth::getCurrentUser()->hasFavorited($post);
$userScore = Auth::getCurrentUser()->getScore($post);
$flagged = in_array(TextHelper::reprPost($post), SessionHelper::get('flagged', []));
$context->isUserFavorite = $isUserFavorite;
$context->userScore = $userScore;
$context->flagged = $flagged;
$context->transport->post = $post;
$context->transport->prevPostId = $prevPostId ? $prevPostId : null;
$context->transport->nextPostId = $nextPostId ? $nextPostId : null;
$this->renderView('post-view');
}
public function fileView($name)
{
$ret = Api::run(new GetPostContentJob(), [JobArgs::ARG_POST_NAME => $name]);
$options = new FileRendererOptions();
$options->cacheDaysToLive = 14;
$options->customFileName = $ret->fileName;
$options->mimeType = $ret->mimeType;
$options->fileHash = 'post' . md5(substr($ret->fileContent, 0, 4096));
$options->fileContent = $ret->fileContent;
$options->lastModified = $ret->lastModified;
$this->renderFile($options);
}
public function thumbnailView($name)
{
$ret = Api::run(new GetPostThumbnailJob(), [JobArgs::ARG_POST_NAME => $name]);
$options = new FileRendererOptions();
$options->cacheDaysToLive = 365;
$options->customFileName = $ret->fileName;
$options->mimeType = 'image/jpeg';
$options->fileHash = 'thumb' . md5(substr($ret->fileContent, 0, 4096));
$options->fileContent = $ret->fileContent;
$options->lastModified = $ret->lastModified;
$this->renderFile($options);
}
private function appendPostIdentifierArgument(array $arguments, $postIdentifier)
{
if (is_numeric($postIdentifier))
$arguments[JobArgs::ARG_POST_ID] = $postIdentifier;
else
$arguments[JobArgs::ARG_POST_NAME] = $postIdentifier;
return $arguments;
}
private function splitPostIds($string)
{
$ids = preg_split('/\D/', trim($string));
$ids = array_filter($ids, function($x) { return $x != ''; });
$ids = array_map('intval', $ids);
$ids = array_unique($ids);
return $ids;
}
private function splitTags($string)
{
$tags = preg_split('/[,;\s]+/', trim($string));
$tags = array_filter($tags, function($x) { return $x != ''; });
$tags = array_unique($tags);
return $tags;
}
private function redirectToPostList()
{
$this->redirect(Core::getRouter()->linkTo(['PostController', 'listView']));
}
private function redirectToGenericView($identifier)
{
$this->redirect(Core::getRouter()->linkTo(
['PostController', 'genericView'],
['identifier' => $identifier]));
}
}