Closed #10
This commit is contained in:
parent
be4a2615dd
commit
6c4affe454
10 changed files with 534 additions and 137 deletions
22
config.ini
22
config.ini
|
@ -37,14 +37,26 @@ Kind regards,
|
|||
|
||||
[privileges]
|
||||
uploadPost=registered
|
||||
viewPost=anonymous
|
||||
viewPost.sketchy=registered
|
||||
viewPost.unsafe=registered
|
||||
listPosts=anonymous
|
||||
listPosts.sketchy=registered
|
||||
listPosts.unsafe=registered
|
||||
listPosts.hidden=nobody
|
||||
listUsers=registered
|
||||
favoritePost=registered
|
||||
listComments=anonymous
|
||||
viewPost=anonymous
|
||||
viewPost.sketchy=registered
|
||||
viewPost.unsafe=registered
|
||||
viewPost.hidden=admin
|
||||
retrievePost=anonymous
|
||||
favoritePost=registered
|
||||
editPostSafety.own=registered
|
||||
editPostSafety.all=moderator
|
||||
editPostTags.own=registered
|
||||
editPostTags.all=registered
|
||||
editPostThumb.own=moderator
|
||||
editPostThumb.all=moderator
|
||||
hidePost.own=moderator
|
||||
hidePost.all=moderator
|
||||
deletePost.own=moderator
|
||||
deletePost.all=moderator
|
||||
listComments=anonymous
|
||||
listTags=anonymous
|
||||
|
|
|
@ -96,6 +96,9 @@ body {
|
|||
|
||||
#sidebar h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,12 +73,15 @@ i.icon-dl {
|
|||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.options nav ul {
|
||||
.options ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.favorites p {
|
||||
margin: 0;
|
||||
}
|
||||
.favorites ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
|
@ -90,3 +93,42 @@ i.icon-dl {
|
|||
.favorites a {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
form.edit {
|
||||
display: none;
|
||||
padding: 0.5em 1em;
|
||||
border: 1px solid #eee;
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
form.edit>div {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
form.edit input[type=checkbox],
|
||||
form.edit label {
|
||||
vertical-align: middle;
|
||||
line-height: 33px;
|
||||
}
|
||||
form.edit label.left {
|
||||
display: inline-block;
|
||||
width: 5em;
|
||||
float: left;
|
||||
}
|
||||
form.edit .safety label:not(.left) {
|
||||
margin-right: 0.75em;
|
||||
}
|
||||
form.edit>div {
|
||||
clear: left;
|
||||
}
|
||||
ul.tagit {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,122 @@
|
|||
$(function()
|
||||
{
|
||||
$('.add-fav a, .rem-fav a').click(function(e)
|
||||
$('.add-fav a, .rem-fav a, .hide a, .unhide a').click(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
var url = $(this).attr('href');
|
||||
url += '?json';
|
||||
|
||||
var aDom = $(this);
|
||||
if (aDom.hasClass('inactive'))
|
||||
return;
|
||||
aDom.addClass('inactive');
|
||||
|
||||
var url = $(this).attr('href') + '?json';
|
||||
$.get(url, function(data)
|
||||
{
|
||||
if (data['errorMessage'])
|
||||
{
|
||||
alert(data['errorMessage']);
|
||||
}
|
||||
else
|
||||
if (data['success'])
|
||||
{
|
||||
window.location.reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
alert(data['errorMessage']);
|
||||
aDom.removeClass('inactive');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.delete a').click(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var aDom = $(this);
|
||||
if (aDom.hasClass('inactive'))
|
||||
return;
|
||||
aDom.addClass('inactive');
|
||||
|
||||
//todo: move this string literal to html
|
||||
if (confirm(aDom.attr('data-confirm-text')))
|
||||
{
|
||||
var url = $(this).attr('href') + '?json';
|
||||
$.get(url, function(data)
|
||||
{
|
||||
if (data['success'])
|
||||
{
|
||||
window.location.href = aDom.attr('data-redirect-url');
|
||||
}
|
||||
else
|
||||
{
|
||||
alert(data['errorMessage']);
|
||||
aDom.removeClass('inactive');
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
aDom.removeClass('inactive');
|
||||
}
|
||||
});
|
||||
|
||||
$('li.edit a').click(function(e)
|
||||
{
|
||||
var aDom = $(this);
|
||||
if (aDom.hasClass('inactive'))
|
||||
return;
|
||||
aDom.addClass('inactive');
|
||||
|
||||
var tags = [];
|
||||
$.getJSON('/tags?json', function(data)
|
||||
{
|
||||
tags = data['tags'];
|
||||
|
||||
var tagItOptions =
|
||||
{
|
||||
caseSensitive: true,
|
||||
availableTags: tags,
|
||||
placeholderText: $('.tags input').attr('placeholder')
|
||||
};
|
||||
$('.tags input').tagit(tagItOptions);
|
||||
|
||||
e.preventDefault();
|
||||
$('form.edit').slideDown();
|
||||
});
|
||||
});
|
||||
|
||||
$('form.edit').submit(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var formDom = $(this);
|
||||
if (formDom.hasClass('inactive'))
|
||||
return;
|
||||
formDom.addClass('inactive');
|
||||
formDom.find(':input').attr('readonly', true);
|
||||
|
||||
var url = formDom.attr('action') + '?json';
|
||||
var fd = new FormData(formDom[0]);
|
||||
|
||||
var ajaxData =
|
||||
{
|
||||
url: url,
|
||||
data: fd,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: 'POST',
|
||||
|
||||
success: function(data)
|
||||
{
|
||||
if (data['success'])
|
||||
{
|
||||
window.location.reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
alert(data['errorMessage']);
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.ajax(ajaxData);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -154,7 +154,8 @@ $(function()
|
|||
|
||||
postDom.show();
|
||||
var tagItOptions =
|
||||
{ caseSensitive: true,
|
||||
{
|
||||
caseSensitive: true,
|
||||
availableTags: tags,
|
||||
placeholderText: $('.tags input').attr('placeholder')
|
||||
};
|
||||
|
|
|
@ -8,6 +8,60 @@ class PostController
|
|||
$callback();
|
||||
}
|
||||
|
||||
private static function locatePost($key)
|
||||
{
|
||||
if (is_numeric($key))
|
||||
{
|
||||
$post = R::findOne('post', 'id = ?', [$key]);
|
||||
if (!$post)
|
||||
throw new SimpleException('Invalid post ID "' . $key . '"');
|
||||
}
|
||||
else
|
||||
{
|
||||
$post = R::findOne('post', 'name = ?', [$key]);
|
||||
if (!$post)
|
||||
throw new SimpleException('Invalid post name "' . $key . '"');
|
||||
}
|
||||
return $post;
|
||||
}
|
||||
|
||||
private static function serializeTags($post)
|
||||
{
|
||||
$x = [];
|
||||
foreach ($post->sharedTag as $tag)
|
||||
$x []= $tag->name;
|
||||
natcasesort($x);
|
||||
$x = join('', $x);
|
||||
return md5($x);
|
||||
}
|
||||
|
||||
private static function handleUploadErrors($file)
|
||||
{
|
||||
switch ($file['error'])
|
||||
{
|
||||
case UPLOAD_ERR_OK:
|
||||
break;
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
throw new SimpleException('File is too big (maximum size allowed: ' . ini_get('upload_max_filesize') . ')');
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
throw new SimpleException('File is too big than it was allowed in HTML form');
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
throw new SimpleException('File transfer was interrupted');
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
throw new SimpleException('No file was uploaded');
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
throw new SimpleException('Server misconfiguration error: missing temporary folder');
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
throw new SimpleException('Server misconfiguration error: cannot write to disk');
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
throw new SimpleException('Server misconfiguration error: upload was canceled by an extension');
|
||||
default:
|
||||
throw new SimpleException('Generic file upload error (id: ' . $file['error'] . ')');
|
||||
}
|
||||
if (!is_uploaded_file($file['tmp_name']))
|
||||
throw new SimpleException('Generic file upload error');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -37,7 +91,6 @@ class PostController
|
|||
$this->context->subTitle = 'browsing posts';
|
||||
$page = intval($page);
|
||||
$postsPerPage = intval($this->config->browsing->postsPerPage);
|
||||
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ListPosts);
|
||||
|
||||
$buildDbQuery = function($dbQuery)
|
||||
|
@ -54,6 +107,9 @@ class PostController
|
|||
foreach ($allowedSafety as $s)
|
||||
$dbQuery->put($s);
|
||||
|
||||
if (!PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts, 'hidden'))
|
||||
$dbQuery->andNot('hidden');
|
||||
|
||||
//todo construct WHERE based on filters
|
||||
|
||||
//todo construct ORDER based on filers
|
||||
|
@ -82,6 +138,19 @@ class PostController
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* @route /favorites
|
||||
* @route /favorites/{page}
|
||||
* @validate page \d*
|
||||
*/
|
||||
public function favoritesAction($page = 1)
|
||||
{
|
||||
$this->listAction('favmin:1', $page);
|
||||
$this->context->viewName = 'post-list';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /post/upload
|
||||
*/
|
||||
|
@ -90,15 +159,17 @@ class PostController
|
|||
$this->context->stylesheets []= 'upload.css';
|
||||
$this->context->scripts []= 'upload.js';
|
||||
$this->context->subTitle = 'upload';
|
||||
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::UploadPost);
|
||||
|
||||
if (isset($_FILES['file']))
|
||||
{
|
||||
/* safety */
|
||||
$suppliedSafety = intval(InputHelper::get('safety'));
|
||||
if (!in_array($suppliedSafety, PostSafety::getAll()))
|
||||
throw new SimpleException('Invalid safety type "' . $suppliedSafety . '"');
|
||||
|
||||
|
||||
/* tags */
|
||||
$suppliedTags = InputHelper::get('tags');
|
||||
$suppliedTags = preg_split('/[,;\s+]/', $suppliedTags);
|
||||
$suppliedTags = array_filter($suppliedTags);
|
||||
|
@ -109,32 +180,26 @@ class PostController
|
|||
if (empty($suppliedTags))
|
||||
throw new SimpleException('No tags set');
|
||||
|
||||
$suppliedFile = $_FILES['file'];
|
||||
switch ($suppliedFile['error'])
|
||||
$dbTags = [];
|
||||
foreach ($suppliedTags as $tag)
|
||||
{
|
||||
case UPLOAD_ERR_OK:
|
||||
break;
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
throw new SimpleException('File is too big (maximum size allowed: ' . ini_get('upload_max_filesize') . ')');
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
throw new SimpleException('File is too big than it was allowed in HTML form');
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
throw new SimpleException('File transfer was interrupted');
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
throw new SimpleException('No file was uploaded');
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
throw new SimpleException('Server misconfiguration error: missing temporary folder');
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
throw new SimpleException('Server misconfiguration error: cannot write to disk');
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
throw new SimpleException('Server misconfiguration error: upload was canceled by an extension');
|
||||
default:
|
||||
throw new SimpleException('Generic file upload error (id: ' . $suppliedFile['error'] . ')');
|
||||
$dbTag = R::findOne('tag', 'name = ?', [$tag]);
|
||||
if (!$dbTag)
|
||||
{
|
||||
$dbTag = R::dispense('tag');
|
||||
$dbTag->name = $tag;
|
||||
R::store($dbTag);
|
||||
}
|
||||
$dbTags []= $dbTag;
|
||||
}
|
||||
if (!is_uploaded_file($suppliedFile['tmp_name']))
|
||||
throw new SimpleException('Generic file upload error');
|
||||
|
||||
#$mimeType = $suppliedFile['type'];
|
||||
|
||||
/* file contents */
|
||||
$suppliedFile = $_FILES['file'];
|
||||
self::handleUploadErrors($suppliedFile);
|
||||
|
||||
|
||||
/* file details */
|
||||
$mimeType = mime_content_type($suppliedFile['tmp_name']);
|
||||
$imageWidth = null;
|
||||
$imageHeight = null;
|
||||
|
@ -166,19 +231,8 @@ class PostController
|
|||
}
|
||||
while (file_exists($path));
|
||||
|
||||
$dbTags = [];
|
||||
foreach ($suppliedTags as $tag)
|
||||
{
|
||||
$dbTag = R::findOne('tag', 'name = ?', [$tag]);
|
||||
if (!$dbTag)
|
||||
{
|
||||
$dbTag = R::dispense('tag');
|
||||
$dbTag->name = $tag;
|
||||
R::store($dbTag);
|
||||
}
|
||||
$dbTags []= $dbTag;
|
||||
}
|
||||
|
||||
/* db storage */
|
||||
$dbPost = R::dispense('post');
|
||||
$dbPost->type = $postType;
|
||||
$dbPost->name = $name;
|
||||
|
@ -187,6 +241,7 @@ class PostController
|
|||
$dbPost->file_size = filesize($suppliedFile['tmp_name']);
|
||||
$dbPost->mime_type = $mimeType;
|
||||
$dbPost->safety = $suppliedSafety;
|
||||
$dbPost->hidden = false;
|
||||
$dbPost->upload_date = time();
|
||||
$dbPost->image_width = $imageWidth;
|
||||
$dbPost->image_height = $imageHeight;
|
||||
|
@ -201,6 +256,141 @@ class PostController
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /post/edit/{id}
|
||||
*/
|
||||
public function editAction($id)
|
||||
{
|
||||
$post = self::locatePost($id);
|
||||
R::preload($post, ['uploader' => 'user']);
|
||||
$edited = false;
|
||||
$secondary = $post->uploader->id == $this->context->user->id ? 'own' : 'all';
|
||||
|
||||
|
||||
/* safety */
|
||||
$suppliedSafety = InputHelper::get('safety');
|
||||
if ($suppliedSafety !== null)
|
||||
{
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::EditPostSafety, $secondary);
|
||||
$suppliedSafety = intval($suppliedSafety);
|
||||
if (!in_array($suppliedSafety, PostSafety::getAll()))
|
||||
throw new SimpleException('Invalid safety type "' . $suppliedSafety . '"');
|
||||
$post->safety = $suppliedSafety;
|
||||
$edited = true;
|
||||
}
|
||||
|
||||
|
||||
/* tags */
|
||||
$suppliedTags = InputHelper::get('tags');
|
||||
if ($suppliedTags !== null)
|
||||
{
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::EditPostTags, $secondary);
|
||||
$currentToken = self::serializeTags($post);
|
||||
if (InputHelper::get('tags-token') != $currentToken)
|
||||
throw new SimpleException('Someone else has changed the tags in the meantime');
|
||||
|
||||
$suppliedTags = preg_split('/[,;\s+]/', $suppliedTags);
|
||||
$suppliedTags = array_filter($suppliedTags);
|
||||
$suppliedTags = array_unique($suppliedTags);
|
||||
foreach ($suppliedTags as $tag)
|
||||
if (!preg_match('/^[a-zA-Z0-9_-]+$/i', $tag))
|
||||
throw new SimpleException('Invalid tag "' . $tag . '"');
|
||||
if (empty($suppliedTags))
|
||||
throw new SimpleException('No tags set');
|
||||
|
||||
$dbTags = [];
|
||||
foreach ($suppliedTags as $tag)
|
||||
{
|
||||
$dbTag = R::findOne('tag', 'name = ?', [$tag]);
|
||||
if (!$dbTag)
|
||||
{
|
||||
$dbTag = R::dispense('tag');
|
||||
$dbTag->name = $tag;
|
||||
R::store($dbTag);
|
||||
}
|
||||
$dbTags []= $dbTag;
|
||||
}
|
||||
|
||||
$post->sharedTag = $dbTags;
|
||||
$edited = true;
|
||||
}
|
||||
|
||||
|
||||
/* thumbnail */
|
||||
if (isset($_FILES['thumb']))
|
||||
{
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::EditPostThumb, $secondary);
|
||||
$suppliedFile = $_FILES['thumb'];
|
||||
self::handleUploadErrors($suppliedFile);
|
||||
|
||||
$mimeType = mime_content_type($suppliedFile['tmp_name']);
|
||||
if (!in_array($mimeType, ['image/gif', 'image/png', 'image/jpeg']))
|
||||
throw new SimpleException('Invalid thumbnail type "' . $mimeType . '"');
|
||||
list ($imageWidth, $imageHeight) = getimagesize($suppliedFile['tmp_name']);
|
||||
if ($imageWidth != $this->config->browsing->thumbWidth)
|
||||
throw new SimpleException('Invalid thumbnail width (should be ' . $this->config->browsing->thumbWidth . ')');
|
||||
if ($imageWidth != $this->config->browsing->thumbHeight)
|
||||
throw new SimpleException('Invalid thumbnail width (should be ' . $this->config->browsing->thumbHeight . ')');
|
||||
|
||||
$path = $this->config->main->thumbsPath . DS . $post->name;
|
||||
move_uploaded_file($suppliedFile['tmp_name'], $path);
|
||||
}
|
||||
|
||||
|
||||
/* db storage */
|
||||
if ($edited)
|
||||
R::store($post);
|
||||
$this->context->transport->success = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /post/hide/{id}
|
||||
*/
|
||||
public function hideAction($id)
|
||||
{
|
||||
$post = self::locatePost($id);
|
||||
$secondary = $post->uploader->id == $this->context->user->id ? 'own' : 'all';
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::HidePost, $secondary);
|
||||
$post->hidden = true;
|
||||
R::store($post);
|
||||
$this->context->transport->success = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @route /post/unhide/{id}
|
||||
*/
|
||||
public function unhideAction($id)
|
||||
{
|
||||
$post = self::locatePost($id);
|
||||
$secondary = $post->uploader->id == $this->context->user->id ? 'own' : 'all';
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::HidePost, $secondary);
|
||||
$post->hidden = false;
|
||||
R::store($post);
|
||||
$this->context->transport->success = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @route /post/delete/{id}
|
||||
*/
|
||||
public function deleteAction($id)
|
||||
{
|
||||
$post = self::locatePost($id);
|
||||
$secondary = $post->uploader->id == $this->context->user->id ? 'own' : 'all';
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::DeletePost, $secondary);
|
||||
//remove stuff from auxiliary tables
|
||||
$post->ownFavoritee = [];
|
||||
$post->sharedTag = [];
|
||||
R::store($post);
|
||||
R::trash($post);
|
||||
$this->context->transport->success = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /post/add-fav/{id}
|
||||
* @route /post/fav-add/{id}
|
||||
|
@ -260,12 +450,31 @@ class PostController
|
|||
$post = self::locatePost($id);
|
||||
R::preload($post, ['favoritee' => 'user', 'uploader' => 'user', 'tag']);
|
||||
|
||||
$prevPost = R::findOne('post', 'id < ? ORDER BY id DESC LIMIT 1', [$id]);
|
||||
$nextPost = R::findOne('post', 'id > ? ORDER BY id ASC LIMIT 1', [$id]);
|
||||
|
||||
if ($post->hidden)
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, 'hidden');
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
|
||||
|
||||
$buildNextPostQuery = function($dbQuery, $id, $next)
|
||||
{
|
||||
$dbQuery->select('id')
|
||||
->from('post')
|
||||
->where($next ? 'id > ?' : 'id < ?')
|
||||
->put($id);
|
||||
if (!PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts, 'hidden'))
|
||||
$dbQuery->andNot('hidden');
|
||||
$dbQuery->orderBy($next ? 'id asc' : 'id desc')
|
||||
->limit(1);
|
||||
};
|
||||
|
||||
$prevPostQuery = R::$f->begin();
|
||||
$buildNextPostQuery($prevPostQuery, $id, false);
|
||||
$prevPost = $prevPostQuery->get('row');
|
||||
|
||||
$nextPostQuery = R::$f->begin();
|
||||
$buildNextPostQuery($nextPostQuery, $id, true);
|
||||
$nextPost = $nextPostQuery->get('row');
|
||||
|
||||
$favorite = false;
|
||||
if ($this->context->loggedIn)
|
||||
foreach ($post->ownFavoritee as $fav)
|
||||
|
@ -291,8 +500,9 @@ class PostController
|
|||
$this->context->subTitle = 'showing @' . $post->id;
|
||||
$this->context->favorite = $favorite;
|
||||
$this->context->transport->post = $post;
|
||||
$this->context->transport->prevPostId = $prevPost ? $prevPost->id : null;
|
||||
$this->context->transport->nextPostId = $nextPost ? $nextPost->id : null;
|
||||
$this->context->transport->prevPostId = $prevPost ? $prevPost['id'] : null;
|
||||
$this->context->transport->nextPostId = $nextPost ? $nextPost['id'] : null;
|
||||
$this->context->transport->tagsToken = self::serializeTags($post);
|
||||
}
|
||||
|
||||
|
||||
|
@ -309,7 +519,7 @@ class PostController
|
|||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
|
||||
|
||||
$path = $this->config->main->thumbsPath . DS . $post->name . '.png';
|
||||
$path = $this->config->main->thumbsPath . DS . $post->name;
|
||||
if (!file_exists($path))
|
||||
{
|
||||
$srcPath = $this->config->main->filesPath . DS . $post->name;
|
||||
|
@ -317,7 +527,7 @@ class PostController
|
|||
$dstWidth = $this->config->browsing->thumbWidth;
|
||||
$dstHeight = $this->config->browsing->thumbHeight;
|
||||
|
||||
switch($post->mime_type)
|
||||
switch ($post->mime_type)
|
||||
{
|
||||
case 'image/jpeg':
|
||||
$srcImage = imagecreatefromjpeg($srcPath);
|
||||
|
@ -389,34 +599,4 @@ class PostController
|
|||
$this->context->transport->mimeType = $post->mimeType;
|
||||
$this->context->transport->filePath = $path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /favorites
|
||||
* @route /favorites/{page}
|
||||
* @validate page \d*
|
||||
*/
|
||||
public function favoritesAction($page = 1)
|
||||
{
|
||||
$this->listAction('favmin:1', $page);
|
||||
$this->context->viewName = 'post-list';
|
||||
}
|
||||
|
||||
public static function locatePost($key)
|
||||
{
|
||||
if (is_numeric($key))
|
||||
{
|
||||
$post = R::findOne('post', 'id = ?', [$key]);
|
||||
if (!$post)
|
||||
throw new SimpleException('Invalid post ID "' . $key . '"');
|
||||
}
|
||||
else
|
||||
{
|
||||
$post = R::findOne('post', 'name = ?', [$key]);
|
||||
if (!$post)
|
||||
throw new SimpleException('Invalid post name "' . $key . '"');
|
||||
}
|
||||
return $post;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,13 @@ class Privilege extends Enum
|
|||
const ViewPost = 3;
|
||||
const RetrievePost = 4;
|
||||
const FavoritePost = 5;
|
||||
const ListUsers = 6;
|
||||
const ListComments = 7;
|
||||
const ListTags = 8;
|
||||
const EditPostSafety = 6;
|
||||
const EditPostTags = 7;
|
||||
const EditPostThumb = 8;
|
||||
const HidePost = 9;
|
||||
const DeletePost = 10;
|
||||
|
||||
const ListUsers = 11;
|
||||
const ListComments = 12;
|
||||
const ListTags = 13;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
<form name="search" action="<?php echo \Chibi\UrlHelper::route('post', 'list') ?>" method="get">
|
||||
<input type="search" name="query" placeholder="Search…" value="<?php echo isset($this->context->transport->searchQuery) ? $this->context->transport->searchQuery : '' ?>">
|
||||
</form>
|
||||
</i>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
<div class="sidebar-unit tags">
|
||||
<h1>tags (<?php echo count($this->context->transport->post->sharedTag) ?>)</h1>
|
||||
<!-- todo: edit tags -->
|
||||
<ul>
|
||||
<?php foreach ($this->context->transport->post->sharedTag as $tag): ?>
|
||||
<li>
|
||||
|
@ -107,57 +106,71 @@
|
|||
<div class="sidebar-unit options">
|
||||
<h1>options</h1>
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
<?php if (PrivilegesHelper::confirm($this->context->user, Privilege::FavoritePost)): ?>
|
||||
<?php if (!$this->context->favorite): ?>
|
||||
<li class="add-fav">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'add-favorite', ['id' => $this->context->transport->post->id]) ?>">
|
||||
Add to favorites
|
||||
</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="rem-fav">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'rem-favorite', ['id' => $this->context->transport->post->id]) ?>">
|
||||
Remove from favorites
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<ul>
|
||||
<?php if (PrivilegesHelper::confirm($this->context->user, Privilege::FavoritePost)): ?>
|
||||
<?php if (!$this->context->favorite): ?>
|
||||
<li class="add-fav">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'add-favorite', ['id' => $this->context->transport->post->id]) ?>">
|
||||
Add to favorites
|
||||
</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="rem-fav">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'rem-favorite', ['id' => $this->context->transport->post->id]) ?>">
|
||||
Remove from favorites
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
|
||||
<!--
|
||||
<li>
|
||||
<?php
|
||||
$secondary = $this->context->transport->post->uploader->id == $this->context->user->id ? 'own' : 'all';
|
||||
$editPostPrivileges = [
|
||||
Privilege::EditPostSafety,
|
||||
Privilege::EditPostTags,
|
||||
Privilege::EditPostThumb,
|
||||
];
|
||||
$editPostPrivileges = array_fill_keys($editPostPrivileges, false);
|
||||
foreach (array_keys($editPostPrivileges) as $privilege)
|
||||
{
|
||||
if (PrivilegesHelper::confirm($this->context->user, $privilege, $secondary))
|
||||
$editPostPrivileges[$privilege] = true;
|
||||
}
|
||||
$canEditAnything = count(array_filter($editPostPrivileges)) > 0;
|
||||
?>
|
||||
|
||||
<?php if ($canEditAnything): ?>
|
||||
<li class="edit">
|
||||
<a href="#">
|
||||
Edit tags
|
||||
Edit
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
|
||||
<li>
|
||||
<a href="#">
|
||||
Change safety
|
||||
<?php if (PrivilegesHelper::confirm($this->context->user, Privilege::HidePost, $secondary)): ?>
|
||||
<?php if ($this->context->transport->post->hidden): ?>
|
||||
<li class="unhide">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'unhide', ['id' => $this->context->transport->post->id]) ?>">
|
||||
Unhide
|
||||
</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="hide">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'hide', ['id' => $this->context->transport->post->id]) ?>">
|
||||
Hide
|
||||
</a>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (PrivilegesHelper::confirm($this->context->user, Privilege::DeletePost, $secondary)): ?>
|
||||
<li class="delete">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'delete', ['id' => $this->context->transport->post->id]) ?>" data-confirm-text="Are you sure?" data-redirect-url="<?php echo \Chibi\UrlHelper::route('post', 'list') ?>">
|
||||
Delete
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#">
|
||||
Show on main page
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#">
|
||||
Hide from main page
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#">
|
||||
Remove
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</nav>
|
||||
<?php endif ?>
|
||||
</ul>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (!$('.options ul li').length)
|
||||
|
@ -174,4 +187,41 @@
|
|||
<embed width="<?php echo $this->context->transport->post->image_width ?>" height="<?php echo $this->context->transport->post->image_height ?>" type="application/x-shockwave-flash" src="<?php echo \Chibi\UrlHelper::route('post', 'retrieve', ['name' => $this->context->transport->post->name]) ?>"/>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
||||
<?php if ($canEditAnything): ?>
|
||||
<form action="<?php echo \Chibi\UrlHelper::route('post', 'edit', ['id' => $this->context->transport->post->id]) ?>" method="post" enctype="multiplart/form-data" class="edit">
|
||||
<h1>edit post</h1>
|
||||
<?php if ($editPostPrivileges[Privilege::EditPostSafety]): ?>
|
||||
<div class="safety">
|
||||
<label class="left">Safety:</label>
|
||||
<?php foreach (PostSafety::getAll() as $safety): ?>
|
||||
<label>
|
||||
<input type="radio" name="safety" value="<?php echo $safety ?>" <?php if ($this->context->transport->post->safety == $safety) echo 'checked="checked"' ?>/>
|
||||
<?php echo PostSafety::toString($safety) ?>
|
||||
</label>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($editPostPrivileges[Privilege::EditPostTags]): ?>
|
||||
<div class="tags">
|
||||
<label class="left" for="tags">Tags:</label>
|
||||
<input type="text" name="tags" id="tags" placeholder="enter some tags…" value="<?php echo join(',', array_map(function($tag) { return $tag->name; }, $this->context->transport->post->sharedTag)) ?>"/>
|
||||
</div>
|
||||
<input type="hidden" name="tags-token" id="tags-token" value="<?php echo $this->context->transport->tagsToken ?>"/>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($editPostPrivileges[Privilege::EditPostThumb]): ?>
|
||||
<div class="thumb">
|
||||
<label class="left" for="thumb">Thumb:</label>
|
||||
<input type="file" name="thumb" id="thumb"/>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<div>
|
||||
<label class="left"> </label>
|
||||
<button type="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
|
|
@ -40,6 +40,7 @@ function configFactory()
|
|||
|
||||
$config = configFactory();
|
||||
R::setup('sqlite:' . $config->main->dbPath);
|
||||
#R::dependencies(['tag' => ['post'], 'post' => ['user']]);
|
||||
|
||||
//wire models
|
||||
\Chibi\AutoLoader::init([$config->chibi->userCodeDir, __DIR__]);
|
||||
|
|
Loading…
Reference in a new issue