1*a1a3b679SAndreas Boehler<?php 2*a1a3b679SAndreas Boehler 3*a1a3b679SAndreas Boehlernamespace Sabre\VObject\Component; 4*a1a3b679SAndreas Boehler 5*a1a3b679SAndreas Boehleruse Sabre\VObject; 6*a1a3b679SAndreas Boehleruse Sabre\VObject\Reader; 7*a1a3b679SAndreas Boehleruse Sabre\VObject\Component; 8*a1a3b679SAndreas Boehleruse Sabre\VObject\Component\VAvailability; 9*a1a3b679SAndreas Boehler 10*a1a3b679SAndreas Boehler/** 11*a1a3b679SAndreas Boehler * We use `RFCxxx` has a placeholder for the 12*a1a3b679SAndreas Boehler * https://tools.ietf.org/html/draft-daboo-calendar-availability-05 name. 13*a1a3b679SAndreas Boehler */ 14*a1a3b679SAndreas Boehlerclass VAvailabilityTest extends \PHPUnit_Framework_TestCase { 15*a1a3b679SAndreas Boehler 16*a1a3b679SAndreas Boehler function testVAvailabilityComponent() { 17*a1a3b679SAndreas Boehler 18*a1a3b679SAndreas Boehler $vcal = <<<VCAL 19*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 20*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 21*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 22*a1a3b679SAndreas BoehlerEND:VCALENDAR 23*a1a3b679SAndreas BoehlerVCAL; 24*a1a3b679SAndreas Boehler $document = Reader::read($vcal); 25*a1a3b679SAndreas Boehler 26*a1a3b679SAndreas Boehler $this->assertInstanceOf(__NAMESPACE__ . '\VAvailability', $document->VAVAILABILITY); 27*a1a3b679SAndreas Boehler 28*a1a3b679SAndreas Boehler } 29*a1a3b679SAndreas Boehler 30*a1a3b679SAndreas Boehler function testRFCxxxSection3_1_availabilityprop_required() { 31*a1a3b679SAndreas Boehler 32*a1a3b679SAndreas Boehler // UID and DTSTAMP are present. 33*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read( 34*a1a3b679SAndreas Boehler<<<VCAL 35*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 36*a1a3b679SAndreas BoehlerVERSION:2.0 37*a1a3b679SAndreas BoehlerPRODID:-//id 38*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 39*a1a3b679SAndreas BoehlerUID:foo@test 40*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 41*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 42*a1a3b679SAndreas BoehlerEND:VCALENDAR 43*a1a3b679SAndreas BoehlerVCAL 44*a1a3b679SAndreas Boehler )); 45*a1a3b679SAndreas Boehler 46*a1a3b679SAndreas Boehler // UID and DTSTAMP are missing. 47*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read( 48*a1a3b679SAndreas Boehler<<<VCAL 49*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 50*a1a3b679SAndreas BoehlerVERSION:2.0 51*a1a3b679SAndreas BoehlerPRODID:-//id 52*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 53*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 54*a1a3b679SAndreas BoehlerEND:VCALENDAR 55*a1a3b679SAndreas BoehlerVCAL 56*a1a3b679SAndreas Boehler )); 57*a1a3b679SAndreas Boehler 58*a1a3b679SAndreas Boehler // DTSTAMP is missing. 59*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read( 60*a1a3b679SAndreas Boehler<<<VCAL 61*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 62*a1a3b679SAndreas BoehlerVERSION:2.0 63*a1a3b679SAndreas BoehlerPRODID:-//id 64*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 65*a1a3b679SAndreas BoehlerUID:foo@test 66*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 67*a1a3b679SAndreas BoehlerEND:VCALENDAR 68*a1a3b679SAndreas BoehlerVCAL 69*a1a3b679SAndreas Boehler )); 70*a1a3b679SAndreas Boehler 71*a1a3b679SAndreas Boehler // UID is missing. 72*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read( 73*a1a3b679SAndreas Boehler<<<VCAL 74*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 75*a1a3b679SAndreas BoehlerVERSION:2.0 76*a1a3b679SAndreas BoehlerPRODID:-//id 77*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 78*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 79*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 80*a1a3b679SAndreas BoehlerEND:VCALENDAR 81*a1a3b679SAndreas BoehlerVCAL 82*a1a3b679SAndreas Boehler )); 83*a1a3b679SAndreas Boehler 84*a1a3b679SAndreas Boehler } 85*a1a3b679SAndreas Boehler 86*a1a3b679SAndreas Boehler function testRFCxxxSection3_1_availabilityprop_optional_once() { 87*a1a3b679SAndreas Boehler 88*a1a3b679SAndreas Boehler $properties = array( 89*a1a3b679SAndreas Boehler 'BUSYTYPE:BUSY', 90*a1a3b679SAndreas Boehler 'CLASS:PUBLIC', 91*a1a3b679SAndreas Boehler 'CREATED:20111005T135125Z', 92*a1a3b679SAndreas Boehler 'DESCRIPTION:Long bla bla', 93*a1a3b679SAndreas Boehler 'DTSTART:20111005T020000', 94*a1a3b679SAndreas Boehler 'LAST-MODIFIED:20111005T135325Z', 95*a1a3b679SAndreas Boehler 'ORGANIZER:mailto:foo@example.com', 96*a1a3b679SAndreas Boehler 'PRIORITY:1', 97*a1a3b679SAndreas Boehler 'SEQUENCE:0', 98*a1a3b679SAndreas Boehler 'SUMMARY:Bla bla', 99*a1a3b679SAndreas Boehler 'URL:http://example.org/' 100*a1a3b679SAndreas Boehler ); 101*a1a3b679SAndreas Boehler 102*a1a3b679SAndreas Boehler // They are all present, only once. 103*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read($this->template($properties))); 104*a1a3b679SAndreas Boehler 105*a1a3b679SAndreas Boehler // We duplicate each one to see if it fails. 106*a1a3b679SAndreas Boehler foreach ($properties as $property) { 107*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read($this->template(array( 108*a1a3b679SAndreas Boehler $property, 109*a1a3b679SAndreas Boehler $property 110*a1a3b679SAndreas Boehler )))); 111*a1a3b679SAndreas Boehler } 112*a1a3b679SAndreas Boehler 113*a1a3b679SAndreas Boehler } 114*a1a3b679SAndreas Boehler 115*a1a3b679SAndreas Boehler function testRFCxxxSection3_1_availabilityprop_dtend_duration() { 116*a1a3b679SAndreas Boehler 117*a1a3b679SAndreas Boehler // Only DTEND. 118*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read($this->template(array( 119*a1a3b679SAndreas Boehler 'DTEND:21111005T133225Z' 120*a1a3b679SAndreas Boehler )))); 121*a1a3b679SAndreas Boehler 122*a1a3b679SAndreas Boehler // Only DURATION. 123*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read($this->template(array( 124*a1a3b679SAndreas Boehler 'DURATION:PT1H' 125*a1a3b679SAndreas Boehler )))); 126*a1a3b679SAndreas Boehler 127*a1a3b679SAndreas Boehler // Both (not allowed). 128*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read($this->template(array( 129*a1a3b679SAndreas Boehler 'DTEND:21111005T133225Z', 130*a1a3b679SAndreas Boehler 'DURATION:PT1H' 131*a1a3b679SAndreas Boehler )))); 132*a1a3b679SAndreas Boehler } 133*a1a3b679SAndreas Boehler 134*a1a3b679SAndreas Boehler function testAvailableSubComponent() { 135*a1a3b679SAndreas Boehler 136*a1a3b679SAndreas Boehler $vcal = <<<VCAL 137*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 138*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 139*a1a3b679SAndreas BoehlerBEGIN:AVAILABLE 140*a1a3b679SAndreas BoehlerEND:AVAILABLE 141*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 142*a1a3b679SAndreas BoehlerEND:VCALENDAR 143*a1a3b679SAndreas BoehlerVCAL; 144*a1a3b679SAndreas Boehler $document = Reader::read($vcal); 145*a1a3b679SAndreas Boehler 146*a1a3b679SAndreas Boehler $this->assertInstanceOf(__NAMESPACE__, $document->VAVAILABILITY->AVAILABLE); 147*a1a3b679SAndreas Boehler 148*a1a3b679SAndreas Boehler } 149*a1a3b679SAndreas Boehler 150*a1a3b679SAndreas Boehler function testRFCxxxSection3_1_availableprop_required() { 151*a1a3b679SAndreas Boehler 152*a1a3b679SAndreas Boehler // UID, DTSTAMP and DTSTART are present. 153*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read( 154*a1a3b679SAndreas Boehler<<<VCAL 155*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 156*a1a3b679SAndreas BoehlerVERSION:2.0 157*a1a3b679SAndreas BoehlerPRODID:-//id 158*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 159*a1a3b679SAndreas BoehlerUID:foo@test 160*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 161*a1a3b679SAndreas BoehlerBEGIN:AVAILABLE 162*a1a3b679SAndreas BoehlerUID:foo@test 163*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 164*a1a3b679SAndreas BoehlerDTSTART:20111005T133225Z 165*a1a3b679SAndreas BoehlerEND:AVAILABLE 166*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 167*a1a3b679SAndreas BoehlerEND:VCALENDAR 168*a1a3b679SAndreas BoehlerVCAL 169*a1a3b679SAndreas Boehler )); 170*a1a3b679SAndreas Boehler 171*a1a3b679SAndreas Boehler // UID, DTSTAMP and DTSTART are missing. 172*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read( 173*a1a3b679SAndreas Boehler<<<VCAL 174*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 175*a1a3b679SAndreas BoehlerVERSION:2.0 176*a1a3b679SAndreas BoehlerPRODID:-//id 177*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 178*a1a3b679SAndreas BoehlerUID:foo@test 179*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 180*a1a3b679SAndreas BoehlerBEGIN:AVAILABLE 181*a1a3b679SAndreas BoehlerEND:AVAILABLE 182*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 183*a1a3b679SAndreas BoehlerEND:VCALENDAR 184*a1a3b679SAndreas BoehlerVCAL 185*a1a3b679SAndreas Boehler )); 186*a1a3b679SAndreas Boehler 187*a1a3b679SAndreas Boehler // UID is missing. 188*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read( 189*a1a3b679SAndreas Boehler<<<VCAL 190*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 191*a1a3b679SAndreas BoehlerVERSION:2.0 192*a1a3b679SAndreas BoehlerPRODID:-//id 193*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 194*a1a3b679SAndreas BoehlerUID:foo@test 195*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 196*a1a3b679SAndreas BoehlerBEGIN:AVAILABLE 197*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 198*a1a3b679SAndreas BoehlerDTSTART:20111005T133225Z 199*a1a3b679SAndreas BoehlerEND:AVAILABLE 200*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 201*a1a3b679SAndreas BoehlerEND:VCALENDAR 202*a1a3b679SAndreas BoehlerVCAL 203*a1a3b679SAndreas Boehler )); 204*a1a3b679SAndreas Boehler 205*a1a3b679SAndreas Boehler // DTSTAMP is missing. 206*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read( 207*a1a3b679SAndreas Boehler<<<VCAL 208*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 209*a1a3b679SAndreas BoehlerVERSION:2.0 210*a1a3b679SAndreas BoehlerPRODID:-//id 211*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 212*a1a3b679SAndreas BoehlerUID:foo@test 213*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 214*a1a3b679SAndreas BoehlerBEGIN:AVAILABLE 215*a1a3b679SAndreas BoehlerUID:foo@test 216*a1a3b679SAndreas BoehlerDTSTART:20111005T133225Z 217*a1a3b679SAndreas BoehlerEND:AVAILABLE 218*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 219*a1a3b679SAndreas BoehlerEND:VCALENDAR 220*a1a3b679SAndreas BoehlerVCAL 221*a1a3b679SAndreas Boehler )); 222*a1a3b679SAndreas Boehler 223*a1a3b679SAndreas Boehler // DTSTART is missing. 224*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read( 225*a1a3b679SAndreas Boehler<<<VCAL 226*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 227*a1a3b679SAndreas BoehlerVERSION:2.0 228*a1a3b679SAndreas BoehlerPRODID:-//id 229*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 230*a1a3b679SAndreas BoehlerUID:foo@test 231*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 232*a1a3b679SAndreas BoehlerBEGIN:AVAILABLE 233*a1a3b679SAndreas BoehlerUID:foo@test 234*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 235*a1a3b679SAndreas BoehlerEND:AVAILABLE 236*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 237*a1a3b679SAndreas BoehlerEND:VCALENDAR 238*a1a3b679SAndreas BoehlerVCAL 239*a1a3b679SAndreas Boehler )); 240*a1a3b679SAndreas Boehler 241*a1a3b679SAndreas Boehler } 242*a1a3b679SAndreas Boehler 243*a1a3b679SAndreas Boehler function testRFCxxxSection3_1_available_dtend_duration() { 244*a1a3b679SAndreas Boehler 245*a1a3b679SAndreas Boehler // Only DTEND. 246*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read($this->templateAvailable(array( 247*a1a3b679SAndreas Boehler 'DTEND:21111005T133225Z' 248*a1a3b679SAndreas Boehler )))); 249*a1a3b679SAndreas Boehler 250*a1a3b679SAndreas Boehler // Only DURATION. 251*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read($this->templateAvailable(array( 252*a1a3b679SAndreas Boehler 'DURATION:PT1H' 253*a1a3b679SAndreas Boehler )))); 254*a1a3b679SAndreas Boehler 255*a1a3b679SAndreas Boehler // Both (not allowed). 256*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read($this->templateAvailable(array( 257*a1a3b679SAndreas Boehler 'DTEND:21111005T133225Z', 258*a1a3b679SAndreas Boehler 'DURATION:PT1H' 259*a1a3b679SAndreas Boehler )))); 260*a1a3b679SAndreas Boehler } 261*a1a3b679SAndreas Boehler 262*a1a3b679SAndreas Boehler function testRFCxxxSection3_1_available_optional_once() { 263*a1a3b679SAndreas Boehler 264*a1a3b679SAndreas Boehler $properties = array( 265*a1a3b679SAndreas Boehler 'CREATED:20111005T135125Z', 266*a1a3b679SAndreas Boehler 'DESCRIPTION:Long bla bla', 267*a1a3b679SAndreas Boehler 'LAST-MODIFIED:20111005T135325Z', 268*a1a3b679SAndreas Boehler 'RECURRENCE-ID;RANGE=THISANDFUTURE:19980401T133000Z', 269*a1a3b679SAndreas Boehler 'RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR', 270*a1a3b679SAndreas Boehler 'SUMMARY:Bla bla' 271*a1a3b679SAndreas Boehler ); 272*a1a3b679SAndreas Boehler 273*a1a3b679SAndreas Boehler // They are all present, only once. 274*a1a3b679SAndreas Boehler $this->assertIsValid(Reader::read($this->templateAvailable($properties))); 275*a1a3b679SAndreas Boehler 276*a1a3b679SAndreas Boehler // We duplicate each one to see if it fails. 277*a1a3b679SAndreas Boehler foreach ($properties as $property) { 278*a1a3b679SAndreas Boehler $this->assertIsNotValid(Reader::read($this->templateAvailable(array( 279*a1a3b679SAndreas Boehler $property, 280*a1a3b679SAndreas Boehler $property 281*a1a3b679SAndreas Boehler )))); 282*a1a3b679SAndreas Boehler } 283*a1a3b679SAndreas Boehler 284*a1a3b679SAndreas Boehler } 285*a1a3b679SAndreas Boehler function testRFCxxxSection3_2() { 286*a1a3b679SAndreas Boehler 287*a1a3b679SAndreas Boehler $this->assertEquals( 288*a1a3b679SAndreas Boehler 'BUSY', 289*a1a3b679SAndreas Boehler Reader::read($this->templateAvailable(array( 290*a1a3b679SAndreas Boehler 'BUSYTYPE:BUSY' 291*a1a3b679SAndreas Boehler ))) 292*a1a3b679SAndreas Boehler ->VAVAILABILITY 293*a1a3b679SAndreas Boehler ->AVAILABLE 294*a1a3b679SAndreas Boehler ->BUSYTYPE 295*a1a3b679SAndreas Boehler ->getValue() 296*a1a3b679SAndreas Boehler ); 297*a1a3b679SAndreas Boehler 298*a1a3b679SAndreas Boehler $this->assertEquals( 299*a1a3b679SAndreas Boehler 'BUSY-UNAVAILABLE', 300*a1a3b679SAndreas Boehler Reader::read($this->templateAvailable(array( 301*a1a3b679SAndreas Boehler 'BUSYTYPE:BUSY-UNAVAILABLE' 302*a1a3b679SAndreas Boehler ))) 303*a1a3b679SAndreas Boehler ->VAVAILABILITY 304*a1a3b679SAndreas Boehler ->AVAILABLE 305*a1a3b679SAndreas Boehler ->BUSYTYPE 306*a1a3b679SAndreas Boehler ->getValue() 307*a1a3b679SAndreas Boehler ); 308*a1a3b679SAndreas Boehler 309*a1a3b679SAndreas Boehler $this->assertEquals( 310*a1a3b679SAndreas Boehler 'BUSY-TENTATIVE', 311*a1a3b679SAndreas Boehler Reader::read($this->templateAvailable(array( 312*a1a3b679SAndreas Boehler 'BUSYTYPE:BUSY-TENTATIVE' 313*a1a3b679SAndreas Boehler ))) 314*a1a3b679SAndreas Boehler ->VAVAILABILITY 315*a1a3b679SAndreas Boehler ->AVAILABLE 316*a1a3b679SAndreas Boehler ->BUSYTYPE 317*a1a3b679SAndreas Boehler ->getValue() 318*a1a3b679SAndreas Boehler ); 319*a1a3b679SAndreas Boehler 320*a1a3b679SAndreas Boehler } 321*a1a3b679SAndreas Boehler 322*a1a3b679SAndreas Boehler protected function assertIsValid(VObject\Document $document) { 323*a1a3b679SAndreas Boehler 324*a1a3b679SAndreas Boehler $this->assertEmpty($document->validate()); 325*a1a3b679SAndreas Boehler 326*a1a3b679SAndreas Boehler } 327*a1a3b679SAndreas Boehler 328*a1a3b679SAndreas Boehler protected function assertIsNotValid(VObject\Document $document) { 329*a1a3b679SAndreas Boehler 330*a1a3b679SAndreas Boehler $this->assertNotEmpty($document->validate()); 331*a1a3b679SAndreas Boehler 332*a1a3b679SAndreas Boehler } 333*a1a3b679SAndreas Boehler 334*a1a3b679SAndreas Boehler protected function template(array $properties) { 335*a1a3b679SAndreas Boehler 336*a1a3b679SAndreas Boehler return $this->_template( 337*a1a3b679SAndreas Boehler <<<VCAL 338*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 339*a1a3b679SAndreas BoehlerVERSION:2.0 340*a1a3b679SAndreas BoehlerPRODID:-//id 341*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 342*a1a3b679SAndreas BoehlerUID:foo@test 343*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 344*a1a3b679SAndreas Boehler… 345*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 346*a1a3b679SAndreas BoehlerEND:VCALENDAR 347*a1a3b679SAndreas BoehlerVCAL 348*a1a3b679SAndreas Boehler, 349*a1a3b679SAndreas Boehler $properties 350*a1a3b679SAndreas Boehler ); 351*a1a3b679SAndreas Boehler 352*a1a3b679SAndreas Boehler } 353*a1a3b679SAndreas Boehler 354*a1a3b679SAndreas Boehler protected function templateAvailable(array $properties) { 355*a1a3b679SAndreas Boehler 356*a1a3b679SAndreas Boehler return $this->_template( 357*a1a3b679SAndreas Boehler <<<VCAL 358*a1a3b679SAndreas BoehlerBEGIN:VCALENDAR 359*a1a3b679SAndreas BoehlerVERSION:2.0 360*a1a3b679SAndreas BoehlerPRODID:-//id 361*a1a3b679SAndreas BoehlerBEGIN:VAVAILABILITY 362*a1a3b679SAndreas BoehlerUID:foo@test 363*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 364*a1a3b679SAndreas BoehlerBEGIN:AVAILABLE 365*a1a3b679SAndreas BoehlerUID:foo@test 366*a1a3b679SAndreas BoehlerDTSTAMP:20111005T133225Z 367*a1a3b679SAndreas BoehlerDTSTART:20111005T133225Z 368*a1a3b679SAndreas Boehler… 369*a1a3b679SAndreas BoehlerEND:AVAILABLE 370*a1a3b679SAndreas BoehlerEND:VAVAILABILITY 371*a1a3b679SAndreas BoehlerEND:VCALENDAR 372*a1a3b679SAndreas BoehlerVCAL 373*a1a3b679SAndreas Boehler, 374*a1a3b679SAndreas Boehler $properties 375*a1a3b679SAndreas Boehler ); 376*a1a3b679SAndreas Boehler 377*a1a3b679SAndreas Boehler } 378*a1a3b679SAndreas Boehler 379*a1a3b679SAndreas Boehler protected function _template($template, array $properties) { 380*a1a3b679SAndreas Boehler 381*a1a3b679SAndreas Boehler return str_replace('…', implode("\r\n", $properties), $template); 382*a1a3b679SAndreas Boehler 383*a1a3b679SAndreas Boehler } 384*a1a3b679SAndreas Boehler 385*a1a3b679SAndreas Boehler} 386