DEV: Объединение Ответов и Комментариев

См. https://libarea.ru/post/1604/testovyy-post-migraciya-kommentariev
This commit is contained in:
Evg 2023-11-20 03:24:46 +03:00
parent cbfba207a3
commit 40f9345ea4
96 changed files with 1002 additions and 1630 deletions

View File

@ -15,7 +15,7 @@ class ActionController extends Controller
$content_id = Request::getPostInt('content_id');
$type = Request::getPost('type');
$allowed = ['post', 'comment', 'answer', 'reply', 'item'];
$allowed = ['post', 'comment', 'reply', 'item'];
if (!in_array($type, $allowed)) {
return false;
}
@ -23,6 +23,7 @@ class ActionController extends Controller
// Access check
// Проверка доступа
$info_type = ActionModel::getInfoTypeContent($content_id, $type);
if (Access::author($type, $info_type) == false) {
redirect('/');
}
@ -37,11 +38,6 @@ class ActionController extends Controller
$url = post_slug($info_type['comment_post_id'], $post['post_slug']) . '#comment_' . $info_type['comment_id'];
$action_type = 'comment';
break;
case 'answer':
$post = PostModel::getPost($info_type['answer_post_id'], 'id', $this->user);
$url = post_slug($info_type['answer_post_id'], $post['post_slug']) . '#answer_' . $info_type['answer_id'];
$action_type = 'answer';
break;
case 'reply':
$url = '/';
$action_type = 'reply';

View File

@ -1,97 +0,0 @@
<?php
namespace App\Controllers\Answer;
use Hleb\Constructor\Handlers\Request;
use App\Controllers\Controller;
use App\Services\Сheck\PostPresence;
use App\Models\{NotificationModel, ActionModel, AnswerModel, PostModel};
use App\Validate\Validator;
use UserData;
class AddAnswerController extends Controller
{
public function create()
{
$post = PostPresence::index(Request::getPostInt('post_id'), 'id');
$url_post = post_slug($post['post_id'], $post['post_slug']);
Validator::Length($content = $_POST['content'], 6, 5000, 'content', $url_post);
// Let's check the stop words, url
// Проверим стоп слова и url
$trigger = (new \App\Services\Audit())->prohibitedContent($content);
$this->union($post, $url_post, $content);
$last_id = AnswerModel::add($post['post_id'], $content, $trigger);
// Add an audit entry and an alert to the admin
// Аудит и оповещение персоналу
if ($trigger === false) {
(new \App\Services\Audit())->create('answer', $last_id, url('admin.audits'));
}
$url = $url_post . '#answer_' . $last_id;
$this->notif($content, $post, $url);
ActionModel::addLogs(
[
'id_content' => $last_id,
'action_type' => 'answer',
'action_name' => 'added',
'url_content' => $url,
]
);
redirect($url);
}
public function union($post, $url_post, $content)
{
if (config('publication.merge_answer_post') == false) {
return true;
}
// Staff can write a response under their post
// Персонал может писать ответ под своим постом
if (UserData::checkAdmin()) {
return true;
}
// If there are no replies to the post and the author of the post = the author of the answer, then add the answer to the end of the post
// Если ответов на пост нет и автор поста = автора ответа, то дописываем ответ в конец поста
if ((AnswerModel::getNumberAnswers($post['post_id']) == null) && ($post['post_user_id'] == $this->user['id'])) {
AnswerModel::mergePost($post['post_id'], $content);
redirect($url_post);
}
return true;
}
// Notifications when adding a answer
// Уведомления при добавлении ответа
public function notif($content, $post, $url)
{
// Contact via @
// Обращение через @
if ($message = \App\Services\Parser\Content::parseUsers($content, true, true)) {
(new \App\Controllers\NotificationController())->mention(NotificationModel::TYPE_ADDRESSED_ANSWER, $message, $url, $post['post_user_id']);
}
// Who is following this question/post
// Кто подписан на данный вопрос / пост
if ($focus_all = PostModel::getFocusUsersPost($post['post_id'])) {
foreach ($focus_all as $focus_user) {
if ($focus_user['signed_user_id'] != $this->user['id']) {
NotificationModel::send($focus_user['signed_user_id'], NotificationModel::TYPE_AMSWER_POST, $url);
}
}
}
}
}

View File

@ -1,74 +0,0 @@
<?php
namespace App\Controllers\Answer;
use Hleb\Constructor\Handlers\Request;
use App\Controllers\Controller;
use App\Services\Сheck\PostPresence;
use App\Services\Сheck\AnswerPresence;
use App\Models\AnswerModel;
use App\Models\User\UserModel;
use App\Validate\Validator;
use Meta, Access;
use App\Traits\Author;
class EditAnswerController extends Controller
{
use Author;
// Edit form answer
public function index()
{
$answer = AnswerPresence::index(Request::getInt('id'));
if (Access::author('answer', $answer) == false) {
return false;
}
$post = PostPresence::index($answer['answer_post_id'], 'id');
return $this->render(
'/answer/edit',
[
'meta' => Meta::get(__('app.edit_answer')),
'data' => [
'post' => $post,
'answer' => $answer,
'user' => UserModel::getUser($answer['answer_user_id'], 'id'),
'sheet' => 'edit-answers',
'type' => 'answer',
]
]
);
}
public function change()
{
$answer_id = Request::getPostInt('answer_id');
$content = $_POST['content']; // для Markdown
// Access check
$answer = AnswerModel::getAnswerId($answer_id);
if (Access::author('answer', $answer) == false) {
return false;
}
$post = PostPresence::index($answer['answer_post_id'], 'id');
$url_post = post_slug($answer['answer_post_id'], $post['post_slug']);
Validator::Length($content, 6, 5000, 'content', url('content.edit', ['type' => 'answer', 'id' => $answer['answer_id']]));
AnswerModel::edit(
[
'answer_id' => $answer['answer_id'],
'answer_content' => $content,
'answer_user_id' => $this->selectAuthor($answer['answer_user_id'], Request::getPost('user_id')),
'answer_modified' => date("Y-m-d H:i:s"),
]
);
is_return(__('msg.change_saved'), 'success', $url_post . '#answer_' . $answer['answer_id']);
}
}

View File

