vendor/uvdesk/support-center-bundle/Controller/Customer.php line 247

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\SupportCenterBundle\Controller;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\Security\Core\Security;
  6. use Symfony\Component\HttpFoundation\JsonResponse;
  7. use Symfony\Contracts\Translation\TranslatorInterface;
  8. use Symfony\Component\Filesystem\Filesystem as Fileservice;
  9. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  10. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  11. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  12. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  13. use Webkul\UVDesk\CoreFrameworkBundle\Form\UserProfile;
  14. use Webkul\UVDesk\CoreFrameworkBundle\Utils\TokenGenerator;
  15. use Webkul\UVDesk\CoreFrameworkBundle\FileSystem\FileSystem;
  16. use Webkul\UVDesk\CoreFrameworkBundle\Services as CoreServices;
  17. use Webkul\UVDesk\CoreFrameworkBundle\Providers\UserProvider;
  18. use Webkul\UVDesk\SupportCenterBundle\Entity as SupportEntities;
  19. use Webkul\UVDesk\CoreFrameworkBundle\Entity as CoreEntities;
  20. class Customer extends AbstractController
  21. {
  22. private $translator;
  23. private $fileSystem;
  24. private $passwordEncoder;
  25. private $fileUploadService;
  26. private $uvdeskService;
  27. private $userProvider;
  28. private $em;
  29. public function __construct(TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder, FileSystem $fileSystem, CoreServices\FileUploadService $fileUploadService, CoreServices\EmailService $emailService, CoreServices\UVDeskService $uvdeskService, UserProvider $userProvider, EntityManagerInterface $entityManager)
  30. {
  31. $this->translator = $translator;
  32. $this->fileSystem = $fileSystem;
  33. $this->passwordEncoder = $passwordEncoder;
  34. $this->fileUploadService = $fileUploadService;
  35. $this->emailService = $emailService;
  36. $this->uvdeskService = $uvdeskService;
  37. $this->userProvider = $userProvider;
  38. $this->em = $entityManager;
  39. }
  40. protected function redirectUserToLogin()
  41. {
  42. $authChecker = $this->container->get('security.authorization_checker');
  43. if ($authChecker->isGranted('ROLE_CUSTOMER'))
  44. return true;
  45. }
  46. protected function isWebsiteActive()
  47. {
  48. $website = $this->em->getRepository(CoreEntities\Website::class)->findOneByCode('knowledgebase');
  49. if (! empty($website)) {
  50. $knowledgebaseWebsite = $this->em->getRepository(SupportEntities\KnowledgebaseWebsite::class)->findOneBy(['website' => $website->getId(), 'status' => 1]);
  51. if (! empty($knowledgebaseWebsite) && true == $knowledgebaseWebsite->getIsActive()) {
  52. return true;
  53. }
  54. }
  55. $this->noResultFound();
  56. }
  57. protected function noResultFound()
  58. {
  59. throw new NotFoundHttpException('Permission Denied !');
  60. }
  61. protected function isLoginDisabled()
  62. {
  63. $website = $this->em->getRepository(CoreEntities\Website::class)->findOneByCode('knowledgebase');
  64. if (! empty($website)) {
  65. $configuration = $this->em->getRepository(SupportEntities\KnowledgebaseWebsite::class)->findOneBy([
  66. 'website' => $website->getId(),
  67. 'isActive' => 1,
  68. ]);
  69. if (
  70. ! empty($configuration)
  71. && $configuration->getDisableCustomerLogin()
  72. ) {
  73. return true;
  74. }
  75. }
  76. return false;
  77. }
  78. public function loginOtpVerify(Request $request)
  79. {
  80. $params = $request->request->all();
  81. if (empty($params['_username'])) {
  82. return new JsonResponse([
  83. 'success' => false,
  84. 'message' => "No user details provided. Please try again later.",
  85. ], 403);
  86. }
  87. $user = $this->em->getRepository(CoreEntities\User::class)->findOneByEmail($params['_username']);
  88. if (empty($user) || empty($params['otp'])) {
  89. return new JsonResponse([
  90. 'success' => false,
  91. 'message' => "No associated user account details were found. Please try again later.",
  92. ], 403);
  93. } else if ($user->getVerificationCode() != $params['otp']) {
  94. return new JsonResponse([
  95. 'success' => false,
  96. 'message' => "Invalid OTP provided. Please try again later.",
  97. ], 403);
  98. }
  99. $currentTimestamp = new \DateTime('now');
  100. $lastOtpGeneratedAtTimestamp = $user->getLastOtpGeneratedAt();
  101. $lastOtpGeneratedAtTimestamp->modify('+5 minutes');
  102. $interval = $lastOtpGeneratedAtTimestamp->diff($currentTimestamp);
  103. $isTimePeriodElapsed = (bool) $interval->invert ? false : true;
  104. if ($isTimePeriodElapsed == true) {
  105. return new JsonResponse([
  106. 'success' => false,
  107. 'message' => "The provided OTP has expired. Please try again later.",
  108. ], 403);
  109. }
  110. $user = $this->userProvider->refreshUser($user);
  111. try {
  112. $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
  113. $this->container->get('security.token_storage')->setToken($token);
  114. // Regenerate the session
  115. $request->getSession()->migrate();
  116. $this->addFlash('success', $this->translator->trans('Success ! Logged in successfully.'));
  117. return new JsonResponse([
  118. 'success' => true,
  119. 'message' => "Successfully logged in.",
  120. ]);
  121. } catch (\Exception $e) {
  122. return new JsonResponse([
  123. 'success' => false,
  124. 'message' => "Failed to login " . $e->getMessage(),
  125. ], 403);
  126. }
  127. }
  128. public function generateOtp(Request $request)
  129. {
  130. $params = $request->request->all();
  131. $website = $this->em->getRepository(CoreEntities\Website::class)->findOneByCode('helpdesk');
  132. $knowledgebase = $this->em->getRepository(CoreEntities\Website::class)->findOneByCode('knowledgebase');
  133. $user = $this->em->getRepository(CoreEntities\User::class)->retrieveHelpdeskCustomerInstances($params['_username']);
  134. if (empty($user)) {
  135. return new JsonResponse([
  136. 'success' => false,
  137. 'message' => "No associated user accounts were found with the email '{$params['_username']}'.",
  138. ], 403);
  139. } else if ($this->isLoginDisabled()) {
  140. return new JsonResponse([
  141. 'success' => false,
  142. 'message' => "Login has been disabled for this helpdesk.",
  143. ], 403);
  144. }
  145. $currentTimestamp = new \DateTime('now');
  146. $lastOtpGeneratedAtTimestamp = $user->getLastOtpGeneratedAt();
  147. if (! empty($lastOtpGeneratedAtTimestamp)) {
  148. $lastOtpGeneratedAtTimestamp->modify('+1 minute');
  149. $interval = $lastOtpGeneratedAtTimestamp->diff($currentTimestamp);
  150. $isTimePeriodElapsed = (bool) $interval->invert ? false : true;
  151. if ($isTimePeriodElapsed == false) {
  152. return new JsonResponse([
  153. 'success' => false,
  154. 'message' => "Please wait for upto 1 minute before requesting a new OTP.",
  155. ]);
  156. }
  157. }
  158. $user->setVerificationCode(TokenGenerator::generateToken(6, $range = '0123456789'))
  159. ->setLastOtpGeneratedAt(new \DateTime('now'))
  160. ;
  161. $this->em->persist($user);
  162. $this->em->flush();
  163. $name = ucwords(trim(implode(' ', [$user->getFirstName(), $user->getLastName()])));
  164. // Generate email content
  165. $subject = "Login OTP from " . $website->getName();
  166. $content = $this->renderView('@UVDeskSupportCenter/CustomerLogin/customer-login-otp-verification-email.html.twig', [
  167. 'name' => $name,
  168. 'verificationCode' => $user->getVerificationCode(),
  169. 'helpdeskName' => $website->getName(),
  170. 'helpdeskMail' => $this->getParameter('uvdesk.support_email.id'),
  171. 'helpdeskLogo' => $knowledgebase->getLogo() ? $this->uvdeskService->generateCompleteLocalResourcePathUri($knowledgebase->getLogo()) : "",
  172. ]);
  173. $this->emailService->sendMail($subject, $content, $user->getEmail());
  174. return new JsonResponse([
  175. 'success' => true,
  176. 'message' => "Please check your email for a OTP verification code.",
  177. ]);
  178. }
  179. public function login(Request $request)
  180. {
  181. $this->isWebsiteActive();
  182. if ($this->redirectUserToLogin()) {
  183. return $this->redirect($this->generateUrl('helpdesk_customer_ticket_collection')); // Replace with Dashboard route
  184. }
  185. /** check disabled customer login **/
  186. if ($this->isLoginDisabled()) {
  187. $this->addFlash('warning', $this->translator->trans('Warning ! Customer Login disabled by admin.'));
  188. return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  189. }
  190. $session = $request->getSession();
  191. $error = $session->get(Security::AUTHENTICATION_ERROR);
  192. $session->remove(Security::AUTHENTICATION_ERROR);
  193. if ($error) {
  194. $this->addFlash('warning', $this->translator->trans('Warning ! ' . $error->getMessage()));
  195. }
  196. return $this->render('@UVDeskSupportCenter/CustomerLogin/customer-login.html.twig', [
  197. 'searchDisable' => true,
  198. 'last_username' => $session->get(Security::LAST_USERNAME),
  199. 'error' => $error,
  200. 'breadcrumbs' => [
  201. [
  202. 'label' => $this->translator->trans('Support Center'),
  203. 'url' => $this->generateUrl('helpdesk_knowledgebase')
  204. ],
  205. [
  206. 'label' => $this->translator->trans('Sign In'),
  207. 'url' => '#'
  208. ]
  209. ]
  210. ]);
  211. }
  212. public function Account(Request $request)
  213. {
  214. $this->isWebsiteActive();
  215. $em = $this->em;
  216. $user = $this->getUser();
  217. if ($request->getMethod() == 'POST') {
  218. $data = $request->request->all();
  219. $dataFiles = $request->files->get('user_form');
  220. $data = $data['user_form'];
  221. // Profile upload validation
  222. $validMimeType = ['image/jpeg', 'image/png', 'image/jpg'];
  223. if (isset($dataFiles['profileImage'])) {
  224. if (! in_array($dataFiles['profileImage']->getMimeType(), $validMimeType)) {
  225. $this->addFlash('warning', $this->translator->trans('Error ! Profile image is not valid, please upload a valid format'));
  226. return $this->redirect($this->generateUrl('helpdesk_customer_account'));
  227. }
  228. }
  229. $checkUser = $em->getRepository(CoreEntities\User::class)->findOneBy(array('email' => $data['email']));
  230. $errorFlag = 0;
  231. if ($checkUser) {
  232. if ($checkUser->getId() != $user->getId())
  233. $errorFlag = 1;
  234. }
  235. if (! $errorFlag) {
  236. $password = $user->getPassword();
  237. $form = $this->createForm(UserProfile::class, $user);
  238. $form->handleRequest($request);
  239. $form->submit($data);
  240. if ($form->isValid()) {
  241. if ($data != null && (!empty($data['password']['first']))) {
  242. $encodedPassword = $this->passwordEncoder->encodePassword($user, $data['password']['first']);
  243. if (! empty($encodedPassword)) {
  244. $user->setPassword($encodedPassword);
  245. }
  246. } else {
  247. $user->setPassword($password);
  248. }
  249. $user->setFirstName($data['firstName']);
  250. $user->setLastName($data['lastName']);
  251. $user->setEmail($data['email']);
  252. $user->setTimeZone($data['timezone']);
  253. $user->setTimeFormat($data['timeformat']);
  254. $em->persist($user);
  255. $em->flush();
  256. $userInstance = $em->getRepository(CoreEntities\UserInstance::class)->findOneBy(array('user' => $user->getId()));
  257. if (isset($dataFiles['profileImage'])) {
  258. $previousImage = $userInstance->getProfileImagePath();
  259. if ($previousImage != null) {
  260. $image = str_replace("\\", "/", $this->getParameter('kernel.project_dir') . '/public' . $previousImage);
  261. $check = $this->fileUploadService->fileRemoveFromFolder($image);
  262. }
  263. $assetDetails = $this->fileSystem->getUploadManager()->uploadFile($dataFiles['profileImage'], 'profile');
  264. $userInstance->setProfileImagePath($assetDetails['path']);
  265. }
  266. // Removed profile image from database and path
  267. $fileService = new Fileservice;
  268. if ($request->get('removeImage') == 'on') {
  269. if ($userInstance->getProfileImagePath()) {
  270. $fileService->remove($this->getParameter('kernel.project_dir') . '/public' . $userInstance->getProfileImagePath());
  271. }
  272. $userInstance = $userInstance->setProfileImagePath(null);
  273. }
  274. $userInstance = $userInstance->setContactNumber($data['contactNumber']);
  275. $em->persist($userInstance);
  276. $em->flush();
  277. $this->addFlash('success', $this->translator->trans('Success ! Profile updated successfully.'));
  278. return $this->redirect($this->generateUrl('helpdesk_customer_account'));
  279. } else {
  280. $errors = $form->getErrors();
  281. $errors = $this->getFormErrors($form);
  282. }
  283. } else {
  284. $this->addFlash('warning', $this->translator->trans('Error ! User with same email is already exist.'));
  285. return $this->redirect($this->generateUrl('helpdesk_customer_account'));
  286. }
  287. }
  288. return $this->render('@UVDeskSupportCenter/Knowledgebase/customerAccount.html.twig', [
  289. 'searchDisable' => true,
  290. 'user' => $user,
  291. ]);
  292. }
  293. public function searchArticle(Request $request)
  294. {
  295. $this->isWebsiteActive();
  296. $searchQuery = $request->query->get('s');
  297. if (empty($searchQuery)) {
  298. return $this->redirect($this->generateUrl('helpdesk_customer_ticket_collection'));
  299. }
  300. $articleCollection = $this->getDoctrine()->getRepository(SupportEntities\Article::class)->getArticleBySearch($request);
  301. return $this->render('@UVDeskSupportCenter/Knowledgebase/search.html.twig', [
  302. 'search' => $searchQuery,
  303. 'articles' => $articleCollection,
  304. 'breadcrumbs' => [
  305. ['label' => $this->translator->trans('Support Center'), 'url' => $this->generateUrl('helpdesk_knowledgebase')],
  306. ['label' => $searchQuery, 'url' => '#'],
  307. ],
  308. ]);
  309. }
  310. }