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
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • idna_convert
  • SearchResultModule
  • TinyMCE_Compressor

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:  *
216:  * @param int $number
217:  * @return integer
218:  */
219: function lTrimZeros($number) {
220:     while (!empty($number) && $number[0] == '0') {
221:         $number = cString::getPartOfString($number, 1);
222:     }
223:     if (empty($number)) {
224:         $number = 0;
225:     }
226:     return cSecurity::toInteger($number);
227: }
228: 
229: /**
230:  *
231:  * @param array $element
232:  * @param array $targetArray
233:  * @param int $numberOfElements
234:  */
235: function parseElement($element, &$targetArray, $numberOfElements) {
236:     $subelements = explode(",", $element);
237:     for ($i = 0; $i < $numberOfElements; $i++) {
238:         $targetArray[$i] = $subelements[0] == "*";
239:     }
240: 
241:     for ($i = 0; $i < count($subelements); $i++) {
242:         if (preg_match("~^(\\*|([0-9]{1,2})(-([0-9]{1,2}))?)(/([0-9]{1,2}))?$~", $subelements[$i], $matches)) {
243:             if ($matches[1] == "*") {
244:                 $matches[2] = 0;      // from
245:                 $matches[4] = $numberOfElements;      //to
246:             } elseif (!array_key_exists(4, $matches) || $matches[4] == "") {
247:                 $matches[4] = $matches[2];
248:             }
249:             if (array_key_exists(5, $matches)) {
250:                 if ($matches[5][0] != "/") {
251:                     $matches[6] = 1;      // step
252:                 }
253:             } else {
254:                 $matches[6] = 1;      // step
255:             }
256:             for ($j = lTrimZeros($matches[2]); $j <= lTrimZeros($matches[4]); $j+=lTrimZeros($matches[6])) {
257:                 $targetArray[$j] = TRUE;
258:             }
259:         }
260:     }
261: }
262: 
263: /**
264:  *
265:  * @param array $dateArr
266:  * @param int $amount
267:  * @param string $unit
268:  * @param bool $PC_debug
269:  */
270: function decDate(&$dateArr, $amount, $unit, $PC_debug) {
271:     if ($PC_debug) {
272:         echo sprintf("Decreasing from %02d.%02d. %02d:%02d by %d %6s ", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes'], $amount, $unit);
273:     }
274:     if ($unit == "mday") {
275:         $dateArr["hours"] = 23;
276:         $dateArr["minutes"] = 59;
277:         $dateArr["seconds"] = 59;
278:         $dateArr["mday"] -= $amount;
279:         $dateArr["wday"] -= $amount % 7;
280:         if ($dateArr["wday"] < 0) {
281:             $dateArr["wday"]+=7;
282:         }
283:         if ($dateArr["mday"] < 1) {
284:             $dateArr["mon"]--;
285:             switch ($dateArr["mon"]) {
286:                 case 0:
287:                     $dateArr["mon"] = 12;
288:                     $dateArr["year"]--;
289:                 // fall through
290:                 case 1:
291:                 case 3:
292:                 case 5:
293:                 case 7:
294:                 case 8:
295:                 case 10:
296:                 case 12:
297:                     $dateArr["mday"] = 31;
298:                     break;
299:                 case 4:
300:                 case 6:
301:                 case 9:
302:                 case 11:
303:                     $dateArr["mday"] = 30;
304:                     break;
305:                 case 2:
306:                     $dateArr["mday"] = 28;
307:                     break;
308:             }
309:         }
310:     } elseif ($unit == "hour") {
311:         if ($dateArr["hours"] == 0) {
312:             decDate($dateArr, 1, "mday", $PC_debug);
313:         } else {
314:             $dateArr["minutes"] = 59;
315:             $dateArr["seconds"] = 59;
316:             $dateArr["hours"]--;
317:         }
318:     } elseif ($unit == "minute") {
319:         if ($dateArr["minutes"] == 0) {
320:             decDate($dateArr, 1, "hour", $PC_debug);
321:         } else {
322:             $dateArr["seconds"] = 59;
323:             $dateArr["minutes"]--;
324:         }
325:     }
326:     if ($PC_debug) {
327:         echo sprintf("to %02d.%02d. %02d:%02d\n", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes']);
328:     }
329: }
330: 
331: /**
332:  *
333:  * @param string $job
334:  * @param bool $PC_debug
335:  * @return int
336:  */
337: function getLastScheduledRunTime($job, $PC_debug) {
338:     $dateArr = getdate();
339:     $minutesBack = 0;
340:     while (
341:         $minutesBack < 525600 AND
342:         (!$job[PC_MINUTE][$dateArr["minutes"]] OR
343:         !$job[PC_HOUR][$dateArr["hours"]] OR
344:         (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) OR
345:         !$job[PC_MONTH][$dateArr["mon"]])
346:     ) {
347:         if (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) {
348:             decDate($dateArr, 1, "mday", $PC_debug);
349:             $minutesBack+=1440;
350:             continue;
351:         }
352:         if (!$job[PC_HOUR][$dateArr["hours"]]) {
353:             decDate($dateArr, 1, "hour", $PC_debug);
354:             $minutesBack+=60;
355:             continue;
356:         }
357:         if (!$job[PC_MINUTE][$dateArr["minutes"]]) {
358:             decDate($dateArr, 1, "minute", $PC_debug);
359:             $minutesBack++;
360:             continue;
361:         }
362:     }
363: 
364:     if ($PC_debug) {
365:         print_r($dateArr);
366:     }
367: 
368:     return mktime($dateArr["hours"], $dateArr["minutes"], 0, $dateArr["mon"], $dateArr["mday"], $dateArr["year"]);
369: }
370: 
371: /**
372:  *
373:  * @param string $jobname
374:  * @param string $PC_writeDir
375:  * @return string
376:  */
377: function getJobFileName($jobname, $PC_writeDir) {
378:     $jobfile = $PC_writeDir . urlencode($jobname) . ".job";
379:     return $jobfile;
380: }
381: 
382: /**
383:  *
384:  * @param string $jobname
385:  * @param string $PC_writeDir
386:  * @return string|number
387:  */
388: function getLastActialRunTime($jobname, $PC_writeDir) {
389:     $jobfile = getJobFileName($jobname, $PC_writeDir);
390:     if (cFileHandler::exists($jobfile)) {
391:         $file = fopen($jobfile, "rb");
392:         $lastRun = fgets($file, 100);
393:         fclose($file);
394:         if (is_numeric($lastRun)) {
395:             return $lastRun;
396:         }
397:     }
398:     return 0;
399: }
400: 
401: /**
402:  *
403:  * @param string $jobname
404:  * @param int $lastRun
405:  * @param string $PC_writeDir
406:  */
407: function markLastRun($jobname, $lastRun, $PC_writeDir) {
408:     $jobfile = getJobFileName($jobname, $PC_writeDir);
409: 
410:     if ($file = @fopen($jobfile, "w")) {
411:         fputs($file, $lastRun);
412:         fclose($file);
413:     } else {
414:         //echo "Could not write into file $jobfile - permission denied.";
415:     }
416: }
417: 
418: /**
419:  *
420:  * @param string $job
421:  * @param string $PC_jobDir
422:  * @param string $PC_writeDir
423:  * @param int $PC_useLog
424:  * @param bool $PC_debug
425:  * 
426:  * @return bool
427:  */
428: function runJob($job, $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug = false) {
429:     global $sess;
430:     $extjob = array();
431: 
432:     parseElement($job[PC_MINUTE], $extjob[PC_MINUTE], 60);
433:     parseElement($job[PC_HOUR], $extjob[PC_HOUR], 24);
434:     parseElement($job[PC_DOM], $extjob[PC_DOM], 31);
435:     parseElement($job[PC_MONTH], $extjob[PC_MONTH], 12);
436:     parseElement($job[PC_DOW], $extjob[PC_DOW], 7);
437: 
438:     $lastActual = getLastActialRunTime($job[PC_CMD], $PC_writeDir);
439:     $lastScheduled = getLastScheduledRunTime($extjob, $PC_debug);
440: 
441:     if ($lastScheduled > $lastActual) {
442:         logMessage("Running    " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
443:         logMessage("  Last run:       " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
444:         logMessage("  Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
445:         markLastRun($job[PC_CMD], $lastScheduled, $PC_writeDir);
446: 
447:         if ($PC_debug) {
448:             echo getcwd();
449:             include($PC_jobDir . $job[PC_CMD]);      // display errors only when debugging
450:         } else {
451:             if (is_object($sess)) {
452:                 $sess->freeze();
453:             }
454:             @include($PC_jobDir . $job[PC_CMD]);      // any error messages are supressed
455:             if (is_object($sess)) {
456:                 $sess->thaw();
457:             }
458:         }
459:         logMessage("Completed   " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
460:         return true;
461:     } else {
462:         if ($PC_debug) {
463:             logMessage("Skipping    " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
464:             logMessage("  Last run:       " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
465:             logMessage("  Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
466:             logMessage("Completed   " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
467:         }
468:         return false;
469:     }
470: }
471: 
472: /**
473:  *
474:  * @param string $PC_cronTabFile
475:  * @param bool $PC_debug
476:  * 
477:  * @return array
478:  */
479: function parseCronFile($PC_cronTabFile, $PC_debug) {
480:     $file = @file($PC_cronTabFile);
481:     $job = array();
482:     $jobs = array();
483: 
484:     if (!is_array($file)) {
485:         return $jobs;
486:     }
487: 
488:     for ($i = 0; $i < count($file); $i++) {
489:         if ($file[$i][0] != '#') {
490: //         old regex, without dow abbreviations:
491: //         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)) {
492:             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)) {
493:                 $jobNumber = count($jobs);
494:                 $jobs[$jobNumber] = $job;
495:                 if ($jobs[$jobNumber][PC_DOW][0] != '*' AND !is_numeric($jobs[$jobNumber][PC_DOW])) {
496:                     $jobs[$jobNumber][PC_DOW] = str_replace(
497:                         array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"), array(0, 1, 2, 3, 4, 5, 6), $jobs[$jobNumber][PC_DOW]
498:                     );
499:                 }
500:                 $jobs[$jobNumber][PC_CMD] = trim($job[PC_CMD]);
501:                 $jobs[$jobNumber][PC_CRONLINE] = $file[$i];
502:             }
503:         }
504:     }
505: 
506:     if ($PC_debug) {
507:         var_dump($jobs);
508:     }
509:     return $jobs;
510: }
511: 
CMS CONTENIDO 4.10.0 API documentation generated by ApiGen 2.8.0