Moved post editing to API

This commit is contained in:
Marcin Kurczewski 2014-05-03 18:09:31 +02:00
parent 6ae4cea8bb
commit b2b7064ff0
8 changed files with 146 additions and 177 deletions

View file

@ -72,6 +72,8 @@ $postValidation =
\Chibi\Router::register(['PostController', 'uploadView'], 'GET', '/posts/upload', $postValidation); \Chibi\Router::register(['PostController', 'uploadView'], 'GET', '/posts/upload', $postValidation);
\Chibi\Router::register(['PostController', 'uploadAction'], 'POST', '/posts/upload', $postValidation); \Chibi\Router::register(['PostController', 'uploadAction'], 'POST', '/posts/upload', $postValidation);
\Chibi\Router::register(['PostController', 'editView'], 'GET', '/post/{id}/edit', $postValidation);
\Chibi\Router::register(['PostController', 'editAction'], 'POST', '/post/{id}/edit', $postValidation);
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}', $postValidation); \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}', $postValidation);
@ -103,7 +105,6 @@ foreach (['GET', 'POST'] as $method)
\Chibi\Router::register(['PostController', 'deleteAction'], $method, '/post/{id}/delete', $postValidation); \Chibi\Router::register(['PostController', 'deleteAction'], $method, '/post/{id}/delete', $postValidation);
\Chibi\Router::register(['PostController', 'hideAction'], $method, '/post/{id}/hide', $postValidation); \Chibi\Router::register(['PostController', 'hideAction'], $method, '/post/{id}/hide', $postValidation);
\Chibi\Router::register(['PostController', 'unhideAction'], $method, '/post/{id}/unhide', $postValidation); \Chibi\Router::register(['PostController', 'unhideAction'], $method, '/post/{id}/unhide', $postValidation);
\Chibi\Router::register(['PostController', 'editAction'], $method, '/post/{id}/edit', $postValidation);
\Chibi\Router::register(['PostController', 'flagAction'], $method, '/post/{id}/flag', $postValidation); \Chibi\Router::register(['PostController', 'flagAction'], $method, '/post/{id}/flag', $postValidation);
\Chibi\Router::register(['PostController', 'featureAction'], $method, '/post/{id}/feature', $postValidation); \Chibi\Router::register(['PostController', 'featureAction'], $method, '/post/{id}/feature', $postValidation);
\Chibi\Router::register(['PostController', 'scoreAction'], $method, '/post/{id}/score/{score}', $postValidation); \Chibi\Router::register(['PostController', 'scoreAction'], $method, '/post/{id}/score/{score}', $postValidation);

View file

@ -19,8 +19,8 @@ class Api
$p = $job->requiresPrivilege(); $p = $job->requiresPrivilege();
list ($privilege, $subPrivilege) = is_array($p) list ($privilege, $subPrivilege) = is_array($p)
? $p ? $p
: [$p, null]; : [$p, false];
if ($privilege !== null) if ($privilege !== false)
Access::assert($privilege, $subPrivilege); Access::assert($privilege, $subPrivilege);
return $job->execute(); return $job->execute();

View file

