2018-01-19

This commit is contained in:
Visman 2018-01-19 23:13:49 +07:00
parent e81cfb21d7
commit 9ff60e147e
15 changed files with 423 additions and 200 deletions

View file

@ -17,9 +17,9 @@ class Manager extends ManagerModel
/**
* Создает новую модель раздела
*
*
* @param array $attrs
*
*
* @return Forum
*/
public function create(array $attrs = [])
@ -29,7 +29,7 @@ class Manager extends ManagerModel
/**
* Инициализация списка разделов
*
*
* @param Group $group
*
* @return Manager
@ -61,9 +61,9 @@ class Manager extends ManagerModel
/**
* Получение модели раздела
*
*
* @param int $id
*
*
* @return null|Forum
*/
public function get($id)
@ -85,7 +85,7 @@ class Manager extends ManagerModel
* Обновляет раздел в БД
*
* @param Forum $forum
*
*
* @return Forum
*/
public function update(Forum $forum)
@ -97,7 +97,7 @@ class Manager extends ManagerModel
* Добавляет новый раздел в БД
*
* @param Forum $forum
*
*
* @return int
*/
public function insert(Forum $forum)
@ -106,4 +106,25 @@ class Manager extends ManagerModel
$this->set($id, $forum);
return $id;
}
/**
* Получение списка разделов и подразделов с указанием глубины вложения
*
* @param Forum $forum
* @param int $depth
* @param array $list
*
* @return array
*/
public function depthList(Forum $forum, $depth, array $list = [])
{
++$depth;
foreach ($forum->subforums as $sub) {
$sub->__depth = $depth;
$list[] = $sub;
$list = $this->depthList($sub, $depth, $list);
}
return $list;
}
}

View file

@ -172,13 +172,13 @@ class Page extends Model
/**
* Добавляет стиль на страницу
*
*
* @param string $name
* @param string $val
*
*
* @return Page
*/
public function addStyle($name, $val)
public function addStyle($name, $val)
{
$this->a['pageHeaders']['style'][$name] = $val;
return $this;
@ -230,7 +230,7 @@ class Page extends Model
/**
* Дописывает в массив титула страницы новый элемент
* $this->titles
* $this->titles = ...
*
* @param string $val
*/
@ -242,4 +242,22 @@ class Page extends Model
$this->a['titles'][] = $val;
}
}
/**
* Добавление новой ошибки
* $this->fIswev = ...
*
* @param array $val
*/
public function setfIswev(array $val)
{
if (empty($this->a['fIswev'])) {
$this->a['fIswev'] = [];
}
if (isset($val[0]) && isset($val[1]) && is_string($val[0]) && is_string($val[1])) {
$this->a['fIswev'][$val[0]][] = $val[1];
} else {
$this->a['fIswev'] = array_merge_recursive((array) $this->a['fIswev'], $val);
}
}
}

View file

