szurubooru/src/Controllers/PostController.php

383 lines
11 KiB
PHP
Raw Normal View History

2013-10-05 12:55:03 +02:00
<?php
2013-10-05 21:24:20 +02:00
class PostController
2013-10-05 12:55:03 +02:00
{
2014-05-02 13:49:31 +02:00
public function listView($query = null, $page = 1, $source = 'posts', $additionalInfo = null)
2013-10-05 12:55:03 +02:00
{
2014-04-29 21:35:29 +02:00
$context = getContext();
$context->viewName = 'post-list-wrapper';
$context->source = $source;
$context->additionalInfo = $additionalInfo;
$context->handleExceptions = true;
2013-10-09 11:45:18 +02:00
2013-10-14 00:25:40 +02:00
//redirect requests in form of /posts/?query=... to canonical address
$formQuery = InputHelper::get('query');
if ($formQuery !== null)
{
2014-04-29 21:35:29 +02:00
$context->transport->searchQuery = $formQuery;
$context->transport->lastSearchQuery = $formQuery;
if (strpos($formQuery, '/') !== false)
2013-10-14 00:25:40 +02:00
throw new SimpleException('Search query contains invalid characters');
2014-05-02 13:49:31 +02:00
$url = \Chibi\Router::linkTo(['PostController', 'listView'], [
'source' => $source,
'additionalInfo' => $additionalInfo,
'query' => $formQuery]);
2014-04-29 21:35:29 +02:00
\Chibi\Util\Url::forward($url);
return;
}
2013-11-18 14:00:54 +01:00
$query = trim($query);
2014-04-29 21:35:29 +02:00
$context->transport->searchQuery = $query;
$context->transport->lastSearchQuery = $query;
if ($source == 'mass-tag')
{
Access::assert(Privilege::MassTag);
2014-04-29 21:35:29 +02:00
$context->massTagTag = $additionalInfo;
$context->massTagQuery = $query;
2014-05-01 16:06:38 +02:00
if (!Access::check(Privilege::MassTag, 'all'))
2014-05-01 16:12:37 +02:00
$query = trim($query . ' submit:' . Auth::getCurrentUser()->name);
}
2014-05-02 13:49:31 +02:00
$ret = Api::run(
new ListPostsJob(),
[
ListPostsJob::PAGE_NUMBER => $page,
ListPostsJob::QUERY => $query
2014-05-02 13:49:31 +02:00
]);
2013-10-09 11:45:18 +02:00
2014-05-02 13:49:31 +02:00
$context->transport->posts = $ret->posts;
2014-04-29 21:35:29 +02:00
$context->transport->paginator = new StdClass;
2014-05-02 13:49:31 +02:00
$context->transport->paginator->page = $ret->page;
$context->transport->paginator->pageCount = $ret->pageCount;
$context->transport->paginator->entityCount = $ret->postCount;
$context->transport->paginator->entities = $ret->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);
2013-10-05 19:24:08 +02:00
}
public function toggleTagAction($id, $tag, $enable)
{
2014-04-30 08:08:24 +02:00
Access::assert(
Privilege::MassTag,
2014-05-03 11:18:34 +02:00
Access::getIdentity(PostModel::findById($id)->getUploader()));
2014-05-03 11:18:34 +02:00
Api::run(
new TogglePostTagJob(),
[
TogglePostTagJob::POST_ID => $id,
TogglePostTagJob::TAG_NAME => $tag,
TogglePostTagJob::STATE => $enable,
2014-05-03 11:18:34 +02:00
]);
}
2014-05-03 14:20:48 +02:00
public function uploadView()
{
}
2013-10-05 19:24:08 +02:00
public function uploadAction()
{
2014-05-03 14:20:48 +02:00
$jobArgs =
[
AddPostJob::ANONYMOUS => InputHelper::get('anonymous'),
EditPostSafetyJob::SAFETY => InputHelper::get('safety'),
EditPostTagsJob::TAG_NAMES => InputHelper::get('tags'),
EditPostSourceJob::SOURCE => InputHelper::get('source'),
];
if (!empty(InputHelper::get('url')))
{
2014-05-03 18:09:31 +02:00
$jobArgs[EditPostUrlJob::POST_CONTENT_URL] = InputHelper::get('url');
2014-05-03 14:20:48 +02:00
}
elseif (!empty($_FILES['file']['name']))
{
$file = $_FILES['file'];
TransferHelper::handleUploadErrors($file);
2013-10-07 00:44:17 +02:00
2014-05-03 14:20:48 +02:00
$jobArgs[EditPostContentJob::POST_CONTENT] = Api::serializeFile(
$file['tmp_name'],
$file['name']);
}
2014-04-30 08:08:24 +02:00
2014-05-03 14:20:48 +02:00
Api::run(new AddPostJob(), $jobArgs);
2013-10-05 19:24:08 +02:00
}
2014-05-03 18:09:31 +02:00
public function editView($id)
2013-10-13 12:28:16 +02:00
{
$post = PostModel::findByIdOrName($id);
2014-05-03 18:09:31 +02:00
$context = getContext()->transport->post = $post;
}
2013-10-13 12:28:16 +02:00
2014-05-03 18:09:31 +02:00
public function editAction($id)
{
$post = PostModel::findByIdOrName($id);
2013-10-13 12:28:16 +02:00
2014-04-30 08:08:24 +02:00
$editToken = InputHelper::get('edit-token');
if ($editToken != $post->getEditToken())
throw new SimpleException('This post was already edited by someone else in the meantime');
2013-10-13 12:28:16 +02:00
2014-05-03 18:09:31 +02:00
$jobArgs =
[
EditPostJob::POST_ID => $id,
EditPostSafetyJob::SAFETY => InputHelper::get('safety'),
EditPostTagsJob::TAG_NAMES => InputHelper::get('tags'),
EditPostSourceJob::SOURCE => InputHelper::get('source'),
EditPostRelationsJob::RELATED_POST_IDS => InputHelper::get('relations'),
];
2013-10-30 20:20:01 +01:00
2014-05-03 18:09:31 +02:00
if (!empty(InputHelper::get('url')))
{
$jobArgs[EditPostUrlJob::POST_CONTENT_URL] = InputHelper::get('url');
}
elseif (!empty($_FILES['file']['name']))
{
$file = $_FILES['file'];
TransferHelper::handleUploadErrors($file);
$jobArgs[EditPostContentJob::POST_CONTENT] = Api::serializeFile(
$file['tmp_name'],
$file['name']);
}
if (!empty($_FILES['thumb']['name']))
{
$file = $_FILES['thumb'];
TransferHelper::handleUploadErrors($file);
$jobArgs[EditPostThumbJob::THUMB_CONTENT] = Api::serializeFile(
$file['tmp_name'],
$file['name']);
}
Api::run(new EditPostJob(), $jobArgs);
2014-04-30 08:08:24 +02:00
TagModel::removeUnused();
2013-10-13 12:28:16 +02:00
}
2013-11-17 14:52:46 +01:00
public function flagAction($id)
{
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::FlagPost, Access::getIdentity($post->getUploader()));
2013-11-17 14:52:46 +01:00
2014-04-30 08:08:24 +02:00
if (!InputHelper::get('submit'))
return;
2013-11-17 14:52:46 +01:00
2014-04-30 08:08:24 +02:00
$key = TextHelper::reprPost($post);
2013-11-17 14:52:46 +01:00
2014-04-30 08:08:24 +02:00
$flagged = SessionHelper::get('flagged', []);
if (in_array($key, $flagged))
throw new SimpleException('You already flagged this post');
$flagged []= $key;
SessionHelper::set('flagged', $flagged);
LogHelper::log('{user} flagged {post} for moderator attention', ['post' => TextHelper::reprPost($post)]);
2013-11-17 14:52:46 +01:00
}
2013-10-13 12:28:16 +02:00
public function hideAction($id)
{
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::HidePost, Access::getIdentity($post->getUploader()));
2013-11-16 21:21:43 +01:00
2014-04-30 08:08:24 +02:00
if (!InputHelper::get('submit'))
return;
2013-11-16 21:21:43 +01:00
2014-04-30 08:08:24 +02:00
$post->setHidden(true);
PostModel::save($post);
LogHelper::log('{user} hidden {post}', ['post' => TextHelper::reprPost($post)]);
2013-10-13 12:28:16 +02:00
}
public function unhideAction($id)
{
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::HidePost, Access::getIdentity($post->getUploader()));
2013-11-16 21:21:43 +01:00
2014-04-30 08:08:24 +02:00
if (!InputHelper::get('submit'))
return;
2013-11-16 21:21:43 +01:00
2014-04-30 08:08:24 +02:00
$post->setHidden(false);
PostModel::save($post);
LogHelper::log('{user} unhidden {post}', ['post' => TextHelper::reprPost($post)]);
2013-10-13 12:28:16 +02:00
}
public function deleteAction($id)
{
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::DeletePost, Access::getIdentity($post->getUploader()));
2013-11-16 21:21:43 +01:00
2014-04-30 08:08:24 +02:00
if (!InputHelper::get('submit'))
return;
2013-11-16 21:21:43 +01:00
2014-04-30 08:08:24 +02:00
PostModel::remove($post);
LogHelper::log('{user} deleted {post}', ['post' => TextHelper::reprPost($id)]);
2013-10-13 12:28:16 +02:00
}
2013-10-12 14:53:47 +02:00
public function addFavoriteAction($id)
{
2014-04-29 21:35:29 +02:00
$context = getContext();
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::FavoritePost, Access::getIdentity($post->getUploader()));
2014-05-01 16:18:42 +02:00
Access::assertAuthentication();
2013-10-12 14:53:47 +02:00
2014-04-30 08:08:24 +02:00
if (!InputHelper::get('submit'))
return;
2013-10-12 14:53:47 +02:00
2014-05-01 16:12:37 +02:00
UserModel::updateUserScore(Auth::getCurrentUser(), $post, 1);
UserModel::addToUserFavorites(Auth::getCurrentUser(), $post);
2013-10-12 14:53:47 +02:00
}
2014-04-29 21:35:29 +02:00
public function removeFavoriteAction($id)
2013-10-12 14:53:47 +02:00
{
2014-04-29 21:35:29 +02:00
$context = getContext();
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::FavoritePost, Access::getIdentity($post->getUploader()));
2014-05-01 16:18:42 +02:00
Access::assertAuthentication();
2013-10-12 14:53:47 +02:00
2014-04-30 08:08:24 +02:00
if (!InputHelper::get('submit'))
return;
2013-10-12 14:53:47 +02:00
2014-05-01 16:12:37 +02:00
UserModel::removeFromUserFavorites(Auth::getCurrentUser(), $post);
2013-10-12 14:53:47 +02:00
}
2013-11-10 12:23:59 +01:00
public function scoreAction($id, $score)
{
2014-04-29 21:35:29 +02:00
$context = getContext();
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::ScorePost, Access::getIdentity($post->getUploader()));
2014-05-01 16:18:42 +02:00
Access::assertAuthentication();
2013-11-10 12:23:59 +01:00
2014-04-30 08:08:24 +02:00
if (!InputHelper::get('submit'))
return;
2013-11-10 12:23:59 +01:00
2014-05-01 16:12:37 +02:00
UserModel::updateUserScore(Auth::getCurrentUser(), $post, $score);
2013-11-10 12:23:59 +01:00
}
2013-10-19 13:38:20 +02:00
public function featureAction($id)
{
2014-04-29 21:35:29 +02:00
$context = getContext();
$post = PostModel::findByIdOrName($id);
Access::assert(Privilege::FeaturePost, Access::getIdentity($post->getUploader()));
PropertyModel::set(PropertyModel::FeaturedPostId, $post->id);
PropertyModel::set(PropertyModel::FeaturedPostDate, time());
2014-05-01 16:12:37 +02:00
PropertyModel::set(PropertyModel::FeaturedPostUserName, Auth::getCurrentUser()->name);
LogHelper::log('{user} featured {post} on main page', ['post' => TextHelper::reprPost($post)]);
2013-10-19 13:38:20 +02:00
}
public function viewAction($id)
2013-10-05 19:24:08 +02:00
{
2014-04-29 21:35:29 +02:00
$context = getContext();
$post = PostModel::findByIdOrName($id);
CommentModel::preloadCommenters($post->getComments());
2013-10-12 10:46:15 +02:00
2013-10-13 12:28:16 +02:00
if ($post->hidden)
Access::assert(Privilege::ViewPost, 'hidden');
Access::assert(Privilege::ViewPost);
Access::assert(Privilege::ViewPost, PostSafety::toString($post->safety));
try
{
2014-04-29 21:35:29 +02:00
$context->transport->lastSearchQuery = InputHelper::get('last-search-query');
list ($prevPostId, $nextPostId) =
PostSearchService::getPostIdsAround(
2014-04-29 21:35:29 +02:00
$context->transport->lastSearchQuery, $id);
}
#search for some reason was invalid, e.g. tag was deleted in the meantime
catch (Exception $e)
{
2014-04-29 21:35:29 +02:00
$context->transport->lastSearchQuery = '';
list ($prevPostId, $nextPostId) =
PostSearchService::getPostIdsAround(
2014-04-29 21:35:29 +02:00
$context->transport->lastSearchQuery, $id);
}
2013-10-13 12:28:16 +02:00
2014-05-01 16:12:37 +02:00
$favorite = Auth::getCurrentUser()->hasFavorited($post);
$score = Auth::getCurrentUser()->getScore($post);
$flagged = in_array(TextHelper::reprPost($post), SessionHelper::get('flagged', []));
2014-04-29 21:35:29 +02:00
$context->favorite = $favorite;
$context->score = $score;
$context->flagged = $flagged;
$context->transport->post = $post;
$context->transport->prevPostId = $prevPostId ? $prevPostId : null;
$context->transport->nextPostId = $nextPostId ? $nextPostId : null;
}
public function thumbAction($name, $width = null, $height = null)
2013-10-08 23:02:31 +02:00
{
2014-04-29 21:35:29 +02:00
$context = getContext();
$path = PostModel::getThumbCustomPath($name, $width, $height);
2013-10-08 23:02:31 +02:00
if (!file_exists($path))
{
$path = PostModel::getThumbDefaultPath($name, $width, $height);
if (!file_exists($path))
2013-10-08 23:02:31 +02:00
{
$post = PostModel::findByIdOrName($name);
Access::assert(Privilege::ListPosts);
Access::assert(Privilege::ListPosts, PostSafety::toString($post->safety));
2014-04-30 09:54:04 +02:00
$post->generateThumb($width, $height);
if (!file_exists($path))
2014-04-29 21:35:29 +02:00
{
$path = getConfig()->main->mediaPath . DS . 'img' . DS . 'thumb.jpg';
$path = TextHelper::absolutePath($path);
}
2013-10-08 23:02:31 +02:00
}
}
2013-10-08 23:02:31 +02:00
if (!is_readable($path))
throw new SimpleException('Thumbnail file is not readable');
2014-04-29 21:35:29 +02:00
$context->layoutName = 'layout-file';
$context->transport->cacheDaysToLive = 365;
$context->transport->mimeType = 'image/jpeg';
$context->transport->fileHash = 'thumb' . md5($name . filemtime($path));
$context->transport->filePath = $path;
2013-10-08 23:02:31 +02:00
}
2013-10-07 23:17:33 +02:00
public function retrieveAction($name)
{
$post = PostModel::findByName($name, true);
2014-04-29 21:35:29 +02:00
$config = getConfig();
$context = getContext();
Access::assert(Privilege::RetrievePost);
Access::assert(Privilege::RetrievePost, PostSafety::toString($post->safety));
2014-04-29 21:35:29 +02:00
$path = $config->main->filesPath . DS . $post->name;
$path = TextHelper::absolutePath($path);
if (!file_exists($path))
2014-02-05 08:32:19 +01:00
throw new SimpleNotFoundException('Post file does not exist');
if (!is_readable($path))
throw new SimpleException('Post file is not readable');
2013-10-13 13:37:18 +02:00
$fn = sprintf('%s_%s_%s.%s',
2014-04-29 21:35:29 +02:00
$config->main->title,
$post->id,
join(',', array_map(function($tag) { return $tag->name; }, $post->getTags())),
2014-02-17 23:15:10 +01:00
TextHelper::resolveMimeType($post->mimeType) ?: 'dat');
2013-10-13 13:37:18 +02:00
$fn = preg_replace('/[[:^print:]]/', '', $fn);
2013-10-19 13:00:03 +02:00
$ttl = 60 * 60 * 24 * 14;
2013-10-13 14:01:07 +02:00
2014-04-29 21:35:29 +02:00
$context->layoutName = 'layout-file';
$context->transport->cacheDaysToLive = 14;
$context->transport->customFileName = $fn;
$context->transport->mimeType = $post->mimeType;
$context->transport->fileHash = 'post' . $post->fileHash;
$context->transport->filePath = $path;
2013-10-05 12:55:03 +02:00
}
}