@ -100,7 +100,7 @@ class PostController
if (!empty(InputHelper::get('url'))) if (!empty(InputHelper::get('url')))
{ {
$jobArgs[EditPostUrlJob::CONTENT_URL] = InputHelper::get('url'); $jobArgs[EditPostUrlJob::POST_CONTENT_URL] = InputHelper::get('url');
} }
elseif (!empty($_FILES['file']['name'])) elseif (!empty($_FILES['file']['name']))
{ {
@ -115,24 +115,54 @@ class PostController
Api::run(new AddPostJob(), $jobArgs); Api::run(new AddPostJob(), $jobArgs);
} }
public function editView($id)
{
$post = PostModel::findByIdOrName($id);
$context = getContext()->transport->post = $post;
}
public function editAction($id) public function editAction($id)
{ {
$context = getContext();
$post = PostModel::findByIdOrName($id); $post = PostModel::findByIdOrName($id);
$context->transport->post = $post;
if (!InputHelper::get('submit'))
return;
$editToken = InputHelper::get('edit-token'); $editToken = InputHelper::get('edit-token');
if ($editToken != $post->getEditToken()) if ($editToken != $post->getEditToken())
throw new SimpleException('This post was already edited by someone else in the meantime'); throw new SimpleException('This post was already edited by someone else in the meantime');
LogHelper::bufferChanges(); $jobArgs =
$this->doEdit($post, false); [
LogHelper::flush(); 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'),
];
PostModel::save($post); 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);
TagModel::removeUnused(); TagModel::removeUnused();
} }
@ -349,137 +379,4 @@ class PostController
$context->transport->fileHash = 'post' . $post->fileHash; $context->transport->fileHash = 'post' . $post->fileHash;
$context->transport->filePath = $path; $context->transport->filePath = $path;
} }
private function doEdit($post, $isNew)
{
/* safety */
$suppliedSafety = InputHelper::get('safety');
if ($suppliedSafety !== null)
{
if (!$isNew)
Access::assert(Privilege::EditPostSafety, Access::getIdentity($post->getUploader()));
$oldSafety = $post->safety;
$post->setSafety($suppliedSafety);
$newSafety = $post->safety;
if ($oldSafety != $newSafety)
{
LogHelper::log('{user} changed safety of {post} to {safety}', [
'post' => TextHelper::reprPost($post),
'safety' => PostSafety::toString($post->safety)]);
}
}
/* tags */
$suppliedTags = InputHelper::get('tags');
if ($suppliedTags !== null)
{
if (!$isNew)
Access::assert(Privilege::EditPostTags, Access::getIdentity($post->getUploader()));
$oldTags = array_map(function($tag) { return $tag->name; }, $post->getTags());
$post->setTagsFromText($suppliedTags);
$newTags = array_map(function($tag) { return $tag->name; }, $post->getTags());
foreach (array_diff($oldTags, $newTags) as $tag)
{
LogHelper::log('{user} untagged {post} with {tag}', [
'post' => TextHelper::reprPost($post),
'tag' => TextHelper::reprTag($tag)]);
}
foreach (array_diff($newTags, $oldTags) as $tag)
{
LogHelper::log('{user} tagged {post} with {tag}', [
'post' => TextHelper::reprPost($post),
'tag' => TextHelper::reprTag($tag)]);
}
}
/* source */
$suppliedSource = InputHelper::get('source');
if ($suppliedSource !== null)
{
if (!$isNew)
Access::assert(Privilege::EditPostSource, Access::getIdentity($post->getUploader()));
$oldSource = $post->source;
$post->setSource($suppliedSource);
$newSource = $post->source;
if ($oldSource != $newSource)
{
LogHelper::log('{user} changed source of {post} to {source}', [
'post' => TextHelper::reprPost($post),
'source' => $post->source]);
}
}
/* relations */
$suppliedRelations = InputHelper::get('relations');
if ($suppliedRelations !== null)
{
if (!$isNew)
Access::assert(Privilege::EditPostRelations, Access::getIdentity($post->getUploader()));
$oldRelatedIds = array_map(function($post) { return $post->id; }, $post->getRelations());
$post->setRelationsFromText($suppliedRelations);
$newRelatedIds = array_map(function($post) { return $post->id; }, $post->getRelations());
foreach (array_diff($oldRelatedIds, $newRelatedIds) as $post2id)
{
LogHelper::log('{user} removed relation between {post} and {post2}', [
'post' => TextHelper::reprPost($post),
'post2' => TextHelper::reprPost($post2id)]);
}
foreach (array_diff($newRelatedIds, $oldRelatedIds) as $post2id)
{
LogHelper::log('{user} added relation between {post} and {post2}', [
'post' => TextHelper::reprPost($post),
'post2' => TextHelper::reprPost($post2id)]);
}
}
/* file contents */
if (!empty($_FILES['file']['name']))
{
if (!$isNew)
Access::assert(Privilege::EditPostFile, Access::getIdentity($post->getUploader()));
$suppliedFile = $_FILES['file'];
TransferHelper::handleUploadErrors($suppliedFile);
$post->setContentFromPath($suppliedFile['tmp_name'], $suppliedFile['name']);
if (!$isNew)
LogHelper::log('{user} changed contents of {post}', ['post' => TextHelper::reprPost($post)]);
}
elseif (InputHelper::get('url'))
{
if (!$isNew)
Access::assert(Privilege::EditPostFile, Access::getIdentity($post->getUploader()));
$url = InputHelper::get('url');
$post->setContentFromUrl($url);
if (!$isNew)
LogHelper::log('{user} changed contents of {post}', ['post' => TextHelper::reprPost($post)]);
}
/* thumbnail */
if (!empty($_FILES['thumb']['name']))
{
if (!$isNew)
Access::assert(Privilege::EditPostThumb, Access::getIdentity($post->getUploader()));
$suppliedFile = $_FILES['thumb'];
TransferHelper::handleUploadErrors($suppliedFile);
$post->setCustomThumbnailFromPath($srcPath = $suppliedFile['tmp_name']);
LogHelper::log('{user} changed thumb of {post}', ['post' => TextHelper::reprPost($post)]);
}
}
} }

