Completed
Push — master ( 437106...78f9b5 )
by Andreas
31:22
created

cron::execute()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
eloc 15
nc 4
nop 2
dl 0
loc 27
ccs 12
cts 15
cp 0.8
crap 5.2
rs 9.4555
c 2
b 0
f 0
1
<?php
2
/**
3
 * @package midcom.console
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
namespace midcom\console\command;
10
11
use Symfony\Component\Console\Command\Command;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Output\OutputInterface;
14
use midcom;
15
use midcom_error;
16
use midcom_services_cron;
17
use Symfony\Component\Console\Input\InputArgument;
18
use Symfony\Component\Console\Input\InputOption;
19
20
/**
21
 * Cron command
22
 *
23
 * When executed, it checks all component manifests for cron jobs and runs them sequentially.
24
 * The components are processed in the order they are returned by the component loader, the
25
 * jobs are run in the order they are listed in the manifest.
26
 *
27
 * <b>Launching MidCOM Cron from a System Cron</b>
28
 *
29
 * Add something like this to your crontab:
30
 *
31
 * <pre>
32
 * * * * * *  www-data {PROJECT PATH}vendor/bin/midcom --servername=example.com midcom:cron minute
33
 * 1 * * * *  www-data {PROJECT PATH}vendor/bin/midcom --servername=example.com midcom:cron hour
34
 * 1 1 * * *  www-data {PROJECT PATH}vendor/bin/midcom --servername=example.com midcom:cron day
35
 * </pre>
36
 *
37
 * Make sure to pass the correct hostname, this is used e.g. when generating links in mails sent by cron jobs.
38
 * In case you're running more than one site on the same server, this is also needed to get the same cache
39
 * prefix as the website the job belongs to.
40
 *
41
 * Also take care to run the cron command with the same user the website is running, otherwise RCS entries or
42
 * attachments generated by cron jobs could end up unreadable.
43
 *
44
 * @see midcom_services_cron
45
 * @package midcom.console
46
 */
47
class cron extends Command
48
{
49 1
    protected function configure()
50
    {
51 1
        $this->setName('midcom:cron')
52 1
            ->setAliases(['cron'])
53 1
            ->setDescription('Checks all component manifests for cron jobs and runs them sequentially')
54 1
            ->addArgument('type', InputArgument::OPTIONAL, 'Recurrence (minute, hour, or day)', 'minute')
55 1
            ->addOption('job', 'j', InputOption::VALUE_REQUIRED, 'Run only this job');
56 1
    }
57
58 1
    protected function execute(InputInterface $input, OutputInterface $output) : int
59
    {
60 1
        if (!midcom::get()->auth->request_sudo('midcom.services.cron')) {
61
            throw new midcom_error('Failed to get sudo');
62
        }
63
64
        // compat for old-style calls (type=minute)
65 1
        $type = str_replace('type=', '', $input->getArgument('type'));
66
67 1
        $recurrence = 'MIDCOM_CRON_' . strtoupper($type);
68 1
        if (!defined($recurrence)) {
69
            throw new midcom_error('Unsupported type ' . $type);
70
        }
71
72 1
        if ($job = $input->getOption('job')) {
73
            $this->run_job($job, $output);
74
        } else {
75
            // Instantiate cron service and run
76 1
            $cron = new midcom_services_cron(constant($recurrence));
77 1
            $data = midcom::get()->componentloader->get_all_manifest_customdata('midcom.services.cron');
78
79 1
            foreach ($cron->load_jobs($data) as $job) {
80 1
                $this->run_job($job['handler'], $output);
81
            }
82
        }
83 1
        midcom::get()->auth->drop_sudo();
84 1
        return 0;
85
    }
86
87 1
    private function run_job(string $classname, OutputInterface $output)
88
    {
89 1
        $handler = new $classname;
90 1
        if ($handler->initialize($output)) {
91 1
            $output->writeln("Executing job <info>{$classname}</info>", OutputInterface::VERBOSITY_VERBOSE);
92 1
            $handler->execute();
93
        } else {
94
            $output->writeln("Skipping job <info>{$classname}</info>", OutputInterface::VERBOSITY_VERBOSE);
95
        }
96 1
    }
97
}
98