[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/modules/Calendar/iCal/ -> iCalendar_properties.php (source)

   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  ?>


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1