2017-09-30

This commit is contained in:
Visman 2017-10-01 00:12:17 +07:00
parent 7362c03c7a
commit 58b807cb87
18 changed files with 891 additions and 151 deletions

6
.gitignore vendored
View file

@ -2,8 +2,4 @@
/app/config/main.php
/app/cache/**/*.php
/app/cache/**/*.lock
/img/avatars/*
!/img/avatars/index.html
/img/members/*
!/img/members/.htaccess
!/img/members/nofile.gif
/public/avatar/*

View file

@ -82,8 +82,10 @@ class Routing
$r->add('GET', '/forum/{id:[1-9]\d*}[/{name}][/page/{page:[1-9]\d*}]', 'Forum:view', 'Forum');
// темы
$r->add('GET', '/topic/{id:[1-9]\d*}[/{name}][/page/{page:[1-9]\d*}]', 'Topic:view', 'Topic');
$r->add('GET', '/topic/{id:[1-9]\d*}/go_to/new', 'Topic:goToNew', 'TopicGoToNew');
$r->add('GET', '/topic/{id:[1-9]\d*}/go_to/unread', 'Topic:goToUnread', 'TopicGoToUnread');
$r->add('GET', '/topic/{id:[1-9]\d*}/goto/new', 'Topic:goToNew', 'TopicGoToNew');
$r->add('GET', '/topic/{id:[1-9]\d*}/goto/unread', 'Topic:goToUnread', 'TopicGoToUnread');
$r->add('GET', '/topic/{id:[1-9]\d*}/goto/last', 'Topic:goToLast', 'TopicGoToLast');
$r->add('GET', '/topic/{id:[1-9]\d*}/new/post', 'Post:new', 'NewPost');
// сообщения
$r->add('GET', '/post/{id:[1-9]\d*}#p{id}', 'Topic:viewPost', 'ViewPost'); //????

View file

@ -67,7 +67,7 @@ class Container
if (is_array($service)) {
return $this->fromArray($service, $tree);
} elseif (is_object($service)) {
return $service->$tree[0];
return $service->{$tree[0]};
} else {
return null;
}

View file

@ -99,8 +99,6 @@ class Func
}
if ($i === $cur) {
$pages[] = [null, $i, true];
} elseif ($i === 1) {
$pages[] = [$this->c->Router->link($marker, $args), $i, null];
} else {
$pages[] = [$this->c->Router->link($marker, ['page' => $i] + $args), $i, null];
}

View file

@ -97,13 +97,15 @@ class Router
*/
public function link($marker = null, array $args = [])
{
$result = $this->baseUrl; //???? http и https
$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) {
continue;
}
$s = preg_replace(
'%\{' . preg_quote($key, '%') . '(?::[^{}]+)?\}%',

View file

@ -79,7 +79,7 @@ class Forum extends Page
return $this->c->Message->message('Bad request');
}
$offset = $user->dispTopics * ($page - 1);
$offset = ($page - 1) * $user->dispTopics;
switch ($curForum['sort_by']) {
case 1:
@ -132,10 +132,7 @@ class Forum extends Page
$topics = $this->c->DB->query($sql, $vars)->fetchAll();
foreach ($topics as &$cur) {
// цензура
if ($this->config['o_censoring'] == '1') {
$cur['subject'] = preg_replace($this->c->censoring[0], $this->c->censoring[1], $cur['subject']);
}
$cur['subject'] = $this->censor($cur['subject']);
// перенос темы
if ($cur['moved_to']) {
$cur['link'] = $this->c->Router->link('Topic', ['id' => $cur['moved_to'], 'name' => $cur['subject']]);
@ -155,8 +152,8 @@ class Forum extends Page
$cur['link'] = $this->c->Router->link('Topic', ['id' => $cur['id'], 'name' => $cur['subject']]);
$cur['link_last'] = $this->c->Router->link('ViewPost', ['id' => $cur['last_post_id']]);
$cur['num_views'] = $this->config['o_topic_views'] == '1' ? $this->number($cur['num_views']) : null;
$cur['num_replies'] = $this->number($cur['num_replies']);
$cur['views'] = $this->config['o_topic_views'] == '1' ? $this->number($cur['num_views']) : null;
$cur['replies'] = $this->number($cur['num_replies']);
$time = $cur['last_post'];
$cur['last_post'] = $this->time($cur['last_post']);
// для гостя пусто
@ -191,6 +188,7 @@ class Forum extends Page
|| ($user->isAdmMod && isset($moders[$user->id]));
$this->onlinePos = 'forum-' . $args['id'];
$crumbs = [];
$id = $args['id'];
$activ = true;
@ -223,8 +221,8 @@ class Forum extends Page
'pages' => $this->c->Func->paginate($pages, $page, 'Forum', ['id' => $args['id'], 'name' => $fDesc[$args['id']]['forum_name']]),
];
$this->canonical = $page > 1 ? $this->c->Router->link('Forum', ['id' => $args['id'], 'name' => $fDesc[$args['id']]['forum_name'], 'page' => $page])
: $this->c->Router->link('Forum', ['id' => $args['id'], 'name' => $fDesc[$args['id']]['forum_name']]);
$this->canonical = $this->c->Router->link('Forum', ['id' => $args['id'], 'name' => $fDesc[$args['id']]['forum_name'], 'page' => $page]);
return $this;
}
}

