/**
  * Looks if an execution of a given cronjob is pending.
  * 
  * The basic principle of the wcf cronjobs is that a call to this method is being triggered 
  * via ajax with every Burning Board page view. This is being done in order to ensure a sufficient 
  * accuracy of execution time, despite the lack of a "real" crond.
  * Every time this method is being called, configured execution times for a given cronjob 
  * may most likely either lie ahead, or be a thing of the past. In the latter case this cronjob
  * is being estimated as "pending" and thus be executed.
  */
 protected function findPendingCronjobs()
 {
     // there might be ranges of date/time values specified. Ranges can be expressed
     // either with a comma-separated list, or with a dash, or with a combination of both.
     // also there are intervals possible, expressed with an asterisk followed by a slash
     // and a number (e.g. '*/2' meaning 'every two somethings'). days of week and months
     // may also be noted as abbreviations of plaintext names.
     foreach ($this->cronjobsCache as $key => $cronjobsCache) {
         $this->plannedExecs = array();
         if (intval($cronjobsCache['execMultiple']) == 1) {
             // set identificator for an eventual execMultiple action.
             $this->execMultiple = 1;
             // reset counter needed for an eventual execMultiple action.
             $this->countMultipleExecs = 0;
             // initiate array where "planned" dates of inbetween execs are being stored if execMultiple is set.
             if (intval($cronjobsCache['nextExec']) > 1) {
                 $this->plannedExecs[] = intval($cronjobsCache['nextExec']);
             }
         } else {
             $this->execMultiple = 0;
             $this->countMultipleExecs = 1;
         }
         // don't execute this cronjob in case nextExec is in the future.
         if ($cronjobsCache['nextExec'] > $this->now) {
             unset($this->cronjobsCache[$key]);
             continue;
         }
         // determine time base.
         if ($this->execMultiple == 0) {
             $this->timebase = $this->now;
         } else {
             if ($this->execMultiple == 1) {
                 if (intval($cronjobsCache['nextExec'] <= 1)) {
                     $this->timebase = $this->now;
                     $this->countMultipleExecs = 1;
                 } else {
                     $this->timebase = $cronjobsCache['nextExec'];
                     // the nextExec determined during last execution.
                 }
             }
         }
         // get the actual nextExec time.
         if ($this->findCronjobNextExec($cronjobsCache) === false) {
             unset($this->cronjobsCache[$key]);
             continue;
         }
         // write new lastExec and nextExec timestamps to database and add log entry.
         $cronjobObj = new CronjobEditor(null, $cronjobsCache);
         $cronjobObj->setNextExec($this->nextExec);
         $this->cronjobsCache[$key]['newLogID'] = $cronjobObj->logExec();
     }
     // now clear the cache.
     WCF::getCache()->clear(WCF_DIR . 'cache', 'cache.cronjobs-*.php');
     // memcache workaround to be sure that at least the cache of the active application is cleared
     WCF::getCache()->clearResource($this->cacheName);
     foreach ($this->cronjobsCache as $cronjobsCache) {
         try {
             // now really execute the cronjob.
             $this->execPendingCronjobs($cronjobsCache);
         } catch (SystemException $e) {
             CronjobEditor::logSuccess($cronjobsCache['newLogID'], false, $e);
             continue;
         }
     }
 }
 /**
  * Executes this cronjob.
  */
 public function execute()
 {
     // create log entry
     $logID = CronjobEditor::logExec();
     // include class file
     $classPath = FileUtil::getRealPath(WCF_DIR . $this->packageDir . $this->classPath);
     if (!file_exists($classPath)) {
         throw new SystemException("unable to find class file '" . $classPath . "'", 11000);
     }
     require_once $classPath;
     // create instance.
     $className = StringUtil::getClassName($this->classPath);
     if (!class_exists($className)) {
         throw new SystemException("unable to find class '" . $className . "'", 11001);
     }
     // execute cronjob.
     $cronjobExec = new $className();
     if (method_exists($cronjobExec, 'execute')) {
         $cronjobExec->execute($this->data);
     }
     // log success.
     CronjobEditor::logSuccess($logID, true);
 }