Back to index

awl  0.53
Public Member Functions | Protected Attributes | Private Attributes
vCalendar Class Reference
Inheritance diagram for vCalendar:
Inheritance graph
[legend]
Collaboration diagram for vCalendar:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 __construct ($content=null)
 Constructor.
 AddTimeZone (vComponent $vtz, $in_components=false)
 Add a timezone component to this vCalendar.
 GetTimeZone ($tzid)
 Get a timezone component for a specific TZID in this calendar.
 GetOrganizer ()
 Get the organizer of this VEVENT/VTODO.
 GetScheduleAgent ()
 Get the schedule-agent from the organizer.
 GetAttendees ()
 Get the attendees of this VEVENT/VTODO.
 UpdateAttendeeStatus ($email, vProperty $statusProperty)
 Update the attendees of this VEVENT/VTODO.
 UpdateOrganizerStatus (vProperty $statusProperty)
 Update the ORGANIZER of this VEVENT/VTODO.
 StartFilter ($filters)
 Test a PROP-FILTER or COMP-FILTER and return a true/false COMP-FILTER (is-defined | is-not-defined | (time-range?, prop-filter*, comp-filter*)) PROP-FILTER (is-defined | is-not-defined | ((time-range | text-match)?, param-filter*))
 GetOlsonName (vComponent $vtz)
 Work out what Olson timezone this VTIMEZONE really is.
 Confidential ()
 Morph this component (and subcomponents) into a confidential version of it.
 GetItip ($method, $attendee_value)
 Clone this component (and subcomponents) into a minimal iTIP version of it.
 GetUID ()
 Get the UID from the primary component.
 SetUID ($newUid)
 Set the UID on the primary component.
 CollectParameterValues ($parameter_name)
 Collect an array of all parameters of our properties which are the specified type Mainly used for collecting the full variety of references TZIDs.
 ParseFrom ($content)
 Parse the text $content into sets of vProperty & vComponent within this vComponent.
 UnwrapComponent ($content)
 This unescapes the (CRLF + linear space) wrapping specified in RFC2445.
 WrapComponent ($content)
 This imposes the (CRLF + linear space) wrapping specified in RFC2445.
 GetType ()
 Return the type of component which this is.
 SetType ($type)
 Set the type of component which this is.
 GetProperty ($type)
 Return the first instance of a property of this name.
 GetPValue ($type)
 Return the value of the first instance of a property of this name, or null.
 GetProperties ($type=null)
 Get all properties, or the properties matching a particular type, or matching an array associating property names with true values: array( 'PROPERTY' => true, 'PROPERTY2' => true )
 ClearProperties ($type=null)
 Clear all properties, or the properties matching a particular type.
 SetProperties ($new_properties, $type=null)
 Set all properties, or the ones matching a particular type.
 AddProperty ($new_property, $value=null, $parameters=null)
 Adds a new property.
 ComponentCount ()
 Return number of components.
 GetComponents ($type=null, $normal_match=true)
 Get all sub-components, or at least get those matching a type, or failling to match, should the second parameter be set to false.
 ClearComponents ($type=null)
 Clear all components, or the components matching a particular type.
 SetComponents ($new_component, $type=null)
 Sets some or all sub-components of the component to the supplied new components.
 AddComponent ($new_component)
 Adds a new subcomponent.
 MaskComponents ($keep, $recursive=true)
 Mask components, removing any that are not of the types in the list.
 MaskProperties ($keep, $component_list=null)
 Mask properties, removing any that are not in the list.
 Render ($restricted_properties=null, $force_rendering=false)
 Renders the component, possibly restricted to only the listed properties.
 __toString ()
 GetPropertiesByPath ($path)
 Return an array of properties matching the specified path.
 TestFilter ($filters)
 Test a PROP-FILTER or COMP-FILTER and return a true/false COMP-FILTER (is-defined | is-not-defined | (time-range?, prop-filter*, comp-filter*)) PROP-FILTER (is-defined | is-not-defined | ((time-range | text-match)?, param-filter*))

Protected Attributes

 $type
 $properties
 $components
 $rendered

Private Attributes

 $contained_type
 These variables are mostly used to improve efficiency by caching values as they are retrieved to speed any subsequent access.
 $primary_component
 $timezones
 $organizer
 $attendees
 

 $schedule_agent

Detailed Description

Definition at line 23 of file vCalendar.php.


Constructor & Destructor Documentation

vCalendar::__construct ( content = null)

Constructor.

If a string is passed it will be parsed as if it was an iCalendar object, otherwise a new vCalendar will be initialised with basic content. If an array of key value pairs is provided they will also be used as top-level properties.

Typically this will be used to set a METHOD property on the VCALENDAR as something like: $shinyCalendar = new vCalendar( array('METHOD' => 'REQUEST' ) );

Parameters:
mixed$contentCan be a string to be parsed, or an array of key value pairs.

Reimplemented from vComponent.

