Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions Web/Models/Entities/FAQArticle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Entities;
use openvk\Web\Models\Repositories\FAQCategories;
use openvk\Web\Models\RowModel;

class FAQArticle extends RowModel
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

мб отдельную папку для этого

{
protected $tableName = "faq_articles";

function getId(): int
{
return $this->getRecord()->id;
}

function getTitle(): string
{
return $this->getRecord()->title;
}

function getText(): string
{
return $this->getRecord()->text;
}

function canSeeByUnloggedUsers(): bool
{
return (bool) $this->getRecord()->unlogged_can_see;
}

function canSeeByUsers(): bool
{
return (bool) $this->getRecord()->users_can_see;
}

function getCategory(): ?FAQCategory
{
return (new FAQCategories)->get($this->getRecord()->category);
}

function getLanguage(): string
{
return $this->getRecord()->language;
}
}
50 changes: 50 additions & 0 deletions Web/Models/Entities/FAQCategory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Entities;
use openvk\Web\Models\RowModel;
use Chandler\Database\DatabaseConnection;

class FAQCategory extends RowModel
{
protected $tableName = "faq_categories";

function getId(): int
{
return $this->getRecord()->id;
}

function getTitle(): string
{
return $this->getRecord()->title;
}

function canSeeByUsers(): bool
{
return (bool) !$this->getRecord()->for_agents_only;
}

function getIconBackgroundPosition(): int
{
return 28 * $this->getRecord()->icon;
}

function getArticles(?int $limit = NULL, $isAgent): \Traversable
{
$filter = ["category" => $this->getId(), "deleted" => 0];
if (!$isAgent) $filter["users_can_see"] = 1;

$articles = DatabaseConnection::i()->getContext()->table("faq_articles")->where($filter)->limit($limit);
foreach ($articles as $article) {
yield new FAQArticle($article);
}
}

function getIcon(): int
{
return $this->getRecord()->icon;
}

function getLanguage(): string
{
return $this->getRecord()->language;
}
}
27 changes: 27 additions & 0 deletions Web/Models/Repositories/FAQArticles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Repositories;
use Chandler\Database\DatabaseConnection;
use Nette\Database\Table\ActiveRow;
use openvk\Web\Models\Entities\FAQArticle;

class FAQArticles
{
private $context;
private $articles;

function __construct()
{
$this->context = DatabaseConnection::i()->getContext();
$this->articles = $this->context->table("faq_articles");
}

function toFAQArticle(?ActiveRow $ar): ?FAQArticle
{
return is_null($ar) ? NULL : new FAQArticle($ar);
}

function get(int $id): ?FAQArticle
{
return $this->toFAQArticle($this->articles->get($id));
}
}
37 changes: 37 additions & 0 deletions Web/Models/Repositories/FAQCategories.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types=1);
namespace openvk\Web\Models\Repositories;
use Chandler\Database\DatabaseConnection;
use Nette\Database\Table\ActiveRow;
use openvk\Web\Models\Entities\FAQCategory;

class FAQCategories
{
private $context;
private $categories;

function __construct()
{
$this->context = DatabaseConnection::i()->getContext();
$this->categories = $this->context->table("faq_categories");
}

function toFAQCategory(?ActiveRow $ar): ?FAQCategory
{
return is_null($ar) ? NULL : new FAQCategory($ar);
}

function get(int $id): ?FAQCategory
{
return $this->toFAQCategory($this->categories->get($id));
}

function getList(string $language, bool $includeForAgents = false): \Traversable
{
$filter = ["deleted" => 0, "language" => $language];
if (!$includeForAgents) $filter["for_agents_only"] = 0;

foreach ($this->categories->where($filter) as $category) {
yield new FAQCategory($category);
}
}
}
198 changes: 196 additions & 2 deletions Web/Presenters/SupportPresenter.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php declare(strict_types=1);
namespace openvk\Web\Presenters;
use openvk\Web\Models\Entities\{SupportAgent, Ticket, TicketComment};
use openvk\Web\Models\Repositories\{Tickets, Users, TicketComments, SupportAgents};
use openvk\Web\Models\Entities\{FAQArticle, FAQCategory, SupportAgent, Ticket, TicketComment};
use openvk\Web\Models\Repositories\{FAQCategories, Tickets, Users, TicketComments, SupportAgents, FAQArticles};
use openvk\Web\Util\Telegram;
use Chandler\Session\Session;
use Chandler\Database\DatabaseConnection;
Expand All @@ -28,8 +28,12 @@ function renderIndex(): void
{
$this->assertUserLoggedIn();
$this->template->mode = in_array($this->queryParam("act"), ["faq", "new", "list"]) ? $this->queryParam("act") : "faq";
$canEdit = $this->user->identity->getChandlerUser()->can("write")->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0);