@ -8,30 +8,9 @@ use ForkBB\Models\Pages\Admin;
class Forums extends Admin
{
/**
* Получение списка разделов и подразделов
*
* @param Forum $forum
* @param int $depth
* @param array $list
*
* @return array
*/
protected function forumsList(Forum $forum, $depth, array $list = [])
{
++$depth;
foreach ($forum->subforums as $sub) {
$sub->__depth = $depth;
$list[] = $sub;
$list = $this->forumsList($sub, $depth, $list);
}
return $list;
}
/**
* Составление списка категорий/разделов для выбора родителя
*
*
* @param Forum $forum
*/
protected function calcList(Forum $forum)
@ -44,16 +23,16 @@ class Forums extends Admin
$idxs = [];
$root = $this->c->forums->get(0);
if ($root instanceof Forum) {
foreach ($this->forumsList($root, 0) as $f) {
foreach ($this->c->forums->depthList($root, 0) as $f) {
if ($cid !== $f->cat_id) {
$cid = $f->cat_id;
$options[] = [-$cid, \ForkBB\__('Category prefix') . $f->cat_name];
$idxs[] = -$cid;
unset($categories[$cid]);
}
$indent = str_repeat(\ForkBB\__('Forum indent'), $f->depth);
if ($f->id === $forum->id || isset($forum->descendants[$f->id]) || $f->redirect_url) {
$options[] = [$f->id, $indent . \ForkBB\__('Forum prefix') . $f->forum_name, true];
} else {
@ -72,9 +51,9 @@ class Forums extends Admin
/**
* Вычисление позиции для (нового) раздела
*
*
* @param Forum $forum
*
*
* @return int
*/
protected function forumPos(Forum $forum)
@ -163,7 +142,7 @@ class Forums extends Admin
$root = $this->c->forums->get(0);
if ($root instanceof Forum) {
$list = $this->forumsList($root, -1);
$list = $this->c->forums->depthList($root, -1);
$fieldset = [];
$cid = null;
@ -175,7 +154,7 @@ class Forums extends Admin
];
$fieldset = [];
}
$form['sets'][] = [
'info' => [
'info1' => [
@ -186,7 +165,7 @@ class Forums extends Admin
];
$cid = $forum->cat_id;
}
$fieldset[] = [
'dl' => ['name', 'inline', 'depth' . $forum->depth],
'type' => 'btn',
@ -212,7 +191,7 @@ class Forums extends Admin
'disabled' => $disabled,
];
}
$form['sets'][] = [
'fields' => $fieldset,
];
@ -326,7 +305,7 @@ class Forums extends Admin
/**
* Редактирование раздела
* Создание нового раздела
* Создание нового раздела
*
* @param array $args
* @param string $method
@ -405,7 +384,7 @@ class Forums extends Admin
$message = 'Forum updated redirect';
$this->c->forums->update($forum);
}
$this->c->groups->Perm->update($forum, $v->perms);
}

View file

@ -17,9 +17,9 @@ class Auth extends Page
/**
* Выход пользователя
*
*
* @param array $args
*
*
* @return Page
*/
public function logout($args)
@ -38,10 +38,10 @@ class Auth extends Page
/**
* Вход на форум
*
*
* @param array $args
* @param string $method
*
*
* @return Page
*/
public function login(array $args, $method)
@ -63,16 +63,16 @@ class Auth extends Page
'username' => 'Username',
'password' => 'Passphrase',
]);
if ($v->validation($_POST)) {
return $this->c->Redirect->url($v->redirect)->message('Login redirect');
}
$this->fIswev = $v->getErrors();
}
$ref = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
$this->fIndex = 'login';
$this->nameTpl = 'login';
$this->onlinePos = 'login';
@ -91,10 +91,10 @@ class Auth extends Page
/**
* Проверка по базе и вход
*
*
* @param Validator $v
* @param string $password
*
*
* @return string
*/
public function vLoginProcess(Validator $v, $password)
@ -144,10 +144,10 @@ class Auth extends Page
/**
* Запрос на смену кодовой фразы
*
*
* @param array $args
* @param string $method
*
*
* @return Page
*/
public function forget(array $args, $method)
@ -177,7 +177,7 @@ class Auth extends Page
'username' => $this->tmpUser->username,
'link' => $link,
];
try {
$isSent = $this->c->Mail
->reset()
@ -217,10 +217,10 @@ class Auth extends Page
/**
* Дополнительная проверка email
*
*
* @param Validator $v
* @param string $email
*
*
* @return string
*/
public function vCheckEmail(Validator $v, $email)
@ -243,10 +243,10 @@ class Auth extends Page
/**
* Смена кодовой фразы
*
*
* @param array $args
* @param string $method
*
*
* @return Page
*/
public function changePass(array $args, $method)
@ -278,14 +278,14 @@ class Auth extends Page
'password.password' => 'Pass format',
'password2.same' => 'Pass not match',
]);
if ($v->validation($_POST)) {
$user->password = password_hash($v->password, PASSWORD_DEFAULT);
$user->email_confirmed = 1;
$user->activate_string = null;
$this->c->users->update($user);
$this->a['fIswev']['s'][] = \ForkBB\__('Pass updated');
$this->fIswev = ['s', \ForkBB\__('Pass updated')];
return $this->login([], 'GET');
}
@ -297,7 +297,7 @@ class Auth extends Page
$user->email_confirmed = 1;
$this->c->users->update($user);
$this->c->Cache->delete('stats');
$this->a['fIswev']['i'][] = \ForkBB\__('Account activated');
$this->fIswev = ['i', \ForkBB\__('Account activated')];
}
$this->fIndex = 'login';

View file

@ -10,9 +10,9 @@ class Forum extends Page
/**
* Подготовка данных для шаблона
*
*
* @param array $args
*
*
* @return Page
*/
public function view(array $args)
@ -44,7 +44,7 @@ class Forum extends Page
$this->crumbs = $this->crumbs($forum);
if (empty($this->topics)) {
$this->a['fIswev']['i'][] = \ForkBB\__('Empty forum');
$this->fIswev = ['i', \ForkBB\__('Empty forum')];
}
return $this;

View file

