src/Controller/ConfigureHelpdesk.php line 56

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