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

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