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', '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}/{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', 'hideAction'], $method, '/post/{id}/hide', $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', 'featureAction'], $method, '/post/{id}/feature', $postValidation);
\Chibi\Router::register(['PostController', 'scoreAction'], $method, '/post/{id}/score/{score}', $postValidation);

View file

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

View file

@ -100,7 +100,7 @@ class PostController
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']))
{
@ -115,24 +115,54 @@ class PostController
Api::run(new AddPostJob(), $jobArgs);
}
public function editView($id)
{
$post = PostModel::findByIdOrName($id);
$context = getContext()->transport->post = $post;
}
public function editAction($id)
{
$context = getContext();
$post = PostModel::findByIdOrName($id);
$context->transport->post = $post;
if (!InputHelper::get('submit'))
return;
$editToken = InputHelper::get('edit-token');
if ($editToken != $post->getEditToken())
throw new SimpleException('This post was already edited by someone else in the meantime');
LogHelper::bufferChanges();
$this->doEdit($post, false);
LogHelper::flush();
$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'),
];
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();
}
@ -349,137 +379,4 @@ class PostController
$context->transport->fileHash = 'post' . $post->fileHash;
$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);
//do the edits
//warning: each handler runs uses the same privileges as post editing
$subJobs =
[
new EditPostSafetyJob(),
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)
{
}
}
//warning: it uses the same privileges as post editing internally
$arguments = $this->getArguments();
$arguments[EditPostJob::POST_ID] = $post->id;
Api::execute(new EditPostJob(), $arguments);
//load the post after edits
$post = PostModel::findById($post->id);

View file

@ -1,20 +1,21 @@
<?php
class EditPostContentJob extends AbstractPostEditJob
{
const CONTENT = 'content';
const POST_CONTENT = 'post-content';
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}', [
'user' => TextHelper::reprUser(Auth::getCurrentUser()),
'post' => TextHelper::reprPost($this->post)]);
'post' => TextHelper::reprPost($post)]);
return $this->post;
return $post;
}
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
class EditPostUrlJob extends AbstractPostEditJob
{
const CONTENT_URL = 'url';
const POST_CONTENT_URL = 'post-content-url';
public function execute()
{
$post = $this->post;
$url = $this->getArgument(self::CONTENT_URL);
$url = $this->getArgument(self::POST_CONTENT_URL);
$post->setContentFromUrl($url);