1<?php
2
3require_once dirname(__FILE__).'/accesscheck.php';
4
5/*
6 *
7 * page to handle any cron-related activity. Instead of having multiple cron entries, this
8 * one page should be called to do the tasks. It should be called as often as possible, eg once every 5 minutes
9 * or even once a minute.
10 *
11 * For now, the configuration is manually, there is no UI for it yet. Plugins can register their own cron activities.
12 * TODO, work with eg https://github.com/mtdowling/cron-expression
13 *
14 */
15
16if (!$GLOBALS['commandline']) {
17    echo 'This page can only be called from the commandline';
18
19    return;
20}
21$cronJobs = array(
22
23    // at a later stage, these should be added
24    // for now, that involves conflicts, as they all use similar function names in the files. (eg output and finish)
25    // also page locking needs changing, as it's the same page (cron) for all of them
26    // so, for now, we only handle plugin Cron Jobs
27
28    //array(
29    //    'plugin' => '',
30    //    'page' => 'processqueue',
31    //    'frequency'  => 1,    // once a minute
32    //),
33    //array(
34    //'plugin' => '',
35    //'page' => 'processbounces',
36    //'frequency' => 1440, // once a day
37    //),
38);
39
40foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
41    $pluginJobs = $plugin->cronJobs();
42    // cl_output($pluginname.' has '.sizeof($pluginJobs).' jobs');
43    foreach ($pluginJobs as $job) {
44        $cronJobs[] = array(
45            'plugin'    => $pluginname,
46            'page'      => $job['page'],
47            'frequency' => $job['frequency'],
48            //# @@ TODO extend it for eg a method to call on the plugin
49            //'method' => 'method to call';
50        );
51    }
52}
53
54if (!count($cronJobs)) {
55    cl_output(s('Nothing to do'));
56    exit;
57}
58
59$maxNextRun = 0;
60$now = time();
61foreach ($cronJobs as $cronJob) {
62    $cronID = $cronJob['plugin'].'|'.$cronJob['page'];
63    $lastrun = getConfig(md5($cronID));
64    if (empty($lastrun) || ($now - $lastrun > $cronJob['frequency'] * 60)) {
65        cl_output('Need to run '.$cronJob['plugin'].' - '.$cronJob['page']);
66        $cronJob['page'] = basename($cronJob['page'], '.php');
67        $cmd_result = '';
68        if (isset($GLOBALS['plugins'][$cronJob['plugin']]) && is_file($GLOBALS['plugins'][$cronJob['plugin']]->coderoot.$cronJob['page'].'.php')) {
69            cl_output('running php '.$argv[0].' -c '.$GLOBALS['configfile'].' -m '.$cronJob['plugin'].' -p '.$cronJob['page']);
70            exec('php '.$argv[0].' -c '.$GLOBALS['configfile'].' -m '.$cronJob['plugin'].' -p '.$cronJob['page'],
71                $cmd_result);
72        } elseif (empty($cronJob['plugin']) && is_file(__DIR__.'/'.$cronJob['page'].'.php')) {
73            cl_output('running php '.$argv[0].' -c '.$GLOBALS['configfile'].' -p '.$cronJob['page']);
74            exec('php '.$argv[0].' -c '.$GLOBALS['configfile'].' -p '.$cronJob['page'], $cmd_result);
75        }
76        SaveConfig(md5($cronID), time(), 0);
77    } else {
78        $nextRun = ($lastrun + $cronJob['frequency'] * 60) - $now;
79        if ($nextRun > $maxNextRun) {
80            $maxNextRun = $nextRun;
81        }
82        if (VERBOSE) {
83            cl_output('Will run '.$cronJob['plugin'].' - '.$cronJob['page'].' in'.secs2time($nextRun));
84        }
85    }
86}
87//# tell how soon we need to run again, so that the calling system can relax a bit
88if ($maxNextRun > 0) {
89    cl_output('DELAYUNTIL='.(int) ($now + $maxNextRun));
90}
91#var_dump($cronJobs);
92