diff --git a/Controller/Admin/EtlDashboardController.php b/Controller/Admin/EtlDashboardController.php index 17cbfc8..c86834d 100644 --- a/Controller/Admin/EtlDashboardController.php +++ b/Controller/Admin/EtlDashboardController.php @@ -1,5 +1,7 @@ etlExecutionRepository = $etlExecutionRepository; } - /** * @Route("/etl/execution/dashboard", name="etl_execution_dashboard") */ @@ -32,28 +27,28 @@ public function index($startDate = null, $endDate = null): Response { $this->denyAccessUnlessGranted(EtlExecutionVoter::DASHBOARD, EtlExecution::class); - if (is_null($endDate)) { + if (null === $endDate) { $endDate = new \DateTime(); } - if (is_null($startDate)) { + if (null === $startDate) { $startDate = new \DateTime('7 days ago'); } - //TODO add Acl here for future proofing. + // TODO add Acl here for future proofing. return $this->render( - "@Oliverde8PhpEtlEasyAdmin/admin/dashboard.html.twig", + '@Oliverde8PhpEtlEasyAdmin/admin/dashboard.html.twig', [ - 'num_waiting' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_WAITING), - 'num_running' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_RUNNING), - 'num_success' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_SUCCESS), - 'num_failure' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_FAILURE), - 'max_wait_time' => $this->etlExecutionRepository->getMaxWaitTime($startDate, $endDate), - 'avg_wait_time' => $this->etlExecutionRepository->getAvgWaitTime($startDate, $endDate), - 'most_executed' => $this->etlExecutionRepository->getMostExecutedJobs($startDate, $endDate, 10), + 'num_waiting' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_WAITING), + 'num_running' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_RUNNING), + 'num_success' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_SUCCESS), + 'num_failure' => $this->etlExecutionRepository->getCountInStatus($startDate, $endDate, EtlExecution::STATUS_FAILURE), + 'max_wait_time' => $this->etlExecutionRepository->getMaxWaitTime($startDate, $endDate), + 'avg_wait_time' => $this->etlExecutionRepository->getAvgWaitTime($startDate, $endDate), + 'most_executed' => $this->etlExecutionRepository->getMostExecutedJobs($startDate, $endDate, 10), 'most_time_spent' => $this->etlExecutionRepository->getMostTimeSpentJobs($startDate, $endDate, 10), - 'longest' => $this->etlExecutionRepository->getLongestJobs($startDate, $endDate, 10), - 'crudController' => EtlExecutionCrudController::class + 'longest' => $this->etlExecutionRepository->getLongestJobs($startDate, $endDate, 10), + 'crudController' => EtlExecutionCrudController::class, ] ); } diff --git a/Controller/Admin/EtlDownloadFileController.php b/Controller/Admin/EtlDownloadFileController.php index 8c9e605..ed32d75 100644 --- a/Controller/Admin/EtlDownloadFileController.php +++ b/Controller/Admin/EtlDownloadFileController.php @@ -1,35 +1,28 @@ executionContextFactory = $executionContextFactory; } /** * @Route("/etl/execution/download", name="etl_execution_download_file") + * * @ParamConverter(name="execution", Class="Oliverde8PhpEtlBundle:EtlExecution") */ public function index(EtlExecution $execution, string $filename): Response @@ -37,16 +30,16 @@ public function index(EtlExecution $execution, string $filename): Response $this->denyAccessUnlessGranted(EtlExecutionVoter::DOWNLOAD, EtlExecution::class); $context = $this->executionContextFactory->get(['etl' => ['execution' => $execution]]); - $file = $context->getFileSystem()->readStream($filename); + $file = $context->getFileSystem()->readStream($filename); - $response = new StreamedResponse(function () use ($file) { - $outputStream = fopen('php://output', 'wb'); + $response = new StreamedResponse(static function () use ($file): void { + $outputStream = fopen('php://output', 'w'); stream_copy_to_stream($file, $outputStream); }); $disposition = HeaderUtils::makeDisposition( HeaderUtils::DISPOSITION_ATTACHMENT, - "execution-{$execution->getName()}-{$execution->getId()}-" . $filename + \sprintf('execution-%s-%s-', $execution->getName(), $execution->getId()).$filename ); $response->headers->set('Content-Disposition', $disposition); diff --git a/Controller/Admin/EtlExecutionCrudController.php b/Controller/Admin/EtlExecutionCrudController.php index afe9185..3128518 100644 --- a/Controller/Admin/EtlExecutionCrudController.php +++ b/Controller/Admin/EtlExecutionCrudController.php @@ -1,5 +1,7 @@ executionContextFactory = $executionContextFactory; - $this->chainProcessorManager = $chainProcessorManager; - $this->adminUrlGenerator = $adminUrlGenerator; + public function __construct(protected ExecutionContextFactory $executionContextFactory, protected ChainProcessorsManager $chainProcessorManager, protected AdminUrlGenerator $adminUrlGenerator) + { } - public static function getEntityFqcn(): string { return EtlExecution::class; @@ -62,6 +47,7 @@ public function configureActions(Actions $actions): Actions if (!$this->isGranted(EtlExecutionVoter::QUEUE, EtlExecution::class)) { $actions->remove(Crud::PAGE_INDEX, Action::NEW); } + if (!$this->isGranted(EtlExecutionVoter::VIEW, EtlExecution::class)) { $actions->remove(Crud::PAGE_INDEX, Action::DETAIL); } @@ -72,9 +58,9 @@ public function configureActions(Actions $actions): Actions public function configureCrud(Crud $crud): Crud { return $crud - ->setPageTitle("index", "Etl Executions") + ->setPageTitle('index', 'Etl Executions') ->setDateTimeFormat('dd/MM/y - HH:mm:ss') - ->setSearchFields(["name", "id"]) + ->setSearchFields(['name', 'id']) ->setDefaultSort(['id' => 'DESC']); } @@ -82,32 +68,32 @@ public function configureFields(string $pageName): iterable { if (Crud::PAGE_DETAIL === $pageName) { return [ - FormField::addPanel("Details")->addCssClass("col-12 col-xl-6"), + FormField::addFieldset('Details')->addCssClass('col-12 col-xl-6'), Field::new('name'), Field::new('username'), TextField::new('status')->setTemplatePath('@Oliverde8PhpEtlEasyAdmin/fields/status.html.twig'), - FormField::addPanel()->addCssClass("col-12 col-xl-6"), + FormField::addFieldset()->addCssClass('col-12 col-xl-6'), Field::new('createTime'), Field::new('startTime'), Field::new('endTime'), Field::new('failTime'), - FormField::addPanel('Execution Inputs')->addCssClass('col-12'), + FormField::addFieldset('Execution Inputs')->addCssClass('col-12'), CodeEditorField::new('inputData')->setTemplatePath('@Oliverde8PhpEtlEasyAdmin/fields/code_editor.html.twig')->addCssClass('etl-json-div'), CodeEditorField::new('inputOptions')->setTemplatePath('@Oliverde8PhpEtlEasyAdmin/fields/code_editor.html.twig')->addCssClass('etl-json-div'), CodeEditorField::new('definition')->setTemplatePath('@Oliverde8PhpEtlEasyAdmin/fields/code_editor.html.twig'), - FormField::addPanel('Execution outpus')->addCssClass("col-12"), - TextField::new('Files')->formatValue(function ($value, EtlExecution $entity) { + FormField::addFieldset('Execution outpus')->addCssClass('col-12'), + TextField::new('Files')->formatValue(function ($value, EtlExecution $entity): array { $urls = []; if ($this->isGranted(EtlExecutionVoter::DOWNLOAD, EtlExecution::class)) { $context = $this->executionContextFactory->get(['etl' => ['execution' => $entity]]); - $files = $context->getFileSystem()->listContents("/"); + $files = $context->getFileSystem()->listContents('/'); foreach ($files as $file) { - if (strpos($file, '.') !== 0) { + if (!str_starts_with($file, '.')) { $url = $this->adminUrlGenerator - ->setRoute("etl_execution_download_file", ['execution' => $entity->getId(), 'filename' => $file]) + ->setRoute('etl_execution_download_file', ['execution' => $entity->getId(), 'filename' => $file]) ->generateUrl(); $urls[$url] = $file; @@ -119,39 +105,42 @@ public function configureFields(string $pageName): iterable })->setTemplatePath('@Oliverde8PhpEtlEasyAdmin/fields/files.html.twig'), CodeEditorField::new('errorMessage')->setTemplatePath('@Oliverde8PhpEtlEasyAdmin/fields/code_editor.html.twig'), - TextField::new('Logs')->formatValue(function ($value, EtlExecution $entity) { + TextField::new('Logs')->formatValue(function ($value, EtlExecution $entity): array { $context = $this->executionContextFactory->get(['etl' => ['execution' => $entity]]); - $logs = []; - if ($context->getFileSystem()->fileExists("execution.log")) { - $file = $context->getFileSystem()->readStream("execution.log"); - $i = 0; + $logs = []; + if ($context->getFileSystem()->fileExists('execution.log')) { + $file = $context->getFileSystem()->readStream('execution.log'); + $i = 0; while ($i < 100 && $line = fgets($file)) { $logs[] = $line; - $i++; + ++$i; } + fclose($file); } - $url = ""; + $url = ''; $moreLogs = false; - if (!empty($logs)) { + if ([] !== $logs) { $url = $this->adminUrlGenerator - ->setRoute("etl_execution_download_file", ['execution' => $entity->getId(), 'filename' => 'execution.log']) + ->setRoute('etl_execution_download_file', ['execution' => $entity->getId(), 'filename' => 'execution.log']) ->generateUrl(); } - if (count($logs) > 100) { + + if (\count($logs) > 100) { $moreLogs = true; } return [ - "lines" => $logs, + 'lines' => $logs, 'downloadUrl' => $url, - 'moreLogs' => $moreLogs, + 'moreLogs' => $moreLogs, ]; })->setTemplatePath('@Oliverde8PhpEtlEasyAdmin/fields/logs.html.twig'), ]; } + if (Crud::PAGE_INDEX === $pageName) { return [ Field::new('id'), @@ -163,12 +152,13 @@ public function configureFields(string $pageName): iterable Field::new('endTime'), ]; } + if (Crud::PAGE_NEW === $pageName) { return [ ChoiceField::new('name', 'Chain Name') ->setChoices($this->getChainOptions()), - CodeEditorField::new('inputData')->setCssClass("etl-json-input"), - CodeEditorField::new('inputOptions')->setCssClass("etl-json-input"), + CodeEditorField::new('inputData')->setCssClass('etl-json-input'), + CodeEditorField::new('inputOptions')->setCssClass('etl-json-input'), ]; } @@ -200,16 +190,17 @@ public function configureFilters(Filters $filters): Filters ->add('endTime'); } - public function createEntity(string $entityFqcn) + public function createEntity(string $entityFqcn): object { - $user = $this->getUser(); + $user = $this->getUser(); $username = null; - if ($user) { - $username = $user->getUsername(); + if ($user instanceof \Symfony\Component\Security\Core\User\UserInterface) { + $username = $user->getUserIdentifier(); } - $execution = new EtlExecution("", "", [], []); + $execution = new EtlExecution('', '', [], []); $execution->setUsername($username); + return $execution; } @@ -219,10 +210,13 @@ public function persistEntity(EntityManagerInterface $entityManager, $entityInst $entityManager->flush(); } - protected function getChainOptions() + /** + * @return int[]|string[] + */ + protected function getChainOptions(): array { $options = []; - foreach (array_keys($this->chainProcessorManager->getRewDefinitions()) as $definitionName) { + foreach (array_keys($this->chainProcessorManager->getRawDefinitions()) as $definitionName) { $options[$definitionName] = $definitionName; } diff --git a/DependencyInjection/Oliverde8PhpEtlEasyAdminExtension.php b/DependencyInjection/Oliverde8PhpEtlEasyAdminExtension.php index 9451b91..d778473 100644 --- a/DependencyInjection/Oliverde8PhpEtlEasyAdminExtension.php +++ b/DependencyInjection/Oliverde8PhpEtlEasyAdminExtension.php @@ -1,9 +1,9 @@ load('services.yml'); diff --git a/Oliverde8PhpEtlEasyAdminBundle.php b/Oliverde8PhpEtlEasyAdminBundle.php index 5e9a5a8..0bc28ca 100644 --- a/Oliverde8PhpEtlEasyAdminBundle.php +++ b/Oliverde8PhpEtlEasyAdminBundle.php @@ -1,12 +1,9 @@ =8.0", - "oliverde8/php-etl-bundle": "^1.1", - "easycorp/easyadmin-bundle": "^4.0" + "oliverde8/php-etl-bundle": "^v2.0.0-alpha1", + "easycorp/easyadmin-bundle": "^5.0" }, "autoload": { "psr-4": {