Definition at line 51 of file vCalendar.php.

                                      {
    $this->contained_type = null;
    $this->primary_component = null;
    $this->timezones = array();
    if ( empty($content) || is_array($content) ) {
      parent::__construct();
      $this->SetType('VCALENDAR');
      $this->AddProperty('PRODID', '-//davical.org//NONSGML AWL Calendar//EN');
      $this->AddProperty('VERSION', '2.0');
      $this->AddProperty('CALSCALE', 'GREGORIAN');
      if ( !empty($content) ) {
        foreach( $content AS $k => $v ) {
          $this->AddProperty($k,$v);
        }
      }
    }
    else {
      parent::__construct($content);
      foreach( $this->components AS $k => $comp ) {
        if ( $comp->GetType() == 'VTIMEZONE' ) {
          $this->AddTimeZone($comp, true);
        }
        else if ( empty($this->contained_type) ) {
          $this->contained_type = $comp->GetType();
          $this->primary_component = $comp;
        }
      }
      if ( !isset($this->contained_type) && !empty($this->timezones) )
        $this->contained_type = 'VTIMEZONE';
    }
  }

Here is the call graph for this function:


Member Function Documentation

vComponent::__toString ( ) [inherited]

Definition at line 875 of file vComponent.php.

                               {
    return $this->Render();
  }

Here is the call graph for this function:

vComponent::AddComponent ( new_component) [inherited]

Adds a new subcomponent.

Parameters:
vComponent$new_componentThe new component to append to the set

Definition at line 796 of file vComponent.php.

                                          {
    if ( is_array($new_component) && count($new_component) == 0 ) return;
    if ( isset($this->rendered) ) unset($this->rendered);
    if ( is_array($new_component) ) {
      foreach( $new_component AS $k => $v ) {
        $this->components[] = $v;
      }
    }
    else {
      $this->components[] = $new_component;
    }
  }

Here is the caller graph for this function:

vComponent::AddProperty ( new_property,
value = null,
parameters = null 
) [inherited]

Adds a new property.

