Completed
Push — develop ( 4e1ddc...b1c313 )
by Seth
02:25
created
src/SyncIntoCanvas/Calendar.php 4 patches
Doc Comments   +3 added lines patch added patch discarded remove patch
@@ -323,6 +323,9 @@
 block discarded – undo
323 323
         $this->log(static::getTimestamp() . ' sync finished', $log);
324 324
     }
325 325
 
326
+    /**
327
+     * @param string $message
328
+     */
326 329
     private function log($message, Log $log, $flag = PEAR_LOG_INFO)
327 330
     {
328 331
         if ($log) {
Please login to merge, or discard this patch.
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -2,7 +2,6 @@
 block discarded – undo
2 2
 
3 3
 namespace smtech\CanvasICSSync\SyncIntoCanvas;
4 4
 
5
-use DateTime;
6 5
 use vcalendar;
7 6
 use Battis\DataUtilities;
8 7
 
Please login to merge, or discard this patch.
Indentation   +267 added lines, -267 removed lines patch added patch discarded remove patch
@@ -8,171 +8,171 @@  discard block
 block discarded – undo
8 8
 
9 9
 class Calendar
10 10
 {
11
-    /**
12
-     * Canvas calendar context
13
-     * @var CalendarContext
14
-     */
15
-    protected $context;
11
+	/**
12
+	 * Canvas calendar context
13
+	 * @var CalendarContext
14
+	 */
15
+	protected $context;
16 16
 
17
-    /**
18
-     * ICS or webcal feed URL
19
-     * @var string
20
-     */
21
-    protected $feedUrl;
17
+	/**
18
+	 * ICS or webcal feed URL
19
+	 * @var string
20
+	 */
21
+	protected $feedUrl;
22 22
 
23
-    /**
24
-     * Name of this calendar (extracted from feed)
25
-     * @var string
26
-     */
27
-    protected $name;
23
+	/**
24
+	 * Name of this calendar (extracted from feed)
25
+	 * @var string
26
+	 */
27
+	protected $name;
28 28
 
29
-    /**
30
-     * Filter for events in this calendar
31
-     * @var Filter
32
-     */
33
-    protected $filter;
29
+	/**
30
+	 * Filter for events in this calendar
31
+	 * @var Filter
32
+	 */
33
+	protected $filter;
34 34
 
35
-    /**
36
-     * Construct a Calendar object
37
-     *
38
-     * @param string $canvasUrl URL of a Canvas calendar context
39
-     * @param string $feedUrl URL of a webcal or ICS calendar feed
40
-     * @param boolean $enableFilter (Optional, default `false`)
41
-     * @param string $include (Optional) Regular expression to select events
42
-     *     for inclusion in the calendar sync
43
-     * @param string $exclude (Optional) Regular expression to select events
44
-     *     for exclusion from the calendar sync
45
-     */
46
-    public function __construct($canvasUrl, $feedUrl, $enableFilter = false, $include = null, $exclude = null)
47
-    {
48
-        $this->setContext(new CalendarContext($canvasUrl));
49
-        $this->setFeed($feedUrl);
50
-        $this->setFilter(new Filter(
51
-            $enableFilter,
52
-            $include,
53
-            $exclude
54
-        ));
55
-    }
35
+	/**
36
+	 * Construct a Calendar object
37
+	 *
38
+	 * @param string $canvasUrl URL of a Canvas calendar context
39
+	 * @param string $feedUrl URL of a webcal or ICS calendar feed
40
+	 * @param boolean $enableFilter (Optional, default `false`)
41
+	 * @param string $include (Optional) Regular expression to select events
42
+	 *     for inclusion in the calendar sync
43
+	 * @param string $exclude (Optional) Regular expression to select events
44
+	 *     for exclusion from the calendar sync
45
+	 */
46
+	public function __construct($canvasUrl, $feedUrl, $enableFilter = false, $include = null, $exclude = null)
47
+	{
48
+		$this->setContext(new CalendarContext($canvasUrl));
49
+		$this->setFeed($feedUrl);
50
+		$this->setFilter(new Filter(
51
+			$enableFilter,
52
+			$include,
53
+			$exclude
54
+		));
55
+	}
56 56
 
57
-    /**
58
-     * Set the Canvas calendar context
59
-     *
60
-     * @param CalendarContext $context
61
-     * @throws Exception If `$context` is null
62
-     */
63
-    public function setContext(CalendarContext $context)
64
-    {
65
-        if (!empty($context)) {
66
-            $this->context = $context;
67
-        } else {
68
-            throw new Exception(
69
-                'Context cannot be null'
70
-            );
71
-        }
72
-    }
57
+	/**
58
+	 * Set the Canvas calendar context
59
+	 *
60
+	 * @param CalendarContext $context
61
+	 * @throws Exception If `$context` is null
62
+	 */
63
+	public function setContext(CalendarContext $context)
64
+	{
65
+		if (!empty($context)) {
66
+			$this->context = $context;
67
+		} else {
68
+			throw new Exception(
69
+				'Context cannot be null'
70
+			);
71
+		}
72
+	}
73 73
 
74
-    /**
75
-     * Get the Canvas calendar context
76
-     *
77
-     * @return CalendarContext
78
-     */
79
-    public function getContext()
80
-    {
81
-        return $this->context;
82
-    }
74
+	/**
75
+	 * Get the Canvas calendar context
76
+	 *
77
+	 * @return CalendarContext
78
+	 */
79
+	public function getContext()
80
+	{
81
+		return $this->context;
82
+	}
83 83
 
84
-    /**
85
-     * Set the webcal or ICS feed URl for this calendar
86
-     *
87
-     * @param string $feedUrl
88
-     * @throws Exception If `$feedUrl` is not a valid URL
89
-     */
90
-    public function setFeedUrl($feedUrl)
91
-    {
92
-        if (!empty($feedUrl)) {
93
-            /* crude test to see if the feed is a valid URL */
94
-            $handle = fopen($feedUrl, 'r');
95
-            if ($handle !== false) {
96
-                $this->feedUrl = $feedUrl;
97
-            }
98
-        }
99
-        throw new Exception(
100
-            'Feed must be a valid URL'
101
-        );
102
-    }
84
+	/**
85
+	 * Set the webcal or ICS feed URl for this calendar
86
+	 *
87
+	 * @param string $feedUrl
88
+	 * @throws Exception If `$feedUrl` is not a valid URL
89
+	 */
90
+	public function setFeedUrl($feedUrl)
91
+	{
92
+		if (!empty($feedUrl)) {
93
+			/* crude test to see if the feed is a valid URL */
94
+			$handle = fopen($feedUrl, 'r');
95
+			if ($handle !== false) {
96
+				$this->feedUrl = $feedUrl;
97
+			}
98
+		}
99
+		throw new Exception(
100
+			'Feed must be a valid URL'
101
+		);
102
+	}
103 103
 
104
-    /**
105
-     * Get the feed URL for this calendar
106
-     *
107
-     * @return string
108
-     */
109
-    public function getFeedUrl()
110
-    {
111
-        return $this->feedUrl;
112
-    }
104
+	/**
105
+	 * Get the feed URL for this calendar
106
+	 *
107
+	 * @return string
108
+	 */
109
+	public function getFeedUrl()
110
+	{
111
+		return $this->feedUrl;
112
+	}
113 113
 
114
-    /**
115
-     * Set the name of the calendar
116
-     *
117
-     * @param string $name
118
-     */
119
-    public function setName($name)
120
-    {
121
-        $this->name = (string) $name;
122
-    }
114
+	/**
115
+	 * Set the name of the calendar
116
+	 *
117
+	 * @param string $name
118
+	 */
119
+	public function setName($name)
120
+	{
121
+		$this->name = (string) $name;
122
+	}
123 123
 
124
-    /**
125
-     * Get the name of the calendar
126
-     *
127
-     * @return string
128
-     */
129
-    public function getName()
130
-    {
131
-        return $this->name;
132
-    }
124
+	/**
125
+	 * Get the name of the calendar
126
+	 *
127
+	 * @return string
128
+	 */
129
+	public function getName()
130
+	{
131
+		return $this->name;
132
+	}
133 133
 
134
-    /**
135
-     * Set the regular expression filter for this calendar
136
-     *
137
-     * @param Filter $filter
138
-     */
139
-    public function setFilter(Filter $filter)
140
-    {
141
-        $this->filter = $filter;
142
-    }
134
+	/**
135
+	 * Set the regular expression filter for this calendar
136
+	 *
137
+	 * @param Filter $filter
138
+	 */
139
+	public function setFilter(Filter $filter)
140
+	{
141
+		$this->filter = $filter;
142
+	}
143 143
 
144
-    /**
145
-     * Get the regular expression filter for this calendar
146
-     *
147
-     * @return Filter
148
-     */
149
-    public function getFilter()
150
-    {
151
-        return $this->filter;
152
-    }
144
+	/**
145
+	 * Get the regular expression filter for this calendar
146
+	 *
147
+	 * @return Filter
148
+	 */
149
+	public function getFilter()
150
+	{
151
+		return $this->filter;
152
+	}
153 153
 
154
-    /**
155
-     * Generate a unique ID to identify this particular pairing of ICS feed and
156
-     * Canvas calendar
157
-     **/
158
-    protected function getId($algorithm = 'md5')
159
-    {
160
-        return hash($algorithm, $this->getContext()->getCanonicalUrl() . $this->getFeedUrl());
161
-    }
154
+	/**
155
+	 * Generate a unique ID to identify this particular pairing of ICS feed and
156
+	 * Canvas calendar
157
+	 **/
158
+	protected function getId($algorithm = 'md5')
159
+	{
160
+		return hash($algorithm, $this->getContext()->getCanonicalUrl() . $this->getFeedUrl());
161
+	}
162 162
 
163
-    public function getContextCode()
164
-    {
165
-        return $this->getContext()->getContext() . '_' . $this->getContext()->getId();
166
-    }
163
+	public function getContextCode()
164
+	{
165
+		return $this->getContext()->getContext() . '_' . $this->getContext()->getId();
166
+	}
167 167
 
168
-    public function save()
169
-    {
170
-        $db = static::getDatabase();
171
-        $find = $db->prepare(
172
-            "SELECT * FROM `calendars` WHERE `id` = :id"
173
-        );
174
-        $update = $db->prepare(
175
-            "UPDATE `calendars`
168
+	public function save()
169
+	{
170
+		$db = static::getDatabase();
171
+		$find = $db->prepare(
172
+			"SELECT * FROM `calendars` WHERE `id` = :id"
173
+		);
174
+		$update = $db->prepare(
175
+			"UPDATE `calendars`
176 176
                 SET
177 177
                     `name` = :name,
178 178
                     `canvas_url` = :canvas_url,
@@ -183,9 +183,9 @@  discard block
 block discarded – undo
183 183
                     `exclude_regexp` = :exclude_regexp
184 184
                 WHERE
185 185
                 `id` = :id"
186
-        );
187
-        $insert = $db->prepare(
188
-            "INSERT INTO `calendars`
186
+		);
187
+		$insert = $db->prepare(
188
+			"INSERT INTO `calendars`
189 189
                 (
190 190
                     `id`,
191 191
                     `name`,
@@ -205,140 +205,140 @@  discard block
 block discarded – undo
205 205
                     :include_regexp,
206 206
                     :exclude_regexp
207 207
                 )"
208
-        );
209
-        $params = [
210
-            'id' => $this->getPairingHash(),
211
-            'name' => $this->getName(),
212
-            'canvas_url' => $this->getContext()->getCanonicalUrl(),
213
-            'ics_url' => $this->getFeedUrl(),
214
-            'synced' => static::getSyncTimestamp(),
215
-            'enable_regex_filter' => $this->getFilter()->isEnabled(),
216
-            'include_regexp' => $this->getFilter()->getIncludeExpression(),
217
-            'exclude_regexp' => $this->getFilter()->getExcludeExpression()
218
-        ];
208
+		);
209
+		$params = [
210
+			'id' => $this->getPairingHash(),
211
+			'name' => $this->getName(),
212
+			'canvas_url' => $this->getContext()->getCanonicalUrl(),
213
+			'ics_url' => $this->getFeedUrl(),
214
+			'synced' => static::getSyncTimestamp(),
215
+			'enable_regex_filter' => $this->getFilter()->isEnabled(),
216
+			'include_regexp' => $this->getFilter()->getIncludeExpression(),
217
+			'exclude_regexp' => $this->getFilter()->getExcludeExpression()
218
+		];
219 219
 
220
-        $find->execute($params);
221
-        if ($find->fetch() !== false) {
222
-            $update->execute($params);
223
-        } else {
224
-            $insert->execute($params);
225
-        }
226
-    }
220
+		$find->execute($params);
221
+		if ($find->fetch() !== false) {
222
+			$update->execute($params);
223
+		} else {
224
+			$insert->execute($params);
225
+		}
226
+	}
227 227
 
228
-    /**
229
-     * Load a Calendar from the database
230
-     *
231
-     * @param int $id
232
-     * @return Calendar
233
-     */
234
-    public static function load($id)
235
-    {
236
-        $find = static::getDatabase()->prepare(
237
-            "SELECT * FROM `calendars` WHERE `id` = :id"
238
-        );
239
-        $find->execute($id);
240
-        if (($calendar = $find->fetch()) !== false) {
241
-            return new Calendar(
242
-                $calendar['canvas_url'],
243
-                $calendar['ics_url'],
244
-                $calendar['enable_regex_filter'],
245
-                $calendar['include_regexp'],
246
-                $calendar['exclude_regexp']
247
-            );
248
-        }
249
-        return null;
250
-    }
228
+	/**
229
+	 * Load a Calendar from the database
230
+	 *
231
+	 * @param int $id
232
+	 * @return Calendar
233
+	 */
234
+	public static function load($id)
235
+	{
236
+		$find = static::getDatabase()->prepare(
237
+			"SELECT * FROM `calendars` WHERE `id` = :id"
238
+		);
239
+		$find->execute($id);
240
+		if (($calendar = $find->fetch()) !== false) {
241
+			return new Calendar(
242
+				$calendar['canvas_url'],
243
+				$calendar['ics_url'],
244
+				$calendar['enable_regex_filter'],
245
+				$calendar['include_regexp'],
246
+				$calendar['exclude_regexp']
247
+			);
248
+		}
249
+		return null;
250
+	}
251 251
 
252
-    public function sync(Log $log)
253
-    {
254
-        try {
255
-            $api->get($this->getContext()->getVerificationUrl());
256
-        } catch (Exception $e) {
257
-            $this->logThrow(new Exception("Cannot sync calendars without a valid Canvas context"), $log);
258
-        }
252
+	public function sync(Log $log)
253
+	{
254
+		try {
255
+			$api->get($this->getContext()->getVerificationUrl());
256
+		} catch (Exception $e) {
257
+			$this->logThrow(new Exception("Cannot sync calendars without a valid Canvas context"), $log);
258
+		}
259 259
 
260
-        if (!DataUtilities::URLexists($this>getFeedUrl())) {
261
-            $this->logThrow(new Exception("Cannot sync calendars with a valid calendar feed"), $log);
262
-        }
260
+		if (!DataUtilities::URLexists($this>getFeedUrl())) {
261
+			$this->logThrow(new Exception("Cannot sync calendars with a valid calendar feed"), $log);
262
+		}
263 263
 
264
-        $this->log(static::getTimestamp() . ' sync started', $log);
264
+		$this->log(static::getTimestamp() . ' sync started', $log);
265 265
 
266
-        $this->save();
266
+		$this->save();
267 267
 
268
-        $ics = new vcalendar([
269
-            'unique_id' => __FILE__,
270
-            'url' => $this->getFeedUrl()
271
-        ]);
272
-        $ics->parse();
268
+		$ics = new vcalendar([
269
+			'unique_id' => __FILE__,
270
+			'url' => $this->getFeedUrl()
271
+		]);
272
+		$ics->parse();
273 273
 
274
-        /*
274
+		/*
275 275
          * TODO: would it be worth the performance improvement to just process
276 276
          *     things from today's date forward? (i.e. ignore old items, even
277 277
          *     if they've changed...)
278 278
          */
279
-        /*
279
+		/*
280 280
          * TODO:0 the best window for syncing would be the term of the course
281 281
          *     in question, right? issue:12
282 282
          */
283
-        /*
283
+		/*
284 284
          * TODO:0 Arbitrarily selecting events in for a year on either side of
285 285
          *     today's date, probably a better system? issue:12
286 286
          */
287
-        foreach ($ics->selectComponents(
288
-            date('Y')-1, // startYear
289
-            date('m'), // startMonth
290
-            date('d'), // startDay
291
-            date('Y')+1, // endYEar
292
-            date('m'), // endMonth
293
-            date('d'), // endDay
294
-            'vevent', // cType
295
-            false, // flat
296
-            true, // any
297
-            true // split
298
-        ) as $year) {
299
-            foreach ($year as $month => $days) {
300
-                foreach ($days as $day => $events) {
301
-                    foreach ($events as $i => $_event) {
302
-                        try {
303
-                            $event = new Event($_event, $this);
304
-                            if ($this->getFilter()->filter($event)) {
305
-                                $event->save();
306
-                            } else {
307
-                                $event->delete();
308
-                            }
309
-                        } catch (Exception $e) {
310
-                            $this->logThrow($e, $log);
311
-                        }
312
-                    }
313
-                }
314
-            }
315
-        }
287
+		foreach ($ics->selectComponents(
288
+			date('Y')-1, // startYear
289
+			date('m'), // startMonth
290
+			date('d'), // startDay
291
+			date('Y')+1, // endYEar
292
+			date('m'), // endMonth
293
+			date('d'), // endDay
294
+			'vevent', // cType
295
+			false, // flat
296
+			true, // any
297
+			true // split
298
+		) as $year) {
299
+			foreach ($year as $month => $days) {
300
+				foreach ($days as $day => $events) {
301
+					foreach ($events as $i => $_event) {
302
+						try {
303
+							$event = new Event($_event, $this);
304
+							if ($this->getFilter()->filter($event)) {
305
+								$event->save();
306
+							} else {
307
+								$event->delete();
308
+							}
309
+						} catch (Exception $e) {
310
+							$this->logThrow($e, $log);
311
+						}
312
+					}
313
+				}
314
+			}
315
+		}
316 316
 
317
-        try {
318
-            Event::purgeUnmatched(static::getTimestamp(), $this);
319
-        } catch (Exception $e) {
320
-            $this->logThrow($e, $log);
321
-        }
317
+		try {
318
+			Event::purgeUnmatched(static::getTimestamp(), $this);
319
+		} catch (Exception $e) {
320
+			$this->logThrow($e, $log);
321
+		}
322 322
 
323
-        $this->log(static::getTimestamp() . ' sync finished', $log);
324
-    }
323
+		$this->log(static::getTimestamp() . ' sync finished', $log);
324
+	}
325 325
 
326
-    private function log($message, Log $log, $flag = PEAR_LOG_INFO)
327
-    {
328
-        if ($log) {
329
-            $log->log($message, $flag);
330
-        }
331
-    }
326
+	private function log($message, Log $log, $flag = PEAR_LOG_INFO)
327
+	{
328
+		if ($log) {
329
+			$log->log($message, $flag);
330
+		}
331
+	}
332 332
 
333
-    private function logThrow(
334
-        Exception $exception,
335
-        Log $log,
336
-        $flag = PEAR_LOG_ERR
337
-    ) {
338
-        if ($log) {
339
-            $log->log($e->getMessage() . ': ' . $e->getTraceAsString(), $flag);
340
-        } else {
341
-            throw $e;
342
-        }
343
-    }
333
+	private function logThrow(
334
+		Exception $exception,
335
+		Log $log,
336
+		$flag = PEAR_LOG_ERR
337
+	) {
338
+		if ($log) {
339
+			$log->log($e->getMessage() . ': ' . $e->getTraceAsString(), $flag);
340
+		} else {
341
+			throw $e;
342
+		}
343
+	}
344 344
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -118,7 +118,7 @@  discard block
 block discarded – undo
118 118
      */
119 119
     public function setName($name)
120 120
     {
121
-        $this->name = (string) $name;
121
+        $this->name = (string)$name;
122 122
     }
123 123
 
124 124
     /**
@@ -157,12 +157,12 @@  discard block
 block discarded – undo
157 157
      **/
158 158
     protected function getId($algorithm = 'md5')
159 159
     {
160
-        return hash($algorithm, $this->getContext()->getCanonicalUrl() . $this->getFeedUrl());
160
+        return hash($algorithm, $this->getContext()->getCanonicalUrl().$this->getFeedUrl());
161 161
     }
162 162
 
163 163
     public function getContextCode()
164 164
     {
165
-        return $this->getContext()->getContext() . '_' . $this->getContext()->getId();
165
+        return $this->getContext()->getContext().'_'.$this->getContext()->getId();
166 166
     }
167 167
 
168 168
     public function save()
@@ -257,11 +257,11 @@  discard block
 block discarded – undo
257 257
             $this->logThrow(new Exception("Cannot sync calendars without a valid Canvas context"), $log);
258 258
         }
259 259
 
260
-        if (!DataUtilities::URLexists($this>getFeedUrl())) {
260
+        if (!DataUtilities::URLexists($this > getFeedUrl())) {
261 261
             $this->logThrow(new Exception("Cannot sync calendars with a valid calendar feed"), $log);
262 262
         }
263 263
 
264
-        $this->log(static::getTimestamp() . ' sync started', $log);
264
+        $this->log(static::getTimestamp().' sync started', $log);
265 265
 
266 266
         $this->save();
267 267
 
@@ -285,10 +285,10 @@  discard block
 block discarded – undo
285 285
          *     today's date, probably a better system? issue:12
286 286
          */
287 287
         foreach ($ics->selectComponents(
288
-            date('Y')-1, // startYear
288
+            date('Y') - 1, // startYear
289 289
             date('m'), // startMonth
290 290
             date('d'), // startDay
291
-            date('Y')+1, // endYEar
291
+            date('Y') + 1, // endYEar
292 292
             date('m'), // endMonth
293 293
             date('d'), // endDay
294 294
             'vevent', // cType
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
             $this->logThrow($e, $log);
321 321
         }
322 322
 
323
-        $this->log(static::getTimestamp() . ' sync finished', $log);
323
+        $this->log(static::getTimestamp().' sync finished', $log);
324 324
     }
325 325
 
326 326
     private function log($message, Log $log, $flag = PEAR_LOG_INFO)
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
         $flag = PEAR_LOG_ERR
337 337
     ) {
338 338
         if ($log) {
339
-            $log->log($e->getMessage() . ': ' . $e->getTraceAsString(), $flag);
339
+            $log->log($e->getMessage().': '.$e->getTraceAsString(), $flag);
340 340
         } else {
341 341
             throw $e;
342 342
         }
Please login to merge, or discard this patch.
src/SyncIntoCanvas/Event.php 2 patches
Doc Comments   +3 added lines patch added patch discarded remove patch
@@ -204,6 +204,9 @@
 block discarded – undo
204 204
         }
205 205
     }
206 206
 
207
+    /**
208
+     * @param Calendar $calendar
209
+     */
207 210
     public static function purgeUnmatched($timestamp, $calendar)
208 211
     {
209 212
         $db = static::getDatabase();
Please login to merge, or discard this patch.
Indentation   +201 added lines, -201 removed lines patch added patch discarded remove patch
@@ -8,123 +8,123 @@  discard block
 block discarded – undo
8 8
 
9 9
 class Event extends Syncable
10 10
 {
11
-    /*
11
+	/*
12 12
      * TODO:0 Can we detect the timezone for the Canvas instance and use it? issue:18
13 13
      */
14
-    const LOCAL_TIMEZONE = 'US/Eastern';
15
-    const CANVAS_TIMESTAMP_FORMAT = 'Y-m-d\TH:iP';
16
-
17
-    const FIELD_MAP = [
18
-        'calendar_event[title]' => 'SUMMARY',
19
-        'calendar_event[description]' => 'DESCRIPTION',
20
-        'calendar_event[start_at]' => [
21
-            0 => 'X-CURRENT-DTSTART',
22
-            1 => 'DTSTART'
23
-        ],
24
-        'calendar_event[end_at]' => [
25
-            0 => 'X-CURRENT-DTEND',
26
-            1 => 'DTEND'
27
-        ],
28
-        'calendar_event[location_name]' => 'LOCATION'
29
-    ];
30
-
31
-    /**
32
-     * VEVENT
33
-     * @var vevent
34
-     */
35
-    protected $vevent;
36
-
37
-    /**
38
-     * Calendar
39
-     * @var Calendar
40
-     */
41
-    protected $calendar;
42
-
43
-    /**
44
-     * Unique hash identifying this version of this event
45
-     * @var string
46
-     */
47
-    protected $hash;
48
-
49
-    protected $canvasId;
50
-
51
-    public function __construct(vevent $vevent, Calendar $calendar)
52
-    {
53
-        if (empty($vevent)) {
54
-            throw new Exception(
55
-                'Valid VEVENT required'
56
-            );
57
-        }
58
-        $this->vevent = $vevent;
59
-
60
-        if (empty($calendar)) {
61
-            throw new Exception(
62
-                'Valid Calendar required'
63
-            );
64
-        }
65
-        $this->calendar = $calendar;
66
-
67
-        $this->getHash();
68
-    }
69
-
70
-    public function getProperty($property)
71
-    {
72
-        return (empty($this->vevent) ? false : $this->vevent->getProperty($property));
73
-    }
74
-
75
-    public function getCalendar()
76
-    {
77
-        return $this->calendar;
78
-    }
79
-
80
-    /**
81
-     * Generate a hash of this version of an event to cache in the database
82
-     **/
83
-    public function getHash($algorithm = 'md5')
84
-    {
85
-        if (empty($this->hash)) {
86
-            $blob = '';
87
-            foreach (static::$FIELD_MAP as $field) {
88
-                if (is_array($field)) {
89
-                    foreach ($field as $option) {
90
-                        if (!empty($property = $this->getProperty($option))) {
91
-                            $blob .= serialize($property);
92
-                            break;
93
-                        }
94
-                    }
95
-                } else {
96
-                    if (!empty($property = $this->getProperty($field))) {
97
-                        $blob .= serialize($property);
98
-                    }
99
-                }
100
-            }
101
-            $this->hash = hash($algorithm, $blob);
102
-        }
103
-        return $this->hash;
104
-    }
105
-
106
-    public function save()
107
-    {
108
-        $db = static::getDatabase();
109
-        $api = static::getApi();
110
-
111
-        $select = $db->prepare(
112
-            "SELECT *
14
+	const LOCAL_TIMEZONE = 'US/Eastern';
15
+	const CANVAS_TIMESTAMP_FORMAT = 'Y-m-d\TH:iP';
16
+
17
+	const FIELD_MAP = [
18
+		'calendar_event[title]' => 'SUMMARY',
19
+		'calendar_event[description]' => 'DESCRIPTION',
20
+		'calendar_event[start_at]' => [
21
+			0 => 'X-CURRENT-DTSTART',
22
+			1 => 'DTSTART'
23
+		],
24
+		'calendar_event[end_at]' => [
25
+			0 => 'X-CURRENT-DTEND',
26
+			1 => 'DTEND'
27
+		],
28
+		'calendar_event[location_name]' => 'LOCATION'
29
+	];
30
+
31
+	/**
32
+	 * VEVENT
33
+	 * @var vevent
34
+	 */
35
+	protected $vevent;
36
+
37
+	/**
38
+	 * Calendar
39
+	 * @var Calendar
40
+	 */
41
+	protected $calendar;
42
+
43
+	/**
44
+	 * Unique hash identifying this version of this event
45
+	 * @var string
46
+	 */
47
+	protected $hash;
48
+
49
+	protected $canvasId;
50
+
51
+	public function __construct(vevent $vevent, Calendar $calendar)
52
+	{
53
+		if (empty($vevent)) {
54
+			throw new Exception(
55
+				'Valid VEVENT required'
56
+			);
57
+		}
58
+		$this->vevent = $vevent;
59
+
60
+		if (empty($calendar)) {
61
+			throw new Exception(
62
+				'Valid Calendar required'
63
+			);
64
+		}
65
+		$this->calendar = $calendar;
66
+
67
+		$this->getHash();
68
+	}
69
+
70
+	public function getProperty($property)
71
+	{
72
+		return (empty($this->vevent) ? false : $this->vevent->getProperty($property));
73
+	}
74
+
75
+	public function getCalendar()
76
+	{
77
+		return $this->calendar;
78
+	}
79
+
80
+	/**
81
+	 * Generate a hash of this version of an event to cache in the database
82
+	 **/
83
+	public function getHash($algorithm = 'md5')
84
+	{
85
+		if (empty($this->hash)) {
86
+			$blob = '';
87
+			foreach (static::$FIELD_MAP as $field) {
88
+				if (is_array($field)) {
89
+					foreach ($field as $option) {
90
+						if (!empty($property = $this->getProperty($option))) {
91
+							$blob .= serialize($property);
92
+							break;
93
+						}
94
+					}
95
+				} else {
96
+					if (!empty($property = $this->getProperty($field))) {
97
+						$blob .= serialize($property);
98
+					}
99
+				}
100
+			}
101
+			$this->hash = hash($algorithm, $blob);
102
+		}
103
+		return $this->hash;
104
+	}
105
+
106
+	public function save()
107
+	{
108
+		$db = static::getDatabase();
109
+		$api = static::getApi();
110
+
111
+		$select = $db->prepare(
112
+			"SELECT *
113 113
                 FROM `events`
114 114
                 WHERE
115 115
                     `event_hash` = :event_hash AND
116 116
                     `calendar` = :calendar"
117
-        );
118
-        $update = $db->prepare(
119
-            "UPDATE `events`
117
+		);
118
+		$update = $db->prepare(
119
+			"UPDATE `events`
120 120
                 SET
121 121
                     `synced` = :synced
122 122
                 WHERE
123 123
                     `event_hash` = :event_hash AND
124 124
                     `calendar` = :calendar"
125
-        );
126
-        $insert = $db->prepare(
127
-            "INSERT INTO `events`
125
+		);
126
+		$insert = $db->prepare(
127
+			"INSERT INTO `events`
128 128
                 (
129 129
                     `calendar`,
130 130
                     `calendar_event[id]`,
@@ -136,114 +136,114 @@  discard block
 block discarded – undo
136 136
                     :event_hash,
137 137
                     :synced
138 138
                 )"
139
-        );
140
-
141
-        $params = [
142
-            'calendar' => $this->getCalendar()->getId(),
143
-            'event_hash' => $this->getHash(),
144
-            'synced' => static::getTimestamp()
145
-        ];
146
-
147
-        $select->execute($params);
148
-        if ($select->fetch() !== false) {
149
-            $update->execute($params);
150
-        } else {
151
-            /*
139
+		);
140
+
141
+		$params = [
142
+			'calendar' => $this->getCalendar()->getId(),
143
+			'event_hash' => $this->getHash(),
144
+			'synced' => static::getTimestamp()
145
+		];
146
+
147
+		$select->execute($params);
148
+		if ($select->fetch() !== false) {
149
+			$update->execute($params);
150
+		} else {
151
+			/*
152 152
              * FIXME: how sure are we of this? issue:14
153 153
              */
154
-            /*
154
+			/*
155 155
              * multi-day event instance start times need to be changed to
156 156
              * _this_ date
157 157
              */
158
-            $start = new DateTime(
159
-                iCalUtilityFunctions::_date2strdate(
160
-                    $this->getProperty('DTSTART')
161
-                )
162
-            );
163
-            $end = new DateTime(
164
-                iCalUtilityFunctions::_date2strdate(
165
-                    $this->getProperty('DTEND')
166
-                )
167
-            );
168
-            if ($this->getProperty('X-RECURRENCE')) {
169
-                $start = new DateTime($this->getProperty('X-CURRENT-DTSTART')[1]);
170
-                $end = new DateTime($this->getProperty('X-CURRENT-DTEND')[1]);
171
-            }
172
-            $start->setTimeZone(new DateTimeZone(self::LOCAL_TIMEZONE));
173
-            $end->setTimeZone(new DateTimeZone(self::LOCAL_TIMEZONE));
174
-
175
-            $calendarEvent = $api->post(
176
-                "/calendar_events",
177
-                [
178
-                    'calendar_event' => [
179
-                        'context_code' => $this->getCalendar()->getContextCode(),
180
-                        /*
158
+			$start = new DateTime(
159
+				iCalUtilityFunctions::_date2strdate(
160
+					$this->getProperty('DTSTART')
161
+				)
162
+			);
163
+			$end = new DateTime(
164
+				iCalUtilityFunctions::_date2strdate(
165
+					$this->getProperty('DTEND')
166
+				)
167
+			);
168
+			if ($this->getProperty('X-RECURRENCE')) {
169
+				$start = new DateTime($this->getProperty('X-CURRENT-DTSTART')[1]);
170
+				$end = new DateTime($this->getProperty('X-CURRENT-DTEND')[1]);
171
+			}
172
+			$start->setTimeZone(new DateTimeZone(self::LOCAL_TIMEZONE));
173
+			$end->setTimeZone(new DateTimeZone(self::LOCAL_TIMEZONE));
174
+
175
+			$calendarEvent = $api->post(
176
+				"/calendar_events",
177
+				[
178
+					'calendar_event' => [
179
+						'context_code' => $this->getCalendar()->getContextCode(),
180
+						/*
181 181
                          * TODO this should be configurable issue:5
182 182
                          */
183
-                        /* removing trailing [TAGS] from event title */
184
-                        'title' => preg_replace(
185
-                            '%^([^\]]+)(\s*\[[^\]]+\]\s*)+$%',
186
-                            '\\1',
187
-                            strip_tags($this->getProperty('SUMMARY'))
188
-                        ),
189
-                        'description' => Markdown::defaultTransform(
190
-                            str_replace(
191
-                                '\n',
192
-                                "\n\n",
193
-                                $this->getProperty('DESCRIPTION', 1)
194
-                            )
195
-                        ),
196
-                        'start_at' => $start->format(self::CANVAS_TIMESTAMP_FORMAT),
197
-                        'end_at' => $end->format(self::CANVAS_TIMESTAMP_FORMAT),
198
-                        'location_name' => $this->getProperty('LOCATION')
199
-                    ]
200
-                ]
201
-            );
202
-            $params['calendar_event_id'] = $calendarEvent['id'];
203
-            $insert->execute($params);
204
-        }
205
-    }
206
-
207
-    public static function purgeUnmatched($timestamp, $calendar)
208
-    {
209
-        $db = static::getDatabase();
210
-        $api = static::getApi();
211
-
212
-        $findDeletedEvents = $db->prepare(
213
-            "SELECT *
183
+						/* removing trailing [TAGS] from event title */
184
+						'title' => preg_replace(
185
+							'%^([^\]]+)(\s*\[[^\]]+\]\s*)+$%',
186
+							'\\1',
187
+							strip_tags($this->getProperty('SUMMARY'))
188
+						),
189
+						'description' => Markdown::defaultTransform(
190
+							str_replace(
191
+								'\n',
192
+								"\n\n",
193
+								$this->getProperty('DESCRIPTION', 1)
194
+							)
195
+						),
196
+						'start_at' => $start->format(self::CANVAS_TIMESTAMP_FORMAT),
197
+						'end_at' => $end->format(self::CANVAS_TIMESTAMP_FORMAT),
198
+						'location_name' => $this->getProperty('LOCATION')
199
+					]
200
+				]
201
+			);
202
+			$params['calendar_event_id'] = $calendarEvent['id'];
203
+			$insert->execute($params);
204
+		}
205
+	}
206
+
207
+	public static function purgeUnmatched($timestamp, $calendar)
208
+	{
209
+		$db = static::getDatabase();
210
+		$api = static::getApi();
211
+
212
+		$findDeletedEvents = $db->prepare(
213
+			"SELECT *
214 214
                 FROM `events`
215 215
                 WHERE
216 216
                     `calendar` = :calendar AND
217 217
                     `synced` != :synced"
218
-        );
219
-        $deleteCachedEvent = $db->prepare(
220
-            "DELETE FROM `events` WHERE `id` = :id"
221
-        );
222
-
223
-        $findDeletedEvents->execute([
224
-            'calendar' => $calendar->getId(),
225
-            'synced' => $timestamp
226
-        ]);
227
-        if (($deletedEvents = $findDeletedEvents->fetchAll()) !== false) {
228
-            foreach ($deletedEvents as $event) {
229
-                $params['cancel_reason'] = $timestamp;
230
-                if ($calendar->getContext()->getContext() == 'user') {
231
-                    $params['as_user_id'] = $calendar->getContext()->getId();
232
-                }
233
-                try {
234
-                    $api->delete(
235
-                        "/calendar_events/{$event['calendar_event[id]']}",
236
-                        $params
237
-                    );
238
-                } catch (Pest_Unauthorized $e) {
239
-                    /*
218
+		);
219
+		$deleteCachedEvent = $db->prepare(
220
+			"DELETE FROM `events` WHERE `id` = :id"
221
+		);
222
+
223
+		$findDeletedEvents->execute([
224
+			'calendar' => $calendar->getId(),
225
+			'synced' => $timestamp
226
+		]);
227
+		if (($deletedEvents = $findDeletedEvents->fetchAll()) !== false) {
228
+			foreach ($deletedEvents as $event) {
229
+				$params['cancel_reason'] = $timestamp;
230
+				if ($calendar->getContext()->getContext() == 'user') {
231
+					$params['as_user_id'] = $calendar->getContext()->getId();
232
+				}
233
+				try {
234
+					$api->delete(
235
+						"/calendar_events/{$event['calendar_event[id]']}",
236
+						$params
237
+					);
238
+				} catch (Pest_Unauthorized $e) {
239
+					/*
240 240
                      * Do nothing: an event was cached that had been deleted
241 241
                      * from Canvas -- deleting the cached event is
242 242
                      * inconsequential
243 243
                      */
244
-                }
245
-                $deleteCachedEvent->execute($event['id']);
246
-            }
247
-        }
248
-    }
244
+				}
245
+				$deleteCachedEvent->execute($event['id']);
246
+			}
247
+		}
248
+	}
249 249
 }
