Completed
Pull Request — master (#163)
by
unknown
01:10
created

Event::setSourceProperty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Spatie\GoogleCalendar;
4
5
use Carbon\Carbon;
6
use Carbon\CarbonInterface;
7
use DateTime;
8
use Google_Service_Calendar_Event;
9
use Google_Service_Calendar_EventDateTime;
10
use Illuminate\Support\Arr;
11
use Illuminate\Support\Collection;
12
use Illuminate\Support\Str;
13
14
class Event
15
{
16
    /** @var \Google_Service_Calendar_Event */
17
    public $googleEvent;
18
19
    /** @var string */
20
    protected $calendarId;
21
22
    /** @var array */
23
    protected $attendees;
24
25
    public function __construct()
26
    {
27
        $this->attendees = [];
28
        $this->googleEvent = new Google_Service_Calendar_Event;
29
    }
30
31
    /**
32
     * @param \Google_Service_Calendar_Event $googleEvent
33
     * @param $calendarId
34
     *
35
     * @return static
36
     */
37
    public static function createFromGoogleCalendarEvent(Google_Service_Calendar_Event $googleEvent, $calendarId)
38
    {
39
        $event = new static;
40
41
        $event->googleEvent = $googleEvent;
42
        $event->calendarId = $calendarId;
43
44
        return $event;
45
    }
46
47
    /**
48
     * @param array $properties
49
     * @param string|null $calendarId
50
     *
51
     * @return mixed
52
     */
53
    public static function create(array $properties, string $calendarId = null, $optParams = [])
54
    {
55
        $event = new static;
56
57
        $event->calendarId = static::getGoogleCalendar($calendarId)->getCalendarId();
58
59
        foreach ($properties as $name => $value) {
60
            $event->$name = $value;
61
        }
62
63
        return $event->save('insertEvent', $optParams);
64
    }
65
66
    public static function quickCreate(string $text)
67
    {
68
        $event = new static;
69
70
        $event->calendarId = static::getGoogleCalendar()->getCalendarId();
71
72
        return $event->quickSave($text);
73
    }
74
75
    public static function get(CarbonInterface $startDateTime = null, CarbonInterface $endDateTime = null, array $queryParameters = [], string $calendarId = null): Collection
76
    {
77
        $googleCalendar = static::getGoogleCalendar($calendarId);
78
79
        $googleEvents = $googleCalendar->listEvents($startDateTime, $endDateTime, $queryParameters);
80
81
        $googleEventsList = $googleEvents->getItems();
82
83
        while ($googleEvents->getNextPageToken()) {
84
            $queryParameters['pageToken'] = $googleEvents->getNextPageToken();
85
86
            $googleEvents = $googleCalendar->listEvents($startDateTime, $endDateTime, $queryParameters);
87
88
            $googleEventsList = array_merge($googleEventsList, $googleEvents->getItems());
89
        }
90
91
        $useUserOrder = isset($queryParameters['orderBy']);
92
93
        return collect($googleEventsList)
94
            ->map(function (Google_Service_Calendar_Event $event) use ($calendarId) {
95
                return static::createFromGoogleCalendarEvent($event, $calendarId);
96
            })
97
            ->sortBy(function (self $event, $index) use ($useUserOrder) {
98
                if ($useUserOrder) {
99
                    return $index;
100
                }
101
102
                return $event->sortDate;
103
            })
104
            ->values();
105
    }
106
107
    public static function find($eventId, string $calendarId = null): self
108
    {
109
        $googleCalendar = static::getGoogleCalendar($calendarId);
110
111
        $googleEvent = $googleCalendar->getEvent($eventId);
112
113
        return static::createFromGoogleCalendarEvent($googleEvent, $calendarId);
114
    }
115
116
    public function __get($name)
117
    {
118
        $name = $this->getFieldName($name);
119
120
        if ($name === 'sortDate') {
121
            return $this->getSortDate();
122
        }
123
124
        if ($name === 'source') {
125
            return [
126
                'title' => $this->googleEvent->getSource()->title,
127
                'url' => $this->googleEvent->getSource()->url,
128
            ];
129
        }
130
131
        $value = Arr::get($this->googleEvent, $name);
132
133
        if (in_array($name, ['start.date', 'end.date']) && $value) {
134
            $value = Carbon::createFromFormat('Y-m-d', $value)->startOfDay();
135
        }
136
137
        if (in_array($name, ['start.dateTime', 'end.dateTime']) && $value) {
138
            $value = Carbon::createFromFormat(DateTime::RFC3339, $value);
139
        }
140
141
        return $value;
142
    }
143
144
    public function __set($name, $value)
145
    {
146
        $name = $this->getFieldName($name);
147
148
        if (in_array($name, ['start.date', 'end.date', 'start.dateTime', 'end.dateTime'])) {
149
            $this->setDateProperty($name, $value);
150
151
            return;
152
        }
153
154
        if ($name == 'source') {
155
            $this->setSourceProperty($value);
156
157
            return;
158
        }
159
160
        Arr::set($this->googleEvent, $name, $value);
0 ignored issues
show
Documentation introduced by
$this->googleEvent is of type object<Google_Service_Calendar_Event>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
161
    }
162
163
    public function exists(): bool
164
    {
165
        return $this->id != '';
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Spatie\GoogleCalendar\Event>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
166
    }
167
168
    public function isAllDayEvent(): bool
169
    {
170
        return is_null($this->googleEvent['start']['dateTime']);
171
    }
172
173
    public function save(string $method = null, $optParams = []): self
174
    {
175
        $method = $method ?? ($this->exists() ? 'updateEvent' : 'insertEvent');
176
177
        $googleCalendar = $this->getGoogleCalendar($this->calendarId);
178
179
        $this->googleEvent->setAttendees($this->attendees);
180
181
        $googleEvent = $googleCalendar->$method($this, $optParams);
182
183
        return static::createFromGoogleCalendarEvent($googleEvent, $googleCalendar->getCalendarId());
184
    }
185
186
    public function quickSave(string $text): self
187
    {
188
        $googleCalendar = $this->getGoogleCalendar($this->calendarId);
189
190
        $googleEvent = $googleCalendar->insertEventFromText($text);
191
192
        return static::createFromGoogleCalendarEvent($googleEvent, $googleCalendar->getCalendarId());
193
    }
194
195
    public function update(array $attributes, $optParams = []): self
196
    {
197
        foreach ($attributes as $name => $value) {
198
            $this->$name = $value;
199
        }
200
201
        return $this->save('updateEvent', $optParams);
202
    }
203
204
    public function delete(string $eventId = null)
205
    {
206
        $this->getGoogleCalendar($this->calendarId)->deleteEvent($eventId ?? $this->id);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Spatie\GoogleCalendar\Event>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
207
    }
208
209
    public function addAttendee(array $attendees)
210
    {
211
        $this->attendees[] = $attendees;
212
    }
213
214
    public function getSortDate(): string
215
    {
216
        if ($this->startDate) {
0 ignored issues
show
Documentation introduced by
The property startDate does not exist on object<Spatie\GoogleCalendar\Event>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
217
            return $this->startDate;
0 ignored issues
show
Documentation introduced by
The property startDate does not exist on object<Spatie\GoogleCalendar\Event>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
218
        }
219
220
        if ($this->startDateTime) {
0 ignored issues
show
Documentation introduced by
The property startDateTime does not exist on object<Spatie\GoogleCalendar\Event>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
221
            return $this->startDateTime;
0 ignored issues
show
Documentation introduced by
The property startDateTime does not exist on object<Spatie\GoogleCalendar\Event>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
222
        }
223
224
        return '';
225
    }
226
227
    public function getCalendarId(): string
228
    {
229
        return $this->calendarId;
230
    }
231
232
    protected static function getGoogleCalendar(string $calendarId = null): GoogleCalendar
233
    {
234
        $calendarId = $calendarId ?? config('google-calendar.calendar_id');
235
236
        return GoogleCalendarFactory::createForCalendarId($calendarId);
237
    }
238
239
    protected function setDateProperty(string $name, CarbonInterface $date)
240
    {
241
        $eventDateTime = new Google_Service_Calendar_EventDateTime;
242
243
        if (in_array($name, ['start.date', 'end.date'])) {
244
            $eventDateTime->setDate($date->format('Y-m-d'));
245
            $eventDateTime->setTimezone($date->getTimezone());
246
        }
247
248
        if (in_array($name, ['start.dateTime', 'end.dateTime'])) {
249
            $eventDateTime->setDateTime($date->format(DateTime::RFC3339));
250
            $eventDateTime->setTimezone($date->getTimezone());
251
        }
252
253
        if (Str::startsWith($name, 'start')) {
254
            $this->googleEvent->setStart($eventDateTime);
255
        }
256
257
        if (Str::startsWith($name, 'end')) {
258
            $this->googleEvent->setEnd($eventDateTime);
259
        }
260
    }
261
262
    protected function setSourceProperty(array $value)
263
    {
264
        $source = new \Google_Service_Calendar_EventSource([
265
            'title' => $value['title'],
266
            'url' => $value['url'],
267
        ]);
268
269
        $this->googleEvent->setSource($source);
270
    }
271
272
    protected function getFieldName(string $name): string
273
    {
274
        return [
275
            'name' => 'summary',
276
            'description' => 'description',
277
            'startDate' => 'start.date',
278
            'endDate' => 'end.date',
279
            'startDateTime' => 'start.dateTime',
280
            'endDateTime' => 'end.dateTime',
281
        ][$name] ?? $name;
282
    }
283
}
284