Passed
Push — main ( bd03c4...c6ca62 )
by De Cramer
04:36
created

EtlExecutionCrudController   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 21
eloc 112
c 1
b 0
f 0
dl 0
loc 194
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getChainOptions() 0 8 2
A configureFilters() 0 15 1
A __construct() 0 8 1
A configureActions() 0 18 3
A persistEntity() 0 4 1
A configureCrud() 0 7 1
A configureAssets() 0 6 1
B configureFields() 0 79 8
A createEntity() 0 11 2
A getEntityFqcn() 0 3 1
1
<?php
2
3
namespace Oliverde8\PhpEtlBundle\Controller\Admin;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
7
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
8
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
9
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
10
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
11
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
12
use EasyCorp\Bundle\EasyAdminBundle\Field\CodeEditorField;
13
use EasyCorp\Bundle\EasyAdminBundle\Field\Field;
14
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField;
15
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
16
use EasyCorp\Bundle\EasyAdminBundle\Filter\ChoiceFilter;
17
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
18
use Oliverde8\PhpEtlBundle\Entity\EtlExecution;
19
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
20
use Oliverde8\PhpEtlBundle\Security\EtlExecutionVoter;
21
use Oliverde8\PhpEtlBundle\Services\ChainProcessorsManager;
22
use Oliverde8\PhpEtlBundle\Services\ChainWorkDirManager;
23
24
class EtlExecutionCrudController extends AbstractCrudController
25
{
26
    /** @var ChainWorkDirManager */
27
    protected $chainWorkDirManager;
28
29
    /** @var ChainProcessorsManager */
30
    protected $chainProcessorManager;
31
32
    /** @var AdminUrlGenerator */
33
    protected $adminUrlGenerator;
34
35
    /**
36
     * EtlExecutionCrudController constructor.
37
     * @param ChainWorkDirManager $chainWorkDirManager
38
     * @param ChainProcessorsManager $chainProcessorManager
39
     * @param AdminUrlGenerator $adminUrlGenerator
40
     */
41
    public function __construct(
42
        ChainWorkDirManager $chainWorkDirManager,
43
        ChainProcessorsManager $chainProcessorManager,
44
        AdminUrlGenerator $adminUrlGenerator
45
    ) {
46
        $this->chainWorkDirManager = $chainWorkDirManager;
47
        $this->chainProcessorManager = $chainProcessorManager;
48
        $this->adminUrlGenerator = $adminUrlGenerator;
49
    }
50
51
    public static function getEntityFqcn(): string
52
    {
53
        return EtlExecution::class;
54
    }
55
56
    public function configureActions(Actions $actions): Actions
57
    {
58
59
        $actions
60
            ->add(Crud::PAGE_INDEX, Action::DETAIL)
61
            ->remove(Crud::PAGE_INDEX, Action::EDIT)
62
            ->remove(Crud::PAGE_INDEX, Action::DELETE)
63
            ->remove(Crud::PAGE_DETAIL, Action::EDIT)
64
            ->remove(Crud::PAGE_DETAIL, Action::DELETE);
65
66
        if (!$this->isGranted(EtlExecutionVoter::QUEUE, EtlExecution::class)) {
67
            $actions->remove(Crud::PAGE_INDEX, Action::NEW);
68
        }
69
        if (!$this->isGranted(EtlExecutionVoter::VIEW, EtlExecution::class)) {
70
            $actions->remove(Crud::PAGE_INDEX, Action::DETAIL);
71
        }
72
73
        return $actions;
74
    }
75
76
    public function configureCrud(Crud $crud): Crud
77
    {
78
        return $crud
79
            ->setPageTitle("index", "Etl Executions")
80
            ->setDateTimeFormat('dd/MM/y - HH:mm:ss')
81
            ->setSearchFields(["name", "id"])
82
            ->setDefaultSort(['id' => 'DESC']);
83
    }
84
85
    public function configureFields(string $pageName): iterable
86
    {
87
        if (Crud::PAGE_DETAIL === $pageName) {
88
            return [
89
                FormField::addPanel("Details")->addCssClass("col-12 col-xl-6"),
90
                Field::new('name'),
91
                Field::new('username'),
92
                TextField::new('status')->setTemplatePath('@Oliverde8PhpEtl/fields/status.html.twig'),
93
                FormField::addPanel()->addCssClass("col-12 col-xl-6"),
94
                Field::new('createTime'),
95
                Field::new('startTime'),
96
                Field::new('endTime'),
97
                Field::new('failTime'),
98
99
                FormField::addPanel('Execution Inputs')->addCssClass('col-12'),
100
                CodeEditorField::new('inputData')->setTemplatePath('@Oliverde8PhpEtl/fields/code_editor.html.twig')->addCssClass('etl-json-div'),
101
                CodeEditorField::new('inputOptions')->setTemplatePath('@Oliverde8PhpEtl/fields/code_editor.html.twig')->addCssClass('etl-json-div'),
102
                CodeEditorField::new('definition')->setTemplatePath('@Oliverde8PhpEtl/fields/code_editor.html.twig'),
103
104
                FormField::addPanel('Execution outpus')->addCssClass("col-12"),
105
                TextField::new('Files')->formatValue(function ($value, EtlExecution $entity) {
106
                    $urls = [];
107
                    if ($this->isGranted(EtlExecutionVoter::DOWNLOAD, EtlExecution::class)) {
108
                        $files = $this->chainWorkDirManager->listFiles($entity);
109
                        foreach ($files as $file) {
110
                            $url = $this->adminUrlGenerator
111
                                ->setRoute("etl_execution_download_file", ['execution' => $entity->getId(), 'filename' => $file])
112
                                ->generateUrl();
113
114
                            $urls[$url] = $file;
115
                        }
116
                    }
117
118
                    return $urls;
119
                })->setTemplatePath('@Oliverde8PhpEtl/fields/files.html.twig'),
120
                CodeEditorField::new('errorMessage')->setTemplatePath('@Oliverde8PhpEtl/fields/code_editor.html.twig'),
121
                TextField::new('Logs')->formatValue(function ($value, EtlExecution $entity) {
122
                    $logs = $this->chainWorkDirManager->getFirstLogLines($entity, 100);
123
                    $url = "";
124
                    $moreLogs = false;
125
                    if (!empty($logs)) {
126
                        $url = $this->adminUrlGenerator
127
                            ->setRoute("etl_execution_download_file", ['execution' => $entity->getId(), 'filename' => 'execution.log'])
128
                            ->generateUrl();
129
                    }
130
                    if (count($logs) > 100) {
131
                        $moreLogs = true;
132
                    }
133
134
                    return [
135
                        "lines" => $logs,
136
                        'downloadUrl' => $url,
137
                        'moreLogs' => $moreLogs,
138
                    ];
139
                })->setTemplatePath('@Oliverde8PhpEtl/fields/logs.html.twig'),
140
141
            ];
142
        }
143
        if (Crud::PAGE_INDEX === $pageName) {
144
            return [
145
                Field::new('id'),
146
                Field::new('name'),
147
                Field::new('username'),
148
                TextField::new('status')->setTemplatePath('@Oliverde8PhpEtl/fields/status.html.twig'),
149
                Field::new('createTime'),
150
                Field::new('startTime'),
151
                Field::new('endTime'),
152
            ];
153
        }
154
        if (Crud::PAGE_NEW === $pageName) {
155
            return [
156
                ChoiceField::new('name', 'Chain Name')
157
                    ->setChoices($this->getChainOptions()),
158
                CodeEditorField::new('inputData')->setCssClass("etl-json-input"),
159
                CodeEditorField::new('inputOptions')->setCssClass("etl-json-input"),
160
            ];
161
        }
162
163
        return parent::configureFields($pageName);
164
    }
165
166
    public function configureAssets(Assets $assets): Assets
167
    {
168
        return $assets
169
            ->addJsFile('https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.4.1/jsoneditor.min.js')
170
            ->addCssFile('https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.4.1/jsoneditor.min.css')
171
            ->addJsFile('/bundles/oliverde8phpetl/admin/fields/json-editor.js');
172
    }
173
174
    public function configureFilters(Filters $filters): Filters
175
    {
176
        return $filters
177
            ->add('name')
178
            ->add('username')
179
            ->add(
180
                ChoiceFilter::new('status')->setChoices([
181
                    EtlExecution::STATUS_WAITING => EtlExecution::STATUS_WAITING,
182
                    EtlExecution::STATUS_RUNNING => EtlExecution::STATUS_RUNNING,
183
                    EtlExecution::STATUS_SUCCESS => EtlExecution::STATUS_SUCCESS,
184
                    EtlExecution::STATUS_FAILURE => EtlExecution::STATUS_FAILURE,
185
                ])->canSelectMultiple()
186
            )
187
            ->add('startTime')
188
            ->add('endTime');
189
    }
190
191
    public function createEntity(string $entityFqcn)
192
    {
193
        $user = $this->getUser();
194
        $username = null;
195
        if ($user) {
196
            $username = $user->getUsername();
197
        }
198
199
        $execution = new EtlExecution("", "", [], []);
200
        $execution->setUsername($username);
201
        return $execution;
202
    }
203
204
    public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
205
    {
206
        $entityManager->persist($entityInstance);
207
        $entityManager->flush();
208
    }
209
210
    protected function getChainOptions()
211
    {
212
        $options = [];
213
        foreach (array_keys($this->chainProcessorManager->getDefinitions()) as $definitionName) {
214
            $options[$definitionName] = $definitionName;
215
        }
216
217
        return $options;
218
    }
219
}
220