@ -4,47 +4,42 @@ namespace App\Controllers\Comment;
use Hleb\Constructor\Handlers\Request;
use App\Controllers\Controller;
use App\Services\Сheck\PostPresence;
use App\Services\Сheck\AnswerPresence;
use App\Models\{NotificationModel, ActionModel, AnswerModel, CommentModel};
use App\Services\Сheck\{PostPresence, CommentPresence};
use App\Models\{NotificationModel, ActionModel, CommentModel, PostModel};
use App\Validate\Validator;
use UserData;
class AddCommentController extends Controller
{
// Show the form for adding a comment
// Show the form for adding a комментария
// Покажем форму добавление комментария
public function index()
{
insert(
'/_block/form/add-comment',
[
'data' => [
'answer_id' => Request::getPostInt('answer_id'),
'comment_id' => Request::getPostInt('comment_id'),
],
]
);
insert('/_block/form/add-comment');
}
// Adding a comment
public function create()
{
$answer_id = Request::getPostInt('answer_id'); // на какой ответ
$comment_id = Request::getPostInt('comment_id'); // на какой комментарий
$answer = AnswerPresence::index($answer_id);
$post = PostPresence::index($answer['answer_post_id'], 'id');
{
if ($post_id = Request::getPostInt('post_id')) {
$post = PostPresence::index($post_id, 'id');
}
if ($comment_id = Request::getPostInt('comment_id')) {
$comment = CommentPresence::index($comment_id);
$post = PostPresence::index($comment['comment_post_id'], 'id');
}
$url_post = post_slug($post['post_id'], $post['post_slug']);
Validator::Length($content = $_POST['comment'], 6, 2024, 'content', $url_post);
Validator::Length($content = $_POST['content'], 6, 5000, 'content', $url_post);
// Let's check the stop words, url
// Проверим стоп слова, url
// Проверим стоп слова и url
$trigger = (new \App\Services\Audit())->prohibitedContent($content);
$last_id = CommentModel::add($post['post_id'], $answer_id, $comment_id, $content, $trigger);
$this->union($post, $url_post, $content);
$last_id = CommentModel::add($post['post_id'], $comment_id, $content, $trigger);
// Add an audit entry and an alert to the admin
// Аудит и оповещение персоналу
@ -54,13 +49,13 @@ class AddCommentController extends Controller
$url = $url_post . '#comment_' . $last_id;
$this->notif($answer_id, $comment_id, $content, $url);
$this->notifPost($content, $post, $comment_id, $url);
ActionModel::addLogs(
[
'id_content' => $last_id,
'action_type' => 'comment',
'action_name' => 'added',
'action_name' => 'comment',
'url_content' => $url,
]
);
@ -68,30 +63,57 @@ class AddCommentController extends Controller
redirect($url);
}
// Notifications when adding a comment
// Уведомления при добавлении комментария
public function notif($answer_id, $comment_id, $content, $url)
public function union($post, $url_post, $content)
{
// Notification to the author of the answer that there is a comment (do not write to ourselves)
// Оповещение автору ответа, что есть комментарий (себе не записываем)
$answ = AnswerModel::getAnswerId($answer_id);
if ($this->user['id'] != $answ['answer_user_id']) {
NotificationModel::send($answ['answer_user_id'], NotificationModel::TYPE_COMMENT_ANSWER, $url);
if (config('publication.merge_answer_post') == false) {
return true;
}
if ($comment_id) {
$comment = CommentModel::getCommentsId($comment_id);
if ($this->user['id'] != $comment['comment_user_id']) {
if ($answ['answer_user_id'] != $comment['comment_user_id']) {
NotificationModel::send($comment['comment_user_id'], NotificationModel::TYPE_COMMENT_COMMENT, $url);
}
}
// Staff can write a response under their post
// Персонал может писать ответ под своим постом
if (UserData::checkAdmin()) {
return true;
}
// If there are no replies to the post and the author of the post = the author of the comment, then add the comment to the end of the post
// Если ответов на пост нет и автор поста = автора ответа, то дописываем ответ в конец поста
if ((CommentModel::getNumberComment($post['post_id']) == null) && ($post['post_user_id'] == $this->user['id'])) {
CommentModel::mergePost($post['post_id'], $content);
redirect($url_post);
}
return true;
}
// Notifications when adding a answer
// Уведомления при добавлении ответа
public function notifPost($content, $post, $comment_id, $url)
{
// Contact via @
// Обращение через @
if ($message = \App\Services\Parser\Content::parseUsers($content, true, true)) {
(new \App\Controllers\NotificationController())->mention(NotificationModel::TYPE_ADDRESSED_COMMENT, $message, $url, $comment['comment_user_id']);
(new \App\Controllers\NotificationController())->mention(NotificationModel::TYPE_ADDRESSED_ANSWER, $message, $url, $post['post_user_id']);
}
// Who is following this question/post
// Кто подписан на данный вопрос / пост
if ($focus_all = PostModel::getFocusUsersPost($post['post_id'])) {
foreach ($focus_all as $focus_user) {
if ($focus_user['signed_user_id'] != $this->user['id']) {
NotificationModel::send($focus_user['signed_user_id'], NotificationModel::TYPE_AMSWER_POST, $url);
}
}
}
// Notifications when adding a comment
// Уведомления при добавлении комментария
if ($comment_id) {
$comment = CommentModel::getCommentId($comment_id);
if ($this->user['id'] != $comment['comment_user_id']) {
NotificationModel::send($comment['comment_user_id'], NotificationModel::TYPE_COMMENT_COMMENT, $url);
}
}
}
}

View File

@ -3,35 +3,27 @@
namespace App\Controllers\Comment;
use App\Controllers\Controller;
use App\Models\{CommentModel, AnswerModel};
use App\Models\CommentModel;
use Meta, Html;
class CommentController extends Controller
{
protected $limit = 10;
// All comments (combining answers and comments for UX)
// Все комментарии (объединение ответов и комментариев для UX)
// All comments
// Все комменатрии
public function index($sheet)
{
$pagesCount = CommentModel::getCommentsCount($sheet);
$comments = CommentModel::getComments($this->pageNumber, $this->limit, $sheet);
$pagesCount = AnswerModel::getAnswersCount($sheet);
$answers = AnswerModel::getAnswers($this->pageNumber, $this->limit, $sheet);
$comments = CommentModel::getComments($this->pageNumber, $sheet);
$m = [
'og' => false,
'url' => url('comments'),
];
$mergedArr = array_merge($comments, $answers);
usort($mergedArr, function ($a, $b) {
return ($b['comment_date'] ?? $b['answer_date']) <=> ($a['comment_date'] ?? $a['answer_date']);
});
return $this->render(
'/comment/comments',
'/comments/all',
[
'meta' => Meta::get(__('meta.all_comments'), __('meta.comments_desc'), $m),
'data' => [
@ -39,25 +31,10 @@ class CommentController extends Controller
'pNum' => $this->pageNumber,
'sheet' => $sheet,
'type' => 'comments',
'comments' => $mergedArr,
'comments' => $comments,
]
]
);
}
// On the home page
// На главной странице
public function lastComment()
{
$comments = CommentModel::getComments(1, 5, 'all');
$result = [];
foreach ($comments as $ind => $row) {
$row['content'] = fragment($row['comment_content'], 98);
$row['date'] = Html::langDate($row['comment_date']);
$result[$ind] = $row;
}
return json_encode($result, JSON_PRETTY_PRINT);
}
}

View File

@ -4,59 +4,71 @@ namespace App\Controllers\Comment;
use Hleb\Constructor\Handlers\Request;
use App\Controllers\Controller;
use App\Services\Сheck\{PostPresence, CommentPresence};
use App\Services\Сheck\PostPresence;
use App\Services\Сheck\CommentPresence;
use App\Models\CommentModel;
use App\Models\User\UserModel;
use App\Validate\Validator;
use Access;
use Meta, Access;
use App\Traits\Author;
class EditCommentController extends Controller
{
// Comment Editing Form
// Форма редактирования комментария
use Author;
// Edit form comment
public function index()
{
// Access verification
// Проверка доступа
$comment = CommentPresence::index(Request::getPostInt('comment_id'));
$comment = CommentPresence::index(Request::getInt('id'));
if (Access::author('comment', $comment) == false) {
return false;
}
insert(
'/_block/form/edit-comment',
$post = PostPresence::index($comment['comment_post_id'], 'id');
return $this->render(
'/comments/edit',
[
'meta' => Meta::get(__('app.edit_comment')),
'data' => [
'comment_id' => $comment['comment_id'],
'comment_content' => $comment['comment_content'],
],
'user' => $this->user
'post' => $post,
'comment' => $comment,
'user' => UserModel::getUser($comment['comment_user_id'], 'id'),
'sheet' => 'edit-answers',
'type' => 'comment',
]
]
);
}
public function change()
{
// Access verification
$comment = CommentPresence::index(Request::getPostInt('comment_id'));
$comment_id = Request::getPostInt('comment_id');
$content = $_POST['content']; // для Markdown
// Access check
$comment = CommentModel::getCommentId($comment_id);
if (Access::author('comment', $comment) == false) {
redirect('/');
return false;
}
$post = PostPresence::index($comment['comment_post_id'], 'id');
$redirect = post_slug($post['post_id'], $post['post_slug']) . '#comment_' . $comment['comment_id'];
$url_post = post_slug($comment['comment_post_id'], $post['post_slug']);
$content = $_POST['comment']; // для Markdown
Validator::length($content, 3, 5500, 'content', $redirect);
Validator::Length($content, 6, 5000, 'content', url('content.edit', ['type' => 'comment', 'id' => $comment['comment_id']]));
CommentModel::edit(
[
'comment_id' => $comment['comment_id'],
'comment_content' => $content,
'comment_modified' => date("Y-m-d H:i:s"),
'comment_id' => $comment['comment_id'],
'comment_content' => $content,
'comment_user_id' => $this->selectAuthor($comment['comment_user_id'], Request::getPost('user_id')),
'comment_modified' => date("Y-m-d H:i:s"),
]
);
redirect($redirect);
is_return(__('msg.change_saved'), 'success', $url_post . '#comment_' . $comment['comment_id']);
}
}

View File

@ -55,8 +55,8 @@ class FormController extends Controller
return (new Poll\EditPollController)->index();
}
if ($this->type === 'answer') {
return (new Answer\EditAnswerController)->index();
if ($this->type === 'comment') {
return (new Comment\EditCommentController)->index();
}
if ($this->type === 'item') {
@ -83,10 +83,6 @@ class FormController extends Controller
return (new Facets\AddFacetController)->create($this->type);
}
if ($this->type === 'answer') {
return (new Answer\AddAnswerController)->create();
}
if ($this->type === 'comment') {
return (new Comment\AddCommentController)->create();
}
@ -131,10 +127,6 @@ class FormController extends Controller
return (new Poll\EditPollController)->change();
}
if ($this->type === 'answer') {
return (new Answer\EditAnswerController)->change();
}
if ($this->type === 'comment') {
return (new Comment\EditCommentController)->change();
}

View File

@ -24,7 +24,7 @@ class HomeController extends Controller
'sheet' => $sheet,
'topics' => $topics,
'type' => 'main',
'latest_answers' => HomeModel::latestAnswers(),
'latest_comments' => HomeModel::latestComments(),
'topics_user' => HomeModel::subscription(),
'posts' => HomeModel::feed($this->pageNumber, $sheet),
'items' => HomeModel::latestItems(),

View File

@ -183,7 +183,7 @@ class EditPostController extends Controller
$type = Request::get('type');
$id = Request::getInt('id');
if (!in_array($type, ['post-telo', 'answer'])) {
if (!in_array($type, ['post-telo', 'comment'])) {
return false;
}

View File

@ -7,7 +7,8 @@ use App\Controllers\Controller;
use App\Services\Сheck\PostPresence;
use App\Services\Сheck\FacetPresence;
use App\Services\Meta\Post;
use App\Models\{PostModel, AnswerModel, CommentModel, SubscriptionModel, FeedModel};
use App\Services\Tree\BuildTree;
use App\Models\{PostModel, CommentModel, SubscriptionModel, FeedModel};
use Meta, UserData;
use App\Traits\Views;
@ -28,6 +29,7 @@ class PostController extends Controller
{
$slug = Request::get('slug');
$id = Request::getInt('id');
$sorting = Request::getGet('sort');
$content = self::presence($type, $id, $slug);
@ -48,12 +50,6 @@ class PostController extends Controller
redirect(url('facet.article', ['facet_slug' => 'info', 'slug' => $content['post_slug']]));
}
// Q&A (post_feature == 1) or Discussiona
$content['amount_content'] = ($content['post_feature'] == 0) ? $content['post_comments_count'] + $content['post_answers_count'] : $content['post_answers_count'];
// Get replies and comments on the post
$answers = $this->answersPost($content['post_id'], $content['post_feature'], $sorting = Request::getGet('sort'));
if ($content['post_related']) {
$related_posts = PostModel::postRelated($content['post_related']);
}
@ -61,6 +57,8 @@ class PostController extends Controller
// Sending Last-Modified and handling HTTP_IF_MODIFIED_SINCE
$this->getDataModified($content['post_modified']);
$comments = CommentModel::getCommentsPost($content['post_id'], $content['post_feature'], $sorting);
if ($type == 'post') {
return $this->render(
'/post/post-view',
@ -68,7 +66,7 @@ class PostController extends Controller
'meta' => Post::metadata($content),
'data' => [
'post' => $content,
'answers' => $answers,
'comments' => BuildTree::index(0, $comments),
'recommend' => PostModel::postSimilars($content['post_id'], $facets[0]['facet_id'] ?? null),
'related_posts' => $related_posts ?? '',
'post_signed' => SubscriptionModel::getFocus($content['post_id'], 'post'),
@ -103,26 +101,6 @@ class PostController extends Controller
);
}
// Get replies and comments on the post
// Получим ответы и комментарии на пост
public function answersPost($post_id, $post_feature, $sorting)
{
$post_answers = AnswerModel::getAnswersPost($post_id, $post_feature, $sorting);
$answers = [];
foreach ($post_answers as $ind => $row) {
if (strtotime($row['answer_modified']) < strtotime($row['answer_date'])) {
$row['edit'] = 1;
}
// TODO: N+1 см. AnswerModel()
$row['comments'] = CommentModel::getCommentsAnswer($row['answer_id']);
$answers[$ind] = $row;
}
return $answers;
}
public static function presence($type, $id, $slug)
{
// Check id and get content data

View File

@ -30,7 +30,7 @@ class SearchController extends Controller
$q = Request::getGet('q');
$type = Request::getGet('cat');
if (!in_array($type, ['post', 'website', 'answer'])) {
if (!in_array($type, ['post', 'website', 'comment'])) {
$type = 'post';
}
@ -44,6 +44,7 @@ class SearchController extends Controller
}
$results = SearchModel::getSearch($this->pageNumber, $this->limit, $q, $type);
$count_results = SearchModel::getSearchCount($q, $type);
$user_id = UserData::getUserId();

View File

@ -6,7 +6,7 @@ use Hleb\Constructor\Handlers\Request;
use App\Services\Meta\Profile;
use App\Controllers\Controller;
use App\Models\User\{UserModel, BadgeModel};
use App\Models\{FacetModel, FeedModel, AnswerModel, CommentModel, PostModel, IgnoredModel};
use App\Models\{FacetModel, FeedModel, CommentModel, PostModel, IgnoredModel};
use UserData;
use App\Traits\Views;
@ -71,18 +71,8 @@ class ProfileController extends Controller
{
$profile = $this->profile();
$answers = AnswerModel::userAnswers($this->pageNumber, $this->limit, $profile['id'], $this->user['id']);
$answerCount = AnswerModel::userAnswersCount($profile['id']);
$comments = CommentModel::userComments($this->pageNumber, $this->limit, $profile['id'], $this->user['id']);
$commentCount = CommentModel::userCommentsCount($profile['id']);
$pagesCount = $answerCount + $commentCount;
$mergedArr = array_merge($comments, $answers);
usort($mergedArr, function ($a, $b) {
return ($b['comment_date'] ?? $b['answer_date']) <=> ($a['comment_date'] ?? $a['answer_date']);
});
$comments = CommentModel::userComments($this->pageNumber, $profile['id'], $this->user['id']);
$commentsCount = CommentModel::userCommentsCount($profile['id']);
$this->indexing($profile['id']);
@ -90,7 +80,7 @@ class ProfileController extends Controller
'/user/profile/comments',
[
'meta' => Profile::metadata('profile_comments', $profile),
'data' => array_merge($this->sidebar($pagesCount, $profile), ['comments' => $mergedArr]),
'data' => array_merge($this->sidebar($commentsCount, $profile), ['comments' => $comments]),
]
);
}
@ -151,7 +141,7 @@ class ProfileController extends Controller
public function indexing($profile_id)
{
$amount = UserModel::contentCount($profile_id, 'active');
if (($amount['count_answers'] + $amount['count_comments']) < 3) {
if (($amount['count_comments']) < 3) {
Request::getHead()->addMeta('robots', 'noindex');
}

View File

@ -250,7 +250,6 @@ class SettingController extends Controller
'setting_email_appealed' => Request::getPostInt('setting_email_appealed'),
'setting_email_post' => 0,
'setting_email_answer' => 0,
'setting_email_comment' => 0,
]
);

View File

@ -49,10 +49,10 @@ class UserController extends Controller
$result = [];
foreach ($favorites as $ind => $row) {
if ($row['action_type'] == 'post') {
$row['answer_post_id'] = $row['post_id'];
$row['comment_post_id'] = $row['post_id'];
}
$row['post'] = PostModel::getPost($row['answer_post_id'], 'id', $this->user);
$row['post'] = PostModel::getPost($row['comment_post_id'], 'id', $this->user);
$result[$ind] = $row;
}

View File

@ -76,7 +76,7 @@ class Html
return ((int)$a[2] . " " . $months[$later] . " " . $a[0]);
}
// Voting for posts, replies, comments and sites
// Voting for posts, replies, answer and sites
public static function votes($content, $type, $icon = 'heart')
{
$count = $content[$type . '_votes'] > 0 ? $content[$type . '_votes'] : '';

View File

@ -311,6 +311,7 @@ return [
'num_message' => ['رسالة', 'رسائل', 'رسائل'],
'num_answer' => ['اجابة', 'اجابات', 'اجابات'],
'num_comment' => ['تعليق', 'تعليقات', 'تعليقات'],
'num_post' => ['منشور', 'منشورات', 'منشورات'],
'num_view' => ['مشاهدة', 'مشاهدات', 'مشاهدات'],
'num_up' => ['اعجابات', 'اعجابات', 'اعجابات'],
@ -356,7 +357,7 @@ return [
'slug' => 'اختصار',
'email' => 'بريد الكتروني',
'wiki' => 'ويكي',
'edit_answer' => 'لـ\'تعديل الاجابة',
'edit_comment' => 'دعونا نغير التعليق',
'enter' => 'ادخل',
'enter_password' => 'ادخل كلمة السر',

View File

@ -10,7 +10,7 @@ return [
'all' => 'الكل',
'posts' => 'المنشورات',
'websites' => 'المواقع',
'answers' => 'اجابات',
'comments' => 'تعليقات',
'registration' => 'التسجيل',
'sign_in' => 'تسجيل الدخول',
'find' => 'البحث...',

View File

@ -315,6 +315,7 @@ return [
'num_message' => ['Message', 'Messages', 'Messages'],
'num_answer' => ['Answer', 'Answers', 'Answers'],
'num_comment' => ['Comment', 'Comments', 'Comments'],
'num_post' => ['Post', 'Posts', 'Posts'],
'num_view' => ['View', 'Views', 'Views'],
'num_up' => ['likes', 'likes', 'likes'],
@ -360,7 +361,7 @@ return [
'slug' => 'SLUG',
'email' => 'Email',
'wiki' => 'Wiki',
'edit_answer' => 'Let\'s change the answer',
'edit_comment' => 'Change the comment',
'enter' => 'Enter',
'enter_password' => 'Enter password',

View File

@ -9,7 +9,7 @@
return [
'all' => 'All',
'posts' => 'Posts',
'answers' => 'Answers',
'comments' => 'Comments',
'websites' => 'Sites',
'registration' => 'Registration',
'sign_in' => 'To come in',

View File

@ -314,6 +314,7 @@ return [
'num_message' => ['Mesaj', 'Mesaje', 'Mesaje'],
'num_answer' => ['Răspuns', 'Răspuns', 'Răspunsuri'],
'num_comment' => ['Comentariu', 'Comentariu', 'Comentarii'],
'num_post' => ['Postează', 'Postează', 'Postează'],
'num_view' => ['Vizualizare', 'Vizualizare', 'Vizualizare'],
'num_up' => ['Voce', 'Voci', 'Voci'],
@ -359,7 +360,7 @@ return [
'slug' => 'SLUG',
'email' => 'Email',
'wiki' => 'Wiki',
'edit_answer' => 'Să schimbăm răspunsul',
'edit_comment' => 'Schimbă comentariul',
'enter' => 'Introduce',
'enter_password' => 'Introdu parola',

View File

@ -9,7 +9,7 @@
return [
'all' => 'Toate',
'posts' => 'Postări',
'answers' => 'Răspunsuri',
'comments' => 'Comentarii',
'websites' => 'Site-uri',
'registration' => 'Înregistrare',
'sign_in' => 'Conectare',

View File

@ -245,7 +245,7 @@ return [
'default' => '(по умолчанию)',
'qa' => 'Вопросы и ответы',
'best_answer' => 'Лучший ответ',
'raise_answer' => 'Поднять ответ',
'raise_answer' => 'Поднять ответ',
'answered' => 'Ответили',
'post_translation' => 'Пост является переводом?',
'translation' => 'Перевод',
@ -314,6 +314,7 @@ return [
'num_message' => ['Сообщение', 'Сообщения', 'Сообщений'],
'num_answer' => ['Ответ', 'Ответа', 'Ответов'],
'num_comment' => ['Комментарий', 'Комментария', 'Комментариев'],
'num_post' => ['Пост', 'Поста', 'Постов'],
'num_view' => ['Просмотр', 'Просмотра', 'Просмотров'],
'num_up' => ['Голос', 'Голоса', 'Голосов'],
@ -359,7 +360,7 @@ return [
'slug' => 'SLUG',
'email' => 'Email',
'wiki' => 'Wiki',
'edit_answer' => 'Изменим ответ',
'edit_comment' => 'Изменим комментарий',
'enter' => 'Введите',
'enter_password' => 'Введите пароль',

View File

@ -9,7 +9,7 @@
return [
'all' => 'Все',
'posts' => 'Посты',
'answers' => 'Ответы',
'comments' => 'Комментарии',
'websites' => 'Сайты',
'registration' => 'Регистрация',
'sign_in' => 'Войти',

View File

@ -314,6 +314,7 @@ return [
'num_message' => ['Повідомлення', 'Повідомлення', 'Повідомлень'],
'num_answer' => ['Відповідь', 'Відповіді', 'Відповідей'],
'num_comment' => ['Коментар', 'Коментаря', 'Коментарів'],
'num_post' => ['Пост', 'Поста', 'Постів'],
'num_view' => ['Перегляд', 'Перегляду', 'Переглядів'],
'num_up' => ['Голос', 'Голосу', 'Голосів'],
@ -359,7 +360,7 @@ return [
'slug' => 'SLUG',
'email' => 'Email',
'wiki' => 'Wiki',
'edit_answer' => 'Змінимо відповідь',
'edit_comment' => 'Змінимо коментар',
'enter' => 'Введіть',
'enter_password' => 'Введіть пароль',

View File

@ -9,7 +9,7 @@
return [
'all' => 'Всі',
'posts' => 'Пости',
'answers' => 'Відповіді',
'comments' => 'Коментарі',
'websites' => 'Сайти',
'registration' => 'Реєстрація',
'sign_in' => 'Увійти',

View File

@ -314,6 +314,7 @@ return [
'num_message' => ['Tin nhắn', 'Tin nhắn', 'Tin nhắn'],
'num_answer' => ['Trả lời', 'Trả lời', 'Câu trả lời'],
'num_comment' => ['Bình Luận', 'Bình Luận', 'Bình Luận'],
'num_post' => ['Bài đăng', 'Bài đăng', 'Postov'],
'num_view' => ['Chế độ xem', 'Lượt xem', 'Lượt xem'],
'num_up' => ['Giọng nói', 'Giọng nói', 'Giọng nói'],
@ -359,7 +360,7 @@ return [
'slug' => 'SLUG',
'email' => 'Email',
'wiki' => 'Wiki',
'edit_answer' => 'Hãy thay đổi câu trả lời',
'edit_comment' => 'Thay đổi nhận xé',
'enter' => 'Đi vào',
'enter_password' => 'Nhập mật khẩu',

View File

@ -9,7 +9,7 @@
return [
'all' => 'Tất cả',
'posts' => 'Bài viết',
'answers' => 'Trả lời',
'comments' => 'Bình luận',
'websites' => 'Trang',
'registration' => 'Đăng ký',
'sign_in' => 'Cần đi vào',

View File

@ -312,11 +312,12 @@ return [
'today' => '今天',
'yesterday' => '昨天',
'num_message' => ['消息', '消息', '消息'],
'num_answer' => ['回复', '回复', '回复'],
'num_post' => ['帖子', '帖子', '帖子'],
'num_view' => ['查看', '查看', '查看'],
'num_up' => ['喜欢', '喜欢', '喜欢'],
'num_message' => ['消息', '消息', '消息'],
'num_answer' => ['回复', '回复', '回复'],
'num_comment' => ['注释','注释','注释'],
'num_post' => ['帖子', '帖子', '帖子'],
'num_view' => ['查看', '查看', '查看'],
'num_up' => ['喜欢', '喜欢', '喜欢'],
'comment' => '评论',
'comments' => '评论',
@ -360,7 +361,7 @@ return [
'slug' => '别名',
'email' => '邮箱',
'wiki' => 'Wiki',
'edit_answer' => '让我们更改答复',
'edit_comment' => '更改注释',
'enter' => '输入',
'enter_password' => '输入密码',

View File

@ -9,7 +9,7 @@
return [
'all' => '全部',
'posts' => '帖子',
'answers' => '答案',
'comments' => '评论',
'websites' => '网站',
'registration' => '注册',
'sign_in' => '登录',

View File

@ -313,11 +313,12 @@ return [
'today' => '今天',
'yesterday' => '昨天',
'num_message' => ['消息', '消息', '消息'],
'num_answer' => ['答案', '答案', '答案'],
'num_post' => ['后', '后', '后'],
'num_view' => ['视图', '视图', '视图'],
'num_up' => ['声音', '声音', '声音'],
'num_message' => ['消息', '消息', '消息'],
'num_answer' => ['答案', '答案', '答案'],
'num_comment' => ['注释','注释','注释'],
'num_post' => ['后', '后', '后'],
'num_view' => ['视图', '视图', '视图'],
'num_up' => ['声音', '声音', '声音'],
'comment' => '评论',
'comments' => '评论',
@ -360,7 +361,7 @@ return [
'slug' => 'SLUG',
'email' => 'Email',
'wiki' => 'Wiki',
'edit_answer' => '让我们改变答案',
'edit_comment' => '更改注释',
'enter' => '进入',
'enter_password' => '输入密码',

View File

@ -9,7 +9,7 @@
return [
'all' => '全部',
'posts' => '帖子',
'answers' => '答案',
'comments' => '评论',
'websites' => '網站',
'registration' => '登記',
'sign_in' => '進來',

View File

@ -72,13 +72,11 @@ class ActionModel extends \Hleb\Scheme\App\Models\MainModel
(SELECT COUNT(*) FROM
posts WHERE post_user_id = $user_id and post_is_deleted = 0) AS t1Count,
(SELECT COUNT(*) FROM
answers WHERE answer_user_id = $user_id and answer_is_deleted = 0) AS t2Count,
(SELECT COUNT(*) FROM
comments WHERE comment_user_id = $user_id and comment_is_deleted = 0) AS t3Count";
comments WHERE comment_user_id = $user_id and comment_is_deleted = 0) AS t2Count";
$lists = DB::run($sql)->fetch();
return $lists['t1Count'] + $lists['t2Count'] + $lists['t3Count'];
return $lists['t1Count'] + $lists['t2Count'];
}
// Member Content Posting Frequency

View File

@ -1,324 +0,0 @@
<?php
namespace App\Models;
use Hleb\Constructor\Handlers\Request;
use App\Models\PostModel;
use UserData;
use DB;
class AnswerModel extends \Hleb\Scheme\App\Models\MainModel
{
// Add an answer
// Добавим ответ
public static function add($post_id, $content, $trigger)
{
$params = [
'answer_post_id' => $post_id,
'answer_content' => $content,
'answer_published' => ($trigger === false) ? 0 : 1,
'answer_ip' => Request::getRemoteAddress(),
'answer_user_id' => UserData::getUserId(),
];
$sql = "INSERT INTO answers(answer_post_id,
answer_content,
answer_published,
answer_ip,
answer_user_id)
VALUES(:answer_post_id,
:answer_content,
:answer_published,
:answer_ip,
:answer_user_id)";
DB::run($sql, $params);
$sql_last_id = DB::run("SELECT LAST_INSERT_ID() as last_id")->fetch();
// Recalculating the number of responses for the post + 1
// Пересчитываем количество ответов для поста + 1
PostModel::updateCount($post_id, 'answers');
return $sql_last_id['last_id'];
}
// Editing the answer
// Редактируем ответ
public static function edit($params)
{
$sql_two = "UPDATE answers SET answer_content = :answer_content,
answer_modified = :answer_modified, answer_user_id = :answer_user_id
WHERE answer_id = :answer_id";
return DB::run($sql_two, $params);
}
// All answers
// Все ответы
public static function getAnswers($page, $limit, $sheet)
{
$user_id = UserData::getUserId();
$sort = self::sorts($sheet);
$start = ($page - 1) * $limit;
$sql = "SELECT
post_id,
post_title,
post_slug,
post_user_id,
post_closed,
post_feature,
post_is_deleted,
answer_id,
answer_content,
answer_date,
answer_after,
answer_user_id,
answer_ip,
answer_post_id,
answer_votes,
answer_is_deleted,
answer_published,
votes_answer_item_id,
votes_answer_user_id,
fav.tid,
fav.user_id,
fav.action_type,
u.id,
u.login,
u.avatar
FROM answers
INNER JOIN users u ON u.id = answer_user_id
INNER JOIN posts ON answer_post_id = post_id
LEFT JOIN votes_answer ON votes_answer_item_id = answer_id
AND votes_answer_user_id = $user_id
LEFT JOIN favorites fav ON fav.tid = answer_id
AND fav.user_id = $user_id
AND fav.action_type = 'answer'
$sort
ORDER BY answer_id DESC LIMIT :start, :limit ";
return DB::run($sql, ['start' => $start, 'limit' => $limit])->fetchAll();
}
public static function getAnswersCount($sheet)
{
$sort = self::sorts($sheet);
$sql = "SELECT answer_id FROM answers INNER JOIN posts ON answer_post_id = post_id $sort";
return DB::run($sql)->rowCount();
}
public static function sorts($sheet)
{
$hidden = UserData::checkAdmin() ? "" : "AND post_hidden = 0";
switch ($sheet) {
case 'all':
$sort = "WHERE answer_is_deleted = 0 AND post_tl = 0 AND post_is_deleted = 0 $hidden";
break;
case 'deleted':
$sort = "WHERE answer_is_deleted = 1";
break;
}
return $sort;
}
// Number of replies per post
// Количество ответов на пост
public static function getNumberAnswers($post_id)
{
$sql = "SELECT answer_id FROM answers WHERE answer_post_id = :id AND answer_is_deleted = 0";
return DB::run($sql, ['id' => $post_id])->rowCount();
}
// Add the answer to the end of the post
// Добавим ответ в конец поста
public static function mergePost($post_id, $content)
{
$sql = "UPDATE posts SET post_content = CONCAT(post_content, :content) WHERE post_id = :post_id";
$content = "\n\n `+` " . $content;
return DB::run($sql, ['post_id' => $post_id, 'content' => $content]);
}
// Getting answers in a post
// Получаем ответы в посте
public static function getAnswersPost($post_id, $type, $sorting = 'new')
{
$user_id = UserData::getUserId();
if ($type == 1) {
$sorting = 'top';
}
switch ($sorting) {
case 'top':
$sort = 'ORDER BY answer_lo DESC, answer_votes DESC';
break;
case 'old':
$sort = 'ORDER BY answer_id DESC';
break;
// new
default:
$sort = '';
break;
}
// TODO: Сгруппировать комментарии по ответу (избавимся N+1)
// LEFT JOIN comments ON comment_answer_id = answer_id
// comment_answer_id,
// comment_user_id,
// comment_date,
// comment_ip,
// comment_content,
$sql = "SELECT
answer_id,
answer_user_id,
answer_post_id,
answer_date,
answer_content,
answer_modified,
answer_published,
answer_ip,
answer_votes,
answer_after,
answer_lo,
answer_is_deleted,
votes_answer_item_id,
votes_answer_user_id,
fav.tid,
fav.user_id,
fav.action_type,
u.id,
u.login,
u.avatar,
u.created_at
FROM answers
LEFT JOIN users u ON u.id = answer_user_id
LEFT JOIN votes_answer ON votes_answer_item_id = answer_id
AND votes_answer_user_id = $user_id
LEFT JOIN favorites fav ON fav.tid = answer_id
AND fav.user_id = $user_id
AND fav.action_type = 'answer'
WHERE answer_post_id = $post_id
$sort ";
return DB::run($sql)->fetchAll();
}
// User responses
// Ответы участника
public static function userAnswers($page, $limit, $user_id, $uid_vote)
{
$start = ($page - 1) * $limit;
$sql = "SELECT
answer_id,
answer_user_id,
answer_post_id,
answer_date,
answer_content,
answer_modified,
answer_published,
answer_ip,
answer_votes,
answer_after,
answer_is_deleted,
votes_answer_item_id,
votes_answer_user_id,
post_id,
post_title,
post_slug,
post_user_id,
post_closed,
post_is_deleted,
id,
login,
avatar
FROM answers
LEFT JOIN users ON id = answer_user_id
LEFT JOIN posts ON answer_post_id = post_id
LEFT JOIN votes_answer ON votes_answer_item_id = answer_id
AND votes_answer_user_id = :uid_vote
WHERE answer_user_id = :user_id AND post_hidden = 0
AND answer_is_deleted = 0 AND post_is_deleted = 0 AND post_tl = 0 AND post_tl = 0
ORDER BY answer_id DESC LIMIT :start, :limit ";
return DB::run($sql, ['user_id' => $user_id, 'uid_vote' => $uid_vote, 'start' => $start, 'limit' => $limit])->fetchAll();
}
public static function userAnswersCount($user_id)
{
$sql = "SELECT
answer_id
FROM answers
LEFT JOIN posts ON answer_post_id = post_id
WHERE answer_user_id = :user_id AND answer_is_deleted = 0
AND post_is_deleted = 0 AND post_tl = 0 AND post_tl = 0";
return DB::run($sql, ['user_id' => $user_id])->rowCount();
}
// Information on the id of the answer
// Информацию по id ответа
public static function getAnswerId($answer_id)
{
$sql = "SELECT
answer_id,
answer_post_id,
answer_user_id,
answer_date,
answer_modified,
answer_published,
answer_ip,
answer_order,
answer_after,
answer_votes,
answer_content,
answer_lo,
answer_is_deleted
FROM answers
WHERE answer_id = :answer_id";
return DB::run($sql, ['answer_id' => $answer_id])->fetch();
}
/*
* Best answer
*/
// Choice of the best answer
// Выбор лучшего ответа
public static function setBest($post_id, $answer_id, $selected_best_answer)
{
if ($selected_best_answer) {
DB::run("UPDATE answers SET answer_lo = 0 WHERE answer_id = :id", ['id' => $selected_best_answer]);
}
self::setAnswerBest($answer_id);
self::answerPostBest($post_id, $answer_id);
}
// Let's write down the id of the participant who chose the best answer
// Запишем id участника выбравший лучший ответ
public static function setAnswerBest($answer_id)
{
$sql = "UPDATE answers SET answer_lo = :user_id WHERE answer_id = :answer_id";
return DB::run($sql, ['answer_id' => $answer_id, 'user_id' => UserData::getUserId()]);
}
// Rewriting the number of the selected best answer in the post
// Переписываем номер выбранного лучший ответ в посте
public static function answerPostBest($post_id, $answer_id)
{
$sql_two = "UPDATE posts SET post_lo = :answer_id WHERE post_id = :post_id";
return DB::run($sql_two, ['post_id' => $post_id, 'answer_id' => $answer_id]);
}
}

View File

@ -9,246 +9,309 @@ use DB;
class CommentModel extends \Hleb\Scheme\App\Models\MainModel
{
// Adding a comment
// Добавляем комментарий
public static function add($post_id, $answer_id, $comment_id, $content, $trigger)
public static $limit = 15;
// Add an comment
// Добавим ответ
public static function add($post_id, $comment_id, $content, $trigger)
{
$params = [
'comment_post_id' => $post_id,
'comment_answer_id' => $answer_id,
'comment_parent_id' => $comment_id,
'comment_content' => $content,
'comment_published' => ($trigger === false) ? 0 : 1,
'comment_ip' => Request::getRemoteAddress(),
'comment_user_id' => UserData::getUserId(),
'comment_post_id' => $post_id,
'comment_parent_id' => $comment_id,
'comment_content' => $content,
'comment_published' => ($trigger === false) ? 0 : 1,
'comment_ip' => Request::getRemoteAddress(),
'comment_user_id' => UserData::getUserId(),
];
$sql = "INSERT INTO comments(comment_post_id,
comment_answer_id,
comment_parent_id,
comment_content,
comment_published,
comment_ip,
comment_user_id)
VALUES(:comment_post_id,
:comment_answer_id,
:comment_parent_id,
:comment_content,
:comment_published,
:comment_ip,
:comment_user_id)";
comment_parent_id,
comment_content,
comment_published,
comment_ip,
comment_user_id)
VALUES(:comment_post_id,
:comment_parent_id,
:comment_content,
:comment_published,
:comment_ip,
:comment_user_id)";
DB::run($sql, $params);
$sql_last_id = DB::run("SELECT LAST_INSERT_ID() as last_id")->fetch();
$last_id = $sql_last_id['last_id'];
$sql_last_id = DB::run("SELECT LAST_INSERT_ID() as last_id")->fetch();
// Отмечаем комментарий, что за ним есть ответ
self::setThereComment($last_id, $params['comment_parent_id']);
$sql = "SELECT * FROM answers WHERE answer_id = :comment_answer_id";
$answer = DB::run($sql, ['comment_answer_id' => $params['comment_answer_id']])->fetch();
if ($answer['answer_after'] == 0) {
self::setThereAnswer($last_id, $params['comment_answer_id']);
}
// Add the number of comments for the post + 1
// Recalculating the number of responses for the post + 1
// Пересчитываем количество ответов для поста + 1
PostModel::updateCount($post_id, 'comments');
return $last_id;
return $sql_last_id['last_id'];
}
// Editing a comment
// Редактируем комментарий
// Editing the comment
// Редактируем ответ
public static function edit($params)
{
$sql = "UPDATE comments SET
comment_content = :comment_content,
comment_modified = :comment_modified
WHERE comment_id = :comment_id";
$sql_two = "UPDATE comments SET comment_content = :comment_content,
comment_modified = :comment_modified, comment_user_id = :comment_user_id
WHERE comment_id = :comment_id";
return DB::run($sql, $params);
return DB::run($sql_two, $params);
}
// Отметим комментарий, что за ним есть ответ
public static function setThereComment($last_id, $comment_id)
// All comments
// Все ответы
public static function getComments($page, $sheet)
{
$sql = "UPDATE comments SET comment_after = :last_id WHERE comment_id = :comment_id";
return DB::run($sql, ['last_id' => $last_id, 'comment_id' => $comment_id]);
}
// Отмечаем ответ, что за ним есть комментарии
public static function setThereAnswer($last_id, $answer_id)
{
$sql = "UPDATE answers SET answer_after = :last_id WHERE answer_id = :answer_id";
return DB::run($sql, ['last_id' => $last_id, 'answer_id' => $answer_id]);
}
// Все комментарии
public static function getComments($page, $limit, $sheet)
{
$hidden = UserData::checkAdmin() ? "" : "AND post_hidden = 0";
$user_id = UserData::getUserId();
$sort = self::sorts($sheet);
$start = ($page - 1) * $limit;
$sql = "SELECT
$start = ($page - 1) * self::$limit;
$sql = "SELECT
post_id,
post_title,
post_slug,
post_tl,
post_hidden,
post_feature,
post_user_id,
post_closed,
post_feature,
post_is_deleted,
comment_id,
comment_ip,
comment_date,
comment_content,
comment_post_id,
comment_date,
comment_user_id,
comment_parent_id,
comment_published,
comment_ip,
comment_post_id,
comment_votes,
comment_after,
comment_is_deleted,
comment_published,
votes_comment_item_id,
votes_comment_user_id,
id,
login,
avatar,
created_at
FROM comments
JOIN users ON id = comment_user_id
JOIN posts ON comment_post_id = post_id AND post_tl <= :tl
LEFT JOIN votes_comment ON votes_comment_item_id = comment_id
AND votes_comment_user_id = :uid
WHERE $sort $hidden
ORDER BY comment_id DESC LIMIT :start, :limit";
fav.tid,
fav.user_id,
fav.action_type,
u.id,
u.login,
u.avatar
FROM comments
INNER JOIN users u ON u.id = comment_user_id
INNER JOIN posts ON comment_post_id = post_id
LEFT JOIN votes_comment ON votes_comment_item_id = comment_id
AND votes_comment_user_id = $user_id
LEFT JOIN favorites fav ON fav.tid = comment_id
AND fav.user_id = $user_id
AND fav.action_type = 'comment'
$sort
ORDER BY comment_id DESC LIMIT :start, :limit ";
return DB::run($sql, ['uid' => UserData::getUserId(), 'start' => $start, 'limit' => $limit, 'tl' => UserData::getUserTl()])->fetchAll();
return DB::run($sql, ['start' => $start, 'limit' => self::$limit])->fetchAll();
}
// Количество комментариев
public static function getCommentsCount($sheet)
{
$sort = self::sorts($sheet);
$sql = "SELECT
comment_id,
comment_is_deleted
FROM comments
JOIN posts ON comment_post_id = post_id AND post_tl <= :tl
WHERE $sort";
$sql = "SELECT comment_id FROM comments INNER JOIN posts ON comment_post_id = post_id $sort";
return DB::run($sql, ['tl' => UserData::getUserTl()])->rowCount();
return DB::run($sql)->rowCount();
}
public static function sorts($sheet)
{
return $sheet == 'all' ? "comment_is_deleted = 0" : "comment_is_deleted = 1";
$hidden = UserData::checkAdmin() ? "" : "AND post_hidden = 0";
switch ($sheet) {
case 'all':
$sort = "WHERE comment_is_deleted = 0 AND post_tl = 0 AND post_is_deleted = 0 $hidden";
break;
case 'deleted':
$sort = "WHERE comment_is_deleted = 1";
break;
}
return $sort;
}
// Получаем комментарии к ответу
public static function getCommentsAnswer($answer_id)
// Number of replies per post
// Количество ответов на пост
public static function getNumberComment($post_id)
{
$sql = "SELECT comment_id FROM comments WHERE comment_post_id = :id AND comment_is_deleted = 0";
return DB::run($sql, ['id' => $post_id])->rowCount();
}
// Add the comment to the end of the post
// Добавим ответ в конец поста
public static function mergePost($post_id, $content)
{
$sql = "UPDATE posts SET post_content = CONCAT(post_content, :content) WHERE post_id = :post_id";
$content = "\n\n `+` " . $content;
return DB::run($sql, ['post_id' => $post_id, 'content' => $content]);
}
// Getting comments in a post
// Получаем ответы в посте
public static function getCommentsPost($post_id, $type, $sorting = 'new')
{
$user_id = UserData::getUserId();
if ($type == 1) {
$sorting = 'top';
}
switch ($sorting) {
case 'top':
$sort = 'ORDER BY comment_lo DESC, comment_votes DESC';
break;
case 'old':
$sort = 'ORDER BY comment_id DESC';
break;
// new
default:
$sort = '';
break;
}
$sql = "SELECT
comment_id,
comment_user_id,
comment_answer_id,
comment_parent_id,
comment_content,
comment_user_id,
comment_post_id,
comment_parent_id,
comment_date,
comment_votes,
comment_content,
comment_modified,
comment_published,
comment_ip,
comment_after,
comment_votes,
comment_lo,
comment_is_deleted,
votes_comment_item_id,
votes_comment_user_id,
id,
login,
avatar,
created_at
FROM comments
LEFT JOIN users ON id = comment_user_id
LEFT JOIN votes_comment ON votes_comment_item_id = comment_id
AND votes_comment_user_id = :user_id
WHERE comment_answer_id = :answer_id";
fav.tid,
fav.user_id,
fav.action_type,
u.id,
u.login,
u.avatar,
u.created_at
FROM comments
LEFT JOIN users u ON u.id = comment_user_id
LEFT JOIN votes_comment ON votes_comment_item_id = comment_id
AND votes_comment_user_id = $user_id
LEFT JOIN favorites fav ON fav.tid = comment_id
AND fav.user_id = $user_id
AND fav.action_type = 'comment'
WHERE comment_post_id = $post_id $sort";
return DB::run($sql, ['user_id' => UserData::getUserId(), 'answer_id' => $answer_id])->fetchAll();
return DB::run($sql)->fetchAll();
}
// Страница комментариев участника
public static function userComments($page, $limit, $user_id, $id)
// User responses
// Ответы участника
public static function userComments($page, $user_id, $uid_vote)
{
$start = ($page - 1) * $limit;
$start = ($page - 1) * self::$limit;
$sql = "SELECT
comment_id,
comment_user_id,
comment_answer_id,
comment_parent_id,
comment_content,
comment_user_id,
comment_post_id,
comment_date,
comment_content,
comment_modified,
comment_published,
comment_votes,
comment_ip,
comment_after,
comment_votes,
comment_is_deleted,
votes_comment_item_id,
votes_comment_user_id,
post_id,
post_slug,
post_id,
post_title,
post_slug,
post_user_id,
post_closed,
post_is_deleted,
id,
login,
avatar
FROM comments
LEFT JOIN users ON id = comment_user_id
LEFT JOIN posts ON comment_post_id = post_id
LEFT JOIN votes_comment ON votes_comment_item_id = comment_id
AND votes_comment_user_id = :id
WHERE comment_user_id = :user_id AND comment_is_deleted = 0
AND post_is_deleted = 0 AND post_tl = 0 AND post_hidden = 0
ORDER BY comment_id DESC LIMIT :start, :limit";
FROM comments
LEFT JOIN users ON id = comment_user_id
LEFT JOIN posts ON comment_post_id = post_id
LEFT JOIN votes_comment ON votes_comment_item_id = comment_id
AND votes_comment_user_id = :uid_vote
WHERE comment_user_id = :user_id AND post_hidden = 0
AND comment_is_deleted = 0 AND post_is_deleted = 0 AND post_tl = 0 AND post_tl = 0
ORDER BY comment_id DESC LIMIT :start, :limit ";
return DB::run($sql, ['user_id' => $user_id, 'id' => $id, 'start' => $start, 'limit' => $limit])->fetchAll();
return DB::run($sql, ['user_id' => $user_id, 'uid_vote' => $uid_vote, 'start' => $start, 'limit' => self::$limit])->fetchAll();
}
// Количество комментариев участника
public static function userCommentsCount($user_id)
{
$sql = "SELECT
comment_id
FROM comments
LEFT JOIN posts ON comment_post_id = post_id
FROM comments
LEFT JOIN posts ON comment_post_id = post_id
WHERE comment_user_id = :user_id AND comment_is_deleted = 0
AND post_is_deleted = 0 AND post_tl = 0";
AND post_is_deleted = 0 AND post_tl = 0 AND post_tl = 0";
return DB::run($sql, ['user_id' => $user_id])->rowCount();
}
// Получаем комментарий по id комментария
public static function getCommentsId($comment_id)
// Information on the id of the comment
// Информацию по id ответа
public static function getCommentId($comment_id)
{
$sql = "SELECT
comment_id,
comment_content,
comment_post_id,
comment_user_id,
comment_date,
comment_post_id,
comment_modified,
comment_published,
comment_ip,
comment_votes,
comment_content,
comment_lo,
comment_is_deleted
FROM comments WHERE comment_id = :comment_id";
FROM comments
WHERE comment_id = :comment_id";
return DB::run($sql, ['comment_id' => $comment_id])->fetch();
return DB::run($sql, ['comment_id' => $comment_id])->fetch();
}
/*
* Best comment
*/
// Choice of the best comment
// Выбор лучшего ответа
public static function setBest($post_id, $comment_id, $selected_best_comment)
{
if ($selected_best_comment) {
DB::run("UPDATE comments SET comment_lo = 0 WHERE comment_id = :id", ['id' => $selected_best_comment]);
}
self::setCommentBest($comment_id);
self::commentPostBest($post_id, $comment_id);
}
// Let's write down the id of the participant who chose the best comment
// Запишем id участника выбравший лучший ответ
public static function setCommentBest($comment_id)
{
$sql = "UPDATE comments SET comment_lo = :user_id WHERE comment_id = :comment_id";
return DB::run($sql, ['comment_id' => $comment_id, 'user_id' => UserData::getUserId()]);
}
// Rewriting the number of the selected best comment in the post
// Переписываем номер выбранного лучший ответ в посте
public static function commentPostBest($post_id, $comment_id)
{
$sql_two = "UPDATE posts SET post_lo = :comment_id WHERE post_id = :post_id";
return DB::run($sql_two, ['post_id' => $post_id, 'comment_id' => $comment_id]);
}
}

View File

@ -19,7 +19,7 @@ class FeedModel extends \Hleb\Scheme\App\Models\MainModel
// Sorting posts by conditions
// Сортировка постов по условиям
$sort = "ORDER BY post_answers_count DESC";
$sort = "ORDER BY post_comments_count DESC";
if (in_array($sheet, ['facet.feed', 'web.feed', 'questions', 'posts'])) {
$sort = "ORDER BY post_top DESC, post_date DESC";
} elseif (in_array($sheet, ['admin.posts.all', 'admin.posts.ban', 'profile.posts'])) {
@ -41,7 +41,6 @@ class FeedModel extends \Hleb\Scheme\App\Models\MainModel
post_user_id,
post_votes,
post_hits_count,
post_answers_count,
post_comments_count,
post_content,
post_content_img,

View File

@ -59,7 +59,6 @@ class HomeModel extends \Hleb\Scheme\App\Models\MainModel
post_user_id,
post_votes,
post_hits_count,
post_answers_count,
post_comments_count,
post_content,
post_content_img,
@ -172,33 +171,33 @@ class HomeModel extends \Hleb\Scheme\App\Models\MainModel
// The last 5 responses on the main page
// Последние 5 ответа на главной
public static function latestAnswers()
public static function latestComments()
{
$trust_level = UserData::getUserTl();
$user_answer = "AND post_tl = 0";
$user_comment = "AND post_tl = 0";
if ($user_id = UserData::getUserId()) {
$user_answer = "AND answer_user_id != $user_id AND post_tl <= $trust_level";
$user_comment = "AND comment_user_id != $user_id AND post_tl <= $trust_level";
}
$hidden = UserData::checkAdmin() ? "" : "AND post_hidden = 0";
$sql = "SELECT
answer_id,
answer_post_id,
answer_content,
answer_date,
comment_id,
comment_post_id,
comment_content,
comment_date,
post_id,
post_slug,
post_hidden,
login,
avatar
FROM answers
LEFT JOIN users ON id = answer_user_id
RIGHT JOIN posts ON post_id = answer_post_id
WHERE answer_is_deleted = 0 AND post_is_deleted = 0 $hidden
$user_answer AND post_type = 'post'
ORDER BY answer_id DESC LIMIT 5";
FROM comments
LEFT JOIN users ON id = comment_user_id
RIGHT JOIN posts ON post_id = comment_post_id
WHERE comment_is_deleted = 0 AND post_is_deleted = 0 $hidden
$user_comment AND post_type = 'post'
ORDER BY comment_id DESC LIMIT 5";
return DB::run($sql)->fetchAll();
}

View File

@ -94,7 +94,6 @@ class PostModel extends \Hleb\Scheme\App\Models\MainModel
post_user_id,
post_ip,
post_votes,
post_answers_count,
post_comments_count,
post_content,
post_content_img,
@ -147,7 +146,7 @@ class PostModel extends \Hleb\Scheme\App\Models\MainModel
post_title,
post_slug,
post_feature,
post_answers_count,
post_comments_count,
post_type
FROM posts
LEFT JOIN facets_posts_relation on post_id = relation_post_id
@ -163,7 +162,7 @@ class PostModel extends \Hleb\Scheme\App\Models\MainModel
return DB::run($sql, ['post_id' => $post_id, 'user_id' => UserData::getUserId(), 'tl' => $tl, 'limit' => $limit, 'facet_id' => $facet_id])->fetchAll();
}
// $type (comments / answers / hits)
// $type (comments / hits)
public static function updateCount($post_id, $type)
{
$sql = "UPDATE posts SET post_" . $type . "_count = (post_" . $type . "_count + 1) WHERE post_id = :post_id";
@ -397,7 +396,6 @@ class PostModel extends \Hleb\Scheme\App\Models\MainModel
post_user_id,
post_votes,
post_hits_count,
post_answers_count,
post_comments_count,
post_content,
post_content_img,

View File

@ -41,7 +41,6 @@ class RssModel extends \Hleb\Scheme\App\Models\MainModel
post_published,
post_user_id,
post_votes,
post_answers_count,
post_comments_count,
post_content,
post_content_img,

View File

@ -14,8 +14,8 @@ class SearchModel extends \Hleb\Scheme\App\Models\MainModel
return self::getWebsite($page, $limit, $query);
}
if ($type == 'answer') {
return self::getAnswers($page, $limit, $query);
if ($type == 'comment') {
return self::getComments($page, $limit, $query);
}
return self::getPosts($page, $limit, $query);
@ -52,14 +52,14 @@ class SearchModel extends \Hleb\Scheme\App\Models\MainModel
return DB::run($sql, ['qa' => $query, 'start' => $start, 'limit' => $limit])->fetchAll();
}
public static function getAnswers($page, $limit, $query)
public static function getComments($page, $limit, $query)
{
$start = ($page - 1) * $limit;
$sql = "SELECT answer_id, answer_content, post_id, post_slug, post_title as title
FROM answers
LEFT JOIN posts ON answer_post_id = post_id
$sql = "SELECT comment_id, comment_content, post_id, post_slug, post_title as title
FROM comments
LEFT JOIN posts ON comment_post_id = post_id
WHERE post_is_deleted = 0
AND answer_content LIKE :qa LIMIT :start, :limit";
AND comment_content LIKE :qa LIMIT :start, :limit";
return DB::run($sql, ['qa' => "%" . $query . "%", 'start' => $start, 'limit' => $limit])->fetchAll();
}
@ -94,8 +94,8 @@ class SearchModel extends \Hleb\Scheme\App\Models\MainModel
public static function getSearchCount($query, $type)
{
if ($type == 'answer') {
$sql = "SELECT answer_id FROM answers LEFT JOIN posts ON answer_post_id = post_id WHERE post_is_deleted = 0 AND answer_content LIKE :qa";
if ($type == 'comment') {
$sql = "SELECT comment_id FROM comments LEFT JOIN posts ON comment_post_id = post_id WHERE post_is_deleted = 0 AND comment_content LIKE :qa";
return DB::run($sql, ['qa' => "%" . $query . "%"])->rowCount();
}

View File

@ -89,8 +89,7 @@ class SettingModel extends \Hleb\Scheme\App\Models\MainModel
setting_email_pm = :setting_email_pm,
setting_email_appealed = :setting_email_appealed,
setting_email_post = :setting_email_post,
setting_email_answer = :setting_email_answer,
setting_email_comment = :setting_email_comment
setting_email_answer = :setting_email_answer
WHERE setting_user_id = :setting_user_id";
if (!self::countNotifications($params['setting_user_id'])) {
@ -99,14 +98,12 @@ class SettingModel extends \Hleb\Scheme\App\Models\MainModel
setting_email_pm,
setting_email_appealed,
setting_email_post,
setting_email_answer,
setting_email_comment)
setting_email_answer)
VALUES(:setting_user_id,
:setting_email_pm,
:setting_email_appealed,
:setting_email_post,
:setting_email_answer,
:setting_email_comment)";
:setting_email_answer)";
}
return DB::run($sql, $params);

View File

@ -145,9 +145,9 @@ class UserModel extends \Hleb\Scheme\App\Models\MainModel
post_id,
post_title,
post_slug,
answer_id,
answer_post_id,
answer_content,
comment_id,
comment_post_id,
comment_content,
item_id,
item_title,
item_url,
@ -156,7 +156,7 @@ class UserModel extends \Hleb\Scheme\App\Models\MainModel
item_domain
FROM favorites fav
LEFT JOIN posts ON post_id = fav.tid AND fav.action_type = 'post'
LEFT JOIN answers ON answer_id = fav.tid AND fav.action_type = 'answer'
LEFT JOIN comments ON comment_id = fav.tid AND fav.action_type = 'comment'
LEFT JOIN items ON item_id = fav.tid AND fav.action_type = 'website'
LEFT JOIN folders_relation fr ON fr.tid = fav.tid
LEFT JOIN folders fol ON folder_id = fol.id AND fol.user_id = :uid2
@ -219,8 +219,6 @@ class UserModel extends \Hleb\Scheme\App\Models\MainModel
$sql = "SELECT
(SELECT COUNT(post_id) FROM posts WHERE post_user_id = $user_id and post_draft = 0 and post_is_deleted = $condition) AS count_posts,
(SELECT COUNT(answer_id) FROM answers WHERE answer_user_id = $user_id and answer_is_deleted = $condition) AS count_answers,
(SELECT COUNT(comment_id) FROM comments WHERE comment_user_id = $user_id and comment_is_deleted = $condition) AS count_comments,
(SELECT COUNT(item_id) FROM items WHERE item_user_id = $user_id and item_is_deleted = $condition) AS count_items";

View File

@ -23,20 +23,17 @@ class Audit extends Base
$content_type = Request::getPost('type');
$post_id = Request::getPostInt('post_id');
$content_id = Request::getPostInt('content_id');
// Limit the flags
if ($this->user['trust_level'] < config('trust-levels.tl_add_report')) return 1;
if (AuditModel::getSpeedReport($this->user['id']) > config('trust-levels.perDay_report')) return 1;
$post = PostPresence::index($post_id, 'id');
if (!in_array($content_type, ['post', 'comment'])) return false;
if (!in_array($content_type, ['post', 'answer', 'comment'])) return false;
$type_id = $content_type == 'answer' ? 'answer_' . $content_id : 'comment_' . $content_id;
$url = post_slug($post['post_id'], $post['post_slug']) . '#' . $type_id;
$this->create($content_type, $content_id, $url, 'report');
$this->create($content_type, $content_id, $post, 'report');
return true;
}
@ -127,7 +124,7 @@ class Audit extends Base
return false;
}
public function create(string $type, int $last_content_id, string $url, string $type_notification = 'audit')
public function create(string $type, int $last_content_id, array $post, string $type_notification = 'audit')
{
$action_type = ($type_notification == 'audit') ? NotificationModel::TYPE_AUDIT : NotificationModel::TYPE_REPORT;
@ -140,6 +137,8 @@ class Audit extends Base
]
);
$url = '/post/' . $post['post_id'] . '/' . $post['post_slug'] . '#' . 'comment_' . $last_content_id;
// Send notification type 21 (audit) to administrator (id 1)
// Отправим тип уведомления 21 (аудит) администратору (id 1)
NotificationModel::send(UserData::REGISTERED_ADMIN_ID, $action_type, $url);

View File

@ -6,42 +6,42 @@ namespace App\Services;
use Hleb\Constructor\Handlers\Request;
use App\Services\Сheck\PostPresence;
use App\Services\Сheck\AnswerPresence;
use App\Models\AnswerModel;
use App\Services\Сheck\CommentPresence;
use App\Models\CommentModel;
use UserData, Access;
class AnswerBest extends Base
class CommentBest extends Base
{
public function index()
{
// Get the answer data (for which the "best answer" is selected)
// Получим данные ответа (на который выбирается "лучший ответ")
$answer = AnswerPresence::index(Request::getPostInt('answer_id'));
// Get the comment data (for which the "best comment" is selected)
// Получим данные комментария (на который выбирается "лучший ответ")
$comment = CommentPresence::index(Request::getPostInt('comment_id'));
// Get the data of the post that has this answer
// Get the data of the post that has this comment
// Получим данные поста в котором есть этот ответ
$post = PostPresence::index($answer['answer_post_id'], 'id');
$post = PostPresence::index($comment['comment_post_id'], 'id');
// Let's check the access. Only the staff and the author of the post can choose the best answer (without regard to time)
// Let's check the access. Only the staff and the author of the post can choose the best comment (without regard to time)
// Проверим доступ. Только персонал и автор поста может выбирать лучший ответ (без учета времени)
if ($post['post_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) {
return false;
}
// If the number of answers is less than 2, then we will not let you choose the best answer
// If the number of answers is less than 2, then we will not let you choose the best comment
// Если количество ответов меньше 2, то не дадим выбирать лучший ответ
if ($post['post_answers_count'] < 2) {
if ($post['post_comments_count'] < 2) {
return false;
}
// Если Лучший Ответ уже выбран, то переписываем...
if ($post['post_lo']) {
AnswerModel::setBest($post['post_id'], $answer['answer_id'], $post['post_lo']);
CommentModel::setBest($post['post_id'], $comment['comment_id'], $post['post_lo']);
return true;
}
// Если Лучшего ответа нет, то первичная запись
AnswerModel::setBest($post['post_id'], $answer['answer_id'], false);
CommentModel::setBest($post['post_id'], $comment['comment_id'], false);
return true;
}
}

View File

@ -6,7 +6,7 @@ namespace App\Services;
use Hleb\Constructor\Handlers\Request;
use App\Models\Item\WebModel;
use App\Models\{FavoriteModel, PostModel, AnswerModel};
use App\Models\{FavoriteModel, PostModel, CommentModel};
class Favorite extends Base
{
@ -15,7 +15,7 @@ class Favorite extends Base
$content_id = Request::getPostInt('content_id');
$type = Request::getPost('type');
$allowed = ['post', 'website', 'answer'];
$allowed = ['post', 'website', 'comment'];
if (!in_array($type, $allowed)) {
return false;
}
@ -36,8 +36,8 @@ class Favorite extends Base
case 'website':
$content = WebModel::getItemId($content_id);
break;
case 'answer':
$content = AnswerModel::getAnswerId($content_id);
case 'comment':
$content = CommentModel::getCommentId($content_id);
break;
}

View File

@ -27,10 +27,9 @@ class BuildTree
return $siblings;
};
$tree = [];
if (isset($grouped[$group])) {
$tree = $fnBuilder($grouped[$group]);
} else {
$tree = [];
}
return $tree;

View File

@ -1,19 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Services\Сheck;
use App\Models\AnswerModel;
class AnswerPresence
{
public static function index(int $answer_id): array
{
$answer = AnswerModel::getAnswerId($answer_id);
notEmptyOrView404($answer);
return $answer;
}
}

View File

@ -10,7 +10,7 @@ class CommentPresence
{
public static function index(int $comment_id): array
{
$comment = CommentModel::getCommentsId($comment_id);;
$comment = CommentModel::getCommentId($comment_id);
notEmptyOrView404($comment);

52
dev.sql
View File

@ -1579,10 +1579,56 @@ CREATE TABLE `items_status` (
KEY `status_item_id` (`status_item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
ALTER TABLE `posts` ADD `post_nsfw` TINYINT(1) NOT NULL DEFAULT '0' AFTER `post_published`;
ALTER TABLE `users` ADD `nsfw` TINYINT(1) NOT NULL DEFAULT '0' AFTER `my_post`;
ALTER TABLE `posts` ADD `post_hidden` TINYINT(1) NOT NULL DEFAULT '0' COMMENT 'Скрытый пост' AFTER `post_top`;
ALTER TABLE `facets` ADD `facet_is_comments` TINYINT(1) NOT NULL DEFAULT '0' COMMENT 'Are comments closed (posts, websites...)?' AFTER `facet_type`;
ALTER TABLE `facets` ADD `facet_is_comments` TINYINT(1) NOT NULL DEFAULT '0' COMMENT 'Are comments closed (posts, websites...)?' AFTER `facet_type`;
ALTER TABLE `answers` ADD `answer_parent_id` INT(11) NOT NULL DEFAULT '0' AFTER `answer_post_id`;
INSERT INTO answers (answer_post_id,
answer_user_id,
answer_parent_id,
answer_date,
answer_modified,
answer_ip,
answer_content,
answer_published,
answer_is_deleted)
SELECT comment_post_id,
comment_user_id,
comment_answer_id,
comment_date,
comment_modified,
comment_ip,
comment_content,
comment_published,
comment_is_deleted
FROM comments WHERE comment_parent_id = 0;
ALTER TABLE `posts` DROP `post_comments_count`;
ALTER TABLE `answers` DROP `answer_order`;
ALTER TABLE `answers` DROP `answer_after`;
ALTER TABLE `users_setting` DROP `setting_email_comment`;
UPDATE files SET file_type = 'comment' WHERE file_type = 'answer';
DROP TABLE `votes_comment`;
ALTER TABLE `votes_answer` RENAME TO `votes_comment`;
ALTER TABLE `votes_comment` CHANGE `votes_answer_id` `votes_comment_id` INT(11) NOT NULL AUTO_INCREMENT, CHANGE `votes_answer_item_id` `votes_comment_item_id` INT(11) NOT NULL, CHANGE `votes_answer_points` `votes_comment_points` INT(11) NOT NULL, CHANGE `votes_answer_ip` `votes_comment_ip` VARCHAR(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, CHANGE `votes_answer_user_id` `votes_comment_user_id` INT(11) NOT NULL DEFAULT '1', CHANGE `votes_answer_date` `votes_comment_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
DROP TABLE `comments`;
ALTER TABLE `answers` RENAME TO `comments`;
ALTER TABLE `comments` CHANGE `answer_id` `comment_id` INT(11) NOT NULL AUTO_INCREMENT, CHANGE `answer_post_id` `comment_post_id` INT(11) NOT NULL DEFAULT '0', CHANGE `answer_parent_id` `comment_parent_id` INT(11) NOT NULL DEFAULT '0', CHANGE `answer_user_id` `comment_user_id` INT(11) NOT NULL DEFAULT '0', CHANGE `answer_date` `comment_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, CHANGE `answer_modified` `comment_modified` TIMESTAMP NOT NULL DEFAULT '2020-12-31 03:00:00', CHANGE `answer_published` `comment_published` TINYINT(1) NOT NULL DEFAULT '1', CHANGE `answer_ip` `comment_ip` VARBINARY(16) NULL DEFAULT NULL, CHANGE `answer_votes` `comment_votes` SMALLINT(6) NOT NULL DEFAULT '0', CHANGE `answer_content` `comment_content` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, CHANGE `answer_lo` `comment_lo` INT(11) NOT NULL DEFAULT '0', CHANGE `answer_is_deleted` `comment_is_deleted` TINYINT(1) NOT NULL DEFAULT '0';
ALTER TABLE `posts` CHANGE `post_answers_count` `post_comments_count` INT(11) NULL DEFAULT '0';
UPDATE `audits` SET `action_type` = 'comment' WHERE `action_type` = 'answer';
UPDATE `favorites` SET `action_type` = 'comment' WHERE `action_type` = 'answer';

View File

@ -4,7 +4,7 @@ namespace Modules\Admin\App;
use Hleb\Constructor\Handlers\Request;
use App\Controllers\Controller;
use App\Models\{PostModel, AnswerModel, CommentModel};
use App\Models\{PostModel, CommentModel};
use Modules\Admin\App\Models\LogModel;
use Meta;
@ -22,13 +22,11 @@ class Audits extends Controller
if ($row['action_type'] == 'post') {
$row['content'] = PostModel::getPost($row['content_id'], 'id', $this->user);
} elseif ($row['action_type'] == 'answer') {
$row['content'] = AnswerModel::getAnswerId($row['content_id']);
$row['post'] = PostModel::getPost($row['content']['answer_post_id'], 'id', $this->user);
} elseif ($row['action_type'] == 'comment') {
$row['content'] = CommentModel::getCommentsId($row['content_id']);
}
$row['content'] = CommentModel::getCommentId($row['content_id']);
$row['post'] = PostModel::getPost($row['content']['comment_post_id'], 'id', $this->user);
}
$result[$ind] = $row;
}

View File

@ -11,7 +11,7 @@ class Console
public static function index()
{
$choice = Request::getPost('type');
$allowed = ['css', 'topic', 'up', 'tl', 'indexer'];
$allowed = ['css', 'topic', 'post', 'up', 'tl'];
if (!in_array($choice, $allowed)) {
redirect(url('admin.tools'));
}
@ -25,6 +25,13 @@ class Console
self::consoleRedirect();
}
public static function post()
{
ConsoleModel::recalculateCountCommentPost();
self::consoleRedirect();
}
public static function up()
{
$users = ConsoleModel::allUsers();

View File

@ -6,28 +6,36 @@ use DB;
class ConsoleModel extends \Hleb\Scheme\App\Models\MainModel
{
// Let's recalculate the number of posts in the Topics
// Пересчитаем количество постов в Темах
public static function recalculateTopic()
{
$sql = "UPDATE facets SET facet_count = (SELECT count(relation_post_id) FROM facets_posts_relation
LEFT JOIN posts ON relation_post_id = post_id WHERE relation_facet_id = facet_id AND post_is_deleted = 0)";
return DB::run($sql);
}
// Let's recalculate the number of сщььутеы in the Posts
// Пересчитаем количество комментариев в Постах
public static function recalculateCountCommentPost()
{
$sql = "UPDATE posts SET post_comments_count = (SELECT count(comment_post_id) FROM comments WHERE comment_post_id = post_id AND comment_is_deleted = 0)";
return DB::run($sql);
}
public static function allUp($uid)
{
$sql = "SELECT
(SELECT SUM(post_votes) FROM posts WHERE post_user_id = $uid)
AS count_posts,
(SELECT SUM(answer_votes) FROM answers WHERE answer_user_id = $uid)
AS count_answers,
(SELECT SUM(comment_votes) FROM comments WHERE comment_user_id = $uid)
AS count_comments";
$user = DB::run($sql)->fetch();
// Вернем сумму, но этот запрос необходим будет далее именно по отдельным типам
return $user['count_posts'] + $user['count_answers'] + $user['count_comments'];
return $user['count_posts'] + $user['count_comments'];
}
public static function allUsers()

View File

@ -38,7 +38,7 @@
<td class="text-sm">
<div class="content-telo">
<?php $content = $audit['content'][$audit['action_type'] . '_content']; ?>
<?= fragment($content, 200); ?>
<?= fragment($content ?? 'no', 200); ?>
</div>
(id:<?= $audit['id']; ?>)

View File

@ -21,6 +21,10 @@
<label><?= __('admin.trust_level'); ?></label>
<div class="update btn btn-primary" data-type="tl"><?= __('admin.update'); ?></div>
</fieldset>
<fieldset>
<label><?= __('admin.number_comments'); ?></label>
<div class="update btn btn-primary" data-type="post"><?= __('admin.update'); ?></div>
</fieldset>
<fieldset class="max-w300">
<label for="mail"><?= __('admin.email'); ?></label>
<form action="<?= url('admin.test.mail'); ?>" method="post">

View File

@ -1 +1 @@
.dropdown,.delet-count{right:unset;left:0}.mr5{margin-right:0;margin-left:5px}.mr10{margin-right:0;margin-left:10px}.ml5{margin-left:0;margin-right:5px}.right-close{padding:5px;float:left}.showPassword{left:5px;right:auto}.dropdown.user{padding:1rem .7rem .7rem 0}.d-header_contents .btn-outline-primary{width:120px}.box-search{margin:10px 0 10px 45px}.block-answer .right{float:left}
.dropdown,.delet-count{right:unset;left:0}.mr5{margin-right:0;margin-left:5px}.mr10{margin-right:0;margin-left:10px}.ml5{margin-left:0;margin-right:5px}.right-close{padding:5px;float:left}.showPassword{left:5px;right:auto}.dropdown.user{padding:1rem .7rem .7rem 0}.d-header_contents .btn-outline-primary{width:120px}.box-search{margin:10px 0 10px 45px}.block-comment .right{float:left}

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
const focusId=queryAll(".focus-id"),saveFolder=queryAll(".save-folder"),delFolderContent=queryAll(".del-folder-content"),delFolder=queryAll(".del-folder"),delVotingOption=queryAll(".del-voting-option"),addProfile=queryAll(".add-profile"),postRecommend=queryAll(".post-recommend"),typeAction=queryAll(".type-action"),reply=queryAll(".actreply");focusId.forEach(el=>el.addEventListener("click",function(e){makeRequest("/focus",options={body:"content_id="+el.dataset.id+"&type="+el.dataset.type+"&_token="+token})}));saveFolder.forEach(el=>el.addEventListener("click",function(e){makeRequest("/folder/content/save",options={body:"id="+el.dataset.id+"&type="+el.dataset.type+"&tid="+el.dataset.tid})}));addProfile.forEach(el=>el.addEventListener("click",function(e){makeRequest("/post/profile",options={body:"post_id="+el.dataset.post+"&_token="+token})}));delFolderContent.forEach(el=>el.addEventListener("click",function(e){makeRequest("/folder/content/del",options={body:"id="+el.dataset.id+"&type="+el.dataset.type+"&tid="+el.dataset.tid+"&_token="+token})}));delFolder.forEach(el=>el.addEventListener("click",function(e){makeRequest("/folder/del",options={body:"id="+el.dataset.id+"&type="+el.dataset.type+"&_token="+token})}));postRecommend.forEach(el=>el.addEventListener("click",function(e){makeRequest("/post/recommend",options={body:"post_id="+el.dataset.id+"&_token="+token})}));typeAction.forEach(el=>el.addEventListener("click",function(e){makeRequest("/status/action",options={body:"content_id="+el.dataset.id+"&type="+el.dataset.type+"&_token="+token})}));isIdEmpty('colorPicker').onclick=function(){let box=getById("box");let color=getById("color");box.style.borderColor=colorPicker.value;colorPicker.addEventListener("input",function(event){box.style.borderColor=event.target.value},!1);colorPicker.addEventListener("change",function(event){color.value=colorPicker.value},!1)}
reply.forEach(el=>el.addEventListener("click",function(e){let reply=document.querySelector('#reply_addentry'+el.dataset.id);fetch("/reply/"+el.dataset.type,{method:"POST",body:"id="+el.dataset.id+"&item_id="+el.dataset.item_id+"&_token="+token,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(response=>response.text()).then(text=>{reply.classList.add("block");reply.innerHTML=text;queryAll("#cancel_comment").forEach(el=>el.addEventListener("click",function(e){reply.classList.remove("block")}))})}));queryAll(".up-id").forEach(el=>el.addEventListener("click",function(e){fetch("/votes",{method:"POST",body:"content_id="+el.dataset.id+"&type="+el.dataset.type+"&_token="+token,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then((response)=>{return}).then((text)=>{let upVot=document.querySelector('#up'+el.dataset.id);let act=upVot.classList.contains('active');let upScr=upVot.querySelector('.score');let number=parseInt(upScr.innerText);if(!number){number=0}
queryAll(".up-id").forEach(el=>el.addEventListener("click",function(e){fetch("/votes",{method:"POST",body:"content_id="+el.dataset.id+"&type="+el.dataset.type+"&_token="+token,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then((response)=>{return}).then((text)=>{let upVot=document.querySelector('#up'+el.dataset.id);let act=upVot.classList.contains('active');let upScr=upVot.querySelector('.score');let number=parseInt(upScr.innerText);if(!number){number=0}
if(act==!0){new_cont=(number-parseInt(1))}else{new_cont=(number+parseInt(1))}
upVot.classList.toggle('active');upScr.innerHTML=new_cont})}));queryAll(".add-favorite").forEach(el=>el.addEventListener("click",function(e){fetch("/favorite",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"content_id="+el.dataset.id+"&type="+el.dataset.type+"&_token="+token,}).then(response=>response.text()).then(text=>{if(el.dataset.front=='personal'){location.reload()}else{let dom=document.querySelector("#favorite_"+el.dataset.id);dom.classList.toggle("active")}})}));queryAll(".add-poll").forEach(el=>el.addEventListener("click",function(e){fetch("/poll",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"question_id="+el.dataset.id+"&answer_id="+el.dataset.answer+"&_token="+token,}).then(response=>response.text()).then(text=>{location.reload()})}));delVotingOption.forEach(el=>el.addEventListener("click",function(e){makeRequest("/poll/option/del",options={body:"id="+el.dataset.id+"&_token="+token})}));queryAll(".add-ignore").forEach(el=>el.addEventListener("click",function(e){fetch("/ignored",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"user_id="+el.dataset.id+"&_token="+token,}).then(response=>response.text()).then(text=>{location.reload()})}));queryAll(".answer-best").forEach(el=>el.addEventListener("click",function(e){fetch("/best",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"answer_id="+el.dataset.id+"&_token="+token,}).then(response=>response.text()).then(text=>{let dom=document.querySelector("#best_"+el.dataset.id);dom.classList.toggle("active");location.reload()})}));queryAll("#graburl").forEach(el=>el.addEventListener("click",function(e){let uri=getById('link').value;if(uri===''){return}
upVot.classList.toggle('active');upScr.innerHTML=new_cont})}));queryAll(".add-favorite").forEach(el=>el.addEventListener("click",function(e){fetch("/favorite",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"content_id="+el.dataset.id+"&type="+el.dataset.type+"&_token="+token,}).then(response=>response.text()).then(text=>{if(el.dataset.front=='personal'){location.reload()}else{let dom=document.querySelector("#favorite_"+el.dataset.id);dom.classList.toggle("active")}})}));queryAll(".add-poll").forEach(el=>el.addEventListener("click",function(e){fetch("/poll",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"question_id="+el.dataset.id+"&answer_id="+el.dataset.answer+"&_token="+token,}).then(response=>response.text()).then(text=>{location.reload()})}));delVotingOption.forEach(el=>el.addEventListener("click",function(e){makeRequest("/poll/option/del",options={body:"id="+el.dataset.id+"&_token="+token})}));queryAll(".add-ignore").forEach(el=>el.addEventListener("click",function(e){fetch("/ignored",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"user_id="+el.dataset.id+"&_token="+token,}).then(response=>response.text()).then(text=>{location.reload()})}));queryAll(".comment-best").forEach(el=>el.addEventListener("click",function(e){fetch("/best",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"comment_id="+el.dataset.id+"&_token="+token,}).then(response=>response.text()).then(text=>{let dom=document.querySelector("#best_"+el.dataset.id);dom.classList.toggle("active");location.reload()})}));queryAll("#graburl").forEach(el=>el.addEventListener("click",function(e){let uri=getById('link').value;if(uri===''){return}
fetch("/post/grabtitle",{method:"POST",body:"uri="+uri,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(function(response){if(!response.ok){return Promise.reject(new Error('Response failed: '+response.status+' ('+response.statusText+')'))}
return response.json()}).then(function(data){document.querySelector('input[name=post_title]').value=data.title;document.querySelector('textarea.url').insertAdjacentHTML('afterBegin',data.description)}).catch(function(error){})}));queryAll(".editcomm").forEach(el=>el.addEventListener("click",function(e){let comment_id=el.dataset.comment_id;let comment=document.querySelector('#insert_id_'+el.dataset.comment_id);fetch("/comment/editform",{method:"POST",body:"comment_id="+comment_id,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(response=>{return response.text()}).then(text=>{getById("comment_"+comment_id).classList.add("edit");comment.classList.add("block");comment.innerHTML=text;queryAll("#cancel_comment").forEach(el=>el.addEventListener("click",function(e){comment.classList.remove("block")}))})}));const tabs_post=document.querySelector(".tabs-post");if(tabs_post){const tabButton=queryAll(".tab-button");const contents=queryAll(".content-tabs");tabs_post.onclick=e=>{const id=e.target.dataset.id;if(id){tabButton.forEach(btn=>{btn.classList.remove("active")});e.target.classList.add("active");contents.forEach(content=>{content.classList.remove("tab_active")});getById('inputQa').value=0;if(id=='qa'){getById('inputQa').value=1}
return response.json()}).then(function(data){document.querySelector('input[name=post_title]').value=data.title;document.querySelector('textarea.url').insertAdjacentHTML('afterBegin',data.description)}).catch(function(error){})}));const tabs_post=document.querySelector(".tabs-post");if(tabs_post){const tabButton=queryAll(".tab-button");const contents=queryAll(".content-tabs");tabs_post.onclick=e=>{const id=e.target.dataset.id;if(id){tabButton.forEach(btn=>{btn.classList.remove("active")});e.target.classList.add("active");contents.forEach(content=>{content.classList.remove("tab_active")});getById('inputQa').value=0;if(id=='qa'){getById('inputQa').value=1}
const element=getById(id);element.classList.add("tab_active")}}}

View File

@ -2,4 +2,5 @@ const favicon=queryAll(".add-favicon"),sturl=queryAll(".status"),screenshot=quer
sturl.forEach(el=>el.addEventListener("click",function(e){makeRequest("/web/status/update")}));function fetchSearchUrl(){let url=getById("find-url").value;if(url.length<5)return;fetch("/search/web/url",{method:"POST",headers:{'Content-Type':'application/x-www-form-urlencoded'},body:"url="+url+"&_token="+token,}).then(response=>{return response.text()}).then(text=>{let obj=JSON.parse(text);let html='<div class="flex">';for(let key in obj){if(obj[key].item_id){html+='<a class="block green text-sm mt5 mb5" href="/web/website/'+obj[key].item_id+'">'+obj[key].item_url+'</a>'}
html+='</div>'}
if(!Object.keys(obj).length==0){let items=getById("search_url");items.classList.add("block");items.innerHTML=html}
let menu=document.querySelector('.none.block');if(menu){document.onclick=function(e){if(event.target.className!='.none.block'){let items=getById("search_url");items.classList.remove("block")}}}})}
let menu=document.querySelector('.none.block');if(menu){document.onclick=function(e){if(event.target.className!='.none.block'){let items=getById("search_url");items.classList.remove("block")}}}})}
reply.forEach(el=>el.addEventListener("click",function(e){let reply=document.querySelector('#reply_addentry'+el.dataset.id);fetch("/reply/"+el.dataset.type,{method:"POST",body:"id="+el.dataset.id+"&item_id="+el.dataset.item_id+"&_token="+token,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(response=>response.text()).then(text=>{reply.classList.add("block");reply.innerHTML=text;queryAll("#cancel_comment").forEach(el=>el.addEventListener("click",function(e){reply.classList.remove("block")}))})}))

View File

@ -1,7 +1,7 @@
let scrolled;let dHeader=document.querySelector(".d-header");if(dHeader){window.onscroll=function(){scrolled=window.pageYOffset||document.documentElement.scrollTop;if(scrolled>70){document.querySelector(".d-header").classList.add('show')}
if(70>scrolled){document.querySelector(".d-header").classList.remove('show')}}}
let token=document.querySelector("meta[name='csrf-token']").getAttribute("content");queryAll(".add-comment").forEach(el=>el.addEventListener("click",function(e){let answer_id=insert_id=el.dataset.answer_id;let comment_id=el.dataset.comment_id;if(comment_id){insert_id=el.dataset.comment_id}
let comment=document.querySelector('#insert_id_'+insert_id);comment.classList.add("block");fetch("/comments/addform",{method:"POST",body:"answer_id="+answer_id+"&comment_id="+comment_id+"&_token="+token,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(response=>{return response.text()}).then(text=>{comment.innerHTML=text;queryAll("#cancel_comment").forEach(el=>el.addEventListener("click",function(e){comment.classList.remove("block")}))})}));isIdEmpty('toggledark').onclick=function(){let mode=getCookie("dayNight");let expires=defTime();if(mode=="dark"){document.cookie="dayNight"+"="+"light"+"; "+expires+";path=/";document.getElementsByTagName('body')[0].classList.remove('dark')}else{document.cookie="dayNight"+"="+"dark"+"; "+expires+";path=/";document.getElementsByTagName('body')[0].classList.add('dark')}}
let token=document.querySelector("meta[name='csrf-token']").getAttribute("content");queryAll(".add-comment").forEach(el=>el.addEventListener("click",function(e){let comment_id=insert_id=el.dataset.comment_id;let post_id=el.dataset.post_id;if(post_id){insert_id=el.dataset.post_id}
let comment=document.querySelector('#insert_id_'+insert_id);comment.classList.add("block");fetch("/comment/addform",{method:"POST",body:"post_id="+post_id+"&comment_id="+comment_id+"&_token="+token,headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(response=>{return response.text()}).then(text=>{comment.innerHTML=text;queryAll("#cancel_comment").forEach(el=>el.addEventListener("click",function(e){comment.classList.remove("block")}))})}));isIdEmpty('toggledark').onclick=function(){let mode=getCookie("dayNight");let expires=defTime();if(mode=="dark"){document.cookie="dayNight"+"="+"light"+"; "+expires+";path=/";document.getElementsByTagName('body')[0].classList.remove('dark')}else{document.cookie="dayNight"+"="+"dark"+"; "+expires+";path=/";document.getElementsByTagName('body')[0].classList.add('dark')}}
isIdEmpty('togglemenu').onclick=function(){let mode=getCookie("menuYesNo");let expires=defTime();if(mode=="menuno"){document.cookie="menuYesNo"+"="+"menuyes"+"; "+expires+";path=/";document.getElementsByTagName('body')[0].classList.remove('menuno')}else{document.cookie="menuYesNo"+"="+"menuno"+"; "+expires+";path=/";document.getElementsByTagName('body')[0].classList.add('menuno')}}
isIdEmpty('postmenu').onclick=function(){let mode=getCookie("postAppearance");let expires=defTime();if(mode=="classic"){document.cookie="postAppearance"+"="+"card"+"; "+expires+";path=/";location.reload()}else{document.cookie="postAppearance"+"="+"classic"+"; "+expires+";path=/"}
location.reload()}

View File

@ -1,11 +1,12 @@
<?php use Hleb\Constructor\Handlers\Request; ?>
<div class="cm_addentry max-w780 mt10">
<?php if (UserData::checkActiveUser()) : ?>
<form action="<?= url('content.create', ['type' => 'comment']); ?>" accept-charset="UTF-8" method="post">
<?= csrf_field() ?>
<textarea id="qcomment" rows="5" minlength="6" placeholder="<?= __('app.markdown'); ?>..." name="comment"></textarea>
<textarea id="qcomment" rows="5" minlength="6" placeholder="<?= __('app.markdown'); ?>..." name="content"></textarea>
<fieldset>
<input type="hidden" name="answer_id" id="answer_id" value="<?= $data['answer_id']; ?>">
<input type="hidden" name="comment_id" id="comment_id" value="<?= $data['comment_id']; ?>">
<input type="hidden" name="comment_id" id="comment_id" value="<?= Request::getPostInt('comment_id'); ?>">
<?= Html::sumbit(__('app.reply')); ?>
<span id="cancel_comment" class="text-sm inline ml5 gray"><?= __('app.cancel'); ?></span>
</fieldset>

View File

@ -1,14 +0,0 @@
<div class="cm_addentry max-w780 mt10">
<?php if (UserData::checkActiveUser()) : ?>
<form id="add_comm" class="new_comment" action="<?= url('content.change', ['type' => 'comment']); ?>" accept-charset="UTF-8" method="post">
<?= csrf_field() ?>
<textarea rows="5" minlength="6" name="comment" id="comment"><?= $data['comment_content']; ?></textarea>
<fieldset>
<input type="hidden" name="comment_id" id="comment_id" value="<?= $data['comment_id']; ?>">
<?= Html::sumbit(__('app.edit')); ?>
<span id="cancel_comment" class="text-sm inline ml5 gray"><?= __('app.cancel'); ?></span>
</fieldset>
<div class="v-otsr"></div>
</form>
<?php endif; ?>
</div>

View File

@ -1,36 +0,0 @@
<?php if (!empty($latest_answers)) : ?>
<div class="p15 wrapper">
<div class="mb15">
<ul class="nav small">
<li class="tab-button active" data-id="home">
<?= __('app.answers'); ?>
</li>
<li class="tab-button pointer" data-id="more_comment">
<?= __('app.comments'); ?>
</li>
</ul>
</div>
<ul class="last-content content-tabs tab_active" id="home">
<?php foreach ($latest_answers as $answer) : ?>
<li>
<div class="gray-600 flex items-center gap-min text-sm">
<a class="flex gray-600 gap-min items-center" title="<?= $answer['login']; ?>" href="<?= url('profile', ['login' => $answer['login']]); ?>">
<?= Img::avatar($answer['avatar'], $answer['login'], 'img-sm', 'small'); ?>
<span class="nickname"><?= $answer['login']; ?></span>
</a>
<span class="lowercase"><?= Html::langDate($answer['answer_date']); ?></span>
</div>
<a class="last-content_telo" href="<?= post_slug($answer['post_id'], $answer['post_slug']); ?>#answer_<?= $answer['answer_id']; ?>">
<?php if (mb_strlen($fragment = fragment($answer['answer_content'], 98), 'utf-8') < 5) : ?>
<span class="lowercase">+ <?= __('app.comment'); ?>...</span>
<?php else : ?>
<?= $fragment; ?>
<?php endif; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<ul class="last-content content-tabs more_go" id="more_comment">
</ul>
</div>
<?php endif; ?>

View File

@ -0,0 +1,31 @@
<?php if (!empty($latest_comments)) : ?>
<div class="p15">
<div class="mb15">
<ul class="nav small">
<li class="tab-button active" data-id="home">
<?= __('app.comments'); ?>
</li>
</ul>
</div>
<ul class="last-content content-tabs tab_active" id="home">
<?php foreach ($latest_comments as $comment) : ?>
<li>
<div class="gray-600 flex items-center gap-min text-sm">
<a class="flex gray-600 gap-min items-center" title="<?= $comment['login']; ?>" href="<?= url('profile', ['login' => $comment['login']]); ?>">
<?= Img::avatar($comment['avatar'], $comment['login'], 'img-sm', 'small'); ?>
<span class="nickname"><?= $comment['login']; ?></span>
</a>
<span class="lowercase"><?= Html::langDate($comment['comment_date']); ?></span>
</div>
<a class="last-content_telo" href="<?= post_slug($comment['post_id'], $comment['post_slug']); ?>#comment_<?= $comment['comment_id']; ?>">
<?php if (mb_strlen($fragment = fragment($comment['comment_content'], 98), 'utf-8') < 5) : ?>
<span class="lowercase">+ <?= __('app.comment'); ?>...</span>
<?php else : ?>
<?= $fragment; ?>
<?php endif; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>

View File

@ -1,46 +0,0 @@
<?php $n = 0;
foreach ($comments as $comment) :
$n++; ?>
<?php if ($n != 1) { ?><div class="br-dotted mt10 mb10"></div><?php } ?>
<?php if (!empty($comment['answer_id'])) : ?>
<?php if ($comment['answer_published'] == 0 && $comment['answer_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<div class="content-body">
<div class="flex justify-between gap-min">
<div class="flex gap">
<a class="gray-600 flex gap-min" href="<?= url('profile', ['login' => $comment['login']]); ?>">
<?= Img::avatar($comment['avatar'], $comment['login'], 'img-sm', 'small'); ?>
<?= $comment['login']; ?>
</a>
<span class="gray-600 lowercase"><?= Html::langDate($comment['answer_date']); ?></span>
</div>
<div><?= Html::votes($comment, 'answer'); ?></div>
</div>
<a class="block" href="<?= post_slug($comment['post_id'], $comment['post_slug']); ?>#answer_<?= $comment['answer_id']; ?>">
<?= $comment['post_title']; ?>
</a>
<div class="ind-first-p max-w780"><?= markdown($comment['answer_content']); ?></div>
</div>
<?php else : ?>
<?php if ($comment['comment_published'] == 0 && $comment['comment_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<div class="content-body">
<div class="flex justify-between gap">
<div class="flex gap-min">
<a class="gray-600 flex gap-min" href="<?= url('profile', ['login' => $comment['login']]); ?>">
<?= Img::avatar($comment['avatar'], $comment['login'], 'img-sm', 'small'); ?>
<span class="nickname<?php if (Html::loginColor($comment['created_at'] ?? false)) : ?> green<?php endif; ?>">
<?= $comment['login']; ?>
</span>
</a>
<span class="gray-600 lowercase"><?= Html::langDate($comment['comment_date']); ?></span>
</div>
<div><?= Html::votes($comment, 'comment'); ?></div>
</div>
<a class="block" href="<?= post_slug($comment['post_id'], $comment['post_slug']); ?>#comment_<?= $comment['comment_id']; ?>">
<?= $comment['post_title']; ?>
</a>
<div class="ind-first-p"><?= markdown($comment['comment_content']); ?></div>
</div>
<?php endif; ?>
<?php endforeach; ?>

View File

@ -6,7 +6,7 @@
</ul>
</div>
<?php if (!empty($data['comments'])) : ?>
<?= insert('/content/comment/comment', ['comments' => $data['comments']]); ?>
<?= insert('/content/comments/comment', ['comments' => $data['comments']]); ?>
<?php $path = ($data['sheet'] == 'deleted') ? url('comments.deleted') : '/comments'; ?>
<?= Html::pagination($data['pNum'], $data['pagesCount'], false, $path); ?>

View File

@ -0,0 +1,22 @@
<?php $n = 0;
foreach ($comments as $comment) :
$n++; ?>
<?php if ($n != 1) { ?><div class="br-dotted mt10 mb10"></div><?php } ?>
<?php if ($comment['comment_published'] == 0 && $comment['comment_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<div class="content-body">
<div class="flex justify-between gap-min">
<div class="flex gap-min">
<a class="gray-600 flex gap-min" href="<?= url('profile', ['login' => $comment['login']]); ?>">
<?= Img::avatar($comment['avatar'], $comment['login'], 'img-sm', 'small'); ?>
<?= $comment['login']; ?>
</a>
<span class="gray-600 lowercase"><?= Html::langDate($comment['comment_date']); ?></span>
</div>
<div><?= Html::votes($comment, 'comment'); ?></div>
</div>
<a class="block" href="<?= post_slug($comment['post_id'], $comment['post_slug']); ?>#comment_<?= $comment['comment_id']; ?>">
<?= $comment['post_title']; ?>
</a>
<div class="ind-first-p max-w780"><?= markdown($comment['comment_content']); ?></div>
</div>
<?php endforeach; ?>

View File

@ -1,20 +1,20 @@
<?= insert('/_block/add-js-css'); ?>
<main>
<a href="/"><?= __('app.home'); ?></a> / <span class="gray-600"><?= __('app.edit_answer'); ?>:</span>
<a href="/"><?= __('app.home'); ?></a> / <span class="gray-600"><?= __('app.edit_comment'); ?>:</span>
<a class="mb5 block" href="<?= post_slug($data['post']['post_id'], $data['post']['post_slug']); ?>"><?= $data['post']['post_title']; ?></a>
<form class="max-w780" action="<?= url('content.change', ['type' => 'answer']); ?>" accept-charset="UTF-8" method="post">
<form class="max-w780" action="<?= url('content.change', ['type' => 'comment']); ?>" accept-charset="UTF-8" method="post">
<?= csrf_field() ?>
<?= insert('/_block/form/editor', ['height' => '300px', 'content' => $data['answer']['answer_content'], 'type' => 'answer', 'id' => $data['post']['post_id']]); ?>
<?= insert('/_block/form/editor', ['height' => '300px', 'content' => $data['comment']['comment_content'], 'type' => 'comment', 'id' => $data['post']['post_id']]); ?>
<?php if (UserData::checkAdmin()) : ?>
<?= insert('/_block/form/select/user', ['user' => $data['user']]); ?>
<?php endif; ?>
<input type="hidden" name="answer_id" value="<?= $data['answer']['answer_id']; ?>">
<input type="hidden" name="comment_id" value="<?= $data['comment']['comment_id']; ?>">
<?= Html::sumbit(__('app.edit')); ?>
<a href="<?= post_slug($data['post']['post_id'], $data['post']['post_slug']); ?>#answer_<?= $data['answer']['answer_id']; ?>" class="text-sm inline ml15 gray"><?= __('app.cancel'); ?></a>
<a href="<?= post_slug($data['post']['post_id'], $data['post']['post_slug']); ?>#comment_<?= $data['comment']['comment_id']; ?>" class="text-sm inline ml15 gray"><?= __('app.cancel'); ?></a>
</form>
</main>

View File

@ -0,0 +1,82 @@
<div class="right inline">
<div class="relative ml10">
<span class="trigger gray-600 text-sm">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#more-horizontal"></use>
</svg>
</span>
<ul class="dropdown">
<?php if (Access::author('comment', $comment) === true) : ?>
<li>
<a class="editansw" href="<?= url('content.edit', ['type' => 'comment', 'id' => $comment['comment_id']]); ?>">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#edit"></use>
</svg>
<?= __('app.edit'); ?>
</a>
</li>
<?php endif; ?>
<?php if (UserData::checkAdmin()) : ?>
<li>
<a data-type="comment" data-id="<?= $comment['comment_id']; ?>" class="type-action">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#trash-2"></use>
</svg>
<?= $comment['comment_is_deleted'] == 1 ? __('app.recover') : __('app.remove'); ?>
</a>
</li>
<li>
<a href="<?= url('admin.logip', ['ip' => $comment['comment_ip']]); ?>">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#info"></use>
</svg>
<?= $comment['comment_ip']; ?>
</a>
<li>
<?php endif; ?>
<?php if (UserData::getUserId() != $comment['comment_user_id'] && UserData::getRegType(config('trust-levels.tl_add_report'))) : ?>
<li>
<a data-post_id="<?= $post['post_id']; ?>" data-type="comment" data-content_id="<?= $comment['comment_id']; ?>" data-a11y-dialog-show="my-dialog">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#alert-circle"></use>
</svg>
<?= __('app.report'); ?>
</a>
</li>
<?php endif; ?>
<?php if ($type == 'qa') : ?>
<?php if ($post['post_comments_count'] > 1 && $level == 0) : ?>
<?php if (UserData::getUserId() == $post['post_user_id'] || UserData::checkAdmin()) : ?>
<li>
<a id="best_<?= $comment['comment_id']; ?>" data-id="<?= $comment['comment_id']; ?>" class="comment-best">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#award"></use>
</svg>
<?= __('app.raise_answer'); ?>
</a>
</li>
<?php endif; ?>
<?php endif; ?>
<li>
<?= Html::favorite($comment['comment_id'], 'comment', $comment['tid'], 'heading'); ?>
</li>
<?php endif; ?>
<li>
<a rel="nofollow" class="gray-600" href="<?= post_slug($post['post_id'], $post['post_slug']); ?>#comment_<?= $comment['comment_id']; ?>">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#anchor"></use>
</svg>
<?= __('app.link'); ?>
</a>
</li>
</ul>
</div>
</div>

View File

@ -89,7 +89,7 @@ use Hleb\Constructor\Handlers\Request; ?>
<?php endif; ?>
<div class="sticky top-sm">
<?= insert('/_block/latest-answers-tabs', ['latest_answers' => $data['latest_answers']]); ?>
<?= insert('/_block/latest-comments-tabs', ['latest_comments' => $data['latest_comments']]); ?>
<?php if (UserData::getUserScroll()) : ?>
<?= insert('/global/sidebar-footer'); ?>

View File

@ -1,80 +0,0 @@
<div class="right inline">
<div class="relative ml10">
<span class="trigger gray-600 text-sm">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#more-horizontal"></use>
</svg>
</span>
<ul class="dropdown">
<?php if (Access::author('answer', $answer) === true) : ?>
<li>
<a class="editansw" href="<?= url('content.edit', ['type' => 'answer', 'id' => $answer['answer_id']]); ?>">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#edit"></use>
</svg>
<?= __('app.edit'); ?>
</a>
</li>
<?php endif; ?>
<?php if (UserData::checkAdmin()) : ?>
<li>
<a data-type="answer" data-id="<?= $answer['answer_id']; ?>" class="type-action">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#trash-2"></use>
</svg>
<?= $answer['answer_is_deleted'] == 1 ? __('app.recover') : __('app.remove'); ?>
</a>
</li>
<li>
<a href="<?= url('admin.logip', ['ip' => $answer['answer_ip']]); ?>">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#info"></use>
</svg>
<?= $answer['answer_ip']; ?>
</a>
<li>
<?php endif; ?>
<?php if (UserData::getUserId() != $answer['answer_user_id'] && UserData::getRegType(config('trust-levels.tl_add_report'))) : ?>
<li>
<a data-post_id="<?= $post['post_id']; ?>" data-type="answer" data-content_id="<?= $answer['answer_id']; ?>" data-a11y-dialog-show="my-dialog">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#alert-circle"></use>
</svg>
<?= __('app.report'); ?>
</a>
</li>
<?php endif; ?>
<?php if ($post['amount_content'] > 1) : ?>
<?php if (UserData::getUserId() == $post['post_user_id'] || UserData::checkAdmin()) : ?>
<li>
<a id="best_<?= $answer['answer_id']; ?>" data-id="<?= $answer['answer_id']; ?>" class="answer-best">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#award"></use>
</svg>
<?= __('app.raise_answer'); ?>
</a>
</li>
<?php endif; ?>
<?php endif; ?>
<li>
<?= Html::favorite($answer['answer_id'], 'answer', $answer['tid'], 'heading'); ?>
</li>
<li>
<a rel="nofollow" class="gray-600" href="<?= $post_url; ?>#answer_<?= $answer['answer_id']; ?>">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#anchor"></use>
</svg>
<?= __('app.link'); ?>
</a>
</li>
</ul>
</div>
</div>

View File

@ -1,209 +1,111 @@
<?php if (!empty($data['answers'])) : ?>
<?php if (!empty($data['comments'])) : ?>
<div class="indent-body">
<div class="flex justify-between mb20">
<h2 class="lowercase mb15 text-2xl"><?= Html::numWord($post['amount_content'], __('app.num_answer'), true); ?></h2>
<h2 class="lowercase mb15 text-2xl"><?= Html::numWord($post['post_comments_count'], __('app.num_comment'), true); ?></h2>
<ul class="nav scroll-menu">
<li<?php if ($data['sorting'] == 'top') : ?> class="active" <?php endif; ?>><a href="?sort=top#comment"><?= __('app.top'); ?></a></li>
<li<?php if ($data['sorting'] == 'old') : ?> class="active" <?php endif; ?>><a href="?sort=old#comment"><?= __('app.new_ones'); ?></a></li>
<li<?php if ($data['sorting'] == '') : ?> class="active" <?php endif; ?>><a href="./<?= $post['post_slug']; ?>#comment"><?= __('app.by_date'); ?></a></li>
</ul>
</div>
<?php $n = 0;
foreach ($data['answers'] as $answer) :
$n++;
$post_url = post_slug($post['post_id'], $post['post_slug']);
<?php
function internalRender($nodes, $post, $level = 0)
{
foreach ($nodes as $node) :
$level = $level > 5 ? 5 : $level;
?>
<?php if ($answer['answer_is_deleted'] == 1 && !UserData::checkAdmin()) : ?>
<div class="gray-600 text-sm m10"><?= __('app.content_deleted', ['name' => __('app.answer')]); ?>...</div>
<?php else : ?>
<?php if ($node['comment_is_deleted'] == 1 && !UserData::checkAdmin()) : ?>
<div class="gray-600 text-sm m10"><?= __('app.content_deleted', ['name' => __('app.comment')]); ?>...</div>
<?php else : ?>
<?php if ($n != 1) : ?><div class="br-dotted mt10 mb10"></div><?php endif; ?>
<?php if ($node['comment_published'] == 0 && $node['comment_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<?php if ($answer['answer_published'] == 0 && $answer['answer_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<ol class="comment-telo">
<li>
<div class="comment-thread comment-level-<?= $level; ?>"></div>
<ol class="mb20 list-none<?php if ($answer['answer_is_deleted'] == 1) : ?> m5 bg-red-200<?php endif; ?>">
<li class="content_tree" id="answer_<?= $answer['answer_id']; ?>">
<div class="content-body">
<div class="flex justify-between">
<div class="flex text-sm gap">
<a class="gray-600" href="<?= url('profile', ['login' => $answer['login']]); ?>">
<?= Img::avatar($answer['avatar'], $answer['login'], 'img-sm mr5', 'small'); ?>
<span class="nickname<?php if (Html::loginColor($answer['created_at'])) : ?> green<?php endif; ?>">
<?= $answer['login']; ?>
</span>
</a>
<?php if ($post['post_user_id'] == $answer['answer_user_id']) : ?>
<svg class="icons icon-small sky">
<use xlink:href="/assets/svg/icons.svg#mic"></use>
</svg>
<?php endif; ?>
<span class="gray-600 lowercase">
<?= Html::langDate($answer['answer_date']); ?>
</span>
<?php if (empty($answer['edit'])) : ?>
<span class="gray-600">
(<?= __('app.ed'); ?>.)
</span>
<?php endif; ?>
<?php if ($answer['answer_published'] == 0 && UserData::checkAdmin()) : ?>
<span class="ml15 red lowercase"><?= __('app.audits'); ?></span>
<?php endif; ?>
<?php if ($answer['answer_lo']) : ?>
<svg class="icons red">
<use xlink:href="/assets/svg/icons.svg#arrow-up"></use>
</svg>
<?php endif; ?>
</div>
<?= insert('/content/post/answer-menu', ['post_url' => $post_url, 'post' => $post, 'answer' => $answer]); ?>
</div>
<div class="ind-first-p">
<?= markdown($answer['answer_content'], 'text'); ?>
</div>
</div>
<div class="flex text-sm gap mt10">
<?= Html::votes($answer, 'answer'); ?>
<?php if ($post['post_closed'] == 0 && $post['post_is_deleted'] == 0 || UserData::checkAdmin()) : ?>
<a data-answer_id="<?= $answer['answer_id']; ?>" class="add-comment gray-600"><?= __('app.reply'); ?></a>
<?php endif; ?>
</div>
<div data-insert="<?= $answer['answer_id']; ?>" id="insert_id_<?= $answer['answer_id']; ?>" class="none"></div>
</li>
</ol>
<?php endif; ?>
<?php foreach ($answer['comments'] as $comment) : ?>
<?php if ($comment['comment_is_deleted'] == 1 && !UserData::checkAdmin()) continue; ?>
<?php if ($comment['comment_published'] == 0 && $comment['comment_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<ol class="list-none">
<li class="content_tree mb20 ml15<?php if ($comment['comment_parent_id'] > 0) : ?> ml30<?php endif; ?><?php if ($comment['comment_is_deleted'] == 1) : ?> m5 bg-red-200<?php endif; ?>" id="comment_<?= $comment['comment_id']; ?>">
<div class="flex justify-between">
<div class="text-sm flex gap">
<a class="gray-600" href="<?= url('profile', ['login' => $comment['login']]); ?>">
<?= Img::avatar($comment['avatar'], $comment['login'], 'img-sm', 'small'); ?>
<span class="nickname<?php if (Html::loginColor($comment['created_at'])) : ?> green<?php endif; ?>">
<?= $comment['login']; ?>
</span>
</a>
<?php if ($post['post_user_id'] == $comment['comment_user_id']) : ?>
<svg class="icons icon-small sky">
<use xlink:href="/assets/svg/icons.svg#mic"></use>
</svg>
<?php endif; ?>
<span class="gray-600 lowercase">
<?= Html::langDate($comment['comment_date']); ?>
</span>
<?php if ($comment['comment_parent_id'] > 0) : ?>
<a class="gray-600" rel="nofollow" href="<?= $post_url; ?>#comment_<?= $comment['comment_parent_id']; ?>"><svg class="icons icon-small">
<use xlink:href="/assets/svg/icons.svg#arrow-up"></use>
</svg></a>
<?php else : ?>
<a class="gray-600" rel="nofollow" href="<?= $post_url; ?>#answer_<?= $comment['comment_answer_id']; ?>"><svg class="icons icon-small">
<use xlink:href="/assets/svg/icons.svg#arrow-up"></use>
</svg></a>
<?php endif; ?>
<?php if ($comment['comment_published'] == 0 && UserData::checkAdmin()) : ?>
<span class="ml15 red lowercase"><?= __('app.audits'); ?></span>
<?php endif; ?>
</div>
<div class="right inline">
<div class="relative ml10">
<span class="trigger gray-600 text-sm">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#more-horizontal"></use>
</svg>
</span>
<ul class="dropdown">
<?php if (Access::author('comment', $comment) === true) : ?>
<li>
<a data-post_id="<?= $post['post_id']; ?>" data-comment_id="<?= $comment['comment_id']; ?>" class="editcomm gray-600">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#edit"></use>
</svg>
<?= __('app.edit'); ?>
</a>
</li>
<?php endif; ?>
<?php if (UserData::checkAdmin()) : ?>
<li>
<a data-type="comment" data-id="<?= $comment['comment_id']; ?>" class="type-action gray-600">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#trash-2"></use>
</svg>
<?= $comment['comment_is_deleted'] == 1 ? __('app.recover') : __('app.remove'); ?>
</a>
</li>
<li>
<a href="<?= url('admin.logip', ['ip' => $comment['comment_ip']]); ?>">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#info"></use>
</svg>
<?= $comment['comment_ip']; ?>
</a>
<li>
<div class="content_tree relative comment-level-left-<?= $level; ?><?php if ($node['comment_is_deleted'] == 1) : ?> bg-red-200<?php endif; ?>" id="comment_<?= $node['comment_id']; ?>">
<div class="content-body">
<div class="flex justify-between">
<div class="flex text-sm gap-min">
<a class="gray-600" href="<?= url('profile', ['login' => $node['login']]); ?>">
<?= Img::avatar($node['avatar'], $node['login'], 'img-sm mr5', 'small'); ?>
<span class="nickname<?php if (Html::loginColor($node['created_at'])) : ?> green<?php endif; ?>">
<?= $node['login']; ?>
</span>
</a>
<?php if ($post['post_user_id'] == $node['comment_user_id']) : ?>
<svg class="icons icon-small sky">
<use xlink:href="/assets/svg/icons.svg#mic"></use>
</svg>
<?php endif; ?>
<span class="gray-600 lowercase">
<?= Html::langDate($node['comment_date']); ?>
</span>
<?php if (strtotime($node['comment_modified']) < strtotime($node['comment_date'])) : ?>
<span class="gray-600">
(<?= __('app.ed'); ?>.)
</span>
<?php endif; ?>
<?php if ($node['comment_published'] == 0 && UserData::checkAdmin()) : ?>
<span class="ml15 red lowercase"><?= __('app.audits'); ?></span>
<?php endif; ?>
<?php if ($node['comment_lo']) : ?>
<svg class="icons red">
<use xlink:href="/assets/svg/icons.svg#arrow-up"></use>
</svg>
<?php endif; ?>
<?php if (UserData::getUserId() != $comment['comment_user_id'] && UserData::getRegType(config('trust-levels.tl_add_report'))) : ?>
<li>
<a data-post_id="<?= $post['post_id']; ?>" data-type="comment" data-content_id="<?= $comment['comment_id']; ?>" data-a11y-dialog-show="my-dialog" class="gray-600">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#alert-circle"></use>
</svg>
<?= __('app.report'); ?>
</a>
</li>
<?php endif; ?>
<li>
<a class="gray-600" rel="nofollow" href="<?= $post_url; ?>#comment_<?= $comment['comment_id']; ?>">
<svg class="icons icon-small">
<use xlink:href="/assets/svg/icons.svg#anchor"></use>
</svg>
<?= __('app.link'); ?>
</a>
</li>
</ul>
<?php if ($node['comment_parent_id'] > 0) : ?>
<a class="gray-600" rel="nofollow" href="<?= post_slug($post['post_id'], $post['post_slug']); ?>#comment_<?= $node['comment_parent_id']; ?>">
<svg class="icons icon-small">
<use xlink:href="/assets/svg/icons.svg#arrow-up"></use>
</svg></a>
<?php endif; ?>
<span class="text-sm gray-600">вложение - <?= $level; ?> </span>
</div>
<?= insert('/content/comments/menu', ['post' => $post, 'comment' => $node, 'type' => 'discussion']); ?>
</div>
<div class="ind-first-p">
<?= markdown($node['comment_content'], 'text'); ?>
</div>
</div>
<div class="flex text-sm gap mt10 ml5">
<?= Html::votes($node, 'comment'); ?>
<?php if ($post['post_closed'] == 0 && $post['post_is_deleted'] == 0 || UserData::checkAdmin()) : ?>
<a data-comment_id="<?= $node['comment_id']; ?>" class="add-comment gray-600"><?= __('app.reply'); ?></a>
<?php endif; ?>
</div>
<div data-insert="<?= $node['comment_id']; ?>" id="insert_id_<?= $node['comment_id']; ?>" class="none"></div>
</div>
</div>
<div class="ind-first-p">
<?= markdown($comment['comment_content'], 'text'); ?>
</div>
<div class="text-sm flex gap">
<?= Html::votes($comment, 'comment'); ?>
<?php if ($post['post_closed'] == 0 && $post['post_is_deleted'] == 0 || UserData::checkAdmin()) : ?>
<a data-answer_id="<?= $answer['answer_id']; ?>" data-comment_id="<?= $comment['comment_id']; ?>" class="add-comment gray-600">
<?= __('app.reply'); ?>
</a>
<?php endif; ?>
<?php if (isset($node['children'])) {
internalRender($node['children'], $post, $level + 1);
} ?>
</div>
<div data-insert="<?= $comment['comment_id']; ?>" id="insert_id_<?= $comment['comment_id']; ?>" class="none"></div>
</li>
</ol>
<?php endforeach; ?>
<?php endforeach; ?>
</li>
</ol>
<?php endif; ?>
<?php endforeach;
}
echo internalRender($data['comments'], $data['post']);
?>
</div>
<?php else : ?>
<?php if ($post['post_closed'] != 1) : ?>
<?php if (UserData::checkActiveUser()) : ?>
<?= insert('/_block/no-content', ['type' => 'small', 'text' => __('app.no_comments'), 'icon' => 'info']); ?>
<?php else : ?>
<?= insert('/_block/no-content', ['type' => 'small', 'text' => __('app.no_auth'), 'icon' => 'info']); ?>
<?php endif; ?>
<?php if ($post['post_closed'] == 1) : ?>
<?= insert('/_block/no-content', ['type' => 'small', 'text' => __('app.close'), 'icon' => 'closed']); ?>
<?php elseif (!UserData::checkActiveUser()) : ?>
<?= insert('/_block/no-content', ['type' => 'small', 'text' => __('app.no_auth'), 'icon' => 'info']); ?>
<?php else : ?>
<?= insert('/_block/no-content', ['type' => 'small', 'text' => __('app.no_comments'), 'icon' => 'info']); ?>
<?php endif; ?>
<?php endif; ?>
<?php if ($post['post_closed'] == 1) :
echo insert('/_block/no-content', ['type' => 'small', 'text' => __('app.close'), 'icon' => 'closed']);
endif; ?>
<?php endif; ?>

View File

@ -1,125 +1,83 @@
<?php if (!empty($data['answers'])) : ?>
<?php if (!empty($data['comments'])) : ?>
<div class="indent-body">
<h2 class="lowercase m0 text-2xl">
<?= Html::numWord($post['amount_content'], __('app.num_answer'), true); ?>
<?= Html::numWord($post['post_comments_count'], __('app.num_comment'), true); ?>
</h2>
<?php
foreach ($data['answers'] as $answer) :
$post_url = post_slug($post['post_id'], $post['post_slug']);
function internalRender($nodes, $post, $level = 0, $type = 'comment')
{
foreach ($nodes as $node) :
$level = $level > 1 ? 1 : $level;
?>
<?php if ($answer['answer_is_deleted'] == 1 && !UserData::checkAdmin()) continue; ?>
<?php if ($answer['answer_published'] == 0 && $answer['answer_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<?php if ($node['comment_is_deleted'] == 1 && !UserData::checkAdmin()) continue; ?>
<?php if ($node['comment_published'] == 0 && $node['comment_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<div class="block-answer br-bottom<?php if ($answer['answer_is_deleted'] == 1) : ?> m5 bg-red-200<?php endif; ?>">
<div class="block-comment br-bottom<?php if ($node['comment_is_deleted'] == 1) : ?> m5 bg-red-200<?php endif; ?>">
<?= insert('/content/post/answer-menu', ['post_url' => $post_url, 'post' => $post, 'answer' => $answer]); ?>
<?= insert('/content/comments/menu', ['post' => $post, 'comment' => $node, 'type' => 'qa', 'level' => $level]); ?>
<?php if ($answer['answer_lo']) : ?>
<div title="<?= __('app.best_answer'); ?>" class="red right text-2xl p5"></div>
<?php endif; ?>
<?php if ($node['comment_lo']) : ?>
<div title="<?= __('app.best_answer'); ?>" class="red right text-2xl p5"></div>
<?php endif; ?>
<?php if (UserData::getUserId() == $answer['answer_user_id']) { ?> <?php $otvet = 1; ?> <?php } ?>
<div class="br-dotted mb5"></div>
<ol class="list-none">
<li class="content_tree" id="answer_<?= $answer['answer_id']; ?>">
<div class="max-w780">
<?= markdown($answer['answer_content'], 'text'); ?>
</div>
<div class="flex text-sm justify-between">
<div class="flex gap">
<?= Html::votes($answer, 'answer'); ?>
<?php if (UserData::getRegType(config('trust-levels.tl_add_comm_qa'))) : ?>
<?php if ($post['post_closed'] == 0 ?? $post['post_is_deleted'] == 0 || UserData::checkAdmin()) : ?>
<a data-answer_id="<?= $answer['answer_id']; ?>" class="add-comment gray"><?= __('app.reply'); ?></a>
<?php endif; ?>
<?php endif; ?>
</div>
<div class="text-sm gray-600 flex gap lowercase mb10">
<a class="gray-600<?php if (Html::loginColor($answer['created_at'] ?? false)) : ?> green<?php endif; ?>" href="<?= url('profile', ['login' => $answer['login']]); ?>">
<span class="nickname"><?= $answer['login']; ?></span>
</a>
<span class="mb-none"><?= Html::langDate($answer['answer_date']); ?>
<?php if (empty($answer['edit'])) : ?>
(<?= __('app.ed'); ?>.)
<?php endif; ?></span>
<?php if ($answer['answer_published'] == 0 && UserData::checkAdmin()) : ?>
<span class="ml15 red lowercase"><?= __('app.audits'); ?></span>
<?php endif; ?>
</div>
</div>
<div data-insert="<?= $answer['answer_id']; ?>" id="insert_id_<?= $answer['answer_id']; ?>" class="none"></div>
</li>
</ol>
</div>
<ol class="list-none">
<?php foreach ($answer['comments'] as $comment) : ?>
<?php if ($comment['comment_is_deleted'] == 1 && !UserData::checkAdmin()) continue; ?>
<?php if ($comment['comment_published'] == 0 && $comment['comment_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<li class="content_tree br-li-bottom-no br-bottom ml15<?php if ($comment['comment_is_deleted'] == 1) : ?> m5 bg-red-200<?php endif; ?>" id="comment_<?= $comment['comment_id']; ?>">
<div class="qa-comment">
<div class="flex3 gap-min">
<?= fragment($comment['comment_content'], 1500); ?>
<span class="gray-600"> </span>
<a class="gray-600<?php if (Html::loginColor($comment['created_at'] ?? false)) : ?> green<?php endif; ?>" href="<?= url('profile', ['login' => $comment['login']]); ?>">
<span class="nickname"><?= $comment['login']; ?></span>
</a>
<span class="lowercase gray-600 ml5 mr5"><?= Html::langDate($comment['comment_date']); ?></span>
<?php if (UserData::getRegType(config('trust-levels.tl_add_comm_qa'))) : ?>
<?php if ($post['post_closed'] == 0) : ?>
<?php if ($post['post_is_deleted'] == 0 || UserData::checkAdmin()) : ?>
<a data-answer_id="<?= $answer['answer_id']; ?>" data-comment_id="<?= $comment['comment_id']; ?>" class="add-comment gray-600 ml5 mr5">
<?= __('app.reply'); ?>
</a>
<?php if (UserData::getUserId() == $node['comment_user_id']) { ?> <?php $otvet = 1; ?> <?php } ?>
<div class="br-dotted mb5"></div>
<ol class="list-none">
<li class="content_tree" id="comment_<?= $node['comment_id']; ?>">
<div class="comment-comm comment-thread comment-level-<?= $level; ?>"></div>
<div class="comment-level-left-<?= $level; ?>" id="comment_<?= $node['comment_id']; ?>">
<div class="max-w780 ind-first-p">
<?= markdown($node['comment_content'], 'text'); ?>
</div>
<div class="flex text-sm justify-between">
<div class="flex gap">
<?php if ($type != 'qa') : ?>
<?= Html::votes($node, 'comment'); ?>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
<?php if (Access::author('comment', $comment) === true) : ?>
<a data-post_id="<?= $post['post_id']; ?>" data-comment_id="<?= $comment['comment_id']; ?>" class="editcomm gray-600 ml5 mr5">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#edit"></use>
</svg>
</a>
<?php endif; ?>
<?php if (UserData::getRegType(config('trust-levels.tl_add_comm_qa'))) : ?>
<?php if ($post['post_closed'] == 0 ?? $post['post_is_deleted'] == 0 || UserData::checkAdmin()) : ?>
<a data-comment_id="<?= $node['comment_id']; ?>" class="add-comment gray"><?= __('app.reply'); ?></a>
<?php endif; ?>
<?php endif; ?>
</div>
<div class="text-sm gray-600 flex gap lowercase mb5">
<a class="gray-600<?php if (Html::loginColor($node['created_at'] ?? false)) : ?> green<?php endif; ?>" href="<?= url('profile', ['login' => $node['login']]); ?>">
<span class="nickname"><?= $node['login']; ?></span>
</a>
<span class="mb-none"><?= Html::langDate($node['comment_date']); ?>
<?php if ($type != 'qa') : ?>
<?php if (empty($node['edit'])) : ?>
(<?= __('app.ed'); ?>.)
<?php endif; ?>
<?php endif; ?>
</span>
<?php if ($node['comment_published'] == 0 && UserData::checkAdmin()) : ?>
<span class="ml15 red lowercase"><?= __('app.audits'); ?></span>
<?php endif; ?>
</div>
</div>
<div data-insert="<?= $node['comment_id']; ?>" id="insert_id_<?= $node['comment_id']; ?>" class="none"></div>
</li>
</ol>
</div>
<?php if (UserData::checkAdmin()) : ?>
<a data-type="comment" data-id="<?= $comment['comment_id']; ?>" class="type-action gray-600 ml5 mr5">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#trash"></use>
</svg>
</a>
<?php endif; ?>
<?php if (isset($node['children'])) {
internalRender($node['children'], $post, $level + 1, 'qa');
} ?>
<?php if (UserData::getUserId() != $comment['comment_user_id'] && UserData::checkActiveUser()) : ?>
<a data-post_id="<?= $post['post_id']; ?>" data-type="comment" data-content_id="<?= $comment['comment_id']; ?>" data-a11y-dialog-show="my-dialog" class="gray-600 ml5 mr5">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#alert-circle"></use>
</svg>
</a>
<?php endif; ?>
<?php endforeach;
}
echo internalRender($data['comments'], $data['post']);
?>
</div>
<div data-insert="<?= $comment['comment_id']; ?>" id="insert_id_<?= $comment['comment_id']; ?>" class="none"></div>
</div>
</li>
<?php endforeach; ?>
</ol>
<?php endforeach; ?>
</div>
<?php else : ?>
<?php if ($post['post_closed'] != 1) : ?>
<?= insert('/_block/no-content', ['type' => 'small', 'text' => __('app.no_answers'), 'icon' => 'info']); ?>
<?= insert('/_block/no-content', ['type' => 'small', 'text' => __('app.no_comments'), 'icon' => 'info']); ?>
<?php endif; ?>
<?php endif; ?>
@ -129,17 +87,17 @@
<?php if (UserData::checkActiveUser()) : ?>
<?php if ($post['post_feature'] == 1 && $post['post_draft'] == 0 && $post['post_closed'] == 0) : ?>
<form class="mb15 mt20" action="<?= url('content.create', ['type' => 'answer']); ?>" accept-charset="UTF-8" method="post">
<form class="mb15 mt20" action="<?= url('content.create', ['type' => 'comment']); ?>" accept-charset="UTF-8" method="post">
<?= csrf_field() ?>
<?= insert('/_block/form/editor', [
'height' => '250px',
'id' => $post['post_id'],
'type' => 'answer',
'type' => 'comment',
]); ?>
<div class="clear mt5">
<input type="hidden" name="post_id" value="<?= $post['post_id']; ?>">
<input type="hidden" name="answer_id" value="0">
<input type="hidden" name="comment_id" value="0">
<?= Html::sumbit(__('app.reply')); ?>
</div>
</form>

View File

@ -8,11 +8,11 @@
<?php endif; ?>
<?php $post_url = post_slug($post['post_id'], $post['post_slug']); ?>
<?php if ($post['post_hidden'] == 1) : ?>
<?php if ($post['post_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<?php if ($post['post_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<?php endif; ?>
<div class="box shadow-bottom">
<div class="flex items-center gap-min text-sm mb5">
<a class="gray-600 flex gap-min items-center" href="<?= url('profile', ['login' => $post['login']]); ?>">
@ -86,12 +86,12 @@
</svg>
<?= $post['post_hits_count'] == 0 ? 1 : $post['post_hits_count']; ?>
</div>
<?php if ($post['post_answers_count'] != 0) : ?>
<?php if ($post['post_comments_count'] != 0) : ?>
<a class="flex gray-600 gap-min" href="<?= $post_url; ?>#comment">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#comments"></use>
</svg>
<?= $post['post_answers_count'] + $post['post_comments_count']; ?>
<?= $post['post_comments_count']; ?>
</a>
<?php endif; ?>
</div>

View File

@ -11,11 +11,11 @@ use Hleb\Constructor\Handlers\Request; ?>
<?php endif; ?>
<?php $post_url = post_slug($post['post_id'], $post['post_slug']); ?>
<?php if ($post['post_hidden'] == 1) : ?>
<?php if ($post['post_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<?php if ($post['post_user_id'] != UserData::getUserId() && !UserData::checkAdmin()) continue; ?>
<?php endif; ?>
<div class="box shadow-bottom article_<?= $post['post_id']; ?>">
<div class="flex justify-between">
@ -72,17 +72,17 @@ use Hleb\Constructor\Handlers\Request; ?>
<a class="gray-600" href="<?= url('profile', ['login' => $post['login']]); ?>">
<span class="nickname<?php if (Html::loginColor($post['created_at'] ?? false)) : ?> green<?php endif; ?>">
<?= $post['login']; ?>
</span>
</span>
</a>
<div class="gray-600 lowercase"><?= Html::langDate($post['post_date']); ?></div>
<?php if ($post['post_answers_count'] != 0) : ?>
<?php if ($post['post_comments_count'] != 0) : ?>
<a class="flex gray-600" href="<?= $post_url; ?>#comment">
<svg class="icons mr5">
<use xlink:href="/assets/svg/icons.svg#comments"></use>
</svg>
<?= $post['post_answers_count'] + $post['post_comments_count']; ?>
<?= $post['post_comments_count']; ?>
</a>
<?php endif; ?>

View File

@ -170,14 +170,14 @@ $blog = $data['blog'][0] ?? null;
<?php if (UserData::checkActiveUser()) : ?>
<?php if ($post['post_feature'] == 0 && $post['post_draft'] == 0 && $post['post_closed'] == 0) : ?>
<form action="<?= url('content.create', ['type' => 'answer']); ?>" accept-charset="UTF-8" method="post">
<form action="<?= url('content.create', ['type' => 'comment']); ?>" accept-charset="UTF-8" method="post">
<?= csrf_field() ?>
<?= insert('/_block/form/editor', ['height' => '170px', 'type' => 'answer', 'id' => $post['post_id']]); ?>
<?= insert('/_block/form/editor', ['height' => '170px', 'type' => 'comment', 'id' => $post['post_id']]); ?>
<div class="clear mt5">
<input type="hidden" name="post_id" value="<?= $post['post_id']; ?>">
<input type="hidden" name="answer_id" value="0">
<input type="hidden" name="comment_id" value="0">
<?= Html::sumbit(__('app.reply')); ?>
</div>
</form>
@ -246,9 +246,9 @@ $blog = $data['blog'][0] ?? null;
<?php foreach ($data['recommend'] as $rec_post) : ?>
<div class="mb15 hidden flex gap text-sm">
<a class="gray" href="<?= post_slug($rec_post['post_id'], $rec_post['post_slug']); ?>">
<?php if ($rec_post['post_answers_count'] > 0) : ?>
<?php if ($rec_post['post_comments_count'] > 0) : ?>
<div class="box-small bg-green">
<?= $rec_post['post_answers_count'] ?>
<?= $rec_post['post_comments_count'] ?>
</div>
<?php else : ?>
<div class="box-small bg-lightgray">0</div>

View File

@ -27,8 +27,8 @@ $sw = $sw ?? '?';
if ($type == 'website') {
$url_content = $result['item_url'];
} elseif ($type == 'answer') {
$url_content = post_slug($result['post_id'], $result['post_slug']) . '#answer_' . $result['answer_id'];
} elseif ($type == 'comment') {
$url_content = post_slug($result['post_id'], $result['post_slug']) . '#comment_' . $result['comment_id'];
} else {
$url_content = '/post/' . $result['post_id'];
}
@ -49,9 +49,8 @@ $sw = $sw ?? '?';
<a class="gray-600 ml15" href="<?= url('website', ['id' => $result['item_id'], 'slug' => $result['item_slug']]); ?>"><?= __('web.more'); ?></a>
</div>
<?= fragment($result['content'], 250); ?>
<?php elseif ($type == 'answer') : ?>
<?= fragment($result['answer_content'], 250); ?>
<?php elseif ($type == 'comment') : ?>
<?= fragment($result['comment_content'], 250); ?>
<?php else : ?>
<div>
<?= Html::facets($result['facet_list'], 'topic', 'tag mr15'); ?>

View File

@ -55,13 +55,13 @@
</a>
</div>
<?php else : ?>
<a href="<?= post_slug($fav['post']['post_id'], $fav['post']['post_slug']); ?>#answer_<?= $fav['answer_id']; ?>">
<a href="<?= post_slug($fav['post']['post_id'], $fav['post']['post_slug']); ?>#comment_<?= $fav['comment_id']; ?>">
<?= $fav['post']['post_title']; ?>
</a>
<?php endif; ?>
<?php if ($fav['action_type'] == 'answer') : ?>
<div> <?= markdown($fav['answer_content'], 'text'); ?></div>
<?php if ($fav['action_type'] == 'comment') : ?>
<div> <?= markdown($fav['comment_content'], 'text'); ?></div>
<?php endif; ?>
<?php if ($fav['tag_id']) : ?>

View File

@ -8,7 +8,7 @@
<div class="mb15"><?= __('app.comments'); ?> <b><?= $data['profile']['login']; ?></b></div>
<?php if (!empty($data['comments'])) : ?>
<div class="box">
<?= insert('/content/comment/comment', ['comments' => $data['comments']]); ?>
<?= insert('/content/comments/comment', ['comments' => $data['comments']]); ?>
<?= Html::pagination($data['pNum'], $data['pagesCount'], false, '/@' . $data['profile']['login'] . '/comments'); ?>
</div>
<?php else : ?>

View File

@ -1,4 +1,4 @@
<?php if ($count['count_posts'] + $count['count_answers'] + $count['count_comments'] > 0) : ?>
<?php if ($count['count_posts'] + $count['count_comments'] > 0) : ?>
<div class="delet-count">
<?= __('app.deleted'); ?>:
@ -6,10 +6,6 @@
<span><?= __('app.posts'); ?> <?= $count['count_posts']; ?></span>
<?php endif; ?>
<?php if ($count['count_answers'] > 0) : ?>
<span><?= __('app.answers'); ?> <?= $count['count_answers']; ?></span>
<?php endif; ?>
<?php if ($count['count_comments'] > 0) : ?>
<span><?= __('app.comments'); ?> <?= $count['count_comments']; ?></span>
<?php endif; ?>

View File

@ -85,12 +85,10 @@ endif;
</div>
<?php endif; ?>
<?php $comentsCount = $data['counts']['count_comments'] + $data['counts']['count_answers']; ?>
<?php if ($comentsCount > 0) : ?>
<?php if ($data['counts']['count_comments'] > 0) : ?>
<div class="ml15 mr15 center box-number">
<a class="focus-user sky" href="<?= url('profile.comments', ['login' => $profile['login']]); ?>">
<?= Html::formatToHuman($comentsCount); ?>
<?= Html::formatToHuman($data['counts']['count_comments']); ?>
</a>
<div class="uppercase mt5 text-sm gray-600"><?= __('app.comments'); ?></div>
</div>

View File

@ -25,11 +25,11 @@
</a>
<div class="text-sm mt5 gray-600 lowercase">
<?= $data['my_post']['post_date'] ?>
<?php if ($data['my_post']['post_answers_count'] != 0) : ?>
<?php if ($data['my_post']['post_comments_count'] != 0) : ?>
<span class="right">
<svg class="icons">
<use xlink:href="/assets/svg/icons.svg#comments"></use>
</svg> <?= $data['my_post']['post_answers_count']; ?>
</svg> <?= $data['my_post']['post_comments_count']; ?>
</span>
<?php endif; ?>
</div>

View File

@ -21,7 +21,7 @@ h5 {
display: none;
font-size: .72rem;
color: #fff;
background-color: red;
background-color: var(--red);
padding: 1px 6px;
border-radius: 50%;
position: absolute;
@ -30,9 +30,7 @@ h5 {
}
.number-notif.show,
.video-pl {
display: block;
}
.video-pl { display: block; }
/* См. https://feathericons.com/ и https://tabler-icons.io/ */
.icons {
@ -53,9 +51,7 @@ h5 {
height: 48px;
}
.icon-small {
width: 15px;
}
.icon-small { width: 15px; }
.list-none {
list-style: none;
@ -75,9 +71,7 @@ h5 {
margin-bottom: 15px;
}
.medium-zoom--opened .d-header {
display: none;
}
.medium-zoom--opened .d-header { display: none; }
.banner {
background-image: url(/assets/images/banner-fon.jpg);
@ -133,7 +127,7 @@ h5 {
.box-results {
position: absolute;
border-radius: 3px;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, .15);
box-shadow: 0 2px 4px -1px rgba(0,0,0,.15);
background-color: var(--white);
padding: 15px;
z-index: 2;
@ -158,9 +152,7 @@ h5 {
vertical-align: middle;
}
.d-header.scroll-hide-search.show .box-search {
display: none;
}
.d-header.scroll-hide-search.show .box-search { display: none; }
.box-logo {
width: 209px;
@ -177,9 +169,7 @@ h5 {
text-overflow: ellipsis;
}
aside {
width: 340px;
}
aside { width: 340px; }
aside ul {
list-style: none;
@ -188,13 +178,11 @@ aside ul {
font-size: 0.9375rem;
}
aside ul a {
color: var(--gray);
}
aside ul a { color: var(--gray); }
blockquote {
margin-left: 15px;
background-color: #f3f3f6;
background-color: var(--blockquote-bg);
padding: 0.1rem 1rem;
border-left: 3px solid #d2d6dd;
display: table;
@ -206,12 +194,10 @@ blockquote {
word-wrap: break-word;
padding: 0.1rem 1rem;
border-left: 3px solid #d2d6dd;
font-size: .91rem
font-size:.91rem
}
.blockquote-profile p {
margin: 2px;
}
.blockquote-profile p { margin: 2px; }
hr {
border: none;
@ -233,7 +219,7 @@ summary {
font-size: 14px;
}
details[open]>summary {
details[open] > summary {
padding: 0 0 10px 0;
color: #666;
}
@ -305,9 +291,7 @@ details[open]>summary {
padding: 0.5rem 0;
}
ul.last-content li {
margin-bottom: 15px;
}
ul.last-content li { margin-bottom: 15px; }
ul.last-content a.last-content_telo {
display: block;
@ -323,44 +307,82 @@ ul.last-content a.last-content_telo {
}
.trigger img,
a:hover>img {
opacity: 0.8;
}
a:hover > img { opacity: 0.8; }
.focus-id:hover {
cursor: pointer
}
.underline-hover:hover {
text-decoration: underline;
}
.focus-id:hover { cursor: pointer }
.underline-hover:hover { text-decoration: underline; }
.content-body {
max-width: 810px;
overflow-wrap: break-word;
}
.content_tree {
word-wrap: break-word;
margin: 5px;
}
.content_tree:target,
.content_tree.edit {
background-clip: content-box;
background-color: lightyellow;
margin-top: -70px;
padding-top: 70px;
}
ol.bg-red-200 {
display: table;
width: 100%;
.comment-telo {
margin: 20px 5px 20px 0;
list-style: none;
padding: 0;
}
.comment-level-1 {
width: 32px;
}
.comment-level-2 {
width: 52px;
}
.comment-level-3 {
width: 72px;
}
.comment-level-4 {
width: 92px;
}
.comment-level-5 {
width: 112px;
}
.comment-level-left-1 {
margin-left: 36px;
}
.comment-level-left-2 {
margin-left: 56px;
}
.comment-level-left-3 {
margin-left: 76px;
}
.comment-level-left-4 {
margin-left: 96px;
}
.comment-level-left-5 {
margin-left: 116px;
}
.comment-thread {
border: 0;
padding: 0;
height: 100%;
}
.qa-comment {
font-size: 0.875rem;
padding: 0.24rem 0;
}
.bg-red-200 .content_tree,
.content_tree.bg-red-200 {
background-color: var(--red-200);
}
.content_tree.bg-red-200 { background-color: var(--red-200); }
.ind-first-p p {
margin: 0.5em 0;
@ -372,14 +394,7 @@ article iframe {
max-height: 320px;
}
video {
max-width: 560px;
}
.qa-comment {
font-size: 0.875rem;
padding: 0.24rem 0;
}
video { max-width: 560px; }
.showPassword {
position: absolute;
@ -394,8 +409,8 @@ video {
}
.scroll-menu::-webkit-scrollbar {
width: 0;
height: 0
width:0;
height:0
}
.scroll-wrapper {
@ -425,34 +440,17 @@ video {
*
* Иконки, поделиться
*/
.icon-share {
color: #fff;
height: 28px;
width: 28px;
margin: 3px;
}
.bg-vk {
background-color: #07f;
}
.bg-ok {
background-color: #eb722e;
}
.bg-tg {
background-color: #64a9dc;
}
.bg-fb {
background-color: #3b5998;
}
.bg-lj {
background-color: #0d425a;
}
.bg-tw {
background-color: #00aced;
}
.bg-vk { background-color: #07f; }
.bg-ok { background-color: #eb722e; }
.bg-tg { background-color: #64a9dc; }
.bg-fb { background-color: #3b5998; }
.bg-lj { background-color: #0d425a; }
.bg-tw { background-color: #00aced; }

View File

@ -41,6 +41,6 @@
margin: 10px 0 10px 45px;
}
.block-answer .right {
.block-comment .right {
float: left;
}

View File

@ -49,6 +49,8 @@ body.dark {
--footer-text-color: #eee;
--footer-color-active: #ccc;
--blockquote-bg: #2e3d49;
/* Colors used */
--black: #fff;
--white: #161f27;
@ -81,7 +83,22 @@ body.dark .content_tree.edit {
background-color: var(--form-bg-color);
}
body.dark .content_tree {
word-wrap: break-word;
box-shadow: 0 15px 25px rgba(0,0,0,.1);
padding: 5px;
}
body.dark blockquote {
background-color: #5f5f67;
background-color: var(--blockquote-bg);
border-left: 3px solid #6d6e6f;
}
body.dark :not(pre)>code[class*=language-], pre[class*=language-] {
background: var(--blockquote-bg);
}
body.dark code[class*=language-], pre[class*=language-] {
color: #eee;
text-shadow: none;
}

View File

@ -52,6 +52,8 @@
--footer-box-shadow: 0 -5px 5px -5px rgb(0 0 0 / 15%);
--footer-text-color: #9ca3af;
--footer-color-active: #332f2f;
--blockquote-bg: #f3f3f6;
/* Colors used */
--black: #030303;

View File

@ -74,8 +74,8 @@ $q = $data['q'];
<li<?php if ($uri == 'post') : ?> class="active" <?php endif; ?>>
<a href="<?= url('search.go'); ?>?q=<?= $q; ?>&cat=post"><?= __('search.posts'); ?></a>
</li>
<li<?php if ($uri == 'answer') : ?> class="active" <?php endif; ?>>
<a href="<?= url('search.go'); ?>?q=<?= $q; ?>&cat=answer"><?= __('search.answers'); ?></a>
<li<?php if ($uri == 'comment') : ?> class="active" <?php endif; ?>>
<a href="<?= url('search.go'); ?>?q=<?= $q; ?>&cat=comment"><?= __('search.comments'); ?></a>
</li>
<li<?php if ($uri == 'website') : ?> class="active" <?php endif; ?>>
<a href="<?= url('search.go'); ?>?q=<?= $q; ?>&cat=website"><?= __('search.websites'); ?></a>

View File

@ -59,25 +59,6 @@ isIdEmpty('colorPicker').onclick = function () {
}, false);
}
// Call the form for adding / edit a reply
reply.forEach(el => el.addEventListener("click", function (e) {
let reply = document.querySelector('#reply_addentry' + el.dataset.id);
fetch("/reply/" + el.dataset.type, {
method: "POST",
body: "id=" + el.dataset.id + "&item_id=" + el.dataset.item_id + "&_token=" + token,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(response => response.text())
.then(text => {
reply.classList.add("block");
reply.innerHTML = text;
queryAll("#cancel_comment")
.forEach(el => el.addEventListener("click", function (e) {
reply.classList.remove("block");
}));
});
}));
// Up
queryAll(".up-id")
.forEach(el => el.addEventListener("click", function (e) {
@ -164,13 +145,13 @@ queryAll(".add-ignore")
}));
// Choice of Best Answer
queryAll(".answer-best")
// Choice of Best Comment
queryAll(".comment-best")
.forEach(el => el.addEventListener("click", function (e) {
fetch("/best", {
method: "POST",
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: "answer_id=" + el.dataset.id + "&_token=" + token,
body: "comment_id=" + el.dataset.id + "&_token=" + token,
})
.then(response => response.text())
.then(text => {
@ -209,35 +190,6 @@ queryAll("#graburl")
})
}));
// Edit comment
queryAll(".editcomm")
.forEach(el => el.addEventListener("click", function (e) {
let comment_id = el.dataset.comment_id;
let comment = document.querySelector('#insert_id_' + el.dataset.comment_id);
fetch("/comment/editform", {
method: "POST",
body: "comment_id=" + comment_id,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(
response => {
return response.text();
}
).then(
text => {
getById("comment_" + comment_id).classList.add("edit");
comment.classList.add("block");
comment.innerHTML = text;
queryAll("#cancel_comment")
.forEach(el => el.addEventListener("click", function (e) {
comment.classList.remove("block");
}));
}
);
}));
// Add post tab
const tabs_post = document.querySelector(".tabs-post");
if (tabs_post) {

View File

@ -67,4 +67,23 @@ function fetchSearchUrl() {
}
}
);
}
}
// Call the form for adding / edit a reply
reply.forEach(el => el.addEventListener("click", function (e) {
let reply = document.querySelector('#reply_addentry' + el.dataset.id);
fetch("/reply/" + el.dataset.type, {
method: "POST",
body: "id=" + el.dataset.id + "&item_id=" + el.dataset.item_id + "&_token=" + token,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(response => response.text())
.then(text => {
reply.classList.add("block");
reply.innerHTML = text;
queryAll("#cancel_comment")
.forEach(el => el.addEventListener("click", function (e) {
reply.classList.remove("block");
}));
});
}));

View File

@ -18,19 +18,19 @@ let token = document.querySelector("meta[name='csrf-token']").getAttribute("cont
queryAll(".add-comment")
.forEach(el => el.addEventListener("click", function (e) {
let answer_id = insert_id = el.dataset.answer_id;
let comment_id = el.dataset.comment_id;
let comment_id = insert_id = el.dataset.comment_id;
let post_id = el.dataset.post_id;
if (comment_id) {
insert_id = el.dataset.comment_id;
if (post_id) {
insert_id = el.dataset.post_id;
}
let comment = document.querySelector('#insert_id_' + insert_id);
comment.classList.add("block");
fetch("/comments/addform", {
fetch("/comment/addform", {
method: "POST",
body: "answer_id=" + answer_id + "&comment_id=" + comment_id + "&_token=" + token,
body: "post_id=" + post_id + "&comment_id=" + comment_id + "&_token=" + token,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(
@ -301,8 +301,7 @@ if (tabs) {
element.classList.remove("pointer");
}
}
}
}
/* MIT license https://github.com/vivekweb2013/toastmaker */
(function (global, factory) {
if (typeof define === "function" && define.amd) {

View File

@ -10,7 +10,7 @@
<body>
<main class="box mr-auto max-w780">
<h1 class="text-3xl gray"><?= __('off.maintenance'); ?></h1>
<h1 class="text-3xl gray"><?= __('off.under_maintenance'); ?></h1>
<p class="gray-600"><?= __('off.under_reconstruction'); ?>...</p>
<form class="max-w300" action="/login" method="post">

View File

@ -35,10 +35,11 @@ body.dark ul.nav > li.active {
color: #fff;
}
ul.nav > li.active > a { color: var(--nav-color-active); }
.user-nav li:hover, .menu li.active, .menu li:hover { background-color: var(--nav-bg-active); }
.user-nav li:hover,
.menu li.active,
.menu li:hover { background-color: var(--nav-bg-active); }
.active { color: #eab308; }
.menu .active .icons { stroke: #eab308; }

View File

@ -123,7 +123,7 @@ $post = $data['post'];
<div class="clear mb15">
<input type="hidden" name="post_id" value="<?= $post['post_id']; ?>">
<input type="hidden" name="answer_id" value="0">
<input type="hidden" name="comment_id" value="0">
<?= Html::sumbit(__('app.reply')); ?>
</div>
</form>

View File

@ -28,10 +28,10 @@
<div class="gray-600 lowercase text-sm">
<?= Html::langDate($post['post_date']); ?>
</div>
<?php if ($post['post_answers_count'] != 0) : ?>
<?php if ($post['post_comments_count'] != 0) : ?>
<span class="gray-600">&#183;</span>
<a class="flex lowercase gray-600" href="<?= $post_url; ?>#comment">
<?= Html::numWord($post['post_answers_count'] + $post['post_comments_count'], __('app.num_answer'), true); ?>
<?= Html::numWord($post['post_comments_count'], __('app.num_comment'), true); ?>
</a>
<?php endif; ?>
</div>

View File

@ -50,7 +50,7 @@
<?php endif; ?>
<div class="sticky top-sm">
<?= insert('/_block/latest-answers-tabs', ['latest_answers' => $data['latest_answers']]); ?>
<?= insert('/_block/latest-comments-tabs', ['latest_answers' => $data['latest_answers']]); ?>
<?php if (UserData::getUserScroll()) : ?>
<?= insert('/global/sidebar-footer'); ?>

View File

@ -21,10 +21,9 @@ use Hleb\Constructor\Handlers\Request; ?>
<?php $bg_url = $post['post_url_domain'] == NULL ? '' : ' bg-blue'; ?>
<div class="box-answer<?= $bg; ?><?= $bg_url; ?>">
<a class="block white" href="<?= $post_url; ?>#comment">
<?php $anw = $post['post_answers_count'] + $post['post_comments_count'];
echo $anw; ?>
<?= $post['post_comments_count']; ?>
</a>
<div class="text-xs white"> <?= Html::numWord($anw, __('app.num_answer'), false); ?></div>
<div class="text-xs white"> <?= Html::numWord($anw, __('app.num_comment'), false); ?></div>
</div>
</div>

View File

@ -5,7 +5,6 @@ Route::before('Designator', [UserData::USER_FIRST_LEVEL, '>='])->getGroup();
Route::post('/backend/upload/{type}/{id}')->controller('Post\EditPostController@uploadContentImage')->where(['type' => '[a-z-]+', 'id' => '[0-9]+']);
Route::post('/status/action')->controller('ActionController@deletingAndRestoring');
Route::post('/post/grabtitle')->controller('Post\AddPostController@grabMeta');
Route::post('/comment/editform')->controller('Comment\EditCommentController');
Route::post('/reply/editform')->controller('Item\ReplyController');
// @ users | posts | topics | category
Route::post('/search/{type}')->controller('SearchController@select')->where(['type' => '[a-z]+']);
@ -80,7 +79,7 @@ Route::before('Designator', [UserData::USER_ZERO_LEVEL, '='])->getGroup();
Route::endGroup();
Route::getProtect();
Route::post('/comments/addform')->controller('Comment\AddCommentController');
Route::post('/comment/addform')->controller('Comment\AddCommentController');
Route::post('/reply/addform')->controller('Item\ReplyController@addForma');
Route::endProtect();

View File

@ -1,7 +1,6 @@
<?php
Radjax\Route::get("/search/api", ["post"], "App\Controllers\SearchController@api", ["protected" => true, "session_saved" => false]);
Radjax\Route::get("/more/comments", ["post"], "App\Controllers\Comment\CommentController@lastComment", ["protected" => true, "session_saved" => false]);
$access = 'App\Middleware\Before\UserAuth@index';
Radjax\Route::get("/post/profile", ["post"], "App\Controllers\Post\PostController@postProfile", ["protected" => true, "before" => $access]);
@ -16,6 +15,6 @@ Radjax\Route::get("/votes", ["post"], "App\Services\Votes", ["protected" => true
Radjax\Route::get("/poll", ["post"], "App\Controllers\Poll\PollController@vote", ["protected" => true, "before" => $access]);
Radjax\Route::get("/favorite", ["post"], "App\Services\Favorite", ["protected" => true, "before" => $access]);
Radjax\Route::get("/ignored", ["post"], "App\Services\Ignored", ["protected" => true, "before" => $access]);
Radjax\Route::get("/best", ["post"], "App\Services\AnswerBest", ["protected" => true, "before" => $access]);
Radjax\Route::get("/best", ["post"], "App\Services\CommentBest", ["protected" => true, "before" => $access]);
Radjax\Route::get("/flag/repost", ["post"], "App\Services\Audit", ["protected" => true, "before" => $access]);
Radjax\Route::get("/notif", ["post"], "App\Controllers\NotificationController@get", ["protected" => false, "before" => $access]);