Passed
Push — master ( 8b8928...9eea0d )
by Andreas
11:05
created

cron   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Test Coverage

Coverage 86.21%

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 62
ccs 25
cts 29
cp 0.8621
rs 10
c 0
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A run_job() 0 8 2
A configure() 0 5 1
A __construct() 0 5 1
A execute() 0 27 5
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_services_auth;
15
use midcom_helper__componentloader;
16
use midcom_error;
17
use midcom_services_cron;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Input\InputOption;
20
use Symfony\Component\Console\Attribute\AsCommand;
21
22
/**
23
 * Cron command
24
 *
25
 * When executed, it checks all component manifests for cron jobs and runs them sequentially.
26
 * The components are processed in the order they are returned by the component loader, the
27
 * jobs are run in the order they are listed in the manifest.
28
 *
29
 * <b>Launching MidCOM Cron from a System Cron</b>
30
 *
31
 * Add something like this to your crontab:
32
 *
33
 * <pre>
34
 * * * * * *  www-data {PROJECT PATH}vendor/bin/midcom --servername=example.com midcom:cron minute
35
 * 1 * * * *  www-data {PROJECT PATH}vendor/bin/midcom --servername=example.com midcom:cron hour
36
 * 1 1 * * *  www-data {PROJECT PATH}vendor/bin/midcom --servername=example.com midcom:cron day
37
 * </pre>
38
 *
39
 * Make sure to pass the correct hostname, this is used e.g. when generating links in mails sent by cron jobs.
40
 * In case you're running more than one site on the same server, this is also needed to get the same cache
41
 * prefix as the website the job belongs to.
42
 *
43
 * Also take care to run the cron command with the same user the website is running, otherwise RCS entries or
44
 * attachments generated by cron jobs could end up unreadable.
45
 *
46
 * @see midcom_services_cron
47
 * @package midcom.console
48
 */
49
#[AsCommand(
50
    name: 'midcom:cron',
51
    description: 'Checks all component manifests for cron jobs and runs them sequentially',
52
    aliases: ['cron']
53
)]
54
class cron extends Command
55
{
56
    private midcom_services_auth $auth;
57
58
    private midcom_helper__componentloader $loader;
59
60 1
    public function __construct(midcom_services_auth $auth, midcom_helper__componentloader $loader)
61
    {
62 1
        $this->auth = $auth;
63 1
        $this->loader = $loader;
64 1
        parent::__construct();
65
    }
66
67 1
    protected function configure()
68
    {
69 1
        $this
70 1
            ->addArgument('type', InputArgument::OPTIONAL, 'Recurrence (minute, hour, or day)', 'minute')
71 1
            ->addOption('job', 'j', InputOption::VALUE_REQUIRED, 'Run only this job');
72
    }
73
74 1
    protected function execute(InputInterface $input, OutputInterface $output) : int
75
    {
76 1
        if (!$this->auth->request_sudo('midcom.services.cron')) {
77
            throw new midcom_error('Failed to get sudo');
78
        }
79
80
        // compat for old-style calls (type=minute)
81 1
        $type = str_replace('type=', '', $input->getArgument('type'));
82
83 1
        $recurrence = 'MIDCOM_CRON_' . strtoupper($type);
84 1
        if (!defined($recurrence)) {
85
            throw new midcom_error('Unsupported type ' . $type);
86
        }
87
88 1
        if ($job = $input->getOption('job')) {
89
            $this->run_job($job, $output);
90
        } else {
91
            // Instantiate cron service and run
92 1
            $cron = new midcom_services_cron(constant($recurrence));
93 1
            $data = $this->loader->get_all_manifest_customdata('midcom.services.cron');
94
95 1
            foreach ($cron->load_jobs($data) as $job) {
96 1
                $this->run_job($job['handler'], $output);
97
            }
98
        }
99 1
        $this->auth->drop_sudo();
100 1
        return Command::SUCCESS;
101
    }
102
103 1
    private function run_job(string $classname, OutputInterface $output)
104
    {
105 1
        $handler = new $classname;
106 1
        if ($handler->initialize($output)) {
107 1
            $output->writeln("Executing job <info>{$classname}</info>", OutputInterface::VERBOSITY_VERBOSE);
108 1
            $handler->execute();
109
        } else {
110
            $output->writeln("Skipping job <info>{$classname}</info>", OutputInterface::VERBOSITY_VERBOSE);
111
        }
112
    }
113
}
114