src/Controller/ManufacturerUsersController.php line 422

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\DistributorUsers;
  4. use App\Entity\ManufacturerUsers;
  5. use App\Form\ResetPasswordRequestFormType;
  6. use App\Services\PaginationManager;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Nzo\UrlEncryptorBundle\Encryptor\Encryptor;
  9. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  10. use Symfony\Component\HttpFoundation\JsonResponse;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\Mailer\MailerInterface;
  14. use Symfony\Component\Mime\Email;
  15. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  16. use Symfony\Component\Routing\Annotation\Route;
  17. class ManufacturerUsersController extends AbstractController
  18. {
  19.     private $em;
  20.     private $pageManager;
  21.     private $mailer;
  22.     private $plainPassword;
  23.     private $encryptor;
  24.     const ITEMS_PER_PAGE 10;
  25.     public function __construct(EntityManagerInterface $emPaginationManager $paginationMailerInterface $mailerEncryptor $encryptor)
  26.     {
  27.         $this->em $em;
  28.         $this->pageManager $pagination;
  29.         $this->mailer $mailer;
  30.         $this->encryptor $encryptor;
  31.     }
  32.     #[Route('/manufacturers/get-user'name'manufacturer_get_user_data')]
  33.     public function manufacturerGetUserDataAction(Request $request): Response
  34.     {
  35.         $user $this->em->getRepository(ManufacturerUsers::class)->find($request->request->get('id'));
  36.         $response = [
  37.             'id' => $user->getId(),
  38.             'firstName' => $this->encryptor->decrypt($user->getFirstName()),
  39.             'lastName' => $this->encryptor->decrypt($user->getLastName()),
  40.             'email' => $this->encryptor->decrypt($user->getEmail()),
  41.             'mobile' => $this->encryptor->decrypt($user->getTelephone()),
  42.             'telephone' => $this->encryptor->decrypt($user->getIntlCode()) . substr($this->encryptor->decrypt($user->getTelephone()), 1),
  43.             'isoCode' => $this->encryptor->decrypt($user->getIsoCode()),
  44.             'intlCode' => $this->encryptor->decrypt($user->getIntlCode()),
  45.         ];
  46.         return new JsonResponse($response);
  47.     }
  48.     #[Route('/manufacturers/manage-users'name'manufacturer_manage_user')]
  49.     public function manufacturerUsersAction(Request $requestUserPasswordHasherInterface $passwordHasherMailerInterface $mailer): Response
  50.     {
  51.         $data $request->request;
  52.         $manufacturer $this->getUser()->getManufacturer();
  53.         $user $this->em->getRepository(ManufacturerUsers::class)->findOneBy([
  54.             'hashedEmail' => md5($data->get('user-email'))
  55.         ]);
  56.         $userId = (int) $data->get('user-id');
  57.         if($user == null && $userId 0)
  58.         {
  59.             $response = [
  60.                 'response' => false,
  61.                 'message' => '<b><i class="fas fa-check-circle"></i> User details already exist.<div class="flash-close"><i class="fa-solid fa-xmark"></i></div>',
  62.             ];
  63.             return new JsonResponse($response);
  64.         }
  65.         if($userId == 0)
  66.         {
  67.             $manufacturerUser = new ManufacturerUsers();
  68.             $plainTextPwd $this->generatePassword();
  69.             $manufacturerUser->setIsPrimary(0);
  70.             if (!empty($plainTextPwd))
  71.             {
  72.                 $hashedPwd $passwordHasher->hashPassword($manufacturerUser$plainTextPwd);
  73.                 $manufacturerUser->setRoles(['ROLE_MANUFACTURER']);
  74.                 $manufacturerUser->setPassword($hashedPwd);
  75.                 // Send Email
  76.                 $body '<table style="padding: 8px; border-collapse: collapse; border: none; font-family: arial">';
  77.                 $body .= '<tr><td colspan="2">Hi '$data->get('firstName') .',</td></tr>';
  78.                 $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  79.                 $body .= '<tr><td colspan="2">Please use the credentials below login to the Fluid Backend.</td></tr>';
  80.                 $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  81.                 $body .= '<tr>';
  82.                 $body .= '    <td><b>URL: </b></td>';
  83.                 $body .= '    <td><a href="https://'$_SERVER['HTTP_HOST'] .'/manufacturers/login">https://'$_SERVER['HTTP_HOST'] .'/manufacturers/login</a></td>';
  84.                 $body .= '</tr>';
  85.                 $body .= '<tr>';
  86.                 $body .= '    <td><b>Username: </b></td>';
  87.                 $body .= '    <td>'$data->get('user-email') .'</td>';
  88.                 $body .= '</tr>';
  89.                 $body .= '<tr>';
  90.                 $body .= '    <td><b>Password: </b></td>';
  91.                 $body .= '    <td>'$plainTextPwd .'</td>';
  92.                 $body .= '</tr>';
  93.                 $body .= '</table>';
  94.                 $html $this->forward('App\Controller\ResetPasswordController::emailFooter', [
  95.                     'html'  => $body,
  96.                 ])->getContent();
  97.                 $subject 'Fluid Login Credentials';
  98.                 exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($html) .'" "'$data->get('user-email') .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  99.             }
  100.             $message '<b><i class="fas fa-check-circle"></i> User details successfully created.<div class="flash-close"><i class="fa-solid fa-xmark"></i></div>';
  101.         }
  102.         else
  103.         {
  104.             $manufacturerUser $this->em->getRepository(ManufacturerUsers::class)->find($userId);
  105.             $manufacturerUser->setIsPrimary($manufacturerUser->getIsPrimary());
  106.             $message '<b><i class="fas fa-check-circle"></i> User successfully updated.<div class="flash-close"><i class="fa-solid fa-xmark"></i></div>';
  107.         }
  108.         $manufacturerUser->setManufacturer($manufacturer);
  109.         $manufacturerUser->setFirstName($this->encryptor->encrypt($data->get('user-first-name')));
  110.         $manufacturerUser->setLastName($this->encryptor->encrypt($data->get('user-last-name')));
  111.         $manufacturerUser->setEmail($this->encryptor->encrypt($data->get('user-email')));
  112.         $manufacturerUser->setHashedEmail(md5($data->get('user-email')));
  113.         $manufacturerUser->setTelephone($this->encryptor->encrypt($data->get('user-mobile')));
  114.         $manufacturerUser->setIsoCode($this->encryptor->encrypt($data->get('user-iso-code')));
  115.         $manufacturerUser->setIntlCode($this->encryptor->encrypt($data->get('user-intl-code')));
  116.         $this->em->persist($manufacturerUser);
  117.         $this->em->flush();
  118.         // Get Users List
  119.         $usersList $this->forward('App\Controller\ManufacturerUsersController::manufacturerGetUsersAction')->getContent();
  120.         $response = [
  121.             'response' => true,
  122.             'message' => $message,
  123.             'usersList' => json_decode($usersList)
  124.         ];
  125.         return new JsonResponse($response);
  126.     }
  127.     #[Route('/manufacturers/get-users'name'manufacturer_get_users')]
  128.     public function manufacturerGetUsersAction(Request $request): Response
  129.     {
  130.         $manufacturerId $this->getUser()->getManufacturer()->getId();
  131.         $users $this->em->getRepository(ManufacturerUsers::class)->findManufacturerUsers($manufacturerId);
  132.         $userResults $this->pageManager->paginate($users[0], $requestself::ITEMS_PER_PAGE);
  133.         $pageId $request->request->get('page_id');
  134.         $html '
  135.         <div class="row" id="users">
  136.             <div class="col-12 mb-3 d-flex d-md-none">
  137.                 <button type="button" class="btn btn-secondary btn-sm float-end" data-bs-toggle="modal" data-bs-target="#modal_user" id="user_new">
  138.                     <i class="fa-solid fa-circle-plus"></i>
  139.                     ADD COLLEAGUE
  140.                 </button>
  141.             </div>
  142.             <div class="col-12 text-center pt-3 pb-3 mt-1">
  143.                 <h3 class="text-primary text-truncate">Manage User Accounts</h3>
  144.                 <span class="d-none d-sm-inline mb-5 mt-2 text-center text-primary text-sm-start">
  145.                     Fluid supports having several users under a single clinic. Each user will have their own login, can
  146.                     independently participate in the Fluid discussions. You have full control over editing the permissions
  147.                     of each user in your clinic. Use the table below to view the available permission levels.
  148.                 </span>
  149.             </div>
  150.             <div class="col-12 d-none d-xl-block">
  151.                 <div class="row">
  152.                     <div class="col-md-3 pt-3 pb-3 text-primary fw-bold bg-light border-bottom border-left border-top">
  153.                         First Name
  154.                     </div>
  155.                     <div class="col-md-3 pt-3 pb-3 text-primary fw-bold bg-light border-bottom border-top">
  156.                         Last Name
  157.                     </div>
  158.                     <div class="col-md-2 pt-3 pb-3 text-primary fw-bold bg-light border-bottom border-top">
  159.                         Username
  160.                     </div>
  161.                     <div class="col-md-2 pt-3 pb-3 text-primary fw-bold bg-light border-bottom border-top">
  162.                         Telephone
  163.                     </div>
  164.                     <div class="col-md-2 pt-3 pb-3 text-primary fw-bold bg-light border-bottom border-right border-top">
  165.                         <button type="button" class="bg-transparent float-end border-0 p-0 m-0" data-bs-toggle="modal" data-bs-target="#modal_user" id="user_new">
  166.                         <i class="fa-regular fa-square-plus float-end edit-icon"></i>
  167.                         </button>
  168.                     </div>
  169.                 </div>
  170.             </div>
  171.             <div class="col-12" id="users_list">';
  172.             $i 0;
  173.             $borderBottom 'border-bottom-dashed';
  174.             
  175.             foreach($userResults as $user)
  176.             {
  177.                 $i++;
  178.                 
  179.                 if(count($userResults) == $i)
  180.                 {
  181.                     $borderBottom 'border-bottom';
  182.                 }
  183.                 $html .= '
  184.                 <div class="row">
  185.                     <div 
  186.                         class="col-5 col-md-2 d-xl-none t-cell fw-bold bg-light border-left text-primary text-truncate '$borderBottom .' pt-3 pb-3"
  187.                     >
  188.                         First Name:
  189.                     </div>
  190.                     <div 
  191.                         class="col-7 col-md-10 col-xl-3 '$borderBottom .' pt-3 pb-3 t-cell text-truncate bg-light border-left" 
  192.                         id="string_user_first_name_'$user->getId() .'"
  193.                     >
  194.                         '$this->encryptor->decrypt($user->getFirstName()) .'
  195.                     </div>
  196.                     <div 
  197.                         class="col-5 col-md-2 d-xl-none t-cell fw-bold bg-light border-bottom text-primary text-truncate '$borderBottom .' pt-3 pb-3"
  198.                     >
  199.                         Last Name:
  200.                     </div>
  201.                     <div 
  202.                         class="col-7 col-md-10 col-xl-3 pt-3 pb-3 bg-light '$borderBottom .' border-bottom t-cell text-truncate"
  203.                         >
  204.                         '$this->encryptor->decrypt($user->getLastName()) .'
  205.                     </div>
  206.                     <div 
  207.                         class="col-5 col-md-2 d-xl-none t-cell fw-bold bg-light border-bottom border-left text-primary text-truncate '$borderBottom .' pt-3 pb-3"
  208.                     >
  209.                         Username:
  210.                     </div>
  211.                     <div 
  212.                         class="col-7 col-md-10 col-xl-2 pt-3 pb-3 bg-light '$borderBottom .' border-bottom t-cell text-truncate"
  213.                     >
  214.                         '$this->encryptor->decrypt($user->getEmail()) .'
  215.                     </div>
  216.                     <div 
  217.                         class="col-5 col-md-2 d-xl-none t-cell fw-bold bg-light border-bottom border-left text-primary text-truncate '$borderBottom .' pt-3 pb-3"
  218.                     >
  219.                         Telephone:
  220.                     </div>
  221.                     <div 
  222.                         class="col-7 col-md-10 col-xl-2 pt-3 pb-3 bg-light '$borderBottom .' border-bottom t-cell text-truncate"
  223.                     >
  224.                         '$this->encryptor->decrypt($user->getTelephone()) .'
  225.                     </div>
  226.                     <div class="col-md-2 t-cell bg-light '$borderBottom .' border-right">
  227.                         <a href="" class="float-end update-user" data-bs-toggle="modal" data-bs-target="#modal_user" data-user-id="'$user->getId() .'">
  228.                             <i class="fa-solid fa-pen-to-square edit-icon"></i>
  229.                         </a>';
  230.                 if($user->getIsPrimary() != 1)
  231.                 {
  232.                     $html .= '
  233.                             <a href="" class="delete-icon float-end delete-user" data-bs-toggle="modal"
  234.                                 data-value="' $user->getId() . '" data-bs-target="#modal_user_delete" data-user-id="' $user->getId() . '">
  235.                                 <i class="fa-solid fa-trash-can"></i>
  236.                             </a>';
  237.                 }
  238.                 $html .= '
  239.                     </div>
  240.                 </div>';
  241.             }
  242.             $html .= '
  243.             </div>
  244.             <!-- Modal Manage Users -->
  245.             <div class="modal fade" id="modal_user" tabindex="-1" aria-labelledby="modal_user" aria-hidden="true">
  246.                 <div class="modal-dialog modal-dialog-centered modal-xl">
  247.                     <div class="modal-content">
  248.                         <form name="form_users" id="form_users" method="post">
  249.                             <input type="hidden" name="user-id" id="user_id" value="0">
  250.                             <div class="modal-header">
  251.                                 <h5 class="modal-title" id="user_modal_label"></h5>
  252.                                 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  253.                             </div>
  254.                             <div class="modal-body">
  255.                                 <div class="row mb-3">
  256.                                     <!-- First Name -->
  257.                                     <div class="col-12 col-sm-6">
  258.                                         <label>First Name <span class="text-danger">*</span></label>
  259.                                         <input type="hidden" value="" name="distributor_users_form[user_id]" id="user_id">
  260.                                         <input
  261.                                             type="text"
  262.                                             name="user-first-name"
  263.                                             id="user_first_name"
  264.                                             class="form-control"
  265.                                             placeholder="First Name"
  266.                                         >
  267.                                         <div class="hidden_msg" id="error_user_first_name">
  268.                                             Required Field
  269.                                         </div>
  270.                                     </div>
  271.                                     <!-- Last Name -->
  272.                                     <div class="col-12 col-sm-6">
  273.                                         <label>Last Name <span class="text-danger">*</span></label>
  274.                                         <input
  275.                                             type="text"
  276.                                             name="user-last-name"
  277.                                             id="user_last_name"
  278.                                             class="form-control"
  279.                                             placeholder="last Name"
  280.                                         >
  281.                                         <div class="hidden_msg" id="error_user_last_name">
  282.                                             Required Field
  283.                                         </div>
  284.                                     </div>
  285.                                 </div>
  286.                                 <div class="row mb-3">
  287.                                     <!-- Email -->
  288.                                     <div class="col-12 col-sm-6">
  289.                                         <label>Email <span class="text-danger">*</span></label>
  290.                                         <input
  291.                                             type="text"
  292.                                             name="user-email"
  293.                                             id="user_email"
  294.                                             class="form-control"
  295.                                             placeholder="Email Address"
  296.                                         >
  297.                                         <div class="hidden_msg" id="error_user_email">
  298.                                             Required Field
  299.                                         </div>
  300.                                     </div>
  301.                                     <!-- Telephone Number -->
  302.                                     <div class="col-12 col-sm-6">
  303.                                         <label>Telephone <span class="text-danger">*</span></label>
  304.                                         <span id="telephone_container">
  305.                                             <input
  306.                                                 type="text"
  307.                                                 class="form-control"
  308.                                                 name="user-mobile"
  309.                                                 id="user_mobile"
  310.                                                 placeholder="(123) 456-7890*"
  311.                                             >
  312.                                         </span>
  313.                                         <div class="hidden_msg" id="error_user_telephone">
  314.                                             Required Field
  315.                                         </div>
  316.                                         <input type="hidden" name="user-telephone" id="user_telephone">
  317.                                         <input type="hidden" name="user-iso-code" id="user_iso_code">
  318.                                         <input type="hidden" name="user-intl-code" id="user_intl_code">
  319.                                     </div>
  320.                                 </div>
  321.                             </div>
  322.                             <div class="modal-footer">
  323.                                 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">CANCEL</button>
  324.                                 <button type="submit" class="btn btn-primary" id="create_user">SAVE</button>
  325.                             </div>
  326.                         </form>
  327.                     </div>
  328.                 </div>
  329.             </div>
  330.             <!-- Modal Delete User -->
  331.             <div class="modal fade" id="modal_user_delete" tabindex="-1" aria-labelledby="user_delete_label" aria-hidden="true">
  332.                 <div class="modal-dialog modal-dialog-centered">
  333.                     <div class="modal-content">
  334.                         <div class="modal-header">
  335.                             <h5 class="modal-title" id="user_delete_label">Delete User</h5>
  336.                             <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  337.                         </div>
  338.                         <div class="modal-body">
  339.                             <div class="row">
  340.                                 <div class="col-12 mb-0">
  341.                                     Are you sure you would like to delete this user? This action cannot be undone.
  342.                                 </div>
  343.                             </div>
  344.                         </div>
  345.                         <div class="modal-footer">
  346.                             <button type="button" class="btn btn-primary btn-sm" data-bs-dismiss="modal">CANCEL</button>
  347.                             <button type="submit" class="btn btn-danger btn-sm" id="delete_user">DELETE</button>
  348.                         </div>
  349.                     </div>
  350.                 </div>
  351.             </div>
  352.         </div>';
  353.         $pagination $this->getPagination($pageId ?? 1$userResults$manufacturerId);
  354.         $html .= $pagination;
  355.         return new JsonResponse($html);
  356.     }
  357.     #[Route('/manufacturers/user/delete'name'manufacturer_user_delete')]
  358.     public function manufacturerDeleteUser(Request $request): Response
  359.     {
  360.         $userId = (int) $request->request->get('id');
  361.         $user $this->em->getRepository(ManufacturerUsers::class)->find($userId);
  362.         $this->em->remove($user);
  363.         $this->em->flush();
  364.         // Get Users List
  365.         $response['html'] = json_decode($this->forward('App\Controller\ManufacturerUsersController::manufacturerGetUsersAction')->getContent());
  366.         $response['flash'] = '<b><i class="fas fa-check-circle"></i> User successfully deleted.<div class="flash-close"><i class="fa-solid fa-xmark"></i></div>';
  367.         return new JsonResponse($response);
  368.     }
  369.     #[Route('/manufacturer/forgot-password'name'manufacturers_forgot_password_request')]
  370.     public function clinicForgotPasswordAction(Request $requestMailerInterface $mailer): Response
  371.     {
  372.         $form $this->createForm(ResetPasswordRequestFormType::class);
  373.         $form->handleRequest($request);
  374.         if ($form->isSubmitted() && $form->isValid())
  375.         {
  376.             $manufacturerUser $this->em->getRepository(ManufacturerUsers::class)->findOneBy(
  377.                 [
  378.                     'hashedEmail' => md5($request->request->get('reset_password_request_form')['email'])
  379.                 ]
  380.             );
  381.             if($manufacturerUser != null)
  382.             {
  383.                 $resetToken uniqid();
  384.                 $manufacturerUser->setResetKey($resetToken);
  385.                 $this->em->persist($manufacturerUser);
  386.                 $this->em->flush();
  387.                 $html '
  388.                 <p>To reset your password, please visit the following link</p>
  389.                 <p>
  390.                     <a
  391.                         href="https://'$_SERVER['HTTP_HOST'] .'/manufacturers/reset/'$resetToken .'"
  392.                     >https://'$_SERVER['HTTP_HOST'] .'/manufacturers/reset/'$resetToken .'</a>
  393.                 </p>';
  394.                 $html $this->forward('App\Controller\ResetPasswordController::emailFooter', [
  395.                     'html'  => $html,
  396.                 ])->getContent();
  397.                 $subject 'Fluid Password Reset';
  398.                 $to $this->encryptor->decrypt($manufacturerUser->getEmail());
  399.                 exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($html) .'" "'$to .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  400.                 return $this->render('reset_password/manufacturers_check_email.html.twig');
  401.             }
  402.         }
  403.         return $this->render('reset_password/request.html.twig', [
  404.             'requestForm' => $form->createView(),
  405.         ]);
  406.     }
  407.     #[Route('/manufacturers/reset/{token}'name'manufacturers_reset_password')]
  408.     public function reset(Request $requestUserPasswordHasherInterface $passwordHasherstring $token nullMailerInterface $mailer): Response
  409.     {
  410.         $plainTextPwd $this->generatePassword();
  411.         $manufacturerUser $this->em->getRepository(DistributorUsers::class)->findOneBy([
  412.             'resetKey' => $request->get('token')
  413.         ]);
  414.         if (!empty($plainTextPwd))
  415.         {
  416.             $hashedPwd $passwordHasher->hashPassword($manufacturerUser$plainTextPwd);
  417.             $manufacturerUser->setPassword($hashedPwd);
  418.             $this->em->persist($manufacturerUser);
  419.             $this->em->flush();
  420.             // Send Email
  421.             $body  '<p style="margin-bottom: 0">Hi '$this->encryptor->decrypt($manufacturerUser->getFirstName()) .',</p>';
  422.             $body .= '<br>';
  423.             $body .= '<p style="margin-bottom: 0">Please use the credentials below login to the Fluid Backend.</p>';
  424.             $body .= '<br>';
  425.             $body .= '<table style="border: none; font-family: Arial, Helvetica, sans-serif">';
  426.             $body .= '<tr>';
  427.             $body .= '    <td><b>URL: </b></td>';
  428.             $body .= '    <td><a href="https://'$_SERVER['HTTP_HOST'] .'/manufacturers/login">https://'$_SERVER['HTTP_HOST'] .'/manufacturers/login</a></td>';
  429.             $body .= '</tr>';
  430.             $body .= '<tr>';
  431.             $body .= '    <td><b>Username: </b></td>';
  432.             $body .= '    <td>'$this->encryptor->decrypt($manufacturerUser->getEmail()) .'</td>';
  433.             $body .= '</tr>';
  434.             $body .= '<tr>';
  435.             $body .= '    <td><b>Password: </b></td>';
  436.             $body .= '    <td>'$plainTextPwd .'</td>';
  437.             $body .= '</tr>';
  438.             $body .= '</table>';
  439.             $html $this->forward('App\Controller\ResetPasswordController::emailFooter', [
  440.                 'html'  => $body,
  441.             ])->getContent();
  442.             $subject 'Fluid Login Credentials';
  443.             $to $this->encryptor->decrypt($manufacturerUser->getEmail());
  444.             exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($html) .'" "'$to .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  445.         }
  446.         return $this->redirectToRoute('manufacturers_password_reset');
  447.     }
  448.     #[Route('/manufacturers/password/reset'name'manufacturers_password_reset')]
  449.     public function manufacturerPasswordReset(Request $request): Response
  450.     {
  451.         return $this->render('reset_password/manufacturers_password_reset.html.twig');
  452.     }
  453.     private function generatePassword()
  454.     {
  455.         $sets = [];
  456.         $sets[] = 'abcdefghjkmnpqrstuvwxyz';
  457.         $sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ';
  458.         $sets[] = '23456789';
  459.         $sets[] = '!@$%*?';
  460.         $all '';
  461.         $password '';
  462.         foreach ($sets as $set)
  463.         {
  464.             $password .= $set[array_rand(str_split($set))];
  465.             $all .= $set;
  466.         }
  467.         $all str_split($all);
  468.         for ($i 0$i 16 count($sets); $i++)
  469.         {
  470.             $password .= $all[array_rand($all)];
  471.         }
  472.         $this->plainPassword str_shuffle($password);
  473.         return $this->plainPassword;
  474.     }
  475.     private function sendLoginCredentials($clinic_user$plainTextPwd$data)
  476.     {
  477.         // Send Email
  478.         $body '<table style="padding: 8px; border-collapse: collapse; border: none; font-family: arial">';
  479.         $body .= '<tr><td colspan="2">Hi '$data['firstName'] .',</td></tr>';
  480.         $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  481.         $body .= '<tr><td colspan="2">Please use the credentials below login to the Fluid Backend.</td></tr>';
  482.         $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  483.         $body .= '<tr>';
  484.         $body .= '    <td><b>URL: </b></td>';
  485.         $body .= '    <td><a href="https://'$_SERVER['HTTP_HOST'] .'/clinics/login">https://'$_SERVER['HTTP_HOST'] .'/clinics/login</a></td>';
  486.         $body .= '</tr>';
  487.         $body .= '<tr>';
  488.         $body .= '    <td><b>Username: </b></td>';
  489.         $body .= '    <td>'$data['email'] .'</td>';
  490.         $body .= '</tr>';
  491.         $body .= '<tr>';
  492.         $body .= '    <td><b>Password: </b></td>';
  493.         $body .= '    <td>'$plainTextPwd .'</td>';
  494.         $body .= '</tr>';
  495.         $body .= '</table>';
  496.         $subject 'Fluid Login Credentials';
  497.         $to $data['email'];
  498.         exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($body) .'" "'$to .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  499.     }
  500.     public function getPagination($pageId$results$manufacturerId)
  501.     {
  502.         $currentPage = (int) $pageId;
  503.         $lastPage $this->pageManager->lastPage($results);
  504.         $pagination '
  505.         <!-- Pagination -->
  506.         <div class="row mt-3">
  507.             <div class="col-12">';
  508.         if($lastPage 1) {
  509.             $previousPageNo $currentPage 1;
  510.             $url '/manufacturers/users';
  511.             $previousPage $url $previousPageNo;
  512.             $pagination .= '
  513.             <nav class="custom-pagination">
  514.                 <ul class="pagination justify-content-center">
  515.             ';
  516.             $disabled 'disabled';
  517.             $dataDisabled 'true';
  518.             // Previous Link
  519.             if ($currentPage 1)
  520.             {
  521.                 $disabled '';
  522.                 $dataDisabled 'false';
  523.             }
  524.             $pagination .= '
  525.             <li class="page-item ' $disabled '">
  526.                 <a 
  527.                     class="user-pagination" 
  528.                     aria-disabled="' $dataDisabled '" 
  529.                     data-page-id="' $currentPage '" 
  530.                     data-manufacturer-id="' $manufacturerId '"
  531.                     href="' $previousPage '"
  532.                 >
  533.                     <span aria-hidden="true">&laquo;</span> <span class="d-none d-sm-inline">Previous</span>
  534.                 </a>
  535.             </li>';
  536.             for ($i 1$i <= $lastPage$i++)
  537.             {
  538.                 $active '';
  539.                 if ($i == (int)$currentPage) {
  540.                     $active 'active';
  541.                 }
  542.                 $pagination .= '
  543.                 <li class="page-item ' $active '">
  544.                     <a 
  545.                         class="user-pagination" 
  546.                         data-page-id="' $i '" 
  547.                         href="' $url '"
  548.                         data-manufacturer-id="' $manufacturerId '"
  549.                     >' $i '</a>
  550.                 </li>';
  551.             }
  552.             $disabled 'disabled';
  553.             $dataDisabled 'true';
  554.             if ($currentPage $lastPage)
  555.             {
  556.                 $disabled '';
  557.                 $dataDisabled 'false';
  558.             }
  559.             $pagination .= '
  560.             <li class="page-item ' $disabled '">
  561.                 <a 
  562.                     class="user-pagination" 
  563.                     aria-disabled="' $dataDisabled '" 
  564.                     data-page-id="' $currentPage '" 
  565.                     href="' $url '"
  566.                     data-manufacturer-id="' $manufacturerId '"
  567.                 >
  568.                     <span class="d-none d-sm-inline">Next</span> <span aria-hidden="true">&raquo;</span>
  569.                 </a>
  570.             </li>';
  571.             $pagination .= '
  572.                     </ul>
  573.                 </nav>';
  574.         }
  575.         $pagination .= '
  576.             </div>
  577.         </div>';
  578.         return $pagination;
  579.     }
  580. }