Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • PHP
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SIWECOS
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • CurlService
  • idna_convert
  • SearchResultModule
  • TinyMCE_Compressor

Exceptions

  • CurlException

Functions

  • buildCategoryArray
  • decDate
  • getJobFileName
  • getLastActialRunTime
  • getLastScheduledRunTime
  • logMessage
  • lTrimZeros
  • markLastRun
  • parseCronFile
  • parseElement
  • runJob
  • Overview
  • Package
  • Function
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: 
  3: /**
  4:  * *************************************************************************
  5: 
  6:   pseudo-cron v1.2.1.con // modified version for CONTENIDO
  7:   (c) 2003 Kai Blankenhorn
  8:   www.bitfolge.de/en
  9:   kaib@bitfolge.de
 10: 
 11:   This program is free software; you can redistribute it and/or
 12:   modify it under the terms of the GNU General Public License
 13:   as published by the Free Software Foundation; either version 2
 14:   of the License, or (at your option) any later version.
 15: 
 16:   This program is distributed in the hope that it will be useful,
 17:   but WITHOUT ANY WARRANTY; without even the implied warranty of
 18:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 19:   GNU General Public License for more details.
 20: 
 21:   You should have received a copy of the GNU General Public License
 22:   along with this program; if not, write to the Free Software
 23:   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 24: 
 25:  * ***************************************************************************
 26: 
 27:   Usually regular tasks like backup up the site's database are run using cron
 28:   jobs. With cron jobs, you can exactly plan when a certain command is to be
 29:   executed. But most homepage owners can't create cron jobs on their web
 30:   server - providers demand some extra money for that.
 31:   The only thing that's certain to happen quite regularly on a web page are
 32:   page requests. This is where pseudo-cron comes into play: With every page
 33:   request it checks if any cron jobs should have been run since the previous
 34:   request. If there are, they are run and logged.
 35: 
 36:   Pseudo-cron uses a syntax very much like the Unix cron's one. For an
 37:   overview of the syntax used, see a page of the UNIXGEEKS. The syntax
 38:   pseudo-cron uses is different from the one described on that page in
 39:   the following points:
 40: 
 41:   -  there is no user column
 42:   -  the executed command has to be an include()able file (which may contain further PHP code)
 43: 
 44: 
 45:   All job definitions are made in a text file on the server with a
 46:   user-definable name. A valid command line in this file is, for example:
 47: 
 48:  *   2   1,15   *   *   samplejob.inc.php
 49: 
 50:   This runs samplejob.inc.php at 2am on the 1st and 15th of each month.
 51: 
 52: 
 53:   Features:
 54:   -  runs any PHP script
 55:   -  periodical or time-controlled script execution
 56:   -  logs all executed jobs
 57:   -  can be run from an IMG tag in an HTML page
 58:   -  follow Unix cron syntax for crontabs
 59: 
 60: 
 61:   Usage:
 62:   -  Modify the variables in the config section below to match your server.
 63:   -  Write a PHP script that does the job you want to be run regularly. Be
 64:   sure that any paths in it are relative to the script that will run
 65:   pseudo-cron in the end.
 66:   -  Set up your crontab file with your script
 67:   -  Wait for the next scheduled run :)
 68: 
 69: 
 70:   Note:
 71:   You can log messages to pseudo-cron's log file by calling
 72:   logMessage("log a message", $PC_writeDir, $PC_useLog, $PC_debug);
 73: 
 74: 
 75:   Changelog:
 76: 
 77:   v1.2.1.con   11-28-03
 78:   changed: removed all global variables
 79:   changed: renamed intern variables
 80:   changed: intern function calls
 81:   changed: extended debug information
 82:   modified by horwath@opensa.org
 83: 
 84:   v1.2.1   02-03-03
 85:   fixed:    jobs may be run too often under certain conditions
 86:   added:    global debug switch
 87:   changed: typo in imagecron.php which prevented it from working
 88: 
 89: 
 90:   v1.2   01-31-03
 91:   added:   more documentation
 92:   changed: log file should now be easier to use
 93:   changed: log file name
 94: 
 95: 
 96:   v1.1   01-29-03
 97:   changed: renamed pseudo-cron.php to pseudo-cron.inc.php
 98:   fixed:   comments at the end of a line don't work
 99:   fixed:   empty lines in crontab file create nonsense jobs
100:   changed: log file grows big very quickly
101:   changed: included config file in main file to avoid directory confusion
102:   added:   day of week abbreviations may now be used (three letters, english)
103: 
104: 
105:   v1.0   01-17-03
106:   inital release
107: 
108:  * ************************************************************************* */
109: 
110: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
111: 
112: 
113: /* * ************************************* */
114: /*      config section               */
115: /* * ************************************* */
116: 
117: // || PLEASE NOTE:
118: // || all paths used here and in cron scripts
119: // || must be absolute or relative to the script which includes pseudo-cron.inc.php!
120: // the file that contains the job descriptions
121: // for a description of the format, see http://www.unixgeeks.org/security/newbie/unix/cron-1.html
122: // and http://www.bitfolge.de/pseudocron
123: $PC_cronTab = $cfg['path']['contenido_cronlog'] . 'crontab.txt';
124: $PC_localCronTab = $cfg['path']['contenido_cronlog'] . 'crontab.local.txt';
125: 
126: // the directory where the script can store information on completed jobs and its log file
127: // include trailing slash
128: $PC_writeDir = $cfg['path']['contenido_cronlog'];
129: 
130: // the directory where the script can store information on completed jobs and its log file
131: // include trailing slash
132: $PC_jobDir = cRegistry::getBackendPath() . $cfg['path']['cronjobs'];
133: 
134: // store directory information
135: $PC_reqDir = getcwd();
136: 
137: // control logging, 1=use log file, 0=don't use log file
138: $PC_useLog = 1;
139: 
140: // turn on / off debugging output
141: // DO NOT use this on live servers!
142: $PC_debug = false;
143: 
144: /* * ************************************* */
145: /*      don't change anything here      */
146: /* * ************************************* */
147: 
148: define("PC_MINUTE", 1);
149: define("PC_HOUR", 2);
150: define("PC_DOM", 3);
151: define("PC_MONTH", 4);
152: define("PC_DOW", 5);
153: define("PC_CMD", 7);
154: define("PC_CRONLINE", 8);
155: 
156: if ($PC_debug) {
157:     echo "<pre>Configuration:";
158:     echo "\nPC_cronTab = " . $PC_cronTab;
159:     echo "\nPC_writeDir = " . $PC_writeDir;
160:     echo "\nPC_jobDir = " . $PC_jobDir;
161:     echo "\nPC_reqDir = " . $PC_reqDir;
162:     echo "\nPC_useLog = " . $PC_useLog;
163:     echo "\n";
164: }
165: 
166: global $bJobRunned;
167: 
168: $bJobRunned = false;
169: 
170: chdir($PC_jobDir);
171: $PC_jobs = parseCronFile($PC_cronTab, $PC_debug);
172: 
173: for ($i = 0; $i < count($PC_jobs); $i++) {
174:     $bJobRunned = true;
175:     runJob($PC_jobs[$i], $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug);
176: }
177: 
178: $PC_jobs = parseCronFile($PC_localCronTab, $PC_debug);
179: for ($i = 0; $i < count($PC_jobs); $i++) {
180:     $bJobRunned = true;
181:     runJob($PC_jobs[$i], $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug);
182: }
183: chdir($PC_reqDir);
184: 
185: if ($PC_debug) {
186:     echo "\n</pre>";
187: }
188: 
189: /**
190:  *
191:  * @param string $msg
192:  * @param string $PC_writeDir
193:  * @param string $PC_useLog
194:  * @param int $PC_debug
195:  */
196: function logMessage($msg, $PC_writeDir, $PC_useLog, $PC_debug) {
197:     if ($PC_useLog == 1) {
198:         $logfile = $PC_writeDir . "pseudo-cron.log";
199: 
200:         if (is_writable($logfile)) {
201:             $file = fopen($logfile, "ab");
202:             if ($msg[cString::getStringLength($msg) - 1] != "\n") {
203:                 $msg.="\r\n";
204:             }
205:             if ($PC_debug) {
206:                 echo $msg;
207:             }
208:             fputs($file, date("r", time()) . "  " . $msg);
209:             fclose($file);
210:         }
211:     }
212: }
213: 
214: /**
215:  * @param int|string $number
216:  *
217:  * @return int
218:  */
219: function lTrimZeros($number)
220: {
221:     return (int)ltrim($number, '0');
222: }
223: 
224: /**
225:  *
226:  * @param array $element
227:  * @param array $targetArray
228:  * @param int $numberOfElements
229:  */
230: function parseElement($element, &$targetArray, $numberOfElements) {
231:     $subelements = explode(",", $element);
232:     for ($i = 0; $i < $numberOfElements; $i++) {
233:         $targetArray[$i] = $subelements[0] == "*";
234:     }
235: 
236:     for ($i = 0; $i < count($subelements); $i++) {
237:         if (preg_match("~^(\\*|([0-9]{1,2})(-([0-9]{1,2}))?)(/([0-9]{1,2}))?$~", $subelements[$i], $matches)) {
238:             if ($matches[1] == "*") {
239:                 $matches[2] = 0;      // from
240:                 $matches[4] = $numberOfElements;      //to
241:             } elseif (!array_key_exists(4, $matches) || $matches[4] == "") {
242:                 $matches[4] = $matches[2];
243:             }
244:             if (array_key_exists(5, $matches)) {
245:                 if ($matches[5][0] != "/") {
246:                     $matches[6] = 1;      // step
247:                 }
248:             } else {
249:                 $matches[6] = 1;      // step
250:             }
251:             for ($j = lTrimZeros($matches[2]); $j <= lTrimZeros($matches[4]); $j+=lTrimZeros($matches[6])) {
252:                 $targetArray[$j] = TRUE;
253:             }
254:         }
255:     }
256: }
257: 
258: /**
259:  *
260:  * @param array $dateArr
261:  * @param int $amount
262:  * @param string $unit
263:  * @param bool $PC_debug
264:  */
265: function decDate(&$dateArr, $amount, $unit, $PC_debug) {
266:     if ($PC_debug) {
267:         echo sprintf("Decreasing from %02d.%02d. %02d:%02d by %d %6s ", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes'], $amount, $unit);
268:     }
269:     if ($unit == "mday") {
270:         $dateArr["hours"] = 23;
271:         $dateArr["minutes"] = 59;
272:         $dateArr["seconds"] = 59;
273:         $dateArr["mday"] -= $amount;
274:         $dateArr["wday"] -= $amount % 7;
275:         if ($dateArr["wday"] < 0) {
276:             $dateArr["wday"]+=7;
277:         }
278:         if ($dateArr["mday"] < 1) {
279:             $dateArr["mon"]--;
280:             switch ($dateArr["mon"]) {
281:                 case 0:
282:                     $dateArr["mon"] = 12;
283:                     $dateArr["year"]--;
284:                 // fall through
285:                 case 1:
286:                 case 3:
287:                 case 5:
288:                 case 7:
289:                 case 8:
290:                 case 10:
291:                 case 12:
292:                     $dateArr["mday"] = 31;
293:                     break;
294:                 case 4:
295:                 case 6:
296:                 case 9:
297:                 case 11:
298:                     $dateArr["mday"] = 30;
299:                     break;
300:                 case 2:
301:                     $dateArr["mday"] = 28;
302:                     break;
303:             }
304:         }
305:     } elseif ($unit == "hour") {
306:         if ($dateArr["hours"] == 0) {
307:             decDate($dateArr, 1, "mday", $PC_debug);
308:         } else {
309:             $dateArr["minutes"] = 59;
310:             $dateArr["seconds"] = 59;
311:             $dateArr["hours"]--;
312:         }
313:     } elseif ($unit == "minute") {
314:         if ($dateArr["minutes"] == 0) {
315:             decDate($dateArr, 1, "hour", $PC_debug);
316:         } else {
317:             $dateArr["seconds"] = 59;
318:             $dateArr["minutes"]--;
319:         }
320:     }
321:     if ($PC_debug) {
322:         echo sprintf("to %02d.%02d. %02d:%02d\n", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes']);
323:     }
324: }
325: 
326: /**
327:  *
328:  * @param string $job
329:  * @param bool $PC_debug
330:  * @return int
331:  */
332: function getLastScheduledRunTime($job, $PC_debug) {
333:     $dateArr = getdate();
334:     $minutesBack = 0;
335:     while (
336:         $minutesBack < 525600 AND
337:         (!$job[PC_MINUTE][$dateArr["minutes"]] OR
338:         !$job[PC_HOUR][$dateArr["hours"]] OR
339:         (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) OR
340:         !$job[PC_MONTH][$dateArr["mon"]])
341:     ) {
342:         if (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) {
343:             decDate($dateArr, 1, "mday", $PC_debug);
344:             $minutesBack+=1440;
345:             continue;
346:         }
347:         if (!$job[PC_HOUR][$dateArr["hours"]]) {
348:             decDate($dateArr, 1, "hour", $PC_debug);
349:             $minutesBack+=60;
350:             continue;
351:         }
352:         if (!$job[PC_MINUTE][$dateArr["minutes"]]) {
353:             decDate($dateArr, 1, "minute", $PC_debug);
354:             $minutesBack++;
355:             continue;
356:         }
357:     }
358: 
359:     if ($PC_debug) {
360:         print_r($dateArr);
361:     }
362: 
363:     return mktime($dateArr["hours"], $dateArr["minutes"], 0, $dateArr["mon"], $dateArr["mday"], $dateArr["year"]);
364: }
365: 
366: /**
367:  *
368:  * @param string $jobname
369:  * @param string $PC_writeDir
370:  * @return string
371:  */
372: function getJobFileName($jobname, $PC_writeDir) {
373:     $jobfile = $PC_writeDir . urlencode($jobname) . ".job";
374:     return $jobfile;
375: }
376: 
377: /**
378:  *
379:  * @param string $jobname
380:  * @param string $PC_writeDir
381:  * @return string|number
382:  */
383: function getLastActialRunTime($jobname, $PC_writeDir) {
384:     $jobfile = getJobFileName($jobname, $PC_writeDir);
385:     if (cFileHandler::exists($jobfile)) {
386:         $file = fopen($jobfile, "rb");
387:         $lastRun = fgets($file, 100);
388:         fclose($file);
389:         if (is_numeric($lastRun)) {
390:             return $lastRun;
391:         }
392:     }
393:     return 0;
394: }
395: 
396: /**
397:  *
398:  * @param string $jobname
399:  * @param int $lastRun
400:  * @param string $PC_writeDir
401:  */
402: function markLastRun($jobname, $lastRun, $PC_writeDir) {
403:     $jobfile = getJobFileName($jobname, $PC_writeDir);
404: 
405:     if ($file = @fopen($jobfile, "w")) {
406:         fputs($file, $lastRun);
407:         fclose($file);
408:     } else {
409:         //echo "Could not write into file $jobfile - permission denied.";
410:     }
411: }
412: 
413: /**
414:  *
415:  * @param string $job
416:  * @param string $PC_jobDir
417:  * @param string $PC_writeDir
418:  * @param int $PC_useLog
419:  * @param bool $PC_debug
420:  *
421:  * @return bool
422:  */
423: function runJob($job, $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug = false) {
424:     global $sess;
425:     $extjob = array();
426: 
427:     parseElement($job[PC_MINUTE], $extjob[PC_MINUTE], 60);
428:     parseElement($job[PC_HOUR], $extjob[PC_HOUR], 24);
429:     parseElement($job[PC_DOM], $extjob[PC_DOM], 31);
430:     parseElement($job[PC_MONTH], $extjob[PC_MONTH], 12);
431:     parseElement($job[PC_DOW], $extjob[PC_DOW], 7);
432: 
433:     $lastActual = getLastActialRunTime($job[PC_CMD], $PC_writeDir);
434:     $lastScheduled = getLastScheduledRunTime($extjob, $PC_debug);
435: 
436:     if ($lastScheduled > $lastActual) {
437:         logMessage("Running    " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
438:         logMessage("  Last run:       " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
439:         logMessage("  Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
440:         markLastRun($job[PC_CMD], $lastScheduled, $PC_writeDir);
441: 
442:         if ($PC_debug) {
443:             echo getcwd();
444:             include($PC_jobDir . $job[PC_CMD]);      // display errors only when debugging
445:         } else {
446:             if (is_object($sess)) {
447:                 $sess->freeze();
448:             }
449:             @include($PC_jobDir . $job[PC_CMD]);      // any error messages are supressed
450:             if (is_object($sess)) {
451:                 $sess->thaw();
452:             }
453:         }
454:         logMessage("Completed   " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
455:         return true;
456:     } else {
457:         if ($PC_debug) {
458:             logMessage("Skipping    " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
459:             logMessage("  Last run:       " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
460:             logMessage("  Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
461:             logMessage("Completed   " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
462:         }
463:         return false;
464:     }
465: }
466: 
467: /**
468:  *
469:  * @param string $PC_cronTabFile
470:  * @param bool $PC_debug
471:  *
472:  * @return array
473:  */
474: function parseCronFile($PC_cronTabFile, $PC_debug) {
475:     $file = @file($PC_cronTabFile);
476:     $job = array();
477:     $jobs = array();
478: 
479:     if (!is_array($file)) {
480:         return $jobs;
481:     }
482: 
483:     for ($i = 0; $i < count($file); $i++) {
484:         if ($file[$i][0] != '#') {
485: //         old regex, without dow abbreviations:
486: //         if (preg_match("~^([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-7,/*]+|Sun|Mon|Tue|Wen|Thu|Fri|Sat)\\s+([^#]*)(#.*)?$~i",$file[$i],$job)) {
487:             if (preg_match("~^([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-7,/*]+|(-|/|Sun|Mon|Tue|Wed|Thu|Fri|Sat)+)\\s+([^#]*)(#.*)?$~i", $file[$i], $job)) {
488:                 $jobNumber = count($jobs);
489:                 $jobs[$jobNumber] = $job;
490:                 if ($jobs[$jobNumber][PC_DOW][0] != '*' AND !is_numeric($jobs[$jobNumber][PC_DOW])) {
491:                     $jobs[$jobNumber][PC_DOW] = str_replace(
492:                         array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"), array(0, 1, 2, 3, 4, 5, 6), $jobs[$jobNumber][PC_DOW]
493:                     );
494:                 }
495:                 $jobs[$jobNumber][PC_CMD] = trim($job[PC_CMD]);
496:                 $jobs[$jobNumber][PC_CRONLINE] = $file[$i];
497:             }
498:         }
499:     }
500: 
501:     if ($PC_debug) {
502:         var_dump($jobs);
503:     }
504:     return $jobs;
505: }
506: 
CMS CONTENIDO 4.10.1 API documentation generated by ApiGen 2.8.0