Completed
Pull Request — master (#98)
by
unknown
01:12
created

Event::watch()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 2
nc 2
nop 3
1
<?php
2
3
namespace Spatie\GoogleCalendar;
4
5
use DateTime;
6
use Carbon\Carbon;
7
use Google_Service_Calendar_Event;
8
use Illuminate\Support\Collection;
9
use Google_Service_Calendar_EventDateTime;
10
11
class Event
12
{
13
    /**
14
     * @var \Google_Service_Calendar_Event 
15
     */
16
    public $googleEvent;
17
18
    /**
19
     * @var string 
20
     */
21
    protected $calendarId;
22
23
    /**
24
     * @var array 
25
     */
26
    protected $attendees;
27
28
    public function __construct()
29
    {
30
        $this->attendees = [];
31
        $this->googleEvent = new Google_Service_Calendar_Event;
32
    }
33
34
    /**
35
     * @param \Google_Service_Calendar_Event $googleEvent
36
     * @param $calendarId
37
     *
38
     * @return static
39
     */
40
    public static function createFromGoogleCalendarEvent(Google_Service_Calendar_Event $googleEvent, $calendarId)
41
    {
42
        $event = new static;
43
44
        $event->googleEvent = $googleEvent;
45
        $event->calendarId = $calendarId;
46
47
        return $event;
48
    }
49
50
    /**
51
     * @param array       $properties
52
     * @param string|null $calendarId
53
     *
54
     * @return mixed
55
     */
56
    public static function create(array $properties, string $calendarId = null, $optParams = [])
57
    {
58
        $event = new static;
59
60
        $event->calendarId = static::getGoogleCalendar($calendarId)->getCalendarId();
61
62
        foreach ($properties as $name => $value) {
63
            $event->$name = $value;
64
        }
65
66
        return $event->save('insertEvent', $optParams);
67
    }
68
69
    public static function get(Carbon $startDateTime = null, Carbon $endDateTime = null, array $queryParameters = [], string $calendarId = null) : Collection
70
    {
71
        $googleCalendar = static::getGoogleCalendar($calendarId);
72
73
        $googleEvents = $googleCalendar->listEvents($startDateTime, $endDateTime, $queryParameters);
74
75
        $useUserOrder = isset($queryParameters['orderBy']);
76
77
        return collect($googleEvents)
78
            ->map(
79
                function (Google_Service_Calendar_Event $event) use ($calendarId) {
80
                    return static::createFromGoogleCalendarEvent($event, $calendarId);
81
                }
82
            )
83
            ->sortBy(
84
                function (Event $event, $index) use ($useUserOrder) {
85
                    if ($useUserOrder) {
86
                        return $index;
87
                    }
88
89
                    return $event->sortDate;
0 ignored issues
show
Documentation introduced by
The property sortDate 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...
90
                }
91
            )
92
            ->values();
93
    }
94
95
    public static function find($eventId, string $calendarId = null): self
96
    {
97
        $googleCalendar = static::getGoogleCalendar($calendarId);
98
99
        $googleEvent = $googleCalendar->getEvent($eventId);
100
101
        return static::createFromGoogleCalendarEvent($googleEvent, $calendarId);
102
    }
103
104
    public function __get($name)
105
    {
106
        $name = $this->getFieldName($name);
107
108
        if ($name === 'sortDate') {
109
            return $this->getSortDate();
110
        }
111
112
        $value = array_get($this->googleEvent, $name);
113
114
        if (in_array($name, ['start.date', 'end.date']) && $value) {
115
            $value = Carbon::createFromFormat('Y-m-d', $value)->startOfDay();
116
        }
117
118
        if (in_array($name, ['start.dateTime', 'end.dateTime']) && $value) {
119
            $value = Carbon::createFromFormat(DateTime::RFC3339, $value);
120
        }
121
122
        return $value;
123
    }
124
125
    public function __set($name, $value)
126
    {
127
        $name = $this->getFieldName($name);
128
129
        if (in_array($name, ['start.date', 'end.date', 'start.dateTime', 'end.dateTime'])) {
130
            $this->setDateProperty($name, $value);
131
132
            return;
133
        }
134
135
        array_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...
136
    }
137
138
    public function exists(): bool
139
    {
140
        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...
141
    }
142
143
    public function isAllDayEvent(): bool
144
    {
145
        return is_null($this->googleEvent['start']['dateTime']);
146
    }
147
148
    public function save(string $method = null, $optParams = []): self
149
    {
150
        $method = $method ?? ($this->exists() ? 'updateEvent' : 'insertEvent');
151
152
        $googleCalendar = $this->getGoogleCalendar($this->calendarId);
153
154
        $this->googleEvent->setAttendees($this->attendees);
155
156
        $googleEvent = $googleCalendar->$method($this, $optParams);
157
158
        return static::createFromGoogleCalendarEvent($googleEvent, $googleCalendar->getCalendarId());
159
    }
160
161
    public function update(array $attributes, $optParams = []): self
162
    {
163
        foreach ($attributes as $name => $value) {
164
            $this->$name = $value;
165
        }
166
167
        return $this->save('updateEvent', $optParams);
168
    }
169
170
    public function delete(string $eventId = null)
171
    {
172
        $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...
173
    }
174
175
    public function addAttendee(array $attendees)
176
    {
177
        $this->attendees[] = $attendees;
178
    }
179
180
    public function getSortDate(): string
181
    {
182
        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...
183
            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...
184
        }
185
186
        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...
187
            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...
188
        }
189
190
        return '';
191
    }
