only settings is left until fully router

This commit is contained in:
flash 2016-03-25 18:10:42 +01:00
parent ac14ee2fab
commit 95f431a7d4
16 changed files with 469 additions and 452 deletions

View file

@ -70,35 +70,28 @@ class BBcode
// Add the standard definitions
self::$bbcode->addCodeDefinitionSet(new DefaultCodeDefinitionSet());
// Header tag
$builder = new CodeDefinitionBuilder('header', '<h1>{param}</h1>');
self::$bbcode->addCodeDefinition($builder->build());
$simpleCodes = [
['header', '<h1>{param}</h1>'],
['s', '<del>{param}</del>'],
['spoiler', '<span class="spoiler">{param}</span>'],
['box', '<div class="spoiler-box-container">
<div class="spoiler-box-title" onclick="Sakura.toggleClass(this.parentNode.children[1], \'hidden\');">
Click to open</div><div class="spoiler-box-content hidden">{param}</div></div>', ],
['box', '<div class="spoiler-box-container"><div class="spoiler-box-title"
onclick="Sakura.toggleClass(this.parentNode.children[1], \'hidden\');">{option}</div>
<div class="spoiler-box-content hidden">{param}</div></div>', ],
['quote', '<blockquote><div class="quotee">Quote</div><div class="quote">{param}</div></blockquote>'],
];
// Strike tag
$builder = new CodeDefinitionBuilder('s', '<del>{param}</del>');
self::$bbcode->addCodeDefinition($builder->build());
foreach ($simpleCodes as $code) {
$builder = new CodeDefinitionBuilder($code[0], $code[1]);
// Spoiler tag
$builder = new CodeDefinitionBuilder('spoiler', '<span class="spoiler">{param}</span>');
self::$bbcode->addCodeDefinition($builder->build());
if (strstr($code[1], '{option}')) {
$builder->setUseOption(true);
}
// Box tag
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="Sakura.toggleClass(this.parentNode.children[1], \'hidden\');">Click to open</div><div class="spoiler-box-content hidden">{param}</div></div>');
self::$bbcode->addCodeDefinition($builder->build());
// Box tag
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="Sakura.toggleClass(this.parentNode.children[1], \'hidden\');">{option}</div><div class="spoiler-box-content hidden">{param}</div></div>');
$builder->setUseOption(true);
self::$bbcode->addCodeDefinition($builder->build());
// Quote tag
$builder = new CodeDefinitionBuilder('quote', '<blockquote><div class="quotee">Quote</div><div class="quote">{param}</div></blockquote>');
self::$bbcode->addCodeDefinition($builder->build());
// Quote tag
$builder = new CodeDefinitionBuilder('quote', '<blockquote><div class="quotee">{option} wrote</div><div class="quote">{param}</div></blockquote>');
$builder->setUseOption(true);
self::$bbcode->addCodeDefinition($builder->build());
self::$bbcode->addCodeDefinition($builder->build());
}
// Add special definitions (PHP files MUST have the same name as the definition class
foreach (glob(ROOT . 'libraries/BBcodeDefinitions/*.php') as $ext) {

View file

@ -0,0 +1,77 @@
<?php
/**
* Holds the forum post quoting bbcode class.
*
* @package Sakura
*/
namespace Sakura\BBcodeDefinitions;
use JBBCode\CodeDefinition;
use JBBCode\ElementNode;
use Sakura\Forum\Forum;
use Sakura\Forum\Post;
use Sakura\Perms\Forum as ForumPerms;
use Sakura\Router;
use Sakura\User;
/**
* Quote BBcode for JBBCode.
*
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class Quote extends CodeDefinition
{
/**
* Constructor.
*/
public function __construct()
{
parent::__construct();
$this->setTagName("quote");
$this->setUseOption(true);
$this->setParseContent(true);
}
/**
* Compiles the user bbcode to HTML
*
* @param ElementNode $el The JBBCode element node.
*
* @return string The compiled HTML.
*/
public function asHtml(ElementNode $el)
{
global $currentUser;
$attr = $el->getAttribute()['quote'];
if (substr($attr, 0, 1) === '#') {
$postId = substr($attr, 1);
$post = new Post($postId);
$forum = new Forum($post->forum);
if ($post->id !== 0
&& $forum->permission(ForumPerms::VIEW, $currentUser->id)) {
$postLink = Router::route('forums.post', $post->id);
$content = "<blockquote><div class='quotee'><a href='{$postLink}' style='color: inherit;'>"
. "<span style='color: {$post->poster->colour}'>"
. "{$post->poster->username}</span> wrote</a></div>"
. "<div class='quote'>{$post->parsed}</div></blockquote>";
return $content;
}
}
$content = "";
foreach ($el->getChildren() as $child) {
$content .= $child->getAsHTML();
}
return "<blockquote><div class='quotee'>{$attr} wrote</div>
<div class='quote'>{$content}</div></blockquote>";
}
}

View file

@ -67,7 +67,7 @@ class AuthController extends Controller
public function loginGet()
{
return Template::render('main/login');
return Template::render('auth/login');
}
public function loginPost()
@ -204,7 +204,7 @@ class AuthController extends Controller
]);
}
return Template::render('main/register');
return Template::render('auth/register');
}
public function registerPost()
@ -428,7 +428,7 @@ class AuthController extends Controller
public function reactivateGet()
{
return Template::render('main/reactivate');
return Template::render('auth/reactivate');
}
public function reactivatePost()
@ -500,7 +500,7 @@ class AuthController extends Controller
public function resetPasswordGet()
{
return Template::render('main/resetpassword');
return Template::render('auth/resetpassword');
}
public function resetPasswordPost()

