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

Namespaces

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