Issues (62)

Command/WorkflowCommand.php (7 issues)

1
<?php
2
3
namespace Kaliop\eZWorkflowEngineBundle\Command;
4
5
use Kaliop\eZMigrationBundle\API\Value\Migration;
6
use Kaliop\eZMigrationBundle\API\Value\MigrationDefinition;
7
use Symfony\Component\Console\Input\InputArgument;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
/**
13
 * Command to manipulate existing workflows.
14
 */
15
class WorkflowCommand extends AbstractCommand
16
{
17
    /**
18
     * Set up the command.
19
     *
20
     * Define the name, options and help text.
21
     */
22
    protected function configure()
23
    {
24
        parent::configure();
25
26
        $this
27
            ->setName('kaliop:workflows:workflow')
28
            ->setDescription('Manually delete workflows from the database table.')
29
            ->addOption('delete', null, InputOption::VALUE_NONE, "Delete the specified workflow.")
30
            ->addOption('info', null, InputOption::VALUE_NONE, "Get info about the specified workflow.")
31
            ->addOption('fail', null, InputOption::VALUE_NONE, "Mark the specified migration as failed.")
32
            ->addOption('no-interaction', 'n', InputOption::VALUE_NONE, "Do not ask any interactive question.")
33
            ->addArgument('workflow', InputArgument::REQUIRED, 'The workflow to view or delete (plain workflow name).', null)
34
            ->setHelp(<<<EOT
35
The <info>kaliop:workflows:workflow</info> command allows you to manually manage workflows in the database table.
36
37
To see detailed information about a workflow:
38
39
    <info>php bin/console kaliop:workflows:workflow --info workflow_name</info>
40
41
To remove a workflow from the workflow table, or mark it as failed:
42
43
    <info>php bin/console kaliop:workflows:workflow --delete workflow_name</info>
44
45
    <info>php bin/console kaliop:workflows:workflow --fail workflow_name</info>
46
EOT
47
            );
48
    }
49
50
    /**
51
     * Execute the command.
52
     *
53
     * @param InputInterface $input
54
     * @param OutputInterface $output
55
     * @return null|int null or 0 if everything went fine, or an error code
56
     */
57
    protected function execute(InputInterface $input, OutputInterface $output)
58
    {
59
        if (!$input->getOption('delete') && !$input->getOption('info') && !$input->getOption('fail')) {
60
            throw new \InvalidArgumentException('You must specify whether you want to --delete, --fail or --info the specified workflow.');
61
        }
62
63
        $workflowService = $this->getWorkflowService();
64
        $workflowNameOrPath = $input->getArgument('workflow');
65
66
        if ($input->getOption('info')) {
67
            $output->writeln('');
68
69
            $workflow = $workflowService->getWorkflow($workflowNameOrPath);
0 ignored issues
show
The method getWorkflow() does not exist on Kaliop\eZWorkflowEngineB...e\WorkflowServiceFacade. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

69
            /** @scrutinizer ignore-call */ 
70
            $workflow = $workflowService->getWorkflow($workflowNameOrPath);
Loading history...
70
            if ($workflow == null) {
71
                throw new \InvalidArgumentException(sprintf('The workflow "%s" does not exist in the database table.', $workflowNameOrPath));
0 ignored issues
show
It seems like $workflowNameOrPath can also be of type string[]; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

71
                throw new \InvalidArgumentException(sprintf('The workflow "%s" does not exist in the database table.', /** @scrutinizer ignore-type */ $workflowNameOrPath));
Loading history...
72
            }
73
74
            switch ($workflow->status) {
75
                case Migration::STATUS_DONE:
76
                    $status = '<info>executed</info>';
77
                    break;
78
                case Migration::STATUS_STARTED:
79
                    $status = '<comment>execution started</comment>';
80
                    break;
81
                case Migration::STATUS_TODO:
82
                    // bold to-migrate!
83
                    $status = '<error>not executed</error>';
84
                    break;
85
                case Migration::STATUS_SKIPPED:
86
                    $status = '<comment>skipped</comment>';
87
                    break;
88
                case Migration::STATUS_PARTIALLY_DONE:
89
                    $status = '<comment>partially executed</comment>';
90
                    break;
91
                case Migration::STATUS_SUSPENDED:
92
                    $status = '<comment>suspended</comment>';
93
                    break;
94
                case Migration::STATUS_FAILED:
95
                    $status = '<error>failed</error>';
96
                    break;
97
            }
98
99
            $output->writeln('<info>Workflow: ' . $workflow->name . '</info>');
100
            $output->writeln('Status: ' . $status);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $status does not seem to be defined for all execution paths leading up to this point.
Loading history...
101
            $output->writeln('Executed on: <info>' . ($workflow->executionDate != null ? date("Y-m-d H:i:s", $workflow->executionDate) : '--'). '</info>');
102
            $output->writeln('Execution notes: <info>' . $workflow->executionError . '</info>');
103
            $output->writeln('Signal: <info>' . $workflow->signalName . '</info>');
104
105
            if ($workflow->status == Migration::STATUS_SUSPENDED) {
106
                /// @todo decode the suspension context: date, step, ...
107
            }
108
109
            $output->writeln('Definition path: <info>' . $workflow->path . '</info>');
110
            $output->writeln('Definition md5: <info>' . $workflow->md5 . '</info>');
111
112
            if ($workflow->path != '') {
113
                // q: what if we have a loader which does not work with is_file? We could probably remove this check...
114
                if (is_file($workflow->path)) {
115
                    try {
116
                        $workflowDefinitionCollection = $workflowService->getWorkflowsDefinitions(array($workflow->path));
117
                        if (count($workflowDefinitionCollection)) {
118
                            $workflowDefinition = $workflowDefinitionCollection->reset();
119
                            $workflowDefinition = $workflowService->parseWorkflowDefinition($workflowDefinition);
0 ignored issues
show
The method parseWorkflowDefinition() does not exist on Kaliop\eZWorkflowEngineB...e\WorkflowServiceFacade. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

119
                            /** @scrutinizer ignore-call */ 
120
                            $workflowDefinition = $workflowService->parseWorkflowDefinition($workflowDefinition);
Loading history...
120
121
                            if ($workflowDefinition->status != MigrationDefinition::STATUS_PARSED) {
122
                                $output->writeln('Definition error: <error>' . $workflowDefinition->parsingError . '</error>');
123
                            }
124
125
                            if (md5($workflowDefinition->rawDefinition) != $workflow->md5) {
126
                                $output->writeln('Notes: <comment>The workflow definition file has now a different checksum</comment>');
127
                            }
128
129
                            $output->writeln('Switch User: <info>' . (($workflowDefinition->runAs === false) ? '-' : $workflowDefinition->runAs) . '</info>');
130
                            $output->writeln('Use transaction: <info>' . ($workflowDefinition->useTransaction ? 'Y' : 'N') . '</info>');
131
132
                        } else {
133
                            $output->writeln('Definition error: <error>The workflow definition file can not be loaded</error>');
134
                        }
135
                    } catch (\Exception $e) {
136
                        /// @todo one day we should be able to limit the kind of exceptions we have to catch here...
137
                        $output->writeln('Definition parsing error: <error>' . $e->getMessage() . '</error>');
138
                    }
139
                } else {
140
                    $output->writeln('Definition error: <error>The workflow definition file can not be found any more</error>');
141
                }
142
            }
143
144
            $output->writeln('');
145
            return 0;
146
        }
147
148
        // ask user for confirmation to make changes
149
        if ($input->isInteractive() && !$input->getOption('no-interaction')) {
150
            $dialog = $this->getHelperSet()->get('dialog');
151
            if (!$dialog->askConfirmation(
0 ignored issues
show
The method askConfirmation() does not exist on Symfony\Component\Console\Helper\Helper. It seems like you code against a sub-type of Symfony\Component\Console\Helper\Helper such as Symfony\Component\Console\Helper\DialogHelper. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

151
            if (!$dialog->/** @scrutinizer ignore-call */ askConfirmation(
Loading history...
152
                $output,
153
                '<question>Careful, the database will be modified. Do you want to continue Y/N ?</question>',
154
                false
155
            )
156
            ) {
157
                $output->writeln('<error>Workflow change cancelled!</error>');
158
                return 0;
159
            }
160
        }
161
162
        if ($input->getOption('delete') || $input->getOption('fail')) {
163
            $workflow = $workflowService->getWorkflow($workflowNameOrPath);
164
            if ($workflow == null) {
165
                throw new \InvalidArgumentException(sprintf('The workflow "%s" does not exist in the database table.', $workflowNameOrPath));
166
            }
167
168
            if ($input->getOption('delete')) {
169
                $workflowService->deleteWorkflow($workflow);
0 ignored issues
show
The method deleteWorkflow() does not exist on Kaliop\eZWorkflowEngineB...e\WorkflowServiceFacade. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

169
                $workflowService->/** @scrutinizer ignore-call */ 
170
                                  deleteWorkflow($workflow);
Loading history...
170
            } else {
171
                $errorMessage = 'Manually failed on ' . date("Y-m-d H:i:s");
172
                if ($workflow->executionError != '') {
173
                    $errorMessage .= ". Previous notes: " . $workflow->executionError;
174
                }
175
                $workflowService->failWorkflow($workflow, $errorMessage);
0 ignored issues
show
The method failWorkflow() does not exist on Kaliop\eZWorkflowEngineB...e\WorkflowServiceFacade. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

175
                $workflowService->/** @scrutinizer ignore-call */ 
176
                                  failWorkflow($workflow, $errorMessage);
Loading history...
176
            }
177
178
            return 0;
179
        }
180
    }
181
}
182