View file

@ -12,6 +12,7 @@ use Sakura\DB;
use Sakura\Forum\Forum;
use Sakura\Forum\Post;
use Sakura\Forum\Thread;
use Sakura\Perms;
use Sakura\Perms\Forum as ForumPerms;
use Sakura\Router;
use Sakura\Template;
@ -428,16 +429,14 @@ class ForumController extends Controller
$forum = new Forum($thread->forum);
// Check if the forum exists
if ($post->id == 0 || $thread->id == 0 || !$forum->permission(ForumPerms::VIEW, $currentUser->id)) {
// Set render data
Template::vars([
'page' => [
'message' => 'This post doesn\'t exist or you don\'t have access to it!',
'redirect' => Router::route('forums.index'),
],
]);
if ($post->id == 0
|| $thread->id == 0
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id)) {
$message = "This post doesn't exist or you don't have access to it!";
$redirect = Router::route('forums.index');
Template::vars(['page' => compact('message', 'redirect')]);
// Print page contents
return Template::render('global/information');
}
@ -461,6 +460,29 @@ class ForumController extends Controller
return header("Location: {$threadLink}#p{$post->id}");
}
public function postRaw($id = 0)
{
global $currentUser;
// Attempt to get the post
$post = new Post($id);
// And attempt to get the forum
$thread = new Thread($post->thread);
// And attempt to get the forum
$forum = new Forum($thread->forum);
// Check if the forum exists
if ($post->id == 0
|| $thread->id == 0
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id)) {
return "";
}
return $post->text;
}
public function threadReply($id = 0)
{
global $currentUser;
@ -476,14 +498,23 @@ class ForumController extends Controller
// Check if the thread exists
if ($thread->id == 0
|| $forum->type !== 0
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id)
|| !$forum->permission(ForumPerms::REPLY, $currentUser->id)
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id)) {
$message = "This post doesn't exist or you don't have access to it!";
$redirect = Router::route('forums.index');
Template::vars(['page' => compact('message', 'redirect')]);
return Template::render('global/information');
}
// Check if the thread exists
if (!$forum->permission(ForumPerms::REPLY, $currentUser->id)
|| (
$thread->status === 1
&& !$forum->permission(ForumPerms::LOCK, $currentUser->id)
)) {
$message = "This post doesn't exist or you don't have access to it!";
$redirect = Router::route('forums.index');
$message = "You are not allowed to post in this thread!";
$redirect = Router::route('forums.thread', $thread->id);
Template::vars(['page' => compact('message', 'redirect')]);
@ -631,4 +662,202 @@ class ForumController extends Controller
return Template::render('forum/viewtopic');
}
public function editPost($id = 0)
{
global $currentUser;
$title = isset($_POST['title']) ? $_POST['title'] : null;
$text = isset($_POST['text']) ? $_POST['text'] : null;
// Attempt to get the post
$post = new Post($id);
// Attempt to get the thread
$thread = new Thread($post->thread);
// And attempt to get the forum
$forum = new Forum($thread->forum);
// Check permissions
$noAccess = $post->id == 0
|| $thread->id == 0
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id);
$noEdit = (
$post->poster->id === $currentUser->id
? !$currentUser->permission(ForumPerms::EDIT_OWN, Perms::FORUM)
: !$forum->permission(ForumPerms::EDIT_ANY, $currentUser->id)
) || (
$thread->status === 1
&& !$forum->permission(ForumPerms::LOCK, $currentUser->id)
);
// Check if the forum exists
if ($noAccess || $noEdit) {
if ($noDelete) {
$message = "You aren't allowed to edit posts in this thread!";
$redirect = Router::route('forums.post', $post->id);
} else {
$message = "This post doesn't exist or you don't have access to it!";
$redirect = Router::route('forums.index');
}
Template::vars(['page' => compact('message', 'redirect')]);
return Template::render('global/information');
}
// Length
$titleLength = strlen($title);
$textLength = strlen($text);
$titleMin = Config::get('forum_title_min');
$titleMax = Config::get('forum_title_max');
$textMin = Config::get('forum_text_min');
$textMax = Config::get('forum_text_max');
// Checks
$titleTooShort = $title !== null
&& $post->id === $thread->firstPost()->id
&& $titleLength < $titleMin;
$titleTooLong = $title !== null
&& $post->id === $thread->firstPost()->id
&& $titleLength > $titleMax;
$textTooShort = $textLength < $textMin;
$textTooLong = $textLength > $textMax;
// Check requirments
if ($titleTooShort
|| $titleTooLong
|| $textTooShort
|| $textTooLong) {
$message = "";
if ($titleTooShort) {
$message = "This title is too short!";
} elseif ($titleTooLong) {
$message = "This title is too long!";
} elseif ($textTooShort) {
$message = "Please make your post a little bit longer!";
} elseif ($textTooLong) {
$message = "Your post is too long, you're gonna have to cut a little!";
}
$redirect = Router::route('forums.post', $post->id);
Template::vars(['page' => compact('message', 'redirect')]);
if (!isset($_SESSION['replyText'])) {
$_SESSION['replyText'] = [];
}
$_SESSION['replyText']["t{$forum->id}"] = $text;
return Template::render('global/information');
}
unset($_SESSION['replyText']["t{$forum->id}"]);
if ($post->id !== $thread->firstPost()->id || $title === null) {
$title = "Re: {$thread->title}";
} else {
$thread->title = $title;
$thread->update();
}
// Create the post
$post->subject = $title;
$post->text = $text;
$post->editTime = time();
$post->editReason = '';
$post->editUser = $currentUser;
$post = $post->update();
// Go to the post
$postLink = Router::route('forums.post', $post->id);
// Head to the post
return header("Location: {$postLink}");
}
public function deletePost($id = 0)
{
global $currentUser;
$action = isset($_POST['yes']) && isset($_POST['sessionid'])
? $_POST['sessionid'] === session_id()
: null;
// Attempt to get the post
$post = new Post($id);
// And attempt to get the forum
$thread = new Thread($post->thread);
// And attempt to get the forum
$forum = new Forum($thread->forum);
// Check permissions
$noAccess = $post->id == 0
|| $thread->id == 0
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id);
$noDelete = (
$post->poster->id === $currentUser->id
? !$currentUser->permission(ForumPerms::DELETE_OWN, Perms::FORUM)
: !$forum->permission(ForumPerms::DELETE_ANY, $currentUser->id)
) || (
$thread->status === 1
&& !$forum->permission(ForumPerms::LOCK, $currentUser->id)
);
// Check if the forum exists
if ($noAccess || $noDelete) {
if ($noDelete) {
$message = "You aren't allowed to delete posts in this thread!";
$redirect = Router::route('forums.post', $post->id);
} else {
$message = "This post doesn't exist or you don't have access to it!";
$redirect = Router::route('forums.index');
}
Template::vars(['page' => compact('message', 'redirect')]);
return Template::render('global/information');
}
if ($action !== null) {
if ($action) {
// Set message
$message = "Deleted the post!";
// Check if the thread only has 1 post
if ($thread->replyCount() === 1) {
// Delete the entire thread
$thread->delete();
$redirect = Router::route('forums.forum', $forum->id);
} else {
// Just delete the post
$post->delete();
$redirect = Router::route('forums.thread', $thread->id);
}
Template::vars(['page' => compact('message', 'redirect')]);
return Template::render('global/information');
}
$postLink = Router::route('forums.post', $post->id);
return header("Location: {$postLink}");
}
$message = "Are you sure?";
Template::vars(compact('message'));
return Template::render('global/confirm');
}
}

