This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||
2 | /** |
||
3 | * Cron. |
||
4 | * |
||
5 | * @package App |
||
6 | * |
||
7 | * @copyright YetiForce S.A. |
||
8 | * @license YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com) |
||
9 | * @author Sławomir Kłos <[email protected]> |
||
10 | * @author Mariusz Krzaczkowski <[email protected]> |
||
11 | */ |
||
12 | |||
13 | namespace App; |
||
14 | |||
15 | /** |
||
16 | * Class to handle Cron operations. |
||
17 | */ |
||
18 | class Cron |
||
19 | { |
||
20 | /** |
||
21 | * @var int status disabled |
||
22 | */ |
||
23 | const STATUS_DISABLED = 0; |
||
24 | /** |
||
25 | * @var int status enabled |
||
26 | */ |
||
27 | const STATUS_ENABLED = 1; |
||
28 | /** |
||
29 | * @var int status running |
||
30 | */ |
||
31 | const STATUS_RUNNING = 2; |
||
32 | /** |
||
33 | * @var int status completed |
||
34 | */ |
||
35 | const STATUS_COMPLETED = 3; |
||
36 | |||
37 | /** |
||
38 | * Cron run start time in microtime. |
||
39 | * |
||
40 | * @var int|null Cron run start time in microtime |
||
41 | */ |
||
42 | public static $cronTimeStart; |
||
43 | |||
44 | /** |
||
45 | * Script run start time in microtime. |
||
46 | * |
||
47 | * @var int|null Script run start time in microtime |
||
48 | */ |
||
49 | public static $scriptTimeStart; |
||
50 | |||
51 | /** |
||
52 | * @var string Log files directory path |
||
53 | 1 | */ |
|
54 | public $logPath = ROOT_DIRECTORY . \DIRECTORY_SEPARATOR . 'cache' . \DIRECTORY_SEPARATOR . 'logs' . \DIRECTORY_SEPARATOR . 'cron' . \DIRECTORY_SEPARATOR; |
||
55 | 1 | ||
56 | 1 | /** |
|
57 | 1 | * @var bool|string Current log file name |
|
58 | 1 | */ |
|
59 | public $logFile = false; |
||
60 | |||
61 | /** |
||
62 | 1 | * @var bool Logging enabled flag |
|
63 | */ |
||
64 | public static $logActive = false; |
||
65 | 1 | ||
66 | /** @var bool Flag to keep log file after run finish */ |
||
67 | public static $keepLogFile = false; |
||
68 | |||
69 | 1 | /** @var bool Register enabled flag */ |
|
70 | 1 | public static $registerIsActive = true; |
|
71 | |||
72 | 1 | /** @var bool Watchdog enabled flag */ |
|
73 | 1 | public static $watchdogIsActive = true; |
|
74 | |||
75 | /** @var bool Shop enabled flag */ |
||
76 | public static $shopIsActive = true; |
||
77 | |||
78 | /** @var bool ConfReport enabled flag */ |
||
79 | public static $confReportIsActive = true; |
||
80 | |||
81 | /** @var int Max execution cron time. */ |
||
82 | 1 | private static $maxExecutionCronTime; |
|
83 | |||
84 | 1 | /** |
|
85 | * Init and configure object. |
||
86 | * |
||
87 | 1 | * @throws \App\Exceptions\CacheException |
|
88 | */ |
||
89 | public function __construct() |
||
90 | 1 | { |
|
91 | 1 | static::$scriptTimeStart = microtime(true); |
|
0 ignored issues
–
show
|
|||
92 | static::generateStatusFile(); |
||
93 | 1 | if (self::$watchdogIsActive) { |
|
94 | 1 | YetiForce\Watchdog::send(); |
|
95 | } |
||
96 | if (self::$registerIsActive) { |
||
97 | (new YetiForce\Register())->send(); |
||
98 | } |
||
99 | if (!(static::$logActive = Config::debug('DEBUG_CRON'))) { |
||
100 | return; |
||
101 | 1 | } |
|
102 | if (!is_dir($this->logPath) && !mkdir($this->logPath, 0777, true) && !is_dir($this->logPath)) { |
||
103 | 1 | static::$logActive = false; |
|
104 | Log::error("The mechanism of cron logs has been disabled !!!. No access to the log directory '{$this->logPath}'"); |
||
105 | } |
||
106 | if (!$this->logFile) { |
||
107 | $this->logFile = date('Ymd_Hi') . '.log'; |
||
108 | } |
||
109 | 1 | $this->log('File start', 'info', false); |
|
110 | } |
||
111 | 1 | ||
112 | 1 | /** |
|
113 | * Remove log file if no value information was stored. |
||
114 | */ |
||
115 | 1 | public function __destruct() |
|
116 | 1 | { |
|
117 | if (!static::$keepLogFile) { |
||
118 | if (!static::$logActive) { |
||
119 | return; |
||
120 | } |
||
121 | 1 | if (file_exists($this->logPath . $this->logFile)) { |
|
122 | unlink($this->logPath . $this->logFile); |
||
123 | } |
||
124 | } else { |
||
125 | $this->log('------------------------------------' . PHP_EOL . Log::getlastLogs(), 'info', false); |
||
126 | } |
||
127 | } |
||
128 | 1 | ||
129 | /** |
||
130 | 1 | * Add log message. |
|
131 | * |
||
132 | * @param string $message log information |
||
133 | * @param string $level information type [info, warning, error] |
||
134 | * @param bool $indent add three spaces at message begin |
||
135 | */ |
||
136 | public function log(string $message, string $level = 'info', bool $indent = true) |
||
137 | { |
||
138 | if (!static::$logActive) { |
||
139 | return; |
||
140 | } |
||
141 | if ('error' === $level) { |
||
142 | static::$keepLogFile = true; |
||
143 | } |
||
144 | if ($indent) { |
||
145 | $message = ' ' . $message; |
||
146 | } |
||
147 | file_put_contents($this->logPath . $this->logFile, date('Y-m-d H:i:s') . " [{$level}] - {$message}" . PHP_EOL, FILE_APPEND); |
||
148 | } |
||
149 | |||
150 | /** |
||
151 | * Gather and save information for YetiForce Status module. |
||
152 | * |
||
153 | * @return bool|int |
||
154 | */ |
||
155 | public static function generateStatusFile() |
||
156 | { |
||
157 | $all = []; |
||
158 | if (self::$confReportIsActive) { |
||
159 | $all = Utils\ConfReport::getAll(); |
||
160 | } |
||
161 | $all['last_start'] = time(); |
||
162 | return file_put_contents(ROOT_DIRECTORY . '/app_data/cron.php', '<?php return ' . Utils::varExport($all) . ';', LOCK_EX); |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * Calculate current object run time. |
||
167 | * |
||
168 | * @return float|null |
||
169 | */ |
||
170 | public function getCronExecutionTime() |
||
171 | { |
||
172 | return static::$cronTimeStart ? round(microtime(true) - static::$cronTimeStart, 2) : null; |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Update cron task status by name. |
||
177 | * |
||
178 | * @param int $status |
||
179 | * @param string $name |
||
180 | * |
||
181 | * @return void |
||
182 | */ |
||
183 | public static function updateStatus(int $status, string $name): void |
||
184 | { |
||
185 | switch ((int) $status) { |
||
186 | case self::STATUS_DISABLED: |
||
187 | case self::STATUS_ENABLED: |
||
188 | case self::STATUS_RUNNING: |
||
189 | break; |
||
190 | default: |
||
191 | throw new Exceptions\AppException('Invalid status'); |
||
192 | } |
||
193 | Db::getInstance()->createCommand()->update('vtiger_cron_task', ['status' => $status], ['name' => $name])->execute(); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * Get max execution cron time. |
||
198 | * |
||
199 | * @return int |
||
200 | */ |
||
201 | public static function getMaxExecutionTime(): int |
||
202 | { |
||
203 | if (isset(self::$maxExecutionCronTime)) { |
||
204 | return self::$maxExecutionCronTime; |
||
205 | } |
||
206 | $maxExecutionTime = (int) Config::main('maxExecutionCronTime'); |
||
207 | $iniMaxExecutionTime = (int) \ini_get('max_execution_time'); |
||
208 | if (0 !== $iniMaxExecutionTime && $iniMaxExecutionTime < $maxExecutionTime) { |
||
209 | $maxExecutionTime = $iniMaxExecutionTime; |
||
210 | } |
||
211 | return self::$maxExecutionCronTime = $maxExecutionTime; |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Check max execution cron time. |
||
216 | * |
||
217 | * @return bool |
||
218 | */ |
||
219 | public function checkCronTimeout(): bool |
||
220 | { |
||
221 | return time() >= (self::getMaxExecutionTime() + self::$cronTimeStart); |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Check if it is active function. |
||
226 | * |
||
227 | * @param string $className |
||
228 | * |
||
229 | * @return bool |
||
230 | */ |
||
231 | public static function checkActive(string $className): bool |
||
232 | { |
||
233 | return (new Db\Query()) |
||
234 | ->from('vtiger_cron_task') |
||
235 | ->where(['status' => [self::STATUS_ENABLED, self::STATUS_RUNNING], 'handler_class' => $className]) |
||
236 | ->exists(); |
||
237 | } |
||
238 | } |
||
239 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.