Completed
Push — master ( 3825d8...4c8770 )
by Michael
06:10
created

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
#!/usr/bin/env php
2
<?php
3
4
if(php_sapi_name() != "cli")
5
	die("This is a cli script!");
6
7
if(!extension_loaded('pcntl'))
8
	die("This script needs the pcntl extension!");
9
10
$base = __DIR__;
11
require_once( "config.php" );
12
require_once( "init.php" );
13
14
interface cliCommand {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The type cliCommand has been defined more than once; this definition is ignored, only the first definition in cli.php (L65-81) is considered.

This check looks for classes that have been defined more than once.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
15
	/**
16
	 * @return string
17
	 */
18
	public function getDescription();
19
20
	/**
21
	 * @return string
22
	 */
23
	public function getAvailMethods();
24
25
	/**
26
	 * @return void
27
	 */
28
	public function execute($parameters, $db);
29
}
30
31
$cronInfo = array();
32
33
$files = scandir("$base/cli");
34
foreach($files as $file)
35
{
36
	if(!preg_match("/^cli_(.+)\\.php$/", $file, $match))
37
		continue;
38
39
	$command = $match[1];
40
	$className = "cli_$command";
41
	require_once "$base/cli/$file";
42
43
	if(!is_subclass_of($className, "cliCommand"))
44
		continue;
45
46
	if(!method_exists($className, "getCronInfo"))
47
		continue;
48
49
	$class = new $className();
50
	$cronInfo[$command] = $class->getCronInfo();
51
	if(method_exists($className, "executable"))
52
		$cronInfo[$command]["executable"] = $class->executable();
53
54
	unset($class);
55
}
56
57
if(file_exists("$base/cron.overrides"))
58
{
59
	$overrides = file_get_contents("$base/cron.overrides");
60
	$overrides = json_decode($overrides, true);
61
62
	foreach($overrides as $command => $info)
63
	{
64
		foreach($info as $f)
65
			if($f != "disabled")
66
				$cronInfo[$command] = $info;
67
			else
68
				unset($cronInfo[$command]);
69
	}
70
}
71
72
foreach($cronInfo as $command => $info)
73
{
74
	if(isset($info["executable"]))
75
	{
76
		$executable = $info["executable"];
77
		unset($info["executable"]);
78
	}
79
	else
80
		$executable = "php";
81
82
	foreach($info as $interval => $arguments)
83
		runCron($command, $interval, $arguments, $executable);
84
}
85
86
function runCron($command, $interval, $args, $executable)
87
{
88
	global $base;
89
90
	$curTime = time();
91
92
	if(is_array($args))
93
		array_unshift($args, $command);
94
	else if($args != "")
95
		$args = explode(" ", "$command $args");
96
	else
97
		$args = array($command);
98
99
	$cronName = implode(".", $args);
100
	$locker = "lastCronRun.$cronName";
101
	$lastRun = (int)Storage::retrieve($locker, 0);
102
	$dateFormat = "D M j G:i:s T Y";
103
104
	if($curTime - $lastRun < $interval)
105
		return;
106
107
	global $debug;
108
	if ($debug)
109
		Log::log("Cron $cronName running at ".date($dateFormat, $curTime));
110
111
	Storage::store($locker, $curTime);
112
113
	$pid = pcntl_fork();
114
	if($pid < 0)
115
	{
116
		Storage::store($locker, $lastRun);
117
		return;
118
	}
119
120
	if($pid != 0)
121
		return;
122
123
	putenv("SILENT_CLI=1");
124
	pcntl_exec("$base/cliLock.sh", $args, array("EXECUTABLE" => $executable));
125
	// Sleep for a second before starting the next tast..
126
	sleep(1);
127
	Storage::store($locker, $lastRun);
128
	die("Executing $command failed!");
129
}
130