GCalAddEventLink::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 2
nc 2
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\GCalendar;
5
6
use Psr\Log\LoggerInterface;
7
use Psr\Log\NullLogger;
8
9
/**
10
 * Class to generate HTML link to allow the user to add event to his google calendar.
11
 * 
12
 * #### History
13
 * - *2020-12-15*   initial version
14
 * 
15
 * @package SKien/GCalendar
16
 * @version 1.0.0
17
 * @author Stefanius <[email protected]>
18
 * @copyright MIT License - see the LICENSE file for details
19
*/
20
class GCalAddEventLink
21
{
22
    public const EVENTEDIT_URL = 'https://calendar.google.com/calendar/r/eventedit';
23
    
24
    public const AVAILABLE = 'AVAILABLE';
25
    public const BUSY = 'BUSY';
26
    public const BLOCKING = 'BLOCKING';
27
    
28
    /** @var string subject of the event   */
29
    protected string $strSubject = '';
30
    /** @var string detailed text   */
31
    protected string $strDetails = '';
32
    /** @var \DateTime start date and time   */
33
    protected ?\DateTime $dtStart = null;
34
    /** @var \DateTime end date and time   */
35
    protected ?\DateTime $dtEnd = null;
36
    /** @var string location    */
37
    protected string $strLocation = '';
38
    /** @var string timezone    */
39
    protected string $strTimezone = '';
40
    /** @var bool all day event    */
41
    protected bool $bAllday = false;
42
    /** @var array list of guests    */
43
    protected array $aGuest = [];
44
    /** @var string transparency (one of self::AVAILABLE, self::BUSY or self::BLOCKING */
45
    protected string $strTransparency = '';
46
    /** @var LoggerInterface    PSR-3 logger */
47
    protected LoggerInterface $logger;
48
    
49
    /**
50
     * Constructor
51
     */
52
    public function __construct(?LoggerInterface $logger = null)
53
    {
54
        if ($logger === null ) {
55
            // to ensure logger always containing valid PSR-3 logger instance
56
            $this->logger = new NullLogger();
57
        } else {
58
            $this->logger = $logger;
59
        }
60
    }
61
    
62
    /**
63
     * Reset object
64
     */
65
    public function reset() : void
66
    {
67
        $this->strSubject = '';
68
        $this->strDetails = '';
69
        $this->dtStart = null;
70
        $this->dtEnd = null;
71
        $this->strLocation = '';
72
        $this->strTimezone = '';
73
        $this->bAllday = false;
74
        $this->aGuest = [];
75
        $this->strTransparency = '';
76
    }
77
    
78
    /**
79
     * Returns resulting HREF to add the event to the google calendar
80
     * @return string
81
     */
82
    public function getHREF() : string
83
    {
84
        if (!$this->validate()) {
85
            return '';            
86
        }
87
        $strHREF  = self::EVENTEDIT_URL;
88
        $strHREF .= $this->getEncodedParam('?text', $this->strSubject);
89
        $strHREF .= $this->getDatesParam();
90
        $strHREF .= $this->getEncodedParam('&ctz', $this->strTimezone);
91
        $strHREF .= $this->getEncodedParam('&details', $this->strDetails);
92
        $strHREF .= $this->getEncodedParam('&location', $this->strLocation);
93
        $strHREF .= $this->getEncodedParam('&crm', $this->strTransparency);
94
        $strHREF .= $this->getGuestParam();
95
        
96
        return $strHREF;
97
    }
98
    
99
    /**
100
     * @param string $strSubject
101
     */
102
    public function setSubject(string $strSubject) : void
103
    {
104
        $this->strSubject = $strSubject;
105
    }
106
107
    /**
108
     * @param string $strDetails
109
     */
110
    public function setDetails(string $strDetails) : void
111
    {
112
        $this->strDetails = $strDetails;
113
    }
114
115
    /**
116
     * @param \DateTime|string|int $start
117
     * @param string $strFormat
118
     */
119
    public function setStart($start, string $strFormat = '') : void
120
    {
121
        $this->dtStart = $this->getDateTime($start, $strFormat);
122
    }
123
124
    /**
125
     * @param \DateTime|string|int $end
126
     * @param string $strFormat
127
     */
128
    public function setEnd($end, string $strFormat = '') : void
129
    {
130
        $this->dtEnd = $this->getDateTime($end, $strFormat);
131
    }
132
    
133
    /**
134
     * Set duration of the event.
135
     * Start must be specifeid before - otherwise this call is ignored.
136
     * @param string $strIntervall valid intervall
137
     * @link https://www.php.net/manual/en/dateinterval.construct
138
     */
139
    public function setDuration(string $strIntervall) : void
140
    {
141
        if ($this->dtStart !== null) {
142
            $this->dtEnd = clone $this->dtStart;
143
            $di = new \DateInterval($strIntervall);
144
            $this->dtEnd->add($di);
145
        } else {
146
            $this->logger->warning('Call of GCalendar::setDuration() without call of GCalendar::setStart before');
147
        }
148
    }
149
150
    /**
151
     * @param string $strLocation
152
     */
153
    public function setLocation(string $strLocation) : void
154
    {
155
        $this->strLocation = $strLocation;
156
    }
157
    
158
    /**
159
     * @param string $strTimezone
160
     */
161
    public function setTimezone(string $strTimezone) : void
162
    {
163
        if (!in_array($strTimezone, \DateTimeZone::listIdentifiers())) {
164
            $this->logger->warning('Call of GCalendar::setTimezone() with invalid timezone', ['timezone' => $strTimezone]);
165
        } else {
166
            $this->strTimezone = $strTimezone;
167
        }
168
    }
169
170
    /**
171
     * @param boolean $bAllday
172
     */
173
    public function setAllday(bool $bAllday = true) : void
174
    {
175
        $this->bAllday = $bAllday;
176
    }
177
178
    /**
179
     * @param string $strGuest
180
     */
181
    public function addGuest(string $strGuest) : void
182
    {
183
        $this->aGuest[] = $strGuest;
184
    }
185
186
    /**
187
     * @param string $strTransparency
188
     */
189
    public function setTransparency(string $strTransparency) : void
190
    {
191
        $aValidTrp = [self::AVAILABLE, self::BUSY, self::BLOCKING];
192
        if (in_array($strTransparency, $aValidTrp)) {
193
            $this->strTransparency = $strTransparency;
194
        } else {
195
            $this->logger->warning('Invalid Transparency at GCalendar::setTransparency()!', ['strTransparency' => $strTransparency]);
196
        }
197
    }
198
    
199
    /**
200
     * Check, if object contains valid data
201
     * @return bool
202
     */
203
    private function validate() : bool
204
    {
205
        if ($this->dtStart === null) {
206
            $this->logger->warning('GCalendar: No start date/time set!');
207
        } else if ($this->dtEnd === null) {
208
            $this->dtEnd = clone $this->dtStart;
209
            if (!$this->bAllday && $this->dtEnd !== null) {
210
                $this->dtEnd->add(new \DateInterval('PT30M'));
0 ignored issues
show
Bug introduced by
The method add() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

210
                $this->dtEnd->/** @scrutinizer ignore-call */ 
211
                              add(new \DateInterval('PT30M'));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
211
            }
212
        }
213
        if ($this->strTimezone == '' && $this->dtStart !== null) {
214
            $this->strTimezone = $this->dtStart->getTimezone()->getName();
215
        }
216
        if (strlen($this->strSubject) === 0) {
217
            $this->logger->warning('GCalendar: No subject set!');
218
        }
219
        return strlen($this->strSubject) > 0 && $this->dtStart !== null && $this->dtEnd !== null;
220
    }
221
    
222
    /**
223
     * @param \DateTime|string|int $datetime
224
     * @param string $strFormat
225
     * @return \DateTime
226
     */
227
    private function getDateTime($datetime, string $strFormat = '') : ?\DateTime
228
    {
229
        $dt = null;
230
        if (is_object($datetime) && get_class($datetime) == 'DateTime') {
231
            // DateTime -object
232
            $dt = $datetime;
233
        } else if (is_numeric($datetime)) {
234
            // unix timestamp
235
            $dt = new \DateTime();
236
            $dt->setTimestamp(intval($datetime));
237
        } else {
238
            // formated string
239
            if ($strFormat != '') {
240
                // parse according given format
241
                $dt = \DateTime::createFromFormat($strFormat, (string) $datetime);
242
                if ($dt === false) {
243
                    $dt = null;
244
                    $this->logger->warning('Invalid Date parameter GCalendar::setStart()/setEnd()', ['datetime' => $datetime]);
245
                }
246
            } else {
247
                // assuming any English textual datetime
248
                $timestamp = strtotime((string) $datetime);
249
                if ($timestamp !== false) {
250
                    $dt = new \DateTime();
251
                    $dt->setTimestamp($timestamp);
252
                } else {
253
                    $this->logger->warning('Invalid Date parameter GCalendar::setStart()/setEnd()', ['datetime' => $datetime]);
254
                }
255
            }
256
        }
257
        return $dt;
258
    }
259
260
    /**
261
     *  
262
     * @param string $strParam
263
     * @param string $strValue
264
     * @return string
265
     */
266
    private function getEncodedParam(string $strParam, string $strValue) : string
267
    {
268
        if (strlen($strValue) == 0) {
269
            return '';
270
        }
271
        return $strParam . '=' . urlencode($strValue);
272
    }
273
    
274
    /**
275
     * 
276
     * @return string
277
     * @link https://www.php.net/manual/en/datetime.format.php
278
     */
279
    private function getDatesParam() : string
280
    {
281
        $strDates = '';
282
        if ($this->dtStart !== null && $this->dtEnd !== null) {
283
            $strFormat = 'Ymd\THis';
284
            if ($this->bAllday) {
285
                $this->dtEnd->add(new \DateInterval('P1D'));
286
                $strFormat = 'Ymd';
287
            }
288
            $strDates = '&dates=' . $this->dtStart->format($strFormat) . '/' . $this->dtEnd->format($strFormat);
289
        }
290
        return $strDates;
291
    }
292
    
293
    /**
294
     * @return string
295
     */
296
    private function getGuestParam() : string
297
    {
298
        if (count($this->aGuest) == 0) {
299
            return '';
300
        }
301
        $strSep = '';
302
        $strParam = '&add=';
303
        foreach ($this->aGuest as $strGuest) {
304
            $strParam .= $strSep . $strGuest;
305
            $strSep = ',';
306
        }
307
        return $strParam;
308
    }
309
}
310