bbcode parser
This commit is contained in:
parent
4b39806756
commit
5286eff072
27 changed files with 239 additions and 148 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -19,3 +19,7 @@ $RECYCLE.BIN/
|
|||
# Compiled/copied assets
|
||||
/public/js
|
||||
/public/css
|
||||
|
||||
# User assets
|
||||
/uploads/*
|
||||
!/uploads/.gitkeep
|
||||
|
|
236
app/BBcode.php
236
app/BBcode.php
|
@ -16,25 +16,133 @@ namespace Sakura;
|
|||
class BBcode
|
||||
{
|
||||
/**
|
||||
* BBcodes, also for backwards compatibility.
|
||||
* Holds the bbcode parsers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $bbcodes = [];
|
||||
|
||||
/**
|
||||
* Initialiser.
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
}
|
||||
public static $parsers = [
|
||||
'bold' => [
|
||||
'pattern' => '/\[b\](.*?)\[\/b\]/s',
|
||||
'replace' => '<b>$1</b>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'italic' => [
|
||||
'pattern' => '/\[i\](.*?)\[\/i\]/s',
|
||||
'replace' => '<i>$1</i>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'underline' => [
|
||||
'pattern' => '/\[u\](.*?)\[\/u\]/s',
|
||||
'replace' => '<u>$1</u>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'linethrough' => [
|
||||
'pattern' => '/\[s\](.*?)\[\/s\]/s',
|
||||
'replace' => '<del>$1</del>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'header' => [
|
||||
'pattern' => '/\[header\](.*?)\[\/header\]/s',
|
||||
'replace' => '<h1>$1</h1>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'size' => [
|
||||
'pattern' => '/\[size\=([1-7])\](.*?)\[\/size\]/s',
|
||||
'replace' => '<font size="$1">$2</font>',
|
||||
'content' => '$2',
|
||||
],
|
||||
'color' => [
|
||||
'pattern' => '/\[color\=(#[A-f0-9]{6}|#[A-f0-9]{3})\](.*?)\[\/color\]/s',
|
||||
'replace' => '<span style="color: $1">$2</span>',
|
||||
'content' => '$2',
|
||||
],
|
||||
'center' => [
|
||||
'pattern' => '/\[center\](.*?)\[\/center\]/s',
|
||||
'replace' => '<div style="text-align: center;">$1</div>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'left' => [
|
||||
'pattern' => '/\[left\](.*?)\[\/left\]/s',
|
||||
'replace' => '<div style="text-align: left;">$1</div>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'right' => [
|
||||
'pattern' => '/\[right\](.*?)\[\/right\]/s',
|
||||
'replace' => '<div style="text-align: right;">$1</div>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'align' => [
|
||||
'pattern' => '/\[align\=(left|center|right)\](.*?)\[\/align\]/s',
|
||||
'replace' => '<div style="text-align: $1;">$2</div>',
|
||||
'content' => '$2',
|
||||
],
|
||||
'quote' => [
|
||||
'pattern' => '/\[quote\](.*?)\[\/quote\]/s',
|
||||
'replace' => '<blockquote>$1</blockquote>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'namedquote' => [
|
||||
'pattern' => '/\[quote\=(.*?)\](.*)\[\/quote\]/s',
|
||||
'replace' => '<blockquote><small>$1</small>$2</blockquote>',
|
||||
'content' => '$2',
|
||||
],
|
||||
'link' => [
|
||||
'pattern' => '/\[url\](.*?)\[\/url\]/s',
|
||||
'replace' => '<a href="$1">$1</a>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'namedlink' => [
|
||||
'pattern' => '/\[url\=(.*?)\](.*?)\[\/url\]/s',
|
||||
'replace' => '<a href="$1">$2</a>',
|
||||
'content' => '$2',
|
||||
],
|
||||
'image' => [
|
||||
'pattern' => '/\[img\](.*?)\[\/img\]/s',
|
||||
'replace' => '<img src="$1" alt="$1">',
|
||||
'content' => '$1',
|
||||
],
|
||||
'orderedlistnumerical' => [
|
||||
'pattern' => '/\[list=1\](.*?)\[\/list\]/s',
|
||||
'replace' => '<ol>$1</ol>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'orderedlistalpha' => [
|
||||
'pattern' => '/\[list=a\](.*?)\[\/list\]/s',
|
||||
'replace' => '<ol type="a">$1</ol>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'unorderedlist' => [
|
||||
'pattern' => '/\[list\](.*?)\[\/list\]/s',
|
||||
'replace' => '<ul>$1</ul>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'listitem' => [
|
||||
'pattern' => '/\[\*\](.*)/',
|
||||
'replace' => '<li>$1</li>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'code' => [
|
||||
'pattern' => '/\[code\](.*?)\[\/code\]/s',
|
||||
'replace' => '<pre><code>$1</code></pre>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'youtube' => [
|
||||
'pattern' => '/\[youtube\](.*?)\[\/youtube\]/s',
|
||||
'replace' => '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/$1" frameborder="0" allowfullscreen></iframe>',
|
||||
'content' => '$1',
|
||||
],
|
||||
'linebreak' => [
|
||||
'pattern' => '/\r\n|\r|\n/',
|
||||
'replace' => '<br>',
|
||||
'content' => '',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Parse the emoticons.
|
||||
*
|
||||
* @param string $text String to parse emoticons from.
|
||||
*
|
||||
* @return string Parsed text.
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public static function parseEmoticons($text)
|
||||
{
|
||||
|
@ -46,115 +154,27 @@ class BBcode
|
|||
foreach ($emotes as $emote) {
|
||||
$image = "<img src='{$emote->emote_path}' alt='{$emote->emote_string}' class='emoticon'>";
|
||||
$icon = preg_quote($emote->emote_string, '#');
|
||||
$text = preg_replace("#$icon#", $image, $text);
|
||||
$text = preg_replace("#{$icon}#", $image, $text);
|
||||
}
|
||||
|
||||
// Return the parsed text
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text to parse.
|
||||
*
|
||||
* @param string $text The text that should be parsed.
|
||||
*/
|
||||
public static function text($text)
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the parsed text to HTML.
|
||||
*
|
||||
* @param string $text The text that should be parsed.
|
||||
*
|
||||
* @return string The parsed HTML.
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public static function toHTML($text = null)
|
||||
public static function toHTML($text)
|
||||
{
|
||||
// // Check if text isn't null
|
||||
// if ($text !== null) {
|
||||
// self::text($text);
|
||||
// }
|
||||
$text = self::parseEmoticons($text);
|
||||
|
||||
// $parsed = nl2br(self::$bbcode->getAsHtml());
|
||||
|
||||
// $parsed = self::fixCodeTags($parsed);
|
||||
// $parsed = self::parseEmoticons($parsed);
|
||||
|
||||
// return $parsed;
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the parsed text to BBCode.
|
||||
*
|
||||
* @param string $text The text that should be parsed.
|
||||
*
|
||||
* @return string The converted bbcode.
|
||||
*/
|
||||
public static function toEditor($text = null)
|
||||
{
|
||||
// // Check if text isn't null
|
||||
// if ($text !== null) {
|
||||
// self::text($text);
|
||||
// }
|
||||
|
||||
// return self::$bbcode->getAsBBCode();
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the parsed text to plain.
|
||||
*
|
||||
* @param string $text The text that should be parsed.
|
||||
*
|
||||
* @return string The converted plaintext.
|
||||
*/
|
||||
public static function toPlain($text = null)
|
||||
{
|
||||
// // Check if text isn't null
|
||||
// if ($text !== null) {
|
||||
// self::text($text);
|
||||
// }
|
||||
|
||||
// return self::$bbcode->getAsText();
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the contents of <code> tags.
|
||||
* See if this can be deprecated with a custom implementation!
|
||||
*
|
||||
* @param string $text Dirty
|
||||
*
|
||||
* @return string Clean
|
||||
*/
|
||||
public static function fixCodeTags($text)
|
||||
{
|
||||
$parts = explode('<code>', $text);
|
||||
$newStr = '';
|
||||
|
||||
if (count($parts) > 1) {
|
||||
foreach ($parts as $p) {
|
||||
$parts2 = explode('</code>', $p);
|
||||
if (count($parts2) > 1) {
|
||||
$code = str_replace('<br />', '', $parts2[0]);
|
||||
$code = str_replace('<br/>', '', $code);
|
||||
$code = str_replace('<br>', '', $code);
|
||||
$code = str_replace('<', '<', $code);
|
||||
$newStr .= '<code>' . $code . '</code>';
|
||||
$newStr .= $parts2[1];
|
||||
} else {
|
||||
$newStr .= $p;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$newStr = $text;
|
||||
foreach (self::$parsers as $parser) {
|
||||
$text = preg_replace($parser['pattern'], $parser['replace'], $text);
|
||||
}
|
||||
|
||||
return $newStr;
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ class AppearanceController extends Controller
|
|||
$userId = ActiveUser::$user->id;
|
||||
$ext = image_type_to_extension($meta[2]);
|
||||
|
||||
$filename = "{$mode}_{$userId}.{$ext}";
|
||||
$filename = "{$mode}_{$userId}{$ext}";
|
||||
|
||||
// Create the file
|
||||
$file = File::create(file_get_contents($tmpName), $filename, ActiveUser::$user);
|
||||
|
@ -106,7 +106,11 @@ class AppearanceController extends Controller
|
|||
|
||||
public function deleteFile($mode)
|
||||
{
|
||||
(new File(ActiveUser::$user->{$mode}))->delete();
|
||||
$fileId = ActiveUser::$user->{$mode};
|
||||
|
||||
if ($fileId) {
|
||||
(new File($fileId))->delete();
|
||||
}
|
||||
}
|
||||
|
||||
public function avatar()
|
||||
|
|
|
@ -84,13 +84,15 @@ class File
|
|||
$id = DB::table('uploads')
|
||||
->insertGetId([
|
||||
'user_id' => $user->id,
|
||||
'file_data' => $data,
|
||||
'file_name' => $name,
|
||||
'file_mime' => $mime,
|
||||
'file_time' => time(),
|
||||
'file_expire' => $expire,
|
||||
]);
|
||||
|
||||
// Save the file data
|
||||
file_put_contents(config('file.uploads_dir') . $id . ".bin", $data);
|
||||
|
||||
// Return a new File object
|
||||
return new File($id);
|
||||
}
|
||||
|
@ -112,7 +114,7 @@ class File
|
|||
$fileRow = $fileRow[0];
|
||||
$this->id = $fileRow->file_id;
|
||||
$this->user = User::construct($fileRow->user_id);
|
||||
$this->data = $fileRow->file_data;
|
||||
$this->data = file_get_contents(config('file.uploads_dir') . $fileRow->file_id . ".bin");
|
||||
$this->name = $fileRow->file_name;
|
||||
$this->mime = $fileRow->file_mime;
|
||||
$this->time = $fileRow->file_time;
|
||||
|
@ -125,6 +127,8 @@ class File
|
|||
*/
|
||||
public function delete()
|
||||
{
|
||||
unlink(config('file.uploads_dir') . $this->id . ".bin");
|
||||
|
||||
DB::table('uploads')
|
||||
->where('file_id', $this->id)
|
||||
->delete();
|
||||
|
|
21
app/User.php
21
app/User.php
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Sakura;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Sakura\Perms;
|
||||
use Sakura\Perms\Site;
|
||||
use stdClass;
|
||||
|
@ -428,6 +429,26 @@ class User
|
|||
$this->permissions = new Perms(Perms::SITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Carbon object of the registration date
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function registerDate()
|
||||
{
|
||||
return Carbon::createFromTimestamp($this->registered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Carbon object of the last online date
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function lastDate()
|
||||
{
|
||||
return Carbon::createFromTimestamp($this->lastOnline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's birthday.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
; ; sqlite
|
||||
; driver = sqlite
|
||||
; database = sakura.sq3
|
||||
; prefix = sakura_
|
||||
; ; Although the option exists, setting a table prefix for sqlite breaks some migration related things.
|
||||
; prefix =
|
||||
|
||||
; ; postgres
|
||||
; driver = pgsql
|
||||
|
@ -54,6 +55,9 @@ maintenance = false
|
|||
; URL of the sakurako chat (full path) without trailing slash
|
||||
chat = http://chat.localghost
|
||||
|
||||
; Date formatting string
|
||||
date_format = D Y-m-d H:i:s T
|
||||
|
||||
; Cookie settings
|
||||
[cookie]
|
||||
prefix = sakura_
|
||||
|
@ -103,7 +107,7 @@ secure = tls
|
|||
|
||||
; File settings
|
||||
[file]
|
||||
upload_dir = uploads/
|
||||
uploads_dir = uploads/
|
||||
|
||||
; Avatar requirements
|
||||
[file.avatar]
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Sakura\DB;
|
||||
|
||||
class FilesBelongOnTheFilesystem extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$schema = DB::getSchemaBuilder();
|
||||
|
||||
$schema->table('uploads', function (Blueprint $table) {
|
||||
$table->dropColumn('file_data');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
$schema = DB::getSchemaBuilder();
|
||||
|
||||
$schema->table('uploads', function (Blueprint $table) {
|
||||
$table->binary('file_data');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ namespace Sakura
|
|||
title.style.marginBottom = '1px';
|
||||
|
||||
link.innerText = 'Changelog';
|
||||
link.href = Config.ChangelogUrl + '#r' + Config.Revision;
|
||||
link.href = Config.ChangelogUrl;
|
||||
link.target = '_blank';
|
||||
|
||||
DOM.Append(title, link);
|
||||
|
|
|
@ -2,7 +2,6 @@ namespace Sakura
|
|||
{
|
||||
export class Config
|
||||
{
|
||||
public static Revision: number = 0;
|
||||
public static UserId: number = 0;
|
||||
public static SessionId: string = "";
|
||||
public static LoggedIn: boolean = false;
|
||||
|
|
|
@ -106,8 +106,8 @@
|
|||
<div class="profile__username" style="color: {{ profile.colour }}">{{ profile.username }}</div>
|
||||
</div>
|
||||
<div class="profile__header-sub profile__dates">
|
||||
<div class="profile__date--joined">Joined {# $user->joined()->format('r') #}</div>
|
||||
<div class="profile__date--last">Last seen {# $user->lastSeen()->format('r') #}</div>
|
||||
<div class="profile__date--joined">Joined {{ profile.registerDate.format('r') }}</div>
|
||||
<div class="profile__date--last">Last seen {{ profile.lastDate.format('r') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
All active users in the past 2 minutes
|
||||
<table class="panelTable">
|
||||
{% for amount,onlineUser in stats.onlineUsers %}
|
||||
<tr><td style="text-align: left;"><a href="{{ route('user.profile', onlineUser.id) }}" style="font-weight: bold; color: {{ onlineUser.colour }};" class="default">{{ onlineUser.username }}</a></td><td style="text-align: right;"><time class="time-ago" datetime="{{ onlineUser.lastOnline|date('r') }}">{{ onlineUser.lastOnline|date('D Y-m-d H:i:s T') }}</time></td></tr>
|
||||
<tr><td style="text-align: left;"><a href="{{ route('user.profile', onlineUser.id) }}" style="font-weight: bold; color: {{ onlineUser.colour }};" class="default">{{ onlineUser.username }}</a></td><td style="text-align: right;"><time class="time-ago" datetime="{{ onlineUser.lastOnline|date('r') }}">{{ onlineUser.lastOnline|date(config('general.date_format')) }}</time></td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
</div>
|
||||
<div class="clear"></div>
|
||||
<div class="news-post-time">
|
||||
Posted <time class="time-ago" datetime="{{ post.time|date('r') }}">{{ post.time|date('D Y-m-d H:i:s T') }}</time>
|
||||
Posted <time class="time-ago" datetime="{{ post.time|date('r') }}">{{ post.time|date(config('general.date_format')) }}</time>
|
||||
{% if newsHideCommentCount is not defined %}<a class="default" href="{{ route('news.post', post.id) }}#comments">{{ post.commentCount }} comment{% if post.commentCount != 1 %}s{% endif %}</a>{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<div>
|
||||
{% if forum.lastPost.id %}
|
||||
<a href="{{ route('forums.topic', forum.lastPost.topic) }}" class="default">{{ forum.lastPost.subject|slice(0, 30) }}{% if forum.lastPost.subject|length > 30 %}...{% endif %}</a><br>
|
||||
<time class="time-ago" datetime="{{ forum.lastPost.time|date('r') }}">{{ forum.lastPost.time|date('D Y-m-d H:i:s T') }}</time> by {% if forum.lastPost.poster.id %}<a href="{{ route('user.profile', forum.lastPost.poster.id) }}" class="default" style="color: {{ forum.lastPost.poster.colour }}; text-shadow: 0 0 5px {% if forumlastPost.poster.colour != 'inherit' %}{{ forum.lastPost.poster.colour }}{% else %}#222{% endif %};">{{ forum.lastPost.poster.username }}</a>{% else %}[deleted user]{% endif %} <a href="{{ route('forums.post', forum.lastPost.id) }}" class="default fa fa-tag"></a>
|
||||
<time class="time-ago" datetime="{{ forum.lastPost.time|date('r') }}">{{ forum.lastPost.time|date(config('general.date_format')) }}</time> by {% if forum.lastPost.poster.id %}<a href="{{ route('user.profile', forum.lastPost.poster.id) }}" class="default" style="color: {{ forum.lastPost.poster.colour }}; text-shadow: 0 0 5px {% if forumlastPost.poster.colour != 'inherit' %}{{ forum.lastPost.poster.colour }}{% else %}#222{% endif %};">{{ forum.lastPost.poster.username }}</a>{% else %}[deleted user]{% endif %} <a href="{{ route('forums.post', forum.lastPost.id) }}" class="default fa fa-tag"></a>
|
||||
{% else %}
|
||||
There are no posts in this forum.<br>
|
||||
{% endif %}
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
{% else %}
|
||||
[deleted user]
|
||||
{% endif %} <a href="{{ route('forums.post', topic.lastPost.id) }}" class="default fa fa-tag"></a><br>
|
||||
<time class="time-ago" datetime="{{ topic.lastPost.time|date('r') }}">{{ topic.lastPost.time|date('D Y-m-d H:i:s T') }}</time>
|
||||
<time class="time-ago" datetime="{{ topic.lastPost.time|date('r') }}">{{ topic.lastPost.time|date(config('general.date_format')) }}</time>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<td style="text-align: left; border-bottom: 1px solid #9475b2;">
|
||||
<a href="{{ route('forums.topic', _t.id) }}" class="default">{{ _t.title }}</a>
|
||||
</td>
|
||||
<td class="rightAlign" style="border-bottom: 1px solid #9475b2;"><time class="time-ago" datetime="{{ _t.lastPost.time|date('r') }}">{{ _t.lastPost.time|date('D Y-m-d H:i:s T') }}</time></td>
|
||||
<td class="rightAlign" style="border-bottom: 1px solid #9475b2;"><time class="time-ago" datetime="{{ _t.lastPost.time|date('r') }}">{{ _t.lastPost.time|date(config('general.date_format')) }}</time></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
@ -36,7 +36,7 @@
|
|||
by
|
||||
<a href="{{ route('user.profile', _p.poster.id) }}" class="default"><span style="color: {{ _p.poster.colour }};">{{ _p.poster.username }}</span></a>
|
||||
</td>
|
||||
<td class="rightAlign" style="border-bottom: 1px solid #9475b2;"><time class="time-ago" datetime="{{ _p.time|date('r') }}">{{ _p.time|date('D Y-m-d H:i:s T') }}</time></td>
|
||||
<td class="rightAlign" style="border-bottom: 1px solid #9475b2;"><time class="time-ago" datetime="{{ _p.time|date('r') }}">{{ _p.time|date(config('general.date_format')) }}</time></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
@ -48,7 +48,7 @@
|
|||
<div class="user-container" style="background-image: url({{ route('user.header', activePoster.id) }});">
|
||||
<div class="default-avatar-setting user-container-avatar" style="background-image: url({{ route('file.avatar', activePoster.id) }}); box-shadow: 0 0 5px #{% if activePoster.isOnline %}484{% else %}844{% endif %};"></div>
|
||||
<div class="user-container-info">
|
||||
<h1 style="color: {{ activePoster.colour }}; text-shadow: 0 0 7px {% if activePoster.colour != 'inherit' %}{{ activePoster.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;" {% if activePoster.getUsernameHistory %} title="Known as {{ activePoster.getUsernameHistory[0].username_old }} before {{ activePoster.getUsernameHistory[0].change_time|date('D Y-m-d H:i:s T') }}." {% endif %}>{{ activePoster.username }}</h1>
|
||||
<h1 style="color: {{ activePoster.colour }}; text-shadow: 0 0 7px {% if activePoster.colour != 'inherit' %}{{ activePoster.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;" {% if activePoster.getUsernameHistory %} title="Known as {{ activePoster.getUsernameHistory[0].username_old }} before {{ activePoster.getUsernameHistory[0].change_time|date(config('general.date_format')) }}." {% endif %}>{{ activePoster.username }}</h1>
|
||||
{% if activePoster.isPremium %}<img src="/images/tenshi.png" alt="Tenshi" style="vertical-align: middle;"> {% endif %}<img src="/images/flags/{{ activePoster.country|lower }}.png" alt="{{ activePoster.country }}" style="vertical-align: middle;" title="{{ activePoster.country(true) }}"> <span style="font-size: .8em;">{{ activePoster.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
<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 class="time-ago" datetime="{{ post.time|date('r') }}">{{ post.time|date('D Y-m-d H:i:s T') }}</time></a>
|
||||
<a href="{{ route('forums.post', post.id) }}" class="clean">#{{ post.id }} - <time class="time-ago" datetime="{{ post.time|date('r') }}">{{ post.time|date(config('general.date_format')) }}</time></a>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
|
|
@ -112,23 +112,23 @@
|
|||
</div>
|
||||
<div class="footer">
|
||||
<div class="ftsections">
|
||||
<div class="copycentre">Powered by <a href="https://github.com/flashwave/sakura/" target="_blank">Sakura</a>{% if config('dev.show_changelog', true) %} <a href="https://sakura.flash.moe/#r{{ constant('SAKURA_VERSION') }}" target="_blank">r{{ constant('SAKURA_VERSION') }}</a>{% endif %} © 2013-2016 <a href="http://flash.moe/" target="_blank">Flashwave</a></div>
|
||||
<div class="copycentre">Powered by <a href="https://github.com/flashwave/sakura/">Sakura</a> © 2013-2016 <a href="http://flash.moe/">Flashwave</a></div>
|
||||
<ul class="ftsection">
|
||||
<li class="fthead">General</li>
|
||||
<li><a href="{{ route('main.index') }}">Home</a></li>
|
||||
<li><a href="{{ route('news.category') }}">News</a></li>
|
||||
<li><a href="{{ route('main.search') }}">Search</a></li>
|
||||
<li><a href="{{ route('info.contact') }}">Contact</a></li>
|
||||
<li><a href="https://sakura.flash.moe" target="_blank">Changelog</a></li>
|
||||
<li><a href="https://sakura.flash.moe">Changelog</a></li>
|
||||
<li><a href="{{ route('premium.index') }}">Support us</a></li>
|
||||
</ul>
|
||||
<ul class="ftsection">
|
||||
<li class="fthead">Community</li>
|
||||
<li><a href="{{ route('forums.index') }}">Forums</a></li>
|
||||
<li><a href="https://twitter.com/_flashii" target="_blank">Twitter</a></li>
|
||||
<li><a href="https://youtube.com/user/flashiinet" target="_blank">YouTube</a></li>
|
||||
<li><a href="https://steamcommunity.com/groups/flashiinet" target="_blank">Steam</a></li>
|
||||
<li><a href="https://github.com/flashii" target="_blank">GitHub</a></li>
|
||||
<li><a href="https://twitter.com/_flashii">Twitter</a></li>
|
||||
<li><a href="https://youtube.com/user/flashiinet">YouTube</a></li>
|
||||
<li><a href="https://steamcommunity.com/groups/flashiinet">Steam</a></li>
|
||||
<li><a href="https://github.com/flashii">GitHub</a></li>
|
||||
</ul>
|
||||
<ul class="ftsection">
|
||||
<li class="fthead">Information</li>
|
||||
|
@ -142,7 +142,6 @@
|
|||
</div>
|
||||
<script type="text/javascript">
|
||||
Sakura.Config.Set({
|
||||
Revision: {{ constant('SAKURA_VERSION') }},
|
||||
LoggedIn: {{ user.isActive ? 'true' : 'false' }},
|
||||
UserId: {{ user.id }},
|
||||
SessionId: "{{ session_id() }}",
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
<br>
|
||||
<h2>Additional information</h2>
|
||||
<ul style="margin-left: 30px;">
|
||||
<li>You were banned on {{ ban.issued|date('D Y-m-d H:i:s T') }}.</li>
|
||||
<li>{% if ban.expires %}This ban expires on {{ ban.expires|date('D Y-m-d H:i:s T') }}.{% else %}<b>You are permanently banned.</b>{% endif %}</li>
|
||||
<li>You were banned on {{ ban.issued|date(config('general.date_format')) }}.</li>
|
||||
<li>{% if ban.expires %}This ban expires on {{ ban.expires|date(config('general.date_format')) }}.{% else %}<b>You are permanently banned.</b>{% endif %}</li>
|
||||
{% if ban.expires %}
|
||||
<li>You were banned by <a href="{{ route('user.profile', ban.issuer.id) }}" class="default">{{ ban.issuer.username }}</a>.</li>
|
||||
{% endif %}
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
<div class="content standalone" style="text-align: center;">
|
||||
<h1 class="stylised" style="margin: 1em auto;">Thank you for your contribution!</h1>
|
||||
<h1 class="fa fa-heart stylised" style="font-size: 20em;"></h1>
|
||||
<h3>Your Tenshi will expire on {{ user.isPremium|date('D Y-m-d H:i:s T') }}.</h3>
|
||||
<h3>Your Tenshi will expire on {{ user.isPremium|date(config('general.date_format')) }}.</h3>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
Your current Tenshi tag
|
||||
</div>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<h3>{% if persistentPremium %}Your rank has persistent Tenshi.{% else %}Your Tenshi tag is valid till {{ user.premiumInfo.expire|date('D Y-m-d H:i:s T') }}.{% endif %}</h3>
|
||||
<h3>{% if persistentPremium %}Your rank has persistent Tenshi.{% else %}Your Tenshi tag is valid till {{ user.premiumInfo.expire|date(config('general.date_format')) }}.{% endif %}</h3>
|
||||
<progress value="{{ persistentPremium ? 100 : (100 - (((date().timestamp - user.premiumInfo.start) / (user.premiumInfo.expire - user.premiumInfo.start)) * 100)) }}" max="100" style="width: 100%"></progress>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
{% block settingsContent %}
|
||||
<form enctype="multipart/form-data" method="post" action="{{ route('settings.account.username') }}">
|
||||
<h1 class="stylised" style="text-align: center; margin-top: 10px;{% if not eligible %} color: #c44;{% endif %}">You are {% if not eligible %}not {% endif %}eligible for a name change.</h1>
|
||||
<h3 style="text-align: center;">{% if user.getUsernameHistory %}Your last name change was <time class="time-ago" datetime="{{ user.getUsernameHistory[0]['change_time']|date('r') }}">{{ user.getUsernameHistory[0]['change_time']|date('D Y-m-d H:i:s T') }}</time>.{% else %}This is your first username change.{% endif %}</h3>
|
||||
<h3 style="text-align: center;">{% if user.getUsernameHistory %}Your last name change was <time class="time-ago" datetime="{{ user.getUsernameHistory[0]['change_time']|date('r') }}">{{ user.getUsernameHistory[0]['change_time']|date(config('general.date_format')) }}</time>.{% else %}This is your first username change.{% endif %}</h3>
|
||||
{% if eligible %}
|
||||
<div class="profile-field">
|
||||
<div><h2>Username</h2></div>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
{{ s.user_agent }}
|
||||
</td>
|
||||
<td>
|
||||
<time class="time-ago" datetime="{{ s.session_start|date('r') }}">{{ s.session_start|date('D Y-m-d H:i:s T') }}</time>
|
||||
<time class="time-ago" datetime="{{ s.session_start|date('r') }}">{{ s.session_start|date(config('general.date_format')) }}</time>
|
||||
</td>
|
||||
<td style="width: 90px;">
|
||||
<form method="post" action="{{ route('settings.advanced.sessions') }}">
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="notif-hist-time">
|
||||
<time class="time-ago" datetime="{{ alert.time|date('r') }}">{{ alert.time|date('D Y-m-d H:i:s T') }}</time>
|
||||
<time class="time-ago" datetime="{{ alert.time|date('r') }}">{{ alert.time|date(config('general.date_format')) }}</time>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
|
|
|
@ -80,10 +80,10 @@
|
|||
<a href="{{ route('user.profile', user.id) }}" class="default" style="font-weight: bold; color: {{ user.colour }}; text-shadow: 0 0 5px {{ user.colour }};">{{ user.username }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<time class="time-ago" datetime="{{ user.registered|date('r') }}">{{ user.registered|date('D Y-m-d H:i:s T') }}</time>
|
||||
<time class="time-ago" datetime="{{ user.registered|date('r') }}">{{ user.registered|date(config('general.date_format')) }}</time>
|
||||
</td>
|
||||
<td>
|
||||
{% if user.lastOnline == 0 %}<i>Never logged in.</i>{% else %}<time class="time-ago" datetime="{{ user.lastOnline|date('r') }}">{{ user.lastOnline|date('D Y-m-d H:i:s T') }}</time>{% endif %}
|
||||
{% if user.lastOnline == 0 %}<i>Never logged in.</i>{% else %}<time class="time-ago" datetime="{{ user.lastOnline|date('r') }}">{{ user.lastOnline|date(config('general.date_format')) }}</time>{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ user.title }}
|
||||
|
|
|
@ -144,16 +144,16 @@
|
|||
<div class="new-profile-info">
|
||||
<div class="default-avatar-setting new-profile-avatar" style="background-image: url({{ route('file.avatar', profile.id) }}); box-shadow: 0 0 5px #{% if profile.isOnline %}484{% else %}844{% endif %};"></div>
|
||||
<div class="new-profile-username">
|
||||
<h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px {% if profile.colour != 'inherit' %}{{ profile.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;" {% if profile.getUsernameHistory %} title="Known as {{ profile.getUsernameHistory[0].username_old }} before {{ profile.getUsernameHistory[0].change_time|date('D Y-m-d H:i:s T') }}." {% endif %}>{{ profile.username }}</h1>
|
||||
<h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px {% if profile.colour != 'inherit' %}{{ profile.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;" {% if profile.getUsernameHistory %} title="Known as {{ profile.getUsernameHistory[0].username_old }} before {{ profile.getUsernameHistory[0].change_time|date(config('general.date_format')) }}." {% endif %}>{{ profile.username }}</h1>
|
||||
{% if profile.isPremium %}<img src="/images/tenshi.png" alt="Tenshi" style="vertical-align: middle;"> {% endif %}<img src="/images/flags/{{ profile.country|lower }}.png" alt="{{ profile.country }}" style="vertical-align: middle;" title="{{ profile.country(true) }}"> <span style="font-size: .8em;">{{ profile.title }}</span>
|
||||
</div>
|
||||
<div class="new-profile-dates">
|
||||
<b>Joined</b> <time class="time-ago" datetime="{{ profile.registered|date('r') }}">{{ profile.registered|date('D Y-m-d H:i:s T') }}</time>
|
||||
<b>Joined</b> <time class="time-ago" datetime="{{ profile.registered|date('r') }}">{{ profile.registered|date(config('general.date_format')) }}</time>
|
||||
<br>
|
||||
{% if profile.lastOnline < 1 %}
|
||||
<b>{{ profile.username }} hasn't logged in yet.</b>
|
||||
{% else %}
|
||||
<b>Last online</b> <time class="time-ago" datetime="{{ profile.lastOnline|date('r') }}">{{ profile.lastOnline|date('D Y-m-d H:i:s T') }}</time>
|
||||
<b>Last online</b> <time class="time-ago" datetime="{{ profile.lastOnline|date('r') }}">{{ profile.lastOnline|date(config('general.date_format')) }}</time>
|
||||
{% endif %}
|
||||
{% if profile.birthday != '0000-00-00' and profile.birthday|split('-')[0] > 0 %}
|
||||
<br><b>Age</b> <span title="{{ profile.birthday }}">{{ profile.birthday(true) }} years old</span>
|
||||
|
@ -164,7 +164,7 @@
|
|||
<div class="new-profile-interactions">
|
||||
<div class="new-profile-navigation">
|
||||
{% if not noUserpage %}
|
||||
<a class="fa fa-file-text-o" title="View {{ profile.username }}'s user page" href="#_userpage" onclick="profileMode('userpage');"></a>
|
||||
<a class="fa fa-file-text-o" title="View {{ profile.username }}'s user page" href="#_userpage" onclick="profileMode('userpage');"></a>
|
||||
{% endif %}
|
||||
<a class="fa fa-list" title="View {{ profile.username }}'s topics" href="#_topics" onclick="profileMode('topics');"></a>
|
||||
<a class="fa fa-reply" title="View {{ profile.username }}'s posts" href="#_posts" onclick="profileMode('posts');"></a>
|
||||
|
|
|
@ -24,12 +24,12 @@ mb_internal_encoding('utf-8');
|
|||
|
||||
// Check the PHP version
|
||||
if (version_compare(phpversion(), '7.0.0', '<')) {
|
||||
throw new Exception('Sakura requires at least PHP 7.0.0, please upgrade to a newer PHP version.');
|
||||
die('Sakura requires at least PHP 7.0.0, please upgrade to a newer PHP version.');
|
||||
}
|
||||
|
||||
// Check if the composer autoloader exists
|
||||
if (!file_exists(ROOT . 'vendor/autoload.php')) {
|
||||
throw new Exception('Autoloader not found, did you run composer install?');
|
||||
die('Autoloader not found, did you run composer install?');
|
||||
}
|
||||
|
||||
// Include the autoloader
|
||||
|
|
1
uploads/.gitkeep
Normal file
1
uploads/.gitkeep
Normal file
|
@ -0,0 +1 @@
|
|||
#
|
Reference in a new issue