Please login to merge, or discard this patch.
src/SyncIntoCanvas/CalendarContext.php 2 patches
Indentation   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -4,106 +4,106 @@
 block discarded – undo
4 4
 
5 5
 class CalendarContext
6 6
 {
7
-    /**
8
-     * The canonical URL for this context in Canvas
9
-     * @var string
10
-     */
11
-    protected $canonicalUrl;
7
+	/**
8
+	 * The canonical URL for this context in Canvas
9
+	 * @var string
10
+	 */
11
+	protected $canonicalUrl;
12 12
 
13
-    /**
14
-     * The context for this calendar in Canvas (user, group, course)
15
-     * @var CanvasContext
16
-     */
17
-    protected $context;
13
+	/**
14
+	 * The context for this calendar in Canvas (user, group, course)
15
+	 * @var CanvasContext
16
+	 */
17
+	protected $context;
18 18
 
19
-    /**
20
-     * Unique ID for this Canvas context
21
-     * @var int
22
-     */
23
-    protected $id;
19
+	/**
20
+	 * Unique ID for this Canvas context
21
+	 * @var int
22
+	 */
23
+	protected $id;
24 24
 
25
-    /**
26
-     * URL to verify this context against API
27
-     * @var string
28
-     */
29
-    protected $verificationUrl;
25
+	/**
26
+	 * URL to verify this context against API
27
+	 * @var string
28
+	 */
29
+	protected $verificationUrl;
30 30
 
31
-    /**
32
-     * Compute the calendar context for the canvas object based on its URL
33
-     *
34
-     * @param string $canvasUrl URL to the context for a calendar on this
35
-     *     Canvas instance
36
-     * @throws Exception If `$canvasInstance` is not a URL on this Canvas
37
-     *     instance
38
-     * @throws Exception if `$canvasInstance` is not a URL to a recognizable
39
-     *     calendar context
40
-     */
41
-    public function __construct($canvasUrl)
42
-    {
43
-        /*
31
+	/**
32
+	 * Compute the calendar context for the canvas object based on its URL
33
+	 *
34
+	 * @param string $canvasUrl URL to the context for a calendar on this
35
+	 *     Canvas instance
36
+	 * @throws Exception If `$canvasInstance` is not a URL on this Canvas
37
+	 *     instance
38
+	 * @throws Exception if `$canvasInstance` is not a URL to a recognizable
39
+	 *     calendar context
40
+	 */
41
+	public function __construct($canvasUrl)
42
+	{
43
+		/*
44 44
          * TODO: accept calendar2?contexts links too (they would be an intuitively obvious link to use, after all)
45 45
          */
46
-        /*
46
+		/*
47 47
          * FIXME: users aren't working
48 48
          */
49
-        /*
49
+		/*
50 50
          * TODO: it would probably be better to look up users by email address than URL
51 51
          */
52
-        /* get the context (user, course or group) for the canvas URL */
53
-        if (preg_match('%(https?://)?(' .
54
-            /*
52
+		/* get the context (user, course or group) for the canvas URL */
53
+		if (preg_match('%(https?://)?(' .
54
+			/*
55 55
              * FIXME not clear that we should be using $_SESSION
56 56
              */
57
-            parse_url($_SESSION[CANVAS_INSTANCE_URL], PHP_URL_HOST) . '/((about/(\d+))|(courses/(\d+)(/groups/(\d+))?)|(accounts/\d+/groups/(\d+))))%', $canvasUrl, $match)) {
58
-            $this->canonicalUrl = "https://{$match[2]}"; // https://stmarksschool.instructure.com/courses/953
57
+			parse_url($_SESSION[CANVAS_INSTANCE_URL], PHP_URL_HOST) . '/((about/(\d+))|(courses/(\d+)(/groups/(\d+))?)|(accounts/\d+/groups/(\d+))))%', $canvasUrl, $match)) {
58
+			$this->canonicalUrl = "https://{$match[2]}"; // https://stmarksschool.instructure.com/courses/953
59 59
 
60
-            // course or account groups
61
-            if (isset($match[9]) || isset($match[11])) {
62
-                $this->context = CanvasContext::GROUP(); // used for context_code in events
63
-                $this->id = ($match[9] > $match[11] ? $match[9] : $match[11]);
64
-                $this->verificationUrl = "groups/{$this->id}"; // used once to look up the object to be sure it really exists
60
+			// course or account groups
61
+			if (isset($match[9]) || isset($match[11])) {
62
+				$this->context = CanvasContext::GROUP(); // used for context_code in events
63
+				$this->id = ($match[9] > $match[11] ? $match[9] : $match[11]);
64
+				$this->verificationUrl = "groups/{$this->id}"; // used once to look up the object to be sure it really exists
65 65
 
66
-            // courses
67
-            } elseif (isset($match[7])) {
68
-                $this->context = CanvasContext::COURSE();
69
-                $this->id = $match[7];
70
-                $this->verificationUrl = "courses/{$this->id}";
66
+			// courses
67
+			} elseif (isset($match[7])) {
68
+				$this->context = CanvasContext::COURSE();
69
+				$this->id = $match[7];
70
+				$this->verificationUrl = "courses/{$this->id}";
71 71
 
72
-            // users
73
-            } elseif (isset($match[5])) {
74
-                $this->context = CanvasContext::USER();
75
-                $this->id = $match[5];
76
-                $this->verificationUrl = "users/{$this->id}/profile";
72
+			// users
73
+			} elseif (isset($match[5])) {
74
+				$this->context = CanvasContext::USER();
75
+				$this->id = $match[5];
76
+				$this->verificationUrl = "users/{$this->id}/profile";
77 77
 
78
-            // we're somewhere where we don't know where we are
79
-            } else {
80
-                throw new Exception(
81
-                    "'$canvasUrl' is not a recognizable calendar context"
82
-                );
83
-            }
84
-        }
85
-        throw new Exception(
86
-            "'$canvasUrl' is not recognized as a URL to a calendar context on this Canvas instance"
87
-        );
88
-    }
78
+			// we're somewhere where we don't know where we are
79
+			} else {
80
+				throw new Exception(
81
+					"'$canvasUrl' is not a recognizable calendar context"
82
+				);
83
+			}
84
+		}
85
+		throw new Exception(
86
+			"'$canvasUrl' is not recognized as a URL to a calendar context on this Canvas instance"
87
+		);
88
+	}
89 89
 
90
-    public function getCanonicalUrl()
91
-    {
92
-        return $this->canonicalUrl;
93
-    }
90
+	public function getCanonicalUrl()
91
+	{
92
+		return $this->canonicalUrl;
93
+	}
94 94
 
95
-    public function getContext()
96
-    {
97
-        return $this->context;
98
-    }
95
+	public function getContext()
96
+	{
97
+		return $this->context;
98
+	}
99 99
 
100
-    public function getId()
101
-    {
102
-        return $this->id;
103
-    }
100
+	public function getId()
101
+	{
102
+		return $this->id;
103
+	}
104 104
 
105
-    public function getVerificationUrl()
106
-    {
107
-        return $this->verificationUrl;
108
-    }
105
+	public function getVerificationUrl()
106
+	{
107
+		return $this->verificationUrl;
108
+	}
109 109
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -50,11 +50,11 @@
 block discarded – undo
50 50
          * TODO: it would probably be better to look up users by email address than URL
51 51
          */
52 52
         /* get the context (user, course or group) for the canvas URL */
53
-        if (preg_match('%(https?://)?(' .
53
+        if (preg_match('%(https?://)?('.
54 54
             /*
55 55
              * FIXME not clear that we should be using $_SESSION
56 56
              */
57
-            parse_url($_SESSION[CANVAS_INSTANCE_URL], PHP_URL_HOST) . '/((about/(\d+))|(courses/(\d+)(/groups/(\d+))?)|(accounts/\d+/groups/(\d+))))%', $canvasUrl, $match)) {
57
+            parse_url($_SESSION[CANVAS_INSTANCE_URL], PHP_URL_HOST).'/((about/(\d+))|(courses/(\d+)(/groups/(\d+))?)|(accounts/\d+/groups/(\d+))))%', $canvasUrl, $match)) {
58 58
             $this->canonicalUrl = "https://{$match[2]}"; // https://stmarksschool.instructure.com/courses/953
59 59
 
60 60
             // course or account groups
Please login to merge, or discard this patch.
src/Constants.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -4,13 +4,13 @@
 block discarded – undo
4 4
 
5 5
 class Constants
6 6
 {
7
-    /* argument values for sync */
8
-    const SCHEDULE_ONCE = 'once';
9
-    const SCHEDULE_WEEKLY = 'weekly';
10
-    const SCHEDULE_DAILY = 'daily';
11
-    const SCHEDULE_HOURLY = 'hourly';
12
-    const SCHEDULE_CUSTOM = 'custom';
7
+	/* argument values for sync */
8
+	const SCHEDULE_ONCE = 'once';
9
+	const SCHEDULE_WEEKLY = 'weekly';
10
+	const SCHEDULE_DAILY = 'daily';
11
+	const SCHEDULE_HOURLY = 'hourly';
12
+	const SCHEDULE_CUSTOM = 'custom';
13 13
 
14
-    const VALUE_OVERWRITE_CANVAS_CALENDAR = 'overwrite';
15
-    const VALUE_ENABLE_REGEXP_FILTER = 'enable_filter';
14
+	const VALUE_OVERWRITE_CANVAS_CALENDAR = 'overwrite';
15
+	const VALUE_ENABLE_REGEXP_FILTER = 'enable_filter';
16 16
 }
Please login to merge, or discard this patch.