Completed
Pull Request — master (#57)
by
unknown
02:26 queued 01:09
created

Ics::generate()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 41
rs 8.6417
c 0
b 0
f 0
cc 6
nc 16
nop 1
1
<?php
2
3
namespace Spatie\CalendarLinks\Generators;
4
5
use Spatie\CalendarLinks\Link;
6
use Spatie\CalendarLinks\Generator;
7
8
/**
9
 * @see https://icalendar.org/RFC-Specifications/iCalendar-RFC-5545/
10
 */
11
class Ics implements Generator
12
{
13
    public function generate(Link $link): string
14
    {
15
        $url = [
16
            'BEGIN:VCALENDAR',
17
            'VERSION:2.0',
18
            'BEGIN:VTIMEZONE',
19
            'TZID:'.$link->from->format('e'),
20
            'END:VTIMEZONE',
21
            'BEGIN:VEVENT',
22
            'UID:'.$this->generateEventUid($link),
23
            'SUMMARY:'.$link->title,
24
        ];
25
26
        if ($link->allDay) {
27
            $dateTimeFormat = 'Ymd';
28
            $url[] = 'DTSTART:'.$link->from->format($dateTimeFormat);
29
            $url[] = 'DURATION:P1D';
30
        } else {
31
            $dateTimeFormat = "e:Ymd\THis";
32
            $url[] = 'DTSTART;TZID='.$link->from->format($dateTimeFormat);
33
            $url[] = 'DTEND;TZID='.$link->to->format($dateTimeFormat);
34
        }
35
36
        if ($link->description) {
37
            $url[] = 'DESCRIPTION:'.$this->escapeString($link->description);
38
        }
39
        if ($link->address) {
40
            $url[] = 'LOCATION:'.$this->escapeString($link->address);
41
        }
42
        if ($link->attendees) {
0 ignored issues
show
Documentation introduced by
The property $attendees is declared protected in Spatie\CalendarLinks\Link. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Bug Best Practice introduced by
The expression $link->attendees of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
43
            foreach ($link->attendees as $attendee) {
0 ignored issues
show
Documentation introduced by
The property $attendees is declared protected in Spatie\CalendarLinks\Link. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
44
                $url[] = 'ATTENDEE:'.$attendee;
45
            }
46
        }
47
48
        $url[] = 'END:VEVENT';
49
        $url[] = 'END:VCALENDAR';
50
        $redirectLink = implode('%0d%0a', $url);
51
52
        return 'data:text/calendar;charset=utf8,'.$redirectLink;
53
    }
54
55
    /** @see https://tools.ietf.org/html/rfc5545.html#section-3.3.11 */
56
    protected function escapeString(string $field): string
57
    {
58
        return addcslashes($field, "\n,;");
59
    }
60
61
    /** @see https://tools.ietf.org/html/rfc5545#section-3.8.4.7 */
62
    protected function generateEventUid(Link $link): string
63
    {
64
        return md5($link->from->format(\DateTime::ATOM).$link->to->format(\DateTime::ATOM).$link->title.$link->address);
65
    }
66
}
67