Completed
Push — master ( f3a4fe...8c8190 )
by Christian
07:45
created

AbstractCronCommand::getCronTimestamp()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
3
namespace N98\Magento\Command\System\Cron;
4
5
use N98\Magento\Command\AbstractMagentoCommand;
6
use Symfony\Component\Console\Helper\DialogHelper;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
10
abstract class AbstractCronCommand extends AbstractMagentoCommand
11
{
12
    /**
13
     * @var \Magento\Framework\App\State
14
     */
15
    protected $state;
16
17
    /**
18
     * @var \Magento\Cron\Model\ConfigInterface
19
     */
20
    protected $cronConfig;
21
22
    /**
23
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
24
     */
25
    protected $scopeConfig;
26
27
    /**
28
     * @var \Magento\Cron\Model\ResourceModel\Schedule\Collection
29
     */
30
    protected $cronScheduleCollection;
31
32
    /**
33
     * @var \Magento\Framework\App\ProductMetadataInterface $productMetadata
34
     */
35
    private $productMetadata;
36
37
    /**
38
     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
39
     */
40
    protected $timezone;
41
42
    /**
43
     * @var \Magento\Framework\Stdlib\DateTime\DateTime
44
     */
45
    private $dateTime;
46
47
    /**
48
     * @param \Magento\Framework\App\State $state
49
     * @param \Magento\Cron\Model\ConfigInterface $cronConfig
50
     * @param \Magento\Framework\App\ProductMetadataInterface $productMetadata
51
     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone
52
     * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
53
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
54
     * @param \Magento\Cron\Model\ResourceModel\Schedule\Collection $cronScheduleCollection
55
     */
56
    public function inject(
57
        \Magento\Framework\App\State $state,
58
        \Magento\Cron\Model\ConfigInterface $cronConfig,
59
        \Magento\Framework\App\ProductMetadataInterface $productMetadata,
60
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone,
61
        \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
62
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
63
        \Magento\Cron\Model\ResourceModel\Schedule\Collection $cronScheduleCollection
64
    ) {
65
        $this->state = $state;
66
        $this->cronConfig = $cronConfig;
67
        $this->scopeConfig = $scopeConfig;
68
        $this->cronScheduleCollection = $cronScheduleCollection;
69
        $this->productMetadata = $productMetadata;
70
        $this->timezone = $timezone;
71
        $this->dateTime = $dateTime;
72
    }
73
74
    /**
75
     * @return array
76
     */
77
    protected function getJobs()
78
    {
79
        $table = array();
80
81
        $jobs = $this->cronConfig->getJobs();
82
83
        foreach ($jobs as $jobGroupCode => $jobGroup) {
84
            foreach ($jobGroup as $job) {
85
                $row = [
86
                    'Job'   => isset($job['name']) ? $job['name'] : null,
87
                    'Group' => $jobGroupCode,
88
                ];
89
90
                $row = $row + $this->getSchedule($job);
91
92
                $table[] = $row;
93
            }
94
        }
95
96
        usort($table, function ($a, $b) {
97
            return strcmp($a['Job'], $b['Job']);
98
        });
99
100
        return $table;
101
    }
102
103
    /**
104
     * @param string $jobCode
105
     * @return array
106
     */
107
    protected function getJobConfig($jobCode)
108
    {
109
        foreach ($this->cronConfig->getJobs() as $jobGroup) {
110
            foreach ($jobGroup as $job) {
111
                if ($job['name'] == $jobCode) {
112
                    return $job;
113
                }
114
            }
115
        }
116
117
        return [];
118
    }
119
120
    /**
121
     * @param array $job
122
     * @return array
123
     */
124
    protected function getSchedule(array $job)
125
    {
126
        if (isset($job['schedule'])) {
127
            $expr = $job['schedule'];
128
            if ($expr == 'always') {
129
                return ['m' => '*', 'h' => '*', 'D' => '*', 'M' => '*', 'WD' => '*'];
130
            }
131
132
            $schedule = $this->getObjectManager()->create('Magento\Cron\Model\Schedule');
133
            $schedule->setCronExpr($expr);
134
            $array = $schedule->getCronExprArr();
135
136
            return [
137
                'm'  => $array[0],
138
                'h'  => $array[1],
139
                'D'  => $array[2],
140
                'M'  => $array[3],
141
                'WD' => $array[4],
142
            ];
143
        }
144
145
        return ['m' => '-', 'h' => '-', 'D' => '-', 'M' => '-', 'WD' => '-'];
146
    }
147
148
    /**
149
     * @param InputInterface $input
150
     * @param OutputInterface $output
151
     * @param array $jobs
152
     * @return string
153
     * @throws \InvalidArgumentException
154
     * @throws \Exception
155
     */
156
    protected function askJobCode(InputInterface $input, OutputInterface $output, $jobs)
0 ignored issues
show
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
157
    {
158
        $question = array();
159 View Code Duplication
        foreach ($jobs as $key => $job) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160
            $question[] = '<comment>[' . ($key + 1) . ']</comment> ' . $job['Job'] . PHP_EOL;
161
        }
162
        $question[] = '<question>Please select job: </question>' . PHP_EOL;
163
164
        /** @var $dialog DialogHelper */
165
        $dialog = $this->getHelper('dialog');
166
        $jobCode = $dialog->askAndValidate(
167
            $output,
168
            $question,
169
            function ($typeInput) use ($jobs) {
170
                if (!isset($jobs[$typeInput - 1])) {
171
                    throw new \InvalidArgumentException('Invalid job');
172
                }
173
                return $jobs[$typeInput - 1]['Job'];
174
            }
175
        );
176
177
        return $jobCode;
178
    }
179
180
    /**
181
     * @param InputInterface $input
182
     * @param OutputInterface $output
183
     * @return array
184
     */
185
    protected function getJobForExecuteMethod(InputInterface $input, OutputInterface $output)
186
    {
187
        $jobCode = $input->getArgument('job');
188
        $jobs = $this->getJobs();
189
190
        if (!$jobCode) {
191
            $this->writeSection($output, 'Cronjob');
192
            $jobCode = $this->askJobCode($input, $output, $jobs);
193
        }
194
195
        $jobConfig = $this->getJobConfig($jobCode);
196
197
        if (empty($jobCode) || !isset($jobConfig['instance'])) {
198
            throw new \InvalidArgumentException('No job config found!');
199
        }
200
201
        $model = $this->getObjectManager()->get($jobConfig['instance']);
202
203
        if (!$model || !is_callable(array($model, $jobConfig['method']))) {
204
            throw new \RuntimeException(
205
                sprintf(
206
                    'Invalid callback: %s::%s does not exist',
207
                    $jobConfig['instance'],
208
                    $jobConfig['method']
209
                )
210
            );
211
        }
212
213
        return array($jobCode, $jobConfig, $model);
214
    }
215
216
    /**
217
     * Get timestamp used for time related database fields in the cron tables
218
     *
219
     * Note: The timestamp used will change from Magento 2.1.7 to 2.2.0 and
220
     *       these changes are branched by Magento version in this method.
221
     *
222
     * @return int
223
     */
224
    protected function getCronTimestamp()
225
    {
226
        /* @var $version string e.g. "2.1.7" */
227
        $version = $this->productMetadata->getVersion();
228
229
        if (version_compare($version, "2.2.0") >= 0) {
230
            return $this->dateTime->gmtTimestamp();
231
        }
232
233
        return $this->timezone->scopeTimeStamp();
234
    }
235
}
236