src/Controller/DebugController.php line 179

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Service\Features;
  4. use Symfony\Bundle\FrameworkBundle\Console\Application;
  5. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  6. use Symfony\Component\Console\Input\ArrayInput;
  7. use Symfony\Component\Console\Output\BufferedOutput;
  8. use Symfony\Component\Console\Output\NullOutput;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpFoundation\Response;
  11. use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
  12. use Symfony\Component\HttpKernel\KernelInterface;
  13. use Symfony\Component\Routing\Annotation\Route;
  14. class DebugController extends AbstractController
  15. {
  16.     private KernelInterface $kernel;
  17.     private Application $application;
  18.     public function __construct(KernelInterface $kernel)
  19.     {
  20.         $this->kernel = $kernel;
  21.         $this->application = new Application($this->kernel);
  22.         $this->application->setAutoExit(false);
  23.     }
  24.     #[Route(path: '/debug-features/', name: 'debug.task.debug_features')]
  25.     public function debugFeatures(Features $features): Response
  26.     {
  27.         $this->assertAvailable();
  28.         $features = [];
  29.         foreach ($_ENV as $k => $v) {
  30.             if(str_starts_with($k, 'FEATURE'))
  31.                 $features[$k] = $v;
  32.         }
  33.         ksort($features);
  34.         return $this->json($features);
  35.     }
  36.     #[Route(path: '/task-charge-placed/', name: 'debug.task.charge_placements')]
  37.     public function taskChargePlacements(): Response
  38.     {
  39.         return $this->getResponse($this->runCommand('sales:profile-saloon:adboard:charge'));
  40.     }
  41.     #[Route(path: '/task-charge-hidden/', name: 'debug.task.charge_hidings')]
  42.     public function taskChargeHidings(): Response
  43.     {
  44.         return $this->getResponse($this->runCommand('sales:profile:hiding:charge'));
  45.     }
  46.     #[Route(path: '/task-profiles-rotate/', name: 'debug.task.profiles.rotate')]
  47.     public function taskProfilesRotate(): Response
  48.     {
  49.         $output = $this->runCommand('sales:profile:adboard:rotate');
  50.         return $this->getResponse($output);
  51.     }
  52.     #[Route(path: '/task-saloons-rotate/', name: 'debug.task.saloons.rotate')]
  53.     public function taskSaloonsRotate(): Response
  54.     {
  55.         $output = $this->runCommand('sales:saloon:adboard:rotate');
  56.         return $this->getResponse($output);
  57.     }
  58.     #[Route(path: '/task-rotate/', name: 'debug.task.rotate')]
  59.     public function taskRotate(): Response
  60.     {
  61.         $output = $this->runCommand('sales:profile:adboard:rotate');
  62.         $output .= $this->runCommand('sales:saloon:adboard:rotate');
  63.         return $this->getResponse($output);
  64.     }
  65.     #[Route(path: '/task-profiles-rotate-free/', name: 'debug.task.profiles.rotate_free')]
  66.     public function taskProfilesRotateFree(): Response
  67.     {
  68.         return $this->getResponse($this->runCommand('sales:profile:adboard:rotate-free'));
  69.     }
  70.     #[Route(path: '/task-profiles-align/', name: 'debug.task.profiles.align')]
  71.     public function taskProfilesAlign(): Response
  72.     {
  73.         $output = $this->runCommand('sales:profile:adboard:align-positions');
  74.         return $this->getResponse($output);
  75.     }
  76.     #[Route(path: '/task-profiles-delete-rejected-on-moderation/', name: 'debug.task.profiles.delete_rejected_on_moderation')]
  77.     public function taskProfilesDeleteRejectedOnModeration(): Response
  78.     {
  79.         return $this->getResponse($this->runCommand('update:profiles:delete-rejected-on-moderation', [], ['interval' => '5 MINUTE']));
  80.     }
  81.     #[Route(path: '/task-users-set-trusted/', name: 'debug.task.users.set_trusted')]
  82.     public function taskUsersSetTrusted(): Response
  83.     {
  84.         return $this->getResponse($this->runCommand('update:users:set-trusted'));
  85.     }
  86.     #[Route(path: '/task-users-low-balance-notification/', name: 'debug.task.users.low_balance_notification')]
  87.     public function taskUsersLowBalanceNotification(): Response
  88.     {
  89.         return $this->getResponse($this->runCommand('sales:user:low-balance:notify'));
  90.     }
  91.     #[Route(path: '/task-persist-ctr-values-permanent/', name: 'debug.task.profile_ctr.persist_permanent')]
  92.     public function taskPersistCtrValuesPermanent(): Response
  93.     {
  94.         return $this->getResponse($this->runCommand('maintenance:profile-ctr:persist-permanent'));
  95.     }
  96.     #[Route(path: '/task-clear-ctr-values-cache/', name: 'debug.task.profile_ctr.clear_cache')]
  97.     public function taskClearCtrValuesCache(): Response
  98.     {
  99.         return $this->getResponse($this->runCommand('maintenance:profile-ctr:clear-cache'));
  100.     }
  101.     #[Route(path: '/task-clear-project-data-cache/', name: 'debug.task.project_data.clear_cache')]
  102.     public function taskClearProjectDataCache(): Response
  103.     {
  104.         return $this->getResponse($this->runCommand('cache:pool:clear', ['pools' => ['project_data.cache']]));
  105.     }
  106.     #[Route(path: '/task-geo-category-linkage-refresh/', name: 'debug.task.geo_category_linkage.refresh')]
  107.     public function taskGeoCategoryLinkageRefresh(): Response
  108.     {
  109.         return $this->getResponse($this->runCommand('maintenance:geo-category-linkage:refresh'));
  110.     }
  111.     #[Route(path: '/task-refresh-cold-start-recommendations/', name: 'debug.task.recommendations.cold_start.refresh')]
  112.     public function taskRefreshColdStartRecommendations(): Response
  113.     {
  114.         return $this->getResponse($this->runCommand('maintenance:recommendations:cold-start:refresh', [], ['verbose' => true]));
  115.     }
  116.     #[Route(path: '/task-top-100-refresh/', name: 'debug.task.top_100.refresh')]
  117.     public function taskTop100Refresh(): Response
  118.     {
  119.         return $this->getResponse($this->runCommand('maintenance:top-100:refresh'));
  120.     }
  121.     #[Route(path: '/task-map-fallback-refresh/', name: 'debug.task.map_fallback.refresh')]
  122.     public function taskMapFallbackRefresh(): Response
  123.     {
  124.         return $this->getResponse($this->runCommand('maintenance:map-fallback:refresh'));
  125.     }
  126.     #[Route(path: '/task-profile-names-refresh/', name: 'debug.task.profile_names.refresh')]
  127.     public function taskProfileNamesRefresh(): Response
  128.     {
  129.         return $this->getResponse($this->runCommand('maintenance:profile-names:refresh-counts'));
  130.     }
  131.     #[Route(path: '/process-bulk-background-actions/', name: 'debug.task.background.bulk.process_actions')]
  132.     public function taskProcessBulkBackgroundAction(): Response
  133.     {
  134.         set_time_limit(300);
  135.         $this->runCommand('account:bulk-queue:process');
  136.         return $this->getResponse('OK');
  137.     }
  138.     #[Route(path: '/process-bulk-background-actions-via-consumer/', name: 'debug.task.background.bulk.process_actions_via_consumer')]
  139.     public function taskProcessBulkBackgroundActionViaConsumer(): Response
  140.     {
  141.         set_time_limit(600);
  142.         $this->runCommand('messenger:consume');
  143.         return $this->getResponse('OK');
  144.     }
  145.     #[Route(path: '/process-support-broadcast-via-web/', name: 'debug.task.support_broadcast.process_via_web')]
  146.     public function taskProcessSupportBroadcastViaWeb(): Response
  147.     {
  148.         set_time_limit(120);
  149.         $output = $this->runCommand('messenger:consume', ['receivers' => ['async']], [
  150.             'limit' => 100,
  151.             'time-limit' => 60,
  152.             'memory-limit' => '256M',
  153.             'no-reset' => true,
  154.         ]);
  155.         return $this->getResponse($output ?: 'OK');
  156.     }
  157.     #[Route(path: '/process-video-transcoding/', name: 'debug.task.background.process_video_transcoding')]
  158.     public function taskProcessVideoTranscoding(): Response
  159.     {
  160.         set_time_limit(600);
  161.         $this->runCommand('messenger:consume', ['receivers' => ['transcoding']], ['limit' => 1]);
  162.         return $this->getResponse('OK');
  163.     }
  164.     #[Route(path: '/process-test-data-dummy-profiles-create/', name: 'debug.task.test-data.dummy-profiles.create')]
  165.     public function taskCreateDummyProfiles(): Response
  166.     {
  167.         set_time_limit(600);
  168.         return $this->getResponse($this->runCommand('test-data:dummy-profiles:create', ['default_user' => true]));
  169.     }
  170.     #[Route(path: '/task-hide-free-unapproved-placements/', name: 'debug.task.hide_free_unapproved_placements')]
  171.     public function taskHideFreeUnapprovedPlacements(): Response
  172.     {
  173.         return $this->getResponse($this->runCommand('update:profiles:hide-free-unapproved-placements'));
  174.     }
  175.     #[Route(path: '/genereate-profiles-export/', name: 'debug.task.export.create')]
  176.     public function taskCreateProfilesExport(): Response
  177.     {
  178.         set_time_limit(600);
  179.         return $this->getResponse($this->runCommand('export:profiles', [], [
  180.             'city' => 'moscow',
  181.             'price_gte' => 15000,
  182.         ]));
  183.     }
  184.     #[Route(path: '/task-stations-update/', name: 'debug.task.stations_update')]
  185.     public function taskStationsUpdate(): Response
  186.     {
  187.         return $this->getResponse($this->runCommand('stations:update'));
  188.     }
  189.     #[Route(path: '/task-set-seo-phone-numbers-to-profiles/', name: 'debug.task.set_seo_phone_numbers_to_profiles')]
  190.     public function taskSetSeoPhoneNumbersToProfiles(): Response
  191.     {
  192.         return $this->getResponse($this->runCommand('maintenance:seo:set-phones-to-profiles'));
  193.     }
  194.     #[Route(path: '/task-set-seo-phone-numbers-to-saloons/', name: 'debug.task.set_seo_phone_numbers_to_saloons')]
  195.     public function taskSetSeoPhoneNumbersToSaloons(): Response
  196.     {
  197.         return $this->getResponse($this->runCommand('maintenance:seo:set-phones-to-saloons'));
  198.     }
  199.     #[Route(path: '/task-plan-placement-sync/', name: 'debug.task.plan_placement.sync', methods: ['GET', 'POST'])]
  200.     public function taskPlanPlacementSync(Request $request): Response
  201.     {
  202.         $this->assertAvailable();
  203.         $timezone = (string)$request->request->get('timezone', 'Europe/Moscow');
  204.         $at = (string)$request->request->get(
  205.             'at',
  206.             (new \DateTimeImmutable('now', new \DateTimeZone('Europe/Moscow')))->format('Y-m-d H:i:s')
  207.         );
  208.         $profile = trim((string)$request->request->get('profile', ''));
  209.         $onlySync = (bool)$request->request->get('only_sync', false);
  210.         $output = null;
  211.         if ($request->isMethod('POST')) {
  212.             $options = [
  213.                 'at' => $at,
  214.                 'timezone' => $timezone,
  215.             ];
  216.             if ('' !== $profile) {
  217.                 $options['profile'] = $profile;
  218.             }
  219.             if ($onlySync) {
  220.                 $options['only-sync'] = true;
  221.             }
  222.             $output = $this->runCommand('debug:plan-placement:sync', [], $options);
  223.         }
  224.         return $this->render('debug/plan_placement_sync.html.twig', [
  225.             'at' => $at,
  226.             'timezone' => $timezone,
  227.             'profile' => $profile,
  228.             'only_sync' => $onlySync,
  229.             'output' => $output,
  230.         ]);
  231.     }
  232.     protected function assertAvailable()
  233.     {
  234.         if($this->kernel->getEnvironment() != 'dev'
  235.             && $this->kernel->getEnvironment() != 'review')
  236.             throw new UnauthorizedHttpException('Not available');
  237.     }
  238.     protected function runCommand(string $command, array $arguments = [], array $options = []): string
  239.     {
  240.         $this->assertAvailable();
  241.         $arrayInput = [
  242.             'command' => $command,
  243.         ];
  244.         foreach ($arguments as $k => $v)
  245.             $arrayInput[$k] = $v;
  246.         foreach ($options as $k => $v)
  247.             $arrayInput['--'.$k] = $v;
  248.         $input = new ArrayInput($arrayInput);
  249.         $output = new BufferedOutput();
  250.         $this->application->run($input, $output);
  251.         return $output->fetch();
  252.     }
  253.     protected function getResponse(string $output): Response
  254.     {
  255.         return new Response($output, headers: ['Content-Type' => 'text/plain; charset=utf-8']);
  256.     }
  257. }