2017-12-07
This commit is contained in:
parent
375a014e20
commit
c49db50c23
10 changed files with 215 additions and 104 deletions
|
@ -92,21 +92,34 @@ class Mail
|
|||
public function valid($email, $strict = false, $idna = false)
|
||||
{
|
||||
if (! is_string($email)
|
||||
|| mb_strlen($email, 'UTF-8') > 80
|
||||
|| ! preg_match('%^([a-z0-9_!#$\%&\'*+-/=?^`{|}~]+(?:\.[a-z0-9_!#$\%&\'*+-/=?^`{|}~]+)*)@([^\x00-\x20]+)$%Di', $email, $matches)
|
||||
|| mb_strlen($email, 'UTF-8') > 80 //?????
|
||||
|| ! preg_match('%^([^\x00-\x1F\\\/\s@]+)@([^\x00-\x1F\s@]+)$%Du', $email, $matches)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
$local = $matches[1];
|
||||
$domain = mb_strtolower($matches[2], 'UTF-8');
|
||||
if (! preg_match('%^(?:[\p{L}\p{N}]+(?:\-[\p{L}\p{N}]+)*\.)*\p{L}+$%u', $domain)) {
|
||||
return false;
|
||||
|
||||
if ($domain{0} === '[' && substr($domain, -1) === ']') {
|
||||
$ip = substr($domain, 1, -1);
|
||||
if (! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
return $false;
|
||||
}
|
||||
$domainASCII = $domain;
|
||||
} else {
|
||||
$ip = null;
|
||||
if (! preg_match('%^(?:[\p{L}\p{N}]+(?:\-[\p{L}\p{N}]+)*\.)*\p{L}+$%u', $domain)) {
|
||||
return false;
|
||||
}
|
||||
$domainASCII = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
|
||||
}
|
||||
|
||||
$domainASCII = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
|
||||
|
||||
if ($strict) {
|
||||
$mx = @dns_get_record($domainASCII, DNS_MX); //????
|
||||
if ($ip) {
|
||||
$mx = @checkdnsrr($ip, 'MX');
|
||||
} else {
|
||||
$mx = @dns_get_record($domainASCII, DNS_MX);
|
||||
}
|
||||
if (empty($mx)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace ForkBB\Core;
|
||||
|
||||
use Parserus;
|
||||
use ForkBB\Core\Container;
|
||||
|
||||
class Parser extends Parserus
|
||||
{
|
||||
|
@ -65,4 +66,92 @@ class Parser extends Parserus
|
|||
}
|
||||
return parent::addBBCode($bb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет разметку сообщения с бб-кодами
|
||||
* Пытается исправить неточности разметки
|
||||
* Генерирует ошибки разметки
|
||||
*
|
||||
* @param string $text
|
||||
* @param bool $isSignature
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function prepare($text, $isSignature = false)
|
||||
{
|
||||
if ($isSignature) {
|
||||
$whiteList = $this->c->config->p_sig_bbcode == '1' ? $this->c->BBCODE_INFO['forSign'] : [];
|
||||
$blackList = $this->c->config->p_sig_img_tag == '1' ? [] : ['img'];
|
||||
} else {
|
||||
$whiteList = $this->c->config->p_message_bbcode == '1' ? null : [];
|
||||
$blackList = $this->c->config->p_message_img_tag == '1' ? [] : ['img'];
|
||||
}
|
||||
|
||||
$this->setAttr('isSign', $isSignature)
|
||||
->setWhiteList($whiteList)
|
||||
->setBlackList($blackList)
|
||||
->parse($text, ['strict' => true])
|
||||
->stripEmptyTags(" \n\t\r\v", true);
|
||||
|
||||
if ($this->c->config->o_make_links == '1') {
|
||||
$this->detectUrls();
|
||||
}
|
||||
|
||||
return preg_replace('%^(\x20*\n)+|(\n\x20*)+$%D', '', $this->getCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует бб-коды в html в сообщениях
|
||||
*
|
||||
* @param null|string $text
|
||||
* @param bool $hideSmilies
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseMessage($text = null, $hideSmilies = false)
|
||||
{
|
||||
// при null предполагается брать данные после prepare()
|
||||
if (null !== $text) {
|
||||
$whiteList = $this->c->config->p_message_bbcode == '1' ? null : [];
|
||||
$blackList = $this->c->config->p_message_img_tag == '1' ? [] : ['img'];
|
||||
|
||||
$this->setAttr('isSign', false)
|
||||
->setWhiteList($whiteList)
|
||||
->setBlackList($blackList)
|
||||
->parse($text);
|
||||
}
|
||||
|
||||
if (! $hideSmilies && $this->c->config->o_smilies == '1') {
|
||||
$this->detectSmilies();
|
||||
}
|
||||
|
||||
return $this->getHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует бб-коды в html в подписях пользователей
|
||||
*
|
||||
* @param null|string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseSignature($text = null)
|
||||
{
|
||||
// при null предполагается брать данные после prepare()
|
||||
if (null !== $text) {
|
||||
$whiteList = $this->c->config->p_sig_bbcode == '1' ? $this->c->BBCODE_INFO['forSign'] : [];
|
||||
$blackList = $this->c->config->p_sig_img_tag == '1' ? [] : ['img'];
|
||||
|
||||
$this->setAttr('isSign', true)
|
||||
->setWhiteList($whiteList)
|
||||
->setBlackList($blackList)
|
||||
->parse($text);
|
||||
}
|
||||
|
||||
if ($this->c->config->o_smilies_sig == '1') {
|
||||
$this->detectSmilies();
|
||||
}
|
||||
|
||||
return $this->getHtml();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace ForkBB\Core;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Router
|
||||
{
|
||||
const OK = 200;
|
||||
|
@ -103,40 +105,43 @@ class Router
|
|||
public function link($marker = null, array $args = [])
|
||||
{
|
||||
$result = $this->baseUrl;
|
||||
if (is_string($marker) && isset($this->links[$marker])) {
|
||||
$s = $this->links[$marker];
|
||||
foreach ($args as $key => $val) {
|
||||
if ($key == '#') {
|
||||
$s .= '#' . rawurlencode($val);
|
||||
continue;
|
||||
} elseif ($key == 'page' && $val === 1) {
|
||||
$anchor = isset($args['#']) ? '#' . rawurlencode($args['#']) : '';
|
||||
|
||||
// маркер пустой
|
||||
if (null === $marker) {
|
||||
return $result . "/{$anchor}";
|
||||
// такой ссылки нет
|
||||
} elseif (! isset($this->links[$marker])) {
|
||||
return $result . '/';
|
||||
// ссылка статична
|
||||
} elseif (is_string($data = $this->links[$marker])) {
|
||||
return $result . $data . $anchor;
|
||||
}
|
||||
|
||||
list($link, $names, $request) = $data;
|
||||
$data = [];
|
||||
// перечисление имен переменных для построения ссылки
|
||||
foreach ($names as $name) {
|
||||
// значение есть
|
||||
if (isset($args[$name])) {
|
||||
// кроме page = 1
|
||||
if ($name != 'page' || $args[$name] !== 1) {
|
||||
$data['{' . $name . '}'] = rawurlencode(preg_replace('%[\s\\\/]+%u', '-', $args[$name]));
|
||||
continue;
|
||||
}
|
||||
$s = preg_replace_callback( //????
|
||||
'%\{' . preg_quote($key, '%') . '(?::[^{}]+)?\}%',
|
||||
function($match) use ($val) {
|
||||
if (is_string($val)) {
|
||||
$val = trim(preg_replace('%[^\p{L}\p{N}_]+%u', '-', $val), '_-');
|
||||
} elseif (is_numeric($val)) { //????
|
||||
$val = (string) $val;
|
||||
} else {
|
||||
$val = null;
|
||||
}
|
||||
return isset($val[0]) ? rawurlencode($val) : '-';
|
||||
},
|
||||
$s
|
||||
);
|
||||
}
|
||||
$s = preg_replace('%\[[^{}\[\]]*\{[^}]+\}[^{}\[\]]*\]%', '', $s);
|
||||
if (strpos($s, '{') === false) {
|
||||
$result .= str_replace(['[', ']'], '', $s);
|
||||
|
||||
// значения нет, но оно обязательно
|
||||
if ($request[$name]) {
|
||||
return $result . '/';
|
||||
// значение не обязательно
|
||||
} else {
|
||||
$result .= '/';
|
||||
$link = preg_replace('%\[[^\[\]{}]*{' . preg_quote($name, '%') . '}[^\[\]{}]*\]%', '', $link);
|
||||
}
|
||||
} else {
|
||||
$result .= '/';
|
||||
}
|
||||
return $result;
|
||||
$link = str_replace(['[', ']'], '', $link);
|
||||
|
||||
return $result . strtr($link, $data) . $anchor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,12 +232,15 @@ class Router
|
|||
$this->methods[$method] = 1;
|
||||
}
|
||||
|
||||
$link = $route;
|
||||
if (($pos = strpos($route, '#')) !== false) {
|
||||
$route = substr($route, 0, $pos);
|
||||
$link = $route;
|
||||
$anchor = '';
|
||||
if (false !== strpos($route, '#')) {
|
||||
list($route, $anchor) = explode('#', $route, 2);
|
||||
$anchor = '#' . $anchor;
|
||||
}
|
||||
|
||||
if (false === strpbrk($route, '{}[]')) {
|
||||
$data = null;
|
||||
if (is_array($method)) {
|
||||
foreach ($method as $m) {
|
||||
$this->statical[$route][$m] = $handler;
|
||||
|
@ -255,7 +263,11 @@ class Router
|
|||
}
|
||||
|
||||
if ($marker) {
|
||||
$this->links[$marker] = $link;
|
||||
if ($data) {
|
||||
$this->links[$marker] = [$data[3] . $anchor, $data[2], $data[4]];
|
||||
} else {
|
||||
$this->links[$marker] = $link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,11 +293,14 @@ class Router
|
|||
}
|
||||
|
||||
$pattern = '%^';
|
||||
$var = false;
|
||||
$first = false;
|
||||
$buffer = '';
|
||||
$args = [];
|
||||
$s = 0;
|
||||
$var = false;
|
||||
$first = false;
|
||||
$buffer = '';
|
||||
$args = [];
|
||||
$s = 0;
|
||||
$req = true;
|
||||
$argReq = [];
|
||||
$temp = '';
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if ($var) {
|
||||
|
@ -301,9 +316,11 @@ class Router
|
|||
return false;
|
||||
}
|
||||
$pattern .= '(?P<' . $data[0] . '>' . $data[1] . ')';
|
||||
$args[] = $data[0];
|
||||
$var = false;
|
||||
$buffer = '';
|
||||
$args[] = $data[0];
|
||||
$temp .= '{' . $data[0] . '}';
|
||||
$var = false;
|
||||
$buffer = '';
|
||||
$argsReq[$data[0]] = $req;
|
||||
break;
|
||||
default:
|
||||
$buffer .= $part;
|
||||
|
@ -311,8 +328,9 @@ class Router
|
|||
} elseif ($first) {
|
||||
switch ($part) {
|
||||
case '/':
|
||||
$first = false;
|
||||
$first = false;
|
||||
$pattern .= preg_quote($part, '%');
|
||||
$temp .= $part;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -322,7 +340,9 @@ class Router
|
|||
case '[':
|
||||
++$s;
|
||||
$pattern .= '(?:';
|
||||
$first = true;
|
||||
$first = true;
|
||||
$req = false;
|
||||
$temp .= '[';
|
||||
break;
|
||||
case ']':
|
||||
--$s;
|
||||
|
@ -330,6 +350,8 @@ class Router
|
|||
return false;
|
||||
}
|
||||
$pattern .= ')?';
|
||||
$req = true;
|
||||
$temp .= ']';
|
||||
break;
|
||||
case '{':
|
||||
$var = true;
|
||||
|
@ -338,6 +360,7 @@ class Router
|
|||
return false;
|
||||
default:
|
||||
$pattern .= preg_quote($part, '%');
|
||||
$temp .= $part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -345,6 +368,6 @@ class Router
|
|||
return false;
|
||||
}
|
||||
$pattern .= '$%D';
|
||||
return [$base, $pattern, $args];
|
||||
return [$base, $pattern, $args, $temp, $argsReq];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ class Auth extends Page
|
|||
$user->update();
|
||||
|
||||
$this->c->Online->delete($this->c->user);
|
||||
$this->c->Cookie->setUser($user);
|
||||
$this->c->Cookie->setUser($user, (bool) $v->save);
|
||||
}
|
||||
}
|
||||
return $password;
|
||||
|
|
|
@ -67,7 +67,7 @@ class Post extends Page
|
|||
$args['_vars'] = $v->getData();
|
||||
|
||||
if (null !== $v->preview && ! $v->getErrors()) {
|
||||
$this->previewHtml = $this->c->Parser->getHtml();
|
||||
$this->previewHtml = $this->c->Parser->parseMessage(null, (bool) $v->hide_smilies);
|
||||
}
|
||||
|
||||
return $this->newTopic($args, $forum);
|
||||
|
@ -105,7 +105,7 @@ class Post extends Page
|
|||
|
||||
$this->nameTpl = 'post';
|
||||
$this->onlinePos = 'topic-' . $topic->id;
|
||||
$this->canonical = $this->c->Router->link('NewReply', $args);
|
||||
$this->canonical = $this->c->Router->link('NewReply', ['id' => $topic->id]);
|
||||
$this->robots = 'noindex';
|
||||
$this->crumbs = $this->crumbs(__('Post a reply'), $topic);
|
||||
$this->form = $this->messageForm($topic, 'NewReply', $args);
|
||||
|
@ -142,7 +142,7 @@ class Post extends Page
|
|||
$args['_vars'] = $v->getData();
|
||||
|
||||
if (null !== $v->preview && ! $v->getErrors()) {
|
||||
$this->previewHtml = $this->c->Parser->getHtml();
|
||||
$this->previewHtml = $this->c->Parser->parseMessage(null, (bool) $v->hide_smilies);
|
||||
}
|
||||
|
||||
return $this->newReply($args, $topic);
|
||||
|
@ -206,9 +206,10 @@ class Post extends Page
|
|||
|
||||
// попытка объеденить новое сообщение с крайним в теме
|
||||
if ($merge) {
|
||||
$lastPost = $this->c->ModelPost->load($topic->last_post_id);
|
||||
$lastPost = $this->c->ModelPost->load($topic->last_post_id);
|
||||
$newLength = mb_strlen($lastPost->message . $v->message, 'UTF-8');
|
||||
|
||||
if ($this->c->MAX_POST_SIZE > mb_strlen($lastPost->message . $v->message, 'UTF-8') + 100) { //????
|
||||
if ($newLength < $this->c->MAX_POST_SIZE - 100) {
|
||||
$lastPost->message = $lastPost->message . "\n[after=" . ($now - $topic->last_post) . "]\n" . $v->message; //????
|
||||
$lastPost->posted = $lastPost->posted + 1; //???? прибаляем 1 секунду для появления в новых //????
|
||||
|
||||
|
@ -339,7 +340,7 @@ class Post extends Page
|
|||
* @param Validator $v
|
||||
* @param string $message
|
||||
*
|
||||
* @return array
|
||||
* @return string
|
||||
*/
|
||||
public function vCheckMessage(Validator $v, $message, $attr, $executive)
|
||||
{
|
||||
|
@ -355,23 +356,7 @@ class Post extends Page
|
|||
$v->addError('All caps message');
|
||||
// проверка парсером
|
||||
} else {
|
||||
|
||||
$bbWList = $this->c->config->p_message_bbcode == '1' ? null : [];
|
||||
$bbBList = $this->c->config->p_message_img_tag == '1' ? [] : ['img'];
|
||||
|
||||
$this->c->Parser->setAttr('isSign', false)
|
||||
->setWhiteList($bbWList)
|
||||
->setBlackList($bbBList)
|
||||
->parse($message, ['strict' => true])
|
||||
->stripEmptyTags(" \n\t\r\v", true);
|
||||
|
||||
if ($this->c->config->o_make_links == '1') {
|
||||
$this->c->Parser->detectUrls();
|
||||
}
|
||||
|
||||
if ($v->hide_smilies != '1' && $this->c->config->o_smilies == '1') {
|
||||
$this->c->Parser->detectSmilies();
|
||||
}
|
||||
$message = $this->c->Parser->prepare($message); //????
|
||||
|
||||
foreach($this->c->Parser->getErrors() as $error) {
|
||||
$v->addError($error);
|
||||
|
@ -381,6 +366,30 @@ class Post extends Page
|
|||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка времени ограничения флуда
|
||||
*
|
||||
* @param Validator $v
|
||||
* @param null|string $submit
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function vCheckTimeout(Validator $v, $submit)
|
||||
{
|
||||
if (null === $submit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = $this->c->user;
|
||||
$time = time() - (int) $user->last_post;
|
||||
|
||||
if ($time < $user->g_post_flood) {
|
||||
$v->addError(__('Flood start', $user->g_post_flood, $user->g_post_flood - $time), 'e');
|
||||
}
|
||||
|
||||
return $submit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Подготовка валидатора к проверке данных из формы создания темы/сообщения
|
||||
*
|
||||
|
@ -436,6 +445,7 @@ class Post extends Page
|
|||
'check_username' => [$this, 'vCheckUsername'],
|
||||
'check_subject' => [$this, 'vCheckSubject'],
|
||||
'check_message' => [$this, 'vCheckMessage'],
|
||||
'check_timeout' => [$this, 'vCheckTimeout'],
|
||||
])->setRules([
|
||||
'token' => 'token:' . $marker,
|
||||
'email' => [$ruleEmail, __('Email')],
|
||||
|
@ -445,8 +455,8 @@ class Post extends Page
|
|||
'stick_fp' => $ruleStickFP,
|
||||
'merge_post' => $ruleMergePost,
|
||||
'hide_smilies' => $ruleHideSmilies,
|
||||
'submit' => 'string', //????
|
||||
'preview' => 'string', //????
|
||||
'submit' => 'string|check_timeout', //????
|
||||
'message' => 'required|string:trim|max:' . $this->c->MAX_POST_SIZE . '|check_message',
|
||||
])->setArguments([
|
||||
'token' => $args,
|
||||
|
|
|
@ -115,18 +115,6 @@ class Post extends DataModel
|
|||
*/
|
||||
public function html()
|
||||
{
|
||||
$bbWList = $this->c->config->p_message_bbcode == '1' ? null : [];
|
||||
$bbBList = $this->c->config->p_message_img_tag == '1' ? [] : ['img'];
|
||||
|
||||
$parser = $this->c->Parser->setAttr('isSign', false)
|
||||
->setWhiteList($bbWList)
|
||||
->setBlackList($bbBList)
|
||||
->parse($this->cens()->message);
|
||||
|
||||
if ($this->hide_smilies != '1' && $this->c->config->o_smilies == '1') {
|
||||
$parser->detectSmilies();
|
||||
}
|
||||
|
||||
return $parser->getHtml();
|
||||
return $this->c->Parser->parseMessage($this->cens()->message, (bool) $this->hide_smilies); //????
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,18 +199,6 @@ class User extends DataModel
|
|||
*/
|
||||
protected function gethtmlSign()
|
||||
{
|
||||
$bbWList = $this->c->config->p_sig_bbcode == '1' ? $this->c->BBCODE_INFO['forSign'] : [];
|
||||
$bbBList = $this->c->config->p_sig_img_tag == '1' ? [] : ['img'];
|
||||
|
||||
$parser = $this->c->Parser->setAttr('isSign', true)
|
||||
->setWhiteList($bbWList)
|
||||
->setBlackList($bbBList)
|
||||
->parse($this->cens()->signature);
|
||||
|
||||
if ($this->c->config->o_smilies_sig == '1') {
|
||||
$parser->detectSmilies();
|
||||
}
|
||||
|
||||
return $parser->getHtml();
|
||||
return $this->c->Parser->parseSignature($this->cens()->signature); //????
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ msgid "Topic review"
|
|||
msgstr "Topic review (newest first)"
|
||||
|
||||
msgid "Flood start"
|
||||
msgstr "At least %s seconds have to pass between posts. Please wait %s seconds and try posting again."
|
||||
msgstr "At least %1$s seconds have to pass between posts. Please wait %2$s seconds and try posting again."
|
||||
|
||||
msgid "Preview"
|
||||
msgstr "Preview"
|
||||
|
|
|
@ -73,7 +73,7 @@ msgid "Topic review"
|
|||
msgstr "Обзор темы (новое вверху)"
|
||||
|
||||
msgid "Flood start"
|
||||
msgstr "Хотя бы %s секунд должно пройти между отправкой сообщений. Пожалуйста, подождите %s секунд и попробуйте снова."
|
||||
msgstr "Хотя бы %1$s секунд должно пройти между отправкой сообщений. Пожалуйста, подождите %2$s секунд и попробуйте снова."
|
||||
|
||||
msgid "Preview"
|
||||
msgstr "Предпросмотр"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<h2>{!! __('Post preview') !!}</h2>
|
||||
<div class="f-post-body clearfix">
|
||||
<div class="f-post-right f-post-main">
|
||||
{!! $p->previewHtml !!}
|
||||
{!! $p->cens()->previewHtml !!}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
Loading…
Reference in a new issue