very big commit

This commit is contained in:
flash 2016-03-25 02:31:57 +01:00
parent a9bae24479
commit ac14ee2fab
14 changed files with 510 additions and 178 deletions

View file

@ -29,3 +29,6 @@ show_errors = true
; Show a small version of the changelog loaded from sakura.flash.moe
show_changelog = true
; Host for the mahou serve command
host = localhost:8000

View file

@ -8,6 +8,7 @@
namespace Sakura\Console\Command;
use CLIFramework\Command;
use Sakura\Config;
class ServeCommand extends Command
{
@ -18,6 +19,11 @@ class ServeCommand extends Command
public function execute()
{
exec(PHP_BINDIR . '/php -S localhost:8000 -t ' . addslashes(ROOT . 'public/') . ' ' . addslashes(ROOT . 'server.php'));
$document_root = addslashes(ROOT . 'public/');
$router_proxy = addslashes(ROOT . 'server.php');
$php_dir = PHP_BINDIR;
$host = Config::local('dev', 'host');
exec("{$php_dir}/php -S {$host} -t {$document_root} {$router_proxy}");
}
}

View file

@ -274,10 +274,7 @@ class ForumController extends Controller
$thread->viewsUpdate();
// Set parse variables
Template::vars([
'thread' => $thread,
'forum' => $forum,
]);
Template::vars(compact('forum', 'thread'));
// Print page contents
return Template::render('forum/viewtopic');
@ -463,4 +460,175 @@ class ForumController extends Controller
return header("Location: {$threadLink}#p{$post->id}");
}
public function threadReply($id = 0)
{
global $currentUser;
$text = isset($_POST['text']) ? $_POST['text'] : null;
// Attempt to get the forum
$thread = new Thread($id);
// And attempt to get the forum
$forum = new Forum($thread->forum);
// Check if the thread exists
if ($thread->id == 0
|| $forum->type !== 0
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id)
|| !$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');
Template::vars(['page' => compact('message', 'redirect')]);
return Template::render('global/information');
}
// Length
$length = strlen($text);
$minLen = Config::get('forum_text_min');
$maxLen = Config::get('forum_text_max');
$tooShort = $length < $minLen;
$tooLong = $length > $maxLen;
// Check requirments
if ($tooShort
|| $tooLong) {
$route = Router::route('forums.thread', $thread->id);
$message = "Your post is " . (
$tooShort
? "too short, add some more text!"
: "too long, you're gonna have to cut a little!"
);
$redirect = "{$route}#reply";
Template::vars(['page' => compact('message', 'redirect')]);
if (!isset($_SESSION['replyText'])) {
$_SESSION['replyText'] = [];
}
$_SESSION['replyText']["t{$thread->id}"] = $text;
return Template::render('global/information');
}
unset($_SESSION['replyText']["t{$thread->id}"]);
// Create the post
$post = Post::create(
"Re: {$thread->title}",
$text,
$currentUser,
$thread->id,
$forum->id
);
// Go to the post
$postLink = Router::route('forums.post', $post->id);
// Head to the post
return header("Location: {$postLink}");
}
public function createThread($id = 0)
{
global $currentUser;
$title = isset($_POST['title']) ? $_POST['title'] : null;
$text = isset($_POST['text']) ? $_POST['text'] : null;
// And attempt to get the forum
$forum = new Forum($id);
// Check if the forum exists
if ($forum->id === 0
|| $forum->type !== 0
|| !$forum->permission(ForumPerms::VIEW, $currentUser->id)
|| !$forum->permission(ForumPerms::REPLY, $currentUser->id)
|| !$forum->permission(ForumPerms::CREATE_THREADS, $currentUser->id)) {
$message = "This forum 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 ($text && $title) {
// 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 = $titleLength < $titleMin;
$titleTooLong = $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.new', $forum->id);
Template::vars(['page' => compact('message', 'redirect')]);
if (!isset($_SESSION['replyText'])) {
$_SESSION['replyText'] = [];
}
$_SESSION['replyText']["f{$forum->id}"]["title"] = $title;
$_SESSION['replyText']["f{$forum->id}"]["text"] = $text;
return Template::render('global/information');
}
unset($_SESSION['replyText']["f{$forum->id}"]);
// Create the post
$post = Post::create(
$title,
$text,
$currentUser,
0,
$forum->id
);
// Go to the post
$postLink = Router::route('forums.post', $post->id);
// Head to the post
return header("Location: {$postLink}");
}
Template::vars(compact('forum'));
return Template::render('forum/viewtopic');
}
}