@ -8,7 +8,7 @@ class Index extends Page
{
/**
* Подготовка данных для шаблона
*
*
* @return Page
*/
public function view()
@ -17,7 +17,7 @@ class Index extends Page
$this->c->Lang->load('subforums');
// крайний пользователь // ???? может в stats переместить?
$this->c->stats->userLast = $this->c->user->g_view_users == '1'
$this->c->stats->userLast = $this->c->user->g_view_users == '1'
? [ $this->c->Router->link('User', [
'id' => $this->c->stats->userLast['id'],
'name' => $this->c->stats->userLast['username'],
@ -30,7 +30,7 @@ class Index extends Page
$forums = empty($root) ? [] : $root->subforums;
$ctgs = [];
if (empty($forums)) {
$this->a['fIswev']['i'][] = \ForkBB\__('Empty board');
$this->fIswev = ['i', \ForkBB\__('Empty board')];
} else {
foreach($forums as $forum) {
$ctgs[$forum->cat_id][] = $forum;

View file

@ -27,7 +27,7 @@ class Install extends Page
/**
* Возращает доступные типы БД
*
*
* @return array
*/
protected function DBTypes()
@ -57,10 +57,10 @@ class Install extends Page
/**
* Подготовка данных для страницы установки форума
*
*
* @param array $args
* @param string $method
*
*
* @return Page
*/
public function install(array $args, $method)
@ -85,13 +85,13 @@ class Install extends Page
// версия PHP
if (version_compare(PHP_VERSION, self::PHP_MIN, '<')) {
$this->a['fIswev']['e'][] = \ForkBB\__('You are running error', 'PHP', PHP_VERSION, $this->c->FORK_REVISION, self::PHP_MIN);
$this->fIswev = ['e', \ForkBB\__('You are running error', 'PHP', PHP_VERSION, $this->c->FORK_REVISION, self::PHP_MIN)];
}
// типы БД
$this->dbTypes = $this->DBTypes();
if (empty($this->dbTypes)) {
$this->a['fIswev']['e'][] = \ForkBB\__('No DB extensions');
$this->fIswev = ['e', \ForkBB\__('No DB extensions')];
}
// доступность папок на запись
@ -103,30 +103,30 @@ class Install extends Page
foreach ($folders as $folder) {
if (! is_writable($folder)) {
$folder = str_replace(dirname($this->c->DIR_APP), '', $folder);
$this->a['fIswev']['e'][] = \ForkBB\__('Alert folder', $folder);
$this->fIswev = ['e', \ForkBB\__('Alert folder', $folder)];
}
}
// доступность шаблона конфигурации
$config = @file_get_contents($this->c->DIR_CONFIG . '/main.dist.php');
if (false === $config) {
$this->a['fIswev']['e'][] = \ForkBB\__('No access to main.dist.php');
$this->fIswev = ['e', \ForkBB\__('No access to main.dist.php')];
}
unset($config);
// языки
$langs = $this->c->Func->getLangs();
if (empty($langs)) {
$this->a['fIswev']['e'][] = \ForkBB\__('No language packs');
$this->fIswev = ['e', \ForkBB\__('No language packs')];
}
// стили
$styles = $this->c->Func->getStyles();
if (empty($styles)) {
$this->a['fIswev']['e'][] = \ForkBB\__('No styles');
$this->fIswev = ['e', \ForkBB\__('No styles')];
}
if ('POST' === $method && ! $changeLang && empty($this->a['fIswev']['e'])) {
if ('POST' === $method && ! $changeLang && empty($this->a['fIswev']['e'])) { //????
$v = $this->c->Validator->reset()
->addValidators([
'check_prefix' => [$this, 'vCheckPrefix'],
@ -164,7 +164,7 @@ class Install extends Page
])->addMessages([
'email' => 'Wrong email',
]);
if ($v->validation($_POST)) {
return $this->installEnd($v);
} else {
@ -193,8 +193,8 @@ class Install extends Page
],
'btns' => [
'changelang' => [
'type' => 'submit',
'value' => \ForkBB\__('Change language'),
'type' => 'submit',
'value' => \ForkBB\__('Change language'),
],
],
];
@ -363,8 +363,8 @@ class Install extends Page
],
'btns' => [
'submit' => [
'type' => 'submit',
'value' => \ForkBB\__('Start install'),
'type' => 'submit',
'value' => \ForkBB\__('Start install'),
],
],
];
@ -379,10 +379,10 @@ class Install extends Page
/**
* Обработка base URL
*
*
* @param Validator $v
* @param string $url
*
*
* @return string
*/
public function vRtrimURL(Validator $v, $url)
@ -392,10 +392,10 @@ class Install extends Page
/**
* Дополнительная проверка префикса
*
*
* @param Validator $v
* @param string $prefix
*
*
* @return string
*/
public function vCheckPrefix(Validator $v, $prefix)
@ -412,10 +412,10 @@ class Install extends Page
/**
* Полная проверка подключения к БД
*
*
* @param Validator $v
* @param string $dbhost
*
*
* @return string
*/
public function vCheckHost(Validator $v, $dbhost)
@ -482,9 +482,9 @@ class Install extends Page
/**
* Завершение установки форума
*
*
* @param Validator $v
*
*
* @return Page
*/
protected function installEnd(Validator $v)

View file

@ -4,18 +4,18 @@ namespace ForkBB\Models\Pages;
use ForkBB\Models\Model;
trait PostFormTrait
trait PostFormTrait
{
/**
* Возвращает данные для построения формы создания темы/сообщения
*
*
* @param Model $model
* @param string $marker
* @param array $args
* @param bool $editPost
* @param bool $editSubject
* @param bool $quickReply
*
*
* @return array
*/
protected function messageForm(Model $model, $marker, array $args, $editPost = false, $editSubject = false, $quickReply = false)
@ -32,13 +32,13 @@ trait PostFormTrait
'sets' => [],
'btns' => [
'submit' => [
'type' => 'submit',
'value' => \ForkBB\__('Submit'),
'type' => 'submit',
'value' => \ForkBB\__('Submit'),
'accesskey' => 's',
],
'preview' => [
'type' => 'submit',
'value' => \ForkBB\__('Preview'),
'type' => 'submit',
'value' => \ForkBB\__('Preview'),
'accesskey' => 'p',
'class' => 'f-minor',
],
@ -48,7 +48,7 @@ trait PostFormTrait
$fieldset = [];
if ($this->c->user->isGuest) {
$fieldset['username'] = [
'dl' => 't1',
'dl' => 'w1',
'type' => 'text',
'maxlength' => 25,
'title' => \ForkBB\__('Username'),
@ -58,7 +58,7 @@ trait PostFormTrait
'autofocus' => $autofocus,
];
$fieldset['email'] = [
'dl' => 't2',
'dl' => 'w2',
'type' => 'text',
'maxlength' => 80,
'title' => \ForkBB\__('Email'),
@ -98,7 +98,7 @@ trait PostFormTrait
'fields' => $fieldset,
];
$autofocus = null;
$fieldset = [];
if ($this->c->user->isAdmin || $this->c->user->isModerator($model)) {
if ($editSubject) {

View file

@ -4,12 +4,43 @@ namespace ForkBB\Models\Pages;
use ForkBB\Models\Page;
use ForkBB\Core\Validator;
use ForkBB\Models\Forum\Model as Forum;
use InvalidArgumentException;
class Search extends Page
{
use CrumbTrait;
/**
* Составление списка категорий/разделов для выбора
*/
protected function calcList()
{
$cid = null;
$options = [];
$idxs = [];
$root = $this->c->forums->get(0);
if ($root instanceof Forum) {
foreach ($this->c->forums->depthList($root, -1) as $f) {
if ($cid !== $f->cat_id) {
$cid = $f->cat_id;
$options[] = [\ForkBB\__('Category prefix') . $f->cat_name];
}
$indent = str_repeat(\ForkBB\__('Forum indent'), $f->depth);
if ($f->redirect_url) {
$options[] = [$f->id, $indent . \ForkBB\__('Forum prefix') . $f->forum_name, true];
} else {
$options[] = [$f->id, $indent . \ForkBB\__('Forum prefix') . $f->forum_name];
$idxs[] = $f->id;
}
}
}
$this->listOfIndexes = $idxs;
$this->listForOptions = $options;
}
/**
* Поиск
*
@ -21,6 +52,7 @@ class Search extends Page
public function view(array $args, $method)
{
$this->c->Lang->load('search');
$this->calcList();
$v = null;
if ('POST' === $method) {
@ -51,7 +83,8 @@ class Search extends Page
if (isset($args['advanced'])) {
$v->addRules([
'author' => 'string:trim|max:25',
'forums' => 'integer',
'forums' => 'array',
'forums.*' => 'integer|in:' . implode(',', $this->listOfIndexes),
'serch_in' => 'required|integer|in:0,1,2',
'sort_by' => 'required|integer|in:0,1,2,3',
'sort_dir' => 'required|integer|in:0,1',
@ -60,15 +93,33 @@ class Search extends Page
}
if ($v->validation($_POST)) {
$this->c->search->execute([
$forums = $v->forums;
if (empty($forums) && ! $this->c->user->isAdmin) {
$forums = $this->listOfIndexes;
}
$options = [
'keywords' => $v->keywords,
'author' => (string) $v->author,
'forums' => $v->forums,
'forums' => $forums,
'serch_in' => ['all', 'posts', 'topics'][(int) $v->serch_in],
'sort_by' => ['post', 'author', 'subject', 'forum'][(int) $v->sort_by],
'sort_dir' => ['desc', 'asc'][(int) $v->sort_dir],
'show_as' => ['posts', 'topics'][(int) $v->show_as],
]);
];
$result = $this->c->search->execute($options);
$user = $this->c->user;
if ($user->g_search_flood) {
$user->last_search = time();
$this->c->users->update($user); //?????
}
if (empty($result)) {
$this->fIswev = ['i', \ForkBB\__('No hits')];
}
}
$this->fIswev = $v->getErrors();
@ -98,7 +149,7 @@ class Search extends Page
'html' => true,
],
'keywords' => [
'dl' => 't2',
'dl' => 'w2',
'type' => 'text',
'maxlength' => 100,
'title' => \ForkBB\__('Keyword search'),
@ -107,7 +158,7 @@ class Search extends Page
'autofocus' => true,
],
'author' => [
'dl' => 't1',
'dl' => 'w1',
'type' => 'text',
'maxlength' => 25,
'title' => \ForkBB\__('Author search'),
@ -123,28 +174,31 @@ class Search extends Page
'legend' => \ForkBB\__('Search in legend'),
'fields' => [
'forums' => [
'dl' => 'w3',
'type' => 'multiselect',
'options' => [],
'options' => $this->listForOptions,
'value' => $v ? $v->forums : null,
'title' => \ForkBB\__('Forum search'),
'size' => min(count($this->listForOptions), 10),
],
'serch_in' => [
'type' => 'select',
'dl' => 'w3',
'type' => 'select',
'options' => [
0 => \ForkBB\__('Message and subject'),
1 => \ForkBB\__('Message only'),
2 => \ForkBB\__('Topic only'),
],
'value' => $v ? $v->serch_in : 0,
'title' => \ForkBB\__('Search in'),
'value' => $v ? $v->serch_in : 0,
'title' => \ForkBB\__('Search in'),
],
[
'type' => 'info',
'value' => \ForkBB\__('Search in info'),
'type' => 'info',
'value' => \ForkBB\__('Search in info'),
],
[
'type' => 'info',
'value' => \ForkBB\__('Search multiple forums info'),
'type' => 'info',
'value' => \ForkBB\__('Search multiple forums info'),
],
],
@ -153,37 +207,40 @@ class Search extends Page
'legend' => \ForkBB\__('Search results legend'),
'fields' => [
'sort_by' => [
'type' => 'select',
'dl' => 'w4',
'type' => 'select',
'options' => [
0 => \ForkBB\__('Sort by post time'),
1 => \ForkBB\__('Sort by author'),
2 => \ForkBB\__('Sort by subject'),
3 => \ForkBB\__('Sort by forum'),
],
'value' => $v ? $v->sort_by : 0,
'title' => \ForkBB\__('Sort by'),
'value' => $v ? $v->sort_by : 0,
'title' => \ForkBB\__('Sort by'),
],
'sort_dir' => [
'type' => 'radio',
'values' => [
'dl' => 'w4',
'type' => 'radio',
'values' => [
0 => \ForkBB\__('Descending'),
1 => \ForkBB\__('Ascending'),
],
'value' => $v ? $v->sort_dir : 0,
'title' => \ForkBB\__('Sort order'),
'value' => $v ? $v->sort_dir : 0,
'title' => \ForkBB\__('Sort order'),
],
'show_as' => [
'type' => 'radio',
'values' => [
'dl' => 'w4',
'type' => 'radio',
'values' => [
0 => \ForkBB\__('Show as posts'),
1 => \ForkBB\__('Show as topics'),
],
'value' => $v ? $v->show_as : 0,
'title' => \ForkBB\__('Show as'),
'value' => $v ? $v->show_as : 0,
'title' => \ForkBB\__('Show as'),
],
[
'type' => 'info',
'value' => \ForkBB\__('Search results info'),
'type' => 'info',
'value' => \ForkBB\__('Search results info'),
],
],
@ -229,10 +286,16 @@ class Search extends Page
*/
public function vCheckQuery(Validator $v, $query)
{
$search = $this->c->search;
$user = $this->c->user;
if (! $search->prepare($query)) {
$v->addError(\ForkBB\__($search->queryError, $search->queryText));
if ($user->last_search && time() - $user->last_search < $user->g_search_flood) {
$v->addError(\ForkBB\__('Search flood', $user->g_search_flood, $user->g_search_flood - time() + $user->last_search));
} else {
$search = $this->c->search;
if (! $search->prepare($query)) {
$v->addError(\ForkBB\__($search->queryError, $search->queryText));
}
}
return $query;
@ -270,7 +333,7 @@ class Search extends Page
if (false === $list) {
return $this->c->Message->message('Bad request');
} elseif (empty($list)) {
$this->a['fIswev']['i'][] = \ForkBB\__('No hits');
$this->fIswev = ['i', \ForkBB\__('No hits')];
return $this->view(['advanced' => 'advanced'], 'GET');
}

View file

@ -11,11 +11,12 @@ use RuntimeException;
class Execute extends Method
{
protected $selectForIndex;
protected $selectForPosts;
protected $queryIdx;
protected $queryCJK;
protected $sortType;
protected $words;
protected $stmt;
protected $stmtIdx;
protected $stmtCJK;
/**
* @param array $options
@ -33,9 +34,12 @@ class Execute extends Method
echo '<pre>';
var_dump($this->model->queryText);
$this->words = [];
$this->stmt = null;
$vars = $this->buildSelect($options);
$this->words = [];
$this->stmtIdx = null;
$this->stmtCJK = null;
$vars = $this->buildSelect($options);
var_dump($this->queryIdx, $this->queryCJK);
$ids = $this->exec($this->model->queryWords, $vars);
@ -47,7 +51,8 @@ var_dump($this->model->queryText);
var_dump($ids);
echo '</pre>';
exit();
return $ids;
}
/**
@ -55,14 +60,14 @@ echo '</pre>';
*
* @param array $words
* @param array $vars
* @param array $ids
*
* @return array
*/
protected function exec(array $words, array $vars, array $ids = [])
protected function exec(array $words, array $vars)
{
$type = 'AND';
$count = 0;
$ids = [];
foreach ($words as $word) {
@ -80,12 +85,12 @@ var_dump($word);
}
if (is_array($word) && (! isset($word['type']) || 'CJK' !== $word['type'])) {
$ids = $this->exec($word, $vars, $ids);
$ids = $this->exec($word, $vars);
} else {
$CJK = false;
if (isset($word['type']) && 'CJK' === $word['type']) {
$CJK = true;
$word = $word['word']; //???? добавить *
$word = '*' . trim($word['word'], '*') . '*';
}
$word = str_replace(['*', '?'], ['%', '_'], $word);
@ -95,13 +100,23 @@ var_dump($word);
} else {
$vars[':word'] = $word;
if (null === $this->stmt) {
$this->stmt = $this->c->DB->prepare($this->selectForIndex, $vars);
$this->stmt->execute();
if ($CJK) {
if (null === $this->stmtCJK) {
$this->stmtCJK = $this->c->DB->prepare($this->queryCJK, $vars);
$this->stmtCJK->execute();
} else {
$this->stmtCJK->execute($vars);
}
$this->words[$word] = $list = $this->stmtCJK->fetchAll(PDO::FETCH_KEY_PAIR);
} else {
$this->stmt->execute($vars);
if (null === $this->stmtIdx) {
$this->stmtIdx = $this->c->DB->prepare($this->queryIdx, $vars);
$this->stmtIdx->execute();
} else {
$this->stmtIdx->execute($vars);
}
$this->words[$word] = $list = $this->stmtIdx->fetchAll(PDO::FETCH_KEY_PAIR);
}
$this->words[$word] = $list = $this->stmt->fetchAll(PDO::FETCH_KEY_PAIR);
}
var_dump($list);
@ -137,85 +152,134 @@ var_dump($list);
# ["sort_dir"]=> string(4) "desc"
# ["show_as"] => string(5) "posts"
$vars = [];
$where = [];
$joinT = false;
$joinP = false;
$whereIdx = [];
$whereCJK = [];
$joinTIdx = false;
$joinPIdx = false;
$useT = false;
$useP = false;
if (! empty($options['forums'])) {
$joinTIdx = true;
$whereIdx[] = 't.forum_id IN (?ai:forums)';
$whereCJK[] = 't.forum_id IN (?ai:forums)';
$useT = true;
$vars[':forums'] = (array) $options['forums'];
}
//???? нужен индекс по авторам сообщений/тем
//???? что делать с подчеркиванием в именах?
if ('' != $options['author']) {
$joinPIdx = true;
$vars[':author'] = str_replace(['*', '?'], ['%', '_'], $options['author']);
$whereIdx[] = 'p.poster LIKE ?s:author';
}
switch ($options['serch_in']) {
case 'posts':
$where[] = 'm.subject_match=0';
$whereIdx[] = 'm.subject_match=0';
$whereCJK[] = 'p.message LIKE ?s:word';
$useP = true;
if (isset($vars[':author'])) {
$whereCJK[] = 'p.poster LIKE ?s:author';
}
break;
case 'topics':
$where[] = 'm.subject_match=1';
$whereIdx[] = 'm.subject_match=1';
$whereCJK[] = 't.subject LIKE ?s:word';
$useT = true;
if (isset($vars[':author'])) {
$whereCJK[] = 't.poster LIKE ?s:author';
}
// при поиске в заголовках результат только в виде списка тем
$options['show_as'] = 'topics';
break;
}
if (! empty($options['forums'])) {
$joinT = true;
$where[] = 't.forum_id IN (?ai:forums)';
$vars[':forums'] = (array) $options['forums'];
default:
if (isset($vars[':author'])) {
$whereCJK[] = '((p.message LIKE ?s:word AND p.poster LIKE ?s:author) OR (t.subject LIKE ?s:word AND t.poster LIKE ?s:author))';
} else {
$whereCJK[] = '(p.message LIKE ?s:word OR t.subject LIKE ?s:word)';
}
$useP = true;
$useT = true;
break;
}
if ('topics' === $options['show_as']) {
$showTopics = true;
$joinP = true;
$selectF = 'p.topic_id';
$joinPIdx = true;
$selectFIdx = 'p.topic_id';
$selectFCJK = 't.id';
$useT = true;
} else {
$showTopics = false;
$selectF = 'm.post_id';
}
//???? нужен индекс по авторам сообщений
//???? что делать с подчеркиванием в именах?
if ('' != $options['author']) {
$joinP = true;
$vars[':author'] = str_replace(['*', '?'], ['%', '_'], $options['author']);
$where[] = 'p.poster LIKE ?s:author';
$selectFIdx = 'm.post_id';
$selectFCJK = 'p.id';
$useP = true;
}
switch ($options['sort_by']) {
case 'author':
if ($showTopics) {
$sortBy = 't.poster';
$joinT = true;
$sortIdx = 't.poster';
$sortCJK = 't.poster';
$joinTIdx = true;
$useT = true;
} else {
$sortBy = 'p.poster';
$joinP = true;
$sortIdx = 'p.poster';
$sortCJK = 'p.poster';
$joinPIdx = true;
$useP = true;
}
$this->sortType = SORT_STRING;
break;
case 'subject':
$sortBy = 't.subject';
$joinT = true;
$sortIdx = 't.subject';
$sortCJK = 't.subject';
$joinTIdx = true;
$useT = true;
$this->sortType = SORT_STRING;
break;
case 'forum':
$sortBy = 't.forum_id';
$joinT = true;
$sortIdx = 't.forum_id';
$sortCJK = 't.forum_id';
$joinTIdx = true;
$useT = true;
$this->sortType = SORT_NUMERIC;
break;
default:
if ($showTopics) {
$sortBy = 't.last_post';
$joinT = true;
$sortIdx = 't.last_post';
$sortCJK = 't.last_post';
$joinTIdx = true;
$useT = true;
} else {
$sortBy = 'm.post_id';
$sortIdx = 'm.post_id';
$sortCJK = 'p.id';
$useP = true;
}
$this->sortType = SORT_NUMERIC;
break;
}
$joinP = $joinP || $joinT ? 'INNER JOIN ::posts AS p ON p.id=m.post_id ' : '';
$joinT = $joinT ? 'INNER JOIN ::topics AS t ON t.id=p.topic_id ' : '';
$where = empty($where) ? '' : ' AND ' . implode(' AND ', $where);
$joinPIdx = $joinPIdx || $joinTIdx ? 'INNER JOIN ::posts AS p ON p.id=m.post_id ' : '';
$joinTIdx = $joinTIdx ? 'INNER JOIN ::topics AS t ON t.id=p.topic_id ' : '';
$whereIdx = empty($whereIdx) ? '' : ' AND ' . implode(' AND ', $whereIdx);
$this->selectForIndex = "SELECT {$selectF}, {$sortBy} FROM ::search_words AS w " .
'INNER JOIN ::search_matches AS m ON m.word_id=w.id ' .
$joinP .
$joinT .
'WHERE w.word LIKE ?s:word' . $where;
$this->queryIdx = "SELECT {$selectFIdx}, {$sortIdx} FROM ::search_words AS w " .
'INNER JOIN ::search_matches AS m ON m.word_id=w.id ' .
$joinPIdx .
$joinTIdx .
'WHERE w.word LIKE ?s:word' . $whereIdx;
if ($useP) {
$this->queryCJK = "SELECT {$selectFCJK}, {$sortCJK} FROM ::posts AS p " .
($useT ? 'INNER JOIN ::topics AS t ON t.id=p.topic_id ' : '') .
'WHERE ' . implode(' AND ', $whereCJK);
} else {
$this->queryCJK = "SELECT {$selectFCJK}, {$sortCJK} FROM ::topics AS t " .
'WHERE ' . implode(' AND ', $whereCJK);
}
return $vars;
}

View file

@ -74,7 +74,7 @@ class Current extends Action
* @param int $id
*
* @throws RuntimeException
*
*
* @return User;
*/
protected function load($id)
@ -109,7 +109,7 @@ class Current extends Action
/**
* Возврат юзер агента браузера пользователя
*
*
* @return string
*/
protected function getUserAgent()

View file

@ -188,3 +188,12 @@ msgstr "<a href=\"%s\">Advanced search</a>"
msgid "<a href=\"%s\">Simple search</a>"
msgstr "<a href=\"%s\">Simple search</a>"
msgid "Category prefix"
msgstr ""
msgid "Forum prefix"
msgstr ""
msgid "Forum indent"
msgstr "◦ ◦ "

View file

@ -188,3 +188,12 @@ msgstr "<a href=\"%s\">Расширенный поиск</a>"
msgid "<a href=\"%s\">Simple search</a>"
msgstr "<a href=\"%s\">Простой поиск</a>"
msgid "Category prefix"
msgstr ""
msgid "Forum prefix"
msgstr ""
msgid "Forum indent"
msgstr "◦ ◦ "

View file

@ -34,13 +34,45 @@
@endif
@elseif ('select' === $cur['type'])
<select @if (! empty($cur['required'])) required @endif @if (! empty($cur['disabled'])) disabled @endif @if (isset($cur['autofocus'])) autofocus @endif class="f-ctrl" id="id-{{ $key }}" name="{{ $key }}">
@if (null === ($count = null) && is_array(reset($cur['options'])) && 1 === count(reset($cur['options'])) && $count = 0) @endif
@foreach ($cur['options'] as $v => $option)
@if (is_array($option))
@if (null !== $count && 1 === count($option))
@if (++$count > 1)
</optgroup>
@endif
<optgroup label="{{ $option[0] }}">
@else
<option value="{{ $option[0] }}" @if ($option[0] == $cur['value']) selected @endif @if (isset($option[2])) disabled @endif>{{ $option[1] }}</option>
@endif
@else
<option value="{{ $v }}" @if ($v == $cur['value']) selected @endif>{{ $option }}</option>
@endif
@endforeach
@if (null !== $count)
</optgroup>
@endif
</select>
@elseif ('multiselect' === $cur['type'])
<select @if (! empty($cur['required'])) required @endif @if (! empty($cur['disabled'])) disabled @endif @if (isset($cur['autofocus'])) autofocus @endif @if (! empty($cur['size'])) size="{{ $cur['size'] }}" @endif multiple class="f-ctrl" id="id-{{ $key }}" name="{{ $key }}[]">
@if (null === ($count = null) && is_array(reset($cur['options'])) && 1 === count(reset($cur['options'])) && $count = 0) @endif
@foreach ($cur['options'] as $v => $option)
@if (is_array($option))
@if (null !== $count && 1 === count($option))
@if (++$count > 1)
</optgroup>
@endif
<optgroup label="{{ $option[0] }}">
@else
<option value="{{ $option[0] }}" @if ((is_array($cur['value']) && in_array($option[0], $cur['value'])) || $option[0] == $cur['value']) selected @endif @if (isset($option[2])) disabled @endif>{{ $option[1] }}</option>
@endif
@else
<option value="{{ $v }}" @if ((is_array($cur['value']) && in_array($v, $cur['value'])) || $v == $cur['value']) selected @endif>{{ $option }}</option>
@endif
@endforeach
@if (null !== $count)
</optgroup>
@endif
</select>
@elseif ('number' === $cur['type'])
<input @if (! empty($cur['required'])) required @endif @if (! empty($cur['disabled'])) disabled @endif @if (isset($cur['autofocus'])) autofocus @endif class="f-ctrl" id="id-{{ $key }}" name="{{ $key }}" type="number" min="{{ $cur['min'] }}" max="{{ $cur['max'] }}" @if (isset($cur['value'])) value="{{ $cur['value'] }}" @endif>
@ -69,7 +101,7 @@
@foreach ($form['btns'] as $key => $cur)
@if ('submit' === $cur['type'])
<input class="f-btn @if(isset($cur['class'])) {{ $cur['class'] }} @endif" type="{{ $cur['type'] }}" name="{{ $key }}" value="{{ $cur['value'] }}" @if (isset($cur['accesskey'])) accesskey="{{ $cur['accesskey'] }}" @endif>
@elseif ('btn'=== $cur['type'])
@elseif ('btn'=== $cur['type'])
<a class="f-btn @if(isset($cur['class'])) {{ $cur['class'] }} @endif" data-name="{{ $key }}" href="{!! $cur['link'] !!}" @if (isset($cur['accesskey'])) accesskey="{{ $cur['accesskey'] }}" @endif>{{ $cur['value'] }}</a>
@endif
@endforeach

View file

@ -479,6 +479,7 @@ select {
.f-fdiv .f-child6 {
display: block;
width: 100%;
clear: both;
}
.f-fdiv .f-child1 {
@ -1042,6 +1043,12 @@ select {
border-bottom: 0.0625rem solid #AA7939;
}
/*
.f-ftlist .f-row:hover {
background-color: #F8F4E3;
}
*/
.f-ftlist .f-thead {
border-bottom: 0.125rem solid #AA7939;
}
@ -1574,20 +1581,20 @@ li + li .f-btn {
}
@media screen and (min-width: 50rem) {
.f-fdiv .f-field-t1 {
.f-fdiv .f-field-w1 {
width: 30%;
float: left;
padding-top: 0.625rem;
}
.f-fdiv .f-field-t2 {
.f-fdiv .f-field-w2 {
width: 70%;
float: left;
padding-top: 0.625rem;
}
.f-field-t1 + .f-field-t2,
.f-field-t2 + .f-field-t1 {
.f-field-w1 + .f-field-w2,
.f-field-w2 + .f-field-w1 {
padding-left: 0.625rem;
}
}
@ -1663,6 +1670,10 @@ li + li .f-btn {
padding-left: 2.5rem;
}
.f-field-depth5 > dd {
padding-left: 3.125rem;
}
.f-editcategories-form .f-field-inline:nth-child(-n+3) {
padding-top: 0.625rem;
}
@ -1793,8 +1804,25 @@ li + li .f-btn {
}
@media screen and (min-width: 50rem) {
.f-search-form .f-fdiv .f-field-t1,
.f-search-form .f-fdiv .f-field-t2 {
.f-search-form .f-fdiv .f-field-w1,
.f-search-form .f-fdiv .f-field-w2 {
padding-top: 0;
}
.f-search-form .f-fdiv .f-field-w3 {
width: 50%;
float: left;
/* padding-top: 0; */
}
.f-search-form .f-fdiv .f-field-w4 {
width: 33.33%;
float: left;
/* padding-top: 0; */
}
.f-field-w3 + .f-field-w3,
.f-field-w4 + .f-field-w4 {
padding-left: 0.625rem;
}
}