[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php // $Id: iCalendar_properties.php,v 1.13 2005/07/21 22:42:13 defacer Exp $ 2 3 class iCalendar_property { 4 // Properties can have parameters, but cannot have other properties or components 5 6 var $parent_component = NULL; 7 var $value = NULL; 8 var $parameters = NULL; 9 var $valid_parameters = NULL; 10 11 // These are common for 95% of properties, so define them here and override as necessary 12 var $val_multi = false; 13 var $val_default = NULL; 14 15 function iCalendar_property() { 16 $this->construct(); 17 } 18 19 function construct() { 20 $this->parameters = array(); 21 } 22 23 // If some property needs extra care with its parameters, override this 24 // IMPORTANT: the parameter name MUST BE CAPITALIZED! 25 function is_valid_parameter($parameter, $value) { 26 27 if(is_array($value)) { 28 if(!iCalendar_parameter::multiple_values_allowed($parameter)) { 29 return false; 30 } 31 foreach($value as $item) { 32 if(!iCalendar_parameter::is_valid_value($this, $parameter, $item)) { 33 return false; 34 } 35 } 36 return true; 37 } 38 39 return iCalendar_parameter::is_valid_value($this, $parameter, $value); 40 } 41 42 function invariant_holds() { 43 return true; 44 } 45 46 // If some property is very picky about its values, it should do the work itself 47 // Only data type validation is done here 48 function is_valid_value($value) { 49 if(is_array($value)) { 50 if(!$this->val_multi) { 51 return false; 52 } 53 else { 54 foreach($value as $oneval) { 55 if(!rfc2445_is_valid_value($oneval, $this->val_type)) { 56 return false; 57 } 58 } 59 } 60 return true; 61 } 62 return rfc2445_is_valid_value($value, $this->val_type); 63 } 64 65 function default_value() { 66 return $this->val_default; 67 } 68 69 function set_parent_component($componentname) { 70 if(class_exists('iCalendar_'.strtolower(substr($componentname, 1)))) { 71 $this->parent_component = strtoupper($componentname); 72 return true; 73 } 74 75 return false; 76 } 77 78 function set_value($value) { 79 if($this->is_valid_value($value)) { 80 // This transparently formats any value type according to the iCalendar specs 81 if(is_array($value)) { 82 foreach($value as $key => $item) { 83 $value[$key] = rfc2445_do_value_formatting($item, $this->val_type); 84 } 85 $this->value = implode(',', $value); 86 } 87 else { 88 $this->value = rfc2445_do_value_formatting($value, $this->val_type); 89 } 90 91 return true; 92 } 93 return false; 94 } 95 96 function get_value() { 97 // First of all, assume that we have multiple values 98 $valarray = explode('\\,', $this->value); 99 100 // Undo transparent formatting 101 $replace_function = create_function('$a', 'return rfc2445_undo_value_formatting($a, '.$this->val_type.');'); 102 $valarray = array_map($replace_function, $valarray); 103 104 // Now, if this property cannot have multiple values, don't return as an array 105 if(!$this->val_multi) { 106 return $valarray[0]; 107 } 108 109 // Otherwise return an array even if it has one element, for uniformity 110 return $valarray; 111 112 } 113 114 function set_parameter($name, $value) { 115 116 // Uppercase 117 $name = strtoupper($name); 118 119 // Are we trying to add a valid parameter? 120 $xname = false; 121 if(!isset($this->valid_parameters[$name])) { 122 // If not, is it an x-name as per RFC 2445? 123 if(!rfc2445_is_xname($name)) { 124 return false; 125 } 126 // No more checks -- all components are supposed to allow x-name parameters 127 $xname = true; 128 } 129 130 if(!$this->is_valid_parameter($name, $value)) { 131 return false; 132 } 133 134 if(is_array($value)) { 135 foreach($value as $key => $element) { 136 $value[$key] = iCalendar_parameter::do_value_formatting($name, $element); 137 } 138 } 139 else { 140 $value = iCalendar_parameter::do_value_formatting($name, $value); 141 } 142 143 $this->parameters[$name] = $value; 144 145 // Special case: if we just changed the VALUE parameter, reflect this 146 // in the object's status so that it only accepts correct type values 147 if($name == 'VALUE') { 148 // TODO: what if this invalidates an already-set value? 149 $this->val_type = constant('RFC2445_TYPE_'.str_replace('-', '_', $value)); 150 } 151 152 return true; 153 154 } 155 156 function get_parameter($name) { 157 158 // Uppercase 159 $name = strtoupper($name); 160 161 if(isset($this->parameters[$name])) { 162 // If there are any double quotes in the value, invisibly strip them 163 if(is_array($this->parameters[$name])) { 164 foreach($this->parameters[$name] as $key => $value) { 165 if(substr($value, 0, 1) == '"') { 166 $this->parameters[$name][$key] = substr($value, 1, strlen($value) - 2); 167 } 168 } 169 return $this->parameters[$name]; 170 } 171 172 else { 173 if(substr($this->parameters[$name], 0, 1) == '"') { 174 return substr($this->parameters[$name], 1, strlen($this->parameters[$name]) - 2); 175 } 176 } 177 } 178 179 return NULL; 180 } 181 182 function serialize() { 183 $string = $this->name; 184 185 if(!empty($this->parameters)) { 186 foreach($this->parameters as $name => $value) { 187 $string .= ';'.$name.'='; 188 if(is_array($value)) { 189 $string .= implode(',', $value); 190 } 191 else { 192 $string .= $value; 193 } 194 } 195 } 196 197 $string .= ':'.$this->value; 198 199 return rfc2445_fold($string) . RFC2445_CRLF; 200 } 201 } 202 203 // 4.7 Calendar Properties 204 // ----------------------- 205 206 class iCalendar_property_calscale extends iCalendar_property { 207 208 var $name = 'CALSCALE'; 209 var $val_type = RFC2445_TYPE_TEXT; 210 211 function construct() { 212 $this->valid_parameters = array( 213 RFC2445_XNAME => RFC2445_OPTIONAL 214 ); 215 } 216 217 function is_valid_value($value) { 218 // This is case-sensitive 219 return ($value === 'GREGORIAN'); 220 } 221 } 222 223 class iCalendar_property_method extends iCalendar_property { 224 225 var $name = 'METHOD'; 226 var $val_type = RFC2445_TYPE_TEXT; 227 228 function construct() { 229 $this->valid_parameters = array( 230 RFC2445_XNAME => RFC2445_OPTIONAL 231 ); 232 } 233 234 function is_valid_value($value) { 235 // This is case-sensitive 236 // Methods from RFC 2446 237 $methods == array('PUBLISH', 'REQUEST', 'REPLY', 'ADD', 'CANCEL', 'REFRESH', 'COUNTER', 'DECLINECOUNTER'); 238 return in_array($value, $methods); 239 } 240 } 241 242 class iCalendar_property_prodid extends iCalendar_property { 243 244 var $name = 'PRODID'; 245 var $val_type = RFC2445_TYPE_TEXT; 246 var $val_default = NULL; 247 248 function construct() { 249 $this->val_default = '-//John Papaioannou/NONSGML Bennu '._BENNU_VERSION.'//EN'; 250 251 $this->valid_parameters = array( 252 RFC2445_XNAME => RFC2445_OPTIONAL 253 ); 254 } 255 } 256 257 class iCalendar_property_version extends iCalendar_property { 258 259 var $name = 'VERSION'; 260 var $val_type = RFC2445_TYPE_TEXT; 261 var $val_default = '2.0'; 262 263 function construct() { 264 $this->valid_parameters = array( 265 RFC2445_XNAME => RFC2445_OPTIONAL 266 ); 267 } 268 269 function is_valid_value($value) { 270 return($value === '2.0' || $value === 2.0); 271 } 272 273 } 274 275 // 4.8.1 Descriptive Component Properties 276 // -------------------------------------- 277 278 class iCalendar_property_attach extends iCalendar_property { 279 280 var $name = 'ATTACH'; 281 var $val_type = RFC2445_TYPE_URI; 282 283 function construct() { 284 $this->valid_parameters = array( 285 'FMTTYPE' => RFC2445_OPTIONAL | RFC2445_ONCE, 286 'ENCODING' => RFC2445_OPTIONAL | RFC2445_ONCE, 287 'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE, 288 RFC2445_XNAME => RFC2445_OPTIONAL 289 ); 290 } 291 292 function invariant_holds() { 293 if(isset($this->parameters['ENCODING']) && !isset($this->parameters['VALUE'])) { 294 return false; 295 } 296 if(isset($this->parameters['VALUE']) && !isset($this->parameters['ENCODING'])) { 297 return false; 298 } 299 300 return true; 301 } 302 303 function is_valid_parameter($parameter, $value) { 304 305 $parameter = strtoupper($parameter); 306 307 if(!parent::is_valid_parameter($parameter, $value)) { 308 return false; 309 } 310 311 if($parameter === 'ENCODING' && strtoupper($value) != 'BASE64') { 312 return false; 313 } 314 315 if($parameter === 'VALUE' && strtoupper($value) != 'BINARY') { 316 return false; 317 } 318 319 return true; 320 } 321 } 322 323 class iCalendar_property_categories extends iCalendar_property { 324 325 var $name = 'CATEGORIES'; 326 var $val_type = RFC2445_TYPE_TEXT; 327 var $val_multi = true; 328 329 function construct() { 330 $this->valid_parameters = array( 331 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 332 RFC2445_XNAME => RFC2445_OPTIONAL 333 ); 334 } 335 } 336 337 class iCalendar_property_class extends iCalendar_property { 338 339 var $name = 'CLASS'; 340 var $val_type = RFC2445_TYPE_TEXT; 341 var $val_default = 'PUBLIC'; 342 343 function construct() { 344 $this->valid_parameters = array( 345 RFC2445_XNAME => RFC2445_OPTIONAL 346 ); 347 } 348 function is_valid_value($value) { 349 $value = strtoupper($value); 350 // If this is not an xname, it is case-sensitive 351 return ($value === 'PUBLIC' || $value === 'PRIVATE' || $value === 'CONFIDENTIAL' || rfc2445_is_xname(strtoupper($value))); 352 } 353 } 354 355 class iCalendar_property_comment extends iCalendar_property { 356 357 var $name = 'COMMENT'; 358 var $val_type = RFC2445_TYPE_TEXT; 359 360 function construct() { 361 $this->valid_parameters = array( 362 'ALTREP' => RFC2445_OPTIONAL | RFC2445_ONCE, 363 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 364 RFC2445_XNAME => RFC2445_OPTIONAL 365 ); 366 } 367 } 368 369 class iCalendar_property_description extends iCalendar_property { 370 371 var $name = 'DESCRIPTION'; 372 var $val_type = RFC2445_TYPE_TEXT; 373 374 function construct() { 375 $this->valid_parameters = array( 376 'ALTREP' => RFC2445_OPTIONAL | RFC2445_ONCE, 377 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 378 RFC2445_XNAME => RFC2445_OPTIONAL 379 ); 380 } 381 } 382 383 class iCalendar_property_geo extends iCalendar_property { 384 385 var $name = 'GEO'; 386 var $val_type = RFC2445_TYPE_TEXT; 387 388 function construct() { 389 $this->valid_parameters = array( 390 'ALTREP' => RFC2445_OPTIONAL | RFC2445_ONCE, 391 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 392 RFC2445_XNAME => RFC2445_OPTIONAL 393 ); 394 } 395 396 function is_valid_value($value) { 397 // This MUST be two floats separated by a semicolon 398 if(!is_string($value)) { 399 return false; 400 } 401 402 $floats = explode(';', $value); 403 if(count($floats) != 2) { 404 return false; 405 } 406 407 return rfc2445_is_valid_value($floats[0], RFC2445_TYPE_FLOAT) && rfc2445_is_valid_value($floats[1], RFC2445_TYPE_FLOAT); 408 } 409 410 function set_value($value) { 411 // Must override this, otherwise the semicolon separating 412 // the two floats would get auto-quoted, which is illegal 413 if($this->is_valid_value($value)) { 414 $this->value = $value; 415 return true; 416 } 417 418 return false; 419 } 420 421 } 422 423 class iCalendar_property_location extends iCalendar_property { 424 425 var $name = 'LOCATION'; 426 var $val_type = RFC2445_TYPE_TEXT; 427 428 function construct() { 429 $this->valid_parameters = array( 430 'ALTREP' => RFC2445_OPTIONAL | RFC2445_ONCE, 431 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 432 RFC2445_XNAME => RFC2445_OPTIONAL 433 ); 434 } 435 } 436 437 class iCalendar_property_percent_complete extends iCalendar_property { 438 439 var $name = 'PERCENT-COMPLETE'; 440 var $val_type = RFC2445_TYPE_INTEGER; 441 442 function construct() { 443 $this->valid_parameters = array( 444 RFC2445_XNAME => RFC2445_OPTIONAL 445 ); 446 } 447 448 function is_valid_value($value) { 449 // Only integers between 0 and 100 inclusive allowed 450 if(!parent::is_valid_value($value)) { 451 return false; 452 } 453 $value = intval($value); 454 return ($value >= 0 && $value <= 100); 455 } 456 457 } 458 459 class iCalendar_property_priority extends iCalendar_property { 460 461 var $name = 'PRIORITY'; 462 var $val_type = RFC2445_TYPE_TEXT; 463 464 function construct() { 465 $this->valid_parameters = array( 466 RFC2445_XNAME => RFC2445_OPTIONAL 467 ); 468 } 469 470 function is_valid_value($value) { 471 // Only integers between 0 and 9 inclusive allowed 472 if(!parent::is_valid_value($value)) { 473 return false; 474 } 475 return true; 476 //$value = intval($value); 477 //return ($value >= 0 && $value <= 9); 478 } 479 } 480 481 class iCalendar_property_resources extends iCalendar_property { 482 483 var $name = 'RESOURCES'; 484 var $val_type = RFC2445_TYPE_TEXT; 485 var $val_multi = true; 486 487 function construct() { 488 $this->valid_parameters = array( 489 'ALTREP' => RFC2445_OPTIONAL | RFC2445_ONCE, 490 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 491 RFC2445_XNAME => RFC2445_OPTIONAL 492 ); 493 } 494 } 495 496 class iCalendar_property_status extends iCalendar_property { 497 498 var $name = 'STATUS'; 499 var $val_type = RFC2445_TYPE_TEXT; 500 501 function construct() { 502 $this->valid_parameters = array( 503 RFC2445_XNAME => RFC2445_OPTIONAL 504 ); 505 } 506 507 /* function is_valid_value($value) { 508 // This is case-sensitive 509 switch ($this->parent_component) { 510 case 'VEVENT': 511 $allowed = array('TENTATIVE', 'CONFIRMED', 'CANCELLED'); 512 break; 513 case 'VTODO': 514 $allowed = array('NEEDS-ACTION', 'COMPLETED', 'IN-PROCESS', 'CANCELLED'); 515 break; 516 case 'VJOURNAL': 517 $allowed = array('DRAFT', 'FINAL', 'CANCELLED'); 518 break; 519 } 520 return in_array($value, $allowed); 521 522 } 523 */ 524 } 525 526 class iCalendar_property_summary extends iCalendar_property { 527 528 var $name = 'SUMMARY'; 529 var $val_type = RFC2445_TYPE_TEXT; 530 531 function construct() { 532 $this->valid_parameters = array( 533 'ALTREP' => RFC2445_OPTIONAL | RFC2445_ONCE, 534 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 535 RFC2445_XNAME => RFC2445_OPTIONAL 536 ); 537 } 538 } 539 540 // 4.8.2 Date and Time Component Properties 541 // ---------------------------------------- 542 543 class iCalendar_property_completed extends iCalendar_property { 544 545 var $name = 'COMPLETED'; 546 var $val_type = RFC2445_TYPE_DATE_TIME; 547 548 function construct() { 549 $this->valid_parameters = array( 550 RFC2445_XNAME => RFC2445_OPTIONAL 551 ); 552 } 553 554 function is_valid_value($value) { 555 if(!parent::is_valid_value($value)) { 556 return false; 557 } 558 // Time MUST be in UTC format 559 return(substr($value, -1) == 'Z'); 560 } 561 } 562 563 class iCalendar_property_dtend extends iCalendar_property { 564 565 var $name = 'DTEND'; 566 var $val_type = RFC2445_TYPE_DATE_TIME; 567 568 function construct() { 569 $this->valid_parameters = array( 570 'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE, 571 'TZID' => RFC2445_OPTIONAL | RFC2445_ONCE, 572 RFC2445_XNAME => RFC2445_OPTIONAL 573 ); 574 } 575 576 function is_valid_value($value) { 577 if(!parent::is_valid_value($value)) { 578 return false; 579 } 580 581 // If present in a FREEBUSY component, must be in UTC format 582 if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') { 583 return false; 584 } 585 586 return true; 587 588 } 589 590 function is_valid_parameter($parameter, $value) { 591 592 $parameter = strtoupper($parameter); 593 594 if(!parent::is_valid_parameter($parameter, $value)) { 595 return false; 596 } 597 if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) { 598 return false; 599 } 600 601 return true; 602 } 603 } 604 605 class iCalendar_property_due extends iCalendar_property { 606 607 var $name = 'DUE'; 608 var $val_type = RFC2445_TYPE_DATE_TIME; 609 610 function construct() { 611 $this->valid_parameters = array( 612 'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE, 613 'TZID' => RFC2445_OPTIONAL | RFC2445_ONCE, 614 RFC2445_XNAME => RFC2445_OPTIONAL 615 ); 616 } 617 618 function is_valid_value($value) { 619 if(!parent::is_valid_value($value)) { 620 return false; 621 } 622 623 // If present in a FREEBUSY component, must be in UTC format 624 if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') { 625 return false; 626 } 627 628 return true; 629 630 } 631 632 function is_valid_parameter($parameter, $value) { 633 634 $parameter = strtoupper($parameter); 635 636 if(!parent::is_valid_parameter($parameter, $value)) { 637 return false; 638 } 639 if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) { 640 return false; 641 } 642 643 return true; 644 } 645 } 646 647 class iCalendar_property_dtstart extends iCalendar_property { 648 649 var $name = 'DTSTART'; 650 var $val_type = RFC2445_TYPE_DATE_TIME; 651 652 function construct() { 653 $this->valid_parameters = array( 654 'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE, 655 'TZID' => RFC2445_OPTIONAL | RFC2445_ONCE, 656 RFC2445_XNAME => RFC2445_OPTIONAL 657 ); 658 } 659 660 // TODO: unimplemented stuff when parent is a VTIMEZONE component 661 662 function is_valid_value($value) { 663 if(!parent::is_valid_value($value)) { 664 return false; 665 } 666 // If present in a FREEBUSY component, must be in UTC format 667 if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') { 668 return false; 669 } 670 671 return true; 672 } 673 674 function is_valid_parameter($parameter, $value) { 675 $parameter = strtoupper($parameter); 676 677 if(!parent::is_valid_parameter($parameter, $value)) { 678 return false; 679 } 680 if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) { 681 return false; 682 } 683 684 return true; 685 } 686 } 687 688 class iCalendar_property_duration extends iCalendar_property { 689 690 var $name = 'DURATION'; 691 var $val_type = RFC2445_TYPE_DURATION; 692 693 function construct() { 694 $this->valid_parameters = array( 695 RFC2445_XNAME => RFC2445_OPTIONAL 696 ); 697 } 698 699 function is_valid_value($value) { 700 if(!parent::is_valid_value($value)) { 701 return false; 702 } 703 704 // Value must be positive 705 return ($value{0} != '-'); 706 } 707 } 708 709 class iCalendar_property_freebusy extends iCalendar_property { 710 711 var $name = 'FREEBUSY'; 712 var $val_type = RFC2445_TYPE_PERIOD; 713 var $val_multi = true; 714 715 function construct() { 716 $this->valid_parameters = array( 717 'FBTYPE' => RFC2445_OPTIONAL | RFC2445_ONCE, 718 RFC2445_XNAME => RFC2445_OPTIONAL 719 ); 720 } 721 722 function is_valid_value($value) { 723 if(!parent::is_valid_value($value)) { 724 return false; 725 } 726 727 $pos = strpos($value, '/'); // We know there's only one / in there 728 if($value{$pos - 1} != 'Z') { 729 // Start time MUST be in UTC 730 return false; 731 } 732 if($value{$pos + 1} != 'P' && $substr($value, -1) != 'Z') { 733 // If the second part is not a period, it MUST be in UTC 734 return false; 735 } 736 737 return true; 738 } 739 740 // TODO: these properties SHOULD be shorted in ascending order (by start time and end time as tiebreak) 741 } 742 743 class iCalendar_property_transp extends iCalendar_property { 744 745 var $name = 'TRANSP'; 746 var $val_type = RFC2445_TYPE_TEXT; 747 var $val_default = 'OPAQUE'; 748 749 function construct() { 750 $this->valid_parameters = array( 751 RFC2445_XNAME => RFC2445_OPTIONAL 752 ); 753 } 754 755 function is_valid_value($value) { 756 return ($value === 'TRANSPARENT' || $value === 'OPAQUE'); 757 } 758 } 759 760 // TODO: 4.8.3 timezone component properties 761 762 763 // 4.8.4 Relationship Component Properties 764 // --------------------------------------- 765 766 class iCalendar_property_attendee extends iCalendar_property { 767 768 var $name = 'ATTENDEE'; 769 var $val_type = RFC2445_TYPE_CAL_ADDRESS; 770 771 // TODO: MUST NOT be specified when the calendar object has METHOD=PUBLISH 772 // TODO: standard has lots of detail here, make triple sure that we eventually conform 773 774 function construct() { 775 $this->valid_parameters = array( 776 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 777 'CN' => RFC2445_OPTIONAL | RFC2445_ONCE, 778 'ROLE' => RFC2445_OPTIONAL | RFC2445_ONCE, 779 'PARTSTAT' => RFC2445_OPTIONAL | RFC2445_ONCE, 780 'RSVP' => RFC2445_OPTIONAL | RFC2445_ONCE, 781 'CUTYPE' => RFC2445_OPTIONAL | RFC2445_ONCE, 782 'MEMBER' => RFC2445_OPTIONAL | RFC2445_ONCE, 783 'DELEGATED-TO' => RFC2445_OPTIONAL | RFC2445_ONCE, 784 'DELEGATED-FROM' => RFC2445_OPTIONAL | RFC2445_ONCE, 785 'SENT-BY' => RFC2445_OPTIONAL | RFC2445_ONCE, 786 'DIR' => RFC2445_OPTIONAL | RFC2445_ONCE, 787 RFC2445_XNAME => RFC2445_OPTIONAL 788 ); 789 } 790 791 function set_parent_component($componentname) { 792 if(!parent::set_parent_component($componentname)) { 793 return false; 794 } 795 796 if($this->parent_component == 'VFREEBUSY' || $this->parent_component == 'VALARM') { 797 // Most parameters become invalid in this case, the full allowed set is now: 798 $this->valid_parameters = array( 799 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 800 RFC2445_XNAME => RFC2445_OPTIONAL 801 ); 802 } 803 804 return false; 805 } 806 807 } 808 809 class iCalendar_property_contact extends iCalendar_property { 810 811 var $name = 'CONTACT'; 812 var $val_type = RFC2445_TYPE_TEXT; 813 814 function construct() { 815 $this->valid_parameters = array( 816 'ALTREP' => RFC2445_OPTIONAL | RFC2445_ONCE, 817 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 818 RFC2445_XNAME => RFC2445_OPTIONAL 819 ); 820 } 821 } 822 823 class iCalendar_property_organizer extends iCalendar_property { 824 825 var $name = 'ORGANIZER'; 826 var $val_type = RFC2445_TYPE_CAL_ADDRESS; 827 828 function construct() { 829 $this->valid_parameters = array( 830 'CN' => RFC2445_OPTIONAL | RFC2445_ONCE, 831 'DIR' => RFC2445_OPTIONAL | RFC2445_ONCE, 832 'SENT-BY' => RFC2445_OPTIONAL | RFC2445_ONCE, 833 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 834 RFC2445_XNAME => RFC2445_OPTIONAL 835 ); 836 } 837 838 // TODO: 839 /* 840 Conformance: This property MUST be specified in an iCalendar object 841 that specifies a group scheduled calendar entity. This property MUST 842 be specified in an iCalendar object that specifies the publication of 843 a calendar user's busy time. This property MUST NOT be specified in 844 an iCalendar object that specifies only a time zone definition or 845 that defines calendar entities that are not group scheduled entities, 846 but are entities only on a single user's calendar. 847 */ 848 849 } 850 851 class iCalendar_property_recurrence_id extends iCalendar_property { 852 853 // TODO: can only be specified when defining recurring components in the calendar 854 /* 855 Conformance: This property can be specified in an iCalendar object 856 containing a recurring calendar component. 857 858 Description: The full range of calendar components specified by a 859 recurrence set is referenced by referring to just the "UID" property 860 value corresponding to the calendar component. The "RECURRENCE-ID" 861 property allows the reference to an individual instance within the 862 recurrence set. 863 */ 864 865 var $name = 'RECURRENCE-ID'; 866 var $val_type = RFC2445_TYPE_DATE_TIME; 867 868 function construct() { 869 $this->valid_parameters = array( 870 'RANGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 871 'TZID' => RFC2445_OPTIONAL | RFC2445_ONCE, 872 'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE, 873 RFC2445_XNAME => RFC2445_OPTIONAL 874 ); 875 } 876 877 function is_valid_parameter($parameter, $value) { 878 879 $parameter = strtoupper($parameter); 880 881 if(!parent::is_valid_parameter($parameter, $value)) { 882 return false; 883 } 884 if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) { 885 return false; 886 } 887 888 return true; 889 } 890 891 } 892 893 class iCalendar_property_related_to extends iCalendar_property { 894 895 var $name = 'RELATED-TO'; 896 var $val_type = RFC2445_TYPE_TEXT; 897 898 // TODO: the value of this property must reference another component's UID 899 900 function construct() { 901 $this->valid_parameters = array( 902 'RELTYPE' => RFC2445_OPTIONAL | RFC2445_ONCE, 903 RFC2445_XNAME => RFC2445_OPTIONAL 904 ); 905 } 906 } 907 908 class iCalendar_property_url extends iCalendar_property { 909 910 var $name = 'URL'; 911 var $val_type = RFC2445_TYPE_URI; 912 913 function construct() { 914 $this->valid_parameters = array( 915 RFC2445_XNAME => RFC2445_OPTIONAL 916 ); 917 } 918 } 919 920 class iCalendar_property_uid extends iCalendar_property { 921 922 var $name = 'UID'; 923 var $val_type = RFC2445_TYPE_TEXT; 924 925 function construct() { 926 $this->valid_parameters = array( 927 RFC2445_XNAME => RFC2445_OPTIONAL 928 ); 929 930 // The exception to the rule: this is not a static value, so we 931 // generate it on-the-fly here. Guaranteed to be different for 932 // each instance of this property, too. Nice. 933 $this->val_default = rfc2445_guid(); 934 } 935 } 936 937 // 4.8.5 Recurrence Component Properties 938 // ------------------------------------- 939 940 class iCalendar_property_exdate extends iCalendar_property { 941 942 var $name = 'EXDATE'; 943 var $val_type = RFC2445_TYPE_DATE_TIME; 944 var $val_multi = true; 945 946 function construct() { 947 $this->valid_parameters = array( 948 'TZID' => RFC2445_OPTIONAL | RFC2445_ONCE, 949 'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE, 950 RFC2445_XNAME => RFC2445_OPTIONAL 951 ); 952 } 953 954 function is_valid_parameter($parameter, $value) { 955 956 $parameter = strtoupper($parameter); 957 958 if(!parent::is_valid_parameter($parameter, $value)) { 959 return false; 960 } 961 if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) { 962 return false; 963 } 964 965 return true; 966 } 967 968 } 969 970 class iCalendar_property_exrule extends iCalendar_property { 971 972 var $name = 'EXRULE'; 973 var $val_type = RFC2445_TYPE_RECUR; 974 975 function construct() { 976 $this->valid_parameters = array( 977 RFC2445_XNAME => RFC2445_OPTIONAL 978 ); 979 } 980 } 981 982 class iCalendar_property_rdate extends iCalendar_property { 983 984 var $name = 'RDATE'; 985 var $val_type = RFC2445_TYPE_DATE_TIME; 986 var $val_multi = true; 987 988 function construct() { 989 $this->valid_parameters = array( 990 'TZID' => RFC2445_OPTIONAL | RFC2445_ONCE, 991 'VALUE' => RFC2445_OPTIONAL | RFC2445_ONCE, 992 RFC2445_XNAME => RFC2445_OPTIONAL 993 ); 994 } 995 996 function is_valid_parameter($parameter, $value) { 997 998 $parameter = strtoupper($parameter); 999 1000 if(!parent::is_valid_parameter($parameter, $value)) { 1001 return false; 1002 } 1003 if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME' || $value == 'PERIOD')) { 1004 return false; 1005 } 1006 1007 return true; 1008 } 1009 1010 } 1011 1012 class iCalendar_property_rrule extends iCalendar_property { 1013 1014 var $name = 'RRULE'; 1015 var $val_type = RFC2445_TYPE_RECUR; 1016 1017 function construct() { 1018 $this->valid_parameters = array( 1019 RFC2445_XNAME => RFC2445_OPTIONAL 1020 ); 1021 } 1022 } 1023 1024 // TODO: 4.8.6 Alarm Component Properties 1025 1026 // 4.8.7 Change Management Component Properties 1027 // -------------------------------------------- 1028 1029 class iCalendar_property_created extends iCalendar_property { 1030 1031 var $name = 'CREATED'; 1032 var $val_type = RFC2445_TYPE_DATE_TIME; 1033 1034 function construct() { 1035 $this->valid_parameters = array( 1036 RFC2445_XNAME => RFC2445_OPTIONAL 1037 ); 1038 } 1039 1040 function is_valid_value($value) { 1041 if(!parent::is_valid_value($value)) { 1042 return false; 1043 } 1044 // Time MUST be in UTC format 1045 return(substr($value, -1) == 'Z'); 1046 } 1047 } 1048 1049 class iCalendar_property_dtstamp extends iCalendar_property { 1050 1051 var $name = 'DTSTAMP'; 1052 var $val_type = RFC2445_TYPE_DATE_TIME; 1053 1054 function construct() { 1055 $this->valid_parameters = array( 1056 RFC2445_XNAME => RFC2445_OPTIONAL 1057 ); 1058 } 1059 1060 function is_valid_value($value) { 1061 if(!parent::is_valid_value($value)) { 1062 return false; 1063 } 1064 // Time MUST be in UTC format 1065 return(substr($value, -1) == 'Z'); 1066 } 1067 } 1068 1069 class iCalendar_property_last_modified extends iCalendar_property { 1070 var $name = 'LAST-MODIFIED'; 1071 var $val_type = RFC2445_TYPE_DATE_TIME; 1072 1073 function construct() { 1074 $this->valid_parameters = array( 1075 RFC2445_XNAME => RFC2445_OPTIONAL 1076 ); 1077 } 1078 1079 function is_valid_value($value) { 1080 if(!parent::is_valid_value($value)) { 1081 return false; 1082 } 1083 // Time MUST be in UTC format 1084 return(substr($value, -1) == 'Z'); 1085 } 1086 } 1087 1088 class iCalendar_property_sequence extends iCalendar_property { 1089 1090 var $name = 'SEQUENCE'; 1091 var $val_type = RFC2445_TYPE_INTEGER; 1092 var $val_default = 0; 1093 1094 function construct() { 1095 $this->valid_parameters = array( 1096 RFC2445_XNAME => RFC2445_OPTIONAL 1097 ); 1098 } 1099 1100 function is_valid_value($value) { 1101 if(!parent::is_valid_value($value)) { 1102 return false; 1103 } 1104 $value = intval($value); 1105 return ($value >= 0); 1106 } 1107 } 1108 1109 // 4.8.8 Miscellaneous Component Properties 1110 // ---------------------------------------- 1111 1112 class iCalendar_property_x extends iCalendar_property { 1113 1114 var $name = RFC2445_XNAME; 1115 var $val_type = NULL; 1116 1117 function construct() { 1118 $this->valid_parameters = array( 1119 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 1120 RFC2445_XNAME => RFC2445_OPTIONAL 1121 ); 1122 } 1123 1124 function set_name($name) { 1125 1126 $name = strtoupper($name); 1127 1128 if(rfc2445_is_xname($name)) { 1129 $this->name = $name; 1130 return true; 1131 } 1132 1133 return false; 1134 } 1135 } 1136 1137 class iCalendar_property_request_status extends iCalendar_property { 1138 1139 // IMPORTANT NOTE: This property value includes TEXT fields 1140 // separated by semicolons. Unfortunately, auto-value-formatting 1141 // cannot be used in this case. As an exception, the value passed 1142 // to this property MUST be already escaped. 1143 1144 var $name = 'REQUEST-STATUS'; 1145 var $val_type = RFC2445_TYPE_TEXT; 1146 1147 function construct() { 1148 $this->valid_parameters = array( 1149 'LANGUAGE' => RFC2445_OPTIONAL | RFC2445_ONCE, 1150 RFC2445_XNAME => RFC2445_OPTIONAL 1151 ); 1152 } 1153 1154 function is_valid_value($value) { 1155 if(!is_string($value) || empty($value)) { 1156 return false; 1157 } 1158 1159 $len = strlen($value); 1160 $parts = array(); 1161 $from = 0; 1162 $escch = false; 1163 1164 for($i = 0; $i < $len; ++$i) { 1165 if($value{$i} == ';' && !$escch) { 1166 // Token completed 1167 $parts[] = substr($value, $from, $i - $from); 1168 $from = $i + 1; 1169 continue; 1170 } 1171 $escch = ($value{$i} == '\\'); 1172 } 1173 // Add one last token with the remaining text; if the value 1174 // ended with a ';' it was illegal, so check that this token 1175 // is not the empty string. 1176 $parts[] = substr($value, $from); 1177 1178 $count = count($parts); 1179 1180 // May have 2 or 3 tokens (last one is optional) 1181 if($count != 2 && $count != 3) { 1182 return false; 1183 } 1184 1185 // REMEMBER: if ANY part is empty, we have an illegal value 1186 1187 // First token must be hierarchical numeric status (3 levels max) 1188 if(strlen($parts[0]) == 0) { 1189 return false; 1190 } 1191 1192 if($parts[0]{0} < '1' || $parts[0]{0} > '4') { 1193 return false; 1194 } 1195 1196 $len = strlen($parts[0]); 1197 1198 // Max 3 levels, and can't end with a period 1199 if($len > 5 || $parts[0]{$len - 1} == '.') { 1200 return false; 1201 } 1202 1203 for($i = 1; $i < $len; ++$i) { 1204 if(($i & 1) == 1 && $parts[0]{$i} != '.') { 1205 // Even-indexed chars must be periods 1206 return false; 1207 } 1208 else if(($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) { 1209 // Odd-indexed chars must be numbers 1210 return false; 1211 } 1212 } 1213 1214 // Second and third tokens must be TEXT, and already escaped, so 1215 // they are not allowed to have UNESCAPED semicolons, commas, slashes, 1216 // or any newlines at all 1217 1218 for($i = 1; $i < $count; ++$i) { 1219 if(strpos($parts[$i], "\n") !== false) { 1220 return false; 1221 } 1222 1223 $len = strlen($parts[$i]); 1224 if($len == 0) { 1225 // Cannot be empty 1226 return false; 1227 } 1228 1229 $parts[$i] .= '#'; // This guard token saves some conditionals in the loop 1230 1231 for($j = 0; $j < $len; ++$j) { 1232 $thischar = $parts[$i]{$j}; 1233 $nextchar = $parts[$i]{$j + 1}; 1234 if($thischar == '\\') { 1235 // Next char must now be one of ";,\nN" 1236 if($nextchar != ';' && $nextchar != ',' && $nextchar != '\\' && 1237 $nextchar != 'n' && $nextchar != 'N') { 1238 return false; 1239 } 1240 1241 // OK, this escaped sequence is correct, bypass next char 1242 ++$j; 1243 continue; 1244 } 1245 if($thischar == ';' || $thischar == ',' || $thischar == '\\') { 1246 // This wasn't escaped as it should 1247 return false; 1248 } 1249 } 1250 } 1251 1252 return true; 1253 } 1254 1255 function set_value($value) { 1256 // Must override this, otherwise the value would be quoted again 1257 if($this->is_valid_value($value)) { 1258 $this->value = $value; 1259 return true; 1260 } 1261 1262 return false; 1263 } 1264 1265 } 1266 1267 class iCalendar_property_trigger extends iCalendar_property { 1268 1269 var $name = 'TRIGGER'; 1270 var $val_type = RFC2445_TYPE_TEXT; 1271 1272 function construct() { 1273 $this->valid_parameters = array( 1274 RFC2445_XNAME => RFC2445_OPTIONAL 1275 ); 1276 } 1277 } 1278 1279 class iCalendar_property_action extends iCalendar_property { 1280 1281 var $name = 'ACTION'; 1282 var $val_type = RFC2445_TYPE_TEXT; 1283 1284 function construct() { 1285 $this->valid_parameters = array( 1286 'DISPLAY' => RFC2445_OPTIONAL | RFC2445_ONCE, 1287 RFC2445_XNAME => RFC2445_OPTIONAL 1288 ); 1289 } 1290 } 1291 1292 class iCalendar_property_x_wr_alarmuid extends iCalendar_property { 1293 1294 var $name = 'X_WR_ALARMUID'; 1295 var $val_type = RFC2445_TYPE_TEXT; 1296 1297 function construct() { 1298 $this->valid_parameters = array( 1299 RFC2445_XNAME => RFC2445_OPTIONAL 1300 ); 1301 } 1302 } 1303 1304 class iCalendar_property_tzoffsetto extends iCalendar_property { 1305 1306 var $name = 'TZOFFSETTO'; 1307 var $val_type = RFC2445_TYPE_TEXT; 1308 1309 function construct() { 1310 $this->valid_parameters = array( 1311 RFC2445_XNAME => RFC2445_OPTIONAL 1312 ); 1313 } 1314 } 1315 1316 class iCalendar_property_daylightc extends iCalendar_property { 1317 1318 var $name = 'DAYLIGHTC'; 1319 var $val_type = RFC2445_TYPE_INTEGER; 1320 1321 function construct() { 1322 $this->valid_parameters = array( 1323 RFC2445_XNAME => RFC2445_OPTIONAL 1324 ); 1325 } 1326 } 1327 1328 class iCalendar_property_standardc extends iCalendar_property { 1329 1330 var $name = 'STANDARDC'; 1331 var $val_type = RFC2445_TYPE_INTEGER; 1332 1333 function construct() { 1334 $this->valid_parameters = array( 1335 RFC2445_XNAME => RFC2445_OPTIONAL 1336 ); 1337 } 1338 } 1339 1340 class iCalendar_property_tzid extends iCalendar_property { 1341 1342 var $name = 'TZID'; 1343 var $val_type = RFC2445_TYPE_TEXT; 1344 1345 function construct() { 1346 $this->valid_parameters = array( 1347 RFC2445_XNAME => RFC2445_REQUIRED 1348 ); 1349 } 1350 } 1351 1352 ####################### 1353 /* 1354 class iCalendar_property_class extends iCalendar_property { 1355 1356 var $name = 'CLASS'; 1357 var $val_type = RFC2445_TYPE_TEXT; 1358 1359 function construct() { 1360 $this->valid_parameters = array( 1361 RFC2445_XNAME => RFC2445_OPTIONAL 1362 ); 1363 } 1364 } 1365 */ 1366 1367 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |