src/Controller/ClinicUsersController.php line 391

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Clinics;
  4. use App\Entity\ClinicUserPermissions;
  5. use App\Entity\ClinicUsers;
  6. use App\Entity\UserPermissions;
  7. use App\Form\ResetPasswordRequestFormType;
  8. use App\Services\PaginationManager;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Nzo\UrlEncryptorBundle\Encryptor\Encryptor;
  11. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  12. use Symfony\Component\HttpFoundation\JsonResponse;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\Mailer\MailerInterface;
  16. use Symfony\Component\Mime\Email;
  17. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. class ClinicUsersController extends AbstractController
  20. {
  21.     private $em;
  22.     private $page_manager;
  23.     private $mailer;
  24.     private $encryptor;
  25.     const ITEMS_PER_PAGE 6;
  26.     public function __construct(EntityManagerInterface $emPaginationManager $page_managerMailerInterface $mailerEncryptor $encryptor)
  27.     {
  28.         $this->em $em;
  29.         $this->page_manager $page_manager;
  30.         $this->mailer $mailer;
  31.         $this->encryptor $encryptor;
  32.     }
  33.     #[Route('/clinics/get-clinic-users'name'get-clinic-users')]
  34.     public function getClinicUsersAction(Request $request): Response
  35.     {
  36.         $permissions json_decode($request->request->get('permissions'), true);
  37.         if(!in_array(6$permissions)){
  38.             $html $this->render('frontend/clinics/access_denied.html.twig');
  39.             $response = [
  40.                 'html' => $html,
  41.                 'pagination' => ''
  42.             ];
  43.             return new JsonResponse($response);
  44.         }
  45.         $clinic $this->getUser()->getClinic();
  46.         $clinic_users $this->em->getRepository(ClinicUsers::class)->findClinicUsers($clinic->getId());
  47.         $results $this->page_manager->paginate($clinic_users[0], $requestself::ITEMS_PER_PAGE);
  48.         $pagination $this->forward('App\Controller\ProductsController::getPagination', [
  49.             'pageId'  => $request->request->get('page-id'),
  50.             'results' => $results,
  51.             'url' => '/clinics/users/',
  52.             'dataAction' => 'data-action="click->clinics--users#onClickPagination"',
  53.             'itemsPerPage' => self::ITEMS_PER_PAGE,
  54.         ])->getContent();
  55.         $user_permissions $this->em->getRepository(UserPermissions::class)->findBy([
  56.             'isClinic' => 1
  57.         ]);
  58.         $html $this->render('frontend/clinics/users.html.twig', [
  59.             'users' => $results,
  60.             'pageId' => $request->request->get('page_id'),
  61.             'userPermissions' => $user_permissions,
  62.             'pagination' => $pagination,
  63.         ])->getContent();
  64.         $response = [
  65.             'html' => $html,
  66.         ];
  67.         
  68.         return new JsonResponse($response);
  69.     }
  70.     #[Route('/clinics/get-user'name'clinic_get_user')]
  71.     public function clinicsGetUserAction(Request $request): Response
  72.     {
  73.         $user $this->em->getRepository(ClinicUsers::class)->find($request->request->get('id'));
  74.         $permissions = [];
  75.         foreach($user->getClinicUserPermissions() as $permission){
  76.             $permissions[] = $permission->getPermission()->getId();
  77.         }
  78.         $encryptedWhiteSpace '5btuAewE-zQ3DwAsyXmH4A';
  79.         $response = [
  80.             'id' => $user->getId(),
  81.             'firstName' => $this->encryptor->decrypt($user->getFirstName() ?? $encryptedWhiteSpace),
  82.             'lastName' => $this->encryptor->decrypt($user->getLastName() ?? $encryptedWhiteSpace),
  83.             'email' => $this->encryptor->decrypt($user->getEmail()),
  84.             'telephone' => $this->encryptor->decrypt($user->getTelephone() ?? $encryptedWhiteSpace),
  85.             'position' => $this->encryptor->decrypt($user->getPosition() ?? $encryptedWhiteSpace),
  86.             'isoCode' => $this->encryptor->decrypt($user->getIsoCode() ?? $encryptedWhiteSpace),
  87.             'intlCode' => $this->encryptor->decrypt($user->getIntlCode() ?? $encryptedWhiteSpace),
  88.             'permissions' => $permissions,
  89.         ];
  90.         return new JsonResponse($response);
  91.     }
  92.     #[Route('/clinics/user/delete'name'clinic_user_delete')]
  93.     public function clinicDeleteUser(Request $request): Response
  94.     {
  95.         $userId $request->request->get('id');
  96.         $userPermissions $this->em->getRepository(ClinicUserPermissions::class)->findBy([
  97.             'user' => $userId
  98.         ]);
  99.         $user $this->em->getRepository(ClinicUsers::class)->find($userId);
  100.         // Delete the users permissions
  101.         foreach ($userPermissions as $userPermission){
  102.             $this->em->remove($userPermission);
  103.         }
  104.         $this->em->remove($user);
  105.         $this->em->flush();
  106.         $response '<b><i class="fas fa-check-circle"></i> User successfully deleted.<div class="flash-close"><i class="fa-solid fa-xmark"></i></div>';
  107.         return new JsonResponse($response);
  108.     }
  109.     #[Route('/clinics/users-refresh'name'clinic_refresh_users')]
  110.     public function clinicRefreshUsersAction(Request $request): Response
  111.     {
  112.         $clinic_id $this->getUser()->getClinic()->getId();
  113.         $users $this->em->getRepository(ClinicUsers::class)->findClinicUsers($clinic_id);
  114.         $results $this->page_manager->paginate($users[0], $requestself::ITEMS_PER_PAGE);
  115.         $pagination $this->forward('App\Controller\ProductsController::getPagination', [
  116.             'pageId'  => $request->request->get('page-id'),
  117.             'results' => $results,
  118.             'url' => '/clinics/users/',
  119.             'dataAction' => 'data-action="click->clinics--users#onClickPagination"',
  120.             'itemsPerPage' => self::ITEMS_PER_PAGE,
  121.         ])->getContent();
  122.         $html '
  123.         <div class="row" id="users">
  124.             <div class="col-12 col-md-12 mb-3 mt-0">
  125.                 <!-- Create New -->
  126.                 <button 
  127.                     type="button" 
  128.                     class="btn btn-primary float-end w-sm-100" 
  129.                     data-bs-toggle="modal" 
  130.                     data-bs-target="#modal_user" 
  131.                     id="user_new"
  132.                     data-action="click->clinics--users#onClickNewUser"
  133.                 >
  134.                     <i class="fa-solid fa-circle-plus"></i> ADD COLLEAGUE
  135.                 </button>
  136.             </div>
  137.         </div>
  138.         <div class="row">
  139.             <div class="col-12 text-center pt-3 pb-3 mt-4" id="order_header">
  140.                 <h4 class="text-primary">Manage User Accounts</h4>
  141.                 <span class="mb-5 mt-2 text-center text-primary text-sm-start">
  142.                     Fluid supports having several users under a single clinic. Each user will have their own login, 
  143.                     can independently participate in the Fluid discussions. You have full control over editing the 
  144.                     permissions of each user in your clinic. Use the table below to view the available permission levels.
  145.                 </span>
  146.             </div>
  147.         </div>
  148.         <div class="row d-none d-xl-flex bg-light border-xy">
  149.             <div class="col-md-2 pt-3 pb-3 text-primary fw-bold">
  150.                 First Name
  151.             </div>
  152.             <div class="col-md-2 pt-3 pb-3 text-primary fw-bold">
  153.                 Last Name
  154.             </div>
  155.             <div class="col-md-2 pt-3 pb-3 text-primary fw-bold">
  156.                 Username
  157.             </div>
  158.             <div class="col-md-2 pt-3 pb-3 text-primary fw-bold">
  159.                 Telephone
  160.             </div>
  161.             <div class="col-md-2 pt-3 pb-3 text-primary fw-bold">
  162.                 Position
  163.             </div>
  164.             <div class="col-md-2 pt-3 pb-3 text-primary fw-bold">
  165.             </div>
  166.         </div>';
  167.         foreach($results as $user){
  168.             $html .= '
  169.             <div>
  170.                <div class="row bg-light border-left border-bottom">
  171.                    <div class="col-md-2 t-cell fw-bold text-primary text-truncate border-list pt-3 pb-3" id="string_user_first_name_'$user->getId() .'">
  172.                        '$this->encryptor->decrypt($user->getFirstName()) .'
  173.                    </div>
  174.                    <div class="col-md-2 t-cell text-primary text-truncate border-list pt-3 pb-3" id="string_user_last_name_'$user->getId() .'">
  175.                        '$this->encryptor->decrypt($user->getLastName()) .'
  176.                    </div>
  177.                    <div class="col-md-2 t-cell text-primary text-truncate border-list pt-3 pb-3" id="string_user_email_'$user->getId() .'">
  178.                        '$this->encryptor->decrypt($user->getEmail()) .'
  179.                    </div>
  180.                    <div class="col-md-2 t-cell text-primary text-truncate border-list pt-3 pb-3" id="string_user_telephone_'$user->getId() .'">
  181.                        '$this->encryptor->decrypt($user->getTelephone()) .'
  182.                    </div>
  183.                    <div class="col-md-2 t-cell text-primary text-truncate border-list pt-3 pb-3" id="string_user_position_'$user->getId() .'">
  184.                        '$this->encryptor->decrypt($user->getPosition()) .'
  185.                    </div>
  186.                    <div class="col-md-2 t-cell text-primary border-list pt-3 pb-3">
  187.                        <a href="" class="float-end" data-bs-toggle="modal" data-bs-target="#modal_user" id="user_update_'$user->getId() .'">
  188.                            <i class="fa-solid fa-pen-to-square edit-icon"></i>
  189.                        </a>';
  190.                        if($user->getIsPrimary() != 1)
  191.                        {
  192.                            $html .= '
  193.                            <a 
  194.                               href="" 
  195.                               class="delete-icon float-end open-delete-user-modal" 
  196.                               data-bs-toggle="modal"
  197.                               data-user-id="' $user->getId() . '" 
  198.                               data-bs-target="#modal_user_delete"
  199.                               data-action="click->clinics--users#onClickDeleteModal"
  200.                           >
  201.                                <i class="fa-solid fa-trash-can"></i>
  202.                            </a>';
  203.                        }
  204.                    $html .= '
  205.                    </div>
  206.                </div>
  207.            </div>';
  208.         }
  209.         $html .= $pagination;
  210.         return new JsonResponse($html);
  211.     }
  212.     #[Route('/clinics/get-users'name'clinic_get_users')]
  213.     public function clinicUsersAction(Request $requestUserPasswordHasherInterface $passwordHasherMailerInterface $mailer): Response
  214.     {
  215.         $data $request->request->get('clinic_users_form');
  216.         $clinic $this->get('security.token_storage')->getToken()->getUser()->getClinic();
  217.         $user $this->em->getRepository(ClinicUsers::class)->find($data['email']);
  218.         $userId $data['user_id'];
  219.         $pageId $request->request->get('pageId') ?? 1;
  220.         $sendEmail false;
  221.         if($userId == 0){
  222.             if($user != null){
  223.                 $response = [
  224.                     'response' => false
  225.                 ];
  226.                 return new JsonResponse($response);
  227.             }
  228.             $clinicUser = new ClinicUsers();
  229.             $plainTextPwd $this->generatePassword();
  230.             $sendEmail true;
  231.             if (!empty($plainTextPwd)) {
  232.                 $hashedPwd $passwordHasher->hashPassword($clinicUser$plainTextPwd);
  233.                 $clinicUser->setRoles(['ROLE_CLINIC']);
  234.                 $clinicUser->setPassword($hashedPwd);
  235.                 // Send Email
  236.                 $body '<table style="padding: 8px; border-collapse: collapse; border: none; font-family: arial">';
  237.                 $body .= '<tr><td colspan="2">Hi '$data['firstName'] .',</td></tr>';
  238.                 $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  239.                 $body .= '<tr><td colspan="2">Please use the credentials below login to the Fluid Backend.</td></tr>';
  240.                 $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  241.                 $body .= '<tr>';
  242.                 $body .= '    <td><b>URL: </b></td>';
  243.                 $body .= '    <td><a href="https://'$_SERVER['HTTP_HOST'] .'/clinics/login">https://'$_SERVER['HTTP_HOST'] .'/clinics/login</a></td>';
  244.                 $body .= '</tr>';
  245.                 $body .= '<tr>';
  246.                 $body .= '    <td><b>Username: </b></td>';
  247.                 $body .= '    <td>'$data['email'] .'</td>';
  248.                 $body .= '</tr>';
  249.                 $body .= '<tr>';
  250.                 $body .= '    <td><b>Password: </b></td>';
  251.                 $body .= '    <td>'$plainTextPwd .'</td>';
  252.                 $body .= '</tr>';
  253.                 $body .= '</table>';
  254.                 $body $this->forward('App\Controller\ResetPasswordController::emailFooter', [
  255.                     'html'  => $body,
  256.                 ])->getContent();
  257.                 $send_email true;
  258.             }
  259.             $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>';
  260.         } else {
  261.             $clinicUser $this->em->getRepository(ClinicUsers::class)->find($userId);
  262.             $message '<b><i class="fas fa-check-circle"></i> User successfully updated.<div class="flash-close"><i class="fa-solid fa-xmark"></i></div>';
  263.         }
  264.         $isPrimary 0;
  265.         if($clinicUser->getIsPrimary() == 1){
  266.             $isPrimary 1;
  267.         }
  268.         $clinicUser->setClinic($clinic);
  269.         $clinicUser->setFirstName($this->encryptor->encrypt($data['firstName']));
  270.         $clinicUser->setLastName($this->encryptor->encrypt($data['lastName']));
  271.         $clinicUser->setEmail($this->encryptor->encrypt($data['email']));
  272.         $clinicUser->setHashedEmail(md5($data['email']));
  273.         $clinicUser->setTelephone($this->encryptor->encrypt($data['telephone']));
  274.         $clinicUser->setIsoCode($this->encryptor->encrypt($data['isoCode']));
  275.         $clinicUser->setIntlCode($this->encryptor->encrypt($data['intlCode']));
  276.         $clinicUser->setPosition($this->encryptor->encrypt($data['position']));
  277.         $clinicUser->setIsPrimary($isPrimary);
  278.         $this->em->persist($clinicUser);
  279.         $this->em->flush();
  280.         // Update user permissions
  281.         if($clinicUser->getIsPrimary() != 1) {
  282.             // Remove previous entries
  283.             $permissions $this->em->getRepository(ClinicUserPermissions::class)->findBy(['user' => $clinicUser->getId()]);
  284.             if ($permissions 0) {
  285.                 foreach ($permissions as $permission) {
  286.                     $permissionRepo $this->em->getRepository(ClinicUserPermissions::class)->find($permission->getId());
  287.                     $this->em->remove($permissionRepo);
  288.                 }
  289.             }
  290.             // Save new permissions
  291.             if (count($data['permission']) > 0) {
  292.                 foreach ($data['permission'] as $permission) {
  293.                     $clinicUserPermission = new ClinicUserPermissions();
  294.                     $user $this->em->getRepository(ClinicUsers::class)->find($clinicUser->getId());
  295.                     $userPermission $this->em->getRepository(UserPermissions::class)->find($permission);
  296.                     $clinicUserPermission->setClinic($clinic);
  297.                     $clinicUserPermission->setUser($user);
  298.                     $clinicUserPermission->setPermission($userPermission);
  299.                     $this->em->persist($clinicUserPermission);
  300.                 }
  301.                 $this->em->flush();
  302.             }
  303.         }
  304.         if($sendEmail)
  305.         {
  306.             $emailTo $data['email'];
  307.             $subject 'Fluid Login Credentials';
  308.             exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($body) .'" "'$emailTo .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  309.         }
  310.         $response = [
  311.             'response' => true,
  312.             'message' => $message,
  313.             'page_id' => $pageId,
  314.         ];
  315.         return new JsonResponse($response);
  316.     }
  317.     #[Route('/clinics/forgot-password'name'clinic_forgot_password_request')]
  318.     public function clinicForgotPasswordAction(Request $requestMailerInterface $mailer): Response
  319.     {
  320.         $form $this->createForm(ResetPasswordRequestFormType::class);
  321.         $form->handleRequest($request);
  322.         if ($form->isSubmitted() && $form->isValid()) {
  323.             $clinic_user $this->em->getRepository(ClinicUsers::class)->findOneBy(
  324.                 [
  325.                     'hashedEmail' => md5($request->request->get('reset_password_request_form')['email'])
  326.                 ]
  327.             );
  328.             if($clinic_user != null){
  329.                 $resetToken uniqid();
  330.                 $clinic_user->setResetKey($resetToken);
  331.                 $this->em->persist($clinic_user);
  332.                 $this->em->flush();
  333.                 $html '
  334.                 <p>To reset your password, please visit the following link</p>
  335.                 <p>
  336.                     <a
  337.                         href="https://'$_SERVER['HTTP_HOST'] .'/clinics/reset/'$resetToken .'"
  338.                     >https://'$_SERVER['HTTP_HOST'] .'/clinics/reset/'$resetToken .'</a>
  339.                 </p>';
  340.                 $html $this->forward('App\Controller\ResetPasswordController::emailFooter', [
  341.                     'html'  => $html,
  342.                 ]);
  343.                 $emailTo $this->encryptor->decrypt($clinic_user->getEmail());
  344.                 $subject 'Fluid Password Reset';
  345.                 exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($html->getContent()) .'" "'$emailTo .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  346.                 return $this->render('reset_password/clinics_check_email.html.twig');
  347.             }
  348.         }
  349.         return $this->render('reset_password/request.html.twig', [
  350.             'requestForm' => $form->createView(),
  351.         ]);
  352.     }
  353.     #[Route('/clinics/reset/{token}'name'clinic_reset_password')]
  354.     public function reset(Request $requestUserPasswordHasherInterface $passwordHasherstring $token nullMailerInterface $mailer): Response
  355.     {
  356.         $plain_text_pwd $this->generatePassword();
  357.         $clinic_user $this->em->getRepository(ClinicUsers::class)->findOneBy([
  358.             'resetKey' => $request->get('token')
  359.         ]);
  360.         if (!empty($plain_text_pwd)) {
  361.             $hashed_pwd $passwordHasher->hashPassword($clinic_user$plain_text_pwd);
  362.             $clinic_user->setPassword($hashed_pwd);
  363.             $this->em->persist($clinic_user);
  364.             $this->em->flush();
  365.             // Send Email
  366.             $body  '<p style="margin-bottom: 0">Hi '$this->encryptor->decrypt($clinic_user->getFirstName()) .',</p>';
  367.             $body .= '<br>';
  368.             $body .= '<p style="margin-bottom: 0">Please use the credentials below login to the Fluid Backend.</p>';
  369.             $body .= '<br>';
  370.             $body .= '<table style="border: none; font-family: Arial, Helvetica, sans-serif">';
  371.             $body .= '<tr>';
  372.             $body .= '    <td><b>URL: </b></td>';
  373.             $body .= '    <td><a href="https://'$_SERVER['HTTP_HOST'] .'/clinics/login">https://'$_SERVER['HTTP_HOST'] .'/clinics/login</a></td>';
  374.             $body .= '</tr>';
  375.             $body .= '<tr>';
  376.             $body .= '    <td><b>Username: </b></td>';
  377.             $body .= '    <td>'$this->encryptor->decrypt($clinic_user->getEmail()) .'</td>';
  378.             $body .= '</tr>';
  379.             $body .= '<tr>';
  380.             $body .= '    <td><b>Password: </b></td>';
  381.             $body .= '    <td>'$plain_text_pwd .'</td>';
  382.             $body .= '</tr>';
  383.             $body .= '</table>';
  384.             $html $this->forward('App\Controller\ResetPasswordController::emailFooter', [
  385.                 'html'  => $body,
  386.             ]);
  387.             $emailTo $this->encryptor->decrypt($clinic_user->getEmail());
  388.             $subject 'Fluid Login Credentials';
  389.             exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($html->getContent()) .'" "'$emailTo .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  390.         }
  391.         return $this->redirectToRoute('clinics_password_reset');
  392.     }
  393.     #[Route('/clinics/password/reset'name'clinics_password_reset')]
  394.     public function clinicPasswordReset(Request $request): Response
  395.     {
  396.         return $this->render('reset_password/clinics_password_reset.html.twig');
  397.     }
  398.     
  399.     private function generatePassword()
  400.     {
  401.         $sets = [];
  402.         $sets[] = 'abcdefghjkmnpqrstuvwxyz';
  403.         $sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ';
  404.         $sets[] = '23456789';
  405.         $sets[] = '!@$%*?';
  406.         $all '';
  407.         $password '';
  408.         foreach ($sets as $set) {
  409.             $password .= $set[array_rand(str_split($set))];
  410.             $all .= $set;
  411.         }
  412.         $all str_split($all);
  413.         for ($i 0$i 16 count($sets); $i++) {
  414.             $password .= $all[array_rand($all)];
  415.         }
  416.         $this->plain_password str_shuffle($password);
  417.         return $this->plain_password;
  418.     }
  419.     private function sendLoginCredentials($clinic_user$plain_text_pwd$data)
  420.     {
  421.         // Send Email
  422.         $body '<table style="padding: 8px; border-collapse: collapse; border: none; font-family: arial">';
  423.         $body .= '<tr><td colspan="2">Hi '$data['firstName'] .',</td></tr>';
  424.         $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  425.         $body .= '<tr><td colspan="2">Please use the credentials below login to the Fluid Backend.</td></tr>';
  426.         $body .= '<tr><td colspan="2">&nbsp;</td></tr>';
  427.         $body .= '<tr>';
  428.         $body .= '    <td><b>URL: </b></td>';
  429.         $body .= '    <td><a href="https://'$_SERVER['HTTP_HOST'] .'/clinics/login">https://'$_SERVER['HTTP_HOST'] .'/clinics/login</a></td>';
  430.         $body .= '</tr>';
  431.         $body .= '<tr>';
  432.         $body .= '    <td><b>Username: </b></td>';
  433.         $body .= '    <td>'$data['email'] .'</td>';
  434.         $body .= '</tr>';
  435.         $body .= '<tr>';
  436.         $body .= '    <td><b>Password: </b></td>';
  437.         $body .= '    <td>'$plain_text_pwd .'</td>';
  438.         $body .= '</tr>';
  439.         $body .= '</table>';
  440.         $emailTo $this->encryptor->decrypt($clinic_user->getEmail());
  441.         $subject 'Fluid Login Credentials';
  442.         exec(__DIR__ '/../../bin/console app:send-email "'$subject .'" "'addslashes($body) .'" "'$emailTo .'" "'serialize([]) .'" "'serialize([]) .'" "'true .'" > /dev/null 2>&1 &');
  443.     }
  444.     public function getPagination($page_id$results)
  445.     {
  446.         $current_page = (int) $page_id;
  447.         $last_page $this->page_manager->lastPage($results);
  448.         $pagination '
  449.         <!-- Pagination -->
  450.         <div class="row mt-3">
  451.             <div class="col-12">';
  452.         if($last_page 1) {
  453.             $previous_page_no $current_page 1;
  454.             $url '/clinics/users';
  455.             $previous_page $url $previous_page_no;
  456.             $pagination .= '
  457.             <nav class="custom-pagination">
  458.                 <ul class="pagination justify-content-center">
  459.             ';
  460.             $disabled 'disabled';
  461.             $data_disabled 'true';
  462.             // Previous Link
  463.             if($current_page 1){
  464.                 $disabled '';
  465.                 $data_disabled 'false';
  466.             }
  467.             $pagination .= '
  468.             <li class="page-item '$disabled .'">
  469.                 <a 
  470.                     class="user-pagination" 
  471.                     aria-disabled="'$data_disabled .'" 
  472.                     data-page-id="'$current_page .'" 
  473.                     href="'$previous_page .'"
  474.                     data-action="click->clinics--users#onClickPagination"
  475.                 >
  476.                     <span aria-hidden="true">&laquo;</span> <span class="d-none d-sm-inline">Previous</span>
  477.                 </a>
  478.             </li>';
  479.             for($i 1$i <= $last_page$i++) {
  480.                 $active '';
  481.                 if($i == (int) $current_page){
  482.                     $active 'active';
  483.                 }
  484.                 $pagination .= '
  485.                 <li class="page-item '$active .'">
  486.                     <a 
  487.                         class="user-pagination" 
  488.                         data-page-id="'$i .'" 
  489.                         href="'$url .'"
  490.                         data-action="click->clinics--users#onClickPagination"
  491.                     >'$i .'</a>
  492.                 </li>';
  493.             }
  494.             $disabled 'disabled';
  495.             $data_disabled 'true';
  496.             if($current_page $last_page) {
  497.                 $disabled '';
  498.                 $data_disabled 'false';
  499.             }
  500.             $pagination .= '
  501.             <li class="page-item '$disabled .'">
  502.                 <a 
  503.                     class="user-pagination" 
  504.                     aria-disabled="'$data_disabled .'" 
  505.                     data-page-id="'$current_page .'" 
  506.                     href="'$url .'"
  507.                     data-action="click->clinics--users#onClickPagination"
  508.                 >
  509.                     <span class="d-none d-sm-inline">Next</span> <span aria-hidden="true">&raquo;</span>
  510.                 </a>
  511.             </li>';
  512.             $pagination .= '
  513.                     </ul>
  514.                 </nav>';
  515.             $pagination .= '
  516.                 </div>
  517.             </div>';
  518.         }
  519.         return $pagination;
  520.     }
  521. }