Temporary-ish parsing facilities.
This commit is contained in:
parent
60d14f9709
commit
4e2ff47137
28 changed files with 439 additions and 9 deletions
|
@ -59,6 +59,7 @@ function migrate_up(PDO $conn): void
|
||||||
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
||||||
`post_ip` BLOB NOT NULL,
|
`post_ip` BLOB NOT NULL,
|
||||||
`post_text` TEXT NOT NULL,
|
`post_text` TEXT NOT NULL,
|
||||||
|
`post_parse` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
`post_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`post_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`post_edited` TIMESTAMP NULL DEFAULT NULL,
|
`post_edited` TIMESTAMP NULL DEFAULT NULL,
|
||||||
`post_deleted` TIMESTAMP NULL DEFAULT NULL,
|
`post_deleted` TIMESTAMP NULL DEFAULT NULL,
|
||||||
|
|
|
@ -123,7 +123,8 @@ if ($postRequest) {
|
||||||
$forum['forum_id'],
|
$forum['forum_id'],
|
||||||
$app->getUserId(),
|
$app->getUserId(),
|
||||||
IPAddress::remote()->getString(),
|
IPAddress::remote()->getString(),
|
||||||
$postText
|
$postText,
|
||||||
|
MSZ_FORUM_POST_PARSER_BBCODE
|
||||||
);
|
);
|
||||||
forum_topic_mark_read($app->getUserId(), $topicId, $forum['forum_id']);
|
forum_topic_mark_read($app->getUserId(), $topicId, $forum['forum_id']);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
use Misuzu\Database;
|
use Misuzu\Database;
|
||||||
|
use Misuzu\Parsers\MarkdownParser;
|
||||||
|
|
||||||
require_once __DIR__ . '/../misuzu.php';
|
require_once __DIR__ . '/../misuzu.php';
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,8 @@ class Application extends ApplicationBase
|
||||||
$this->templatingInstance->addFilter('colour_get_red');
|
$this->templatingInstance->addFilter('colour_get_red');
|
||||||
$this->templatingInstance->addFilter('colour_get_green');
|
$this->templatingInstance->addFilter('colour_get_green');
|
||||||
$this->templatingInstance->addFilter('colour_get_blue');
|
$this->templatingInstance->addFilter('colour_get_blue');
|
||||||
|
$this->templatingInstance->addFilter('md', 'parse_markdown');
|
||||||
|
$this->templatingInstance->addFilter('bbcode', 'parse_bbcode');
|
||||||
|
|
||||||
$this->templatingInstance->addFunction('git_hash', [Application::class, 'gitCommitHash']);
|
$this->templatingInstance->addFunction('git_hash', [Application::class, 'gitCommitHash']);
|
||||||
$this->templatingInstance->addFunction('git_branch', [Application::class, 'gitBranch']);
|
$this->templatingInstance->addFunction('git_branch', [Application::class, 'gitBranch']);
|
||||||
|
|
|
@ -1,26 +1,42 @@
|
||||||
<?php
|
<?php
|
||||||
use Misuzu\Database;
|
use Misuzu\Database;
|
||||||
|
|
||||||
|
define('MSZ_FORUM_POST_PARSER_PLAIN', 0);
|
||||||
|
define('MSZ_FORUM_POST_PARSER_BBCODE', 1);
|
||||||
|
define('MSZ_FORUM_POST_PARSER_MARKDOWN', 2);
|
||||||
|
define('MSZ_FORUM_POST_PARSERS', [
|
||||||
|
MSZ_FORUM_POST_PARSER_PLAIN,
|
||||||
|
MSZ_FORUM_POST_PARSER_BBCODE,
|
||||||
|
MSZ_FORUM_POST_PARSER_MARKDOWN,
|
||||||
|
]);
|
||||||
|
|
||||||
|
function forum_post_is_valid_parser(int $parser): bool
|
||||||
|
{
|
||||||
|
return in_array($parser, MSZ_FORUM_POST_PARSERS);
|
||||||
|
}
|
||||||
|
|
||||||
function forum_post_create(
|
function forum_post_create(
|
||||||
int $topicId,
|
int $topicId,
|
||||||
int $forumId,
|
int $forumId,
|
||||||
int $userId,
|
int $userId,
|
||||||
string $ipAddress,
|
string $ipAddress,
|
||||||
string $text
|
string $text,
|
||||||
|
int $parser = MSZ_FORUM_POST_PARSER_PLAIN
|
||||||
): int {
|
): int {
|
||||||
$dbc = Database::connection();
|
$dbc = Database::connection();
|
||||||
|
|
||||||
$createPost = $dbc->prepare('
|
$createPost = $dbc->prepare('
|
||||||
INSERT INTO `msz_forum_posts`
|
INSERT INTO `msz_forum_posts`
|
||||||
(`topic_id`, `forum_id`, `user_id`, `post_ip`, `post_text`)
|
(`topic_id`, `forum_id`, `user_id`, `post_ip`, `post_text`, `post_parse`)
|
||||||
VALUES
|
VALUES
|
||||||
(:topic_id, :forum_id, :user_id, INET6_ATON(:post_ip), :post_text)
|
(:topic_id, :forum_id, :user_id, INET6_ATON(:post_ip), :post_text, :post_parse)
|
||||||
');
|
');
|
||||||
$createPost->bindValue('topic_id', $topicId);
|
$createPost->bindValue('topic_id', $topicId);
|
||||||
$createPost->bindValue('forum_id', $forumId);
|
$createPost->bindValue('forum_id', $forumId);
|
||||||
$createPost->bindValue('user_id', $userId);
|
$createPost->bindValue('user_id', $userId);
|
||||||
$createPost->bindValue('post_ip', $ipAddress);
|
$createPost->bindValue('post_ip', $ipAddress);
|
||||||
$createPost->bindValue('post_text', $text);
|
$createPost->bindValue('post_text', $text);
|
||||||
|
$createPost->bindValue('post_parse', $parser);
|
||||||
|
|
||||||
return $createPost->execute() ? $dbc->lastInsertId() : 0;
|
return $createPost->execute() ? $dbc->lastInsertId() : 0;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +66,7 @@ function forum_post_find(int $postId): array
|
||||||
|
|
||||||
define('MSZ_FORUM_POST_LISTING_QUERY_STANDARD', '
|
define('MSZ_FORUM_POST_LISTING_QUERY_STANDARD', '
|
||||||
SELECT
|
SELECT
|
||||||
p.`post_id`, p.`post_text`, p.`post_created`,
|
p.`post_id`, p.`post_text`, p.`post_created`, p.`post_parse`,
|
||||||
p.`topic_id`,
|
p.`topic_id`,
|
||||||
u.`user_id` as `poster_id`,
|
u.`user_id` as `poster_id`,
|
||||||
u.`username` as `poster_name`,
|
u.`username` as `poster_name`,
|
||||||
|
|
51
src/Parsers/BBCode/BBCodeParser.php
Normal file
51
src/Parsers/BBCode/BBCodeParser.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\Parser;
|
||||||
|
|
||||||
|
final class BBCodeParser extends Parser
|
||||||
|
{
|
||||||
|
private $tags = [];
|
||||||
|
|
||||||
|
public function __construct(array $tags = [])
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
if (empty($tags)) {
|
||||||
|
$tags = [
|
||||||
|
// Advanced markup
|
||||||
|
new Tags\CodeTag,
|
||||||
|
new Tags\QuoteTag,
|
||||||
|
new Tags\BoxTag,
|
||||||
|
new Tags\MarkdownTag,
|
||||||
|
|
||||||
|
// Slightly more advanced markup
|
||||||
|
new Tags\AudioTag,
|
||||||
|
new Tags\VideoTag,
|
||||||
|
|
||||||
|
// Basic markup
|
||||||
|
new Tags\BoldTag,
|
||||||
|
new Tags\ItalicsTag,
|
||||||
|
new Tags\UnderlineTag,
|
||||||
|
new Tags\StrikeTag,
|
||||||
|
new Tags\SpoilerTag,
|
||||||
|
new Tags\HeaderTag,
|
||||||
|
new Tags\ImageTag,
|
||||||
|
|
||||||
|
// Finally parse leftover newlines
|
||||||
|
new Tags\NewLineTag,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->tags = $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
foreach ($this->tags as $tag) {
|
||||||
|
$text = $tag->parseText($text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
}
|
13
src/Parsers/BBCode/BBCodeSimpleTag.php
Normal file
13
src/Parsers/BBCode/BBCodeSimpleTag.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode;
|
||||||
|
|
||||||
|
abstract class BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
abstract public function getPattern(): string;
|
||||||
|
abstract public function getReplacement(): string;
|
||||||
|
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return preg_replace($this->getPattern(), $this->getReplacement(), $text);
|
||||||
|
}
|
||||||
|
}
|
7
src/Parsers/BBCode/BBCodeTag.php
Normal file
7
src/Parsers/BBCode/BBCodeTag.php
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode;
|
||||||
|
|
||||||
|
abstract class BBCodeTag
|
||||||
|
{
|
||||||
|
abstract public function parseText(string $text): string;
|
||||||
|
}
|
20
src/Parsers/BBCode/Tags/AudioTag.php
Normal file
20
src/Parsers/BBCode/Tags/AudioTag.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeTag;
|
||||||
|
|
||||||
|
final class AudioTag extends BBCodeTag
|
||||||
|
{
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'#\[audio\]((?:https?:\/\/).*)\[/audio\]#',
|
||||||
|
function ($matches) {
|
||||||
|
// todo: domain matches etc.
|
||||||
|
// sites like soundcloud (and mixcloud, if possible) should be embeddable through this tag
|
||||||
|
return "<audio controls src='{$matches[1]}'></audio>";
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/BoldTag.php
Normal file
17
src/Parsers/BBCode/Tags/BoldTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class BoldTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\[b\](.*)\[\/b\]/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<b>$1</b>';
|
||||||
|
}
|
||||||
|
}
|
23
src/Parsers/BBCode/Tags/BoxTag.php
Normal file
23
src/Parsers/BBCode/Tags/BoxTag.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeTag;
|
||||||
|
|
||||||
|
final class BoxTag extends BBCodeTag
|
||||||
|
{
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'/\[box(?:=(.*))?\](.*)\[\/box\]/',
|
||||||
|
function ($matches) {
|
||||||
|
$randomId = 'toggle_' . bin2hex(random_bytes(8));
|
||||||
|
$title = strlen($matches[1]) ? $matches[1] : 'Spoiler';
|
||||||
|
return '<div class="container container--hidden" id="' . $randomId . '">'
|
||||||
|
. "<div class='container__title' onclick='toggleContainer(\"{$randomId}\")'>{$title}</div>"
|
||||||
|
. "<div class='container__content'>{$matches[2]}</div>"
|
||||||
|
. '</div>';
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
20
src/Parsers/BBCode/Tags/CodeTag.php
Normal file
20
src/Parsers/BBCode/Tags/CodeTag.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeTag;
|
||||||
|
|
||||||
|
final class CodeTag extends BBCodeTag
|
||||||
|
{
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'/\[code(?:\=([a-z]+))?\](.*?)\[\/code\]/s',
|
||||||
|
function ($matches) {
|
||||||
|
$class = strlen($matches[1]) ? "lang-{$matches[1]}" : '';
|
||||||
|
$text = str_replace(['[', ']', '<', '>'], ['[', ']', '<', '>'], $matches[2]);
|
||||||
|
return "<pre class='bbcode__code'><code class='bbcode__code-container {$class}'>{$text}</code></pre>";
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/HeaderTag.php
Normal file
17
src/Parsers/BBCode/Tags/HeaderTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class HeaderTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\[header\](.*)\[\/header\]/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<h1>$1</h1>';
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/ImageTag.php
Normal file
17
src/Parsers/BBCode/Tags/ImageTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class ImageTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\[img\]((?:https?:\/\/).*)\[\/img\]/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<img src="$1" alt="$1">';
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/ItalicsTag.php
Normal file
17
src/Parsers/BBCode/Tags/ItalicsTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class ItalicsTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\[i\](.*)\[\/i\]/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<i>$1</i>';
|
||||||
|
}
|
||||||
|
}
|
19
src/Parsers/BBCode/Tags/MarkdownTag.php
Normal file
19
src/Parsers/BBCode/Tags/MarkdownTag.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\MarkdownParser;
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeTag;
|
||||||
|
|
||||||
|
final class MarkdownTag extends BBCodeTag
|
||||||
|
{
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'#\[md\](.*?)\[/md\]#s',
|
||||||
|
function ($matches) {
|
||||||
|
return MarkdownParser::getOrCreateInstance()->parseText($matches[1]);
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/NewLineTag.php
Normal file
17
src/Parsers/BBCode/Tags/NewLineTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class NewLineTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\r\n|\r|\n/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<br>';
|
||||||
|
}
|
||||||
|
}
|
24
src/Parsers/BBCode/Tags/QuoteTag.php
Normal file
24
src/Parsers/BBCode/Tags/QuoteTag.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeTag;
|
||||||
|
|
||||||
|
final class QuoteTag extends BBCodeTag
|
||||||
|
{
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'#\[quote(?:=(.*))?\](.*)\[/quote\]#',
|
||||||
|
function ($matches) {
|
||||||
|
$prefix = '';
|
||||||
|
|
||||||
|
if (!empty($matches[1])) {
|
||||||
|
$prefix = "<small>{$matches[1]}:</small>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<blockquote>{$prefix}{$matches[2]}</blockquote>";
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/SpoilerTag.php
Normal file
17
src/Parsers/BBCode/Tags/SpoilerTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class SpoilerTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\[spoiler\](.*)\[\/spoiler\]/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<span class="spoiler-class-name">$1</span>';
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/StrikeTag.php
Normal file
17
src/Parsers/BBCode/Tags/StrikeTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class StrikeTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\[s\](.*)\[\/s\]/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<del>$1</del>';
|
||||||
|
}
|
||||||
|
}
|
17
src/Parsers/BBCode/Tags/UnderlineTag.php
Normal file
17
src/Parsers/BBCode/Tags/UnderlineTag.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeSimpleTag;
|
||||||
|
|
||||||
|
final class UnderlineTag extends BBCodeSimpleTag
|
||||||
|
{
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return "/\[u\](.*)\[\/u\]/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplacement(): string
|
||||||
|
{
|
||||||
|
return '<u>$1</u>';
|
||||||
|
}
|
||||||
|
}
|
26
src/Parsers/BBCode/Tags/VideoTag.php
Normal file
26
src/Parsers/BBCode/Tags/VideoTag.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers\BBCode\Tags;
|
||||||
|
|
||||||
|
use Misuzu\Parsers\BBCode\BBCodeTag;
|
||||||
|
|
||||||
|
final class VideoTag extends BBCodeTag
|
||||||
|
{
|
||||||
|
private const YOUTUBE_REGEX = '#^https?://(?:www\.)?youtu(?:be\.(?:[a-z]{2,63})|\.be|\be-nocookie\.com)/(?:.*?)v=([a-zA-Z0-9_-]+)#si';
|
||||||
|
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'#\[video\]((?:https?:\/\/).*)\[/video\]#',
|
||||||
|
function ($matches) {
|
||||||
|
if (preg_match(self::YOUTUBE_REGEX, $matches[1], $ytMatches)) {
|
||||||
|
return '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/'
|
||||||
|
. $ytMatches[1]
|
||||||
|
. '?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<video controls src='{$matches[1]}'></video>";
|
||||||
|
},
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
20
src/Parsers/MarkdownParser.php
Normal file
20
src/Parsers/MarkdownParser.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers;
|
||||||
|
|
||||||
|
use Parsedown;
|
||||||
|
|
||||||
|
final class MarkdownParser extends Parser
|
||||||
|
{
|
||||||
|
private $parsedown;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->parsedown = new Parsedown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseText(string $text): string
|
||||||
|
{
|
||||||
|
return $this->parsedown->text($text);
|
||||||
|
}
|
||||||
|
}
|
34
src/Parsers/Parser.php
Normal file
34
src/Parsers/Parser.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Parsers;
|
||||||
|
|
||||||
|
abstract class Parser
|
||||||
|
{
|
||||||
|
private static $instances = [];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
self::$instances[static::class] = $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInstance(): ?Parser
|
||||||
|
{
|
||||||
|
if (!array_key_exists(static::class, self::$instances)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instances[static::class];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getOrCreateInstance(...$args): Parser
|
||||||
|
{
|
||||||
|
$instance = static::getInstance();
|
||||||
|
|
||||||
|
if ($instance === null) {
|
||||||
|
$instance = new static(...$args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function parseText(string $text): string;
|
||||||
|
}
|
10
utility.php
10
utility.php
|
@ -220,3 +220,13 @@ function pdo_prepare_array(array $keys, bool $useKeys = false, string $format =
|
||||||
|
|
||||||
return implode(', ', $parts);
|
return implode(', ', $parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_markdown(string $text): string
|
||||||
|
{
|
||||||
|
return \Misuzu\Parsers\MarkdownParser::getOrCreateInstance()->parseText($text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_bbcode(string $text): string
|
||||||
|
{
|
||||||
|
return \Misuzu\Parsers\BBCode\BBCodeParser::getOrCreateInstance()->parseText($text);
|
||||||
|
}
|
||||||
|
|
|
@ -281,7 +281,13 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="forum__post__content__text">
|
<div class="forum__post__content__text">
|
||||||
{{ post.post_text }}
|
{% if post.post_parse == 2 %}
|
||||||
|
{{ post.post_text|escape|md|raw }}
|
||||||
|
{% elseif post.post_parse == 1 %}
|
||||||
|
{{ post.post_text|escape|bbcode|raw }}
|
||||||
|
{% else %}
|
||||||
|
{{ post.post_text|escape }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -97,9 +97,9 @@
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (containerIsClosed(elem))
|
if (containerIsClosed(elem))
|
||||||
openContainer(elem);
|
openContainer(id);
|
||||||
else
|
else
|
||||||
closeContainer(elem);
|
closeContainer(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openContainer(id) {
|
function openContainer(id) {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<div class="container__content news__post__content">
|
<div class="container__content news__post__content">
|
||||||
<div class="news__post__text">
|
<div class="news__post__text">
|
||||||
{{ post.post_text|raw }}
|
{{ post.post_text|md|raw }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="news__sidebar news__post__details">
|
<div class="news__sidebar news__post__details">
|
||||||
|
|
Loading…
Add table
Reference in a new issue