Completed
Pull Request — master (#89)
by Markus
02:20
created

Event::setTimezoneString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 0
cts 0
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of the eluceo/iCal package.
5
 *
6
 * (c) Markus Poerschke <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Eluceo\iCal\Component;
13
14
use Eluceo\iCal\Component;
15
use Eluceo\iCal\Property;
16
use Eluceo\iCal\Property\DateTimeProperty;
17
use Eluceo\iCal\Property\DateTimesProperty;
18
use Eluceo\iCal\Property\Event\Attendees;
19
use Eluceo\iCal\Property\Event\Organizer;
20
use Eluceo\iCal\Property\Event\RecurrenceId;
21
use Eluceo\iCal\Property\Event\RecurrenceRule;
22
use Eluceo\iCal\PropertyBag;
23
24
/**
25
 * Implementation of the EVENT component.
26
 */
27
class Event extends Component
28
{
29
    const TIME_TRANSPARENCY_OPAQUE = 'OPAQUE';
30
    const TIME_TRANSPARENCY_TRANSPARENT = 'TRANSPARENT';
31
32
    const STATUS_TENTATIVE = 'TENTATIVE';
33
    const STATUS_CONFIRMED = 'CONFIRMED';
34
    const STATUS_CANCELLED = 'CANCELLED';
35
36
    /**
37
     * @var string
38
     */
39
    protected $uniqueId;
40
41
    /**
42
     * The property indicates the date/time that the instance of
43
     * the iCalendar object was created.
44
     *
45
     * The value MUST be specified in the UTC time format.
46
     *
47
     * @var \DateTime
48
     */
49
    protected $dtStamp;
50
51
    /**
52
     * @var \DateTime
53
     */
54
    protected $dtStart;
55
56
    /**
57
     * Preferentially chosen over the duration if both are set.
58
     *
59
     * @var \DateTime
60
     */
61
    protected $dtEnd;
62
63
    /**
64
     * @var \DateInterval
65
     */
66
    protected $duration;
67
68
    /**
69
     * @var bool
70
     */
71
    protected $noTime = false;
72
73
    /**
74
     * @var string
75
     */
76
    protected $url;
77
78
    /**
79
     * @var string
80
     */
81
    protected $location;
82
83
    /**
84
     * @var string
85
     */
86
    protected $locationTitle;
87
88
    /**
89
     * @var string
90
     */
91
    protected $locationGeo;
92
93
    /**
94
     * @var string
95
     */
96
    protected $summary;
97
98
    /**
99
     * @var Organizer
100
     */
101
    protected $organizer;
102
103
    /**
104
     * @see https://tools.ietf.org/html/rfc5545#section-3.8.2.7
105
     *
106
     * @var string
107
     */
108
    protected $transparency = self::TIME_TRANSPARENCY_OPAQUE;
109
110
    /**
111
     * If set to true the timezone will be added to the event.
112
     *
113
     * @var bool
114
     */
115
    protected $useTimezone = false;
116
117
    /**
118
     * If set will we used as the timezone identifier
119
     *
120
     * @var string
121
     */
122
    protected $timezoneString = '';
123
124
    /**
125
     * @var int
126
     */
127
    protected $sequence = 0;
128
129
    /**
130
     * @var Attendees
131
     */
132
    protected $attendees;
133
134
    /**
135
     * @var string
136
     */
137
    protected $description;
138
139
    /**
140
     * @var string
141
     */
142
    protected $descriptionHTML;
143
144
    /**
145
     * @var string
146
     */
147
    protected $status;
148
149
    /**
150
     * @var RecurrenceRule
151
     */
152
    protected $recurrenceRule;
153
154
    /**
155
     * @var array
156
     */
157
    protected $recurrenceRules = [];
158
159
    /**
160
     * This property specifies the date and time that the calendar
161
     * information was created.
162
     *
163
     * The value MUST be specified in the UTC time format.
164
     *
165
     * @var \DateTime
166
     */
167
    protected $created;
168
169
    /**
170
     * The property specifies the date and time that the information
171
     * associated with the calendar component was last revised.
172
     *
173
     * The value MUST be specified in the UTC time format.
174
     *
175
     * @var \DateTime
176
     */
177
    protected $modified;
178
179
    /**
180
     * Indicates if the UTC time should be used or not.
181
     *
182
     * @var bool
183
     */
184
    protected $useUtc = true;
185
186
    /**
187
     * @var bool
188
     */
189
    protected $cancelled;
190
191
    /**
192
     * This property is used to specify categories or subtypes
193
     * of the calendar component.  The categories are useful in searching
194
     * for a calendar component of a particular type and category.
195
     *
196
     * @see https://tools.ietf.org/html/rfc5545#section-3.8.1.2
197
     *
198
     * @var array
199
     */
200
    protected $categories;
201
202
    /**
203
     * https://tools.ietf.org/html/rfc5545#section-3.8.1.3.
204
     *
205
     * @var bool
206
     */
207
    protected $isPrivate = false;
208
209
    /**
210
     * Dates to be excluded from a series of events.
211
     *
212
     * @var \DateTimeInterface[]
213
     */
214
    protected $exDates = [];
215 4
216
    /**
217 4
     * @var RecurrenceId
218 2
     */
219 2
    protected $recurrenceId;
220
221 4
    public function __construct($uniqueId = null)
222 4
    {
223
        if (null == $uniqueId) {
224
            $uniqueId = uniqid();
225
        }
226
227 4
        $this->uniqueId = $uniqueId;
228
    }
229 4
230
    /**
231
     * {@inheritdoc}
232
     */
233
    public function getType()
234
    {
235 4
        return 'VEVENT';
236
    }
237 4
238
    /**
239
     * {@inheritdoc}
240 4
     */
241
    public function buildPropertyBag()
242 4
    {
243 4
        $propertyBag = new PropertyBag();
244 4
245
        // mandatory information
246 4
        $propertyBag->set('UID', $this->uniqueId);
247
248
        $propertyBag->add(new DateTimeProperty('DTSTART', $this->dtStart, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString));
249
        $propertyBag->set('SEQUENCE', $this->sequence);
250
        $propertyBag->set('TRANSP', $this->transparency);
251 4
252 2
        if ($this->status) {
253
            $propertyBag->set('STATUS', $this->status);
254
        }
255 2
256 4
        // An event can have a 'dtend' or 'duration', but not both.
257
        if (null != $this->dtEnd) {
258
            if ($this->noTime === true) {
259
                $this->dtEnd->add(new \DateInterval('P1D'));
260
            }
261 4
            $propertyBag->add(new DateTimeProperty('DTEND', $this->dtEnd, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString));
262
        } elseif (null != $this->duration) {
263
            $propertyBag->set('DURATION', $this->duration->format('P%dDT%hH%iM%sS'));
264
        }
265 4
266
        // optional information
267
        if (null != $this->url) {
268
            $propertyBag->set('URL', $this->url);
269
        }
270
271
        if (null != $this->location) {
272
            $propertyBag->set('LOCATION', $this->location);
273
274
            if (null != $this->locationGeo) {
275
                $propertyBag->add(
276
                    new Property(
277
                        'X-APPLE-STRUCTURED-LOCATION',
278
                        'geo:' . $this->locationGeo,
279
                        [
280
                            'VALUE' => 'URI',
281
                            'X-ADDRESS' => $this->location,
282
                            'X-APPLE-RADIUS' => 49,
283
                            'X-TITLE' => $this->locationTitle,
284
                        ]
285 4
                    )
286
                );
287
                $propertyBag->set('GEO', str_replace(',', ';', $this->locationGeo));
288
            }
289 4
        }
290
291
        if (null != $this->summary) {
292
            $propertyBag->set('SUMMARY', $this->summary);
293 4
        }
294
295 4
        if (null != $this->attendees) {
296 2
            $propertyBag->add($this->attendees);
297 2
        }
298
299 4
        $propertyBag->set('CLASS', $this->isPrivate ? 'PRIVATE' : 'PUBLIC');
300
301
        if (null != $this->description) {
302
            $propertyBag->set('DESCRIPTION', $this->description);
303
        }
304
305
        if (null != $this->descriptionHTML) {
306
            $propertyBag->add(
307
                new Property(
308
                    'X-ALT-DESC',
309
                    $this->descriptionHTML,
310
                    [
311 4
                        'FMTTYPE' => 'text/html',
312
                    ]
313
                )
314
            );
315 4
        }
316
317 4
        if (null != $this->recurrenceRule) {
318
            $propertyBag->set('RRULE', $this->recurrenceRule);
319 4
        }
320
321
        foreach ($this->recurrenceRules as $recurrenceRule) {
322
            $propertyBag->set('RRULE', $recurrenceRule);
323
        }
324 4
325
        if (null != $this->recurrenceId) {
326
            $this->recurrenceId->applyTimeSettings($this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString);
327
            $propertyBag->add($this->recurrenceId);
328 4
        }
329
330
        if (!empty($this->exDates)) {
331
            $propertyBag->add(new DateTimesProperty('EXDATE', $this->exDates, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString));
332 4
        }
333 2
334 2
        if ($this->cancelled) {
335
            $propertyBag->set('STATUS', 'CANCELLED');
336 4
        }
337
338
        if (null != $this->organizer) {
339
            $propertyBag->add($this->organizer);
340 4
        }
341
342
        if ($this->noTime) {
343
            $propertyBag->set('X-MICROSOFT-CDO-ALLDAYEVENT', 'TRUE');
344 4
        }
345 4
346 4
        if (null != $this->categories) {
347
            $propertyBag->set('CATEGORIES', $this->categories);
348 4
        }
349
350
        $propertyBag->add(
351
            new DateTimeProperty('DTSTAMP', $this->dtStamp ?: new \DateTimeImmutable(), false, false, true)
352 4
        );
353
354
        if ($this->created) {
355
            $propertyBag->add(new DateTimeProperty('CREATED', $this->created, false, false, true));
356 4
        }
357
358
        if ($this->modified) {
359
            $propertyBag->add(new DateTimeProperty('LAST-MODIFIED', $this->modified, false, false, true));
360
        }
361
362
        return $propertyBag;
363
    }
364 2
365
    /**
366 2
     * @param $dtEnd
367
     *
368 2
     * @return $this
369
     */
370
    public function setDtEnd($dtEnd)
371
    {
372
        $this->dtEnd = $dtEnd;
373
374
        return $this;
375
    }
376 2
377
    public function getDtEnd()
378 2
    {
379
        return $this->dtEnd;
380 2
    }
381
382
    public function setDtStart($dtStart)
383
    {
384
        $this->dtStart = $dtStart;
385
386
        return $this;
387
    }
388
389
    public function getDtStart()
390
    {
391
        return $this->dtStart;
392
    }
393
394
    /**
395
     * @param $dtStamp
396
     *
397
     * @return $this
398
     */
399
    public function setDtStamp($dtStamp)
400
    {
401
        $this->dtStamp = $dtStamp;
402
403
        return $this;
404
    }
405
406
    /**
407
     * @param $duration
408
     *
409
     * @return $this
410
     */
411
    public function setDuration($duration)
412
    {
413
        $this->duration = $duration;
414
415
        return $this;
416
    }
417
418
    /**
419
     * @param        $location
420
     * @param string $title
421
     * @param null   $geo
422
     *
423
     * @return $this
424
     */
425
    public function setLocation($location, $title = '', $geo = null)
426
    {
427
        $this->location = $location;
428
        $this->locationTitle = $title;
429
        $this->locationGeo = $geo;
430
431
        return $this;
432
    }
433
434
    /**
435
     * @param $noTime
436
     *
437
     * @return $this
438
     */
439
    public function setNoTime($noTime)
440
    {
441
        $this->noTime = $noTime;
442
443
        return $this;
444
    }
445
446
    /**
447
     * @param int $sequence
448
     *
449
     * @return $this
450
     */
451
    public function setSequence($sequence)
452
    {
453
        $this->sequence = $sequence;
454
455
        return $this;
456
    }
457
458
    /**
459
     * @return int
460
     */
461
    public function getSequence()
462
    {
463
        return $this->sequence;
464
    }
465 2
466
    /**
467 2
     * @param Organizer $organizer
468
     *
469 2
     * @return $this
470
     */
471
    public function setOrganizer(Organizer $organizer)
472
    {
473
        $this->organizer = $organizer;
474
475
        return $this;
476
    }
477
478
    /**
479
     * @param $summary
480
     *
481
     * @return $this
482
     */
483
    public function setSummary($summary)
484
    {
485
        $this->summary = $summary;
486
487
        return $this;
488
    }
489
490
    /**
491
     * @param $uniqueId
492
     *
493
     * @return $this
494
     */
495
    public function setUniqueId($uniqueId)
496
    {
497
        $this->uniqueId = $uniqueId;
498
499
        return $this;
500
    }
501
502
    /**
503
     * @return string
504
     */
505
    public function getUniqueId()
506
    {
507
        return $this->uniqueId;
508
    }
509
510
    /**
511
     * @param $url
512
     *
513
     * @return $this
514
     */
515
    public function setUrl($url)
516
    {
517
        $this->url = $url;
518
519
        return $this;
520
    }
521
522
    /**
523
     * @param $useTimezone
524
     *
525
     * @return $this
526
     */
527
    public function setUseTimezone($useTimezone)
528
    {
529
        $this->useTimezone = $useTimezone;
530
531
        return $this;
532
    }
533
534
    /**
535
     * @return bool
536
     */
537
    public function getUseTimezone()
538
    {
539
        return $this->useTimezone;
540
    }
541
542
    /**
543
     * @param $timezoneString
544
     *
545
     * @return $this
546
     */
547
    public function setTimezoneString($timezoneString)
548
    {
549
        $this->timezoneString = $timezoneString;
550
551
        return $this;
552
    }
553
554
    /**
555
     * @return bool
556
     */
557
    public function getTimezoneString()
558
    {
559
        return $this->timezoneString;
560
    }
561
562
    /**
563
     * @param Attendees $attendees
564
     *
565
     * @return $this
566
     */
567
    public function setAttendees(Attendees $attendees)
568
    {
569
        $this->attendees = $attendees;
570
571
        return $this;
572
    }
573
574
    /**
575
     * @param string $attendee
576
     * @param array  $params
577 2
     *
578
     * @return $this
579 2
     */
580
    public function addAttendee($attendee, $params = [])
581 2
    {
582
        if (!isset($this->attendees)) {
583
            $this->attendees = new Attendees();
584
        }
585
        $this->attendees->add($attendee, $params);
586
587
        return $this;
588
    }
589
590
    /**
591
     * @return Attendees
592
     */
593
    public function getAttendees()
594
    {
595
        return $this->attendees;
596
    }
597
598
    /**
599
     * @param $description
600
     *
601
     * @return $this
602
     */
603
    public function setDescription($description)
604
    {
605
        $this->description = $description;
606
607
        return $this;
608
    }
609
610
    /**
611
     * @param $descriptionHTML
612
     *
613
     * @return $this
614
     */
615
    public function setDescriptionHTML($descriptionHTML)
616
    {
617
        $this->descriptionHTML = $descriptionHTML;
618
619
        return $this;
620
    }
621
622
    /**
623
     * @param bool $useUtc
624
     *
625
     * @return $this
626
     */
627
    public function setUseUtc($useUtc = true)
628
    {
629
        $this->useUtc = $useUtc;
630
631
        return $this;
632
    }
633
634
    /**
635
     * @return string
636
     */
637
    public function getDescription()
638
    {
639
        return $this->description;
640
    }
641
642
    /**
643
     * @return string
644
     */
645
    public function getDescriptionHTML()
646
    {
647
        return $this->descriptionHTML;
648
    }
649
650
    /**
651
     * @param $status
652
     *
653
     * @return $this
654
     */
655
    public function setCancelled($status)
656
    {
657
        $this->cancelled = (bool) $status;
658
659
        return $this;
660
    }
661
662
    /**
663
     * @param $transparency
664
     *
665
     * @return $this
666
     *
667
     * @throws \InvalidArgumentException
668
     */
669 View Code Duplication
    public function setTimeTransparency($transparency)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
670
    {
671
        $transparency = strtoupper($transparency);
672
        if ($transparency === self::TIME_TRANSPARENCY_OPAQUE
673
            || $transparency === self::TIME_TRANSPARENCY_TRANSPARENT
674
        ) {
675
            $this->transparency = $transparency;
676
        } else {
677
            throw new \InvalidArgumentException('Invalid value for transparancy');
678
        }
679
680
        return $this;
681
    }
682
683
    /**
684
     * @param $status
685
     *
686
     * @return $this
687
     *
688
     * @throws \InvalidArgumentException
689
     */
690
    public function setStatus($status)
691
    {
692
        $status = strtoupper($status);
693
        if ($status == self::STATUS_CANCELLED
694
            || $status == self::STATUS_CONFIRMED
695
            || $status == self::STATUS_TENTATIVE
696
        ) {
697
            $this->status = $status;
698
        } else {
699
            throw new \InvalidArgumentException('Invalid value for status');
700
        }
701
702
        return $this;
703
    }
704
705
    /**
706
     * @deprecated Deprecated since version 0.11.0, to be removed in 1.0. Use addRecurrenceRule instead.
707
     *
708
     * @param RecurrenceRule $recurrenceRule
709
     *
710
     * @return $this
711
     */
712
    public function setRecurrenceRule(RecurrenceRule $recurrenceRule)
713
    {
714
        @trigger_error('setRecurrenceRule() is deprecated since version 0.11.0 and will be removed in 1.0. Use addRecurrenceRule instead.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
715
716
        $this->recurrenceRule = $recurrenceRule;
717
718
        return $this;
719
    }
720
721
    /**
722
     * @deprecated Deprecated since version 0.11.0, to be removed in 1.0. Use getRecurrenceRules instead.
723
     *
724
     * @return RecurrenceRule
725
     */
726
    public function getRecurrenceRule()
727
    {
728
        @trigger_error('getRecurrenceRule() is deprecated since version 0.11.0 and will be removed in 1.0. Use getRecurrenceRules instead.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
729
730
        return $this->recurrenceRule;
731
    }
732
733
    /**
734
     * @param RecurrenceRule $recurrenceRule
735
     *
736
     * @return $this
737
     */
738
    public function addRecurrenceRule(RecurrenceRule $recurrenceRule)
739
    {
740
        $this->recurrenceRules[] = $recurrenceRule;
741
742
        return $this;
743
    }
744
745
    /**
746
     * @return array
747
     */
748
    public function getRecurrenceRules()
749
    {
750
        return $this->recurrenceRules;
751
    }
752
753
    /**
754
     * @param $dtStamp
755
     *
756
     * @return $this
757
     */
758
    public function setCreated($dtStamp)
759
    {
760
        $this->created = $dtStamp;
761
762
        return $this;
763
    }
764
765
    /**
766
     * @param $dtStamp
767
     *
768
     * @return $this
769
     */
770
    public function setModified($dtStamp)
771
    {
772
        $this->modified = $dtStamp;
773
774
        return $this;
775
    }
776
777
    /**
778
     * @param $categories
779
     *
780
     * @return $this
781
     */
782
    public function setCategories($categories)
783
    {
784
        $this->categories = $categories;
785
786
        return $this;
787
    }
788
789
    /**
790
     * Sets the event privacy.
791
     *
792
     * @param bool $flag
793
     *
794
     * @return $this
795
     */
796
    public function setIsPrivate($flag)
797
    {
798
        $this->isPrivate = (bool) $flag;
799
800
        return $this;
801
    }
802
803
    /**
804
     * @param \DateTimeInterface $dateTime
805
     *
806
     * @return \Eluceo\iCal\Component\Event
807
     */
808
    public function addExDate(\DateTimeInterface $dateTime)
809
    {
810
        $this->exDates[] = $dateTime;
811
812
        return $this;
813
    }
814
815
    /**
816
     * @return \DateTime[]
817
     */
818
    public function getExDates()
819
    {
820
        return $this->exDates;
821
    }
822
823
    /**
824
     * @param \DateTime[]
825
     *
826
     * @return \Eluceo\iCal\Component\Event
827
     */
828
    public function setExDates(array $exDates)
829
    {
830
        $this->exDates = $exDates;
831
832
        return $this;
833
    }
834
835
    /**
836
     * @return \Eluceo\iCal\Property\Event\RecurrenceId
837
     */
838
    public function getRecurrenceId()
839
    {
840
        return $this->recurrenceId;
841
    }
842
843
    /**
844
     * @param RecurrenceId $recurrenceId
845
     *
846
     * @return \Eluceo\iCal\Component\Event
847
     */
848
    public function setRecurrenceId(RecurrenceId $recurrenceId)
849
    {
850
        $this->recurrenceId = $recurrenceId;
851
852
        return $this;
853
    }
854
}
855