Parameters:
vProperty$new_propertyThe new property to append to the set, or a string with the name
string$valueThe value of the new property (default: param 1 is an vProperty with everything
array$parametersThe key/value parameter pairs (default: none, or param 1 is an vProperty with everything)

Definition at line 693 of file vComponent.php.

                                                                           {
    if ( isset($this->rendered) ) unset($this->rendered);
    if ( isset($value) && gettype($new_property) == 'string' ) {
      $new_prop = new vProperty();
      $new_prop->Name($new_property);
      $new_prop->Value($value);
      if ( $parameters != null ) $new_prop->Parameters($parameters);
//      dbg_error_log('vComponent'," Adding new property '%s'", $new_prop->Render() );
      $this->properties[] = $new_prop;
    }
    else if ( $new_property instanceof vProperty ) {
      $this->properties[] = $new_property;
    }
  }

Here is the caller graph for this function:

vCalendar::AddTimeZone ( vComponent vtz,
in_components = false 
)

Add a timezone component to this vCalendar.

Definition at line 87 of file vCalendar.php.

                                                              {
    $tzid = $vtz->GetPValue('TZID');
    if ( empty($tzid) ) {
      dbg_error_log('ERROR','Ignoring invalid VTIMEZONE with no TZID parameter!');
      dbg_log_array('LOG', 'vTimezone', $vtz, true);
      return;
    }
    $this->timezones[$tzid] = $vtz;
    if ( !$in_components ) $this->AddComponent($vtz);
  }

Here is the call graph for this function:

Here is the caller graph for this function:

vComponent::ClearComponents ( type = null) [inherited]

Clear all components, or the components matching a particular type.

Parameters:
string$typeThe type of component - omit for all components

Definition at line 751 of file vComponent.php.

                                           {
    if ( $type != null ) {
      $testtypes = (gettype($type) == 'string' ? array( $type => true ) : $type );
      // First remove all the existing ones of that type
      foreach( $this->components AS $k => $v ) {
        if ( isset($testtypes[$v->GetType()]) && $testtypes[$v->GetType()] ) {
          unset($this->components[$k]);
          if ( isset($this->rendered) ) unset($this->rendered);
        }
        else {
          if ( ! $this->components[$k]->ClearComponents($testtypes) ) {
            if ( isset($this->rendered) ) unset($this->rendered);
          }
        }
      }
      return isset($this->rendered);
    }
    else {
      if ( isset($this->rendered) ) unset($this->rendered);
      $this->components = array();
      return false;
    }
  }

Here is the caller graph for this function:

vComponent::ClearProperties ( type = null) [inherited]

Clear all properties, or the properties matching a particular type.

Parameters:
string | array$typeThe type of property - omit for all properties - or an array associating property names with true values: array( 'PROPERTY' => true, 'PROPERTY2' => true )

Definition at line 655 of file vComponent.php.

                                           {
    if ( $type != null ) {
      $testtypes = (gettype($type) == 'string' ? array( $type => true ) : $type );
      // First remove all the existing ones of that type
      foreach( $this->properties AS $k => $v ) {
        if ( isset($testtypes[$v->Name()]) && $testtypes[$v->Name()] ) {
          unset($this->properties[$k]);
          if ( isset($this->rendered) ) unset($this->rendered);
        }
      }
      $this->properties = array_values($this->properties);
    }
    else {
      if ( isset($this->rendered) ) unset($this->rendered);
      $this->properties = array();
    }
  }

Here is the caller graph for this function:

vComponent::CollectParameterValues ( parameter_name) [inherited]

Collect an array of all parameters of our properties which are the specified type Mainly used for collecting the full variety of references TZIDs.

Definition at line 462 of file vComponent.php.

                                                     {
    $values = array();
    foreach( $this->components AS $k => $v ) {
      $also = $v->CollectParameterValues($parameter_name);
      $values = array_merge( $values, $also );
    }
    foreach( $this->properties AS $k => $v ) {
      $also = $v->GetParameterValue($parameter_name);
      if ( isset($also) && $also != "" ) {
//        dbg_error_log( 'vComponent', "::CollectParameterValues(%s) : Found '%s'", $parameter_name, $also);
        $values[$also] = 1;
      }
    }
    return $values;
  }
vComponent::ComponentCount ( ) [inherited]

Return number of components.

Definition at line 712 of file vComponent.php.

                            {
    return count($this->components);
  }

Morph this component (and subcomponents) into a confidential version of it.

A confidential event will be scrubbed of any identifying characteristics other than time/date, repeat, uid and a summary which is just a translated 'Busy'.

Definition at line 339 of file vCalendar.php.

                          {
    static $keep_properties = array( 'DTSTAMP'=>1, 'DTSTART'=>1, 'RRULE'=>1, 'DURATION'=>1, 'DTEND'=>1, 'DUE'=>1, 'UID'=>1, 'CLASS'=>1, 'TRANSP'=>1, 'CREATED'=>1, 'LAST-MODIFIED'=>1 );
    static $resource_components = array( 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 );
    $this->MaskComponents(array( 'VTIMEZONE'=>1, 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 ), false);
    $this->MaskProperties($keep_properties, $resource_components );
    if ( isset($this->rendered) ) unset($this->rendered);
    foreach( $this->components AS $comp ) {
      if ( isset($resource_components[$comp->GetType()] ) ) {
        if ( isset($comp->rendered) ) unset($comp->rendered);
        $comp->AddProperty( 'SUMMARY', translate('Busy') );
      }
    }

    return $this;
  }

Here is the call graph for this function:

Get the attendees of this VEVENT/VTODO.

Definition at line 141 of file vCalendar.php.

                          {
    if ( !isset($this->attendees) ) {
      $attendees = $this->GetPropertiesByPath('/VCALENDAR/*/ATTENDEE');
      $wr_attendees = $this->GetPropertiesByPath('/VCALENDAR/*/X-WR-ATTENDEE');
      if ( count ( $wr_attendees ) > 0 ) {
        dbg_error_log( 'PUT', 'Non-compliant iCal request.  Using X-WR-ATTENDEE property' );
        foreach( $wr_attendees AS $k => $v ) {
          $attendees[] = $v;
        }
      }
      $this->attendees = $attendees;
    }
    return $this->attendees;
  }

Here is the call graph for this function:

vComponent::GetComponents ( type = null,
normal_match = true 
) [inherited]

Get all sub-components, or at least get those matching a type, or failling to match, should the second parameter be set to false.

Component types may be a string or an array associating property names with true values: array( 'TYPE' => true, 'TYPE2' => true )

Parameters:
mixed$typeThe type(s) to match (default: All)
boolean$normal_matchSet to false to invert the match (default: true)
Returns:
array an array of the sub-components

Definition at line 726 of file vComponent.php.

                                                               {
    $components = $this->components;
    if ( $type != null ) {
      $testtypes = (gettype($type) == 'string' ? array( $type => true ) : $type );
      foreach( $components AS $k => $v ) {
//        printf( "Type: %s, %s, %s\n", $v->GetType(),
//                 ($normal_match && isset($testtypes[$v->GetType()]) && $testtypes[$v->GetType()] ? 'true':'false'),
//                 ( !$normal_match && (!isset($testtypes[$v->GetType()]) || !$testtypes[$v->GetType()]) ? 'true':'false')
//               );
        if ( !($normal_match && isset($testtypes[$v->GetType()]) && $testtypes[$v->GetType()] )
            && !( !$normal_match && (!isset($testtypes[$v->GetType()]) || !$testtypes[$v->GetType()])) ) {
          unset($components[$k]);
        }
      }
      $components = array_values($components);
    }
//    print_r($components);
    return $components;
  }

Here is the caller graph for this function:

vCalendar::GetItip ( method,
attendee_value 
)

Clone this component (and subcomponents) into a minimal iTIP version of it.

Definition at line 359 of file vCalendar.php.

                                              {
    $iTIP = clone($this);
    static $keep_properties = array( 'DTSTART'=>1, 'DURATION'=>1, 'DTEND'=>1, 'DUE'=>1, 'UID'=>1,
                                     'SEQUENCE'=>1, 'ORGANIZER'=>1, 'ATTENDEE'=>1 );
    static $resource_components = array( 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 );
    $iTIP->MaskComponents($resource_components, false);
    $iTIP->MaskProperties($keep_properties, $resource_components );
    $iTIP->AddProperty('METHOD',$method);
    if ( isset($iTIP->rendered) ) unset($iTIP->rendered);
    if ( !empty($attendee_value) ) {
      $iTIP->attendees = array();
      foreach( $iTIP->components AS $comp ) {
        if ( isset($resource_components[$comp->type] ) ) {
          foreach( $comp->properties AS $k=> $property ) {
            switch( $property->Name() ) {
              case 'ATTENDEE':
                if ( $property->Value() == $attendee_value )
                  $iTIP->attendees[] = $property;
                else
                  unset($comp->properties[$k]);
                break;
              case 'SEQUENCE':
                $property->Value( $property->Value() + 1);
                break;
            }
          }
          $comp->AddProperty('DTSTAMP', date('Ymd\THis\Z'));
        }
      }
    }
    
    return $iTIP;
  }

Work out what Olson timezone this VTIMEZONE really is.

Perhaps we should put this into a vTimezone class.

Parameters:
vComponent$vtzThe VTIMEZONE component.
Returns:
string The Olson name for the timezone.

List of Microsoft CDO Timezone IDs from here: http://msdn.microsoft.com/en-us/library/aa563018%28loband%29.aspx

Definition at line 234 of file vCalendar.php.

                                           {
    $tzstring = $vtz->GetProperty('TZID');
    $tzid = olson_from_tzstring($tzstring);
    if ( !empty($tzid) ) return $tzid;
    
    $tzstring = $vtz->GetProperty('X-LIC-LOCATION');
    $tzid = olson_from_tzstring($tzstring);
    if ( !empty($tzid) ) return $tzid;
    
    $tzcdo =  $vtz->GetProperty('X-MICROSOFT-CDO-TZID');
    if ( empty($tzcdo) ) return null;
    switch( $tzcdo ) {
      case 0:    return('UTC');
      case 1:    return('Europe/London');
      case 2:    return('Europe/Lisbon');
      case 3:    return('Europe/Paris');
      case 4:    return('Europe/Berlin');
      case 5:    return('Europe/Bucharest');
      case 6:    return('Europe/Prague');
      case 7:    return('Europe/Athens');
      case 8:    return('America/Brasilia');
      case 9:    return('America/Halifax');
      case 10:   return('America/New_York');
      case 11:   return('America/Chicago');
      case 12:   return('America/Denver');
      case 13:   return('America/Los_Angeles');
      case 14:   return('America/Anchorage');
      case 15:   return('Pacific/Honolulu');
      case 16:   return('Pacific/Apia');
      case 17:   return('Pacific/Auckland');
      case 18:   return('Australia/Brisbane');
      case 19:   return('Australia/Adelaide');
      case 20:   return('Asia/Tokyo');
      case 21:   return('Asia/Singapore');
      case 22:   return('Asia/Bangkok');
      case 23:   return('Asia/Kolkata');
      case 24:   return('Asia/Muscat');
      case 25:   return('Asia/Tehran');
      case 26:   return('Asia/Baghdad');
      case 27:   return('Asia/Jerusalem');
      case 28:   return('America/St_Johns');
      case 29:   return('Atlantic/Azores');
      case 30:   return('America/Noronha');
      case 31:   return('Africa/Casablanca');
      case 32:   return('America/Argentina/Buenos_Aires');
      case 33:   return('America/La_Paz');
      case 34:   return('America/Indiana/Indianapolis');
      case 35:   return('America/Bogota');
      case 36:   return('America/Regina');
      case 37:   return('America/Tegucigalpa');
      case 38:   return('America/Phoenix');
      case 39:   return('Pacific/Kwajalein');
      case 40:   return('Pacific/Fiji');
      case 41:   return('Asia/Magadan');
      case 42:   return('Australia/Hobart');
      case 43:   return('Pacific/Guam');
      case 44:   return('Australia/Darwin');
      case 45:   return('Asia/Shanghai');
      case 46:   return('Asia/Novosibirsk');
      case 47:   return('Asia/Karachi');
      case 48:   return('Asia/Kabul');
      case 49:   return('Africa/Cairo');
      case 50:   return('Africa/Harare');
      case 51:   return('Europe/Moscow');
      case 53:   return('Atlantic/Cape_Verde');
      case 54:   return('Asia/Yerevan');
      case 55:   return('America/Panama');
      case 56:   return('Africa/Nairobi');
      case 58:   return('Asia/Yekaterinburg');
      case 59:   return('Europe/Helsinki');
      case 60:   return('America/Godthab');
      case 61:   return('Asia/Rangoon');
      case 62:   return('Asia/Kathmandu');
      case 63:   return('Asia/Irkutsk');
      case 64:   return('Asia/Krasnoyarsk');
      case 65:   return('America/Santiago');
      case 66:   return('Asia/Colombo');
      case 67:   return('Pacific/Tongatapu');
      case 68:   return('Asia/Vladivostok');
      case 69:   return('Africa/Ndjamena');
      case 70:   return('Asia/Yakutsk');
      case 71:   return('Asia/Dhaka');
      case 72:   return('Asia/Seoul');
      case 73:   return('Australia/Perth');
      case 74:   return('Asia/Riyadh');
      case 75:   return('Asia/Taipei');
      case 76:   return('Australia/Sydney');

      case 57: // null
      case 52: // null
      default: // null
    }
    return null;
  }   

Here is the call graph for this function:

Get the organizer of this VEVENT/VTODO.

Returns:
vProperty The Organizer property.

Definition at line 114 of file vCalendar.php.

                          {
    if ( !isset($this->organizer) ) {
      $organizers = $this->GetPropertiesByPath('/VCALENDAR/*/ORGANIZER');
      $organizer = (count($organizers) > 0 ? $organizers[0] : false);
      $this->organizer = (empty($organizer) ? false : $organizer );
      if ( $this->organizer ) {
        $this->schedule_agent = $organizer->GetParameterValue('SCHEDULE-AGENT');
        if ( empty($schedule_agent) ) $this->schedule_agent = 'SERVER';
      }
    }
    return $this->organizer;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

vComponent::GetProperties ( type = null) [inherited]

Get all properties, or the properties matching a particular type, or matching an array associating property names with true values: array( 'PROPERTY' => true, 'PROPERTY2' => true )

Definition at line 638 of file vComponent.php.

                                         {
    $properties = array();
    $testtypes = (gettype($type) == 'string' ? array( $type => true ) : $type );
    foreach( $this->properties AS $k => $v ) {
      if ( $type == null || (isset($testtypes[$v->Name()]) && $testtypes[$v->Name()]) ) {
        $properties[] = $v;
      }
    }
    return $properties;
  }

Here is the caller graph for this function:

vComponent::GetPropertiesByPath ( path) [inherited]

Return an array of properties matching the specified path.

Returns:
array An array of vProperty within the tree which match the path given, in the form [/]COMPONENT[/...]/PROPERTY in a syntax kind of similar to our poor man's XML queries. We also allow COMPONENT and PROPERTY to be !COMPONENT and !PROPERTY for ++fun.
Note:
At some point post PHP4 this could be re-done with an iterator, which should be more efficient for common use cases.

There is more to the path, so we recurse into that sub-part

Our input $path was not rooted, so we recurse further

Definition at line 889 of file vComponent.php.

                                        {
    $properties = array();
    dbg_error_log( 'vComponent', "GetPropertiesByPath: Querying within '%s' for path '%s'", $this->type, $path );
    if ( !preg_match( '#(/?)(!?)([^/]+)(/?.*)$#', $path, $matches ) ) return $properties;

    $anchored = ($matches[1] == '/');
    $inverted = ($matches[2] == '!');
    $ourtest = $matches[3];
    $therest = $matches[4];
    dbg_error_log( 'vComponent', "GetPropertiesByPath: Matches: %s -- %s -- %s -- %s\n", $matches[1], $matches[2], $matches[3], $matches[4] );
    if ( $ourtest == '*' || (($ourtest == $this->type) !== $inverted) && $therest != '' ) {
      if ( preg_match( '#^/(!?)([^/]+)$#', $therest, $matches ) ) {
        $normmatch = ($matches[1] =='');
        $proptest  = $matches[2];
        foreach( $this->properties AS $k => $v ) {
          if ( $proptest == '*' || (($v->Name() == $proptest) === $normmatch ) ) {
            $properties[] = $v;
          }
        }
      }
      else {
        foreach( $this->components AS $k => $v ) {
          $properties = array_merge( $properties, $v->GetPropertiesByPath($therest) );
        }
      }
    }

    if ( ! $anchored ) {
      foreach( $this->components AS $k => $v ) {
        $properties = array_merge( $properties, $v->GetPropertiesByPath($path) );
      }
    }
    dbg_error_log('vComponent', "GetPropertiesByPath: Found %d within '%s' for path '%s'\n", count($properties), $this->type, $path );
    return $properties;
  }

Here is the caller graph for this function:

vComponent::GetProperty ( type) [inherited]

Return the first instance of a property of this name.

So we can call methods on the result of this, make sure we always return a vProperty of some kind

Definition at line 610 of file vComponent.php.

                                {
    foreach( $this->properties AS $k => $v ) {
      if ( is_object($v) && $v->Name() == $type ) {
        return $v;
      }
      else if ( !is_object($v) ) {
        debug_error_log("ERROR", 'vComponent::GetProperty(): Trying to get %s on %s which is not an object!', $type, $v );
      }
    }
    return null;
  }

Here is the caller graph for this function:

vComponent::GetPValue ( type) [inherited]

Return the value of the first instance of a property of this name, or null.

Definition at line 627 of file vComponent.php.

                              {
    $p = $this->GetProperty($type);
    if ( isset($p) ) return $p->Value();
    return null;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Get the schedule-agent from the organizer.

Returns:
vProperty The schedule-agent parameter

Definition at line 132 of file vCalendar.php.

                              {
    if ( !isset($this->schedule_agent) ) $this->GetOrganizer();
    return $this->schedule_agent;
  }

Here is the call graph for this function:

Get a timezone component for a specific TZID in this calendar.

Parameters:
string$tzidThe TZID for the timezone to be retrieved.
Returns:
vComponent The timezone as a vComponent.

Definition at line 104 of file vCalendar.php.

                                {
    if ( empty($this->timezones[$tzid]) ) return null;
    return $this->timezones[$tzid];
  }
vComponent::GetType ( ) [inherited]

Return the type of component which this is.

Definition at line 592 of file vComponent.php.

                     {
    return $this->type;
  }

Get the UID from the primary component.

Definition at line 397 of file vCalendar.php.

                    {
    if ( empty($this->primary_component) ) return null;
    return $this->primary_component->GetPValue('UID');
    
  }
vComponent::MaskComponents ( keep,
recursive = true 
) [inherited]

Mask components, removing any that are not of the types in the list.

Parameters:
array$keepAn array of component types to be kept
boolean$recursive(default true) Whether to recursively MaskComponents on the ones we find

Definition at line 815 of file vComponent.php.

                                                      {
    foreach( $this->components AS $k => $v ) {
      if ( !isset($keep[$v->GetType()]) ) {
        unset($this->components[$k]);
        if ( isset($this->rendered) ) unset($this->rendered);
      }
      else if ( $recursive ) {
        $v->MaskComponents($keep);
      }
    }
  }

Here is the caller graph for this function:

vComponent::MaskProperties ( keep,
component_list = null 
) [inherited]

Mask properties, removing any that are not in the list.

Parameters:
array$keepAn array of property names to be kept
array$component_listAn array of component types to check within

Definition at line 833 of file vComponent.php.

                                                         {
    if ( !isset($component_list) || isset($component_list[$this->type]) ) {
      foreach( $this->properties AS $k => $v ) {
        if ( !isset($keep[$v->Name()]) || !$keep[$v->Name()] ) {
          unset($this->properties[$k]);
          if ( isset($this->rendered) ) unset($this->rendered);
        }
      }
    }
    foreach( $this->components AS $k => $v ) {
      $v->MaskProperties($keep, $component_list);
    }
  }

Here is the caller graph for this function:

vComponent::ParseFrom ( content) [inherited]

Parse the text $content into sets of vProperty & vComponent within this vComponent.

Parameters:
string$contentThe raw RFC2445-compliant vComponent component, including BEGIN:TYPE & END:TYPE

Definition at line 483 of file vComponent.php.

                                 {
    $this->rendered = $content;
    $content = $this->UnwrapComponent($content);

    $type = false;
    $subtype = false;
    $finish = null;
    $subfinish = null;

    $length = strlen($content);
    $linefrom = 0;
    while( $linefrom < $length ) {
      $lineto = strpos( $content, "\n", $linefrom );
      if ( $lineto === false ) {
        $lineto = strpos( $content, "\r", $linefrom );
      }
      if ( $lineto > 0 ) {
        $line = substr( $content, $linefrom, $lineto - $linefrom);
        $linefrom = $lineto + 1;
      }
      else {
        $line = substr( $content, $linefrom );
        $linefrom = $length;
      }
      if ( preg_match('/^\s*$/', $line ) ) continue;
      $line = rtrim( $line, "\r\n" );
//      dbg_error_log( 'vComponent',  "::ParseFrom: Parsing line: $line");

      if ( $type === false ) {
        if ( preg_match( '/^BEGIN:(.+)$/i', $line, $matches ) ) {
          // We have found the start of the main component
          $type = strtoupper($matches[1]);
          $finish = 'END:'.$type;
          $this->type = $type;
//          dbg_error_log( 'vComponent', "::ParseFrom: Start component of type '%s'", $type);
        }
        else {
          dbg_error_log( 'vComponent', "::ParseFrom: Ignoring crap before start of component: $line");
          // unset($lines[$k]);  // The content has crap before the start
          if ( $line != "" ) $this->rendered = null;
        }
      }
      else if ( $type == null ) {
        dbg_error_log( 'vComponent', "::ParseFrom: Ignoring crap after end of component");
        if ( $line != "" ) $this->rendered = null;
      }
      else if ( strtoupper($line) == $finish ) {
//        dbg_error_log( 'vComponent', "::ParseFrom: End of component");
        $type = null;  // We have reached the end of our component
      }
      else {
        if ( $subtype === false && preg_match( '/^BEGIN:(.+)$/i', $line, $matches ) ) {
          // We have found the start of a sub-component
          $subtype = strtoupper($matches[1]);
          $subfinish = "END:$subtype";
          $subcomponent = $line . "\r\n";
//          dbg_error_log( 'vComponent', "::ParseFrom: Found a subcomponent '%s'", $subtype);
        }
        else if ( $subtype ) {
          // We are inside a sub-component
          $subcomponent .= $this->WrapComponent($line);
          if ( strtoupper($line) == $subfinish ) {
//            dbg_error_log( 'vComponent', "::ParseFrom: End of subcomponent '%s'", $subtype);
            // We have found the end of a sub-component
            $this->components[] = new vComponent($subcomponent);
            $subtype = false;
          }
//          else
//            dbg_error_log( 'vComponent', "::ParseFrom: Inside a subcomponent '%s'", $subtype );
        }
        else {
//          dbg_error_log( 'vComponent', "::ParseFrom: Parse property of component");
          // It must be a normal property line within a component.
          $this->properties[] = new vProperty($line);
        }
      }
    }
  }

Here is the call graph for this function:

Here is the caller graph for this function:

vComponent::Render ( restricted_properties = null,
force_rendering = false 
) [inherited]

Renders the component, possibly restricted to only the listed properties.

Definition at line 851 of file vComponent.php.

                                                                             {

    $unrestricted = (!isset($restricted_properties) || count($restricted_properties) == 0);

    if ( !$force_rendering && isset($this->rendered) && $unrestricted )
      return $this->rendered;

    $rendered = "BEGIN:$this->type\r\n";
    foreach( $this->properties AS $k => $v ) {
      if ( method_exists($v, 'Render') ) {
        if ( $unrestricted || isset($restricted_properties[$v]) ) $rendered .= $v->Render() . "\r\n";
      }
    }
    foreach( $this->components AS $v ) {   $rendered .= $v->Render( $restricted_properties, $force_rendering );  }
    $rendered .= "END:$this->type\r\n";

    $rendered = preg_replace('{(?<!\r)\n}', "\r\n", $rendered);
    if ( $unrestricted ) $this->rendered = $rendered;

    return $rendered;
  }

Here is the caller graph for this function:

vComponent::SetComponents ( new_component,
type = null 
) [inherited]

Sets some or all sub-components of the component to the supplied new components.

Parameters:
arrayof vComponent $new_components The new components to replace the existing ones
string$typeThe type of components to be replaced. Defaults to null, which means all components will be replaced.

Definition at line 782 of file vComponent.php.

                                                         {
    if ( isset($this->rendered) ) unset($this->rendered);
    $this->ClearComponents($type);
    foreach( $new_component AS $k => $v ) {
      $this->components[] = $v;
    }
  }

Here is the call graph for this function:

vComponent::SetProperties ( new_properties,
type = null 
) [inherited]

Set all properties, or the ones matching a particular type.

Definition at line 677 of file vComponent.php.

                                                          {
    if ( isset($this->rendered) && count($new_properties) > 0 ) unset($this->rendered);
    $this->ClearProperties($type);
    foreach( $new_properties AS $k => $v ) {
      $this->properties[] = $v;
    }
  }

Here is the call graph for this function:

vComponent::SetType ( type) [inherited]

Set the type of component which this is.

Definition at line 600 of file vComponent.php.

                            {
    if ( isset($this->rendered) ) unset($this->rendered);
    $this->type = strtoupper($type);
    return $this->type;
  }

Here is the caller graph for this function:

vCalendar::SetUID ( newUid)

Set the UID on the primary component.

Parameters:
stringnewUid

Definition at line 408 of file vCalendar.php.

                             {
    if ( empty($this->primary_component) ) return;
    $this->primary_component->SetProperties( array( new vProperty('UID', $newUid) ), 'UID');
  }
vCalendar::StartFilter ( filters)

Test a PROP-FILTER or COMP-FILTER and return a true/false COMP-FILTER (is-defined | is-not-defined | (time-range?, prop-filter*, comp-filter*)) PROP-FILTER (is-defined | is-not-defined | ((time-range | text-match)?, param-filter*))

Parameters:
array$filterAn array of XMLElement defining the filter
Returns:
boolean Whether or not this vCalendar passes the test

Definition at line 216 of file vCalendar.php.

                                   {
    dbg_error_log('vCalendar', ':StartFilter we have %d filters to test', count($filters) );

    if ( count($filters) != 1 ) return false;
    
    $tag = $filters[0]->GetNSTag();
    $name = $filters[0]->GetAttribute("name");
    if ( $tag != "urn:ietf:params:xml:ns:caldav:comp-filter" || $name != 'VCALENDAR' ) return false;
    return $this->TestFilter($filters[0]->GetContent());
  }

Here is the call graph for this function:

vComponent::TestFilter ( filters) [inherited]

Test a PROP-FILTER or COMP-FILTER and return a true/false COMP-FILTER (is-defined | is-not-defined | (time-range?, prop-filter*, comp-filter*)) PROP-FILTER (is-defined | is-not-defined | ((time-range | text-match)?, param-filter*))

Parameters:
array$filterAn array of XMLElement defining the filter
Returns:
boolean Whether or not this vComponent passes the test

Definition at line 942 of file vComponent.php.

                                  {
    foreach( $filters AS $k => $v ) {
      $tag = $v->GetNSTag();
//      dbg_error_log( 'vCalendar', ":TestFilter: '%s' ", $tag );
      switch( $tag ) {
        case 'urn:ietf:params:xml:ns:caldav:is-defined':
        case 'urn:ietf:params:xml:ns:carddav:is-defined':
          if ( count($this->properties) == 0 && count($this->components) == 0 ) return false;
          break;
        
        case 'urn:ietf:params:xml:ns:caldav:is-not-defined':
        case 'urn:ietf:params:xml:ns:carddav:is-not-defined':
          if ( count($this->properties) > 0 || count($this->components) > 0 ) return false;
          break;

        case 'urn:ietf:params:xml:ns:caldav:comp-filter':
        case 'urn:ietf:params:xml:ns:carddav:comp-filter':
          $subcomponents = $this->GetComponents($v->GetAttribute('name'));
          $subfilter = $v->GetContent();
//          dbg_error_log( 'vCalendar', ":TestFilter: Found '%d' (of %d) subs of type '%s'",
//                       count($subcomponents), count($this->components), $v->GetAttribute('name') );
          $subtag = $subfilter[0]->GetNSTag(); 
          if ( $subtag == 'urn:ietf:params:xml:ns:caldav:is-not-defined'
                             || $subtag == 'urn:ietf:params:xml:ns:carddav:is-not-defined' ) {
            if ( count($properties) > 0 ) {
//              dbg_error_log( 'vComponent', ":TestFilter: Wanted none => false" );
              return false;
            }
          }
          else if ( count($subcomponents) == 0 ) {
            if ( $subtag == 'urn:ietf:params:xml:ns:caldav:is-defined'
                             || $subtag == 'urn:ietf:params:xml:ns:carddav:is-defined' ) {
//              dbg_error_log( 'vComponent', ":TestFilter: Wanted some => false" );
              return false;
            }
            else {
//              dbg_error_log( 'vCalendar', ":TestFilter: Wanted something from missing sub-components => false" );
              $negate = $subfilter[0]->GetAttribute("negate-condition");
              if ( empty($negate) || strtolower($negate) != 'yes' ) return false;
            }
          }
          else {
            foreach( $subcomponents AS $kk => $subcomponent ) {
              if ( ! $subcomponent->TestFilter($subfilter) ) return false;
            }
          }
          break;

        case 'urn:ietf:params:xml:ns:carddav:prop-filter':
        case 'urn:ietf:params:xml:ns:caldav:prop-filter':
          $subfilter = $v->GetContent();
          $properties = $this->GetProperties($v->GetAttribute("name"));
          dbg_error_log( 'vCalendar', ":TestFilter: Found '%d' props of type '%s'", count($properties), $v->GetAttribute('name') );
          $subtag = $subfilter[0]->GetNSTag();
          if ( $subtag == 'urn:ietf:params:xml:ns:caldav:is-not-defined'
                             || $subtag == 'urn:ietf:params:xml:ns:carddav:is-not-defined' ) {
            if ( count($properties) > 0 ) {
//              dbg_error_log( 'vCalendar', ":TestFilter: Wanted none => false" );
              return false;
            }
          }
          else if ( count($properties) == 0 ) {
            if ( $subtag == 'urn:ietf:params:xml:ns:caldav:is-defined'
                             || $subtag == 'urn:ietf:params:xml:ns:carddav:is-defined' ) {
//              dbg_error_log( 'vCalendar', ":TestFilter: Wanted some => false" );
              return false;
            }
            else {
//              dbg_error_log( 'vCalendar', ":TestFilter: Wanted '%s' from missing sub-properties => false", $subtag );
              $negate = $subfilter[0]->GetAttribute("negate-condition");
              if ( empty($negate) || strtolower($negate) != 'yes' ) return false;
            }
          }
          else {
            foreach( $properties AS $kk => $property ) {
              if ( !$property->TestFilter($subfilter) ) return false;
            }
          }
          break;
      }
    }
    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

vComponent::UnwrapComponent ( content) [inherited]

This unescapes the (CRLF + linear space) wrapping specified in RFC2445.

According to RFC2445 we should always end with CRLF but the CalDAV spec says that normalising XML parsers often muck with it and may remove the CR. We accept either case.

Definition at line 568 of file vComponent.php.

                                       {
    return preg_replace('/\r?\n[ \t]/', '', $content );
  }

Here is the caller graph for this function:

vCalendar::UpdateAttendeeStatus ( email,
vProperty statusProperty 
)

Update the attendees of this VEVENT/VTODO.

Parameters:
string$emailThe e-mail address of the attendee to be updated.
vProperty$statusPropertyA replacement property.

Definition at line 163 of file vCalendar.php.

                                                                     {
    foreach($this->components AS $ck => $v ) {
      if ($v->GetType() == 'VEVENT' || $v->GetType() == 'VTODO' ) {
        $new_attendees = array();
        foreach( $v->properties AS $p ) {
          if ( $p->Name() == 'ATTENDEE' ) {
            if ( $p->Value() == $email || $p->Value() == 'mailto:'.$email ) {
              $new_attendees[] = $statusProperty;
            }
            else {
              $new_attendees[] = clone($p);
            }
          }
        }
        $v->SetProperties($new_attendees,'ATTENDEE');
        $this->attendees = null;
        $this->rendered = null;
      }
    }
  }

Update the ORGANIZER of this VEVENT/VTODO.

Parameters:
vProperty$statusPropertyA replacement property.

Definition at line 190 of file vCalendar.php.

                                                              {
    $this->rendered = null;
    foreach($this->components AS $ck => $v ) {
      if ($v->GetType() == 'VEVENT' || $v->GetType() == 'VTODO' ) {
        foreach( $v->properties AS $pk => $p ) {
          if ( $p->Name() == 'ORGANIZER' ) {
            $v->properties[$pk] = $statusProperty;
            $v->rendered = null;
            unset($this->organizer);
          }
        }
      }
    }
  }
vComponent::WrapComponent ( content) [inherited]

This imposes the (CRLF + linear space) wrapping specified in RFC2445.

According to RFC2445 we should always end with CRLF but the CalDAV spec says that normalising XML parsers often muck with it and may remove the CR. We output RFC2445 compliance.

In order to preserve pre-existing wrapping in the component, we split the incoming string on line breaks before running wordwrap over each component of that.

Definition at line 580 of file vComponent.php.

                                     {
    $strs = preg_split( "/\r?\n/", $content );
    $wrapped = "";
    foreach ($strs as $str) {
      $wrapped .= preg_replace( '/(.{72})/u', '$1'."\r\n ", $str ) ."\r\n";
    }
    return $wrapped;
  }

Here is the caller graph for this function:


Member Data Documentation

array vCalendar::$attendees [private]

Definition at line 38 of file vCalendar.php.

vComponent::$components [protected, inherited]

Definition at line 433 of file vComponent.php.

string vCalendar::$contained_type [private]

These variables are mostly used to improve efficiency by caching values as they are retrieved to speed any subsequent access.

Definition at line 34 of file vCalendar.php.

string vCalendar::$organizer [private]

Definition at line 37 of file vCalendar.php.

Definition at line 35 of file vCalendar.php.

vComponent::$properties [protected, inherited]

Definition at line 426 of file vComponent.php.

vComponent::$rendered [protected, inherited]

Definition at line 440 of file vComponent.php.

Definition at line 39 of file vCalendar.php.

array vCalendar::$timezones [private]

Definition at line 36 of file vCalendar.php.

vComponent::$type [protected, inherited]

Definition at line 419 of file vComponent.php.


The documentation for this class was generated from the following file: