diff --git a/apps/public/static/js/bbcodeParser.js b/apps/public/static/js/bbcodeParser.js
deleted file mode 100644
index 565ce69..0000000
--- a/apps/public/static/js/bbcodeParser.js
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
-Edited from https://github.com/patorjk/Extendible-BBCode-Parser
-
-By Rhilip, 2018/9/24
-*/
-
-var XBBCODE = (function() {
- "use strict";
-
- // -----------------------------------------------------------------------------
- // Set up private variables
- // -----------------------------------------------------------------------------
-
- var urlPattern = /^[-a-zA-Z0-9:;,@#%&()~_?+=\/\\.]*$/,
- colorPattern = /^(?:[a-z]+|#[0-9abcdef]+)$/,
- fontFacePattern = /^([A-Za-z][A-Za-z0-9_\s]+|"[A-Za-z][A-Za-z0-9_\s]+")$/i;
-
- /* -----------------------------------------------------------------------------
- * tags
- * This object contains a list of tags that your code will be able to understand.
- * Each tag object has the following properties:
- *
- * openTag - A function that takes in the tag's parameters (if any) and its
- * contents, and returns what its HTML open tag should be.
- * Example: [color=red]test[/color] would take in "=red" as a
- * parameter input, and "test" as a content input.
- * It should be noted that any BBCode inside of "content" will have
- * been processed by the time it enter the openTag function.
- *
- * closeTag - A function that takes in the tag's parameters (if any) and its
- * contents, and returns what its HTML close tag should be.
- *
- * displayContent - Defaults to true. If false, the content for the tag will
- * not be displayed. This is useful for tags like IMG where
- * its contents are actually a parameter input.
- *
- * restrictChildrenTo - A list of BBCode tags which are allowed to be nested
- * within this BBCode tag. If this property is omitted,
- * any BBCode tag may be nested within the tag.
- *
- * restrictParentsTo - A list of BBCode tags which are allowed to be parents of
- * this BBCode tag. If this property is omitted, any BBCode
- * tag may be a parent of the tag.
- *
- * noParse - true or false. If true, none of the content WITHIN this tag will be
- * parsed by the XBBCode parser.
- *
- *
- *
- * LIMITIONS on adding NEW TAGS:
- * - Tag names should be alphanumeric (including underscores) and all tags should have an opening tag
- * and a closing tag.
- * The [*] tag is an exception because it was already a standard
- * bbcode tag. Technecially tags don't *have* to be alphanumeric, but since
- * regular expressions are used to parse the text, if you use a non-alphanumeric
- * tag names, just make sure the tag name gets escaped properly (if needed).
- * --------------------------------------------------------------------------- */
-
- var defaultTags = {
- "hr": { openTag: '
', closeTag: '' , displayContent: false},
-
- "b": { openTag: '', closeTag: ' ' },
- "i": { openTag: '', closeTag: ' ' },
- "u": { openTag: '', closeTag: ' ' },
- "s": { openTag: '', closeTag: ' ' },
- "pre": { openTag: '', closeTag: ' ' },
- "sub": { openTag: '', closeTag: ' ' },
- "sup": { openTag: '', closeTag: ' ' },
- "center": { openTag: '', closeTag: '
' },
-
- "code": { openTag: ' Code
', closeTag: '
', noParse: true },
- "noparse": { openTag: '', closeTag: '', noParse: true },
-
- "em": {
- openTag: function (params, content) {
- return ' ';
- },
- closeTag: '',
- displayContent: false
- },
- "img": {
- openTag: function (params, content) {
- return ' ';
- },
- closeTag: '',
- displayContent: false
- },
- "color": {
- openTag: function (params) {
- params = params || '';
-
- var colorCode = (params.substr(1)).toLowerCase() || "black";
- if (!colorPattern.test(colorCode)) {
- colorCode = "black";
- }
-
- return '';
- },
- closeTag: ' '
- },
- "font": {
- openTag: function (params, content) {
- params = params || '';
-
- var faceCode = params.substr(1) || "monospace";
- fontFacePattern.lastIndex = 0;
- if (!fontFacePattern.test(faceCode)) {
- faceCode = "monospace";
- }
- return '';
- },
- closeTag: ' '
- },
- "size": {
- openTag: function(params,content) {
- params = params || '';
-
- var mySize = parseInt(params.substr(1),10) || 2;
- if (mySize < 0 || mySize > 40) {
- mySize = 2;
- }
-
- return '';
- },
- closeTag: ' '
- },
-
- "quote": {
- openTag: function (params, content) {
- return ' Quote ' + ((params && params.length > 1) ? (': ' + params.substr(1)) : "") + ' ';
- },
- closeTag: ' '
- },
- "hide": {
- openTag: function (params, content) {
- return "";
- },
- closeTag: "
"
- },
- "url": {
- openTag: function(params,content) {
- var myUrl = !params ? content.replace(/<.*?>/g, "") : params.substr(1);
- if (!urlPattern.test(myUrl)) {
- myUrl = "#";
- }
-
- return '';
- },
- closeTag: ' '
- },
-
- /*
- The [*] tag is special since the user does not define a closing [/*] tag when writing their bbcode.
- Instead this module parses the code and adds the closing [/*] tag in for them. None of the tags you
- add will act like this and this tag is an exception to the others.
- */
- "list": { openTag: '', restrictChildrenTo: ["*", "li"] },
- "li": { openTag: "", closeTag: " ", restrictParentsTo: ["list","ul","ol"] },
- "ol": { openTag: '', closeTag: ' ', restrictChildrenTo: ["*", "li"] },
- "ul": { openTag: '', restrictChildrenTo: ["*", "li"] },
- "*": { openTag: "", closeTag: " "},
-
- "table": { openTag: '', restrictChildrenTo: ["tbody","thead", "tfoot", "tr"] },
- "tbody": { openTag: '', closeTag: ' ', restrictChildrenTo: ["tr"], restrictParentsTo: ["table"] },
- "tfoot": { openTag: '', closeTag: ' ', restrictChildrenTo: ["tr"], restrictParentsTo: ["table"] },
- "thead": { openTag: '', closeTag: ' ', restrictChildrenTo: ["tr"], restrictParentsTo: ["table"] },
- "td": { openTag: '', closeTag: ' ', restrictParentsTo: ["tr"] },
- "th": { openTag: '', closeTag: ' ', restrictParentsTo: ["tr"] },
- "tr": { openTag: '', closeTag: ' ', restrictChildrenTo: ["td","th"], restrictParentsTo: ["table","tbody","tfoot","thead"] }
- };
-
- function Parser() {
- this._tags = {};
- this._tagList = [];
- this._tagsNoParseList = [];
- this._bbRegExp = null;
- this._pbbRegExp = null;
- this._pbbRegExp2 = null;
- this._openTags = null;
- this._closeTags = null;
- this._initialized = false;
- }
-
- // create tag list and lookup fields
- Parser.prototype._initTags = function() {
- var self = this;
- this._tagList = [];
- var tags = this._tags;
- var prop,
- ii,
- len;
- for (prop in tags) {
- if (tags.hasOwnProperty(prop)) {
- if (prop === "*") {
- this._tagList.push("\\" + prop);
- } else {
- this._tagList.push(prop);
- if ( tags[prop].noParse ) {
- this._tagsNoParseList.push(prop);
- }
- }
-
- tags[prop].validChildLookup = {};
- tags[prop].validParentLookup = {};
- tags[prop].restrictParentsTo = tags[prop].restrictParentsTo || [];
- tags[prop].restrictChildrenTo = tags[prop].restrictChildrenTo || [];
-
- len = tags[prop].restrictChildrenTo.length;
- for (ii = 0; ii < len; ii++) {
- tags[prop].validChildLookup[ tags[prop].restrictChildrenTo[ii] ] = true;
- }
- len = tags[prop].restrictParentsTo.length;
- for (ii = 0; ii < len; ii++) {
- tags[prop].validParentLookup[ tags[prop].restrictParentsTo[ii] ] = true;
- }
- }
- }
-
- this._bbRegExp = new RegExp("]*?)?>((?:.|[\\r\\n])*?)", "gi");
- this._pbbRegExp = new RegExp("\\[(" + this._tagList.join("|") + ")([ =][^\\]]*?)?\\]([^\\[]*?)\\[/\\1\\]", "gi");
- this._pbbRegExp2 = new RegExp("\\[(" + this._tagsNoParseList.join("|") + ")([ =][^\\]]*?)?\\]([\\s\\S]*?)\\[/\\1\\]", "gi");
-
- // create the regex for escaping ['s that aren't apart of tags
- (function() {
- var closeTagList = [];
- for (var ii = 0; ii < self._tagList.length; ii++) {
- if ( self._tagList[ii] !== "\\*" ) { // the * tag doesn't have an offical closing tag
- closeTagList.push ( "/" + self._tagList[ii] );
- }
- }
-
- self._openTags = new RegExp("(\\[)((?:" + self._tagList.join("|") + ")(?:[ =][^\\]]*?)?)(\\])", "gi");
- self._closeTags = new RegExp("(\\[)(" + closeTagList.join("|") + ")(\\])", "gi");
- })();
- this._initialized = true;
- };
-
- // -----------------------------------------------------------------------------
- // private functions
- // -----------------------------------------------------------------------------
-
- Parser.prototype._checkParentChildRestrictions = function(parentTag, bbcode, bbcodeLevel, tagName,
- tagParams, tagContents, errQueue) {
- var self = this;
- errQueue = errQueue || [];
- bbcodeLevel++;
-
- // get a list of all of the child tags to this tag
- var reTagNames = new RegExp("(])","gi"),
- reTagNamesParts = new RegExp("(])","i"),
- matchingTags = tagContents.match(reTagNames) || [],
- cInfo,
- errStr,
- ii,
- childTag,
- pInfo = this._tags[parentTag] || {};
-
- reTagNames.lastIndex = 0;
-
- if (!matchingTags) {
- tagContents = "";
- }
-
- for (ii = 0; ii < matchingTags.length; ii++) {
- reTagNamesParts.lastIndex = 0;
- childTag = (matchingTags[ii].match(reTagNamesParts))[2].toLowerCase();
-
- if ( pInfo && pInfo.restrictChildrenTo && pInfo.restrictChildrenTo.length > 0 ) {
- if ( !pInfo.validChildLookup[childTag] ) {
- errStr = "The tag \"" + childTag + "\" is not allowed as a child of the tag \"" + parentTag + "\".";
- errQueue.push(errStr);
- }
- }
- cInfo = this._tags[childTag] || {};
- if ( cInfo.restrictParentsTo.length > 0 ) {
- if ( !cInfo.validParentLookup[parentTag] ) {
- errStr = "The tag \"" + parentTag + "\" is not allowed as a parent of the tag \"" + childTag + "\".";
- errQueue.push(errStr);
- }
- }
-
- }
-
- tagContents = tagContents.replace(this._bbRegExp, function(matchStr, bbcodeLevel, tagName, tagParams, tagContents ) {
- errQueue = self._checkParentChildRestrictions(tagName.toLowerCase(), matchStr, bbcodeLevel, tagName, tagParams, tagContents, errQueue);
- return matchStr;
- });
- return errQueue;
- };
-
- /*
- This function updates or adds a piece of metadata to each tag called "bbcl" which
- indicates how deeply nested a particular tag was in the bbcode. This property is removed
- from the HTML code tags at the end of the processing.
- */
- Parser.prototype._updateTagDepths = function(tagContents) {
- tagContents = tagContents.replace(/\<([^\>][^\>]*?)\>/gi, function(matchStr, subMatchStr) {
- var bbCodeLevel = subMatchStr.match(/^bbcl=([0-9]+) /);
- if (bbCodeLevel === null) {
- return "";
- } else {
- return "<" + subMatchStr.replace(/^(bbcl=)([0-9]+)/, function(matchStr, m1, m2) {
- return m1 + (parseInt(m2, 10) + 1);
- }) + ">";
- }
- });
- return tagContents;
- };
-
- /*
- This function removes the metadata added by the updateTagDepths function
- */
- Parser.prototype._unprocess = function(tagContent) {
- return tagContent.replace(//gi,"").replace(/ /gi,"]");
- };
-
- Parser.prototype._parse = function(config) {
- var self = this;
- var output = config.text;
-
- var replaceFunct = function(matchStr, bbcodeLevel, tagName, tagParams, tagContents) {
- tagName = tagName.toLowerCase();
-
- var processedContent = self._tags[tagName].noParse ? self._unprocess(tagContents) : tagContents.replace(self._bbRegExp, replaceFunct),
- openTag = typeof self._tags[tagName].openTag === "function" ? self._tags[tagName].openTag(tagParams,processedContent) : self._tags[tagName].openTag,
- closeTag = typeof self._tags[tagName].closeTag === "function" ? self._tags[tagName].closeTag(tagParams,processedContent) : self._tags[tagName].closeTag;
-
- if (self._tags[tagName].displayContent === false) {
- processedContent = "";
- }
-
- return openTag + processedContent + closeTag;
- };
-
- output = output.replace(this._bbRegExp, replaceFunct);
- return output;
- };
-
- /*
- The star tag [*] is special in that it does not use a closing tag. Since this parser requires that tags to have a closing
- tag, we must pre-process the input and add in closing tags [/*] for the star tag.
- We have a little levaridge in that we know the text we're processing wont contain the <> characters (they have been
- changed into their HTML entity form to prevent XSS and code injection), so we can use those characters as markers to
- help us define boundaries and figure out where to place the [/*] tags.
- */
- Parser.prototype._fixStarTag = function(text) {
- text = text.replace(/\[(?!\*[ =\]]|list([ =][^\]]*)?\]|\/list[\]])/ig, "<");
- text = text.replace(/\[(?=list([ =][^\]]*)?\]|\/list[\]])/ig, ">");
-
- while (text !== (text = text.replace(/>list([ =][^\]]*)?\]([^>]*?)(>\/list])/gi, function(matchStr,contents,endTag) {
-
- var innerListTxt = matchStr;
- while (innerListTxt !== (innerListTxt = innerListTxt.replace(/\[\*\]([^\[]*?)(\[\*\]|>\/list])/i, function(matchStr,contents,endTag) {
- if (endTag.toLowerCase() === ">/list]") {
- endTag = "*]/g, "<");
- return innerListTxt;
- })));
-
- // add ['s for our tags back in
- text = text.replace(/");
- return self._updateTagDepths(matchStr);
- })) );
- return text;
- };
-
- // -----------------------------------------------------------------------------
- // public functions
- // -----------------------------------------------------------------------------
-
- // API, Expose all available tags
- Parser.prototype.tags = function() {
- return this._tags;
- };
-
- // API
- Parser.prototype.addTags = function(newtags) {
- var tag;
- for (tag in newtags) {
- this._tags[tag] = newtags[tag];
- }
- this._initTags();
- };
-
- Parser.prototype.addDefaultTags = function() {
- this.addTags(defaultTags);
- };
-
- Parser.prototype.process = function(config) {
- if (!this._initialized) {
- throw new Error('Tags are not initialized');
- }
- var ret = { html: "", error: false }, errQueue = [];
-
- // Replace Old tag before Convert
- config.text = config.text.replace(/\[site]\[\/site]/g,"[site]").replace(/\[site]/g,"[site][/site]");
- config.text = config.text.replace(/\[siteurl]\[\/siteurl]/g,"[siteurl]").replace(/\[siteurl]/g,"[siteurl][/siteurl]");
- config.text = config.text.replace(/\[em(\d+)]/g,"[em]$1[/em]");
- config.text = config.text.replace(/\[hr[ /]{1,2}]/g,"[hr]No parser[/hr]");
-
- // escape HTML tag brackets
- config.text = config.text.replace(//g, ">");
-
- config.text = config.text.replace(this._openTags, function(matchStr, openB, contents, closeB) {
- return "<" + contents + ">";
- });
- config.text = config.text.replace(this._closeTags, function(matchStr, openB, contents, closeB) {
- return "<" + contents + ">";
- });
-
- config.text = config.text.replace(/\[/g, "["); // escape ['s that aren't apart of tags
- config.text = config.text.replace(/\]/g, "]"); // escape ['s that aren't apart of tags
- config.text = config.text.replace(//g, "]"); // escape ['s that aren't apart of tags
- config.text = config.text.replace(/ /g," "); // escape whitespace
-
- // process tags that don't have their content parsed
- while ( config.text !== (config.text = config.text.replace(this._pbbRegExp2, function(matchStr, tagName, tagParams, tagContents) {
- tagContents = tagContents.replace(/\[/g, "[");
- tagContents = tagContents.replace(/\]/g, "]");
- tagParams = tagParams || "";
- tagContents = tagContents || "";
- return "[" + tagName + tagParams + "]" + tagContents + "[/" + tagName + "]";
- })) );
-
- config.text = this._fixStarTag(config.text); // add in closing tags for the [*] tag
- config.text = this._addBbcodeLevels(config.text); // add in level metadata
-
- errQueue = this._checkParentChildRestrictions("bbcode", config.text, -1, "", "", config.text);
-
- ret.html = this._parse(config);
-
- if ( ret.html.indexOf("[") !== -1 || ret.html.indexOf("]") !== -1) {
- errQueue.push("Some tags appear to be misaligned, We will try to fix it.");
- ret.html = ret.html.replace(/\[color=([A-Za-z]+|#[0-9abcdef]+)]/g,'').replace(/\[\/color]/g," ");
- ret.html = ret.html.replace(/\[font=([A-Za-z][A-Za-z0-9_\s]+|"[A-Za-z][A-Za-z0-9_\s]+")]/g,'').replace(/\[\/font]/g," ");
- ret.html = ret.html.replace(/\[size=(\d+)]/g,'').replace(/\[\/size]/g," ");
- ret.html = ret.html.replace(/\[([bius])]/g,"<$1>").replace(/\[\/([bius])]/g,"$1>");
- ret.html = ret.html.replace(/\[\*]/g,' ');
-
- var left_quote_match = ret.html.match(/\[quote.*?]/g), right_quote_match = ret.html.match(/\[\/quote]/g);
- if (left_quote_match && right_quote_match && left_quote_match.length === right_quote_match.length) {
- ret.html = ret.html.replace(/\[quote]/g,' Quote ');
- ret.html = ret.html.replace(/\[quote=(.+?)]/g,' Quote : $1 ');
- ret.html = ret.html.replace(/\[\/quote]/g,' ');
- }
- }
-
- if (config.removeMisalignedTags) {
- ret.html = ret.html.replace(/\[.*?\]/g,"");
- }
- if (config.addInLineBreaks) {
- ret.html = '' + ret.html + '
';
- }
-
- if (!config.escapeHtml) {
- ret.html = ret.html.replace("[", "["); // put ['s back in
- ret.html = ret.html.replace("]", "]"); // put ['s back in
- }
-
- ret.html = ret.html.replace(/\n/g," ");
-
- ret.error = errQueue.length !== 0;
- ret.errorQueue = errQueue;
-
- return ret;
- };
-
- var parser = {};
- parser = new Parser();
- parser.addDefaultTags();
- parser.Parser = Parser;
-
- return parser;
-})();
diff --git a/apps/public/static/js/main.js b/apps/public/static/js/main.js
index 3a78934..b5a4940 100644
--- a/apps/public/static/js/main.js
+++ b/apps/public/static/js/main.js
@@ -37,22 +37,6 @@ jQuery(document).ready(function() {
return new $.zui.Messager(text, option).show();
}
- // Convert ubbcode blcok text to html
- $(".ubbcode-block").html(function (index, oldhtml) {
- /*
- Because:
- 1. Cloudflare or other CDN may clean the newline characters like `\n`
- 2. our backend use nl2br() to Inserts HTML line breaks before all newlines in a string,
- It's needed to to remove the exist `\n` (if case 1 not happened), and change the html tag ` ` to `\n`,
- then feed to our XBBCODE converter for safety output.
- */
- oldhtml = oldhtml.trim()
- .replace(/\n/ig, '')
- .replace(/ /ig, '\n');
- return XBBCODE.process({text: oldhtml}).html;
- });
-
-
// Torrent favour Add/Remove action
$('.torrent-favour').click(function () {
let that = $(this);
diff --git a/apps/views/layout/base.php b/apps/views/layout/base.php
index 559bad2..edcd842 100644
--- a/apps/views/layout/base.php
+++ b/apps/views/layout/base.php
@@ -150,7 +150,6 @@
-
diff --git a/composer.json b/composer.json
index da83c95..c7b82f0 100644
--- a/composer.json
+++ b/composer.json
@@ -33,7 +33,8 @@
"robthree/twofactorauth": "^1.6",
"swiftmailer/swiftmailer": "^6.1",
"siriusphp/validation": "^2.2",
- "phpmailer/phpmailer": "^6.0"
+ "phpmailer/phpmailer": "^6.0",
+ "mjohnson/decoda": "^6.12"
},
"autoload": {
"psr-4": {
diff --git a/composer.lock b/composer.lock
index a082c15..14acebe 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "2968ff93657f8d81d11272ad7fa0a007",
+ "content-hash": "14fed92df6bf165c64a519f489ac653f",
"packages": [
{
"name": "doctrine/lexer",
@@ -190,6 +190,66 @@
],
"time": "2016-12-28T00:14:17+00:00"
},
+ {
+ "name": "mjohnson/decoda",
+ "version": "6.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/milesj/decoda.git",
+ "reference": "9817fd5abbd742384f59831d8a5953b01803b45d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/milesj/decoda/zipball/9817fd5abbd742384f59831d8a5953b01803b45d",
+ "reference": "9817fd5abbd742384f59831d8a5953b01803b45d",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8|^7.5"
+ },
+ "suggest": {
+ "ext-memcached": "Cache data using Memcache",
+ "ext-redis": "Cache data using Redis"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Decoda": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Miles Johnson",
+ "homepage": "http://milesj.me"
+ }
+ ],
+ "description": "A lightweight lexical string parser for BBCode styled markup.",
+ "homepage": "http://milesj.me/code/php/decoda",
+ "keywords": [
+ "HOOK",
+ "bbcode",
+ "decoda",
+ "filter",
+ "lexer",
+ "markup",
+ "parser"
+ ],
+ "time": "2019-01-16T04:52:14+00:00"
+ },
{
"name": "phpmailer/phpmailer",
"version": "v6.0.7",
diff --git a/framework/Redis/BaseRedisConnection.php b/framework/Redis/BaseRedisConnection.php
index 814ef52..abe7b10 100644
--- a/framework/Redis/BaseRedisConnection.php
+++ b/framework/Redis/BaseRedisConnection.php
@@ -302,4 +302,12 @@ public function getCalledData()
{
return $this->_calledData;
}
+
+ /**
+ * @return \Redis
+ */
+ public function getRedis(): \Redis
+ {
+ return $this->_redis;
+ }
}
diff --git a/framework/View/Conversion.php b/framework/View/Conversion.php
index 2f028b0..08a676e 100644
--- a/framework/View/Conversion.php
+++ b/framework/View/Conversion.php
@@ -8,6 +8,8 @@
namespace Rid\View;
+use Decoda\Decoda;
+use Decoda\Storage\RedisStorage;
use League\Plates\Engine;
use League\Plates\Extension\ExtensionInterface;
@@ -39,9 +41,13 @@ public function format_bytes($bytes, $precision = 2)
public function format_ubbcode($string)
{
- $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
- $string = str_replace(array_keys(self::UBBCODE_MAP), array_values(self::UBBCODE_MAP), $string);
- $string = nl2br($string);
- return $string;
+ $code = new Decoda($string,[
+ 'escapeHtml' => true
+ ],'Post_cache:' . md5($string));
+
+ $code->defaults();
+
+ $code->setStorage(new RedisStorage(app()->redis->getRedis()));
+ return $code->parse();
}
}