Add command for rebuilding bbcode cache

+ permissioning fixes
This commit is contained in:
flash 2016-10-07 21:21:05 +02:00
parent 5f114d26ae
commit 95f3d237fe
28 changed files with 139 additions and 81 deletions

View file

@ -7,6 +7,7 @@
namespace Sakura\BBCode; namespace Sakura\BBCode;
use Sakura\DB; use Sakura\DB;
use Sakura\User;
/** /**
* BBcode handler. * BBcode handler.
@ -47,7 +48,7 @@ class Parser
Tags\Box::class, Tags\Box::class,
Tags\Code::class, Tags\Code::class,
Tags\ListTag::class, Tags\ListTag::class,
Tags\User::class, Tags\UserTag::class,
Tags\Markdown::class, Tags\Markdown::class,
// Newline must always be last // Newline must always be last
@ -59,7 +60,7 @@ class Parser
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parseEmoticons($text) public static function parseEmoticons($text, User $poster = null)
{ {
// Get emoticons from the database // Get emoticons from the database
$emotes = DB::table('emoticons') $emotes = DB::table('emoticons')
@ -81,12 +82,12 @@ class Parser
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function toHTML($text) public static function toHTML($text, User $poster)
{ {
$text = self::parseEmoticons($text); $text = self::parseEmoticons($text);
foreach (self::$parsers as $parser) { foreach (self::$parsers as $parser) {
$text = call_user_func([$parser, 'parse'], $text); $text = call_user_func_array([$parser, 'parse'], [$text, $poster]);
} }
return $text; return $text;

View file

@ -6,6 +6,8 @@
namespace Sakura\BBCode; namespace Sakura\BBCode;
use Sakura\User;
/** /**
* Interface for tags. * Interface for tags.
* @package Sakura * @package Sakura
@ -30,7 +32,7 @@ class TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace(static::$pattern, static::$replace, $text); return preg_replace(static::$pattern, static::$replace, $text);
} }

View file

@ -7,6 +7,7 @@
namespace Sakura\BBCode\Tags; namespace Sakura\BBCode\Tags;
use Sakura\BBCode\TagBase; use Sakura\BBCode\TagBase;
use Sakura\User;
/** /**
* Align tag. * Align tag.
@ -20,7 +21,7 @@ class Align extends TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[align\=(left|center|centre|right)\](.*?)\[\/align\]/s', '/\[align\=(left|center|centre|right)\](.*?)\[\/align\]/s',
@ -29,7 +30,7 @@ class Align extends TagBase
$matches[1] = 'center'; $matches[1] = 'center';
} }
return "<div style='text-align: {$matches[1]}'>{$matches[2]}</div>"; return "<div style='text-align: {$matches[1]}' class='bbcode__align'>{$matches[2]}</div>";
}, },
$text $text
); );

View file

@ -25,5 +25,5 @@ class Bold extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<b>$1</b>"; public static $replace = "<b class='bbcode__bold'>$1</b>";
} }

View file

@ -7,6 +7,7 @@
namespace Sakura\BBCode\Tags; namespace Sakura\BBCode\Tags;
use Sakura\BBCode\TagBase; use Sakura\BBCode\TagBase;
use Sakura\User;
/** /**
* Box tag. * Box tag.
@ -20,16 +21,16 @@ class Box extends TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[box(?:\=(.*?))?\](.*?)\[\/box\]/s', '/\[box(?:\=(.*?))?\](.*?)\[\/box\]/s',
function ($matches) { function ($matches) {
$title = strlen($matches[1]) ? $matches[1] : 'Click to open'; $title = strlen($matches[1]) ? $matches[1] : 'Click to open';
return "<div class='spoiler-box-container'>" return "<div class='bbcode__box'>"
. "<div class='spoiler-box-title' onclick='alert(\"reimplement the toggle system\");'>{$title}</div>" . "<div class='bbcode__box-title' onclick='alert(\"implement the toggle system\");'>{$title}</div>"
. "<div class='spoiler-box-content hidden'>{$matches[2]}</div>" . "<div class='bbcode__box-content bbcode__box-content--hidden'>{$matches[2]}</div>"
. "</div>"; . "</div>";
}, },
$text $text

View file

@ -7,6 +7,7 @@
namespace Sakura\BBCode\Tags; namespace Sakura\BBCode\Tags;
use Sakura\BBCode\TagBase; use Sakura\BBCode\TagBase;
use Sakura\User;
/** /**
* Code tag. * Code tag.
@ -20,15 +21,15 @@ class Code extends TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[code(?:\=([a-z]+))?\](.*?)\[\/code\]/s', '/\[code(?:\=([a-z]+))?\](.*?)\[\/code\]/s',
function ($matches) { function ($matches) {
$class = strlen($matches[1]) ? " class='lang-{$matches[1]}'" : ''; $class = strlen($matches[1]) ? "lang-{$matches[1]}" : '';
// htmlencode bbcode characters here as well // htmlencode bbcode characters here as well
return "<pre><code{$class}>{$matches[2]}</code></pre>"; return "<pre class='bbcode__code'><code class='bbcode__code-container {$class}'>{$matches[2]}</code></pre>";
}, },
$text $text
); );

View file

@ -25,5 +25,5 @@ class Colour extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<span style='color: $1'>$2</span>"; public static $replace = "<span style='color: $1' class='bbcode__colour'>$2</span>";
} }

View file

@ -25,5 +25,5 @@ class Header extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<h1>$1</h1>"; public static $replace = "<h1 class='bbcode__header'>$1</h1>";
} }

View file

@ -25,5 +25,5 @@ class Image extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<img src='$1' alt='$1'>"; public static $replace = "<img class='bbcode__image' src='$1' alt='$1'>";
} }

View file

@ -25,5 +25,5 @@ class Italics extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<i>$1</i>"; public static $replace = "<i class='bbcode__italics'>$1</i>";
} }

View file

@ -25,5 +25,5 @@ class Link extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<a href='$1'>$1</a>"; public static $replace = "<a href='$1' class='bbcode_link'>$1</a>";
} }

View file

@ -7,6 +7,7 @@
namespace Sakura\BBCode\Tags; namespace Sakura\BBCode\Tags;
use Sakura\BBCode\TagBase; use Sakura\BBCode\TagBase;
use Sakura\User;
/** /**
* List tag. Name is suffixed with Tag since "list" is a language construct. * List tag. Name is suffixed with Tag since "list" is a language construct.
@ -20,18 +21,18 @@ class ListTag extends TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[list(?:\=(1|A|a|I|i))?\](.*?)\[\/list\]/s', '/\[list(?:\=(1|A|a|I|i))?\](.*?)\[\/list\]/s',
function ($matches) { function ($matches) {
$content = preg_replace('/\[\*\](.*)/', '<li>$1</li>', $matches[2]); $content = preg_replace('/\[\*\](.*)/', '<li class="bbcode__list-entry">$1</li>', $matches[2]);
if ($matches[1] !== '') { if ($matches[1] !== '') {
return "<ol type='{$matches[1]}'>{$content}</ol>"; return "<ol type='{$matches[1]}' class='bbcode__list bbcode__list--ordered'>{$content}</ol>";
} }
return "<ul>{$content}</ul>"; return "<ul class='bbcode__list bbcode__list--unordered'>{$content}</ul>";
}, },
$text $text
); );

View file

@ -8,6 +8,7 @@ namespace Sakura\BBCode\Tags;
use Parsedown; use Parsedown;
use Sakura\BBCode\TagBase; use Sakura\BBCode\TagBase;
use Sakura\User;
/** /**
* Markdown! * Markdown!
@ -27,7 +28,7 @@ class Markdown extends TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[md\](.*?)\[\/md\]/s', '/\[md\](.*?)\[\/md\]/s',
@ -41,7 +42,7 @@ class Markdown extends TagBase
->setMarkupEscaped(true) ->setMarkupEscaped(true)
->text($matches[1]); ->text($matches[1]);
return "<div class='markdown'>{$parsed}</div>"; return "<div class='markdown bbcode__markdown'>{$parsed}</div>";
}, },
$text $text
); );

View file

@ -25,5 +25,5 @@ class NamedLink extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<a href='$1'>$2</a>"; public static $replace = "<a href='$1' class='bbcode__link bbcode__link--named'>$2</a>";
} }

View file

@ -11,6 +11,7 @@ use Sakura\CurrentSession;
use Sakura\Forum\Forum; use Sakura\Forum\Forum;
use Sakura\Forum\Post; use Sakura\Forum\Post;
use Sakura\Perms\Forum as ForumPerms; use Sakura\Perms\Forum as ForumPerms;
use Sakura\User;
/** /**
* Named quote tag. * Named quote tag.
@ -24,11 +25,11 @@ class NamedQuote extends TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[quote\=(#?)(.*?)\](.*)\[\/quote\]/s', '/\[quote\=(#?)(.*?)\](.*)\[\/quote\]/s',
function ($matches) { function ($matches) use ($poster) {
$quoting = $matches[2]; $quoting = $matches[2];
$content = $matches[3]; $content = $matches[3];
@ -36,15 +37,15 @@ class NamedQuote extends TagBase
$post = new Post(intval($matches[2])); $post = new Post(intval($matches[2]));
$forum = new Forum($post->forum); $forum = new Forum($post->forum);
if ($post->id !== 0 && $forum->permission(ForumPerms::VIEW, CurrentSession::$user->id)) { if ($post->id !== 0 && $forum->permission(ForumPerms::VIEW, $poster->id)) {
$link = route('forums.post', $post->id); $link = route('forums.post', $post->id);
$quoting = "<a href='{$link}' style='color: {$post->poster->colour}'>{$post->poster->username}</a>"; $quoting = "<a href='{$link}' style='color: {$post->poster->colour}' class='bbcode__quote-post'>{$post->poster->username}</a>";
$content = $post->parsed; $content = $post->parsed;
} }
} }
return "<blockquote><small>{$quoting}</small>{$content}</blockquote>"; return "<blockquote class='bbcode__quote bbcode__quote--named'><small class='bbcode__quote-name'>{$quoting}</small>{$content}</blockquote>";
}, },
$text $text
); );

View file

@ -25,5 +25,5 @@ class Quote extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<blockquote>$1</blockquote>"; public static $replace = "<blockquote class='bbcode__quote'>$1</blockquote>";
} }

View file

@ -7,6 +7,7 @@
namespace Sakura\BBCode\Tags; namespace Sakura\BBCode\Tags;
use Sakura\BBCode\TagBase; use Sakura\BBCode\TagBase;
use Sakura\User;
/** /**
* Size tag. * Size tag.
@ -44,7 +45,7 @@ class Size extends TagBase
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[size\=([a-z0-9]+)\](.*?)\[\/size\]/s', '/\[size\=([a-z0-9]+)\](.*?)\[\/size\]/s',
@ -62,7 +63,7 @@ class Size extends TagBase
} }
// we'll just use per cent for now, don't let this make it to production though // we'll just use per cent for now, don't let this make it to production though
return "<div style='font-size: {$size}%'>{$matches[2]}</div>"; return "<div style='font-size: {$size}%' class='bbcode__size'>{$matches[2]}</div>";
}, },
$text $text
); );

View file

@ -25,5 +25,5 @@ class Spoiler extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<span class='spoiler'>$1</span>"; public static $replace = "<span class='bbcode__spoiler'>$1</span>";
} }

View file

@ -25,5 +25,5 @@ class Strike extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<del>$1</del>"; public static $replace = "<del class='bbcode__strike'>$1</del>";
} }

View file

@ -25,5 +25,5 @@ class Underline extends TagBase
* The string to replace it with. * The string to replace it with.
* @var string * @var string
*/ */
public static $replace = "<u>$1</u>"; public static $replace = "<u class='bbcode__underline'>$1</u>";
} }

