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

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