<?php
namespace App\Controller\FrontApi;
use App\Controller\BaseAbstractApiController;
use App\Entity\Blog;
use App\Entity\Story;
use App\Entity\StoryComment;
use App\Entity\User;
use App\Enum\Banlist\Target;
use App\Enum\Story\Status;
use App\Enum\Site\Domain;
use App\Enum\Site\Lang;
use App\Service\Banlist\BanlistService;
use App\Service\Category\CategoryService;
use App\Service\Stories\StoryService;
use App\Service\User\UserService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Core\Security;
class StoryApiController extends BaseAbstractApiController
{
/**
* @var StoryService
*/
private $storiesService;
/**
* @var UserService
*/
private $userService;
/**
* @var BanlistService
*/
private $banlistService;
public function __construct(
RequestStack $requestStack,
Security $security,
EntityManagerInterface $em,
StoryService $storiesService,
UserService $userService,
BanlistService $banlistService
)
{
parent::__construct($requestStack, $security, $em);
$this->storiesService = $storiesService;
$this->userService = $userService;
$this->banlistService = $banlistService;
}
public function add()
{
$user = $this->security->getUser() ? $this->security->getUser()->getAssociatedUser() : null;
$domain = Domain::isWLDomainHasOwnContent($this->dataArray['original_domain'] ?? '') ? $this->dataArray['original_domain'] : $this->dataArray['domain'];
$story = (new Story())->setDomain($domain);
if ($user) {
$story->setUser($user);
}
$data = $this->dataArray['story'];
if (($data['id'] ?? 0) > 0) {
$story = $this->storiesService->get($data['id'], $domain);
if (isset($data['user'])) {
unset($data['user']);
}
}
if (isset($data['categories'])) {
foreach ($data['categories'] as $key => $categoryId) {
$category = $this->storiesService->getCategory($categoryId);
$story->addCategory($category);
unset($data['categories']);
}
}
if (isset($data['firstStoryCategoryId'])) {
$story->setFirstStoryCategory($data['firstStoryCategoryId']);
}
$story->fromArray($data);
$story->setDomain($domain);
$errors = [];
if (!$this->banlistService->checkText(
$story->getName(),
$story->getDomain(),
Target::TARGET_STORY,
true,
null,
false,
[],
$user ? $user->getId() : null,
($data['id'] ?? 0) > 0 ? $data['id'] : null
)) {
$errors['name'] = 'error_content_link_phone';
}
if (!$this->banlistService->checkText(
$story->getText(),
$story->getDomain(),
Target::TARGET_STORY,
true,
null,
false,
[],
$user ? $user->getId() : null,
($data['id'] ?? 0) > 0 ? $data['id'] : null
)) {
$errors['text'] = 'error_content_link_phone';
}
if (empty($errors)) {
$this->storiesService->update($story);
if (!$story->getId() || $story->getId() <= 0) {
$errors[] = 'Error';
} else {
$this->dataArray['story'] = $story->toArray();
}
}
return $this->json(['errors' => $errors, 'data' => $this->dataArray['story']]);
}
public function getCategories()
{
$lang = $this->dataArray['sys_locale'];
$domain = $this->dataArray['domain'];
$originalDomain = $this->dataArray['original_domain'];
$data = $this->storiesService->getCategories($domain, $originalDomain, $lang);
return $this->json($data);
}
public function getStory()
{
$domain = $this->dataArray['domain'];
$slug = $this->dataArray['slug'];
$lang = $this->dataArray['lang'];
$page = $this->dataArray['page'];
$perPage = $this->dataArray['perPage'];
$data = $this->storiesService->getBySlug($slug, $domain, $lang, $page, $perPage);
return $this->json($data);
}
public function getStoryById()
{
return $this->json($this->storiesService->getById($this->dataArray['id'], $this->dataArray['domain']) ?: []);
}
public function update()
{
$user = $this->security->getUser() ? $this->security->getUser()->getAssociatedUser() : null;
$domain = $this->dataArray['domain'];
$story = (new Story())->setDomain($domain);
if ($user) {
$story->setUser($user);
}
$data = $this->dataArray['story'];
if (($data['id'] ?? 0) > 0) {
$story = $this->storiesService->get($data['id'], $domain);
if ($story && isset($data['categories'])) {
$categoryIds = $this->storiesService->getCategoryIds($story->getCategories());
foreach ($data['categories'] as $newStoryCategory) {
if (!in_array($newStoryCategory, $categoryIds)) {
$category = $this->storiesService->getCategory($newStoryCategory);
if ($category) {
$story->addCategory($category);
}
}
}
foreach ($categoryIds as $oldStoryCategoryId) {
if (!in_array($oldStoryCategoryId, $data['categories'])) {
$oldCategory = $this->storiesService->getCategory($oldStoryCategoryId);
if ($oldCategory) {
$story->removeCategory($oldCategory);
}
}
}
if (isset($data['user'])) {
unset($data['user']);
}
}
}
if (isset($data['firstStoryCategoryId'])) {
$story->setFirstStoryCategory($data['firstStoryCategoryId']);
}
$story->fromArray($data);
$story->setDomain($domain);
if (!isset($data['id']) || !$data['id'] || $data['id'] <= 0) {
$story->setStatus(Status::STATUS_NEW);
}
$errors = [];
if (!$this->banlistService->checkText(
$story->getName(),
$story->getDomain(),
Target::TARGET_STORY,
true,
null,
false,
[],
$user ? $user->getId() : null,
($data['id'] ?? 0) > 0 ? $data['id'] : null
)) {
$errors['name'] = 'error_content_link_phone';
}
if (!$this->banlistService->checkText(
$story->getText(),
$story->getDomain(),
Target::TARGET_STORY,
true,
null,
false,
[],
$user ? $user->getId() : null,
($data['id'] ?? 0) > 0 ? $data['id'] : null
)) {
$errors['text'] = 'error_content_link_phone';
}
if (empty($errors)) {
$this->storiesService->update($story);
if (!$story->getId() || $story->getId() <= 0) {
$errors[] = 'Error';
} else {
$this->dataArray['story'] = $story->toArray();
if ($story->getUser()) {
$this->dataArray['story']['user'] = $story->getUser()->toArray();
}
}
}
return $this->json(['errors' => $errors, 'data' => $this->dataArray['story']]);
}
public function incViews()
{
if (getenv('APP_ENV') === 'dev') {
$story = $this->storiesService->get($this->dataArray['id'], $this->dataArray['domain']);
if ($story) {
$story->incViews();
$this->storiesService->update($story);
file_put_contents(getenv('RAMFSPATH') . '/incStory.cnt', $this->dataArray['id'] . '|', FILE_APPEND);
return $this->json(['views' => $story->getViews()]);
}
} else {
file_put_contents(getenv('RAMFSPATH') . '/incStory.cnt', $this->dataArray['id'] . '|', FILE_APPEND);
}
return $this->json([]);
}
public function map()
{
$sql = 'select slug, lang from story where status="active" and domain="'.$this->dataArray['domain'].'" order by id desc limit 0,1000';
$q = $this->getDoctrine()->getConnection()->prepare($sql);
$q->execute();
$result = [];
foreach ($q->fetchAll() as $item) {
$result[] = $item;
}
return $this->json($result);
}
public function random()
{
$domain = $this->dataArray['domain'];
$lang = $this->dataArray['lang'] ?: Lang::LANG_LV;
$skipId = $this->dataArray['skipId'] ?: 0;
$limit = $this->dataArray['limit'] ?: 3;
$data = $this->storiesService->getRandom($domain, $lang, $skipId, $limit);
return $this->json($data);
}
public function addComment()
{
/** @var Story $story */
$story = $this->storiesService->get($this->dataArray['storyId'], $this->dataArray['domain']);
/** @var User $user */
$user = $this->userService->get($this->dataArray['userId'], $this->dataArray['domain']);
$data = [];
if ($story && $user) {
$comment = new StoryComment();
$comment->setStory($story);
$comment->setUser($user);
$comment->setName($user->getUsername() ?: $user->getName() ?: 'Guest');
$comment->setStatus(Status::STATUS_ACTIVE);
$comment->setText($this->dataArray['text']);
$comment->setIp($this->dataArray['ip']);
$comment->setDomain($this->dataArray['domain']);
$this->storiesService->update($comment);
$isValid = $this->banlistService->checkText(
$this->dataArray['text'],
$this->dataArray['domain'],
Target::TARGET_STORY_COMMENT,
true,
null,
false,
[],
$user->getId(),
$comment->getId()
);
if (!$isValid) {
$comment->setStatus(Status::STATUS_DELETED);
$this->storiesService->update($comment);
}
$data = $comment->toArray();
$data['user'] = $comment->getUser()->toArray();
$data['storySlug'] = $comment->getStory()->getSlug();
}
return $this->json($data);
}
public function getNewSlug()
{
$id = (int)($this->dataArray['id'] ?? 0);
if ($id > 0) {
switch ($this->dataArray['type'] ?? '') {
case 'blog':
$sql = 'SELECT*FROM setting s WHERE s.name="k6blog-'.$id.'-new_id"';
$qTmp = $this->em->getConnection()->prepare($sql);
$qTmp->execute();
$tmp = $qTmp->fetch();
if (isset($tmp['value'])) {
$id = (int) unserialize($tmp['value']);
if ($id > 0) {
$sql = 'select slug from blog where id='.$id;
$qTmp = $this->em->getConnection()->prepare($sql);
$qTmp->execute();
$tmp = $qTmp->fetch();
if (isset($tmp['slug'])) {
return $this->json($tmp['slug']);
}
}
}
break;
case 'novel':
$sql = 'SELECT*FROM setting s WHERE s.name="k6story-'.$id.'-new_id"';
$qTmp = $this->em->getConnection()->prepare($sql);
$qTmp->execute();
$tmp = $qTmp->fetch();
if (isset($tmp['value'])) {
$id = (int) unserialize($tmp['value']);
if ($id > 0) {
$sql = 'select slug from story where id='.$id;
$qTmp = $this->em->getConnection()->prepare($sql);
$qTmp->execute();
$tmp = $qTmp->fetch();
if (isset($tmp['slug'])) {
return $this->json($tmp['slug']);
}
}
}
break;
default:
}
}
return $this->json('');
}
public function deleteComment()
{
/** @var StoryComment $comment */
$comment = $this->storiesService->getComment($this->dataArray['commentId'], $this->dataArray['domain']);
/** @var User $user */
$user = $this->userService->get($this->dataArray['userId'], $this->dataArray['domain']);
/** @var Story $story */
$story = $comment->getStory();
$storyOwner = $story ? $story->getUser() : null;
if ($comment && $user) {
$ownerStoryIsCorrect = $storyOwner && $storyOwner->getId() === $user->getId();
$userIdIsCorrect = $comment->getUser() && $comment->getUser()->getId() === $user->getId();
$isModer = $this->userService->isModer($user->getId(), $user->getDomain());
if ($userIdIsCorrect || $isModer || $ownerStoryIsCorrect) {
$comment->setStatus(Status::STATUS_DELETED);
$this->storiesService->update($comment);
return $this->json([
'status' => 'success',
'storySlug' => $comment->getStory() ? $comment->getStory()->getSlug() : null,
'storyLang' => $comment->getStory() ? $comment->getStory()->getLang() : null,
]);
}
}
return $this->json([
'status' => 'reject'
]);
}
public function delete()
{
$user = $this->security->getUser() ? $this->security->getUser()->getAssociatedUser() : null;
$story = $this->storiesService->get($this->dataArray['id']);
if (!$story || !$user || ($story->getUser()->getId() !== $user->getId() && !$this->userService->isModer($user->getId(), $user->getDomain()))) {
return $this->json([
'status' => 'reject'
]);
}
$story->setStatus(Status::STATUS_DELETED);
$this->storiesService->update($story);
$storyCategoryIds = $this->storiesService->getCategoryIds($story->getCategories());
return $this->json([
'status' => 'success',
'id' => $story->getId(),
'categories' => $storyCategoryIds ?? null,
'slug' => $story->getSlug(),
'lang' => $story->getLang(),
'authorUsername' => $story->getUser() ? $story->getUser()->getUsername() : null,
]);
}
public function prev()
{
$domain = $this->dataArray['domain'];
$lang = $this->dataArray['lang'];
$id = $this->dataArray['id'];
$data = $this->storiesService->getPrev($domain, $lang, $id);
return $this->json($data);
}
public function next()
{
$domain = $this->dataArray['domain'];
$lang = $this->dataArray['lang'];
$id = $this->dataArray['id'];
$data = $this->storiesService->getNext($domain, $lang, $id);
return $this->json($data);
}
public function getStories()
{
$data = $this->storiesService->getStoriesList(
$this->dataArray['page'],
$this->dataArray['perPage'],
$this->dataArray['domain'],
$this->dataArray['sort'],
$this->dataArray['sys_locale'],
$this->dataArray['categoryId'],
$this->dataArray['userId']
);
return $this->json($data);
}
public function getSoftStories()
{
$data = $this->storiesService->getSoftListByLang(
$this->dataArray['lang'],
$this->dataArray['domain'],
(int)$this->dataArray['cnt']
);
return $this->json($data);
}
public function getStoriesByCatsIds()
{
$domain = Domain::isWLDomainHasOwnContent($this->dataArray['original_domain'] ?? '') ? $this->dataArray['original_domain'] : $this->dataArray['domain'];
$data = $this->storiesService->getStoriesListBySeveralIds(
$this->dataArray['page'],
$this->dataArray['perPage'],
$domain,
$this->dataArray['sort'],
$this->dataArray['sys_locale'],
$this->dataArray['storyIds'],
);
return $this->json($data);
}
public function getStoriesSitemapData(): Response
{
$lang = $this->dataArray['sys_locale'];
$domain = $this->dataArray['domain'];
$storySql = "select id, name, slug, first_story_category_id from story where status='active' and domain='{$domain}' and lang='{$lang}' order by id desc limit 0,1000";
$storyQ = $this->getDoctrine()->getConnection()->prepare($storySql);
$storyQ->execute();
$storyResult = $storyQ->fetchAll();
$data = [];
foreach ($storyResult as $key => $story) {
if ($story['first_story_category_id'] === null || $story['first_story_category_id'] === '0') {
continue;
}
$data[] = $story;
unset($storyResult[$key]);
}
$ids = array_map(function ($item) {
return $item['id'];
}, $storyResult);
if (count($ids) > 0) {
$idsAsString = implode(', ', $ids);
$storyCategorySql = "select * from story_story_category where story_id in ({$idsAsString})";
$storyCategoryQ = $this->getDoctrine()->getConnection()->prepare($storyCategorySql);
$storyCategoryQ->execute();
$storyCategoryResult = $storyCategoryQ->fetchAll();
} else {
$storyCategoryResult = [];
}
foreach ($storyResult as $story) {
foreach ($storyCategoryResult as $storyCategoryItem) {
if ($story['id'] === $storyCategoryItem['story_id']) {
$story['first_story_category_id'] = $storyCategoryItem['story_category_id'];
$data[] = $story;
}
}
}
usort($data, function ($a, $b) {
if ($a['id'] == $b['id']) {
return 0;
}
return ($a['id'] > $b['id']) ? -1 : 1;
});
return $this->json($data);
}
}