src/Controller/ConfigureHelpdesk.php line 59

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