src/WPXToolsBundle/Controller/UserController.php line 26

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace WPXToolsBundle\Controller;
  4. use PDO;
  5. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  6. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  7. use Symfony\Component\HttpFoundation\Request;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\HttpFoundation\Session\Session;
  10. use Validator\Validator;
  11. use WPXToolsBundle\Entity\Role;
  12. use WPXToolsBundle\Entity\User;
  13. use WPXToolsBundle\Entity\UserDepartment;
  14. use WPXToolsBundle\Entity\UserPosition;
  15. use WPXToolsBundle\Form\LoginType;
  16. class UserController extends Controller
  17. {
  18.     /**
  19.      * @param Request $request
  20.      * @Route("/login", name="login")
  21.      * @return \Symfony\Component\HttpFoundation\Response
  22.      */
  23.     public function loginForm(Request $request)
  24.     {
  25.         if($request->server->get('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest'){
  26.             $response = new Response();
  27.             $response->headers->set('x-is-ajax-call'true);
  28.             return $response;
  29.         }
  30.         $login = new User();
  31.         $loginForm $this->createForm(LoginType::class, $login);
  32.         $loginForm->handleRequest($request);
  33.         $authenticationUtils $this->get('security.authentication_utils');
  34.         $error $authenticationUtils->getLastAuthenticationError();
  35.         if(($loginForm->isSubmitted() && $loginForm->isValid()) || $this->getUser()){
  36.             return $this->redirectToRoute('dashboard');
  37.         }else{
  38.             return $this->render('default/login_form.html.twig', [
  39.                 'title' => 'User Login',
  40.                 'loginForm' => $loginForm->createView(),
  41.                 'error' => $error
  42.             ]);
  43.         }
  44.     }
  45.     /**
  46.      * @Route ("/logout", name="logout")
  47.      * @return \Symfony\Component\HttpFoundation\RedirectResponse
  48.      * @internal param Request $request
  49.      */
  50.     public function logoutProcess()
  51.     {
  52.         $session = new Session();
  53.         $session->clear();
  54.         return $this->redirectToRoute('dashboard');
  55.     }
  56.     /**
  57.      * @Route("/notifications", name="user_notifications")
  58.      * @Route("/notifications/view/{id}", name="user_notifications_view_message")
  59.      * @param Request $request
  60.      * @return string
  61.      */
  62.     public function userNotifications(Request $request){
  63.         $validator = new Validator([
  64.             'id' => $request->attributes->get('id')
  65.         ], false);
  66.         $validator->validateAll([
  67.             'id' => [
  68.                 'type' => 'int',
  69.                 'required' => false,
  70.                 'msg' => 'The notification ID provided isn\'t valid.'
  71.             ]
  72.         ]);
  73.         if($validator->hasErrors()){
  74.             foreach ($validator->errors as $string){
  75.                 $this->addFlash('warning'$string);
  76.             }
  77.             return false;
  78.         }
  79.         $notificationService $this->get('user_notification');
  80.         if(!empty($validator->valid['id']))
  81.         {
  82.             $notification $notificationService->viewNotification((int)$validator->valid['id']);
  83.             if(!$notification) return $this->redirectToRoute('user_notifications');
  84.             return $this->render('default/user/notifications_view.html.twig', [
  85.                 'title' => $notification['notificationSubject'],
  86.                 'notification' => $notification
  87.             ]);
  88.         }else{
  89.             return $this->render('default/user/notifications.html.twig',[
  90.                 'notifications' => $notificationService->notifications,
  91.                 'title' => 'User notifications'
  92.             ]);
  93.         }
  94.     }
  95.     /**
  96.      * @Route("/notifications/markRead", name="notifications_mark_read")
  97.      * @param Request $request
  98.      * @return \Symfony\Component\HttpFoundation\JsonResponse
  99.      */
  100.     public function notificationMarkRead(Request $request){
  101.         if($this->get('user_notification')->setSeenNotification($request->request->get('alertId'))){
  102.             return $this->json([
  103.                 'message' => 'Successfully marked as read.',
  104.                 'status' => 0
  105.             ]);
  106.         }else{
  107.             return $this->json([
  108.                 'message' => 'Failed to mark the notification as read!',
  109.                 'status' => 1
  110.             ]);
  111.         }
  112.     }
  113.     /**
  114.      * @Route("/profile", name="user_profile")
  115.      * @Route("/profile/{id}", name="user_profile_admin")
  116.      * @param Request $request
  117.      * @return bool|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\Response
  118.      */
  119.     public function userProfile(Request $request){
  120.         $validator = new Validator($_REQUEST);
  121.         $validator->validateAll([
  122.             'id' => [
  123.                 'type' => 'int',
  124.                 'required' => 0,
  125.                 'value' => $request->attributes->get('id'),
  126.                 'default' => $this->getUser()->getId()
  127.             ],
  128.             'action' => [
  129.                 'required' => false
  130.             ]
  131.         ]);
  132.         $adminCheck $this->isGranted('ROLE_ADMIN');
  133.         if($validator->hasErrors()){
  134.             foreach ($validator->errors as $string){
  135.                 $this->addFlash('warning'$string);
  136.             }
  137.             return false;
  138.         }
  139.         if( $validator->valid['action'] ){
  140.             if( !$this->updateProfile($validator->valid['id'], $adminCheck) ){
  141.                 $this->addFlash('warning''Could not update profile.');
  142.             }
  143.         }
  144.         $em $this->getDoctrine();
  145.         $user $em->getRepository(User::class)->findOneBy(['id' => $validator->valid['id']]);
  146.         if(!is_object($user)){
  147.             $this->addFlash('warning''User with this ID doesn\'t exist.');
  148.             return $this->redirectToRoute('user_staff_list');
  149.         }
  150.         if($this->getUser()->getId() != $validator->valid['id'] && !$adminCheck){
  151.             return $this->render('default/user/view_profile.html.twig',[
  152.                 'title' => 'View Profile',
  153.                 'userData' => $user
  154.             ]);
  155.         }
  156.         $roles $em->getRepository(Role::class)->findAll();
  157.         $departments $em->getRepository(UserDepartment::class)->findAll();
  158.         $positions $em->getRepository(UserPosition::class)->findAll();
  159.         $hb $this->get('hb_initialize');
  160.         $hostBillUsers $hb->makeAction('getAllUsers');
  161.         return $this->render('default/user/profile.html.twig',[
  162.             'title' => 'Edit Profile',
  163.             'userData' => $user,
  164.             'roles' => $roles,
  165.             'departments' => $departments,
  166.             'positions' => $positions,
  167.             'hbUsers' => $hostBillUsers['result'],
  168.         ]);
  169.     }
  170.     /**
  171.      * @param $userId
  172.      * @param $adminCheck
  173.      * @return bool|\Symfony\Component\HttpFoundation\JsonResponse
  174.      */
  175.     public function updateProfile($userId$adminCheck){
  176.         if($this->getUser()->getId() != $userId && !$adminCheck){
  177.             return false;
  178.         }
  179.         $validator = new Validator($_REQUESTfalse);
  180.         $validator->validateAll([
  181.             'username' => [
  182.                 'filter' => 'trim',
  183.                 'msg' => 'The username is invalid.',
  184.                 'msg_miss' => 'You haven\'t provided username.'
  185.             ],
  186.             'realname' => [
  187.                 'filter' => 'trim',
  188.                 'msg' => 'The name is invalid.',
  189.                 'msg_miss' => 'You haven\'t provided any name for the account'
  190.             ],
  191.             'fullName' => [
  192.                 'filter' => 'trim',
  193.                 'msg' => 'The name is invalid.',
  194.                 'msg_miss' => 'You haven\'t provided any name for the account'
  195.             ],
  196.             'realPosition' => [
  197.                 'filter' => 'trim',
  198.                 'msg' => 'The real position is invalid.',
  199.                 'msg_miss' => 'You haven\'t provided any real position for the account'
  200.             ],
  201.             'currentPassword' => [
  202.                 'required' => false,
  203.                 'requires' => ['newPassword''newPasswordAgain'],
  204.                 'msg' => 'The entered password is invalid',
  205.                 'msg_miss' => 'The current password wasn\'t provided'
  206.             ],
  207.             'newPassword' => [
  208.                 'required' => false,
  209.                 'requires' => ['currentPassword''newPasswordAgain'],
  210.                 'match' => '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$/',
  211.                 'msg' => 'Password should be containing at least 1 lower case letter, at least 1 upper case letter, at least 1 digit and at least 1 special symbol.',
  212.                 'msg_miss' => 'No new password provided.'
  213.             ],
  214.             'newPasswordAgain' => [
  215.                 'required' => false,
  216.                 'requires' => ['currentPassword''newPassword'],
  217.                 'match' => '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$/',
  218.                 'msg' => 'Password should be the same as the previous field.',
  219.                 'msg_miss' => 'You should repeat the new password.'
  220.             ],
  221.             'email' => [
  222.                 'type' => 'email',
  223.                 'msg' => 'The email address isn\'t valid.',
  224.                 'msg_miss' => 'You haven\'t provided any email address.'
  225.             ],
  226.             'skype' => [
  227.                 'filter' => 'trim',
  228.                 'required' => false,
  229.                 'msg' => 'The provided Skype name isn\'t valid'
  230.             ],
  231.             'mobileNumber' => [
  232.                 'match' => '/^\+?\d{6,12}$/',
  233.                 'required' => false,
  234.                 'msg' => 'Invalid mobile number provided. Should be containing digits only and starting with +359 or 0 only.',
  235.                 'msg_miss' => 'No mobile number provided'
  236.             ],
  237.             'birthdate' => [
  238.                 'type' => 'date',
  239.                 'filter' => 'trim',
  240.                 'required' => false,
  241.                 'msg' => 'The birth date is invalid.',
  242.                 'msg_miss' => 'No birth date provided.'
  243.             ],
  244.             'canUsePLAfter' => [
  245.                 'type' => 'date',
  246.                 'filter' => 'trim',
  247.                 'required' => false,
  248.                 'msg' => 'The paid leave date is invalid.',
  249.                 'msg_miss' => 'No paid leave date provided.'
  250.             ],
  251.             'paidLeaveDays' => [
  252.                 'type' => 'int',
  253.                 'required' => false,
  254.                 'msg' => 'The paid leave value is invalid.',
  255.                 'msg_miss' => 'No paid leave value provided.'
  256.             ],
  257.             'isActive' => [
  258.                 'match' => ['on''off'],
  259.                 'required' => false,
  260.                 'msg' => 'Invalid active status provided.'
  261.             ],
  262.             'popupNotifications' => [
  263.                 'match' => ['on''off'],
  264.                 'required' => false,
  265.                 'msg' => 'Invalid popup notification status provided.'
  266.             ],
  267.             'userRole' => [
  268.                 'type' => 'int',
  269.                 'required' => false,
  270.                 'msg' => 'Invalid user Role provided.'
  271.             ],
  272.             'positions' => [
  273.                 'type' => 'int',
  274.                 'msg' => 'Invalid user Position provided.'
  275.             ],
  276.             'hostBillUser' => [
  277.                 'type' => 'int',
  278.                 'required' => false,
  279.                 'msg' => 'Invalid hostBillUser ID provided.'
  280.             ]
  281.         ]);
  282.         if($validator->hasErrors()){
  283.             foreach ($validator->errors as $string){
  284.                 $this->addFlash('warning'$string);
  285.             }
  286.             return false;
  287.         }
  288.         $valid $validator->valid;
  289.         $em $this->getDoctrine();
  290.         $user $em->getRepository(User::class)->findOneBy(['id'=>$userId]);
  291.         if($valid['hostBillUser'] !== $user->getHostBillId() && $adminCheck) {
  292.             $checkHBUser $em->getRepository(User::class)->findOneBy(['hostBillId' => $valid['hostBillUser']]);
  293.             if (is_object($checkHBUser) && $valid['hostBillUser'] !== && $checkHBUser->getId() !== $user->getId()) {
  294.                 $this->addFlash('warning'$checkHBUser->getRealName() . ' is already related with this HostBill account. Two users can\'t have the same HostBill account relation.');
  295.                 return false;
  296.             }else{
  297.                 $user->setHostBillId($valid['hostBillUser']);
  298.             }
  299.         }
  300.         $currentPassword = (!$adminCheck) ? password_verify($valid['currentPassword'], $user->getPassword()) : true;
  301.         if(!empty($valid['newPassword']) && $currentPassword){
  302.             if($valid['newPassword'] == $valid['newPasswordAgain']){
  303.                 $password $this->get('security.password_encoder')->encodePassword($user$valid['newPassword']);
  304.                 $user->setPassword($password);
  305.             }else{
  306.                 $this->addFlash('warning''The new passwords do not match.');
  307.             }
  308.         }else{
  309.             if(!empty($valid['currentPassword'])){
  310.                 $this->addFlash('warning''The current password doesn\'t match. New password was NOT updated.');
  311.             }elseif(!empty($valid['newPassword'])){
  312.                 $this->addFlash('warning''New password was entered but either wrong or no password was provided as current.');
  313.             }
  314.         }
  315.         if($adminCheck){
  316.             $position $em->getRepository(UserPosition::class)->findOneBy(['id'=>$valid['positions']]);
  317.             $user->setRealName($valid['realname']);
  318.             $user->setUsername($valid['username']);
  319.             $user->setEmail($valid['email']);
  320.             if ($valid['realPosition']) {
  321.                 $user->setDepartmentNameInCyrillic($valid['realPosition']);
  322.             }
  323.             if($valid['canUsePLAfter']){
  324.                 $user->setPaidLeaveDaysDate(new \DateTime($valid['canUsePLAfter']));
  325.             }else{
  326.                 $user->setPaidLeaveDaysDate(NULL);
  327.             }
  328.             $user->setPaidLeaveDays($valid['paidLeaveDays']);
  329.             $user->setPosition($position);
  330.             if($valid['userRole'] === && !$this->isGranted('ROLE_SUPER_ADMIN')) {
  331.                 $roleId 1;
  332.             }else{
  333.                 $roleId $valid['userRole'];
  334.             }
  335.             $sql "UPDATE users_roles SET role_id = :roleId WHERE user_id = :userId";
  336.             $query $em->getConnection()->prepare($sql);
  337.             $query->execute([
  338.                 'roleId' => $roleId,
  339.                 'userId' => $userId
  340.             ]);
  341.             $active = ($valid['isActive'] == 'on') ?  :  0;
  342.             $popupNotifications = ($valid['popupNotifications'] == 'on') ?  :  0;
  343.             $user->setIsActive($active);
  344.             $user->setPopupNotifications($popupNotifications);
  345.         }
  346.         if ($valid['fullName']) {
  347.             $user->setNameInCyrillic($valid['fullName']);
  348.         }
  349.         $user->setSkype($valid['skype']);
  350.         $user->setPhoneNumber($valid['mobileNumber']);
  351.         if($valid['birthdate']){
  352.             $user->setBirthDate(new \DateTime($valid['birthdate']));
  353.         }else{
  354.             $user->setBirthDate(NULL);
  355.         }
  356.         $em->getManager()->flush();
  357.         $this->addFlash('success''Profile has been updated successfully.');
  358.         return true;
  359.     }
  360.     /**
  361.      * @Route("/getPositions", name="get_positions")
  362.      */
  363.     public function getPositions(){
  364.         $validator = new Validator($_REQUESTfalse);
  365.         $validator->validateAll([
  366.             'departmentId' => [
  367.                 'type' => 'int'
  368.             ]
  369.         ]);
  370.         if($validator->hasErrors()){
  371.             foreach ($validator->errors as $string){
  372.                 $this->addFlash('warning'$string);
  373.             }
  374.             return false;
  375.         }
  376.         $em $this->getDoctrine();
  377.         $sql "SELECT positionName, id FROM users_positions WHERE department_id = :departmentId";
  378.         $query $em->getConnection()->prepare($sql);
  379.         $query->execute([
  380.             'departmentId' => $validator->valid['departmentId']
  381.         ]);
  382.         $positions $query->fetchAll();
  383.         return $this->json([
  384.             'message' => 'Shifts have been successfully retrieved.',
  385.             'status' => 0,
  386.             'data' => $positions
  387.         ]);
  388.     }
  389.     /**
  390.      * @Route("/staff", name="user_staff_list")
  391.      */
  392.     public function staffList(){
  393.         $em $this->getDoctrine()->getConnection();
  394.         $sqlStaffList "SELECT d.DepartmentName, u.id, u.realName, u.email, u.skype, u.phoneNumber, u.isActive, p.positionName
  395.                            FROM users as u
  396.                            INNER JOIN users_positions as p ON u.position_id = p.id
  397.                            INNER JOIN users_departments as d ON p.department_id = d.id
  398.                            WHERE u.isActive = '1'
  399.                            ORDER BY d.sortOrder ASC, p.positionPriority ASC";
  400.         $queryStaffList $em->prepare($sqlStaffList);
  401.         $queryStaffList->execute();
  402.         $staffList $queryStaffList->fetchAll(PDO::FETCH_GROUP);
  403.         return $this->render('default/user/staff_list.html.twig',[
  404.             'title' => 'Staff list',
  405.             'staffList' => $staffList
  406.         ]);
  407.     }
  408.     /**
  409.      * @Route("/pull/data", name="pull_data")
  410.      * @param Request $request
  411.      * @return \Symfony\Component\HttpFoundation\JsonResponse
  412.      */
  413.     public function pullData(Request $request){
  414.         /**
  415.          * List all the data that will be pulled and returned in the JSON.
  416.          */
  417.         $notifications $this->get('user_notification');
  418.         $activity $this->get('user_activity')->refreshActivity($request->headers->get('referer'));
  419.         return $this->json([
  420.             'message' => 'OK',
  421.             'status' => 0,
  422.             'data' => [
  423.                 'notifications' => $notifications->notificationsUnseen,
  424.                 'activity' => ($activity['status'] === 0) ? $activity['data'] : 'Failed to update activity.',
  425.                 'feedbackChats' => $notifications->notificationFeedbackChats,
  426.                 'feedbackTickets' => $notifications->notificationFeedbackTickets,
  427.                 'assignedIssues' => $notifications->notificationAssignedIssues
  428.             ]
  429.         ]);
  430.     }
  431. }