View file

@ -7,29 +7,29 @@
namespace Sakura\BBCode\Tags; namespace Sakura\BBCode\Tags;
use Sakura\BBCode\TagBase; use Sakura\BBCode\TagBase;
use Sakura\User as UserObject; use Sakura\User;
/** /**
* User tag. * User tag.
* @package Sakura * @package Sakura
* @author Julian van de Groep <me@flash.moe> * @author Julian van de Groep <me@flash.moe>
*/ */
class User extends TagBase class UserTag extends TagBase
{ {
/** /**
* Parses the bbcode. * Parses the bbcode.
* @param string $text * @param string $text
* @return string * @return string
*/ */
public static function parse($text) public static function parse($text, User $poster)
{ {
return preg_replace_callback( return preg_replace_callback(
'/\[user\]([0-9]+)\[\/user\]/s', '/\[user\]([0-9]+)\[\/user\]/s',
function ($matches) { function ($matches) {
$user = UserObject::construct($matches[1]); $user = User::construct($matches[1]);
$route = route('user.profile', $user->id); $route = route('user.profile', $user->id);
return "<a href='{$route}' class='default username' style='color: {$user->colour}; " return "<a href='{$route}' class='bbcode__user' style='color: {$user->colour}; "
. "text-shadow: 0 0 .3em {$user->colour}; font-weight: bold'>{$user->username}</a>"; . "text-shadow: 0 0 .3em {$user->colour}; font-weight: bold'>{$user->username}</a>";
}, },
$text $text

View file

@ -26,5 +26,5 @@ class YouTube extends TagBase
* @var string * @var string
*/ */
public static $replace = "<iframe width='560' height='315' src='https://www.youtube-nocookie.com/embed/$1'" public static $replace = "<iframe width='560' height='315' src='https://www.youtube-nocookie.com/embed/$1'"
. " frameborder='0' allowfullscreen></iframe>"; . " frameborder='0' allowfullscreen class='bbcode__youtube'></iframe>";
} }

View file

@ -0,0 +1,43 @@
<?php
/**
* Holds the forum bbcode cache rebuilder.
* @package Sakura
*/
namespace Sakura\Console\Command;
use CLIFramework\Command;
use Sakura\DB;
use Sakura\Forum\Post;
/**
* Rebuilds the forum bbcode cache.
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class RebuildForumCacheCommand extends Command
{
/**
* A quick description of this command.
* @return string.
*/
public function brief()
{
return 'Rebuild the forum bbcode cache';
}
/**
* Does the repository installing.
*/
public function execute()
{
$this->getLogger()->writeln("This might take a while...");
$posts = DB::table('posts')->get(['post_id']);
foreach ($posts as $post) {
(new Post($post->post_id))->update(true);
}
$this->getLogger()->writeln("Done!");
}
}

View file

@ -69,9 +69,13 @@ class ExceptionHandler
http_response_code(500); http_response_code(500);
$debug = config('dev.show_errors'); $debug = config('dev.show_errors');
$cli = php_sapi_name() === 'cli';
if ($debug) { if ($cli || $debug) {
if (!$cli) {
header('Content-Type: text/plain'); header('Content-Type: text/plain');
}
echo $ex; echo $ex;
} else { } else {
if (!self::$disableTemplate && Template::available()) { if (!self::$disableTemplate && Template::available()) {

View file

@ -132,7 +132,7 @@ class Post
} }
if (strlen($this->parsed) < 1) { if (strlen($this->parsed) < 1) {
$this->parsed = BBParser::toHTML(htmlentities($this->text)); $this->parsed = BBParser::toHTML(htmlentities($this->text), $this->poster);
$this->update(); $this->update();
} }
} }
@ -171,7 +171,7 @@ class Post
'post_time' => time(), 'post_time' => time(),
'post_subject' => $subject, 'post_subject' => $subject,
'post_text' => $text, 'post_text' => $text,
'post_text_parsed' => BBParser::toHTML(htmlentities($text)), 'post_text_parsed' => BBParser::toHTML(htmlentities($text), $this->poster),
]); ]);
// Update the last post date // Update the last post date
@ -183,9 +183,10 @@ class Post
/** /**
* Commit the changes to the Database. * Commit the changes to the Database.
* @param bool $ignoreIp
* @return Post * @return Post
*/ */
public function update() public function update($ignoreIp = false)
{ {
// Create a topic object // Create a topic object
$topic = new Topic($this->topic); $topic = new Topic($this->topic);
@ -197,11 +198,11 @@ class Post
'topic_id' => $topic->id, 'topic_id' => $topic->id,
'forum_id' => $topic->forum, 'forum_id' => $topic->forum,
'poster_id' => $this->poster->id, 'poster_id' => $this->poster->id,
'poster_ip' => Net::pton(Net::ip()), 'poster_ip' => Net::pton($ignoreIp ? $this->ip : Net::ip()),
'post_time' => $this->time, 'post_time' => $this->time,
'post_subject' => $this->subject, 'post_subject' => $this->subject,
'post_text' => $this->text, 'post_text' => $this->text,
'post_text_parsed' => BBParser::toHTML(htmlentities($this->text)), 'post_text_parsed' => BBParser::toHTML(htmlentities($this->text), $this->poster),
'post_edit_time' => $this->editTime, 'post_edit_time' => $this->editTime,
'post_edit_reason' => $this->editReason, 'post_edit_reason' => $this->editReason,
'post_edit_user' => $this->editUser->id, 'post_edit_user' => $this->editUser->id,

View file

@ -12,10 +12,6 @@ require_once __DIR__ . '/../sakura.php';
// Start output buffering // Start output buffering
ob_start(config('performance.compression') ? 'ob_gzhandler' : null); ob_start(config('performance.compression') ? 'ob_gzhandler' : null);
// Initialise the router and include the routes file
Routerv1::init();
include_once path('routes.php');
// Initialise the current session // Initialise the current session
$cookiePrefix = config('cookie.prefix'); $cookiePrefix = config('cookie.prefix');
CurrentSession::start( CurrentSession::start(

View file

@ -1,49 +1,45 @@
.bbcode { .bbcode {
line-height: 1.4; // line-height: 1.4;
word-wrap: break-word; // word-wrap: break-word;
h1, &__header {
h2,
h3 {
text-shadow: 0 0 5px #8364A1; text-shadow: 0 0 5px #8364A1;
color: #614390; color: #614390;
} }
ul { &__list {
margin-left: 2em; margin-left: 2em;
&--unordered {
list-style: square; list-style: square;
} }
}
.spoiler { &__spoiler {
background: #000; background: #000;
&:hover { &:hover {
background: inherit; background: #888;
} }
} }
blockquote { &__quote {
border: 1px solid #9475b2; border: 1px solid #9475b2;
border-bottom: 0; border-bottom: 0;
border-right: 0; border-right: 0;
background: #D8B9F6; background: #D8B9F6;
margin: .5em; margin: .5em;
> .quotee { &-name {
font-weight: bold; font-weight: bold;
border-bottom: 1px solid #9475b2; border-bottom: 1px solid #9475b2;
border-right: 1px solid #9475b2; border-right: 1px solid #9475b2;
background: #B697d4; background: #B697d4;
padding-left: .5em; padding-left: .5em;
} }
> .quote {
margin-left: .5em;
padding-bottom: .2em;
}
} }
a { &__link {
color: #22E; color: #22E;
text-decoration: none; text-decoration: none;
@ -58,11 +54,11 @@
} }
} }
.spoiler-box-container { &__box {
border: 1px solid #9475b2; border: 1px solid #9475b2;
margin: .5em; margin: .5em;
> .spoiler-box-title { &-title {
text-align: center; text-align: center;
background: #B697d4; background: #B697d4;
font-weight: bold; font-weight: bold;
@ -70,19 +66,24 @@
padding: 4px 0; padding: 4px 0;
} }
> .spoiler-box-content { &-content {
border-top: 1px solid #9475b2; border-top: 1px solid #9475b2;
&--hidden {
.hidden;
}
} }
} }
img { &__image {
width: auto; width: auto;
height: auto; height: auto;
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 100%;
} }
code { &__code {
font-size: 1.1em; font-size: 1.1em;
line-height: 1.5em;
} }
} }

View file

@ -11,3 +11,6 @@ require_once 'vendor/autoload.php';
ExceptionHandler::register(); ExceptionHandler::register();
Config::load(path('config/config.ini')); Config::load(path('config/config.ini'));
DB::connect(config('database')); DB::connect(config('database'));
Routerv1::init();
include_once path('routes.php');