AloFramework documentation
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo

Namespaces

  • Alo
    • Cache
    • CLI
    • Controller
    • Db
    • Exception
    • FileSystem
    • Session
    • Statics
    • Validators
    • Windows
  • Controller
  • None
  • PHP

Classes

  • Cron
  • Curl
  • Email
  • Handler
  • Locale
  • Profiler
  • SFTP
  1 <?php
  2 
  3     namespace Alo;
  4 
  5     use Alo\Exception\CronException as CE;
  6     use Alo\Exception\OSException as OS;
  7     use Log;
  8 
  9     if (!defined('GEN_START')) {
 10         http_response_code(404);
 11     } else {
 12 
 13         /**
 14          * The crontab editor class. You must call the commit() method to save your changes.
 15          *
 16          * @author Art <a.molcanovas@gmail.com>
 17          */
 18         class Cron {
 19 
 20             /**
 21              * Defines the day of the week as Sunday
 22              *
 23              * @var int
 24              */
 25             const WEEKDAY_SUN = 0;
 26             /**
 27              * Defines the day of the week as Monday
 28              *
 29              * @var int
 30              */
 31             const WEEKDAY_MON = 1;
 32             /**
 33              * Defines the day of the week as Tuesday
 34              *
 35              * @var int
 36              */
 37             const WEEKDAY_TUE = 2;
 38             /**
 39              * Defines the day of the week as Wednesday
 40              *
 41              * @var int
 42              */
 43             const WEEKDAY_WED = 3;
 44             /**
 45              * Defines the day of the week as Thursday
 46              *
 47              * @var int
 48              */
 49             const WEEKDAY_THU = 4;
 50             /**
 51              * Defines the day of the week as Friday
 52              *
 53              * @var int
 54              */
 55             const WEEKDAY_FRI = 5;
 56             /**
 57              * Defines the day of the week as Saturday
 58              *
 59              * @var int
 60              */
 61             const WEEKDAY_SAT = 6;
 62             /**
 63              * A pre-setting to run the cronjob yearly at 1 Jan, 00:00
 64              *
 65              * @var string
 66              */
 67             const CONST_YEARLY = '0 0 1 1 *';
 68             /**
 69              * A pre-setting to run the cronjob monthly at 00:00
 70              *
 71              * @var string
 72              */
 73             const CONST_MONTHLY = '0 0 1 * *';
 74             /**
 75              * A pre-setting to run the cronjob weekly on Sunday, 00:00
 76              *
 77              * @var string
 78              */
 79             const CONST_WEEKLY = '0 0 * * 0';
 80             /**
 81              * A pre-setting to run the cronjob daily at 00:00
 82              *
 83              * @var string
 84              */
 85             const CONST_DAILY = '0 0 * * *';
 86             /**
 87              * A pre-setting to run the cronjob hourly at 00 minutes
 88              *
 89              * @var string
 90              */
 91             const CONST_HOURLY = '0 * * * *';
 92             /**
 93              * A pre-setting to run the cronjob on server startup
 94              *
 95              * @var string
 96              */
 97             const CONST_REBOOT = '@reboot';
 98             /**
 99              * Defines the month as January
100              *
101              * @var int
102              */
103             const MONTH_JAN = 1;
104             /**
105              * Defines the month as February
106              *
107              * @var int
108              */
109             const MONTH_FEB = 2;
110             /**
111              * Defines the month as March
112              *
113              * @var int
114              */
115             const MONTH_MAR = 3;
116             /**
117              * Defines the month as April
118              *
119              * @var int
120              */
121             const MONTH_APR = 4;
122             /**
123              * Defines the month as May
124              *
125              * @var int
126              */
127             const MONTH_MAY = 5;
128             /**
129              * Defines the month as June
130              *
131              * @var int
132              */
133             const MONTH_JUN = 6;
134             /**
135              * Defines the month as July
136              *
137              * @var int
138              */
139             const MONTH_JUL = 7;
140             /**
141              * Defines the month as August
142              *
143              * @var int
144              */
145             const MONTH_AUG = 8;
146             /**
147              * Defines the month as September
148              *
149              * @var int
150              */
151             const MONTH_SEP = 9;
152             /**
153              * Defines the month as October
154              *
155              * @var int
156              */
157             const MONTH_OCT = 10;
158             /**
159              * Defines the month as November
160              *
161              * @var int
162              */
163             const MONTH_NOV = 11;
164             /**
165              * Defines the month as December
166              *
167              * @var int
168              */
169             const MONTH_DEC = 12;
170             /**
171              * Static reference to the last instance of the class
172              *
173              * @var Cron
174              */
175             static $this;
176             /**
177              * Array of valid CRON constants
178              *
179              * @var array
180              */
181             protected static $validConstants = ['@yearly',
182                                                 '@annually',
183                                                 '@monthly',
184                                                 '@weekly',
185                                                 '@daily',
186                                                 '@hourly',
187                                                 '@reboot'];
188 
189             /**
190              * The current crontab data
191              *
192              * @var array
193              */
194             protected $crontab;
195 
196             /**
197              * Whether changes should be autocommited automatically
198              *
199              * @var bool
200              */
201             protected $autocommit;
202 
203             /**
204              * Instantiates the crontab handler
205              *
206              * @author Art <a.molcanovas@gmail.com>
207              * @throws OS When the machine is running Windows
208              */
209             function __construct() {
210                 if (\serverIsWindows()) {
211                     throw new OS('Windows does not support cron!', OS::E_UNSUPPORTED);
212                 } else {
213                     $this->autocommit = false;
214                     $this->reloadCrontab();
215                 }
216                 self::$this = &$this;
217             }
218 
219             /**
220              * (re)loads the cron job array
221              *
222              * @author Art <a.molcanovas@gmail.com>
223              * @return Cron
224              */
225             function reloadCrontab() {
226                 $this->crontab = shell_exec('crontab -l');
227 
228                 if ($this->crontab) {
229                     $this->crontab = trim($this->crontab);
230                     $this->crontab = explode("\n", $this->crontab);
231 
232                     //Make sure it's really empty
233                     $lastIndex = count($this->crontab) - 1;
234 
235                     while ($lastIndex >= 0 && !$this->crontab[$lastIndex]) {
236                         unset($this->crontab[$lastIndex]);
237                         $lastIndex--;
238                     }
239                 } else {
240                     $this->crontab = [];
241                 }
242 
243                 Log::debug('(Re)loaded crontab contents');
244 
245                 return $this;
246             }
247 
248             /**
249              * Instantiates the crontab handler
250              *
251              * @author Art <a.molcanovas@gmail.com>
252              * @throws OS When the machine is running Windows
253              * @return Cron
254              */
255             static function cron() {
256                 return new Cron();
257             }
258 
259             /**
260              * Edits the cron job at index $index. Can be substituded with the full
261              * CRON expression (schedule + command) to perform a search -
262              * use with caution!
263              *
264              * @author Art <a.molcanovas@gmail.com>
265              *
266              * @param int        $index   The job index in the crontab array
267              * @param string     $command The command to run
268              * @param int|string $minute  The minute parameter
269              * @param int|string $hour    The hour parameter
270              * @param int|string $day     The day of the month parameter
271              * @param int|string $month   The month parameter
272              * @param int|string $weekday The day of the week parameter
273              *
274              * @throws CE When the minute expression is invalid
275              * @throws CE When the parameters are invalid
276              * @throws CE When one or more parameters are non-scalar
277              * @return Cron
278              */
279             function editCronJob($index, $command, $minute = '*', $hour = '*', $day = '*', $month = '*',
280                                  $weekday = '*') {
281                 if (!is_numeric($index)) {
282                     $search = array_search($index, $this->crontab);
283 
284                     if ($search !== false) {
285                         $index = $search;
286                     }
287                 }
288 
289                 return $this->editCrontab($index, $command, $minute, $hour, $day, $month, $weekday);
290             }
291 
292             /**
293              * Performs modifiation on the crontab file
294              *
295              * @author Art <a.molcanovas@gmail.com>
296              *
297              * @param int        $index   The job index in the crontab array
298              * @param string     $command The command to run
299              * @param int|string $minute  The minute parameter
300              * @param int|string $hour    The hour parameter
301              * @param int|string $day     The day of the month parameter
302              * @param int|string $month   The month parameter
303              * @param int|string $weekday The day of the week parameter
304              *
305              * @return Cron
306              * @throws CE When the minute expression is invalid
307              * @throws CE When the parameters are invalid
308              * @throws CE When one or more parameters are non-scalar
309              */
310             protected function editCrontab($index, $command, $minute = '*', $hour = '*', $day = '*', $month = '*',
311                                            $weekday = '*') {
312 
313                 if (!is_scalar($command) || !is_scalar($minute) || !is_scalar($hour) || !is_scalar($day) ||
314                     !is_scalar($month) || !is_scalar($weekday)
315                 ) {
316                     throw new CE('All cron attributes must be scalar!', CE::E_ARGS_NONSCALAR);
317                 } elseif (!self::formatOK($minute, $hour, $day, $month, $weekday)) {
318                     throw new CE('Invalid schedule parameters: ' . json_encode(['minute/constant' => $minute,
319                                                                                 'hour'            => $hour,
320                                                                                 'day'             => $day,
321                                                                                 'month'           => $month,
322                                                                                 'weekday'         => $weekday,
323                                                                                 'cmd'             => $command,
324                                                                                 'index'           => $index]),
325                                  CE::E_INVALID_EXPR);
326                 } else {
327                     $add = $minute . ' ' . $hour . ' ' . $day . ' ' . $month . ' ' . $weekday . ' ' . $command;
328 
329                     if ($index === null) {
330                         $this->crontab[] = $add;
331                         Log::debug('Appended crontab with ' . $add);
332                     } else {
333                         $this->crontab[$index] = $add;
334                         Log::debug('Edited crontab index ' . $index . ' with ' . $add);
335                     }
336 
337                     if ($this->autocommit) {
338                         $this->commit();
339                     }
340                 }
341 
342                 return $this;
343             }
344 
345             /**
346              * Checks whether all the fields are formatted properly
347              *
348              * @author Art <a.molcanovas@gmail.com>
349              *
350              * @param int|string $min     The minute parameter
351              * @param int|string $hour    The hour parameter
352              * @param int|string $day     The day of the month parameter
353              * @param int|string $month   The month parameter
354              * @param int|string $weekday The day of the week parameter
355              *
356              * @return boolean
357              */
358             protected static function formatOK($min, $hour, $day, $month, $weekday) {
359                 $patMinHMth = '/^(\*|[0-9]{1,2}|\*\/[0-9]{1,2}|[0-9,]+|[0-9\-]+)$/';
360                 $patDay     = '/^(\*|[0-9]{1,2}|[0-9]{1,2}(L|W)|\*\/[0-9]{1,2}|[0-9,]+|[0-9\-]+)$/';
361                 $patWeekday = '/^(\*|[0-9]{1,2}|[0-9]{1,2}L|\*\/[0-9]{1,2}|[0-9,]+|[0-9\-]+)$/';
362 
363                 return preg_match($patMinHMth, $min) && preg_match($patMinHMth, $hour) &&
364                        preg_match($patMinHMth, $month) && preg_match($patDay, $day) &&
365                        preg_match($patWeekday, $weekday);
366             }
367 
368             /**
369              * Saves any changes made
370              *
371              * @author Art <a.molcanovas@gmail.com>
372              * @return bool
373              */
374             function commit() {
375                 $commit = trim(implode("\n", $this->crontab)) . "\n";
376                 $path   = DIR_TMP . 'crontab.txt';
377                 file_put_contents($path, $commit);
378 
379                 if (file_exists($path)) {
380                     $exec = shell_exec('crontab "' . $path . '"');
381                     echo $exec;
382                     unlink($path);
383                     Log::debug('Crontab change output: ' . $exec);
384 
385                     return true;
386                 } else {
387                     trigger_error(Log::error('Failed to save crontab: temporary file could not be created.'),
388                                   E_USER_WARNING);
389                 }
390 
391                 return false;
392             }
393 
394             /**
395              * Appends the crontab file
396              *
397              * @author Art <a.molcanovas@gmail.com>
398              *
399              * @param string     $command     The command to run
400              * @param int|string $minuteConst The minute parameter
401              * @param int|string $hour        The hour parameter
402              * @param int|string $day         The day of the month parameter
403              * @param int|string $month       The month parameter
404              * @param int|string $weekday     The day of the week parameter
405              *
406              * @throws CE When the minute expression is invalid
407              * @throws CE When the parameters are invalid
408              * @throws CE When one or more parameters are non-scalar
409              * @return Cron
410              */
411             function appendCrontab($command, $minuteConst = '*', $hour = '*', $day = '*', $month = '*',
412                                    $weekday = '*') {
413                 return $this->editCrontab(null, $command, $minuteConst, $hour, $day, $month, $weekday);
414             }
415 
416             /**
417              * Removes the cron job @ index $index
418              *
419              * @author Art <a.molcanovas@gmail.com>
420              *
421              * @param int $index The cron job's index in the array
422              *
423              * @return Cron
424              */
425             function deleteJob($index) {
426                 unset($this->crontab[$index]);
427                 Log::debug('Deleted crontab entry @ index ' . $index);
428 
429                 if ($this->autocommit) {
430                     $this->commit();
431                 }
432 
433                 return $this;
434             }
435 
436             /**
437              * Clears the crontab
438              *
439              * @author Art <a.molcanovas@gmail.com>
440              * @return Cron
441              */
442             function clearCrontab() {
443                 $this->crontab = [];
444 
445                 if ($this->autocommit) {
446                     $this->commit();
447                 }
448 
449                 return $this;
450             }
451 
452             /**
453              * If no parameter is passed or the parameter isn't TRUE/FALSE, returns the current autocommit setting, otherwise
454              * sets it. Use with caution!
455              *
456              * @author Art <a.molcanovas@gmail.com>
457              *
458              * @param bool|null $set The desired setting if changing
459              *
460              * @return Cron|bool $this if not changing the autocommit value or the value otherwise
461              */
462             function autocommit($set = null) {
463                 if (is_bool($set)) {
464                     $this->autocommit = $set;
465 
466                     return $this;
467                 } else {
468                     return $this->autocommit;
469                 }
470             }
471 
472             /**
473              * Returns crontab entry at index $i
474              *
475              * @author Art <a.molcanovas@gmail.com>
476              *
477              * @param int $i The index
478              *
479              * @return null|string
480              */
481             function getAtIndex($i) {
482                 return \get($this->crontab[$i]);
483             }
484 
485             /**
486              * Returns the crontab array
487              *
488              * @author Art <a.molcanovas@gmail.com>
489              * @return array
490              */
491             function getCrontab() {
492                 return $this->crontab;
493             }
494 
495             /**
496              * Returns a string representation of the object data
497              *
498              * @author Art <a.molcanovas@gmail.com>
499              * @return string
500              */
501             function __toString() {
502                 return \debugLite($this);
503             }
504 
505         }
506     }
507 
AloFramework documentation API documentation generated byApiGen 2.8.0