243 lines
7.6 KiB
PHP
243 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace KupShop\CommentsBundle\Util;
|
|
|
|
use KupShop\CommentsBundle\Comment;
|
|
use KupShop\CommentsBundle\Email\AdminNotificationCommentEmail;
|
|
use KupShop\CommentsBundle\Email\CommentEmail;
|
|
use KupShop\CommentsBundle\Email\UserNotificationCommentEmail;
|
|
use KupShop\CommentsBundle\Exception\CommentException;
|
|
use KupShop\KupShopBundle\Context\ContextManager;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use KupShop\KupShopBundle\Context\UserContext;
|
|
use KupShop\KupShopBundle\Util\Entity\EntityUtil;
|
|
use KupShop\KupShopBundle\Util\Mail\EmailLocator;
|
|
|
|
class CommentsUtil
|
|
{
|
|
private $emailLocator;
|
|
|
|
private $languageContext;
|
|
|
|
private $userContext;
|
|
|
|
private $contextManager;
|
|
|
|
private $entityUtil;
|
|
|
|
public function __construct(
|
|
EmailLocator $emailLocator,
|
|
LanguageContext $languageContext,
|
|
UserContext $userContext,
|
|
ContextManager $contextManager,
|
|
EntityUtil $entityUtil,
|
|
) {
|
|
$this->emailLocator = $emailLocator;
|
|
$this->languageContext = $languageContext;
|
|
$this->userContext = $userContext;
|
|
$this->contextManager = $contextManager;
|
|
$this->entityUtil = $entityUtil;
|
|
}
|
|
|
|
public function addComment(
|
|
int $objectId,
|
|
string $type,
|
|
string $content,
|
|
?int $parentId = null,
|
|
?int $userId = null,
|
|
?string $languageId = null,
|
|
?int $adminId = null,
|
|
int $status = Comment::STATUS_UNCONFIRMED,
|
|
): Comment {
|
|
if (!$languageId) {
|
|
$languageId = $this->languageContext->getActiveId();
|
|
}
|
|
|
|
$solved = Comment::SOLVED_NO;
|
|
if (!$userId && !$adminId) {
|
|
if (!($userId = $this->userContext->getActiveId())) {
|
|
$admin = getAdminUser();
|
|
if (!($adminId = ($admin['id'] ?? false))) {
|
|
throw new CommentException('User is not logged in and \'$userId\' or \'$adminId\' is not specified!');
|
|
}
|
|
}
|
|
}
|
|
|
|
// set co confirmed and solved if comment added by admin
|
|
if ($adminId) {
|
|
$status = Comment::STATUS_CONFIRMED;
|
|
$solved = Comment::SOLVED_YES;
|
|
}
|
|
|
|
if (empty($content)) {
|
|
throw new CommentException('Empty \'$content\' given. Content cannot be empty!');
|
|
}
|
|
|
|
$comment = sqlGetConnection()->transactional(
|
|
function () use (
|
|
$parentId,
|
|
$languageId,
|
|
$type,
|
|
$objectId,
|
|
$userId,
|
|
$adminId,
|
|
$content,
|
|
$status,
|
|
$solved
|
|
) {
|
|
sqlQueryBuilder()
|
|
->insert('comments')
|
|
->directValues(
|
|
[
|
|
'id_parent' => $parentId,
|
|
'id_language' => $languageId,
|
|
$this->getObjectField($type) => $objectId,
|
|
'id_user' => $userId,
|
|
'id_admin' => $adminId,
|
|
'content' => $content,
|
|
'status' => $status,
|
|
'solved' => $solved,
|
|
]
|
|
)->execute();
|
|
|
|
$id = sqlInsertId();
|
|
|
|
if ($userId) {
|
|
$userGroup = match ($type) {
|
|
'product' => 'Komentáře k produktům',
|
|
'article' => 'Komentáře k článkům',
|
|
default => 'Komentáře k '.$type,
|
|
};
|
|
sqlQuery("INSERT INTO users_groups (name) VALUES ('{$userGroup}') ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)");
|
|
$groupId = sqlInsertID();
|
|
sqlQuery("INSERT IGNORE INTO users_groups_relations (id_group, id_user) VALUES ('{$groupId}', '{$userId}')");
|
|
}
|
|
|
|
return $this->getCommentById((int) $id);
|
|
}
|
|
);
|
|
|
|
$this->sendEmail($comment);
|
|
|
|
return $comment;
|
|
}
|
|
|
|
public function getCommentById(int $id): ?Comment
|
|
{
|
|
// nactu i parenty a children pridaneho komentare - abych byl schopny si getnout parenta, childa...
|
|
$comments = sqlQuery('WITH RECURSIVE ancestors as (
|
|
SELECT * FROM comments WHERE id = :id
|
|
UNION
|
|
SELECT c.* FROM comments c, ancestors a WHERE (a.id_parent = c.id) OR (a.id = c.id_parent)
|
|
) SELECT * FROM ancestors;', ['id' => $id])->fetchAll();
|
|
|
|
if (!$comments) {
|
|
return null;
|
|
}
|
|
|
|
// vytvorim strukturu
|
|
$comments = $this->buildCommentsTree(
|
|
$this->loadComments($comments)
|
|
);
|
|
$comment = reset($comments);
|
|
if (!$comment) {
|
|
return null;
|
|
}
|
|
|
|
// najdu ten jeden konkretni komentar
|
|
while ($comment->getId() !== $id && $children = $comment->getChildren()) {
|
|
$comment = reset($children);
|
|
}
|
|
|
|
return $comment;
|
|
}
|
|
|
|
public function loadComments(array $comments): array
|
|
{
|
|
$result = [];
|
|
|
|
foreach ($comments as $item) {
|
|
$result[] = $this->entityUtil->createEntity($item, Comment::class);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function buildCommentsTree(array $comments, ?Comment $parent = null): array
|
|
{
|
|
$tree = [];
|
|
|
|
$parentId = null;
|
|
if ($parent) {
|
|
$parentId = $parent->getId();
|
|
}
|
|
|
|
/** @var Comment $item */
|
|
foreach ($comments as $index => $item) {
|
|
if ((!$parentId && !$item->getIdParent()) || $item->getIdParent() === $parentId) {
|
|
unset($comments[$index]);
|
|
$children = $this->buildCommentsTree($comments, $item);
|
|
if (count($children) > 0) {
|
|
$item->setChildren($children);
|
|
}
|
|
if ($parent) {
|
|
$item->setParent($parent);
|
|
}
|
|
$tree[] = $item;
|
|
}
|
|
}
|
|
|
|
return $tree;
|
|
}
|
|
|
|
public function getObjectField(string $type): string
|
|
{
|
|
return 'id_'.$type;
|
|
}
|
|
|
|
protected function sendEmail(Comment $comment): void
|
|
{
|
|
$this->contextManager->activateContexts([LanguageContext::class => $comment->getIdLanguage()], function () use ($comment) {
|
|
if (!$comment->getIdAdmin()) {
|
|
$dbcfg = \Settings::getDefault();
|
|
$shopkeeperEmail = $dbcfg->comments['shopkeeper_email'] ?? false;
|
|
if (!empty($shopkeeperEmail)) {
|
|
$this->doSendEmail($comment, AdminNotificationCommentEmail::getType(), $shopkeeperEmail);
|
|
}
|
|
}
|
|
|
|
if ($comment->getIdParent()) {
|
|
$emails = $this->getUsersEmails($comment);
|
|
if (!empty($emails)) {
|
|
$this->doSendEmail($comment, UserNotificationCommentEmail::getType(), implode(',', $emails));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private function doSendEmail(Comment $comment, string $type, string $to): bool
|
|
{
|
|
/** @var CommentEmail $email */
|
|
$email = $this->emailLocator->getEmailService($type);
|
|
$email->setComment($comment);
|
|
|
|
$message = $email->getEmail();
|
|
$message['to'] = $to;
|
|
|
|
return $email->sendEmail($message);
|
|
}
|
|
|
|
private function getUsersEmails(Comment $comment): array
|
|
{
|
|
$return = [];
|
|
|
|
do {
|
|
if ($user = $comment->getUser()) {
|
|
$return[] = $user->email;
|
|
}
|
|
} while ($comment = $comment->getParent());
|
|
|
|
return array_unique($return);
|
|
}
|
|
}
|