192
    /**
193
     * Setup a notification channel to a resource
194
     *
195
     * @param array       $postBody   Channel request body
196
     * 
197
     * @postBody string address  Receiving URL
198
     * 
199
     * @postBody long expiration  Channel expiration time
200
     * 
201
     * @postBody string id  A UUID or similar unique string that identifies this channel
202
     * 
203
     * @postBody string kind Identifies this as a notification channel used to 
204
     * watch for changes to a resource;
205
     * 
206
     * @postBody array params Additional parameters controlling delivery channel behavior
207
     * 
208
     * @postBody string payload;
209
     * 
210
     * @postBody string resourceId An opaque ID that identifies the resource 
211
     * being watched on this channel
212
     * 
213
     * @postBody string resourceUri A version-specific identifier for the 
214
     * watched resource
215
     * 
216
     * @postBody string token An arbitrary string delivered to the target 
217
     * address with each notification delivered over this channel
218
     * 
219
     * @postBody string type The type of delivery mechanism used for this channel
220
     * 
221
     * @param  array       $optParams  Optional parameters
222
     * @param  string|null $calendarId Calendar ID
223
     * @return Google_Service_Calendar_Channel
224
     */
225
    public function watch(array $postBody, $optParams = [],string $calendarId = null)
226
    {
227
228
        $calendar = $calendarId ?? static::getGoogleCalendar();
229
        $calendarService = $calendar->getService();
230
        $calendarId = $calendar->getCalendarId();
231
        $calendarChannel = new Google_Service_Calendar_Channel();
232
233
        foreach($postBody as $key => $item){
234
            $method = "set".$key;
235
            $calendarChannel->$method($item);
236
        }
237
238
        return $calendarService->events->watch($calendarId, $calendarChannel, $optParams);
239
    }     
240
241
    protected static function getGoogleCalendar(string $calendarId = null): GoogleCalendar
242
    {
243
        $calendarId = $calendarId ?? config('google-calendar.calendar_id');
244
245
        return GoogleCalendarFactory::createForCalendarId($calendarId);
246
    }
247
248
    protected function setDateProperty(string $name, Carbon $date)
249
    {
250
        $eventDateTime = new Google_Service_Calendar_EventDateTime;
251
252
        if (in_array($name, ['start.date', 'end.date'])) {
253
            $eventDateTime->setDate($date->format('Y-m-d'));
254
            $eventDateTime->setTimezone($date->getTimezone());
255
        }
256
257
        if (in_array($name, ['start.dateTime', 'end.dateTime'])) {
258
            $eventDateTime->setDateTime($date->format(DateTime::RFC3339));
259
            $eventDateTime->setTimezone($date->getTimezone());
260
        }
261
262
        if (starts_with($name, 'start')) {
263
            $this->googleEvent->setStart($eventDateTime);
264
        }
265
266
        if (starts_with($name, 'end')) {
267
            $this->googleEvent->setEnd($eventDateTime);
268
        }
269
    }
270
271
    protected function getFieldName(string $name): string
272
    {
273
        return [
274
                   'name' => 'summary',
275
                   'description' => 'description',
276
                   'startDate' => 'start.date',
277
                   'endDate' => 'end.date',
278
                   'startDateTime' => 'start.dateTime',
279
                   'endDateTime' => 'end.dateTime',
280
               ][$name] ?? $name;
281
    }
282
}
283