src/Controller/ConfigureHelpdesk.php line 56

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Console\Wizard\ConfigureHelpdesk as Helpdesk;
  4. use Doctrine\DBAL\DriverManager;
  5. use Doctrine\ORM\Tools\Setup;
  6. use Doctrine\ORM\EntityManager;
  7. use Symfony\Bundle\FrameworkBundle\Console\Application;
  8. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  9. use Symfony\Component\Yaml\Yaml;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\HttpFoundation\Response;
  12. use Symfony\Component\Console\Input\ArrayInput;
  13. use Symfony\Component\Console\Output\NullOutput;
  14. use Symfony\Component\HttpKernel\KernelInterface;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  17. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportRole;
  18. use Webkul\UVDesk\CoreFrameworkBundle\Entity\User;
  19. use Webkul\UVDesk\CoreFrameworkBundle\Entity\UserInstance;
  20. use Webkul\UVDesk\CoreFrameworkBundle\Services\UVDeskService;
  21. class ConfigureHelpdesk extends AbstractController
  22. {
  23.     const DB_URL_TEMPLATE "mysql://[user]:[password]@[host]:[port]";
  24.     const DB_ENV_PATH_TEMPLATE "DATABASE_URL=DB_DRIVER://DB_USER:DB_PASSWORD@DB_HOST/DB_NAME\n";
  25.     const DB_ENV_PATH_PARAM_TEMPLATE "env(DATABASE_URL): 'DB_DRIVER://DB_USER:DB_PASSWORD@DB_HOST/DB_NAME'\n";
  26.     const DEFAULT_JSON_HEADERS = [
  27.         'Content-Type' => 'application/json',
  28.     ];
  29.     private static $requiredExtensions = [
  30.         [
  31.             'name' => 'imap',
  32.         ],
  33.         [
  34.             'name' => 'mailparse',
  35.         ],
  36.         [
  37.             'name' => 'mysqli',
  38.         ],
  39.     ];
  40.     private static $requiredConfigfiles = [
  41.         [
  42.             'name' => 'uvdesk',
  43.         ],
  44.         [
  45.             'name' => 'uvdesk_mailbox',
  46.         ],
  47.     ];
  48.     public function load()
  49.     {
  50.         return $this->render('installation-wizard/index.html.twig');
  51.     }
  52.     public function evaluateSystemRequirements(Request $requestKernelInterface $kernel)
  53.     {
  54.         $max_execution_time ini_get('max_execution_time');
  55.         // Evaluate system specification requirements
  56.         switch (strtolower($request->request->get('specification'))) {
  57.             case 'php-version':
  58.                 $response = [
  59.                     'status'  => version_compare(phpversion(), '7.0.0''<') ? false true,
  60.                     'version' => sprintf('%s.%s.%s'PHP_MAJOR_VERSIONPHP_MINOR_VERSIONPHP_RELEASE_VERSION),
  61.                 ];
  62.                 if ($response['status']) {
  63.                     $response['message'] = sprintf('Using PHP v%s'$response['version']);
  64.                 } else {
  65.                     $response['message'] = sprintf('Currently using PHP v%s. Please use PHP 7 or greater.'$response['version']);
  66.                 }
  67.                 break;
  68.             case 'php-extensions':
  69.                 $extensions_status array_map(function ($extension) {
  70.                     return [
  71.                         $extension['name'] => extension_loaded($extension['name']),
  72.                     ];
  73.                 }, self::$requiredExtensions);
  74.                 $response = [
  75.                     'extensions' => $extensions_status,
  76.                 ];
  77.                 break;
  78.             case 'php-maximum-execution':
  79.                 $response['status' ] = $max_execution_time >= 30 true false;
  80.                 if ($response['status']) {
  81.                     $response['message'] = sprintf('Maximum execution time is %s'ini_get('max_execution_time').' sec');
  82.                 } else {
  83.                     $response['message'] = sprintf('Please increase your max execution time.' );
  84.                     $response['description'] = '</span>Issue can be resolved by simply<p><a href="https://www.simplified.guide/php/increase-max-execution-time" target="_blank"> increasing your maximum execution time</a> make it 60 or more and restart your server after making this change, refresh the browser and try again.</p>';
  85.                 }
  86.                 break;
  87.             case 'php-envfile-permission':
  88.                     $filename =  $kernel->getProjectDir().'/.env';
  89.                     
  90.                     if (!is_writable($filename)) {
  91.                         @chmod($filename0666);
  92.                     }
  93.                     $response['status'] = is_writable($filename) ? true false;
  94.    
  95.                     if ($response['status']) {
  96.                         $response['message'] = sprintf('Read/Write permission enabled for .env file.');
  97.                     } else {
  98.                         $response['message'] = sprintf('Please enable read/write permission for <b>.env</b> file of your project.');
  99.                         $response['description'] = '</span> Issue can be resolved by simply <a href="https://www.uvdesk.com/en/blog/open-source-helpdesk-installation-on-ubuntu-uvdesk/" target="_blank"><p> enabling your <b>.env</b> file read/write permission</a> refresh the browser and try again.</p>';
  100.                     }
  101.                 break;
  102.             case 'php-configfiles-permission':
  103.                     $configfiles_status array_map(function ($configfile) use ($kernel) {
  104.                         $filename $kernel->getProjectDir().'/config/packages/'.$configfile['name'].'.yaml';
  105.                         
  106.                         if (!is_writable($filename)) {
  107.                             @chmod($filename0666);
  108.                         }
  109.                         return [
  110.                             $configfile['name'] => is_writable($filename) ,
  111.                         ];
  112.                     }, self::$requiredConfigfiles);
  113.    
  114.                     $response = [
  115.                         'configfiles' => $configfiles_status,
  116.                         'description' => '</span> <br><p> Issue can be resolved by simply <a href="https://www.uvdesk.com/en/blog/open-source-helpdesk-installation-on-ubuntu-uvdesk/" target="_blank"> enabling read/write permissions for your files under config/packages folder of your project.</a></p>',
  117.                     ];
  118.                 break;
  119.             case 'redis-status':
  120.                 if (extension_loaded('redis')) {
  121.                     return new JsonResponse([
  122.                         'status'      => false,
  123.                         'message'     => "Redis extension is installed on your server follow the details",               
  124.                         'description' =>'<span>Please check the  <a href="https://github.com/uvdesk/community-skeleton/issues/364#issuecomment-780486976" target="_blank">Redis host</a> specified in the <span style="font-weight:600;">setup.php</span> file. If your Redis server host is different, you can either update it with your Redis host or follow the steps in the <a href="https://github.com/uvdesk/community-skeleton/issues/364#issuecomment-780486976" target="_blank">URL</a>. After making the changes, reload the page and try again.</span>'
  125.                         ]);
  126.                 }
  127.                 break;
  128.             default:
  129.                 $code 404;
  130.                 break;
  131.         }
  132.         
  133.         return new Response(json_encode($response ?? []), $code ?? 200self::DEFAULT_JSON_HEADERS);
  134.     }
  135.     public function verifyDatabaseCredentials(Request $request)
  136.     {
  137.         if (session_status() == PHP_SESSION_NONE) {
  138.             session_start();
  139.         }
  140.         
  141.         try {
  142.             $connectionUrl strtr(self::DB_URL_TEMPLATE, [
  143.                 '[host]'     => $request->request->get('serverName'),
  144.                 '[port]'     => $request->request->get('serverPort'),
  145.                 '[user]'     => $request->request->get('username'),
  146.                 '[password]' => $request->request->get('password'),
  147.             ]);
  148.             if ($request->request->get('serverVersion') != null) {
  149.                 $connectionUrl .= "?serverVersion=" $request->request->get('serverVersion');
  150.             }
  151.             $databaseConnection DriverManager::getConnection([
  152.                 'url' => $connectionUrl,
  153.             ]);
  154.             $entityManager EntityManager::create($databaseConnectionSetup::createAnnotationMetadataConfiguration(['src/Entity'], false));
  155.             
  156.             // Establish a connection if not active
  157.             if (false == $databaseConnection->isConnected()) {
  158.                 $databaseConnection->connect();
  159.             }
  160.             // Check if database exists
  161.             $createDatabase = (bool) $request->request->get('createDatabase');
  162.             if (
  163.                 ! in_array($request->request->get('database'), $databaseConnection->getSchemaManager()->listDatabases()) 
  164.                 && false == $createDatabase
  165.             ) {
  166.                 return new JsonResponse([
  167.                     'status'  => false,
  168.                     'message' => "The requested database was not found."
  169.                 ]);
  170.             }
  171.             // Storing database configuration to session.
  172.             $_SESSION['DB_CONFIG'] = [
  173.                 'host'           => $request->request->get('serverName'),
  174.                 'port'           => $request->request->get('serverPort'),
  175.                 'version'        => $request->request->get('serverVersion'),
  176.                 'username'       => $request->request->get('username'),
  177.                 'password'       => $request->request->get('password'),
  178.                 'database'       => $request->request->get('database'),
  179.                 'createDatabase' => $createDatabase,
  180.             ];
  181.         } catch (\Exception $e) {
  182.             return new JsonResponse([
  183.                 'status'  => false,
  184.                 'message' => "Failed to establish a connection with database server."
  185.             ]);
  186.         }
  187.         
  188.         return new JsonResponse(['status' => true]);
  189.     }
  190.     public function prepareSuperUserDetailsXHR(Request $request)
  191.     {
  192.         if (session_status() == PHP_SESSION_NONE) {
  193.             session_start();
  194.         }
  195.         
  196.         // unset($_SESSION['USER_DETAILS']);
  197.         $_SESSION['USER_DETAILS'] = [
  198.             'name'     => $request->request->get('name'),
  199.             'email'    => $request->request->get('email'),
  200.             'password' => $request->request->get('password'),
  201.         ];
  202.         return new Response(json_encode(['status' => true]), 200self::DEFAULT_JSON_HEADERS);
  203.     }
  204.     public function updateConfigurationsXHR(Request $requestKernelInterface $kernel)
  205.     {
  206.         if (session_status() == PHP_SESSION_NONE) {
  207.             session_start();
  208.         }
  209.         $database_host    $_SESSION['DB_CONFIG']['host'];
  210.         $database_port    $_SESSION['DB_CONFIG']['port'];
  211.         $database_version $_SESSION['DB_CONFIG']['version'];
  212.         $database_user    $_SESSION['DB_CONFIG']['username'];
  213.         $database_pass    $_SESSION['DB_CONFIG']['password'];
  214.         $database_name    $_SESSION['DB_CONFIG']['database'];
  215.         $create_database $_SESSION['DB_CONFIG']['createDatabase'];
  216.         try {
  217.             $connectionUrl strtr(self::DB_URL_TEMPLATE, [
  218.                 '[host]'     => $database_host,
  219.                 '[port]'     => $database_port,
  220.                 '[user]'     => $database_user,
  221.                 '[password]' => $database_pass,
  222.             ]);
  223.             if (! empty($database_version)) {
  224.                 $connectionUrl .= "?serverVersion=$database_version";
  225.             }
  226.             $databaseConnection DriverManager::getConnection([
  227.                 'url' => $connectionUrl,
  228.             ]);
  229.             $entityManager EntityManager::create($databaseConnectionSetup::createAnnotationMetadataConfiguration(['src/Entity'], false));
  230.             // Establish an active connection with database server
  231.             if (false == $databaseConnection->isConnected()) {
  232.                 $databaseConnection->connect();
  233.             }
  234.             // Check if database exists
  235.             if (! in_array($database_name$databaseConnection->getSchemaManager()->listDatabases())) {
  236.                 if (false == $create_database) {
  237.                     throw new \Exception('Database does not exist.');
  238.                 }
  239.                 
  240.                 // Create database
  241.                 $databaseConnection->getSchemaManager()->createDatabase($databaseConnection->getDatabasePlatform()->quoteSingleIdentifier($database_name));
  242.             }
  243.             $connectionUrl strtr(self::DB_URL_TEMPLATE "/[database]", [
  244.                 '[host]'     => $database_host,
  245.                 '[port]'     => $database_port,
  246.                 '[user]'     => $database_user,
  247.                 '[password]' => $database_pass,
  248.                 '[database]' => $database_name,
  249.             ]);
  250.             if (!empty($database_version)) {
  251.                 $connectionUrl .= "?serverVersion=$database_version";
  252.             }
  253.             // Update .env
  254.             $application = new Application($kernel);
  255.             $application->setAutoExit(false);
  256.             $returnCode $application->run(new ArrayInput([
  257.                 'command' => 'uvdesk_wizard:env:update'
  258.                 'name'    => 'DATABASE_URL'
  259.                 'value'   => $connectionUrl
  260.             ]), new NullOutput());
  261.     
  262.             if (=== $returnCode) {
  263.                 return new JsonResponse(['success' => true]);
  264.             }
  265.         } catch (\Exception $e) {
  266.             return new JsonResponse([
  267.                 'status'  => false,
  268.                 'message' => "An unexpected error occurred: " $e->getMessage(), 
  269.             ]);
  270.         }
  271.         return new JsonResponse(['success' => false], 500);
  272.     }
  273.     public function migrateDatabaseSchemaXHR(Request $requestKernelInterface $kernel)
  274.     {
  275.         $application = new Application($kernel);
  276.         $application->setAutoExit(false);
  277.         $resultCode $application->run(new ArrayInput([
  278.             'command' => 'uvdesk_wizard:database:migrate'
  279.         ]), new NullOutput());
  280.         
  281.         return new Response(json_encode([]), 200self::DEFAULT_JSON_HEADERS);
  282.     }
  283.     public function populateDatabaseEntitiesXHR(Request $requestKernelInterface $kernel)
  284.     {
  285.         $application = new Application($kernel);
  286.         $application->setAutoExit(false);
  287.         $resultCode $application->run(new ArrayInput([
  288.             'command'  => 'doctrine:fixtures:load',
  289.             '--append' => true,
  290.         ]), new NullOutput());
  291.         return new Response(json_encode([]), 200self::DEFAULT_JSON_HEADERS);
  292.     }
  293.     public function createDefaultSuperUserXHR(Request $requestUserPasswordEncoderInterface $encoder)
  294.     {
  295.         if (session_status() == PHP_SESSION_NONE) {
  296.             session_start();
  297.         }
  298.         // $entityManager = $this->getDoctrine()->getEntityManager();
  299.         $entityManager $this->getDoctrine()->getManager();
  300.         $role $entityManager->getRepository(SupportRole::class)->findOneByCode('ROLE_SUPER_ADMIN');
  301.         $userInstance $entityManager->getRepository(UserInstance::class)->findOneBy([
  302.             'isActive'    => true,
  303.             'supportRole' => $role,
  304.         ]);
  305.             
  306.         if (empty($userInstance)) {
  307.             list($name$email$password) = array_values($_SESSION['USER_DETAILS']);
  308.             // Retrieve existing user or generate new empty user
  309.             $accountExistsFlag false;
  310.             $user $entityManager->getRepository(User::class)->findOneByEmail($email) ?: (new User())->setEmail($email);
  311.             if ($user->getId() != null) {
  312.                 $userInstance $user->getAgentInstance();
  313.                 if (!empty($userInstance)) {
  314.                     $accountExistsFlag true;
  315.                     if ($userInstance->getSupportRole()->getId() != $role->getId()) {
  316.                         $userInstance->setSupportRole($role);
  317.                         $entityManager->persist($userInstance);
  318.                         $entityManager->flush();
  319.                     }
  320.                 }
  321.             } else {
  322.                 $username explode(' '$name2);
  323.                 $encodedPassword $encoder->encodePassword($user$password);
  324.                 $user
  325.                     ->setFirstName($username[0])
  326.                     ->setLastName(! empty($username[1]) ? $username[1] : '')
  327.                     ->setPassword($encodedPassword)
  328.                     ->setIsEnabled(true);
  329.                 
  330.                 $entityManager->persist($user);
  331.                 $entityManager->flush();
  332.             }
  333.             
  334.             if (false == $accountExistsFlag) {
  335.                 $userInstance = new UserInstance();
  336.                 $userInstance->setSource('website');
  337.                 $userInstance->setIsActive(true);
  338.                 $userInstance->setIsVerified(true);
  339.                 $userInstance->setUser($user);
  340.                 $userInstance->setSupportRole($role);
  341.                 $entityManager->persist($userInstance);
  342.                 $entityManager->flush();
  343.             }
  344.         }
  345.         return new Response(json_encode([]), 200self::DEFAULT_JSON_HEADERS);
  346.     }
  347.     public function websiteConfigurationXHR(Request $requestUVDeskService $uvdesk)
  348.     {
  349.         switch ($request->getMethod()) {
  350.             case "GET":
  351.                 $currentWebsitePrefixCollection $uvdesk->getCurrentWebsitePrefixes();
  352.                 
  353.                 if ($currentWebsitePrefixCollection) {
  354.                     $result $currentWebsitePrefixCollection;
  355.                     $result['status'] = true;
  356.                 } else {
  357.                     $result['status'] = false;
  358.                 }
  359.                 break;
  360.             case "POST":
  361.                 if (session_status() == PHP_SESSION_NONE) {
  362.                     session_start();
  363.                 }
  364.                 
  365.                 $_SESSION['PREFIXES_DETAILS'] = [
  366.                     'member'   => $request->request->get('member-prefix'),
  367.                     'customer' => $request->request->get('customer-prefix'),
  368.                 ];
  369.                 $result = ['status' => true];
  370.                 break;
  371.             default:
  372.                 break;
  373.         }
  374.         return new Response(json_encode($result ?? []), 200self::DEFAULT_JSON_HEADERS);
  375.     }
  376.     public function updateWebsiteConfigurationXHR(Request $requestUVDeskService $uvdesk)
  377.     {
  378.         if (session_status() == PHP_SESSION_NONE) {
  379.             session_start();
  380.         }
  381.         $collectionURL$uvdesk->updateWebsitePrefixes(
  382.             $_SESSION['PREFIXES_DETAILS']['member'],
  383.             $_SESSION['PREFIXES_DETAILS']['customer']
  384.         );
  385.         
  386.         // uvdesk tracker
  387.         $userDetails =[
  388.             'name'   => $_SESSION['USER_DETAILS']['name'],
  389.             'email'  => $_SESSION['USER_DETAILS']['email'],
  390.             'domain' => $this->getParameter('uvdesk.site_url'),
  391.         ];
  392.         
  393.         Helpdesk::addUserDetailsInTracker($userDetails);
  394.         return new Response(json_encode($collectionURL), 200self::DEFAULT_JSON_HEADERS);
  395.     }
  396. }