src/Controller/SiteMapController.php line 47

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Service\Internal\CmsService;
  4. use App\Service\Internal\HomePageService;
  5. use App\Service\Internal\LineService;
  6. use App\Service\Internal\SiteMapService;
  7. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  8. use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  11. use App\Service\Internal\NetworkService;
  12. use Symfony\Component\Filesystem\Filesystem;
  13. use Symfony\Component\HttpFoundation\Response;
  14. use Symfony\Contracts\Translation\TranslatorInterface;
  15. class SiteMapController extends AbstractController
  16. {
  17. public const SITEMAP_PATH = '/public/sitemap/';
  18. public const LINE_SCHEDULES_FILE_NAME = 'lines-schedules.txt';
  19. public const STOPS_FILE_NAME = 'stops.html';
  20. public const CITIES_FILE_NAME = 'cities.txt';
  21. public const PAGES_FILE_NAME = 'pages.txt';
  22. /** Cache duration in hours **/
  23. public const CACHE_DURATION = 24;
  24. /**
  25. * Get sitemap
  26. */
  27. public function getContent(
  28. HomePageService $newsPageService,
  29. SiteMapService $siteMapService,
  30. NetworkService $networkService
  31. ): Response {
  32. $parameters = $newsPageService->getRenderParameters();
  33. $parameters['isXmlHttpMode'] = true;
  34. $subNetworks = $networkService->getSubNetworks();
  35. $subNetworksName = [];
  36. foreach ($subNetworks as $subNetwork) {
  37. $subNetworksName[$subNetwork['id']]['name'] = $siteMapService->cleanStr($subNetwork['name']);
  38. }
  39. $parameters['subNetworks'] = $subNetworks;
  40. $parameters['subNetworksName'] = $subNetworksName;
  41. return $this->render('pages/sitemap/sitemap.html.twig', $parameters);
  42. }
  43. /**
  44. * Get subNetwork Lines
  45. */
  46. public function subNetworkLines(
  47. $id,
  48. HomePageService $newsPageService,
  49. SiteMapService $siteMapService,
  50. NetworkService $networkService
  51. ): Response {
  52. $parameters = $newsPageService->getRenderParameters();
  53. $parameters['isXmlHttpMode'] = true;
  54. $subNetwork = $networkService->getSubNetwork($id);
  55. $lines = $networkService->getSubNetworkLines($id);
  56. $parameters['subNetwork'] = $subNetwork;
  57. $parameters['subNetworkName'] = $siteMapService->cleanStr($subNetwork[0]['name']);
  58. $parameters['lines'] = $lines;
  59. return $this->render('pages/sitemap/subnetwork-lines.html.twig', $parameters);
  60. }
  61. /**
  62. * Get lines schedules sitemap
  63. */
  64. public function getLinesSchedules(
  65. Request $request,
  66. LineService $lineService,
  67. SiteMapService $siteMapService,
  68. TranslatorInterface $translator
  69. ): BinaryFileResponse {
  70. $locale = $request->getLocale();
  71. $networkId = $this->getParameter('network_id');
  72. $baseUrl = 'https://' . $request->getHost();
  73. $translator->setLocale($locale);
  74. $publicResourcesFolderPath = $this->getParameter(
  75. 'kernel.project_dir'
  76. ) . self::SITEMAP_PATH . $networkId . '/' . $locale . '/';
  77. $filename = self::LINE_SCHEDULES_FILE_NAME;
  78. $file = $publicResourcesFolderPath . $filename;
  79. $currentTime = time();
  80. if (file_exists($file)) {
  81. $fileTime = filemtime($file);
  82. $seconds = $currentTime - $fileTime;
  83. $hours = floor($seconds / 3600);
  84. if ($hours < self::CACHE_DURATION) {
  85. return new BinaryFileResponse($file);
  86. }
  87. }
  88. // get translated url elements
  89. $sSchedules = $translator->trans('route.schedules');
  90. $sLine = $translator->trans('route.line');
  91. $sDirection = $translator->trans('route.direction');
  92. $fileSystem = new Filesystem();
  93. $root = $this->getParameter('kernel.project_dir');
  94. try {
  95. $fileSystem->mkdir($root . '/public/temp/');
  96. } catch (IOExceptionInterface $exception) {
  97. echo "An error occurred while creating your directory at " . $exception->getPath();
  98. }
  99. // temporary file will be deleted
  100. $tempFile = $root . '/public/temp/sitemap-' . $networkId . '-' . $locale . '-lines-schedules.txt';
  101. // final file will be stored
  102. $file = $root . self::SITEMAP_PATH . $networkId . '/' . $locale . '/' . $filename;
  103. try {
  104. $fileSystem->touch($tempFile);
  105. } catch (IOExceptionInterface $exception) {
  106. echo "An error occurred while creating your file at " . $exception->getPath();
  107. }
  108. // get all network lines
  109. $response = $lineService->getAllLines();
  110. $lines = $response['lines'];
  111. foreach ($lines as $line) {
  112. $subNetwork = $siteMapService->cleanStr($line['subNetwork']['name']);
  113. $lineName = $siteMapService->cleanStr($line['sName']);
  114. // write url to bo stored on sitemap file
  115. $content = $baseUrl . "/" . $locale . "/" . $sSchedules . "/" .
  116. $subNetwork . "/" . $line['mode'] . "/" .
  117. $sLine . "/" . $lineName . "/" . $sDirection . "/OUTWARD/" . $line['id'];
  118. $url = str_replace([" ", "'"], "-", $content);
  119. $fileSystem->appendToFile($tempFile, $url . PHP_EOL);
  120. }
  121. $fileSystem->copy($tempFile, $file);
  122. $fileSystem->remove($tempFile);
  123. return new BinaryFileResponse($file);
  124. }
  125. /**
  126. * Get Cities sitemap
  127. */
  128. public function getCities(
  129. Request $request,
  130. SiteMapService $siteMapService,
  131. NetworkService $networkService,
  132. TranslatorInterface $translator
  133. ): BinaryFileResponse {
  134. $locale = $request->getLocale();
  135. $networkId = $this->getParameter('network_id');
  136. $baseUrl = 'https://' . $request->getHost();
  137. $translator->setLocale($locale);
  138. $publicResourcesFolderPath = $this->getParameter(
  139. 'kernel.project_dir'
  140. ) . self::SITEMAP_PATH . $networkId . '/' . $locale . '/';
  141. $filename = self::CITIES_FILE_NAME;
  142. $file = $publicResourcesFolderPath . $filename;
  143. $currentTime = time();
  144. if (file_exists($file)) {
  145. $fileTime = filemtime($file);
  146. $seconds = $currentTime - $fileTime;
  147. $hours = floor($seconds / 3600);
  148. if ($hours < self::CACHE_DURATION) {
  149. return new BinaryFileResponse($file);
  150. }
  151. }
  152. // get translated url elements
  153. $sSchedules = $translator->trans('route.schedules');
  154. $sLinesMap = $translator->trans('route.lines_plan');
  155. $fileSystem = new Filesystem();
  156. $root = $this->getParameter('kernel.project_dir');
  157. try {
  158. $fileSystem->mkdir($root . '/public/temp/');
  159. } catch (IOExceptionInterface $exception) {
  160. echo "An error occurred while creating your directory at " . $exception->getPath();
  161. }
  162. // temporary file will be deleted
  163. $tempFile = $root . '/public/temp/sitemap-' . $networkId . '-' . $locale . '-cities.txt';
  164. // final file will be stored
  165. $file = $root . self::SITEMAP_PATH . $networkId . '/' . $locale . '/' . $filename;
  166. try {
  167. $fileSystem->touch($tempFile);
  168. } catch (IOExceptionInterface $exception) {
  169. echo "An error occurred while creating your file at " . $exception->getPath();
  170. }
  171. $localities = $networkService->getLocalities();
  172. foreach ($localities as $locality) {
  173. $localityName = $siteMapService->cleanStr($locality['name']);
  174. // write url to bo stored on sitemap file
  175. $content = $baseUrl . "/" . $locale . "/" . $sSchedules . "/" . $localityName . "/" . $sLinesMap . "/" . $locality['id'];
  176. $url = str_replace([" ", "'"], "-", $content);
  177. $fileSystem->appendToFile($tempFile, $url . PHP_EOL);
  178. }
  179. $fileSystem->copy($tempFile, $file);
  180. $fileSystem->remove($tempFile);
  181. return new BinaryFileResponse($file);
  182. }
  183. /**
  184. * Get Pages sitemap
  185. */
  186. public function getPages(
  187. Request $request,
  188. TranslatorInterface $translator,
  189. CmsService $cmsService
  190. ): BinaryFileResponse {
  191. $locale = $request->getLocale();
  192. $networkId = $this->getParameter('network_id');
  193. $baseUrl = 'https://' . $request->getHost();
  194. $translator->setLocale($locale);
  195. $publicResourcesFolderPath = $this->getParameter(
  196. 'kernel.project_dir'
  197. ) . self::SITEMAP_PATH . $networkId . '/' . $locale . '/';
  198. $filename = self::PAGES_FILE_NAME;
  199. $file = $publicResourcesFolderPath . $filename;
  200. $currentTime = time();
  201. if (file_exists($file)) {
  202. $fileTime = filemtime($file);
  203. $seconds = $currentTime - $fileTime;
  204. $hours = floor($seconds / 3600);
  205. }
  206. // get translated url elements
  207. $sSitemap = $translator->trans('route.sitemap');
  208. $sNews = $translator->trans('route.news');
  209. $sPage = $translator->trans('route.page');
  210. $fileSystem = new Filesystem();
  211. $root = $this->getParameter('kernel.project_dir');
  212. try {
  213. $fileSystem->mkdir($root . '/public/temp/');
  214. } catch (IOExceptionInterface $exception) {
  215. echo "An error occurred while creating your directory at " . $exception->getPath();
  216. }
  217. // temporary file will be deleted
  218. $tempFile = $root . '/public/temp/sitemap-' . $networkId . '-' . $locale . '-pages.txt';
  219. // final file will be stored
  220. $file = $root . self::SITEMAP_PATH . $networkId . '/' . $locale . '/' . $filename;
  221. try {
  222. $fileSystem->touch($tempFile);
  223. } catch (IOExceptionInterface $exception) {
  224. echo "An error occurred while creating your file at " . $exception->getPath();
  225. }
  226. // Add site map url to xml sitemap
  227. $sitemapUrl = $baseUrl . "/" . $locale . "/" . $sSitemap;
  228. $fileSystem->appendToFile($tempFile, $sitemapUrl . PHP_EOL);
  229. // Add news url to xml sitemap
  230. $newsUrl = $baseUrl . "/" . $locale . "/" . $sNews;
  231. $fileSystem->appendToFile($tempFile, $newsUrl . PHP_EOL);
  232. $pages = $cmsService->getPages();
  233. foreach ($pages as $page) {
  234. // write url to bo stored on sitemap file
  235. $content = $baseUrl . "/" . $locale . "/" . $sPage . "/" . $page->id;
  236. $fileSystem->appendToFile($tempFile, $content . PHP_EOL);
  237. }
  238. $fileSystem->copy($tempFile, $file);
  239. $fileSystem->remove($tempFile);
  240. return new BinaryFileResponse($file);
  241. }
  242. /**
  243. * Get StopAreas
  244. */
  245. public function stopAreas(
  246. Request $request,
  247. HomePageService $newsPageService,
  248. SiteMapService $siteMapService,
  249. NetworkService $networkService
  250. ): BinaryFileResponse {
  251. $locale = $request->getLocale();
  252. $networkId = $this->getParameter('network_id');
  253. $publicResourcesFolderPath = $this->getParameter(
  254. 'kernel.project_dir'
  255. ) . self::SITEMAP_PATH . $networkId . '/' . $locale . '/';
  256. $filename = self::STOPS_FILE_NAME;
  257. $file = $publicResourcesFolderPath . $filename;
  258. if (!file_exists($file) || (file_exists($file) && floor(
  259. (time() - filemtime($file)) / 3600
  260. ) > self::CACHE_DURATION)) {
  261. $parameters = $newsPageService->getRenderParameters();
  262. $parameters['isXmlHttpMode'] = true;
  263. $stopAreas = $networkService->getStopAreas();
  264. $letters = array();
  265. foreach ($stopAreas as $item) {
  266. $firstLetter = substr($item['name'], 0, 1);
  267. $firstLetter = $siteMapService->cleanStr($firstLetter);
  268. $letters[strtoupper($firstLetter)][] = [
  269. 'id' => $item['id'],
  270. 'name' => $item['name'],
  271. 'city' => $item['city']
  272. ];
  273. }
  274. $stopAreasName = [];
  275. $citiesName = [];
  276. foreach ($stopAreas as $stopArea) {
  277. $stopArea['name'] = empty(!$stopArea['name']) ? $stopArea['name'] : '-';
  278. $stopArea['city'] = empty(!$stopArea['city']) ? $stopArea['city'] : '-';
  279. $stopAreasName[$stopArea['id']]['name'] = $siteMapService->cleanStr($stopArea['name']);
  280. $citiesName[$stopArea['id']]['city'] = $siteMapService->cleanStr($stopArea['city']);
  281. }
  282. $parameters['letters'] = $letters;
  283. $parameters['stopAreas'] = $stopAreas;
  284. $parameters['stopAreasName'] = $stopAreasName;
  285. $parameters['citiesName'] = $citiesName;
  286. $html = $this->render('pages/sitemap/stopareas.html.twig', $parameters)->getContent();
  287. // Create cache file
  288. if (!is_dir($publicResourcesFolderPath)) {
  289. try {
  290. mkdir($publicResourcesFolderPath, 0777, true);
  291. } catch (\ErrorException $ex) {
  292. echo "Error: " . $ex->getMessage();
  293. }
  294. }
  295. $cacheFile = fopen($file, 'w');
  296. fputs($cacheFile, $this->sanitize_output($html));
  297. fclose($cacheFile);
  298. }
  299. return new BinaryFileResponse($file);
  300. }
  301. /**
  302. * @param $buffer
  303. * @return null|string|string[]
  304. */
  305. private function sanitize_output($buffer)
  306. {
  307. $search = array(
  308. '/\>[^\S ]+/s', // strip whitespaces after tags, except space
  309. '/[^\S ]+\</s', // strip whitespaces before tags, except space
  310. '/(\s)+/s', // shorten multiple whitespace sequences
  311. '/<!--(.|\s)*?-->/' // Remove HTML comments
  312. );
  313. $replace = array(
  314. '>',
  315. '<',
  316. '\\1',
  317. ''
  318. );
  319. $buffer = preg_replace($search, $replace, $buffer);
  320. return $buffer;
  321. }
  322. /**
  323. * Get Localities
  324. */
  325. public function localities(
  326. HomePageService $newsPageService,
  327. SiteMapService $siteMapService,
  328. NetworkService $networkService
  329. ): Response {
  330. $parameters = $newsPageService->getRenderParameters();
  331. $parameters['isXmlHttpMode'] = true;
  332. $localities = $networkService->getLocalities();
  333. asort($localities);
  334. $localitiesName = [];
  335. $letters = array();
  336. foreach ($localities as $item) {
  337. $firstLetter = substr($item['name'], 0, 1);
  338. $firstLetter = $siteMapService->cleanStr($firstLetter);
  339. $letters[strtoupper($firstLetter)][] = ['id' => $item['id'], 'name' => $item['name']];
  340. }
  341. foreach ($localities as $locality) {
  342. $locality['name'] = empty(!$locality['name']) ? $locality['name'] : '-';
  343. $localitiesName[$locality['id']]['name'] = $siteMapService->cleanStr($locality['name']);
  344. }
  345. $parameters['letters'] = $letters;
  346. $parameters['localities'] = $localities;
  347. $parameters['localitiesName'] = $localitiesName;
  348. return $this->render('pages/sitemap/localities.html.twig', $parameters);
  349. }
  350. }