View file

@ -0,0 +1,28 @@
<?php
/**
* Holds helpers for JavaScript.
*
* @package Sakura
*/
namespace Sakura\Controllers;
use Sakura\BBcode;
/**
* Helper controller.
*
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class HelperController extends Controller
{
public function bbcodeParse()
{
$text = isset($_POST['text']) ? $_POST['text'] : null;
$text = BBcode::toHTML($text);
return $text;
}
}

View file

@ -34,7 +34,10 @@ class MetaController extends Controller
'news' => new News(Config::get('site_news_category')),
'newsCount' => Config::get('front_page_news_posts'),
'stats' => [
'userCount' => DB::table('users')->where('password_algo', '!=', 'disabled')->whereNotIn('rank_main', [1, 10])->count(),
'userCount' => DB::table('users')
->where('password_algo', '!=', 'disabled')
->whereNotIn('rank_main', [1, 10])
->count(),
'newestUser' => User::construct(Users::getNewestUserId()),
'lastRegDate' => date_diff(
date_create(date('Y-m-d', User::construct(Users::getNewestUserId())->registered)),

View file

@ -150,14 +150,6 @@ class Post
*/
public static function create($subject, $text, User $poster, $thread = 0, $forum = 0)
{
// Check if the data meets the requirements
if (strlen($subject) < Config::get('forum_title_min')
|| strlen($subject) > Config::get('forum_title_max')
|| strlen($text) < Config::get('forum_text_min')
|| strlen($text) > Config::get('forum_text_max')) {
return null;
}
// If no thread is specified create a new one
if ($thread) {
$thread = new Thread($thread);

View file

@ -2256,50 +2256,51 @@ textarea.inputStyling {
vertical-align: middle;
}
.forum.posting .posting-subject {
.posting-subject {
padding: 3px 0 2px;
}
.forum.posting .posting-subject input {
.posting-subject input {
width: calc(100% - 10px);
}
.forum.posting .posting-bbcodes {
.posting-bbcodes {
padding: 4px 0 2px;
}
.forum.posting .posting-bbcode-description {
.posting-bbcode-description {
font: .9em/1.2em "SegoeUI", "Segoe UI", sans-serif;
padding: 2px 0 3px;
}
.forum.posting .posting-text {
.posting-text {
padding: 2px 0 0;
margin: 0 0 -1px;
}
.forum.posting .posting-emotes {
.posting-emotes {
text-align: center;
padding: 10px 0;
}
.forum.posting .posting-emotes img {
.posting-emotes img {
vertical-align: middle;
cursor: pointer;
margin: 0 3px;
}
.forum.posting .posting-text textarea {
width: calc(100% - 10px);
min-height: 300px;
.posting-text textarea {
min-width: calc(100% - 10px);
max-width: calc(100% - 10px);
min-height: 200px;
}
.forum.posting .posting-options > div {
.posting-options > div {
float: left;
padding: 10px 10px 0;
}
.forum.posting .posting-buttons {
.posting-buttons {
text-align: center;
}

View file

@ -30,7 +30,7 @@ if ($topicId) {
$forumId = isset($_GET['f']) ?
$_GET['f'] :
$thread->forum;
($topicId ? $thread->forum : 0);
// Creare forum class
$forum = new Forum($forumId);
@ -84,14 +84,6 @@ $mode = isset($_GET['f'])
)
);
$emotes = DB::table('emoticons')
->get();
// Include emotes and bbcodes
$posting = [
'emoticons' => $emotes,
];
// Check if we're in reply mode
if ($mode != 'f') {
// Attempt to get the topic
@ -129,22 +121,6 @@ if ($mode != 'f') {
// Print page contents
echo Template::render('global/information');
exit;
}
// Check if we're in quote mode
if ($mode == 'p'
&& isset($_GET['quote'])
&& $_GET['quote'] == $_GET['p']
&& array_key_exists($_GET['p'], $thread->posts())) {
// Reassign post for ease
$post = $thread->posts()[$_GET['p']];
// Add subject to render data
$quotedPost = BBcode::toEditor($post->text);
$posting['text'] = "[quote={$post->poster->username}]{$quotedPost}[/quote]";
// Post editing
} elseif ($mode == 'p'
&& isset($_GET['edit'])
&& $_GET['edit'] == $_GET['p']
@ -285,16 +261,13 @@ if ($mode != 'f') {
echo Template::render('global/confirm');
exit;
}
// Add subject to render data
if (!isset($posting['subject'])) {
$posting['subject'] = "Re: {$thread->title}";
}
}
// 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']);
@ -310,9 +283,6 @@ if (isset($_POST['post'])) {
} else {
$post = null;
}
} else {
// Attempt to make the post
$post = Post::create($_POST['subject'], $_POST['text'], $currentUser, $topicId, $forumId);
}
// Add page specific things
@ -337,13 +307,5 @@ if (isset($_POST['post'])) {
exit;
}
// Set additional render data
$renderData = array_merge($renderData, [
'posting' => $posting,
]);
// Set parse variables
Template::vars($renderData);
// Print page contents
echo Template::render('forum/posting');
$route = isset($thread) ? Router::route('forums.thread', $thread->id) : Router::route('forums.new', $forum->id);
header("Location: {$route}#reply");

View file

@ -36,7 +36,6 @@ Router::group(['prefix' => 'forum'], function () {
// Post
Router::group(['prefix' => 'post'], function () {
Router::get('/{id:i}', 'ForumController@post', 'forums.post');
Router::get('/{id:i}/reply', 'ForumController@postReply', 'forums.post.reply');
});
// Thread
@ -50,7 +49,8 @@ Router::group(['prefix' => 'forum'], function () {
Router::get('/', 'ForumController@index', 'forums.index');
Router::get('/{id:i}', 'ForumController@forum', 'forums.forum');
Router::get('/{id:i}/mark', 'ForumController@markForumRead', 'forums.mark');
Router::get('/{id:i}/new', 'ForumController@newThread', 'forums.new');
Router::get('/{id:i}/new', 'ForumController@createThread', 'forums.new');
Router::post('/{id:i}/new', 'ForumController@createThread', 'forums.new');
});
// Members
@ -73,6 +73,14 @@ Router::group(['prefix' => 'support'], function () {
Router::get('/tracker', 'PremiumController@tracker', 'premium.tracker');
});
// Helpers
Router::group(['prefix' => 'helper'], function () {
// BBcode
Router::group(['prefix' => 'bbcode'], function () {
Router::post('/parse', 'HelperController@bbcodeParse', 'helper.bbcode.parse');
});
});
// Settings
/*
* General

View file

@ -8,7 +8,7 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', 20160324);
define('SAKURA_VERSION', 20160325);
// Define Sakura Path
define('ROOT', __DIR__ . '/');
@ -156,6 +156,11 @@ if (!defined('SAKURA_NO_TPL')) {
'minPwdEntropy' => Config::get('min_entropy'),
'minUsernameLength' => Config::get('username_min_length'),
'maxUsernameLength' => Config::get('username_max_length'),
'forumTitleMaxLength' => Config::get('forum_title_max'),
'forumTitleMinLength' => Config::get('forum_title_min'),
'forumTextMaxLength' => Config::get('forum_text_max'),
'forumTextMinLength' => Config::get('forum_text_min'),
],
'php' => [
'sessionid' => \session_id(),
@ -163,17 +168,18 @@ if (!defined('SAKURA_NO_TPL')) {
'self' => $_SERVER['PHP_SELF'],
],
'session' => [
'session' => array_merge([
'checkLogin' => $authCheck,
'sessionId' => $authCheck[1],
'userId' => $authCheck[0],
],
], $_SESSION),
'user' => $currentUser,
'urls' => $urls,
'get' => $_GET,
'post' => $_POST,
'request' => $_REQUEST,
'server' => $_SERVER,
]);

View file

@ -1,17 +0,0 @@
{% extends 'global/master.twig' %}
{% set bbcode = {'b': ['Bold', 'bold'], 'i': ['Italic', 'italic'], 'u': ['Underline', 'underline'], 's': ['Strikethrough', 'strikethrough'], 'header': ['Header', 'header'], 'url': ['URL', 'chain'], 'code': ['Code', 'code'], 'spoiler': ['Spoiler', 'minus'], 'box': ['Spoiler box', 'folder', true], 'list': ['List', 'list-ul'], 'img': ['Image', 'picture-o'], 'youtube': ['YouTube video', 'youtube-play']} %}
{% set cancelTarget = 'history.go(-1);' %}
{% set editorFormId = 'forumPostingForm' %}
{% block title %}Posting{% endblock %}
{% block content %}
<div class="content">
<div class="content-column forum posting">
{% include 'elements/editor.twig' %}
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,132 @@
{% set bbcode = {
'b': ['Bold: [b]text[/b]', 'bold'],
'i': ['Italic: [i]text[/i]', 'italic'],
'u': ['Underline: [u]text[/u]', 'underline'],
's': ['Strikethrough: [s]text[/s]', 'strikethrough'],
'header': ['Header: [header]text[/header]', 'header'],
'url': ['URL: [url]link[/url] or [url=link]text[/url]', 'chain'],
'code': ['Code: [code]text[/code] (bbcodes inside this tag are ignored!)', 'code'],
'spoiler': ['Spoiler: [spoiler]text[/spoiler]', 'minus'],
'box': ['Spoiler box: [box]text[/box] or [box=title]text[/box]', 'folder', true],
'list': ['List: [list][*]item\r\n[*]another item[/list]', 'list-ul'],
'img': ['Image: [img]image link[/img], please use https instead of http if possible', 'picture-o'],
'youtube': ['YouTube video: [youtube]video id (in the link after ?v= up until the first &)[/youtube]', 'youtube-play']
} %}
<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-text">
<textarea class="inputStyling" name="text" id="postingText" placeholder="Hit ctrl+enter to submit quickly!"{% if titleCache is defined %} autofocus{% endif %}>{{ textCache }}</textarea>
</div>
<div class="posting-buttons">
<div style="float: left;">
{% 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="forumbtn{% if meta[1] %} fa fa-{{ meta[1] }}{% endif %}">{% if not meta[1] %}{{ code }}{% endif %}</button>
{% endfor %}
</div>
<div style="float: right;">
<button class="forumbtn fa fa-send" title="Reply"></button>
</div>
<div class="clear"></div>
</div>
</form>
</div>
<script type="text/javascript">
var titleMax = {{ sakura.forumTitleMaxLength }},
titleMin = {{ sakura.forumTitleMinLength }},
textMax = {{ sakura.forumTextMaxLength }},
textMin = {{ sakura.forumTextMinLength }},
preview = document.getElementById('postingPreview'),
pTitle = document.getElementById('postingTitle'),
pText = document.getElementById('postingText'),
pForm = document.getElementById('postingForm'),
tTitle = document.getElementById('threadTitle'),
rTitle = document.getElementById('previewTitle'),
rText = document.getElementById('previewText'),
lastParsed = Date.now(),
lastKeystroke = Date.now(),
parser = new AJAX(),
parserActive = false;
parser.setUrl("{{ route('helper.bbcode.parse') }}");
parser.contentType("application/x-www-form-urlencoded");
pText.addEventListener("focus", function () {
preview.style.display = null;
});
setInterval(function () {
if (lastParsed < Date.now() - 1000
&& lastKeystroke > Date.now() - 1000
&& parserActive !== true) {
lastParsed = Date.now();
var text = pText.value;
if (text.length == 0) {
rText.innerHTML = "";
} else if (text.length < textMin) {
rText.innerHTML = "<span style='color: red;'>Too short!</span>";
} else if (text.length > textMax) {
rText.innerHTML = "<span style='color: red;'>Too long!</span>";
} else {
parserActive = true;
parser.setSend({"text":text});
parser.addCallback(200, function () {
rText.innerHTML = parser.response();
var codeBlocks = rText.querySelectorAll("pre code");
for (var _i in codeBlocks) {
if ((typeof codeBlocks[_i]).toLowerCase() === 'object') {
hljs.highlightBlock(codeBlocks[_i]);
}
}
parserActive = false;
});
parser.start(HTTPMethods.POST);
}
}
}, 1000);
pText.addEventListener("keydown", function (e) {
lastKeystroke = Date.now();
if (e.keyCode == 13 && e.ctrlKey) {
pForm.submit();
}
});
{% if titleCache is defined %}
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;
}
tTitle.innerText = title;
rTitle.innerText = title;
});
{% endif %}
</script>

View file

@ -3,7 +3,7 @@
{% set title %}Forums / {{ forum.name }}{% endset %}
{% set forumBackLink %}{{ route('forums.index') }}{% endset %}
{% set forumNewLink %}{{ urls.format('FORUM_NEW_THREAD', [forum.id]) }}{% endset %}
{% set forumNewLink %}{{ route('forums.new', forum.id) }}{% endset %}
{% set forumMarkRead %}{{ route('forums.mark', forum.id) }}?s={{ php.sessionid }}{% endset %}
{% block title %}{{ title }}{% endblock %}

View file

@ -2,53 +2,57 @@
{% set forumBackLink %}{{ route('forums.forum', forum.id) }}{% endset %}
{% if thread.status != 1 or forum.permission(constant('Sakura\\Perms\\Forum::LOCK'), user.id) %}
{% set forumReplyLink %}{{ urls.format('FORUM_REPLY', [thread.id]) }}{% endset %}
{% endif %}
{% block title %}{% if thread is defined %}{{ thread.title }}{% else %}Creating thread in {{ forum.name }}{% endif %}{% endblock %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::STICKY'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::ANNOUNCEMENT'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::LOCK'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::MOVE'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::DELETE_ANY'), user.id) %}
{% set showMod = true %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::STICKY'), user.id) %}
{% set forumSticky = thread.type == 1 ? true : false %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::ANNOUNCEMENT'), user.id) %}
{% set forumAnnounce = thread.type == 2 ? true : false %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::LOCK'), user.id) %}
{% set forumLock = thread.status == 1 ? true : false %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::MOVE'), user.id) %}
{% if thread.oldForum %}
{% set forumRestore = true %}
{% if thread is defined %}
{% if 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 %}
{% if thread.forum != sakura.trashForumId %}
{% set forumTrash = true %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::STICKY'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::ANNOUNCEMENT'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::LOCK'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::MOVE'), user.id)
or forum.permission(constant('Sakura\\Perms\\Forum::DELETE_ANY'), user.id) %}
{% set showMod = true %}
{% endif %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::DELETE_ANY'), user.id) %}
{% if thread.forum == sakura.trashForumId %}
{% set forumPrune = true %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::STICKY'), user.id) %}
{% set forumSticky = thread.type == 1 ? true : false %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::ANNOUNCEMENT'), user.id) %}
{% set forumAnnounce = thread.type == 2 ? true : false %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::LOCK'), user.id) %}
{% set forumLock = thread.status == 1 ? true : false %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::MOVE'), user.id) %}
{% if thread.oldForum %}
{% set forumRestore = true %}
{% endif %}
{% if thread.forum != sakura.trashForumId %}
{% set forumTrash = true %}
{% endif %}
{% endif %}
{% if forum.permission(constant('Sakura\\Perms\\Forum::DELETE_ANY'), user.id) %}
{% if thread.forum == sakura.trashForumId %}
{% set forumPrune = true %}
{% endif %}
{% endif %}
{% set posts = thread.posts|batch(10) %}
{% set paginationPages = posts %}
{% set paginationUrl %}{{ route('forums.thread', thread.id) }}{% endset %}
{% endif %}
{% set posts = thread.posts|batch(10) %}
{% set paginationPages = posts %}
{% set paginationUrl %}{{ route('forums.thread', thread.id) }}{% endset %}
{% block title %}{{ thread.title }}{% endblock %}
{% block css %}
<link rel="stylesheet" href="{{ sakura.contentPath }}/libraries/highlight.css" />
{% endblock %}
@ -61,63 +65,99 @@
{% block content %}
<div class="content homepage forum viewtopic">
<div class="content-column">
<div class="head"><a href="{{ forumBackLink }}" class="clean">{{ forum.name }}</a> / <a href="{{ paginationUrl }}" class="clean">{{ thread.title }}</a></div>
<div class="head"><a href="{{ forumBackLink }}" class="clean">{{ forum.name }}</a> / <span id="threadTitle"><a href="{{ paginationUrl }}" class="clean">{{ thread.title }}</a></span></div>
{% include 'forum/forumBtns.twig' %}
<table class="posts">
{% for post in posts[get.page|default(1) - 1] %}
<tr class="post" id="p{{ post.id }}">
<td class="userpanel">
{% if not post.poster.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or post.poster.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) %}<a href="{{ route('user.profile', post.poster.id) }}" class="default username" style="color: {{ post.poster.colour }}; text-shadow: 0 0 5px {% if post.poster.colour != 'inherit' %}{{ post.poster.colour }}{% else %}#222{% endif %};" title="Go to {{ post.poster.username }}'s profile">{{ post.poster.username }}</a>
<img src="{{ route('file.avatar', post.poster.id) }}" alt="{{ post.poster.username }}" class="avatar" style="box-shadow: 0 3px 7px #{% if post.poster.isOnline %}484{% else %}844{% endif %};" />
{% else %}
<a class="username">[deleted user]</a>
{% endif %}
<div class="userdata">
<div class="usertitle">{{ post.poster.title }}</div>
<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi"{% if not post.poster.isPremium[0] %} style="opacity: 0;"{% endif %} /> <img src="{{ sakura.contentPath }}/images/flags/{{ post.poster.country|lower }}.png" alt="{{ post.poster.country(true) }}" />{% if post.poster.id == (thread.posts|first).poster.id %} <img src="{{ sakura.contentPath }}/images/op.png" alt="OP" title="Original Poster" />{% endif %}
{% 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>
{% 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>
{% 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 %}
<a class="fa fa-{% if user.isFriends(post.poster.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>
{% if thread is defined %}
{% set textCache = session.replyText['t' ~ thread.id] %}
{% set postingAction = route('forums.thread.reply', thread.id) %}
{% for post in posts[get.page|default(1) - 1] %}
<tr class="post" id="p{{ post.id }}">
<td class="userpanel">
{% if not post.poster.permission(constant('Sakura\\Perms\\Site::DEACTIVATED')) or post.poster.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) %}<a href="{{ route('user.profile', post.poster.id) }}" class="default username" style="color: {{ post.poster.colour }}; text-shadow: 0 0 5px {% if post.poster.colour != 'inherit' %}{{ post.poster.colour }}{% else %}#222{% endif %};" title="Go to {{ post.poster.username }}'s profile">{{ post.poster.username }}</a>
<img src="{{ route('file.avatar', post.poster.id) }}" alt="{{ post.poster.username }}" class="avatar" style="box-shadow: 0 3px 7px #{% if post.poster.isOnline %}484{% else %}844{% endif %};" />
{% else %}
<a class="username">[deleted user]</a>
{% endif %}
<div class="userdata">
<div class="usertitle">{{ post.poster.title }}</div>
<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi"{% if not post.poster.isPremium[0] %} style="opacity: 0;"{% endif %} /> <img src="{{ sakura.contentPath }}/images/flags/{{ post.poster.country|lower }}.png" alt="{{ post.poster.country(true) }}" />{% if post.poster.id == (thread.posts|first).poster.id %} <img src="{{ sakura.contentPath }}/images/op.png" alt="OP" title="Original Poster" />{% endif %}
{% 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>
{% endif %}
<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>
{% 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>
{% 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 %}
<a class="fa fa-{% if user.isFriends(post.poster.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>
{% endif %}
<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>
</div>
{% endif %}
<a class="fa fa-reply" title="Quote this post" href="{{ urls.format('FORUM_QUOTE_POST', [post.id]) }}"></a>
</div>
</td>
<td class="post-content">
<div class="details">
<div class="subject">
<a href="#p{{ post.id }}" class="clean">{{ post.subject|slice(0, 50) }}{% if post.subject|length > 50 %}...{% endif %}</a>
</div>
<div class="date">
<a href="{{ route('forums.post', post.id) }}" class="clean">#{{ post.id }} - <time>{{ post.time|date(sakura.dateFormat) }}</time></a>
</div>
<div class="clear"></div>
</div>
<div class="post-text bbcode">
{{ post.parsed|raw }}
</div>
{% if post.poster.signature and post.poster.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
<div class="clear"></div>
<div class="signature bbcode">
{{ post.poster.signature()|raw|nl2br }}
</div>
{% endif %}
</div>
</td>
<td class="post-content">
<div class="details">
<div class="subject">
<a href="#p{{ post.id }}" class="clean">{{ post.subject|slice(0, 50) }}{% if post.subject|length > 50 %}...{% endif %}</a>
</div>
<div class="date">
<a href="{{ route('forums.post', post.id) }}" class="clean">#{{ post.id }} - <time>{{ post.time|date(sakura.dateFormat) }}</time></a>
</div>
<div class="clear"></div>
</div>
<div class="post-text bbcode">
{{ post.parsed|raw }}
</div>
{% if post.poster.signature and post.poster.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
</td>
</tr>
{% endfor %}
{% else %}
{% set titleCache = session.replyText['f' ~ forum.id].title %}
{% 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">
{{ post.poster.signature()|raw|nl2br }}
{{ user.signature()|raw|nl2br }}
</div>
{% endif %}
</td>
</tr>
{% endfor %}
{% endif %}
</td>
</tr>
</table>
{% if forumReplyLink is defined or thread is not defined %}
{% include 'forum/replyForm.twig' %}
{% endif %}
{% include 'forum/forumBtns.twig' %}
</div>
</div>