Completed
Push — develop ( bb0341...06bb72 )
by Tom
03:25
created

RunCommand::execute()   D

Complexity

Conditions 16
Paths 87

Size

Total Lines 85
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 85
rs 4.8736
c 0
b 0
f 0
cc 16
eloc 54
nc 87
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace N98\Magento\Command\System\Cron;
4
5
use Exception;
6
use Mage;
7
use Mage_Cron_Model_Schedule;
8
use RuntimeException;
9
use Symfony\Component\Console\Helper\DialogHelper;
10
use Symfony\Component\Console\Input\InputArgument;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Validator\Exception\InvalidArgumentException;
14
15
class RunCommand extends AbstractCronCommand
16
{
17
    const REGEX_RUN_MODEL = '#^([a-z0-9_]+/[a-z0-9_]+)::([a-z0-9_]+)$#i';
18
    /**
19
     * @var array
20
     */
21
    protected $infos;
22
23
    protected function configure()
24
    {
25
        $this
26
            ->setName('sys:cron:run')
27
            ->addArgument('job', InputArgument::OPTIONAL, 'Job code')
28
            ->setDescription('Runs a cronjob by job code');
29
        $help = <<<HELP
30
If no `job` argument is passed you can select a job from a list.
31
See it in action: http://www.youtube.com/watch?v=QkzkLgrfNaM
32
HELP;
33
        $this->setHelp($help);
34
    }
35
36
    /**
37
     * @param InputInterface $input
38
     * @param OutputInterface $output
39
     *
40
     * @return int|void
41
     */
42
    protected function execute(InputInterface $input, OutputInterface $output)
43
    {
44
        $this->detectMagento($output, true);
45
        if (!$this->initMagento()) {
46
            return;
47
        }
48
49
        $jobCode = $input->getArgument('job');
50
        if (!$jobCode) {
51
            $this->writeSection($output, 'Cronjob');
52
            $jobCode = $this->askJobCode($output, $this->getJobs());
53
        }
54
55
        $jobsRoot = Mage::getConfig()->getNode('crontab/jobs');
56
        $defaultJobsRoot = Mage::getConfig()->getNode('default/crontab/jobs');
57
58
        $jobConfig = $jobsRoot->{$jobCode};
59
        if (!$jobConfig || !$jobConfig->run) {
60
            $jobConfig = $defaultJobsRoot->{$jobCode};
61
            if (!$jobConfig || !$jobConfig->run) {
62
                throw new RuntimeException('No job config found!');
63
            }
64
        }
65
66
        $runConfig = $jobConfig->run;
67
68
        if ($runConfig->model) {
69
            if (!preg_match(self::REGEX_RUN_MODEL, (string) $runConfig->model, $run)) {
70
                throw new RuntimeException('Invalid model/method definition, expecting "model/class::method".');
71
            }
72
73
            list(, $runModel, $runMethod) = $run;
74
            $model = Mage::getModel($runModel);
75
            if (false === $model) {
76
                throw new RuntimeException(sprintf('Failed to create new "%s" model', $run[1]));
77
            }
78
            $callback = array($model, $runMethod);
79
            $callableName = sprintf("%s::%s", $runModel, $runMethod);
80
            if (!$model || !is_callable($callback, false, $callableName)) {
81
                throw new RuntimeException(sprintf('Invalid callback: %s', $callableName));
82
            }
83
84
            $output->write('<info>Run </info><comment>' . $callableName . '</comment> ');
85
86
            Mage::getConfig()->init()->loadEventObservers('crontab');
87
            Mage::app()->addEventArea('crontab');
88
89
            /* @var $schedule Mage_Cron_Model_Schedule */
90
            $schedule = Mage::getModel('cron/schedule');
91
            if (false === $schedule) {
92
                throw new RuntimeException('Failed to create new Mage_Cron_Model_Schedule model');
93
            }
94
95
            try {
96
                $strftime = strftime('%Y-%m-%d %H:%M:%S', time());
97
                $schedule
98
                    ->setJobCode($jobCode)
99
                    ->setStatus(Mage_Cron_Model_Schedule::STATUS_RUNNING)
100
                    ->setCreatedAt($strftime)
101
                    ->setExecutedAt($strftime)
102
                    ->save();
103
104
                call_user_func_array($callback, array($schedule));
105
106
                $schedule->setStatus(Mage_Cron_Model_Schedule::STATUS_SUCCESS);
107
            } catch (Exception $cronException) {
108
                $schedule->setStatus(Mage_Cron_Model_Schedule::STATUS_ERROR);
109
            }
110
111
            $schedule->setFinishedAt(strftime('%Y-%m-%d %H:%M:%S', time()))->save();
112
113
            if (isset($cronException)) {
114
                throw new RuntimeException(
115
                    sprintf('Cron-job "%s" threw exception %s', $jobCode, get_class($cronException)),
116
                    0,
117
                    $cronException
118
                );
119
            }
120
121
            $output->writeln('<info>done</info>');
122
        }
123
        if (empty($callback)) {
124
            Mage::throwException(Mage::helper('cron')->__('No callbacks found'));
125
        }
126
    }
127
128
    /**
129
     * @param OutputInterface $output
130
     * @param array $jobs array of array containing "job" keyed string entries of job-codes
131
     *
132
     * @return string         job-code
133
     * @throws InvalidArgumentException when user selects invalid job interactively
134
     */
135
    protected function askJobCode(OutputInterface $output, array $jobs)
136
    {
137
        $index = 0;
138
        $keyMap = array_keys($jobs);
139
        $question = array();
140
141
        foreach ($jobs as $key => $job) {
142
            $question[] = '<comment>[' . ($index++) . ']</comment> ' . $job['Job'] . PHP_EOL;
143
        }
144
        $question[] = '<question>Please select job: </question>' . PHP_EOL;
145
146
        /** @var $dialogHelper DialogHelper */
147
        $dialogHelper = $this->getHelper('dialog');
148
        $jobCode = $dialogHelper->askAndValidate(
149
            $output,
150
            $question,
151
            function ($typeInput) use ($keyMap, $jobs) {
152
                $key = $keyMap[$typeInput];
153
                if (!isset($jobs[$key])) {
154
                    throw new InvalidArgumentException('Invalid job');
155
                }
156
157
                return $jobs[$key]['Job'];
158
            }
159
        );
160
161
        return $jobCode;
162
    }
163
}
164