if($this->template->mode === "faq") {
$this->template->categories = (new FAQCategories)->getList($canEdit ? $this->queryParam("lang") ?? Session::i()->get("lang", "ru") : Session::i()->get("lang", "ru"), $canEdit);
$this->template->canEditFAQ = $canEdit;

$lang = Session::i()->get("lang", "ru");
$base = OPENVK_ROOT . "/data/knowledgebase/faq";
if(file_exists("$base.$lang.md"))
Expand Down Expand Up @@ -104,6 +108,9 @@ function renderIndex(): void
$this->flashFail("err", tr("error"), tr("you_have_not_entered_name_or_text"));
}
}

$this->template->languages = getLanguages();
$this->template->activeLang = $this->queryParam("lang") ?? Session::i()->get("lang", "ru");
}

function renderList(): void
Expand Down Expand Up @@ -396,4 +403,191 @@ function renderEditAgent(int $id): void
$this->flashFail("succ", "Успех", "Профиль создан. Теперь пользователи видят Ваши псевдоним и аватарку вместо стандартных аватарки и номера.");
}
}

function renderFAQArticle(int $id): void
{
$article = (new FAQArticles)->get($id);
if (!$article || $article->isDeleted())
$this->notFound();

$category = $article->getCategory();

if ($category->isDeleted())
$this->notFound();

if (!$article->canSeeByUnloggedUsers())
$this->assertUserLoggedIn();

if (!$category->canSeeByUsers() || (!$article->canSeeByUsers() && !$article->canSeeByUnloggedUsers()))
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);

$canEdit = false;
if ($this->user->identity)
$canEdit = $this->user->identity->getChandlerUser()->can("write")->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0);

if ($_SERVER["REQUEST_METHOD"] === "POST") {
$this->assertNoCSRF();
if (!$canEdit) {
$this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment"));
}

$cid = $this->postParam("category");
if ($this->postParam("language") != $article->getLanguage()) {
$categories = iterator_to_array((new FAQCategories)->getList($this->postParam("language")));
if (sizeof($categories) > 0) {
$cid = iterator_to_array((new FAQCategories)->getList($this->postParam("language")))[0]->getId();
} else {
$this->flashFail("err", tr("error"), tr("support_cant_change_lang_no_cats"));
}
}

$article->setTitle($this->postParam("title"));
$article->setText($this->postParam("text"));
$article->setUnlogged_Can_see(empty($this->postParam("unlogged_can_see") ? 0 : 1));
$article->setUsers_Can_See(empty($this->postParam("users_can_see") ? 0 : 1));
$article->setCategory($cid);
$article->setLanguage($this->postParam("language"));
$article->save();
$this->flashFail("succ", tr("changes_saved"));
} else {
$this->template->mode = $canEdit ? in_array($this->queryParam("act"), ["view", "edit"]) ? $this->queryParam("act") : "view" : "view";
$this->template->category = $category;
$this->template->article = $article;
$this->template->text = (new Parsedown())->text($article->getText());
$this->template->canEditFAQ = $canEdit;
$this->template->categories = (new FAQCategories)->getList($this->queryParam("lang") ?? $article->getLanguage(), TRUE);
$this->template->languages = getLanguages();
$this->template->activeLang = $this->queryParam("lang") ?? $article->getLanguage();
}
}

function renderFAQCategory(int $id): void
{
$category = (new FAQCategories)->get($id);

if (!$category)
$this->notFound();

if (!$category->canSeeByUsers())
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);