View file

@ -1,311 +0,0 @@
<?php
/*
* Sakura Forum Posting
*/
// Declare Namespace
namespace Sakura;
use Sakura\Forum\Forum;
use Sakura\Forum\Post;
use Sakura\Forum\Thread;
use Sakura\Perms\Forum as ForumPerms;
// Include components
require_once '../sakura.php';
// Set location
$topicId = isset($_GET['t']) ?
$_GET['t'] :
(
isset($_GET['p']) ?
(new Post($_GET['p']))->thread :
0
);
// Get the topic
if ($topicId) {
$thread = new Thread($topicId);
}
$forumId = isset($_GET['f']) ?
$_GET['f'] :
($topicId ? $thread->forum : 0);
// Creare forum class
$forum = new Forum($forumId);
// Check if the user has access to the forum
if (!$forum->permission(ForumPerms::VIEW, $currentUser->id)
|| !$forum->permission(ForumPerms::REPLY, $currentUser->id)) {
// Set render data
$renderData['page'] = [
'title' => 'Information',
'message' => 'You do not have access to this forum.',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
}
// Check if the user has access to the forum
if (!isset($thread)
&& !$forum->permission(ForumPerms::CREATE_THREADS, $currentUser->id)) {
// Set render data
$renderData['page'] = [
'title' => 'Information',
'message' => 'You are not allowed to create threads in this forum.',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
}
$mode = isset($_GET['f'])
// New thread
? 'f'
: (
isset($_GET['t'])
// Reply to thread
? 't'
: (
isset($_GET['p'])
// Quoting a post
? 'p'
: null
)
);
// Check if we're in reply mode
if ($mode != 'f') {
// Attempt to get the topic
$thread = $thread ? $thread : new Thread($topicId);
// Prompt an error if the topic doesn't exist
if (!$thread->id) {
// Add page specific things
$renderData['page'] = [
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('forums.index')),
'message' => 'The requested post does not exist.',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
}
// Prompt an error if the topic doesn't exist
if ($thread->status == 1
&& !$forum->permission(ForumPerms::LOCK, $currentUser->id)) {
// Add page specific things
$renderData['page'] = [
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('forums.index')),
'message' => 'The thread you tried to reply to is locked.',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
} elseif ($mode == 'p'
&& isset($_GET['edit'])
&& $_GET['edit'] == $_GET['p']
&& array_key_exists($_GET['p'], $thread->posts())) {
// Permissions
if (!$currentUser->permission(ForumPerms::EDIT_OWN, Perms::FORUM)) {
// Add page specific things
$renderData['page'] = [
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('forums.index')),
'message' => 'You are not allowed to edit posts!',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
}
// Checks
if ($thread->posts()[$_GET['p']]->poster->id != $currentUser->id
&& !$forum->permission(ForumPerms::EDIT_ANY, $currentUser->id)) {
// Add page specific things
$renderData['page'] = [
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('forums.index')),
'message' => 'You can only edit your own posts!',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
}
// Reassign post for ease
$post = $thread->posts()[$_GET['p']];
// Set variables
$posting = array_merge($posting, [
'subject' => $post->subject,
'text' => BBcode::toEditor($post->text),
'id' => $post->id,
]);
// Post deletion
} elseif ($mode == 'p'
&& isset($_GET['delete'])
&& $_GET['delete'] == $_GET['p']
&& array_key_exists($_GET['p'], $thread->posts())) {
// Permissions
if (!$currentUser->permission(ForumPerms::DELETE_OWN, Perms::FORUM)) {
// Add page specific things
$renderData['page'] = [
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('forums.index')),
'message' => 'You are not allowed to delete posts!',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
}
// Checks
if ($thread->posts()[$_GET['p']]->poster->id != $currentUser->id
&& !$forum->permission(ForumPerms::DELETE_ANY, $currentUser->id)) {
// Add page specific things
$renderData['page'] = [
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Router::route('forums.index')),
'message' => 'You can only delete your own posts!',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
}
// Submit mode
if (isset($_POST['timestamp'], $_POST['sessionid'], $_POST['post_id'])) {
// Post deletion code
if (isset($_POST['yes'])) {
// Delete the post
DB::table('posts')
->where('post_id', $_POST['post_id'])
->delete();
// Reload the topic
$thread = new Thread($topicId);
// If there's no more posts left in the topic delete it as well
if (!$thread->replyCount()) {
DB::table('topics')
->where('topic_id', $thread->id)
->delete();
}
// Add page specific things
$renderData['page'] = [
'redirect' => ($thread->replyCount() ? Router::route('forums.thread', $thread->id) : Router::route('forums.index')),
'message' => 'Your post has been deleted!',
];
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
exit;
// Return to previous page
} else {
header('Location: ' . Router::route('forums.post', $_POST['post_id']));
exit;
}
}
// Form mode
$renderData = array_merge($renderData, [
'message' => "Are you sure you want to delete your reply to {$thread->title}?",
'conditions' => [
'post_id' => $thread->posts()[$_GET['p']]->id,
],
]);
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/confirm');
exit;
}
}
// Check if a post is being made
if (isset($_POST['post'])) {
// Check if an ID is set
$post = null;
if (isset($_POST['id'])) {
// Attempt to create a post object
$post = new Post($_POST['id']);
// Check if the post israel
if ($post->id == $_POST['id']) {
$post->subject = $_POST['subject'];
$post->text = $_POST['text'];
$post->editTime = time();
$post->editReason = '';
$post->editUser = $currentUser;
$post = $post->update();
} else {
$post = null;
}
}
// Add page specific things
$renderData['page'] = [ // Why does fail just kind of not redirect to anywhere
'redirect' => $post ? Router::route('forums.post', $post->id) : '',
'message' => $post ? 'Made the post!' : 'Something is wrong with your post!',
'success' => $post ? 1 : 0,
];
// Print page contents or if the AJAX request is set only display the render data
if (isset($_REQUEST['ajax'])) {
echo $renderData['page']['message'] . '|' .
$renderData['page']['success'] . '|' .
$renderData['page']['redirect'];
} else {
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('global/information');
}
exit;
}
$route = isset($thread) ? Router::route('forums.thread', $thread->id) : Router::route('forums.new', $forum->id);
header("Location: {$route}#reply");

View file

@ -36,6 +36,10 @@ Router::group(['prefix' => 'forum'], function () {
// Post
Router::group(['prefix' => 'post'], function () {
Router::get('/{id:i}', 'ForumController@post', 'forums.post');
Router::get('/{id:i}/raw', 'ForumController@postRaw', 'forums.post.raw');
Router::get('/{id:i}/delete', 'ForumController@deletePost', 'forums.post.delete');
Router::post('/{id:i}/delete', 'ForumController@deletePost', 'forums.post.delete');
Router::post('/{id:i}/edit', 'ForumController@editPost', 'forums.post.edit');
});
// Thread

View file

@ -4,7 +4,7 @@
{% if forum.forums|length %}
<div class="forumCategory">
<div class="forumCategoryHead">
<div class="forumCategoryTitle">{% if forum.type != 1 %}Subforums{% else %}<a href="{{ urls.format('FORUM_SUB', [forum.id]) }}">{{ forum.name }}</a>{% endif %}</div>
<div class="forumCategoryTitle">{% if forum.type != 1 %}Subforums{% else %}<a href="{{ route('forums.forum', forum.id) }}">{{ forum.name }}</a>{% endif %}</div>
<div class="forumCategoryDescription">{{ forum.description }}</div>
</div>
{% for forum in forum.forums %}

View file

@ -30,10 +30,12 @@
<input class="inputStyling" name="remember" type="checkbox" class="ignore-css" id="loginRemember" /><label for="loginRemember">Remember Me</a>
</div>
<div class="centreAlign">
<input class="inputStyling" type="submit" id="loginButton" name="submit" value="Login" />
<button class="inputStyling" id="loginButton"><i class="fa fa-sign-in"></i> Login</button>
</div>
<div class="subLinks centreAlign">
future links to password forgot, reactivate and register here
<div class="subLinks centreAlign" style="line-height: 1.5em;">
<p><a href="{{ route('auth.register') }}" class="default">I don't have an account yet!</a></p>
<p><a href="{{ route('auth.resetpassword') }}" class="default">I forgot my password!</a></p>
<p><a href="{{ route('auth.reactivate') }}" class="default">I want to reactivate my account!</a></p>
</div>
</form>
</div>

View file

@ -10,7 +10,7 @@
{% else %}
<li><a href="{{ urls.format('USER_REPORT', [comment.comment_poster.id]) }}" class="clean fa fa-exclamation-circle" title="Report" id="comment-action-report-{{ comment.comment_id }}"></a></li>
{% endif %}
<li><a href="javascript:void(0);" onclick="commentReply({{ comment.comment_id }}, '{{ php.sessionid }}', '{{ comment.comment_category }}', '{{ urls.format('COMMENT_POST') }}', '{{ urls.format('IMAGE_AVATAR', [user.id]) }}');" class="clean fa fa-reply" title="Reply" id="comment-action-reply-{{ comment.comment_id }}"></a></li>
<li><a href="javascript:void(0);" onclick="commentReply({{ comment.comment_id }}, '{{ php.sessionid }}', '{{ comment.comment_category }}', '{{ urls.format('COMMENT_POST') }}', '{{ route('file.avatar', user.id) }}');" class="clean fa fa-reply" title="Reply" id="comment-action-reply-{{ comment.comment_id }}"></a></li>
<li class="shown voting like"><a href="{{ urls.format('COMMENT_VOTE', [comment.comment_id, 1, comment.comment_category, php.sessionid])}}" class="clean comment-like-link" id="comment-action-like-{{ comment.comment_id }}"><span class="fa fa-thumbs-up"></span> <span id="comment-{{ comment.comment_id }}-likes">{{ comment.comment_likes }}</span></a></li>
<li class="shown voting dislike"><a id="comment-action-dislike-{{ comment.comment_id }}" href="{{ urls.format('COMMENT_VOTE', [comment.comment_id, 0, comment.comment_category, php.sessionid])}}" class="clean comment-dislike-link"><span class="fa fa-thumbs-down"></span> <span id="comment-{{ comment.comment_id }}-dislikes">{{ comment.comment_dislikes }}</span></a></li>
</ul>

View file

@ -1,37 +0,0 @@
<form id="{{ editorFormId }}" method="post" action="{{ sakura.currentPage }}">
<div class="head">Forum / Posting</div>
<div class="posting-subject">
<input type="text" class="inputStyling" name="subject" placeholder="Subject" value="{{ posting.subject }}" />
</div>
<hr class="default" />
<div class="posting-bbcodes">
{% for code,meta in bbcode %}
<button onclick="insertBBcode('postingText', '{{ code }}'{% if meta[2] %}, true{% endif %});" type="button"{% if meta[0] %} title="{{ meta[0] }}"{% endif %} class="inputStyling{% if meta[1] %} fa fa-{{ meta[1] }}{% endif %}" style="min-width: 0;">{% if not meta[1] %}{{ code }}{% endif %}</button>
{% endfor %}
</div>
<hr class="default" />
<div class="posting-text">
<textarea class="inputStyling" name="text" id="postingText">{{ posting.text }}</textarea>
</div>
<hr class="default" />
<div class="posting-emotes">
{% for emoticon in posting.emoticons %}
<img src="{{ emoticon.emote_path }}" alt="{{ emoticon.emote_string }}" title="{{ emoticon.emote_string }}" onclick="insertText('postingText', '{{ emoticon.emote_string }}')" />
{% endfor %}
</div>
<hr class="default" />
<div class="posting-buttons">
<input class="inputStyling" type="submit" name="post" value="Post" />
<input class="inputStyling" type="button" onclick="{{ cancelTarget }}" value="Cancel" />
</div>
{% if posting.id %}
<input type="hidden" name="id" value="{{ posting.id }}" />
{% endif %}
<input type="hidden" name="sessionid" value="{{ php.sessionid }}" />
<input type="hidden" name="timestamp" value="{{ php.time }}" />
<script type="text/javascript">
window.addEventListener("load", function() {
prepareAjaxForm('{{ editorFormId }}', 'Making post...');
});
</script>
</form>

View file

@ -15,11 +15,9 @@
<div id="reply">
<form id="postingForm" method="post" action="{{ postingAction }}">
{% if titleCache is defined %}
<div class="posting-subject">
<input type="text" class="inputStyling" name="title" id="postingTitle" placeholder="Title" value="{{ titleCache }}" />
</div>
{% endif %}
<div class="posting-subject" id="postingTitleContainer"{% if titleCache is not defined %} style="display: none;"{% endif %}>
<input type="text" class="inputStyling" name="title" id="postingTitle" placeholder="Title" value="{{ titleCache is defined ? titleCache : '' }}" />
</div>
<div class="posting-text">
<textarea class="inputStyling" name="text" id="postingText" placeholder="Hit ctrl+enter to submit quickly!"{% if titleCache is defined %} autofocus{% endif %}>{{ textCache }}</textarea>
</div>
@ -30,6 +28,7 @@
{% endfor %}
</div>
<div style="float: right;">
<button class="forumbtn fa fa-remove" title="Stop editing" style="display: none;" type="button" onclick="stopEdit();" id="postingStopEditing"></button>
<button class="forumbtn fa fa-send" title="Reply"></button>
</div>
<div class="clear"></div>
@ -44,15 +43,21 @@
textMin = {{ sakura.forumTextMinLength }},
preview = document.getElementById('postingPreview'),
pTitle = document.getElementById('postingTitle'),
pTitleCont = document.getElementById('postingTitleContainer'),
pText = document.getElementById('postingText'),
pForm = document.getElementById('postingForm'),
pStopEdit = document.getElementById('postingStopEditing'),
pMode = document.getElementById('previewMode'),
tTitle = document.getElementById('threadTitle'),
rTitle = document.getElementById('previewTitle'),
rText = document.getElementById('previewText'),
lastParsed = Date.now(),
lastKeystroke = Date.now(),
parser = new AJAX(),
parserActive = false;
postFetch = new AJAX(),
parserActive = false,
op = {{ thread is defined ? thread.firstPost.id : 0 }},
threadName = "{{ thread is defined ? thread.firstPost.subject : '' }}";
parser.setUrl("{{ route('helper.bbcode.parse') }}");
parser.contentType("application/x-www-form-urlencoded");
@ -61,6 +66,12 @@
preview.style.display = null;
});
pText.addEventListener("blur", function () {
if (op && pText.value.length < 1) {
preview.style.display = 'none';
}
});
setInterval(function () {
if (lastParsed < Date.now() - 1000
&& lastKeystroke > Date.now() - 1000
@ -102,31 +113,74 @@
pText.addEventListener("keydown", function (e) {
lastKeystroke = Date.now();
if (e.keyCode == 9) {
e.preventDefault();
insertText('postingText', ' ');
}
if (e.keyCode == 13 && e.ctrlKey) {
pForm.submit();
}
});
{% if titleCache is defined %}
pTitle.addEventListener("keyup", function (e) {
var title = pTitle.value;
pTitle.addEventListener("keyup", function (e) {
var title = pTitle.value;
if (title.length == 0) {
title = "";
} else if (title.length < titleMin) {
title = "<span style='color: red;'>Too short!</span>";
tTitle.innerHTML = title;
rTitle.innerHTML = title;
return;
} else if (title.length > titleMax) {
title = "<span style='color: red;'>Too long!</span>";
tTitle.innerHTML = title;
rTitle.innerHTML = title;
return;
if (title.length == 0) {
title = "";
} else if (title.length < titleMin) {
title = "<span style='color: red;'>Too short!</span>";
tTitle.innerHTML = title;
rTitle.innerHTML = title;
return;
} else if (title.length > titleMax) {
title = "<span style='color: red;'>Too long!</span>";
tTitle.innerHTML = title;
rTitle.innerHTML = title;
return;
}
tTitle.innerText = title;
rTitle.innerText = title;
});
function quotePost(id) {
pText.value = pText.value + "[quote=#" + id + "][/quote]";
pText.focus();
}
function editPost(id) {
pText.disabled = true;
pTitleCont.style.display = 'none';
rTitle.innerText = 'Re: ' + threadName;
url = "{{ route('forums.post.raw', '1') }}".replace('1', id);
postFetch.setUrl(url);
postFetch.addCallback(200, function () {
pText.value = postFetch.response();
pStopEdit.style.display = null;
pForm.action = "{{ route('forums.post.edit', '1') }}".replace('1', id);
pMode.innerText = 'Editing #' + id;
if (id === op) {
pTitleCont.style.display = null;
pTitle.value = threadName;
rTitle.innerText = threadName;
}
tTitle.innerText = title;
rTitle.innerText = title;
pText.disabled = false;
pText.focus();
});
{% endif %}
postFetch.start(HTTPMethods.GET);
}
function stopEdit() {
pText.value = "";
pForm.action = "{{ postingAction }}";
pStopEdit.style.display = 'none';
pTitleCont.style.display = 'none';
pMode.innerText = 'Preview';
preview.style.display = 'none';
}
</script>

View file

@ -5,9 +5,11 @@
{% block title %}{% if thread is defined %}{{ thread.title }}{% else %}Creating thread in {{ forum.name }}{% endif %}{% endblock %}
{% if thread is defined %}
{% if thread.status != 1
{% if forum.permission(constant('Sakura\\Perms\\Forum::REPLY'), user.id)
and (
thread.status != 1
or forum.permission(constant('Sakura\\Perms\\Forum::LOCK'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::REPLY')) %}
) %}
{% set forumReplyLink %}#reply{% endset %}
{% endif %}
@ -59,13 +61,15 @@
{% block js %}
<script src="{{ sakura.contentPath }}/libraries/highlight.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
hljs.initHighlightingOnLoad();
</script>
{% endblock %}
{% block content %}
<div class="content homepage forum viewtopic">
<div class="content-column">
<div class="head"><a href="{{ forumBackLink }}" class="clean">{{ forum.name }}</a> / <span id="threadTitle"><a href="{{ paginationUrl }}" class="clean">{{ thread.title }}</a></span></div>
<div class="head">{{ forum.name }} / <span id="threadTitle">{{ thread.title }}</span></div>
{% include 'forum/forumBtns.twig' %}
<table class="posts">
{% if thread is defined %}
@ -86,10 +90,10 @@
{% if session.checkLogin %}
<div class="actions">
{% if (user.id == post.poster.id and forum.permission(constant('Sakura\\Perms\\Forum::EDIT_OWN'), user.id)) or forum.permission(constant('Sakura\\Perms\\Forum::EDIT_ANY'), user.id) %}
<a class="fa fa-pencil-square-o" title="Edit this post" href="{{ urls.format('FORUM_EDIT_POST', [post.id]) }}"></a>
<a class="fa fa-pencil-square-o" title="Edit this post" href="javascript:void(0);" onclick="editPost({{ post.id }});"></a>
{% endif %}
{% if (user.id == post.poster.id and forum.permission(constant('Sakura\\Perms\\Forum::DELETE_OWN'), user.id)) or forum.permission(constant('Sakura\\Perms\\Forum::DELETE_ANY'), user.id) %}
<a class="fa fa-trash" title="Delete this post" href="{{ urls.format('FORUM_DELETE_POST', [post.id]) }}"></a>
<a class="fa fa-trash" title="Delete this post" href="{{ route('forums.post.delete', post.id) }}"></a>
{% endif %}
{% if not (post.poster.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or post.poster.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) or user.id == post.poster.id) %}
{% if user.isFriends(post.poster.id) != 0 %}
@ -98,7 +102,7 @@
<a class="fa fa-user-{% if user.isFriends(post.poster.id) == 0 %}plus{% else %}times{% endif %} forum-friend-toggle" title="{% if user.isFriends(post.poster.id) == 0 %}Add {{ post.poster.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if user.isFriends(post.poster.id) == 0 %}{{ urls.format('FRIEND_ADD', [post.poster.id, php.sessionid, php.time, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [post.poster.id, php.sessionid, php.time, sakura.currentPage]) }}{% endif %}"></a>
<a class="fa fa-flag" title="Report {{ post.poster.username }}" href="{{ urls.format('USER_REPORT', [post.poster.id]) }}"></a>
{% endif %}
<a class="fa fa-reply" title="Quote this post" href="{{ urls.format('FORUM_QUOTE_POST', [post.id]) }}"></a>
<a class="fa fa-reply" title="Quote this post" href="javascript:void(0);" onclick="quotePost({{ post.id }});"></a>
</div>
{% endif %}
</div>
@ -130,30 +134,32 @@
{% set textCache = session.replyText['f' ~ forum.id].text %}
{% set postingAction = route('forums.new', forum.id) %}
{% endif %}
<tr class="post" id="postingPreview" style="display: none;">
<td class="userpanel">
<a class="default username" href="{{ route('user.profile', user.id) }}" style="color: {{ user.colour }}; text-shadow: 0 0 5px {% if user.colour != 'inherit' %}{{ user.colour }}{% else %}#222{% endif %};" title="Go to {{ user.username }}'s profile">{{ user.username }}</a>
<img src="{{ route('file.avatar', user.id) }}" alt="{{ user.username }}" class="avatar" style="box-shadow: 0 3px 7px #484;" />
<div class="userdata">
<div class="usertitle">{{ user.title }}</div>
<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi"{% if not user.isPremium[0] %} style="opacity: 0;"{% endif %} /> <img src="{{ sakura.contentPath }}/images/flags/{{ user.country|lower }}.png" alt="{{ user.country(true) }}" />{% if user.id == (thread.posts|first).poster.id %} <img src="{{ sakura.contentPath }}/images/op.png" alt="OP" title="Original Poster" />{% endif %}
</div>
</td>
<td class="post-content">
<div class="details">
<div class="subject" id="previewTitle">{% if titleCache is not defined %}Re: {{ thread.title }}{% endif %}</div>
<div class="date">Preview</div>
<div class="clear"></div>
</div>
<div class="post-text bbcode" id="previewText"></div>
{% if user.signature and user.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
<div class="clear"></div>
<div class="signature bbcode">
{{ user.signature()|raw|nl2br }}
{% if forumReplyLink is defined or thread is not defined %}
<tr class="post" id="postingPreview" style="display: none;">
<td class="userpanel">
<a class="default username" href="{{ route('user.profile', user.id) }}" style="color: {{ user.colour }}; text-shadow: 0 0 5px {% if user.colour != 'inherit' %}{{ user.colour }}{% else %}#222{% endif %};" title="Go to {{ user.username }}'s profile">{{ user.username }}</a>
<img src="{{ route('file.avatar', user.id) }}" alt="{{ user.username }}" class="avatar" style="box-shadow: 0 3px 7px #484;" />
<div class="userdata">
<div class="usertitle">{{ user.title }}</div>
<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi"{% if not user.isPremium[0] %} style="opacity: 0;"{% endif %} /> <img src="{{ sakura.contentPath }}/images/flags/{{ user.country|lower }}.png" alt="{{ user.country(true) }}" />{% if user.id == (thread.posts|first).poster.id %} <img src="{{ sakura.contentPath }}/images/op.png" alt="OP" title="Original Poster" />{% endif %}
</div>
{% endif %}
</td>
</tr>
</td>
<td class="post-content">
<div class="details">
<div class="subject" id="previewTitle">{% if titleCache is not defined %}Re: {{ thread.title }}{% endif %}</div>
<div class="date" id="previewMode">Preview</div>
<div class="clear"></div>
</div>
<div class="post-text bbcode" id="previewText"></div>
{% if user.signature and user.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
<div class="clear"></div>
<div class="signature bbcode">
{{ user.signature()|raw|nl2br }}
</div>
{% endif %}
</td>
</tr>
{% endif %}
</table>
{% if forumReplyLink is defined or thread is not defined %}
{% include 'forum/replyForm.twig' %}

View file

@ -151,7 +151,7 @@
<noscript>
<div class="headerNotify">
<h1>You have JavaScript disabled!</h1>
<div>A lot of things on this site require JavaScript to be enabled (e.g. the chat), we try to keep both sides happy but it is highly recommended that you enable it (you'll also have to deal with this message being here if you don't enable it).</div>
<div>A lot of things are not going to work without it so I recommend you turn it on or use a capable browser.</div>
</div>
</noscript>