Location: PHPKode > scripts > tiCalFile > tiCalFile-3.0/tiCalFile.class.php
<?php
/**
 * tiCalFile 3.0
 *
 * Class creating test iCal files with events.
 *
 * copyright (c) 2011-2012 Kjell-Inge Gustafsson kigkonsult
 * kigkonsult.se/tiCalFile/index.php
 * kigkonsult.se/contact/index.php
 * updated 20120526
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
**/
class tiCalFile {
  const   version = 'tiCalFile 3.0';
  private $baseValues;
  private $config;
  private $filemtime;
  private $fp;
  private $lockFile;
  private $log;
  private $removeTime;
  private static $singleton_Instance; // store the singleton instance
  /** Getter method for creating/returning the single instance of this class */
  public static function singleton( & $log ) {
    if( !self::$singleton_Instance )
      self::$singleton_Instance = new tiCalFile( $log );
    return self::$singleton_Instance;
  }
  /** create instance */
  public function __construct( & $log, $config = array()) {
    $this->config = array( 'VERSION' => tiCalFile::version.' (Kjell-Inge Gustafsson, kigkonsult.se)' );
    if( empty( $log ))
      $log = new dummyLog();
    $this->log    = $log;
    $msg = $this->config['VERSION'].' START ';
    if( isset( $_SERVER ) && !empty( $_SERVER['REMOTE_ADDR'] ))
      $msg .= 'from IP:'.$_SERVER['REMOTE_ADDR'].' HOST:'.gethostbyaddr( $_SERVER['REMOTE_ADDR'] );
    $this->log->log( $msg, 6 );
          // defaults
    $this->config['CALDIR']        = 'calendars';
    $this->config['FILENAMES']     = array( 'testFile.ics' );
    $this->config['LOCKDIR']       = FALSE; // => $this->config['CALDIR'];
    $this->config['LOCKFILE']      = 'tiCalFile.lck';
    $this->config['THISDATE']      = date( 'YmdHis' ); // now
    $this->config['METHOD']        = 'PUBLISH';
    $tz = date_default_timezone_get();
    $this->config['X-WR-TIMEZONE'] = ( !empty( $tz ) && ( 'UTC' != strtoupper( $tz ))) ? $tz : FALSE;
    $this->config['CALAGE']        = 1;                // one hour
    $this->config['DAYCNT']        = 10;               // ten days
    $this->config['EVENTCNT']      = 5;                // five events every day
    $this->config['EVENTSTART']    = 7;                // start between seven..
    $this->config['EVENTEND']      = 18;               // .. and 18
    $this->config['EVENTDURMIN']   = 1;                // event duration from one..
    $this->config['EVENTDURMAX']   = 36;               // .. to 36 hours
    $this->config['LANGUAGE']      = FALSE;
    $this->config['ALTREP']        = FALSE;
    $this->config['X-PARAM']       = FALSE;
    $this->config['TZID']          = FALSE;
    foreach( $config as $key => $value )
      $this->setConfig( $key,   $value );
  }
  public function __destruct() {
    foreach( $this as $key => $value )
      unset( $this->$key ); 
  }
            /* check occurrence */
  private function accepted( $occurrParam ) {
    if( !isset( $this->config[$occurrParam] ))
      $this->config[$occurrParam] = 50;
    if( empty( $this->config[$occurrParam] ))
      return FALSE;
    if( 100 == $this->config[$occurrParam] )
      return TRUE;
    return ( $this->config[$occurrParam] >= mt_rand( 1, 99 )) ? TRUE : FALSE;
  }
  private function checkDirectory( & $directory) {
    $this->log->log( "checkDirectory: '$directory'", 7 );
    $dssl         = strlen( DIRECTORY_SEPARATOR );
    if( DIRECTORY_SEPARATOR != substr( $directory, ( 0 - $dssl )))
      $directory .= DIRECTORY_SEPARATOR;
    if((      DIRECTORY_SEPARATOR != substr( $directory, 0, (   + $dssl))) &&
       (  '.'.DIRECTORY_SEPARATOR != substr( $directory, 0, ( 1 + $dssl))) &&
       ( '..'.DIRECTORY_SEPARATOR != substr( $directory, 0, ( 2 + $dssl))))
      $directory  = '.'.DIRECTORY_SEPARATOR.$directory;
//    $this->log->log( "checkDirectory: '$directory'", 7 );
    if( 0 < substr_count( $directory, '..' ))
      $directory  = realpath( $directory );
    $this->log->log( "checkDirectory: '$directory'", 7 );
    return ( is_dir( $directory ) && is_writable( $directory )) ? TRUE : FALSE;
  }
  private function checkLockfile() {
    $this->log->log( 'checkLockfile \''.$this->lockFile.'\'', 7 );
    if( FALSE !== ( $this->fp = @fopen( $this->lockFile, 'a+' ))) {
      if( FALSE !== ( flock( $this->fp, LOCK_EX ))) {
        $filesize        = filesize( $this->lockFile );
        $this->filemtime = filemtime( $this->lockFile );
        $this->log->log( 'actual lock file time:     '.date( 'Y-m-d H:i:s', $this->filemtime )." filesize=$filesize", 6 );
        return (( 10 > $filesize ) || ( $this->filemtime < $this->removeTime )) ? TRUE : FALSE;
      }
      $this->log->log( 'checkLockfile (17) creating lock on file \''.$this->lockFile.'\', check directory/file!!', 3 );
      $this->log->flush();
      return FALSE;
    }
    $this->log->log( 'checkLockfile (16) opening lock file \''.$this->lockFile.'\', check directory/file!!', 3 );
    $this->log->flush();
    return FALSE;
  }
  private function createTestFile( $filename ) {
    $dirFile  = $this->config['CALDIR'].$filename;
    $calendar = new vcalendar();
    if( isset( $this->config['UNIQUE'] ) && !empty( $this->config['UNIQUE'] ))
      $calendar->setConfig( 'unique_id', $this->config['UNIQUE'] );
    if( !$calendar->setConfig('directory',   $this->config['CALDIR'] )) {
      $this->log->log( '(11) setting iCalcreator directory \''.$this->config['CALDIR'].'\', check directory/file!!', 3 );
      $this->log->log( "createTestFile '$dirFile'", 3 );
      $this->log->flush();
      return FALSE;
    }
    if( !$calendar->setConfig('filename',    $filename )) {
      $this->log->log( '(12) setting iCalcreator file \''.$dirFile.'\', check file!!', 3 );
      $this->log->log( "createTestFile '$dirFile'", 3 );
      $this->log->flush();
      return FALSE;
    }
    if( isset( $this->config['LANGUAGE'] ) && !empty( $this->config['LANGUAGE'] ))
      $calendar->setConfig( 'language',      $this->config['LANGUAGE'] );
    if( isset( $this->config['METHOD'] ) && !empty( $this->config['METHOD'] ))
      $calendar->setProperty( 'METHOD',        $this->config['METHOD'] );
    $calendar->setProperty( 'X-WR-CALNAME',  $this->config['VERSION'].' test calendar file' );
    $calendar->setProperty( 'X-WR-CALDESC',  'A test calendar file created by '.$this->config['VERSION'].' utilizing '.ICALCREATOR_VERSION );
    if( isset( $this->config['X-WR-TIMEZONE'] ) && !empty( $this->config['X-WR-TIMEZONE'] ))
      $calendar->setProperty( 'X-WR-TIMEZONE', $this->config['X-WR-TIMEZONE'] );
    if( $this->accepted( 'X_PROP1STCALOCCURRENCE' ))
      $calendar->setProperty( 'X-PROP1', $this->getValue( 'descriptions' ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), 0 ));
    if( $this->accepted( 'X_PROP2NDCALOCCURRENCE' ))
      $calendar->setProperty( 'X-PROP2', $this->getValue( 'descriptions' ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), 0 ));
    $date         = mktime( 0, 0, 0, (int) substr( $this->config['THISDATE'], 4, 2 ), (int) substr( $this->config['THISDATE'], 6, 2 ), (int) substr( $this->config['THISDATE'], 0, 4 ));
    $stopDate     = $date + ($this->config['DAYCNT'] * 24 * 3600);
    $eventCount   = 0;
    $UIDs         = array();
    while( $date < $stopDate ) {
      $dayCount  = 0;
      while( $dayCount < $this->config['EVENTCNT'] ) {
        $eventCount++;
        $dayCount++;
        $event = & $calendar->newComponent( 'vevent' );
        $UIDs[] = $event->getProperty( 'UID' );
            /** always one DTSTART property in every event */
        $eventdate = $date + ( mt_rand( $this->config['EVENTSTART'], $this->config['EVENTEND'] ) * 3600 );           // random start hour, 7 to 18
        if( $this->accepted( 'ALLDAYEVENTOCCURRENCE' )) {
          $event->setProperty( 'DTSTART',  array( 'timestamp' => $date), $this->fixParameters( array( 'VALUE' => 'DATE', 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          $allDayEvent = TRUE;
        }
        else {
          $allDayEvent = FALSE;
          $event->setProperty( 'DTSTART',  array( 'timestamp' => $eventdate ), $this->fixParameters( array( 'TZID' => $this->config['TZID'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          $duration = mt_rand( $this->config['EVENTDURMIN'], $this->config['EVENTDURMAX'] ) * 3600;
          if( $this->accepted( 'DTENDOCCURRENCE' ))
            $event->setProperty( 'DTEND',  array( 'timestamp' => ( $eventdate + $duration )), $this->fixParameters( array( 'TZID' => $this->config['TZID'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          elseif( $this->accepted( 'DURATIONDOCCURRENCE' ))
            $event->setProperty( 'DURATION', array( 'sec' => $duration ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
        }
            /** always one SUMMARY property in every event */
        $summary = "Event #$eventCount. ".$this->getValue( 'summaries' );
        $event->setProperty( 'SUMMARY',   $summary, $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** always one DESCRIPTION property in every event */
        $description = $this->getValue( 'descriptions' );
        $event->setProperty( 'DESCRIPTION', $description, $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** always one property Categories, selects 1 of 10 categories */
        $pValue = 'Category #'.mt_rand( 1, 10);
        $event->setProperty( 'CATEGORIES', $pValue, $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** 2nd property Categories, 3rd occurence (3rd ocurrence in 2nd), 0=none */
        if( $this->accepted( 'CATEGORIES2NDOCCURRENCE' )) {
          $pValue = 'Category #A'.mt_rand( 1, 10);
          if( $this->accepted( 'CATEGORIES3RDOCCURRENCE' ))
            $pValue .= ',Category #XB'.mt_rand( 1, 10);
          $event->setProperty( 'CATEGORIES', $pValue, $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
        }
            /** always one property Resources, selects 1 of 10 resources */
        $pValue = 'Resource R'.mt_rand( 1, 10);
        $event->setProperty( 'RESOURCES', $pValue, $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** percent 2nd property Resources, 3rd occurence (3rd percent ocurrence in 2nd), 0=none */
        if( $this->accepted( 'RESOURCES2NDOCCURRENCE' )) {
          $pValue = 'Resource #P'.mt_rand( 1, 10);
          if( $this->accepted( 'RESOURCES3RDOCCURRENCE' ))
            $pValue .= ',Resource #XP'.mt_rand( 1, 10);
          $event->setProperty( 'RESOURCES', $pValue, $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
        }
            /** ATTACH */
        if( $this->accepted( 'ATTACHOCCURRENCE' ))
          $event->setProperty( 'ATTACH', 'http://kigkonsult.se/info/info.rtf', $this->fixParameters( array( "FMTTYPE" => "application/binary", 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** Attendee */
        if( $this->accepted( 'ATTENDEE1STOCCURRENCE' ))
          $event->setProperty( 'ATTENDEE', $this->getValue( 'attendees' ));
        if( $this->accepted( 'ATTENDEE2NDOCCURRENCE' ))
          $event->setProperty( 'ATTENDEE', $this->getValue( 'attendees' ));
            /** Comment */
        if( $this->accepted( 'COMMENT1STOCCURRENCE' ))
          $event->setProperty( 'COMMENT',  $this->getValue( 'comments' ), $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
        if( $this->accepted( 'COMMENT2NDOCCURRENCE' ))
          $event->setProperty( 'COMMENT',  $this->getValue( 'comments' ), $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** CONTACT */
        if( $this->accepted( 'CONTACTOCCURRENCE' ))
          $event->setProperty( 'CONTACT', $this->getValue( 'attendees' ), $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** CREATED */
        if( $this->accepted( 'CREATEDOCCURRENCE' ))
          $event->setProperty( 'CREATED',  array( 'timestamp' => ($eventdate - (2*24*3600))), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount )); // fake two days before event startdate
            /** EXDATE */
        $setExdate = 0;
        if( $this->accepted( 'EXDATEOCCURRENCE' ))
          $setExdate = 1;
            /** GEO */
        if( $this->accepted( 'GEOOCCURRENCE' )) {
          $fraction  = pow( 10, mt_rand( 0, 6 ));
          $latitude  = sprintf( '%1.6f', ( mt_rand( 0, (2*( 90 * $fraction ))) - ( 90 * $fraction )) / $fraction );
          $latitude  = rtrim( rtrim( $latitude, '0' ), '.' );
          $fraction  = pow( 10, mt_rand( 0, 6 ));
          $longitude = sprintf( '%1.6f', ( mt_rand( 0, (2*( 180 * $fraction ))) - ( 180 * $fraction )) / $fraction );
          $longitude = rtrim( rtrim( $longitude, '0' ), '.' );
          $event->setProperty( 'GEO', $latitude, $longitude );
        }
            /** LAST-MODIFIED */
        if( $this->accepted( 'LAST_MODIFIEDOCCURRENCE' ))
          $event->setProperty( 'LAST-MODIFIED', array( 'timestamp' => ($eventdate - (23*3600))), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount )); // fake 25 hours before event startdate
            /** LOCATION */
        if( $this->accepted( 'LOCATIONOCCURRENCE' ))
          $event->setProperty( 'LOCATION', "Location #$eventCount", $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** ORGANIZER */
        if( $this->accepted( 'ORGANIZEROCCURRENCE' ))
          $event->setProperty( 'ORGANIZER', $this->getValue( 'attendees' ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** PRIORITY */
        if( $this->accepted( 'PRIORITY' )) // priority, 1 to 9. HIGH (1-4), MEDIUM (5), LOW (6-9)
          $event->setProperty( 'PRIORITY',  $this->getValue( 'prioArr' ));
            /** RDATE */
        if( $this->accepted( 'RDATEOCCURRENCE' )) {  // fake one week after event start date
          if( $allDayEvent )
            $params = $this->fixParameters( array( 'VALUE' => 'DATE', 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount );
          else
            $params = $this->fixParameters( array( 'TZID' => $this->config['TZID'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount );
          $event->setProperty( 'RDATE', array( array( 'timestamp' => ($eventdate + (7*24*3600)))), $params );
          $setExdate += 1;
        }
            /** RELATED-TO */
        if( $this->accepted( 'RELATED_TOOCCURRENCE' ))
          $event->setProperty( 'RELATED-TO', $UIDs[mt_rand( 0, ( count( $UIDs ) - 1 ))], $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** RRULE */
        if( $this->accepted( 'RRULEOCCURRENCE' )) {
          $recur = (( $eventCount % 2 ) == 0 ) ? array( 'FREQ' => 'WEEKLY' ) : array( 'FREQ' => 'MONTHLY' );
          if(( $eventCount % 2 ) == 0 ) {
            if( 'WEEKLY' == $recur['FREQ'] ) {
              if( $allDayEvent )
                $recur['UNTIL'] = date( 'Ymd',          $eventdate + ((24*3600) * mt_rand( 20, 30 ))); // end within 20-30 days, 3-5 weeks
              else
                $recur['UNTIL'] = array( 'timestamp' => $eventdate + ((24*3600) * mt_rand( 20, 30 ))); // end within 20-30 days, 3-5 weeks
            }
            elseif( $allDayEvent )
              $recur['UNTIL'] = date( 'Ymd',            $eventdate + ((24*3600) * mt_rand( 20, 30 ))); // end within 40-70 days, 2-3 month
            else
              $recur['UNTIL'] = array( 'timestamp' =>   $eventdate + ((24*3600) * mt_rand( 40, 70 ))); // end within 40-70 days, 2-3 month
          }
          else
            $recur['COUNT'] = mt_rand( 3, 5 );
          $x = mt_rand( 0, 5 );
          if( 1 < $x )
            $recur['BYDAY'] = $this->baseValues['bydays'][$x];
          elseif( 0 < $x )
            $recur['BYDAY'] = array( 'DAY' => $this->baseValues['days'][date( 'w', $eventdate )] );
          $event->setProperty( 'RRULE',  $recur );
          $setExdate += 1;
        } // end - if( $this->accepted( 'RRULEOCCURRENCE' ))
        if( 2 <= $setExdate ) { // exclude event startdate
          if( $allDayEvent )
            $params = $this->fixParameters( array( 'VALUE' => 'DATE', 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount );
          else
            $params = $this->fixParameters( array( 'TZID' => $this->config['TZID'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount );
          $event->setProperty( 'EXDATE', array( array( 'timestamp' => $eventdate )), $params );
        }
            /** STATUS */
        if( $this->accepted( 'STATUSOCCURRENCE' ))
          $event->setProperty( 'STATUS', $this->getValue( 'status' ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** TRANSP */
        if( $this->accepted( 'TRANSPOCCURRENCE' ))
          $event->setProperty( 'TRANSP', $this->getValue( 'transp' ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** URL */
        if( $this->accepted( 'URLOCCURRENCE' ))
          $event->setProperty( 'URL', 'http://kigkonsult.se/info/index.php?event='.$eventCount, $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** X-prop */
        if( $this->accepted( 'X_PROP1STOCCURRENCE' ))
          $event->setProperty( 'X-PROP1', $this->getValue( 'descriptions' ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
        if( $this->accepted( 'X_PROP2NDOCCURRENCE' ))
          $event->setProperty( 'X-PROP2', $this->getValue( 'descriptions' ), $this->fixParameters( array( 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
            /** AUDIO ALARM */
        if( $this->accepted( 'AUDIOALARMOCCURRENCE' )) {
          $alarm = & $event->newComponent( 'valarm' );
          $alarm->setProperty( 'ACTION', 'AUDIO' );
          $alarm->setProperty( 'ATTACH', 'ftp://kigkonsult.se/sounds/bell-01.aud', $this->fixParameters( array( "FMTTYPE" => "audio/basic", 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          $alarm->setProperty( 'DURATION', 'PT1H' );
          $alarm->setProperty( 'REPEAT', 2 );
          if( !isset( $this->config['AUDIOALARMTRIGGER'] ) || !ctype_digit((string) $this->config['AUDIOALARMTRIGGER'] ))
            $trigger = array( 'hour' => 1 );
          elseif( 23 < $this->config['AUDIOALARMTRIGGER'] )
            $trigger = array( 'day' => floor( $this->config['AUDIOALARMTRIGGER'] / 24 ), 'hour' => $this->config['AUDIOALARMTRIGGER'] % 24 );
          else
            $trigger = array( 'hour' => $this->config['AUDIOALARMTRIGGER'] );
          $alarm->setProperty( 'TRIGGER', $trigger );
        } // end - if( $this->accepted( 'AUDIOALARMOCCURRENCE' ))
            /** DISPLAY ALARM */
        if( $this->accepted( 'DISPLAYALARMOCCURRENCE' )) {
          $alarm = & $event->newComponent( 'valarm' );
          $alarm->setProperty( 'ACTION', 'DISPLAY' );
          $alarm->setProperty( 'DESCRIPTION', $description, $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          if( !isset( $this->config['DISPLAYALARMTRIGGER'] ) || !ctype_digit((string) $this->config['DISPLAYALARMTRIGGER'] ))
            $trigger = array( 'hour' => 4 );
          elseif( 23 < $this->config['DISPLAYALARMTRIGGER'] )
            $trigger = array( 'day' => floor( $this->config['DISPLAYALARMTRIGGER'] / 24 ), 'hour' => $this->config['DISPLAYALARMTRIGGER'] % 24 );
          else
            $trigger = array( 'hour' => $this->config['DISPLAYALARMTRIGGER'] );
          $alarm->setProperty( 'TRIGGER', $trigger );
        } // end - if( $this->accepted( 'DISPLAYALARMOCCURRENCE' ))
            /** EMAIL ALARM */
        if( $this->accepted( 'EMAILALARMOCCURRENCE' )) {
          $alarm = & $event->newComponent( 'valarm' );
          $alarm->setProperty( 'ACTION', 'EMAIL' );
          $alarm->setProperty( 'DESCRIPTION', $description, $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          $alarm->setProperty( 'SUMMARY',     $summary, $this->fixParameters( array( 'ALTREP' => $this->config['ALTREP'], 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          if( $this->accepted( 'ATTACHOCCURRENCE' ))
            $alarm->setProperty( 'ATTACH', 'http://kigkonsult.se/info/info.doc', $this->fixParameters( array( "FMTTYPE" => "application/binary", 'X-PARAM' => $this->config['X-PARAM'] ), $eventCount ));
          $alarm->setProperty( 'attendee',    $this->getValue( 'attendees' ));
          $alarm->setProperty( 'attendee',    $this->getValue( 'attendees' ));
          if( !isset( $this->config['EMAILALARMTRIGGER'] ) || !ctype_digit((string) $this->config['EMAILALARMTRIGGER'] ))
            $trigger = array( 'hour' => 24 );
          elseif( 23 < $this->config['EMAILALARMTRIGGER'] )
            $trigger = array( 'day' => floor( $this->config['EMAILALARMTRIGGER'] / 24 ), 'hour' => $this->config['EMAILALARMTRIGGER'] % 24 );
          else
            $trigger = array( 'hour' => $this->config['EMAILALARMTRIGGER'] );
          $alarm->setProperty( 'trigger',     $trigger );
        } // end - if( $this->accepted( 'EMAILALARMOCCURRENCE' ))
      } // end - while( $dayCount < $this->config['EVENTCNT'] )
      $date += (24*3600);
    } // end - while( $date < $stopDate )
    $calendar->sort();
    iCalUtilityFunctions::createTimezone( $calendar, $this->config['X-WR-TIMEZONE'] );
    if( FALSE === $calendar->saveCalendar()) {
      $this->log->log( "createTestFile (13) can't save calendar file '$dirFile', check directory/fil-e permissions!!", 3 );
      return FALSE;
    }
    $this->log->log( "Created '$dirFile', start ".$this->config['THISDATE']." with $eventCount components", 7 );
    return TRUE;
  }
  public function createTestFiles() {
    $start        = microtime( TRUE );
    if( !isset( $this->config['CALDIR'] ) || empty( $this->config['CALDIR'] ))
      $this->config['CALDIR']    = '.';
    if( FALSE === $this->checkDirectory( $this->config['CALDIR'] )) {
      $this->log->log( "createTestFiles (14) no write rights in '".$this->config['CALDIR']."', check directory!!", 2 );
      $this->log->flush();
      return FALSE;
    }
    if( !isset( $this->config['FILENAMES'] ) || empty( $this->config['FILENAMES'] ))
      $this->config['FILENAMES'] = array( 'testFile.ics' );
    elseif( !is_array( $this->config['FILENAMES'] ))
      $this->config['FILENAMES'] = array( $this->config['FILENAMES'] );
    if( !isset( $this->config['LOCKDIR'] ) || empty( $this->config['LOCKDIR'] ))
      $this->config['LOCKDIR']   = $this->config['CALDIR'];
    elseif( FALSE === $this->checkDirectory( $this->config['LOCKDIR'] )) {
      $this->log->log( "createTestFiles (15) no write rights in '".$this->config['LOCKDIR']."', check directory!!", 2 );
      $this->log->flush();
      return FALSE;
    }
    foreach($this->config as $k => $v ) { 
      if( is_array( $v )) 
        $v = str_replace( PHP_EOL, '', var_export( $v, TRUE )); 
      $this->log->log( "$k: $v", 7 );
    }
    if( !isset( $this->config['LOCKFILE'] ) || empty( $this->config['LOCKFILE'] ))
      $this->config['LOCKFILE']  = 'tiCalFile.lck';
    $this->lockFile = $this->config['LOCKDIR'].$this->config['LOCKFILE'];
    $this->setBaseValues();
    $fileCount    = 0;
    $this->removeTime = time() - ( $this->config['CALAGE'] * 3600 );
    $this->log->log(   'checking file remove time: '.date( 'Y-m-d H:i:s', $this->removeTime ), 6 );
    if( $this->checkLockfile()) {
      foreach( $this->config['FILENAMES'] as $filename ) {
        if( $this->createTestFile( $filename ))
          $fileCount   += 1;
      }
      $this->updLockfile();
    }
    else
      $this->log->log( 'No action now due to previous lock file creation at '.date( 'Y-m-d H:i:s', $this->filemtime ), 6 );
    if( FALSE !== ( $this->fp ))
      $this->freeLockfile();
    $this->log->log( "Created $fileCount test iCal files (".number_format(( microtime( TRUE ) - $start ), 5 ).' msec)', 5 );
    $this->log->flush();
  }
            /* check and create (opt.) parameters */
  private function fixParameters( $params, $unique ) {
    $output = array();
    foreach( $params as $pkey => $pvalue ) {
      if( !$pvalue )
        continue;
      $output[$pkey] = ( 'X-' != substr( $pkey, 0, 2 )) ? $pvalue : $pvalue.$unique;
    }
    return ( empty( $output )) ? null : $output;
  }
  private function freeLockfile() {
    @flock( $this->fp, LOCK_UN);
    @fclose( $this->fp );
  }
  public function getConfig( $key ) {
    $key = strtoupper( $key );
    return ( isset( $this->config[$key] ) && !empty( $this->config[$key] )) ? $this->config[$key] : FALSE;
  }
  private function getValue( $spec ) {
    if( !isset( $this->baseValues[$spec] ) || empty( $this->baseValues[$spec] ))
      return '';
    $max = count( $this->baseValues[$spec] ) - 1;
    return $this->baseValues[$spec][mt_rand( 0, $max )];
  }
  private function setBaseValues() {
            // array to randomly select a summary from
    $this->baseValues['summaries']    = array(
      'Duis ac dui sit amet ante auctor euismod.'
    , 'Suspendisse_pellentesque_velit_in_tortor.'
    , 'Mauris vulputate.'
    , 'Nulla sapien pede, dapibus sed.'
    , 'Maecenas tristique, pede_id_sollicitudin_posuere, enim nibh mollis odio.'
    , 'Lorem ipsum dolor sit amet, consectetuerAdipiscingElit.' );
            // array to randomly select a description from
    $this->baseValues['descriptions'] = array(
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus tempus erat vel risus. Aenean augue velit, bibendum ac, porttitor ut, egestas vel, massa.'
    , 'Sed varius dignissim est. Integer venenatis, odio vel imperdiet tincidunt, felis mi consectetur quam, at consequat justo dui eu ante. Nam nec lectus.'
    , 'Aenean vel lorem sed tortor venenatis scelerisque. Integer eget felis. Sed id justo. Sed ullamcorper mauris nec eros. Praesent mattis ligula non est.'
    , 'Donec libero dolor, tincidunt vel, fermentum at, condimentum ut, ante. Nam mi. Aliquam lobortis enim at mi. Donec ornare varius turpis.'
    , 'Phasellus tempor dui nec velit. Quisque viverra, nunc vel facilisis accumsan, lorem lacus consequat libero, sed lobortis justo nisl at odio.'
    , 'Pellentesque bibendum, ipsum et rutrum volutpat, arcu libero accumsan turpis, et egestas nunc purus et erat.'  );
            // random priority, 1 to 9. HIGH (1-4), MEDIUM (5), LOW (6-9)
            // reversed prio; HIGH: weight 1, MEDIUM weight 4, LOW: weight 8
    $this->baseValues['prioArr'] = array();
    for( $r=1; $r<=9; $r++) {
      $weight = ( 5 < $r ) ? 1 : ( 5 > $r ) ? 8 : 4;
      for( $r1=1; $r1<=$weight; $r1++)
        $this->baseValues['prioArr'][] = $r;
    }
    mt_srand();
    shuffle( $this->baseValues['prioArr'] );
            // arrays to randomly select names and site from
    $sNames       = array(  'Martin', 'Bernard', 'Dubois', 'Thomas', 'Robert', 'Richard'
                          , 'Kim', 'Khan', 'Chandra', 'Nayak', 'Singh', 'Castillo', 'Diaz'
                          , 'Michel', 'Garcia', 'David', 'Bertrand', 'Roux', 'Vincent', 'Fournier'



                         );
    $fNames       = array(  'Sem', 'Sophie', 'Lucas', 'Julia', 'Milan', 'Emma', 'Daan'
                          , 'Jing', 'Li', 'Hussain', 'Wei', 'Nalda', 'Chan', 'Riel'
                          , 'Thomas', 'Sanne', 'Thijs', 'Noa', 'Jesse', 'Anna', 'Luuk'
                         );
    $sites        = array( '@kigkonsult.se', '@siteOnThe.net', '@org.org' );
    if( isset( $this->config['UNIQUE'] ) && !empty( $this->config['UNIQUE'] ))
      $sites[2]   = '@'.$this->config['UNIQUE'];
    $this->baseValues['attendees']       = array();
    $sv = $fNv = TRUE;
    foreach( $sNames as $sName ) {
      foreach( $fNames as $fName ) {
        if( $fNv )
          $fName = $fName{0};
        $sep = ( $sv ) ? '.' : '';
        $this->baseValues['attendees'][] = $fName.$sep.$sName.$sites[mt_rand( 0, 2 )];
        $fNv = !$fNv;
      }
      $sv  = !$sv;
    }
            // array to randomly select a comment from
    $this->baseValues['comments']     = array(
      'Praesent eros nibh, posuere at, hendrerit non, aliquam a, sapien. Curabitur commodo orci eget neque. Vivamus tempor posuere sapien.'
    , 'Fusce id nisl ut enim consectetur pulvinar. Ut auctor elit at lorem. Maecenas purus arcu, faucibus eu, iaculis quis, pretium quis, velit.'
    , 'Fusce vel sem quis felis dictum venenatis. Sed ipsum. Fusce vel diam sit amet sapien pretium pretium.'
    , 'Sed nunc ligula, consequat vel, facilisis eu, vulputate sed, libero. Maecenas vel augue mattis risus elementum mattis.'
    , 'Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur tempor sodales ante.');
            // arrays, rrule/exrule
    $this->baseValues['days']         = array( 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA' );
    $this->baseValues['bydays']       = array();
    $this->baseValues['bydays'][2]    = array( array( 'DAY' => 'MO' ), array( 'DAY' => 'TU' ), array( 'DAY' => 'WE' ), array( 'DAY' => 'TH' ), array( 'DAY' => 'FR' ));
    $this->baseValues['bydays'][3]    = array( array( 'DAY' => 'TU' ), array( 'DAY' => 'TH' ));
    $this->baseValues['bydays'][4]    = array( array( 'DAY' => 'MO' ), array( 'DAY' => 'WE' ), array( 'DAY' => 'FR' ));
    $this->baseValues['bydays'][5]    = array( array( 'DAY' => 'SA' ), array( 'DAY' => 'SU' ));
            // array to randomly select a status from
    $this->baseValues['status']       = array( 'TENTATIVE', 'CONFIRMED', 'CANCELLED' );
            // array to randomly select TRANSP from
    $this->baseValues['transp']       = array( 'OPAQUE', 'TRANSPARENT' );
  }
  public function setConfig( $key, $value ) {
    $this->config[strtoupper( $key )] = $value;
  }
  private function updLockfile() {
    ftruncate( $this->fp, 0 );
    fwrite( $this->fp, date( 'Y-m-d H:i:s' ));
    fflush( $this->fp );
    $this->log->log( "updLockfile: '".$this->lockFile."' ".date( 'Y-m-d H:i:s' ), 6 );
  }
}
class dummyLog {
  function log( $m, $p ) {} // { error_log( "$p: $m" );  }
  function flush() {}
}
?>
Return current item: tiCalFile