Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/bennu/iCalendar_properties.php
Go to the documentation of this file.
00001 <?php
00002 
00016 class iCalendar_property {
00017     // Properties can have parameters, but cannot have other properties or components
00018 
00019     var $parent_component = NULL;
00020     var $value            = NULL;
00021     var $parameters       = NULL;
00022     var $valid_parameters = NULL;
00023 
00024     // These are common for 95% of properties, so define them here and override as necessary
00025     var $val_multi        = false;
00026     var $val_default      = NULL;
00027 
00028     function __construct() {
00029         $this->parameters = array();
00030     }
00031 
00032     // If some property needs extra care with its parameters, override this
00033     // IMPORTANT: the parameter name MUST BE CAPITALIZED!
00034     function is_valid_parameter($parameter, $value) {
00035 
00036         if(is_array($value)) {
00037             if(!iCalendar_parameter::multiple_values_allowed($parameter)) {
00038                 return false;
00039             }
00040             foreach($value as $item) {
00041                 if(!iCalendar_parameter::is_valid_value($this, $parameter, $item)) {
00042                     return false;
00043                 }
00044             }
00045             return true;
00046         }
00047 
00048         return iCalendar_parameter::is_valid_value($this, $parameter, $value);
00049     }
00050 
00051     function invariant_holds() {
00052         return true;
00053     }
00054 
00055     // If some property is very picky about its values, it should do the work itself
00056     // Only data type validation is done here
00057     function is_valid_value($value) {
00058         if(is_array($value)) {
00059             if(!$this->val_multi) {
00060                 return false;
00061             }
00062             else {
00063                 foreach($value as $oneval) {
00064                     if(!rfc2445_is_valid_value($oneval, $this->val_type)) {
00065                         return false;
00066                     }
00067                 }
00068             }
00069             return true;
00070         }
00071         return rfc2445_is_valid_value($value, $this->val_type);
00072     }
00073 
00074     function default_value() {
00075         return $this->val_default;
00076     }
00077 
00078     function set_parent_component($componentname) {
00079         if(class_exists('iCalendar_'.strtolower(substr($componentname, 1)))) {
00080             $this->parent_component = strtoupper($componentname);
00081             return true;
00082         }
00083 
00084         return false;
00085     }
00086 
00087     function set_value($value) {
00088         if($this->is_valid_value($value)) {
00089             // This transparently formats any value type according to the iCalendar specs
00090             if(is_array($value)) {
00091                 foreach($value as $key => $item) {
00092                     $value[$key] = rfc2445_do_value_formatting($item, $this->val_type);
00093                 }
00094                 $this->value = implode(',', $value);
00095             }
00096             else {
00097                 $this->value = rfc2445_do_value_formatting($value, $this->val_type);
00098             }
00099             
00100             return true;
00101         }
00102         return false;
00103     }
00104 
00105     function get_value() {
00106         // First of all, assume that we have multiple values
00107         $valarray = explode('\\,', $this->value);
00108 
00109         // Undo transparent formatting
00110         $replace_function = create_function('$a', 'return rfc2445_undo_value_formatting($a, '.$this->val_type.');');
00111         $valarray = array_map($replace_function, $valarray);
00112 
00113         // Now, if this property cannot have multiple values, don't return as an array
00114         if(!$this->val_multi) {
00115             return $valarray[0];
00116         }
00117 
00118         // Otherwise return an array even if it has one element, for uniformity
00119         return $valarray;
00120 
00121     }
00122 
00123     function set_parameter($name, $value) {
00124 
00125         // Uppercase
00126         $name = strtoupper($name);
00127 
00128         // Are we trying to add a valid parameter?
00129         $xname = false;
00130         if(!isset($this->valid_parameters[$name])) {
00131             // If not, is it an x-name as per RFC 2445?
00132             if(!rfc2445_is_xname($name)) {
00133                 return false;
00134             }
00135             // No more checks -- all components are supposed to allow x-name parameters
00136             $xname = true;
00137         }
00138 
00139         if(!$this->is_valid_parameter($name, $value)) {
00140             return false;
00141         }
00142 
00143         if(is_array($value)) {
00144             foreach($value as $key => $element) {
00145                 $value[$key] = iCalendar_parameter::do_value_formatting($name, $element);
00146             }
00147         }
00148         else {
00149             $value = iCalendar_parameter::do_value_formatting($name, $value);
00150         }
00151 
00152         $this->parameters[$name] = $value;
00153 
00154         // Special case: if we just changed the VALUE parameter, reflect this
00155         // in the object's status so that it only accepts correct type values
00156         if($name == 'VALUE') {
00157             // TODO: what if this invalidates an already-set value?
00158             $this->val_type = constant('RFC2445_TYPE_'.str_replace('-', '_', $value));
00159         }
00160 
00161         return true;
00162 
00163     }
00164 
00165     function get_parameter($name) {
00166 
00167         // Uppercase
00168         $name = strtoupper($name);
00169 
00170         if(isset($this->parameters[$name])) {
00171             // If there are any double quotes in the value, invisibly strip them
00172             if(is_array($this->parameters[$name])) {
00173                 foreach($this->parameters[$name] as $key => $value) {
00174                     if(substr($value, 0, 1) == '"') {
00175                        $this->parameters[$name][$key] = substr($value, 1, strlen($value) - 2);
00176                     }
00177                 }
00178                 return $this->parameters[$name];
00179             }
00180 
00181             else {
00182                 if(substr($this->parameters[$name], 0, 1) == '"') {
00183                     return substr($this->parameters[$name], 1, strlen($this->parameters[$name]) - 2);
00184                 }
00185             }
00186         }
00187 
00188         return NULL;
00189     }
00190 
00191     function serialize() {
00192         $string = $this->name;
00193 
00194         if(!empty($this->parameters)) {
00195             foreach($this->parameters as $name => $value) {
00196                 $string .= ';'.$name.'=';
00197                 if(is_array($value)) {
00198                     $string .= implode(',', $value);
00199                 }
00200                 else {
00201                     $string .= $value;
00202                 }
00203             }
00204         }
00205 
00206         $string .= ':'.$this->value;
00207 
00208         return rfc2445_fold($string) . RFC2445_CRLF;
00209     }
00210 }
00211 
00212 // 4.7 Calendar Properties
00213 // -----------------------
00214 
00215 class iCalendar_property_calscale extends iCalendar_property {
00216 
00217     var $name        = 'CALSCALE';
00218     var $val_type    = RFC2445_TYPE_TEXT;
00219 
00220     function __construct() {
00221         parent::__construct();
00222         $this->valid_parameters = array(
00223             RFC2445_XNAME => RFC2445_OPTIONAL
00224         );
00225     }
00226 
00227     function is_valid_value($value) {
00228         // This is case-sensitive
00229         return ($value === 'GREGORIAN');
00230     }
00231 }
00232 
00233 class iCalendar_property_method extends iCalendar_property {
00234 
00235     var $name        = 'METHOD';
00236     var $val_type    = RFC2445_TYPE_TEXT;
00237 
00238     function __construct() {
00239         parent::__construct();
00240         $this->valid_parameters = array(
00241             RFC2445_XNAME => RFC2445_OPTIONAL
00242         );
00243     }
00244 
00245     function is_valid_value($value) {
00246         // This is case-sensitive
00247         // Methods from RFC 2446
00248         $methods = array('PUBLISH', 'REQUEST', 'REPLY', 'ADD', 'CANCEL', 'REFRESH', 'COUNTER', 'DECLINECOUNTER');
00249         return in_array($value, $methods);
00250     }
00251 }
00252 
00253 class iCalendar_property_prodid extends iCalendar_property {
00254 
00255     var $name        = 'PRODID';
00256     var $val_type    = RFC2445_TYPE_TEXT;
00257     var $val_default = NULL;
00258 
00259     function __construct() {
00260         parent::__construct();
00261         $this->val_default = '-//John Papaioannou/NONSGML Bennu '._BENNU_VERSION.'//EN';
00262 
00263         $this->valid_parameters = array(
00264             RFC2445_XNAME => RFC2445_OPTIONAL
00265         );
00266     }
00267 }
00268 
00269 class iCalendar_property_version extends iCalendar_property {
00270 
00271     var $name        = 'VERSION';
00272     var $val_type    = RFC2445_TYPE_TEXT;
00273     var $val_default = '2.0';
00274 
00275     function __construct() {
00276         parent::__construct();
00277         $this->valid_parameters = array(
00278             RFC2445_XNAME => RFC2445_OPTIONAL
00279         );
00280     }
00281 
00282     function is_valid_value($value) {
00283         return($value === '2.0' || $value === 2.0);
00284     }
00285 
00286 }
00287 
00288 // 4.8.1 Descriptive Component Properties
00289 // --------------------------------------
00290 
00291 class iCalendar_property_attach extends iCalendar_property {
00292 
00293     var $name        = 'ATTACH';
00294     var $val_type    = RFC2445_TYPE_URI;
00295 
00296     function __construct() {
00297         parent::__construct();
00298         $this->valid_parameters = array(
00299             'FMTTYPE'     => RFC2445_OPTIONAL | RFC2445_ONCE,
00300             'ENCODING'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00301             'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00302             RFC2445_XNAME => RFC2445_OPTIONAL
00303         );
00304     }
00305 
00306     function invariant_holds() {
00307         if(isset($this->parameters['ENCODING']) && !isset($this->parameters['VALUE'])) {
00308             return false;
00309         }
00310         if(isset($this->parameters['VALUE']) && !isset($this->parameters['ENCODING'])) {
00311             return false;
00312         }
00313 
00314         return true;
00315     }
00316 
00317     function is_valid_parameter($parameter, $value) {
00318 
00319         $parameter = strtoupper($parameter);
00320 
00321         if(!parent::is_valid_parameter($parameter, $value)) {
00322             return false;
00323         }
00324 
00325         if($parameter === 'ENCODING' && strtoupper($value) != 'BASE64') {
00326             return false;
00327         }
00328 
00329         if($parameter === 'VALUE' && strtoupper($value) != 'BINARY') {
00330             return false;
00331         }
00332 
00333         return true;
00334     }
00335 }
00336 
00337 class iCalendar_property_categories extends iCalendar_property {
00338 
00339     var $name        = 'CATEGORIES';
00340     var $val_type    = RFC2445_TYPE_TEXT;
00341     var $val_multi   = true;
00342 
00343     function __construct() {
00344         parent::__construct();
00345         $this->valid_parameters = array(
00346             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00347             RFC2445_XNAME => RFC2445_OPTIONAL
00348         );
00349     }
00350 }
00351 
00352 class iCalendar_property_class extends iCalendar_property {
00353 
00354     var $name        = 'CLASS';
00355     var $val_type    = RFC2445_TYPE_TEXT;
00356     var $val_default = 'PUBLIC';
00357 
00358     function __construct() {
00359         parent::__construct();
00360         $this->valid_parameters = array(
00361             RFC2445_XNAME => RFC2445_OPTIONAL
00362         );
00363     }
00364 
00365     function is_valid_value($value) {
00366         // If this is not an xname, it is case-sensitive
00367         return ($value === 'PUBLIC' || $value === 'PRIVATE' || $value === 'CONFIDENTIAL' || rfc2445_is_xname(strtoupper($value)));
00368     }
00369 }
00370 
00371 class iCalendar_property_comment extends iCalendar_property {
00372 
00373     var $name        = 'COMMENT';
00374     var $val_type    = RFC2445_TYPE_TEXT;
00375 
00376     function __construct() {
00377         parent::__construct();
00378         $this->valid_parameters = array(
00379             'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00380             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00381             RFC2445_XNAME => RFC2445_OPTIONAL
00382         );
00383     }
00384 }
00385 
00386 class iCalendar_property_description extends iCalendar_property {
00387 
00388     var $name        = 'DESCRIPTION';
00389     var $val_type    = RFC2445_TYPE_TEXT;
00390 
00391     function __construct() {
00392         parent::__construct();
00393         $this->valid_parameters = array(
00394             'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00395             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00396             RFC2445_XNAME => RFC2445_OPTIONAL
00397         );
00398     }
00399 }
00400 
00401 class iCalendar_property_geo extends iCalendar_property {
00402 
00403     var $name        = 'GEO';
00404     var $val_type    = RFC2445_TYPE_TEXT;
00405 
00406     function __construct() {
00407         parent::__construct();
00408         $this->valid_parameters = array(
00409             'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00410             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00411             RFC2445_XNAME => RFC2445_OPTIONAL
00412         );
00413     }
00414 
00415     function is_valid_value($value) {
00416         // This MUST be two floats separated by a semicolon
00417         if(!is_string($value)) {
00418             return false;
00419         }
00420 
00421         $floats = explode(';', $value);
00422         if(count($floats) != 2) {
00423             return false;
00424         }
00425 
00426         return rfc2445_is_valid_value($floats[0], RFC2445_TYPE_FLOAT) && rfc2445_is_valid_value($floats[1], RFC2445_TYPE_FLOAT);
00427     }
00428 
00429     function set_value($value) {
00430         // Must override this, otherwise the semicolon separating
00431         // the two floats would get auto-quoted, which is illegal
00432         if($this->is_valid_value($value)) {
00433             $this->value = $value;
00434             return true;
00435         }
00436 
00437         return false;
00438     }
00439 
00440 }
00441 
00442 class iCalendar_property_location extends iCalendar_property {
00443 
00444     var $name        = 'LOCATION';
00445     var $val_type    = RFC2445_TYPE_TEXT;
00446 
00447     function __construct() {
00448         parent::__construct();
00449         $this->valid_parameters = array(
00450             'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00451             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00452             RFC2445_XNAME => RFC2445_OPTIONAL
00453         );
00454     }
00455 }
00456 
00457 class iCalendar_property_percent_complete extends iCalendar_property {
00458 
00459     var $name        = 'PERCENT-COMPLETE';
00460     var $val_type    = RFC2445_TYPE_INTEGER;
00461 
00462     function __construct() {
00463         parent::__construct();
00464         $this->valid_parameters = array(
00465             RFC2445_XNAME => RFC2445_OPTIONAL
00466         );
00467     }
00468 
00469     function is_valid_value($value) {
00470         // Only integers between 0 and 100 inclusive allowed
00471         if(!parent::is_valid_value($value)) {
00472             return false;
00473         }
00474         $value = intval($value);
00475         return ($value >= 0 && $value <= 100);
00476     }
00477 
00478 }
00479 
00480 class iCalendar_property_priority extends iCalendar_property {
00481 
00482     var $name        = 'PRIORITY';
00483     var $val_type    = RFC2445_TYPE_INTEGER;
00484 
00485     function __construct() {
00486         parent::__construct();
00487         $this->valid_parameters = array(
00488             RFC2445_XNAME => RFC2445_OPTIONAL
00489         );
00490     }
00491 
00492     function is_valid_value($value) {
00493         // Only integers between 0 and 9 inclusive allowed        
00494         if(!parent::is_valid_value($value)) {
00495             return false;
00496         }
00497 
00498         $value = intval($value);
00499         return ($value >= 0 && $value <= 9);
00500     }
00501 }
00502 
00503 class iCalendar_property_resources extends iCalendar_property {
00504 
00505     var $name        = 'RESOURCES';
00506     var $val_type    = RFC2445_TYPE_TEXT;
00507     var $val_multi   = true;
00508 
00509     function __construct() {
00510         parent::__construct();
00511         $this->valid_parameters = array(
00512             'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00513             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00514             RFC2445_XNAME => RFC2445_OPTIONAL
00515         );
00516     }
00517 }
00518 
00519 class iCalendar_property_status extends iCalendar_property {
00520 
00521     var $name        = 'STATUS';
00522     var $val_type    = RFC2445_TYPE_TEXT;
00523 
00524     function __construct() {
00525         parent::__construct();
00526         $this->valid_parameters = array(
00527             RFC2445_XNAME => RFC2445_OPTIONAL
00528         );
00529     }
00530 
00531     function is_valid_value($value) {
00532         // This is case-sensitive
00533         switch ($this->parent_component) {
00534             case 'VEVENT':
00535                 $allowed = array('TENTATIVE', 'CONFIRMED', 'CANCELLED');
00536             break;
00537             case 'VTODO':
00538                 $allowed = array('NEEDS-ACTION', 'COMPLETED', 'IN-PROCESS', 'CANCELLED');
00539             break;
00540             case 'VJOURNAL':
00541                 $allowed = array('DRAFT', 'FINAL', 'CANCELLED');
00542             break;
00543         }
00544         return in_array($value, $allowed);
00545 
00546     }
00547 
00548 }
00549 
00550 class iCalendar_property_summary extends iCalendar_property {
00551 
00552     var $name        = 'SUMMARY';
00553     var $val_type    = RFC2445_TYPE_TEXT;
00554 
00555     function __construct() {
00556         parent::__construct();
00557         $this->valid_parameters = array(
00558             'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00559             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00560             RFC2445_XNAME => RFC2445_OPTIONAL
00561         );
00562     }
00563 }
00564 
00565 // 4.8.2 Date and Time Component Properties
00566 // ----------------------------------------
00567 
00568 class iCalendar_property_completed extends iCalendar_property {
00569 
00570     var $name        = 'COMPLETED';
00571     var $val_type    = RFC2445_TYPE_DATE_TIME;
00572 
00573     function __construct() {
00574         parent::__construct();
00575         $this->valid_parameters = array(
00576             RFC2445_XNAME => RFC2445_OPTIONAL
00577         );
00578     }
00579 
00580     function is_valid_value($value) {
00581         if(!parent::is_valid_value($value)) {
00582             return false;
00583         }
00584         // Time MUST be in UTC format
00585         return(substr($value, -1) == 'Z');
00586     }
00587 }
00588 
00589 class iCalendar_property_dtend extends iCalendar_property {
00590 
00591     var $name        = 'DTEND';
00592     var $val_type    = RFC2445_TYPE_DATE_TIME;
00593 
00594     function __construct() {
00595         parent::__construct();
00596         $this->valid_parameters = array(
00597             'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00598             'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
00599             RFC2445_XNAME => RFC2445_OPTIONAL
00600         );
00601     }
00602 
00603     function is_valid_value($value) {
00604         if(!parent::is_valid_value($value)) {
00605             return false;
00606         }
00607 
00608         // If present in a FREEBUSY component, must be in UTC format
00609         if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
00610             return false;
00611         }
00612 
00613         return true;
00614 
00615     }
00616 
00617     function is_valid_parameter($parameter, $value) {
00618 
00619         $parameter = strtoupper($parameter);
00620 
00621         if(!parent::is_valid_parameter($parameter, $value)) {
00622             return false;
00623         }
00624         if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
00625             return false;
00626         }
00627 
00628         return true;
00629     }
00630 }
00631 
00632 class iCalendar_property_due extends iCalendar_property {
00633 
00634     var $name        = 'DUE';
00635     var $val_type    = RFC2445_TYPE_DATE_TIME;
00636 
00637     function __construct() {
00638         parent::__construct();
00639         $this->valid_parameters = array(
00640             'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00641             'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
00642             RFC2445_XNAME => RFC2445_OPTIONAL
00643         );
00644     }
00645 
00646     function is_valid_value($value) {
00647         if(!parent::is_valid_value($value)) {
00648             return false;
00649         }
00650 
00651         // If present in a FREEBUSY component, must be in UTC format
00652         if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
00653             return false;
00654         }
00655 
00656         return true;
00657 
00658     }
00659 
00660     function is_valid_parameter($parameter, $value) {
00661 
00662         $parameter = strtoupper($parameter);
00663 
00664         if(!parent::is_valid_parameter($parameter, $value)) {
00665             return false;
00666         }
00667         if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
00668             return false;
00669         }
00670 
00671         return true;
00672     }
00673 }
00674 
00675 class iCalendar_property_dtstart extends iCalendar_property {
00676 
00677     var $name        = 'DTSTART';
00678     var $val_type    = RFC2445_TYPE_DATE_TIME;
00679 
00680     function __construct() {
00681         parent::__construct();
00682         $this->valid_parameters = array(
00683             'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00684             'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
00685             RFC2445_XNAME => RFC2445_OPTIONAL
00686         );
00687     }
00688 
00689     // TODO: unimplemented stuff when parent is a VTIMEZONE component
00690 
00691     function is_valid_value($value) {
00692         if(!parent::is_valid_value($value)) {
00693             return false;
00694         }
00695 
00696         // If present in a FREEBUSY component, must be in UTC format
00697         if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
00698             return false;
00699         }
00700 
00701         return true;
00702     }
00703 
00704     function is_valid_parameter($parameter, $value) {
00705 
00706         $parameter = strtoupper($parameter);
00707 
00708         if(!parent::is_valid_parameter($parameter, $value)) {
00709             return false;
00710         }
00711         if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
00712             return false;
00713         }
00714 
00715         return true;
00716     }
00717 }
00718 
00719 class iCalendar_property_duration extends iCalendar_property {
00720 
00721     var $name        = 'DURATION';
00722     var $val_type    = RFC2445_TYPE_DURATION;
00723 
00724     function __construct() {
00725         parent::__construct();
00726         $this->valid_parameters = array(
00727             RFC2445_XNAME => RFC2445_OPTIONAL
00728         );
00729     }
00730 
00731     function is_valid_value($value) {
00732         if(!parent::is_valid_value($value)) {
00733             return false;
00734         }
00735 
00736         // Value must be positive
00737         return ($value{0} != '-');
00738     }
00739 }
00740 
00741 class iCalendar_property_freebusy extends iCalendar_property {
00742 
00743     var $name        = 'FREEBUSY';
00744     var $val_type    = RFC2445_TYPE_PERIOD;
00745     var $val_multi   = true;
00746 
00747     function __construct() {
00748         parent::__construct();
00749         $this->valid_parameters = array(
00750             'FBTYPE'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00751             RFC2445_XNAME => RFC2445_OPTIONAL
00752         );
00753     }
00754 
00755     function is_valid_value($value) {
00756         if(!parent::is_valid_value($value)) {
00757             return false;
00758         }
00759 
00760         $pos = strpos($value, '/'); // We know there's only one / in there
00761         if($value{$pos - 1} != 'Z') {
00762             // Start time MUST be in UTC
00763             return false;
00764         }
00765         if($value{$pos + 1} != 'P' && substr($value, -1) != 'Z') {
00766             // If the second part is not a period, it MUST be in UTC
00767             return false;
00768         }
00769 
00770         return true;
00771     }
00772 
00773     // TODO: these properties SHOULD be shorted in ascending order (by start time and end time as tiebreak)
00774 }
00775 
00776 class iCalendar_property_transp extends iCalendar_property {
00777 
00778     var $name        = 'TRANSP';
00779     var $val_type    = RFC2445_TYPE_TEXT;
00780     var $val_default = 'OPAQUE';
00781 
00782     function __construct() {
00783         parent::__construct();
00784         $this->valid_parameters = array(
00785             RFC2445_XNAME => RFC2445_OPTIONAL
00786         );
00787     }
00788 
00789     function is_valid_value($value) {
00790         return ($value === 'TRANSPARENT' || $value === 'OPAQUE');
00791     }
00792 }
00793 
00794 // TODO: 4.8.3 timezone component properties
00795 
00796 
00797 // 4.8.4 Relationship Component Properties
00798 // ---------------------------------------
00799 
00800 class iCalendar_property_attendee extends iCalendar_property {
00801 
00802     var $name        = 'ATTENDEE';
00803     var $val_type    = RFC2445_TYPE_CAL_ADDRESS;
00804 
00805     // TODO: MUST NOT be specified when the calendar object has METHOD=PUBLISH
00806     // TODO: standard has lots of detail here, make triple sure that we eventually conform
00807 
00808     function __construct() {
00809         parent::__construct();
00810         $this->valid_parameters = array(
00811             'LANGUAGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00812             'CN'             => RFC2445_OPTIONAL | RFC2445_ONCE,
00813             'ROLE'           => RFC2445_OPTIONAL | RFC2445_ONCE,
00814             'PARTSTAT'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00815             'RSVP'           => RFC2445_OPTIONAL | RFC2445_ONCE,
00816             'CUTYPE'         => RFC2445_OPTIONAL | RFC2445_ONCE,
00817             'MEMBER'         => RFC2445_OPTIONAL | RFC2445_ONCE,
00818             'DELEGATED-TO'   => RFC2445_OPTIONAL | RFC2445_ONCE,
00819             'DELEGATED-FROM' => RFC2445_OPTIONAL | RFC2445_ONCE,
00820             'SENT-BY'        => RFC2445_OPTIONAL | RFC2445_ONCE,
00821             'DIR'            => RFC2445_OPTIONAL | RFC2445_ONCE,
00822             RFC2445_XNAME    => RFC2445_OPTIONAL
00823         );
00824     }
00825 
00826     function set_parent_component($componentname) {
00827         if(!parent::set_parent_component($componentname)) {
00828             return false;
00829         }
00830 
00831         if($this->parent_component == 'VFREEBUSY' || $this->parent_component == 'VALARM') {
00832             // Most parameters become invalid in this case, the full allowed set is now:
00833             $this->valid_parameters = array(
00834                 'LANGUAGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00835                 RFC2445_XNAME    => RFC2445_OPTIONAL
00836             );
00837         }
00838 
00839         return false;
00840     }
00841 
00842 }
00843 
00844 class iCalendar_property_contact extends iCalendar_property {
00845 
00846     var $name        = 'CONTACT';
00847     var $val_type    = RFC2445_TYPE_TEXT;
00848 
00849     function __construct() {
00850         parent::__construct();
00851         $this->valid_parameters = array(
00852             'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
00853             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00854             RFC2445_XNAME => RFC2445_OPTIONAL
00855         );
00856     }
00857 }
00858 
00859 class iCalendar_property_organizer extends iCalendar_property {
00860 
00861     var $name        = 'ORGANIZER';
00862     var $val_type    = RFC2445_TYPE_CAL_ADDRESS;
00863 
00864     function __construct() {
00865         parent::__construct();
00866         $this->valid_parameters = array(
00867             'CN'          => RFC2445_OPTIONAL | RFC2445_ONCE,
00868             'DIR'         => RFC2445_OPTIONAL | RFC2445_ONCE,
00869             'SENT-BY'     => RFC2445_OPTIONAL | RFC2445_ONCE,
00870             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
00871             RFC2445_XNAME => RFC2445_OPTIONAL
00872         );
00873     }
00874 
00875     // TODO:
00876 /*    
00877    Conformance: This property MUST be specified in an iCalendar object
00878    that specifies a group scheduled calendar entity. This property MUST
00879    be specified in an iCalendar object that specifies the publication of
00880    a calendar user's busy time. This property MUST NOT be specified in
00881    an iCalendar object that specifies only a time zone definition or
00882    that defines calendar entities that are not group scheduled entities,
00883    but are entities only on a single user's calendar.
00884 */
00885 
00886 }
00887 
00888 class iCalendar_property_recurrence_id extends iCalendar_property {
00889 
00890     // TODO: can only be specified when defining recurring components in the calendar
00891 /*
00892    Conformance: This property can be specified in an iCalendar object
00893    containing a recurring calendar component.
00894 
00895    Description: The full range of calendar components specified by a
00896    recurrence set is referenced by referring to just the "UID" property
00897    value corresponding to the calendar component. The "RECURRENCE-ID"
00898    property allows the reference to an individual instance within the
00899    recurrence set.
00900 */
00901 
00902     var $name        = 'RECURRENCE-ID';
00903     var $val_type    = RFC2445_TYPE_DATE_TIME;
00904 
00905     function __construct() {
00906         parent::__construct();
00907         $this->valid_parameters = array(
00908             'RANGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00909             'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
00910             'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00911             RFC2445_XNAME => RFC2445_OPTIONAL
00912         );
00913     }
00914 
00915     function is_valid_parameter($parameter, $value) {
00916 
00917         $parameter = strtoupper($parameter);
00918 
00919         if(!parent::is_valid_parameter($parameter, $value)) {
00920             return false;
00921         }
00922         if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
00923             return false;
00924         }
00925 
00926         return true;
00927     }
00928 
00929 }
00930 
00931 class iCalendar_property_related_to extends iCalendar_property {
00932 
00933     var $name        = 'RELATED-TO';
00934     var $val_type    = RFC2445_TYPE_TEXT;
00935 
00936     // TODO: the value of this property must reference another component's UID
00937 
00938     function __construct() {
00939         parent::__construct();
00940         $this->valid_parameters = array(
00941             'RELTYPE'     => RFC2445_OPTIONAL | RFC2445_ONCE,
00942             RFC2445_XNAME => RFC2445_OPTIONAL
00943         );
00944     }
00945 }
00946 
00947 class iCalendar_property_url extends iCalendar_property {
00948 
00949     var $name        = 'URL';
00950     var $val_type    = RFC2445_TYPE_URI;
00951 
00952     function __construct() {
00953         parent::__construct();
00954         $this->valid_parameters = array(
00955             RFC2445_XNAME => RFC2445_OPTIONAL
00956         );
00957     }
00958 }
00959 
00960 class iCalendar_property_uid extends iCalendar_property {
00961 
00962     var $name        = 'UID';
00963     var $val_type    = RFC2445_TYPE_TEXT;
00964 
00965     function __construct() {
00966         parent::__construct();
00967         $this->valid_parameters = array(
00968             RFC2445_XNAME => RFC2445_OPTIONAL
00969         );
00970 
00971         // The exception to the rule: this is not a static value, so we
00972         // generate it on-the-fly here. Guaranteed to be different for
00973         // each instance of this property, too. Nice.
00974         $this->val_default = Bennu::generate_guid();
00975     }
00976 }
00977 
00978 // 4.8.5 Recurrence Component Properties
00979 // -------------------------------------
00980 
00981 class iCalendar_property_exdate extends iCalendar_property {
00982 
00983     var $name        = 'EXDATE';
00984     var $val_type    = RFC2445_TYPE_DATE_TIME;
00985     var $val_multi   = true;
00986 
00987     function __construct() {
00988         parent::__construct();
00989         $this->valid_parameters = array(
00990             'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
00991             'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
00992             RFC2445_XNAME => RFC2445_OPTIONAL
00993         );
00994     }
00995 
00996     function is_valid_parameter($parameter, $value) {
00997 
00998         $parameter = strtoupper($parameter);
00999 
01000         if(!parent::is_valid_parameter($parameter, $value)) {
01001             return false;
01002         }
01003         if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
01004             return false;
01005         }
01006 
01007         return true;
01008     }
01009 
01010 }
01011 
01012 class iCalendar_property_exrule extends iCalendar_property {
01013 
01014     var $name        = 'EXRULE';
01015     var $val_type    = RFC2445_TYPE_RECUR;
01016 
01017     function __construct() {
01018         parent::__construct();
01019         $this->valid_parameters = array(
01020             RFC2445_XNAME => RFC2445_OPTIONAL
01021         );
01022     }
01023 }
01024 
01025 class iCalendar_property_rdate extends iCalendar_property {
01026 
01027     var $name        = 'RDATE';
01028     var $val_type    = RFC2445_TYPE_DATE_TIME;
01029     var $val_multi   = true;
01030 
01031     function __construct() {
01032         parent::__construct();
01033         $this->valid_parameters = array(
01034             'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
01035             'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
01036             RFC2445_XNAME => RFC2445_OPTIONAL
01037         );
01038     }
01039 
01040     function is_valid_parameter($parameter, $value) {
01041 
01042         $parameter = strtoupper($parameter);
01043 
01044         if(!parent::is_valid_parameter($parameter, $value)) {
01045             return false;
01046         }
01047         if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME' || $value == 'PERIOD')) {
01048             return false;
01049         }
01050 
01051         return true;
01052     }
01053 
01054 }
01055 
01056 class iCalendar_property_rrule extends iCalendar_property {
01057 
01058     var $name        = 'RRULE';
01059     var $val_type    = RFC2445_TYPE_RECUR;
01060 
01061     function __construct() {
01062         parent::__construct();
01063         $this->valid_parameters = array(
01064             RFC2445_XNAME => RFC2445_OPTIONAL
01065         );
01066     }
01067 }
01068 
01069 // 4.8.6 Alarm Component Properties
01070 // -------------------------------------------
01071 class iCalendar_property_action extends iCalendar_property {
01072         var $name      = 'ACTION';
01073     var $val_type   = RFC2445_TYPE_TEXT;
01074     
01075     function __construct() {
01076         parent::__construct();
01077         $this->valid_parameters = array(
01078             RFC2445_XNAME => RFC2445_OPTIONAL
01079         );
01080     }
01081     
01082     function is_valid_value($value) {
01083         if(!parent::is_valid_value($value)) {
01084             return false;
01085         }
01086         
01087         // Value must be one of the following, or an x-name.
01088         $valid_values = array('ACTION', 'DISPLAY', 'EMAIL', 'PROCEDURE');
01089         return(in_array($value, $valid_values) || rfc2445_is_xname($value));        
01090         
01091     }
01092 }
01093 
01094 class iCalendar_property_repeat extends iCalendar_property {
01095     var $name      = 'REPEAT';
01096     var $val_type   = RFC2445_TYPE_INTEGER;
01097     
01098     function __construct() {
01099         parent::__construct();
01100         $this->valid_parameters = array(
01101             RFC2445_XNAME => RFC2445_OPTIONAL
01102         );
01103     }   
01104 }
01105 
01106 class iCalendar_property_trigger extends iCalendar_property {
01107     var $name      = 'TRIGGER';
01108     var $val_type   = RFC2445_TYPE_TEXT;
01109     
01110     function __construct() {
01111         parent::__construct();
01112         $this->valid_parameters = array(
01113             'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE,
01114             'RELATED' => RFC2445_OPTIONAL | RFC2445_ONCE,
01115             RFC2445_XNAME => RFC2445_OPTIONAL
01116         );
01117     }
01118     
01119     function is_valid_value($value) {        
01120         if(!parent::is_valid_value($value)) {
01121             return false;
01122         }
01123         // Must either be DURATION or DATE_TIME type
01124         return(rfc2445_is_valid_value($value, RFC2445_TYPE_DURATION) 
01125             || rfc2445_is_valid_value($value, RFC2445_TYPE_DATE_TIME));
01126     }
01127 }
01128 
01129 
01130 
01131 // 4.8.7 Change Management Component Properties
01132 // --------------------------------------------
01133 
01134 class iCalendar_property_created extends iCalendar_property {
01135 
01136     var $name        = 'CREATED';
01137     var $val_type    = RFC2445_TYPE_DATE_TIME;
01138 
01139     function __construct() {
01140         parent::__construct();
01141         $this->valid_parameters = array(
01142             RFC2445_XNAME => RFC2445_OPTIONAL
01143         );
01144     }
01145 
01146     function is_valid_value($value) {
01147         if(!parent::is_valid_value($value)) {
01148             return false;
01149         }
01150         // Time MUST be in UTC format
01151         return(substr($value, -1) == 'Z');
01152     }
01153 }
01154 
01155 class iCalendar_property_dtstamp extends iCalendar_property {
01156 
01157     var $name        = 'DTSTAMP';
01158     var $val_type    = RFC2445_TYPE_DATE_TIME;
01159 
01160     function __construct() {
01161         parent::__construct();
01162         $this->valid_parameters = array(
01163             RFC2445_XNAME => RFC2445_OPTIONAL
01164         );
01165     }
01166 
01167     function is_valid_value($value) {
01168         if(!parent::is_valid_value($value)) {
01169             return false;
01170         }
01171         // Time MUST be in UTC format
01172         return(substr($value, -1) == 'Z');
01173     }
01174 }
01175 
01176 class iCalendar_property_last_modified extends iCalendar_property {
01177 
01178     var $name        = 'LAST-MODIFIED';
01179     var $val_type    = RFC2445_TYPE_DATE_TIME;
01180 
01181     function __construct() {
01182         parent::__construct();
01183         $this->valid_parameters = array(
01184             RFC2445_XNAME => RFC2445_OPTIONAL
01185         );
01186     }
01187 
01188     function is_valid_value($value) {
01189         if(!parent::is_valid_value($value)) {
01190             return false;
01191         }
01192         // Time MUST be in UTC format
01193         return(substr($value, -1) == 'Z');
01194     }
01195 }
01196 
01197 class iCalendar_property_sequence extends iCalendar_property {
01198 
01199     var $name        = 'SEQUENCE';
01200     var $val_type    = RFC2445_TYPE_INTEGER;
01201     var $val_default = 0;
01202 
01203     function __construct() {
01204         parent::__construct();
01205         $this->valid_parameters = array(
01206             RFC2445_XNAME => RFC2445_OPTIONAL
01207         );
01208     }
01209 
01210     function is_valid_value($value) {
01211         if(!parent::is_valid_value($value)) {
01212             return false;
01213         }
01214         $value = intval($value);
01215         return ($value >= 0);
01216     }
01217 }
01218 
01219 // 4.8.8 Miscellaneous Component Properties
01220 // ----------------------------------------
01221 
01222 class iCalendar_property_x extends iCalendar_property {
01223 
01224     var $name        = RFC2445_XNAME;
01225     var $val_type    = NULL;
01226 
01227     function __construct() {
01228         parent::__construct();
01229         $this->valid_parameters = array(
01230             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
01231             RFC2445_XNAME => RFC2445_OPTIONAL
01232         );
01233     }
01234 
01235     function set_name($name) {
01236 
01237         $name = strtoupper($name);
01238 
01239         if(rfc2445_is_xname($name)) {
01240             $this->name = $name;
01241             return true;
01242         }
01243 
01244         return false;
01245     }
01246 }
01247 
01248 class iCalendar_property_request_status extends iCalendar_property {
01249 
01250     // IMPORTANT NOTE: This property value includes TEXT fields
01251     // separated by semicolons. Unfortunately, auto-value-formatting
01252     // cannot be used in this case. As an exception, the value passed
01253     // to this property MUST be already escaped.
01254 
01255     var $name        = 'REQUEST-STATUS';
01256     var $val_type    = RFC2445_TYPE_TEXT;
01257 
01258     function __construct() {
01259         parent::__construct();
01260         $this->valid_parameters = array(
01261             'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
01262             RFC2445_XNAME => RFC2445_OPTIONAL
01263         );
01264     }
01265 
01266     function is_valid_value($value) {
01267         if(!is_string($value) || empty($value)) {
01268             return false;
01269         }
01270 
01271         $len   = strlen($value);
01272         $parts = array();
01273         $from  = 0;
01274         $escch = false;
01275 
01276         for($i = 0; $i < $len; ++$i) {
01277             if($value{$i} == ';' && !$escch) {
01278                 // Token completed
01279                 $parts[] = substr($value, $from, $i - $from);
01280                 $from = $i + 1;
01281                 continue;
01282             }
01283             $escch = ($value{$i} == '\\');
01284         }
01285         // Add one last token with the remaining text; if the value
01286         // ended with a ';' it was illegal, so check that this token
01287         // is not the empty string.
01288         $parts[] = substr($value, $from);
01289 
01290         $count = count($parts);
01291 
01292         // May have 2 or 3 tokens (last one is optional)
01293         if($count != 2 && $count != 3) {
01294             return false;
01295         }
01296 
01297         // REMEMBER: if ANY part is empty, we have an illegal value
01298 
01299         // First token must be hierarchical numeric status (3 levels max)
01300         if(strlen($parts[0]) == 0) {
01301             return false;
01302         }
01303 
01304         if($parts[0]{0} < '1' || $parts[0]{0} > '4') {
01305             return false;
01306         }
01307 
01308         $len = strlen($parts[0]);
01309 
01310         // Max 3 levels, and can't end with a period
01311         if($len > 5 || $parts[0]{$len - 1} == '.') {
01312             return false;
01313         }
01314 
01315         for($i = 1; $i < $len; ++$i) {
01316             if(($i & 1) == 1 && $parts[0]{$i} != '.') {
01317                 // Even-indexed chars must be periods
01318                 return false;
01319             }
01320             else if(($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) {
01321                 // Odd-indexed chars must be numbers
01322                 return false;
01323             }
01324         }
01325 
01326         // Second and third tokens must be TEXT, and already escaped, so
01327         // they are not allowed to have UNESCAPED semicolons, commas, slashes,
01328         // or any newlines at all
01329 
01330         for($i = 1; $i < $count; ++$i) {
01331             if(strpos($parts[$i], "\n") !== false) {
01332                 return false;
01333             }
01334 
01335             $len = strlen($parts[$i]);
01336             if($len == 0) {
01337                 // Cannot be empty
01338                 return false;
01339             }
01340 
01341             $parts[$i] .= '#'; // This guard token saves some conditionals in the loop
01342 
01343             for($j = 0; $j < $len; ++$j) {
01344                 $thischar = $parts[$i]{$j};
01345                 $nextchar = $parts[$i]{$j + 1};
01346                 if($thischar == '\\') {
01347                     // Next char must now be one of ";,\nN"
01348                     if($nextchar != ';' && $nextchar != ',' && $nextchar != '\\' &&
01349                        $nextchar != 'n' && $nextchar != 'N') {
01350                         return false;
01351                     }
01352 
01353                     // OK, this escaped sequence is correct, bypass next char
01354                     ++$j;
01355                     continue;
01356                 }
01357                 if($thischar == ';' || $thischar == ',' || $thischar == '\\') {
01358                     // This wasn't escaped as it should
01359                     return false;
01360                 }
01361             }
01362         }
01363 
01364         return true;
01365     }
01366 
01367     function set_value($value) {
01368         // Must override this, otherwise the value would be quoted again
01369         if($this->is_valid_value($value)) {
01370             $this->value = $value;
01371             return true;
01372         }
01373 
01374         return false;
01375     }
01376 
01377 }
01378 
01379 class iCalendar_property_tzid extends iCalendar_property {
01380 
01381     var $name        = 'TZID';
01382     var $val_type    = RFC2445_TYPE_TEXT;
01383 
01384     function __construct() {
01385         parent::__construct();
01386         $this->valid_parameters = array(
01387             RFC2445_XNAME => RFC2445_OPTIONAL
01388         );
01389     }
01390 
01391     function is_valid_value($value) {
01392         if(!parent::is_valid_value($value)) {
01393             return false;
01394         } else {
01395             return true;
01396         }
01397     }
01398 }
01399 
01400 class iCalendar_property_tzname extends iCalendar_property {
01401 
01402     var $name        = 'TZNAME';
01403     var $val_type    = RFC2445_TYPE_TEXT;
01404 
01405     function __construct() {
01406         parent::__construct();
01407         $this->valid_parameters = array(
01408             'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE,
01409             RFC2445_XNAME => RFC2445_OPTIONAL
01410         );
01411     }
01412 
01413     function is_valid_value($value) {
01414         if(!parent::is_valid_value($value)) {
01415             return false;
01416         } else {
01417             return true;
01418         }
01419     }
01420 }
01421 
01422 class iCalendar_property_tzoffsetfrom extends iCalendar_property {
01423 
01424     var $name        = 'TZOFFSETFROM';
01425     var $val_type    = RFC2445_TYPE_UTC_OFFSET;
01426 
01427     function __construct() {
01428         parent::__construct();
01429         $this->valid_parameters = array(
01430             RFC2445_XNAME => RFC2445_OPTIONAL
01431         );
01432     }
01433 
01434     function is_valid_value($value) {
01435         if(!parent::is_valid_value($value)) {
01436             return false;
01437         } else {
01438             return true;
01439         }
01440     }
01441 }
01442 
01443 class iCalendar_property_tzoffsetto extends iCalendar_property {
01444 
01445     var $name        = 'TZOFFSETTO';
01446     var $val_type    = RFC2445_TYPE_UTC_OFFSET;
01447 
01448     function __construct() {
01449         parent::__construct();
01450         $this->valid_parameters = array(
01451             RFC2445_XNAME => RFC2445_OPTIONAL
01452         );
01453     }
01454 
01455     function is_valid_value($value) {
01456         if(!parent::is_valid_value($value)) {
01457             return false;
01458         } else {
01459                 return true;
01460         }
01461     }
01462 }
01463 
01464 
01465 
01466 #######################
01467 /*
01468 class iCalendar_property_class extends iCalendar_property {
01469 
01470     var $name        = 'CLASS';
01471     var $val_type    = RFC2445_TYPE_TEXT;
01472 
01473     function __construct() {
01474         parent::__construct();
01475         $this->valid_parameters = array(
01476             RFC2445_XNAME => RFC2445_OPTIONAL
01477         );
01478     }
01479 }
01480 */
01481 
 All Data Structures Namespaces Files Functions Variables Enumerations