src/Controller/AppController.php line 70

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Form\AssetSearchSimpleType;
  4. use App\Form\ChangePasswordFormType;
  5. use App\Form\AccountFormType;
  6. use App\Repository\AssetLogRepository;
  7. use App\Repository\AssetRepository;
  8. use App\Repository\LanguageRepository;
  9. use App\Repository\ProductRepository;
  10. use App\Repository\UserRepository;
  11. use App\Service\UserAccessService;
  12. use Doctrine\ORM\NonUniqueResultException;
  13. use Doctrine\ORM\NoResultException;
  14. use FilesystemIterator;
  15. use imagick;
  16. use RecursiveIteratorIterator;
  17. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  18. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  19. use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
  20. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  21. use Symfony\Component\HttpFoundation\JsonResponse;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  25. use Symfony\Component\Routing\Annotation\Route;
  26. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  27. class AppController extends AbstractController
  28. {
  29. private $assetRepository;
  30. private $userRepository;
  31. private $accessService;
  32. private $assetLogRepository;
  33. private $languageRepository;
  34. private $productRepository;
  35. /**
  36. * AppController constructor.
  37. * @param AssetRepository $assetRepository
  38. * @param UserRepository $userRepository
  39. * @param UserAccessService $accessService
  40. * @param AssetLogRepository $assetLogRepository
  41. * @param LanguageRepository $languageRepository
  42. * @param ProductRepository $productRepository
  43. */
  44. public function __construct(
  45. AssetRepository $assetRepository,
  46. UserRepository $userRepository,
  47. UserAccessService $accessService,
  48. AssetLogRepository $assetLogRepository,
  49. LanguageRepository $languageRepository,
  50. ProductRepository $productRepository
  51. )
  52. {
  53. $this->assetRepository = $assetRepository;
  54. $this->userRepository = $userRepository;
  55. $this->accessService = $accessService;
  56. $this->assetLogRepository = $assetLogRepository;
  57. $this->languageRepository = $languageRepository;
  58. $this->productRepository = $productRepository;
  59. }
  60. /**
  61. * @Route("/", name="home")
  62. * @IsGranted("IS_AUTHENTICATED_REMEMBERED")
  63. */
  64. public function index(Request $request): Response
  65. {
  66. $user = $this->getUser();
  67. $filterData = $this->accessService->getUserAccessFilterData();
  68. $assets = $this->assetRepository->findLatestByUser($filterData);
  69. $products = $this->productRepository->findLatestByUser($filterData);
  70. // Smarthub statistics
  71. if($this->isGranted("ROLE_SMART_STAFF")) {
  72. $generalTotals = $this->getGeneralTotals();
  73. $userTotals = $this->getUserTotals();
  74. $languageTotals = $this->getLanguageData();
  75. }
  76. // Subscribe to newsletter form
  77. $accountForm = $this->createForm(AccountFormType::class, $user);
  78. $accountForm->handleRequest($request);
  79. if ($accountForm->isSubmitted() && $accountForm->isValid()) {
  80. $user->setIsSubscribed(
  81. $accountForm->get('isSubscribed')->getData()
  82. );
  83. $this->getDoctrine()->getManager()->flush();
  84. $this->addFlash(
  85. 'success',
  86. "Successfully saved settings."
  87. );
  88. return $this->redirectToRoute('home');
  89. }
  90. // Quick search
  91. $filterData = $this->accessService->getUserAccessFilterData();
  92. $assetSearchSimpleForm = $this->createForm(AssetSearchSimpleType::class, null, [
  93. 'category' => $filterData['category']
  94. ]);
  95. $assetSearchSimpleForm->handleRequest($request);
  96. if ($assetSearchSimpleForm->isSubmitted() && $assetSearchSimpleForm->isValid()) {
  97. $product = $assetSearchSimpleForm->get('product')->getData();
  98. return $this->redirectToRoute('asset_index', ['product' => $product->getId()]);
  99. }
  100. return $this->render('app/index.html.twig', [
  101. 'products' => $products,
  102. 'assets' => array_splice($assets, 0,6),
  103. 'generalTotals' => $generalTotals ?? null,
  104. 'userTotals' => $userTotals ?? null,
  105. 'languageTotals' => $languageTotals ?? null,
  106. 'notices' => $this->getNotices(),
  107. 'accountForm' => $accountForm->createView(),
  108. 'assetSearchSimpleForm' => $assetSearchSimpleForm->createView(),
  109. ]);
  110. }
  111. /**
  112. * @Route("/list", name="smarthub_stats_list", options={"expose"="true"}, methods={"GET","POST"})
  113. * @param Request $request
  114. * @return Response
  115. */
  116. public function list(Request $request): Response
  117. {
  118. if(!$this->isGranted("ROLE_SMART_STAFF")) {
  119. return new JsonResponse();
  120. }
  121. $start = $request->query->get('start');
  122. $end = $request->query->get('end');
  123. $totalsThisYear = $this->getGeneralData($start, $end);
  124. $topUsers = $this->getTopUsers($start, $end);
  125. $topDownloads = $this->assetLogRepository->getPopularDownloads($start, $end);
  126. $topAssets = $this->assetRepository->findTopDownloadsById(array_column($topDownloads, 'id'));
  127. $ids = array_column($topDownloads, 'logs', 'id');
  128. foreach($topAssets as &$asset) {
  129. $asset['thumbnail'] = $asset[0]->getThumbnail();
  130. $values = $asset[0]->getType()->getValues();
  131. $v = [];
  132. foreach($values as $value) {
  133. $v[] = $value->getName();
  134. }
  135. $id = $asset[0]->getId();
  136. $asset['types'] = $v;
  137. $asset['logs'] = $ids[$id];
  138. foreach($asset[0]->getFiles() as $file) {
  139. if(!$file->getDeleted()) {
  140. $asset['route'] = $this->generateUrl('file_download', [
  141. 'id' =>$file->getId(),
  142. ]);
  143. }
  144. }
  145. }
  146. usort($topAssets, function($a, $b) {
  147. return $a['logs'] < $b['logs'];
  148. });
  149. $response = new JsonResponse();
  150. $response->setData(
  151. [
  152. 'topDownloads' => $topAssets,
  153. 'totalsThisYear' => $totalsThisYear,
  154. 'topUsers' => $topUsers,
  155. ]
  156. );
  157. return $response;
  158. }
  159. /**
  160. * @return array
  161. * @throws NoResultException
  162. * @throws NonUniqueResultException
  163. */
  164. private function getGeneralTotals(): array
  165. {
  166. $totalAssets = $this->assetRepository->getTotal();
  167. $totalUploadFiles = $this->assetRepository->getTotalFileType();
  168. $totalTextFiles = $this->assetRepository->getTotalTextType();
  169. $totalDownloads = $this->assetLogRepository->getTotalDownloads();
  170. return [
  171. 'Total Assets' => $totalAssets,
  172. 'Total Files' => $totalUploadFiles,
  173. 'Total Texts' => $totalTextFiles,
  174. 'Total Downloads' => $totalDownloads,
  175. 'Assets Filesize' => 'N/A',
  176. 'Archive Filesize' => 'N/A',
  177. ];
  178. }
  179. /**
  180. * @return array
  181. * @throws NoResultException
  182. * @throws NonUniqueResultException
  183. */
  184. private function getLanguageData(): array
  185. {
  186. $languages = $this->languageRepository->findAll();
  187. $totalDownloadsForLanguage = [];
  188. foreach ($languages as $language) {
  189. $totalDownloadsForLanguage[$language->getName()] = $this->assetLogRepository->getTotalDownloadsForLanguage($language->getId());
  190. }
  191. return $totalDownloadsForLanguage;
  192. }
  193. /**
  194. * @param $start
  195. * @param $end
  196. * @return array
  197. * @throws NoResultException
  198. * @throws NonUniqueResultException
  199. */
  200. private function getGeneralData($start, $end): array
  201. {
  202. $data = [];
  203. $data[0] = $this->assetRepository->getTotalForDates($start, $end);
  204. $data[1] = $this->assetLogRepository->getTotalDownloadsForDates($start, $end);
  205. $data[2] = $this->userRepository->getTotalForDates($start, $end);
  206. return $data;
  207. }
  208. /**
  209. * @return array
  210. */
  211. private function getUserTotals(): array
  212. {
  213. $totalUsers = $this->userRepository->getTotal();
  214. $totalVerifiedUsers = $this->userRepository->getTotalVerified();
  215. $totalSubscribed = $this->userRepository->getTotalSubscribed();
  216. return [
  217. 'Total Users' => $totalUsers,
  218. 'Total Verified Users' => $totalVerifiedUsers,
  219. 'Total Subscribed' => $totalSubscribed,
  220. ];
  221. }
  222. /**
  223. * @param $start
  224. * @param $end
  225. * @return array
  226. */
  227. private function getTopUsers($start, $end): array
  228. {
  229. $topExternalDownloaded = $this->assetLogRepository->getPopularExternalDownloaders($start, $end);
  230. $topSmartDownloaded = $this->assetLogRepository->getPopularSmartDownloaders($start, $end);
  231. return [
  232. 'Top Users (External)' => $topExternalDownloaded,
  233. 'Top Users (Smart)' => $topSmartDownloaded,
  234. ];
  235. }
  236. /**
  237. * @Route("/account", name="account")
  238. * @IsGranted("IS_AUTHENTICATED_FULLY")
  239. * @param Request $request
  240. * @param UserPasswordEncoderInterface $passwordEncoder
  241. * @return Response
  242. */
  243. public function account(Request $request, UserPasswordEncoderInterface $passwordEncoder): Response
  244. {
  245. $user = $this->getUser();
  246. $passwordform = $this->createForm(ChangePasswordFormType::class);
  247. $accountform = $this->createForm(AccountFormType::class, $user);
  248. $passwordform->handleRequest($request);
  249. if ($passwordform->isSubmitted() && $passwordform->isValid()) {
  250. $encodedPassword = $passwordEncoder->encodePassword(
  251. $user,
  252. $passwordform->get('plainPassword')->getData()
  253. );
  254. $user->setPassword($encodedPassword);
  255. $this->getDoctrine()->getManager()->flush();
  256. $this->addFlash(
  257. 'success',
  258. "Password successfully changed."
  259. );
  260. return $this->redirectToRoute('home');
  261. }
  262. $accountform->handleRequest($request);
  263. if ($accountform->isSubmitted() && $accountform->isValid()) {
  264. $user->setIsSubscribed(
  265. $accountform->get('isSubscribed')->getData()
  266. );
  267. $this->getDoctrine()->getManager()->flush();
  268. $this->addFlash(
  269. 'success',
  270. "Successfully saved settings."
  271. );
  272. return $this->redirectToRoute('home');
  273. }
  274. return $this->render('user/account.html.twig', [
  275. 'user' => $user,
  276. 'passwordform' => $passwordform->createView(),
  277. 'accountform' => $accountform->createView(),
  278. ]);
  279. }
  280. /**
  281. * @Route("/phpinfo", name="phpinfo")
  282. * @IsGranted("ROLE_SUPER_ADMIN")
  283. */
  284. public function phpinfo(): Response
  285. {
  286. phpinfo();
  287. exit(0);
  288. }
  289. /**
  290. * @param $path
  291. * @return int
  292. */
  293. private function getDirectorySize($path): int
  294. {
  295. return 0; // Deprecated due to S3 usage
  296. }
  297. /**
  298. * @param $bytes
  299. * @param int $precision
  300. * @return string
  301. */
  302. function formatBytes($bytes, $precision = 2): string
  303. {
  304. $units = array('B', 'KB', 'MB', 'GB', 'TB');
  305. $bytes = max($bytes, 0);
  306. $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
  307. $pow = min($pow, count($units) - 1);
  308. $bytes /= pow(1024, $pow);
  309. return round($bytes, $precision) . ' ' . $units[$pow];
  310. }
  311. /**
  312. * @Route("/userguide", name="userguide")
  313. * @IsGranted("IS_AUTHENTICATED_REMEMBERED")
  314. **/
  315. public function downloadUserGuide(): BinaryFileResponse
  316. {
  317. $response = new BinaryFileResponse('assets/media/files/smarthub-user-guide.pdf');
  318. $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT,'smarthub-user-guide.pdf');
  319. return $response;
  320. }
  321. /**
  322. * @return array
  323. */
  324. private function getNotices(): array
  325. {
  326. $notices = [];
  327. if(!$this->isGranted('ROLE_ADMIN')) return $notices;
  328. $env = $this->getParameter('kernel.environment');
  329. $notices[] = "kernel.environment: $env";
  330. $notices[] = extension_loaded('imagick') ? 'imagick extension is installed' : 'imagick extension is not installed';
  331. $notices[] = shell_exec('which ffmpeg');
  332. $upload_max_filesize = ini_get('upload_max_filesize');
  333. $notices[] = "upload_max_filesize: $upload_max_filesize";
  334. $max_post = ini_get('post_max_size');
  335. $notices[] = "post_max_size: $max_post";
  336. $max_size_mb = preg_replace('/[^0-9]/', '', $upload_max_filesize);
  337. $max_post_mb = preg_replace('/[^0-9]/', '', $max_post);
  338. $min = min($max_size_mb, $max_post_mb);
  339. $notices[] = "file upload limit: $min";
  340. $memory_limit = ini_get('memory_limit');
  341. $notices[] = "memory_limit: $memory_limit";
  342. $img = new imagick();
  343. $imagick_limit_undefined = $img->getResourceLimit(imagick::RESOURCETYPE_UNDEFINED);
  344. $notices[] = "imagick_limit RESOURCETYPE_UNDEFINED: $imagick_limit_undefined";
  345. $imagick_limit_disk = $img->getResourceLimit(imagick::RESOURCETYPE_DISK);
  346. $notices[] = "imagick_limit RESOURCETYPE_DISK: $imagick_limit_disk";
  347. $imagick_limit_file = $img->getResourceLimit(imagick::RESOURCETYPE_FILE);
  348. $notices[] = "imagick_limit RESOURCETYPE_FILE: $imagick_limit_file";
  349. $imagick_limit_map = $img->getResourceLimit(imagick::RESOURCETYPE_MAP);
  350. $notices[] = "imagick_limit RESOURCETYPE_MAP: $imagick_limit_map";
  351. $imagick_limit_memory = $img->getResourceLimit(imagick::RESOURCETYPE_MEMORY);
  352. $notices[] = "imagick_limit RESOURCETYPE_MEMORY: $imagick_limit_memory";
  353. return $notices;
  354. }
  355. }