$canEdit = $this->user->identity->getChandlerUser()->can("write")->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0);

if ($_SERVER["REQUEST_METHOD"] === "POST") {
$this->assertNoCSRF();
if (!$canEdit) {
$this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment"));
}

if ($this->queryParam("mode") === "copy") {
$orig_cat = $category;
$category = new FAQCategory;
}

$category->setTitle($this->postParam("title"));
$category->setIcon($orig_cat->getIcon() ?? $this->postParam("icon"));
$category->setFor_Agents_Only(empty($this->postParam("for_agents_only") ? 0 : 1));
$category->setLanguage($this->postParam("language"));
$category->save();

if ($this->queryParam("mode") === "copy" && !empty($this->postParam("copy_with_articles"))) {
$articles = $orig_cat->getArticles(NULL, TRUE);
foreach ($articles as $article) {
$_article = new FAQArticle;
$_article->setCategory($category->getId());
$_article->setTitle($article->getTitle());
$_article->setText($article->getText());
$_article->setUsers_Can_See($article->canSeeByUsers());
$_article->setUnlogged_Can_See($article->canSeeByUnloggedUsers());
$_article->setLanguage($category->getLanguage());
$_article->save();
}
}

$this->flashFail("succ", tr("changes_saved"));
}

$this->template->mode = $canEdit ? in_array($this->queryParam("act"), ["view", "edit"]) ? $this->queryParam("act") : "view" : "view";
$this->template->copyMode = $canEdit ? $this->queryParam("mode") === "copy" : FALSE;
$this->template->category = $category;
$this->template->canEditFAQ = $canEdit;
$this->template->languages = getLanguages();
}

function renderFAQNewArticle(): void
{
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);

if ($_SERVER["REQUEST_METHOD"] === "POST") {
if (!$this->postParam("category"))
$this->flashFail("err", tr("support_category_not_specified"));

$article = new FAQArticle;
$article->setTitle($this->postParam("title"));
$article->setText($this->postParam("text"));
$article->setUnlogged_Can_see(empty($this->postParam("unlogged_can_see") ? 0 : 1));
$article->setUsers_Can_See(empty($this->postParam("users_can_see") ? 0 : 1));
$article->setCategory($this->postParam("category"));
$article->setLanguage(Session::i()->get("lang", "ru"));
$article->save();
$this->redirect("/faq" . $article->getId());
} else {
$this->template->categories = (new FAQCategories)->getList($this->queryParam("lang") ?? Session::i()->get("lang", "ru"), TRUE);
$this->template->category_id = $this->queryParam("cid");
$this->template->activeLang = $this->queryParam("lang") ?? Session::i()->get("lang", "ru");
$this->template->languages = getLanguages();
}
}

function renderFAQNewCategory(): void
{
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);

if ($_SERVER["REQUEST_METHOD"] === "POST") {
$category = new FAQCategory;
$category->setTitle($this->postParam("title"));
$category->setIcon($this->postParam("icon"));
$category->setFor_Agents_Only(empty($this->postParam("for_agents_only") ? 0 : 1));
$category->setLanguage($this->postParam("language"));
$category->save();
$this->redirect("/faqs" . $category->getId());
}

$this->template->activeLang = $this->queryParam("lang") ?? Session::i()->get("lang", "ru");
$this->template->languages = getLanguages();
}

function renderFAQDeleteArticle(int $id): void
{
$this->assertNoCSRF();
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);

$article = (new FAQArticles)->get($id);
if (!$article || $article->isDeleted())
$this->notFound();

$cid = $article->getCategory()->getId();
$article->delete();
$this->redirect("/faqs" . $cid);
}

function renderFAQDeleteCategory(int $id): void
{
$this->assertNoCSRF();
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);

$category = (new FAQCategories)->get($id);
if (!$category || $category->isDeleted())
$this->notFound();

if (!empty($this->postParam("delete_articles"))) {
$articles = $category->getArticles(NULL, TRUE);
foreach ($articles as $article) {
$article->delete();
}
}

$category->delete();
$this->redirect("/support");
}
}
Loading