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

Namespaces

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

Classes

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