View file

@ -407,6 +407,20 @@ abstract class Page
}
}
/**
* Выполняет цензуру при необходимости
* @param string $str
* @return string
*/
protected function censor($str)
{
if ($this->config['o_censoring'] == '1') {
return (string) preg_replace($this->c->censoring[0], $this->c->censoring[1], $str);
} else {
return $str;
}
}
/**
* Заглушка
* @param string $name

View file

@ -115,9 +115,7 @@ class Register extends Page
if (preg_match('%^(guest|' . preg_quote(__('Guest'), '%') . ')$%iu', $username)) {
$error = __('Username guest');
// цензура
} elseif ($this->config['o_censoring'] == '1'
&& preg_replace($this->c->censoring[0], $this->c->censoring[1], $username) !== $username
) {
} elseif ($this->censor($username) !== $username) {
$error = __('Username censor');
// username забанен
} elseif ($this->c->CheckBans->isBanned($username) > 0) {

338
app/Models/Pages/Topic.php Normal file
View file

@ -0,0 +1,338 @@
<?php
namespace ForkBB\Models\Pages;
class Topic extends Page
{
use UsersTrait;
/**
* Имя шаблона
* @var string
*/
protected $nameTpl = 'topic';
/**
* Позиция для таблицы онлайн текущего пользователя
* @var null|string
*/
protected $onlinePos = 'topic';
/**
* Подготовка данных для шаблона
* @param array $args
* @return Page
*/
public function goToNew(array $args)
{
}
/**
* Подготовка данных для шаблона
* @param array $args
* @return Page
*/
public function goToUnread(array $args)
{
}
/**
* Переход к последнему сообщению темы
* @param array $args
* @return Page
*/
public function goToLast(array $args)
{
$vars = [
':tid' => $args['id'],
];
$sql = 'SELECT MAX(id) FROM ::posts WHERE topic_id=?i:tid';
$pid = $this->c->DB->query($sql, $vars)->fetchColumn();
// нет ни одного сообщения в теме
if (empty($pid)) {
return $this->c->Message->message('Bad request');
}
return $this->c->Redirect->setPage('ViewPost', ['id' => $pid]);
}
/**
* Просмотр темы по номеру сообщения
* @param array $args
* @return Page
*/
public function viewPost(array $args)
{
$vars = [
':pid' => $args['id'],
];
$sql = 'SELECT topic_id FROM ::posts WHERE id=?i:pid';
$tid = $this->c->DB->query($sql, $vars)->fetchColumn();
// сообшение не найдено в базе
if (empty($tid)) {
return $this->c->Message->message('Bad request');
}
$vars = [
':pid' => $args['id'],
':tid' => $tid,
];
$sql = 'SELECT COUNT(id) FROM ::posts WHERE topic_id=?i:tid AND id<?i:pid';
$num = 1 + $this->c->DB->query($sql, $vars)->fetchColumn();
return $this->view([
'id' => $tid,
'page' => ceil($num / $this->c->user->dispPosts),
]);
}
/**
* Подготовка данных для шаблона
* @param array $args
* @return Page
*/
public function view(array $args)
{
$this->c->Lang->load('topic');
$user = $this->c->user;
$vars = [
':tid' => $args['id'],
':uid' => $user->id,
];
if ($user->isGuest) {
$sql = 'SELECT t.*, f.moderators, 0 AS is_subscribed
FROM ::topics AS t
INNER JOIN ::forums AS f ON f.id=t.forum_id
WHERE t.id=?i:tid AND t.moved_to IS NULL';
} else {
$sql = 'SELECT t.*, f.moderators, s.user_id AS is_subscribed
FROM ::topics AS t
INNER JOIN ::forums AS f ON f.id=t.forum_id
LEFT JOIN ::topic_subscriptions AS s ON (t.id=s.topic_id AND s.user_id=?i:uid)
WHERE t.id=?i:tid AND t.moved_to IS NULL';
}
$topic = $this->c->DB->query($sql, $vars)->fetch();
// тема отсутствует или недоступна
if (empty($topic)) {
return $this->c->Message->message('Bad request');
}
list($fTree, $fDesc, $fAsc) = $this->c->forums;
// раздел отсутствует в доступных
if (empty($fDesc[$topic['forum_id']])) {
return $this->c->Message->message('Bad request');
}
$page = isset($args['page']) ? (int) $args['page'] : 1;
$pages = ceil(( $topic['num_replies'] + 1) / $user->dispPosts);
// попытка открыть страницу которой нет
if ($page < 1 || $page > $pages) {
return $this->c->Message->message('Bad request');
}
$offset = ($page - 1) * $user->dispPosts;
$vars = [
':tid' => $args['id'],
':offset' => $offset,
':rows' => $user->dispPosts,
];
$sql = 'SELECT id
FROM ::posts
WHERE topic_id=?i:tid
ORDER BY id LIMIT ?i:offset, ?i:rows';
$ids = $this->c->DB->query($sql, $vars)->fetchAll(\PDO::FETCH_COLUMN);
// нарушена синхронизация количества сообщений в темах
if (empty($ids)) {
return $this->goToLast($args); //????
}
$moders = empty($topic['moderators']) ? [] : array_flip(unserialize($topic['moderators']));
$parent = isset($fDesc[$topic['forum_id']][0]) ? $fDesc[$topic['forum_id']][0] : 0;
$perm = $fTree[$parent][$topic['forum_id']];
if ($user->isAdmin) {
$newPost = $this->c->Router->link('NewPost', ['id' => $args['id']]);
} elseif ($topic['closed'] == '1') {
$newPost = false;
} elseif ($perm['post_replies'] === 1
|| (null === $perm['post_replies'] && $user->gPostReplies == '1')
|| ($user->isAdmMod && isset($moders[$user->id]))
) {
$newPost = $this->c->Router->link('NewPost', ['id' => $args['id']]);
} else {
$newPost = null;
}
// приклейка первого сообщения темы
$stickFP = (! empty($topic['stick_fp']) || ! empty($topic['poll_type']));
if ($stickFP) {
$ids[] = $topic['first_post_id'];
}
$vars = [
':ids' => $ids,
];
$sql = 'SELECT id, message, poster, posted
FROM ::warnings
WHERE id IN (?ai:ids)';
$warnings = $this->c->DB->query($sql, $vars)->fetchAll(\PDO::FETCH_GROUP);
$vars = [
':ids' => $ids,
];
$sql = 'SELECT u.warning_all, u.gender, u.email, u.title, u.url, u.location, u.signature,
u.email_setting, u.num_posts, u.registered, u.admin_note, u.messages_enable,
p.id, p.poster as username, p.poster_id, p.poster_ip, p.poster_email, p.message,
p.hide_smilies, p.posted, p.edited, p.edited_by, p.edit_post, p.user_agent,
g.g_id, g.g_user_title, g.g_promote_next_group, g.g_pm
FROM ::posts AS p
INNER JOIN ::users AS u ON u.id=p.poster_id
INNER JOIN ::groups AS g ON g.g_id=u.group_id
WHERE p.id IN (?ai:ids) ORDER BY p.id';
$stmt = $this->c->DB->query($sql, $vars);
$genders = [1 => ' f-user-male', 2 => ' f-user-female'];
$postCount = 0;
$posts = [];
$posters = [];
while ($cur = $stmt->fetch()) {
// данные по автору сообшения
if (isset($posters[$cur['poster_id']])) {
$post = $posters[$cur['poster_id']];
} else {
$post = [
'poster' => $cur['username'],
'poster_title' => $this->censor($this->userGetTitle($cur)),
'poster_avatar' => null,
'poster_registered' => null,
'poster_location' => null,
'poster_info_add' => false,
'poster_link' => null,
'poster_posts' => null,
'poster_gender' => '',
'poster_online' => '',
];
if ($cur['poster_id'] > 1) {
if ($user->gViewUsers == '1') {
$post['poster_link'] = $this->c->Router->link('User', ['id' => $cur['poster_id'], 'name' => $cur['username']]);
}
if ($this->config['o_avatars'] == '1' && $user->showAvatars == '1') {
$post['poster_avatar'] = $this->userGetAvatarLink($cur['poster_id']);
}
if ($this->config['o_show_user_info'] == '1') {
$post['poster_info_add'] = true;
$post['poster_registered'] = $this->time($cur['registered'], true);
$post['poster_posts'] = $this->number($cur['num_posts']);
$post['poster_num_posts'] = $cur['num_posts'];
if ($cur['location'] != '') {
$post['poster_location'] = $this->censor($cur['location']);
}
if (isset($genders[$cur['gender']])) {
$post['poster_gender'] = $genders[$cur['gender']];
}
}
$post['poster_online'] = ' f-user-online'; //????
$posters[$cur['poster_id']] = $post;
}
}
// данные по сообщению
$post['id'] = $cur['id'];
$post['link'] = $this->c->Router->link('ViewPost', ['id' => $cur['id']]);
$post['posted'] = $this->time($cur['posted']);
$post['posted_utc'] = gmdate('Y-m-d\TH:i:s\Z', $cur['posted']);
// номер сообшения в теме
if ($stickFP && $offset > 0 && $cur['id'] == $topic['first_post_id']) {
$post['post_number'] = 1;
} else {
++$postCount;
$post['post_number'] = $offset + $postCount;
}
// данные по элементам управления
$controls = [];
if (! $user->isAdmin && ! $user->isGuest) {
$controls['report'] = ['#', 'Report'];
}
if ($user->isAdmin
|| ($user->isAdmMod && isset($moders[$user->id]))
|| ($cur['poster_id'] == $user->id) //????
) {
$controls['edit'] = ['#', 'Edit'];
}
if ($newPost) {
$controls['quote'] = ['#', 'Reply'];
}
$post['controls'] = $controls;
$posts[] = $post;
}
$topic['subject'] = $this->censor($topic['subject']);
$crumbs = [];
$crumbs[] = [
$this->c->Router->link('Topic', ['id' => $args['id'], 'name' => $topic['subject']]),
$topic['subject'],
true,
];
$this->titles[] = $topic['subject'];
$id = $topic['forum_id'];
$activ = null;
while (true) {
$name = $fDesc[$id]['forum_name'];
$this->titles[] = $name;
$crumbs[] = [
$this->c->Router->link('Forum', ['id' => $id, 'name' => $name]),
$name,
$activ,
];
$activ = null;
if (! isset($fDesc[$id][0])) {
break;
}
$id = $fDesc[$id][0];
}
$crumbs[] = [
$this->c->Router->link('Index'),
__('Index'),
null,
];
$this->data = [
'topic' => $topic,
'posts' => $posts,
'warnings' => $warnings,
'crumbs' => array_reverse($crumbs),
'topicName' => $topic['subject'],
'newPost' => $newPost,
'stickFP' => $stickFP,
'pages' => $this->c->Func->paginate($pages, $page, 'Topic', ['id' => $args['id'], 'name' => $topic['subject']]),
];
$this->canonical = $this->c->Router->link('Topic', ['id' => $args['id'], 'name' => $topic['subject'], 'page' => $page]);
return $this;
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace ForkBB\Models\Pages;
trait UsersTrait
{
/**
* Имена забаненных пользователей
* @var array
*/
protected $userBanNames;
/**
* Определение титула для пользователя
* @param array $data
* @return string
*/
protected function userGetTitle(array $data)
{
if (! isset($this->userBanNames)) {
$this->userBanNames = [];
foreach($this->c->bans as $cur) {
$this->userBanNames[mb_strtolower($cur['username'])] = true;
}
}
if(isset($this->userBanNames[$data['username']])) {
return __('Banned');
} elseif ($data['title'] != '') {
return $data['title'];
} elseif ($data['g_user_title'] != '') {
return $data['g_user_title'];
} elseif ($data['g_id'] == $this->c->GROUP_GUEST) {
return __('Guest');
} else {
return __('Member');
}
}
/**
* Определение ссылки на аватарку
* @param int $id
* @return string|null
*/
protected function userGetAvatarLink($id)
{
$filetypes = array('jpg', 'gif', 'png');
foreach ($filetypes as $type) {
$path = $this->c->DIR_PUBLIC . "/avatar/{$id}.{$type}";
if (file_exists($path) && getimagesize($path)) {
return $this->c->PUBLIC_URL . "/avatar/{$id}.{$type}";
}
}
return null;
}
}

View file

@ -31,6 +31,14 @@ if (file_exists(__DIR__ . '/config/main.php')) {
require __DIR__ . '/functions.php';
// https or http?
if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
$c->BASE_URL = str_replace('http://', 'https://', $c->BASE_URL);
} else {
$c->BASE_URL = str_replace('https://', 'http://', $c->BASE_URL);
}
$c->PUBLIC_URL = $c->BASE_URL . $forkPublicPrefix;
$c->FORK_REVISION = 1;
$c->START = $forkStart;
$c->DIR_APP = __DIR__;
@ -52,7 +60,7 @@ if ($page->getDataForOnline(true)) {
$c->Online->handle($page);
}
$tpl = $c->View->rendering($page);
if ($c->DEBUG > 0) {
if ($tpl !== null && $c->DEBUG > 0) {
$debug = $c->Debug->debug();
$debug = $c->View->rendering($debug);
$tpl = str_replace('<!-- debuginfo -->', $debug, $tpl);

View file

@ -12,7 +12,7 @@ function __($data, ...$args)
$tr = $lang->get($data);
if (is_array($tr)) {
if (isset($args[0]) && is_numeric($args[0])) {
if (isset($args[0]) && is_int($args[0])) {
$n = array_shift($args);
eval('$n = (int) ' . $tr['plural']);
$tr = $tr[$n];

102
app/lang/English/topic.po Normal file
View file

@ -0,0 +1,102 @@
#
msgid ""
msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Project-Id-Version: ForkBB\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: ForkBB <mio.visman@yandex.ru>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en\n"
msgid "Post reply"
msgstr "Post reply"
msgid "Topic closed"
msgstr "Topic closed"
msgid "From"
msgstr "From:"
msgid "Promote user"
msgstr "Promote user"
msgid "IP address logged"
msgstr "IP address logged"
msgid "Note"
msgstr "Note:"
msgid "%s post"
msgid_plural "%s posts"
msgstr[0] "%s post"
msgstr[1] "%s posts"
msgid "Registered:"
msgstr "Registered:"
msgid "Replies"
msgstr "Replies:"
msgid "Website"
msgstr "Website"
msgid "Online"
msgstr "Online"
msgid "Offline"
msgstr "Offline"
msgid "Last edit"
msgstr "Last edited by"
msgid "Report"
msgstr "Report"
msgid "Delete"
msgstr "Delete"
msgid "Edit"
msgstr "Edit"
msgid "Quote"
msgstr "Quote"
msgid "Is subscribed"
msgstr "You are currently subscribed to this topic"
msgid "Unsubscribe"
msgstr "Unsubscribe"
msgid "Subscribe"
msgstr "Subscribe to this topic"
msgid "Quick post"
msgstr "Quick reply"
msgid "Mod controls"
msgstr "Moderator controls"
msgid "New icon"
msgstr "New post"
msgid "Re"
msgstr "Re:"
msgid "Preview"
msgstr "Preview"
msgid "Warnings"
msgstr "Warnings:"
msgid "Reply"
msgstr "Reply"
msgid "Users online"
msgstr "Registered users online in this topic: %s"
msgid "Guests online"
msgstr "guests: %s"

103
app/lang/Russian/topic.po Normal file
View file

@ -0,0 +1,103 @@
#
msgid ""
msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Project-Id-Version: ForkBB\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: ForkBB <mio.visman@yandex.ru>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\n"
msgid "Post reply"
msgstr "Ответить"
msgid "Topic closed"
msgstr "Тема закрыта"
msgid "From"
msgstr "Откуда:"
msgid "Promote user"
msgstr "Переместить пользователя"
msgid "IP address logged"
msgstr "IP адрес"
msgid "Note"
msgstr "Замечание"
msgid "%s post"
msgid_plural "%s posts"
msgstr[0] "%s сообщение"
msgstr[1] "%s сообщения"
msgstr[2] "%s сообщений"
msgid "Registered:"
msgstr "Здесь с"
msgid "Replies"
msgstr "Ответов:"
msgid "Website"
msgstr "Сайт"
msgid "Online"
msgstr "Активен"
msgid "Offline"
msgstr "Вне форума"
msgid "Last edit"
msgstr "Отредактировано"
msgid "Report"
msgstr "Просигналить"
msgid "Delete"
msgstr "Удалить"
msgid "Edit"
msgstr "Редактировать"
msgid "Quote"
msgstr "Цитировать"
msgid "Is subscribed"
msgstr "Вы подписаны на эту тему"
msgid "Unsubscribe"
msgstr "Отказаться от подписки"
msgid "Subscribe"
msgstr "Подписаться на тему"
msgid "Quick post"
msgstr "Быстрый ответ"
msgid "Mod controls"
msgstr "Операции модерирования"
msgid "New icon"
msgstr "New post"
msgid "Re"
msgstr "Re:"
msgid "Preview"
msgstr "Предпросмотр"
msgid "Warnings"
msgstr "Предупреждений:"
msgid "Reply"
msgstr "Ответить"
msgid "Users online"
msgstr "Сейчас в этой теме пользователей: %s"
msgid "Guests online"
msgstr "гостей: %s"

View file

@ -141,9 +141,9 @@
</div>
<div class="f-cell f-cstats">
<ul>
<li>{!! __('%s Reply', $topic['num_replies'], $topic['num_replies']) !!}</li>
@if(null !== $topic['num_views'])
<li>{!! __('%s View', $topic['num_views'], $topic['num_views'])!!}</li>
<li>{!! __('%s Reply', $topic['num_replies'], $topic['replies']) !!}</li>
@if($topic['views'])
<li>{!! __('%s View', $topic['num_views'], $topic['views']) !!}</li>
@endif
</ul>
</div>

114
app/templates/topic.tpl Normal file
View file

@ -0,0 +1,114 @@
@section('crumbs')
<ul class="f-crumbs">
@foreach($crumbs as $cur)
@if($cur[2])
<li class="f-crumb"><a href="{!! $cur[0] !!}" class="active">{{ $cur[1] }}</a></li>
@else
<li class="f-crumb"><a href="{!! $cur[0] !!}">{{ $cur[1] }}</a></li>
@endif
@endforeach
</ul>
@endsection
@section('linkpost')
@if($newPost !== null)
<div class="f-link-post">
@if($newPost === false)
__('Topic closed')
@else
<a class="f-btn" href="{!! $newPost !!}">{!! __('Post reply') !!}</a>
@endif
</div>
@endif
@endsection
@section('pages')
<nav class="f-pages">
@foreach($pages as $cur)
@if($cur[2])
<span class="f-page active">{{ $cur[1] }}</span>
@elseif($cur[1] === 'space')
<span class="f-page f-pspacer">{!! __('Spacer') !!}</span>
@elseif($cur[1] === 'prev')
<a rel="prev" class="f-page f-pprev" href="{!! $cur[0] !!}">{!! __('Previous') !!}</a>
@elseif($cur[1] === 'next')
<a rel="next" class="f-page f-pnext" href="{!! $cur[0] !!}">{!! __('Next') !!}</a>
@else
<a class="f-page" href="{!! $cur[0] !!}">{{ $cur[1] }}</a>
@endif
@endforeach
</nav>
@endsection
@extends('layouts/main')
<div class="f-nav-links">
@yield('crumbs')
@if($newPost || $pages)
<div class="f-links-b clearfix">
@yield('pages')
@yield('linkpost')
</div>
@endif
</div>
<section class="f-main f-topic">
<h2>{{ $topicName }}</h2>
@foreach($posts as $post)
<article id="p{!! $post['id'] !!}" class="f-post{!! $post['poster_gender'].$post['poster_online'] !!} clearfix">
<div class="f-post-header clearfix">
<h3>{{ $topicName }} - #{!! $post['post_number'] !!}</h3>
<span class="left"><time datetime="{{ $post['posted_utc'] }}">{{ $post['posted'] }}</time></span>
<span class="right"><a href="{!! $post['link'] !!}" rel="bookmark">#{!! $post['post_number'] !!}</a></span>
</div>
<div class="f-post-body clearfix">
<address class="f-post-left clearfix">
<ul class="f-user-info">
@if($post['poster_link'])
<li class="f-username"><a href="{!! $post['poster_link'] !!}">{{ $post['poster'] }}</a></li>
@else
<li class="f-username">{{ $post['poster'] }}</li>
@endif
@if($post['poster_avatar'])
<li class="f-avatar">
<img alt="{{ $post['poster'] }}" src="{!! $post['poster_avatar'] !!}">
</li>
@endif
<li class="f-usertitle"><span>{{$post['poster_title']}}</span></li>
@if($post['poster_posts'])
<li class="f-postcount"><span>{!! __('%s post', $post['poster_num_posts'], $post['poster_posts']) !!}</span></li>
@endif
</ul>
@if($post['poster_info_add'])
<ul class="f-user-info-add">
<li><span>{!! __('Registered:') !!} {{ $post['poster_registered'] }}</span></li>
@if($post['poster_location'])
<li><span>{!! __('From') !!} {{ $post['poster_location'] }}</span></li>
@endif
<li><span></span></li>
</ul>
@endif
</address>
</div>
<div class="f-post-footer clearfix">
<div class="f-post-left">
<span></span>
</div>
@if($post['controls'])
<div class="f-post-right clearfix">
<ul>
@foreach($post['controls'] as $key => $control)
<li class="f-post{!! $key !!}"><a class="f-btn" href="{!! $control[0] !!}">{!! __($control[1]) !!}</a></li>
@endforeach
</ul>
</div>
@endif
</div>
</article>
@endforeach
</section>
<div class="f-nav-links">
@if($newPost || $pages)
<div class="f-links-a clearfix">
@yield('linkpost')
@yield('pages')
</div>
@endif
@yield('crumbs')
</div>

View file

@ -2,5 +2,6 @@
$forkStart = empty($_SERVER['REQUEST_TIME_FLOAT']) ? microtime(true) : $_SERVER['REQUEST_TIME_FLOAT'];
$forkPublic = __DIR__;
$forkPublicPrefix = '';
require __DIR__ . '/../app/bootstrap.php';

View file

@ -696,129 +696,6 @@ select {
padding: 0.625rem;
}
/********************/
/* Сообщение в теме */
/********************/
.f-post {
border-top: 0.0625rem solid #AA7939;
margin-bottom: 0.625rem;
position: relative;
background-color: #FFFFFF;
overflow: hidden;
}
.f-post-header > h3 {
display: none;
}
.f-post-header {
padding: 0.625rem;
border-bottom: 0.0625rem solid #AA7939;
background-color: #D3B58D;
}
.f-post-left {
padding: 0.625rem;
background-color: #F8F4E3;
}
.f-post-right {
padding: 0.625rem;
}
.f-post-footer .f-post-right {
text-align: right;
}
.f-post-footer .f-post-left {
display: none;
}
.f-post-footer li {
display: inline;
}
li + li .f-btn {
margin-left: 0.1875rem;
}
.f-user-info {
font-size: 0.875rem;
}
.f-user-info-custom {
display: none;
}
.f-username {
font-size: 1.25rem;
float: left;
}
.f-username a {
border: 0;
}
.f-avatar {
float: right;
}
.f-avatar img {
max-width: 4.6875rem;
height: auto;
}
.f-usertitle {
clear: left;
}
@media screen and (min-width: 50rem) {
.f-post {
background-color: #F8F4E3;
}
.f-post-body, .f-post-footer {
width: 100%;
float: right;
margin-right: -13rem;
position: relative;
border-left: 0.0625rem solid #AA7939;
background-color: #FFFFFF;
}
.f-post-left {
width: 11.75rem;
margin-left: -13rem;
float: left;
position: relative;
background-color: transparent;
}
.f-post-right {
padding-right: 13.625rem;
position: relative;
}
.f-post-footer .f-post-left {
display: block;
}
.f-user-info-custom {
display: block;
font-size: 0.875rem;
}
.f-username, .f-avatar {
float: none;
}
.f-avatar img {
max-width: 100%;
height: auto;
}
} /* @media screen and (min-width: 50rem) */
/******************/
/* Админка - меню */
/******************/
@ -1253,3 +1130,133 @@ li + li .f-btn {
border: 0;
padding: 0;
}
/*****************/
/* Страница темы */
/*****************/
.f-topic > h2 {
display: none;
}
/********************/
/* Сообщение в теме */
/********************/
.f-post {
border-top: 0.0625rem solid #AA7939;
margin-bottom: 0.625rem;
position: relative;
background-color: #FFFFFF;
overflow: hidden;
}
.f-post-header > h3 {
display: none;
}
.f-post-header {
padding: 0.625rem;
border-bottom: 0.0625rem solid #AA7939;
background-color: #D3B58D;
}
.f-post-left {
padding: 0.625rem;
background-color: #F8F4E3;
}
.f-post-right {
padding: 0.625rem;
}
.f-post-footer .f-post-right {
text-align: right;
}
.f-post-footer .f-post-left {
display: none;
}
.f-post-footer li {
display: inline;
}
li + li .f-btn {
/* margin-left: 0.1875rem; */
}
.f-user-info {
font-size: 0.875rem;
}
.f-user-info-add {
display: none;
}
.f-username {
font-size: 1.25rem;
float: left;
}
.f-username a {
border: 0;
}
.f-avatar {
float: right;
}
.f-avatar img {
max-width: 4.6875rem;
height: auto;
}
.f-usertitle {
clear: left;
}
@media screen and (min-width: 50rem) {
.f-post {
background-color: #F8F4E3;
}
.f-post-body, .f-post-footer {
width: 100%;
float: right;
margin-right: -13rem;
position: relative;
border-left: 0.0625rem solid #AA7939;
background-color: #FFFFFF;
}
.f-post-left {
width: 11.75rem;
margin-left: -13rem;
float: left;
position: relative;
background-color: transparent;
}
.f-post-right {
padding-right: 13.625rem;
position: relative;
}
.f-post-footer .f-post-left {
display: block;
}
.f-user-info-add {
display: block;
font-size: 0.875rem;
}
.f-username, .f-avatar {
float: none;
}
.f-avatar img {
max-width: 100%;
height: auto;
}
} /* @media screen and (min-width: 50rem) */