View file

@ -17,29 +17,10 @@ class AddPostJob extends AbstractJob
PostModel::forgeId($post); PostModel::forgeId($post);
//do the edits //do the edits
//warning: each handler runs uses the same privileges as post editing //warning: it uses the same privileges as post editing internally
$subJobs = $arguments = $this->getArguments();
[ $arguments[EditPostJob::POST_ID] = $post->id;
new EditPostSafetyJob(), Api::execute(new EditPostJob(), $arguments);
new EditPostTagsJob(),
new EditPostSourceJob(),
new EditPostRelationsJob(),
new EditPostContentJob(),
new EditPostUrlJob(),
];
foreach ($subJobs as $subJob)
{
$args = $this->getArguments();
$args[self::POST_ID] = $post->id;
try
{
Api::run($subJob, $args);
}
catch (ApiMissingArgumentException $e)
{
}
}
//load the post after edits //load the post after edits
$post = PostModel::findById($post->id); $post = PostModel::findById($post->id);

View file

@ -1,20 +1,21 @@
<?php <?php
class EditPostContentJob extends AbstractPostEditJob class EditPostContentJob extends AbstractPostEditJob
{ {
const CONTENT = 'content'; const POST_CONTENT = 'post-content';
public function execute() public function execute()
{ {
$file = $this->getArgument(self::CONTENT); $post = $this->post;
$file = $this->getArgument(self::POST_CONTENT);
$this->post->setContentFromPath($file->filePath, $file->fileName); $post->setContentFromPath($file->filePath, $file->fileName);
PostModel::save($this->post); PostModel::save($post);
LogHelper::log('{user} changed contents of {post}', [ LogHelper::log('{user} changed contents of {post}', [
'user' => TextHelper::reprUser(Auth::getCurrentUser()), 'user' => TextHelper::reprUser(Auth::getCurrentUser()),
'post' => TextHelper::reprPost($this->post)]); 'post' => TextHelper::reprPost($post)]);
return $this->post; return $post;
} }
public function requiresPrivilege() public function requiresPrivilege()

49
src/Jobs/EditPostJob.php Normal file
View file

@ -0,0 +1,49 @@
<?php
class EditPostJob extends AbstractPostEditJob
{
public function execute()
{
$post = $this->post;
$subJobs =
[
new EditPostSafetyJob(),
new EditPostTagsJob(),
new EditPostSourceJob(),
new EditPostRelationsJob(),
new EditPostContentJob(),
new EditPostUrlJob(),
new EditPostThumbJob(),
];
foreach ($subJobs as $subJob)
{
$args = $this->getArguments();
$args[self::POST_ID] = $post->id;
try
{
Api::run($subJob, $args);
}
catch (ApiMissingArgumentException $e)
{
}
}
return $post;
}
public function requiresPrivilege()
{
return false;
}
public function requiresAuthentication()
{
return false;
}
public function requiresConfirmedEmail()
{
return false;
}
}

View file

@ -0,0 +1,40 @@
<?php
class EditPostThumbJob extends AbstractPostEditJob
{
const THUMB_CONTENT = 'thumb-content';
public function execute()
{
$post = $this->post;
$file = $this->getArgument(self::THUMB_CONTENT);
$post->setCustomThumbnailFromPath($file->filePath);
PostModel::save($post);
LogHelper::log('{user} changed thumb of {post}', [
'user' => TextHelper::reprUser(Auth::getCurrentUser()),
'post' => TextHelper::reprPost($post)]);
return $post;
}
public function requiresPrivilege()
{
return
[
Privilege::EditPostThumb,
Access::getIdentity($this->post->getUploader())
];
}
public function requiresAuthentication()
{
return false;
}
public function requiresConfirmedEmail()
{
return false;
}
}

View file

@ -1,12 +1,12 @@
<?php <?php
class EditPostUrlJob extends AbstractPostEditJob class EditPostUrlJob extends AbstractPostEditJob
{ {
const CONTENT_URL = 'url'; const POST_CONTENT_URL = 'post-content-url';
public function execute() public function execute()
{ {
$post = $this->post; $post = $this->post;
$url = $this->getArgument(self::CONTENT_URL); $url = $this->getArgument(self::POST_CONTENT_URL);
$post->setContentFromUrl($url); $post->setContentFromUrl($url);