vendor/uvdesk/support-center-bundle/Repository/Article.php line 112

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\SupportCenterBundle\Repository;
  3. use Doctrine\ORM\EntityRepository;
  4. use Doctrine\Common\Collections\Criteria;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Webkul\UVDesk\CoreFrameworkBundle\Entity as CoreEntities;
  7. use Webkul\UVDesk\SupportCenterBundle\Entity as SupportEntities;
  8. class Article extends EntityRepository
  9. {
  10. const LIMIT = 10;
  11. private $defaultSort = 'a.id';
  12. private $searchAllowed = ['tag'];
  13. private $direction = ['asc', 'desc'];
  14. private $sorting = ['a.name', 'a.dateAdded', 'a.viewed'];
  15. private $safeFields = ['page', 'limit', 'sort', 'order', 'direction'];
  16. private $allowedFormFields = ['search', 'query', 'name', 'description', 'viewed', 'status'];
  17. private function validateSorting($sorting)
  18. {
  19. return in_array($sorting, $this->sorting) ? $sorting : $this->defaultSort;
  20. }
  21. private function validateDirection($direction)
  22. {
  23. return in_array($direction, $this->direction) ? $direction : Criteria::DESC;
  24. }
  25. private function presetting(&$data)
  26. {
  27. $data['sort'] = $_GET['sort'] = $this->validateSorting(isset($data['sort']) ? $data['sort'] : false);
  28. $data['direction'] = $_GET['direction'] = $this->validateDirection(isset($data['direction']) ? $data['direction'] : false);
  29. $this->cleanAllData($data);
  30. }
  31. private function cleanAllData(&$data)
  32. {
  33. if (isset($data['isActive'])) {
  34. $data['status'] = $data['isActive'];
  35. unset($data['isActive']);
  36. }
  37. unset($data['categoryId']);
  38. unset($data['solutionId']);
  39. }
  40. public function getTotalArticlesBySupportTag($supportTag)
  41. {
  42. $result = $this->getEntityManager()->createQueryBuilder()
  43. ->select('COUNT(articleTags) as totalArticle')
  44. ->from(SupportEntities\ArticleTags::class, 'articleTags')
  45. ->where('articleTags.tagId = :supportTag')->setParameter('supportTag', $supportTag)
  46. ->getQuery()->getResult();
  47. return !empty($result) ? $result[0]['totalArticle'] : 0;
  48. }
  49. public function getAllHistoryByArticle($params)
  50. {
  51. $qbS = $this->getEntityManager()->createQueryBuilder();
  52. $results = $qbS->select('a.id, a.dateAdded, a.content')
  53. ->from('Webkul\UVDesk\SupportCenterBundle\Entity\ArticleHistory', 'a')
  54. ->leftJoin('Webkul\UVDesk\CoreFrameworkBundle\Entity\User', 'u', 'WITH', 'a.userId = u.id')
  55. ->leftJoin('u.userInstance', 'ud')
  56. ->addSelect("CONCAT(u.firstName,' ',u.lastName) AS name")
  57. ->andWhere('a.articleId = :articleId')
  58. ->andWhere('ud.supportRole IN (:roleId)')
  59. ->orderBy(
  60. 'a.id',
  61. Criteria::DESC
  62. )
  63. ->setParameters([
  64. 'articleId' => $params['articleId'],
  65. 'roleId' => [1, 2, 3],
  66. ])
  67. ->getQuery()
  68. ->getResult();
  69. return $results;
  70. }
  71. public function getAllRelatedByArticle($params, $status = [0, 1])
  72. {
  73. $qbS = $this->getEntityManager()->createQueryBuilder();
  74. $qbS->select('DISTINCT a.id, a.relatedArticleId as articleId, aR.name, aR.stared, aR.status, aR.slug')
  75. ->from('Webkul\UVDesk\SupportCenterBundle\Entity\ArticleRelatedArticle', 'a')
  76. ->leftJoin('Webkul\UVDesk\SupportCenterBundle\Entity\Article', 'aR', 'WITH', 'a.relatedArticleId = aR.id')
  77. ->andWhere('a.articleId = :articleId')
  78. ->andWhere('aR.status IN (:status)')
  79. ->orderBy(
  80. 'a.id',
  81. Criteria::DESC
  82. )
  83. ->setParameters([
  84. 'articleId' => $params['articleId'],
  85. 'status' => $status,
  86. ]);
  87. $results = $qbS->getQuery()->getResult();
  88. return $results;
  89. }
  90. public function getAllArticles(\Symfony\Component\HttpFoundation\ParameterBag $obj = null, $container, $allResult = false)
  91. {
  92. $json = array();
  93. $qb = $this->getEntityManager()->createQueryBuilder();
  94. $qb->select('a')->from($this->getEntityName(), 'a');
  95. $data = $obj ? $obj->all() : [];
  96. $data = array_reverse($data);
  97. $articles = [];
  98. if (isset($data['categoryId'])) {
  99. $qbS = $this->getEntityManager()->createQueryBuilder();
  100. $qbS->select('a.articleId')->from('Webkul\UVDesk\SupportCenterBundle\Entity\ArticleCategory', 'a');
  101. $qbS->where('a.categoryId = :categoryId');
  102. $qbS->setParameter('categoryId', $data['categoryId']);
  103. $articles = $qbS->getQuery()->getResult();
  104. $articles = $articles ? $articles : [0];
  105. }
  106. if (isset($data['solutionId'])) {
  107. $qbS = $this->getEntityManager()->createQueryBuilder();
  108. $qbS->select('DISTINCT ac.articleId')->from('Webkul\UVDesk\SupportCenterBundle\Entity\SolutionCategoryMapping', 'scm');
  109. $qbS->leftJoin('Webkul\UVDesk\SupportCenterBundle\Entity\ArticleCategory', 'ac', 'with', 'scm.categoryId = ac.categoryId');
  110. $qbS->where('scm.solutionId = :solutionId');
  111. $qbS->setParameter('solutionId', $data['solutionId']);
  112. $articles = $qbS->getQuery()->getResult();
  113. $articles = $articles ? $articles : [0];
  114. }
  115. if (isset($data['search'])) {
  116. $search = explode(':', $data['search']);
  117. if (
  118. isset($search[0])
  119. && isset($search[1])
  120. ) {
  121. if (in_array($search[0], $this->searchAllowed)) {
  122. if ($search[0] == 'tag') {
  123. $qbS = $this->getEntityManager()->createQueryBuilder();
  124. $qbS->select('at.articleId')->from('Webkul\UVDesk\SupportCenterBundle\Entity\ArticleTags', 'at');
  125. $articlesTag = $qbS->getQuery()->getResult();
  126. if ($articlesTag) {
  127. if ($articles) {
  128. $oldArticles = $articles;
  129. $articles = [0];
  130. foreach ($oldArticles as $article) {
  131. if (in_array($article, $articlesTag)) {
  132. $articles[] = $article;
  133. }
  134. }
  135. } else
  136. $articles = $articlesTag;
  137. } else
  138. $articles = [0];
  139. }
  140. unset($data['search']);
  141. }
  142. }
  143. }
  144. $this->presetting($data);
  145. foreach ($data as $key => $value) {
  146. if (
  147. ! in_array($key, $this->safeFields)
  148. && in_array($key, $this->allowedFormFields)
  149. ) {
  150. if ($key != 'dateUpdated' and $key != 'dateAdded' and $key != 'search' and $key != 'query') {
  151. $qb->andWhere('a.' . $key . ' = :' . $key);
  152. $qb->setParameter($key, $value);
  153. } else {
  154. if ($key == 'search' || $key == 'query') {
  155. $qb->orWhere('a.name' . ' LIKE :name');
  156. $qb->setParameter('name', '%' . urldecode(trim($value)) . '%');
  157. $qb->orWhere('a.content' . ' LIKE :content'); //can use regexBundle for it so that it can\'t match html
  158. $qb->setParameter('content', '%' . urldecode(trim($value)) . '%');
  159. }
  160. }
  161. }
  162. }
  163. if ($articles) {
  164. $qb->andWhere('a.id IN (:articles)');
  165. $qb->setParameter('articles', $articles);
  166. }
  167. if (! $allResult) {
  168. $paginator = $container->get('knp_paginator');
  169. $results = $paginator->paginate(
  170. $qb,
  171. isset($data['page']) ? $data['page'] : 1,
  172. self::LIMIT,
  173. array('distinct' => true)
  174. );
  175. } else {
  176. $qb->select($allResult);
  177. $results = $qb->getQuery()->getResult();
  178. return $results;
  179. }
  180. $newResult = [];
  181. foreach ($results as $key => $result) {
  182. $newResult[] = array(
  183. 'id' => $result->getId(),
  184. 'name' => $result->getName(),
  185. 'slug' => $result->getSlug(),
  186. 'status' => $result->getStatus(),
  187. 'viewed' => $result->getViewed(),
  188. 'dateAdded' => date_format($result->getDateAdded(), 'd-M h:i A'),
  189. 'categories' => ($articles ? $this->getCategoryByArticle($result->getId()) : $this->getCategoryByArticle($result->getId())),
  190. );
  191. }
  192. $paginationData = $results->getPaginationData();
  193. $queryParameters = $results->getParams();
  194. unset($queryParameters['solution']);
  195. if (isset($queryParameters['category']))
  196. unset($queryParameters['category']);
  197. $paginationData['url'] = '#' . $container->get('uvdesk.service')->buildPaginationQuery($queryParameters);
  198. $json['results'] = $newResult;
  199. $json['pagination_data'] = $paginationData;
  200. return $json;
  201. }
  202. public function getCategoryByArticle($id)
  203. {
  204. $queryBuilder = $this->createQueryBuilder('a');
  205. $results = $queryBuilder->select('c.id, c.name')
  206. ->leftJoin('Webkul\UVDesk\SupportCenterBundle\Entity\ArticleCategory', 'ac', 'WITH', 'ac.articleId = a.id')
  207. ->leftJoin('Webkul\UVDesk\SupportCenterBundle\Entity\SolutionCategory', 'c', 'WITH', 'ac.categoryId = c.id')
  208. ->andWhere('ac.articleId = :articleId')
  209. ->setParameters([
  210. 'articleId' => $id,
  211. ])
  212. ->getQuery()
  213. ->getResult();
  214. return $results;
  215. }
  216. public function getTagsByArticle($id)
  217. {
  218. $queryBuilder = $this->createQueryBuilder('a');
  219. $results = $queryBuilder->select('DISTINCT t.id, t.name')
  220. ->leftJoin('Webkul\UVDesk\SupportCenterBundle\Entity\ArticleTags', 'at', 'WITH', 'at.articleId = a.id')
  221. ->leftJoin('Webkul\UVDesk\CoreFrameworkBundle\Entity\Tag', 't', 'WITH', 'at.tagId = t.id')
  222. ->andWhere('at.articleId = :articleId')
  223. ->andWhere('at.tagId = t.id')
  224. ->setParameters([
  225. 'articleId' => $id,
  226. ])
  227. ->getQuery()
  228. ->getResult();
  229. return $results;
  230. }
  231. public function removeCategoryByArticle($articleId, $categories = [])
  232. {
  233. $where = is_array($categories) ? 'ac.categoryId IN (:id)' : 'ac.categoryId = :id';
  234. $queryBuilder = $this->createQueryBuilder('ac');
  235. $queryBuilder->delete(SupportEntities\ArticleCategory::class, 'ac')
  236. ->andWhere('ac.articleId = :articleId')
  237. ->andWhere($where)
  238. ->setParameters([
  239. 'articleId' => $articleId,
  240. 'id' => $categories,
  241. ])
  242. ->getQuery()
  243. ->execute()
  244. ;
  245. }
  246. public function removeTagByArticle($articleId, $tags = [])
  247. {
  248. $where = is_array($tags) ? 'ac.tagId IN (:id)' : 'ac.tagId = :id';
  249. $queryBuilder = $this->createQueryBuilder('ac');
  250. $queryBuilder->delete(SupportEntities\ArticleTags::class, 'ac')
  251. ->andWhere('ac.articleId = :articleId')
  252. ->andWhere($where)
  253. ->setParameters(['articleId' => $articleId, 'id' => $tags])
  254. ->getQuery()
  255. ->execute();
  256. }
  257. public function removeRelatedByArticle($articleId, $ids = [])
  258. {
  259. $where = is_array($ids) ? 'ac.id IN (:id)' : 'ac.id = :id';
  260. $queryBuilder = $this->createQueryBuilder('ac');
  261. $queryBuilder->delete(SupportEntities\ArticleRelatedArticle::class, 'ac')
  262. ->andWhere('ac.articleId = :articleId')
  263. ->andWhere($where)
  264. ->setParameters(['articleId' => $articleId, 'id' => $ids])
  265. ->getQuery()
  266. ->execute();
  267. }
  268. public function removeEntryByArticle($id)
  269. {
  270. $where = is_array($id) ? 'ac.articleId IN (:id)' : 'ac.articleId = :id';
  271. $queryBuilder = $this->createQueryBuilder('ac');
  272. $queryBuilder->delete(SupportEntities\ArticleCategory::class, 'ac')
  273. ->andWhere($where)
  274. ->setParameters([
  275. 'id' => $id,
  276. ])
  277. ->getQuery()
  278. ->execute();
  279. }
  280. public function bulkArticleStatusUpdate($ids, $status)
  281. {
  282. $query = 'UPDATE Webkul\UVDesk\SupportCenterBundle\Entity\Article a SET a.status = ' . (int)$status . ' WHERE a.id IN (' . implode(',', $ids) . ')';
  283. $this->getEntityManager()->createQuery($query)->execute();
  284. }
  285. private function getStringToOrder($string)
  286. {
  287. switch ($string) {
  288. case 'ascending':
  289. return 'ASC';
  290. break;
  291. case 'decending':
  292. case 'popularity':
  293. return 'DESC';
  294. break;
  295. default:
  296. return 'DESC';
  297. break;
  298. }
  299. }
  300. public function getArticlesByCategory(Request $request, $companyId)
  301. {
  302. $queryBuilder = $this->createQueryBuilder('a');
  303. $prams = array(
  304. 'solutionId' => (int)$request->attributes->get('solution'),
  305. 'categoryId' => (int)$request->attributes->get('category'),
  306. );
  307. $results = $queryBuilder->select('a')
  308. ->leftJoin('Webkul\SupportCenterBundle\Entity\ArticleCategory', 'ac', 'WITH', 'ac.articleId = a.id')
  309. ->andWhere('a.solutionId = :solutionId')
  310. ->andWhere('ac.categoryId = :categoryId')
  311. ->orderBy(
  312. $request->query->get('sort') ? 'a.' . $request->query->get('sort') : 'a.id',
  313. $request->query->get('direction') ? $request->query->get('direction') : Criteria::DESC
  314. )
  315. ->setParameters($prams)
  316. ->getQuery()
  317. ->getResult();
  318. return $results;
  319. }
  320. public function getSolutionArticles(Request $request, $companyId)
  321. {
  322. $queryBuilder = $this->createQueryBuilder('a');
  323. $prams = array(
  324. 'solutionId' => (int)$request->attributes->get('solution'),
  325. );
  326. $results = $queryBuilder->select('a')
  327. ->andWhere('a.solutionId = :solutionId')
  328. ->orderBy(
  329. $request->query->get('sort') ? 'a.' . $request->query->get('sort') : 'a.id',
  330. $request->query->get('direction') ? $request->query->get('direction') : Criteria::DESC
  331. )
  332. ->setParameters($prams)
  333. ->getQuery()
  334. ->getResult();
  335. return $results;
  336. }
  337. public function getArticlesByCategoryFront($category)
  338. {
  339. $queryBuilder = $this->createQueryBuilder('a');
  340. $prams = array(
  341. 'solutionId' => $category->getSolution(),
  342. 'categoryId' => $category->getId(),
  343. );
  344. $results = $queryBuilder->select('a')
  345. ->leftJoin('Webkul\SupportCenterBundle\Entity\ArticleCategory', 'ac', 'WITH', 'ac.articleId = a.id')
  346. ->andWhere('a.solutionId = :solutionId')
  347. ->andWhere('ac.categoryId = :categoryId')
  348. ->andWhere('a.status = 1')
  349. ->orderBy(
  350. $category->getSorting() == 'popularity' ? 'a.viewed' : 'a.name',
  351. $this->getStringToOrder($category->getSorting())
  352. )
  353. ->setParameters($prams)
  354. ->getQuery()
  355. ->getResult();
  356. return $results;
  357. }
  358. public function getArticleCategory(Request $request)
  359. {
  360. $queryBuilder = $this->createQueryBuilder('a');
  361. $prams = array(
  362. 'articleId' => (int)$request->attributes->get('article'),
  363. );
  364. $results = $queryBuilder->select('ac')
  365. ->leftJoin('Webkul\SupportCenterBundle\Entity\ArticleCategory', 'ac', 'WITH', 'ac.articleId = a.id')
  366. ->andWhere('ac.articleId = :articleId')
  367. ->orderBy(
  368. $request->query->get('sort') ? 'a.' . $request->query->get('sort') : 'a.id',
  369. $request->query->get('direction') ? $request->query->get('direction') : Criteria::DESC
  370. )
  371. ->setParameters($prams)
  372. ->getQuery()
  373. ->getResult();
  374. return $results;
  375. }
  376. public function getArticleBySearch(Request $request)
  377. {
  378. $sort = $request->query->get('sort');
  379. $direction = $request->query->get('direction');
  380. $searchQuery = $request->query->get('s');
  381. $params = [
  382. 'name' => '%' . trim($searchQuery) . '%',
  383. 'status' => 1,
  384. ];
  385. $results = $this->createQueryBuilder('a')
  386. ->select('a.id, a.name, a.slug, a.content, a.metaDescription, a.keywords, a.metaTitle, a.status, a.viewed, a.stared, a.dateAdded, a.dateUpdated')
  387. ->andWhere('a.name LIKE :name OR a.content LIKE :name')
  388. ->andWhere('a.status = :status')
  389. ->orderBy((!empty($sort)) ? 'a.' . $sort : 'a.id', (!empty($direction)) ? $direction : Criteria::DESC)
  390. ->setParameters($params)
  391. ->getQuery()
  392. ->getResult();
  393. return $results;
  394. }
  395. public function getArticleByTags(array $tagList = [], $sort = null, $direction = null)
  396. {
  397. if (empty($tagList))
  398. return [];
  399. $queryBuilder = $this->getEntityManager()->createQueryBuilder()
  400. ->select('a')
  401. ->from(SupportEntities\Article::class, 'a')
  402. ->leftJoin(SupportEntities\ArticleTags::class, 'at', 'WITH', 'at.articleId = a.id')
  403. ->leftJoin(CoreEntities\Tag::class, 't', 'WITH', 't.id = at.tagId')
  404. ->andWhere('a.status = :status')->setParameter('status', 1)
  405. ->orderBy(
  406. (! empty($sort)) ? 'a.' . $sort : 'a.id',
  407. (! empty($direction)) ? $direction : Criteria::DESC
  408. );
  409. // Build the sub-query
  410. $subQuery = '';
  411. foreach ($tagList as $index => $tag) {
  412. $queryBuilder->setParameter('tag' . $index, '%' . $tag . '%');
  413. $subQuery .= ($index == 0) ? 't.name LIKE :tag' . $index : ' OR t.name LIKE :tag' . $index;
  414. }
  415. $queryBuilder->andWhere($subQuery);
  416. $articleCollection = $queryBuilder->getQuery()->getResult();
  417. return (!empty($articleCollection)) ? $articleCollection : [];
  418. }
  419. public function getArticleAuthorDetails($articleId = null, $companyId = null)
  420. {
  421. if (empty($articleId))
  422. throw new \Exception('Article::getArticleAuthorDetails() expects parameter 1 to be defined.');
  423. $queryBuilder = $this->getEntityManager()->createQueryBuilder()
  424. ->select('ud')
  425. ->from(CoreEntities\UserInstance::class, 'ud')
  426. ->leftJoin(SupportEntities\ArticleHistory::class, 'ah', 'WITH', 'ah.userId = ud.user')
  427. ->where('ah.articleId = :articleId')->setParameter('articleId', $articleId)
  428. ->andWhere('ud.supportRole != :userRole')->setParameter('userRole', 4)
  429. ->orderBy('ah.dateAdded', 'ASC')
  430. ->setMaxResults(1);
  431. $articleAuthorCollection = $queryBuilder->getQuery()->getResult();
  432. if (
  433. ! empty($articleAuthorCollection)
  434. && count($articleAuthorCollection) > 1
  435. ) {
  436. // Parse through the collection and priorotize entity which have the designation field. This case
  437. // will occur when the user is mapped with more than one userData entity with differing userRoles.
  438. // If none is found, return the very first element in collection. It doesn't matter then.
  439. $defaultArticleAuthor = $articleAuthorCollection[0];
  440. foreach ($articleAuthorCollection as $articleAuthor) {
  441. if (! empty($articleAuthor->getJobTitle())) {
  442. $defaultArticleAuthor = $articleAuthor;
  443. break;
  444. }
  445. }
  446. return (! empty($defaultArticleAuthor)) ? $defaultArticleAuthor : $articleAuthorCollection[0];
  447. } else {
  448. return (! empty($articleAuthorCollection)) ? $articleAuthorCollection[0] : null;
  449. }
  450. }
  451. /**
  452. * search company articles by keyword and returns articles array
  453. *
  454. * @param string $keyword
  455. *
  456. * @return array Articles
  457. */
  458. public function SearchCompanyArticles($company, $keyword)
  459. {
  460. $qb = $this->getEntityManager()->createQueryBuilder()
  461. ->select('a')
  462. ->from('SupportCenterBundle:Article', 'a')
  463. // ->leftJoin('SupportCenterBundle:ArticleTags', 'at', 'WITH', 'at.articleId = a.id')
  464. ->where('a.companyId = :companyId')->setParameter('companyId', $company->getId())
  465. ->andWhere('a.status = :status')->setParameter('status', 1)
  466. ->andWhere('a.name LIKE :keyword OR a.slug LIKE :keyword OR a.content LIKE :keyword')->setParameter('keyword', '%' . $keyword . '%')
  467. ->orderBy(
  468. 'a.dateUpdated'
  469. );
  470. $articles = $qb->getQuery()->getArrayResult();
  471. return $articles;
  472. }
  473. public function getArticleFeedbacks($article)
  474. {
  475. $response = ['positiveFeedbacks' => 0, 'negativeFeedbacks' => 0, 'collection' => []];
  476. $nativeQuery = strtr('SELECT user_id, is_helpful, description FROM uv_article_feedback WHERE article_id = {ARTICLE_ID}', [
  477. '{ARTICLE_ID}' => $article->getId(),
  478. ]);
  479. $preparedDBStatement = $this->getEntityManager()->getConnection()->prepare($nativeQuery);
  480. $feedbackCollection = $preparedDBStatement->executeStatement();
  481. if (! empty($feedbackCollection)) {
  482. $response['collection'] = array_map(function ($feedback) {
  483. return ['user' => $feedback['user_id'], 'direction' => ((int) $feedback['is_helpful'] === 1) ? 'positive' : 'negative', 'feedbackMessage' => $feedback['description']];
  484. }, $feedbackCollection);
  485. $ratings = array_count_values(array_column($response['collection'], 'direction'));
  486. $response['positiveFeedbacks'] = !empty($ratings['positive']) ? $ratings['positive'] : 0;
  487. $response['negativeFeedbacks'] = !empty($ratings['negative']) ? $ratings['negative'] : 0;
  488. }
  489. return $response;
  490. }
  491. public function getPopularTranslatedArticles($locale)
  492. {
  493. $qb = $this->getEntityManager()->createQueryBuilder()
  494. ->select('a.id', 'a.name', 'a.slug', 'a.content', 'a.stared')
  495. ->from($this->getEntityName(), 'a')
  496. ->andWhere('a.status = :status')
  497. ->setParameter('status', 1)
  498. ->addOrderBy('a.viewed', Criteria::DESC)
  499. ->setMaxResults(10);
  500. return $qb->getQuery()->getArrayResult();
  501. }
  502. }