Completed
Pull Request — master (#10059)
by Georg
29:44 queued 13:38
created
apps/dav/lib/Migration/Version1006Date20180628111625.php 1 patch
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -31,78 +31,78 @@
 block discarded – undo
31 31
 
32 32
 class Version1006Date20180628111625 extends SimpleMigrationStep {
33 33
 
34
-	/**
35
-	 * @param IOutput $output
36
-	 * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
37
-	 * @param array $options
38
-	 * @return null|ISchemaWrapper
39
-	 */
40
-	public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
41
-		/** @var ISchemaWrapper $schema */
42
-		$schema = $schemaClosure();
34
+    /**
35
+     * @param IOutput $output
36
+     * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
37
+     * @param array $options
38
+     * @return null|ISchemaWrapper
39
+     */
40
+    public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
41
+        /** @var ISchemaWrapper $schema */
42
+        $schema = $schemaClosure();
43 43
 
44
-		if (!$schema->hasTable('calendarsubscrobjects')) {
45
-			$table = $schema->createTable('calendarsubscrobjects');
46
-			$table->addColumn('id', Type::BIGINT, [
47
-				'autoincrement' => true,
48
-				'notnull' => true,
49
-				'length' => 11,
50
-				'unsigned' => true,
51
-			]);
52
-			$table->addColumn('calendardata', Type::BLOB, [
53
-				'notnull' => false,
54
-			]);
55
-			$table->addColumn('uri', Type::STRING, [
56
-				'notnull' => false,
57
-				'length' => 255,
58
-			]);
59
-			$table->addColumn('subscriptionid', Type::BIGINT, [
60
-				'notnull' => true,
61
-				'length' => 11,
62
-				'unsigned' => true,
63
-			]);
64
-			$table->addColumn('lastmodified', Type::INTEGER, [
65
-				'notnull' => false,
66
-				'length' => 10,
67
-				'unsigned' => true,
68
-			]);
69
-			$table->addColumn('etag', Type::STRING, [
70
-				'notnull' => false,
71
-				'length' => 32,
72
-			]);
73
-			$table->addColumn('size', Type::BIGINT, [
74
-				'notnull' => true,
75
-				'length' => 11,
76
-				'unsigned' => true,
77
-			]);
78
-			$table->addColumn('componenttype', Type::STRING, [
79
-				'notnull' => false,
80
-				'length' => 8,
81
-			]);
82
-			$table->addColumn('firstoccurence', Type::BIGINT, [
83
-				'notnull' => false,
84
-				'length' => 11,
85
-				'unsigned' => true,
86
-			]);
87
-			$table->addColumn('lastoccurence', Type::BIGINT, [
88
-				'notnull' => false,
89
-				'length' => 11,
90
-				'unsigned' => true,
91
-			]);
92
-			$table->addColumn('uid', Type::STRING, [
93
-				'notnull' => false,
94
-				'length' => 255,
95
-			]);
96
-			$table->addColumn('classification', Type::INTEGER, [
97
-				'notnull' => false,
98
-				'default' => 0,
99
-			]);
100
-			$table->setPrimaryKey(['id']);
101
-			$table->addUniqueIndex(['subscriptionid', 'uri'], 'subobjects_index');
102
-		}
44
+        if (!$schema->hasTable('calendarsubscrobjects')) {
45
+            $table = $schema->createTable('calendarsubscrobjects');
46
+            $table->addColumn('id', Type::BIGINT, [
47
+                'autoincrement' => true,
48
+                'notnull' => true,
49
+                'length' => 11,
50
+                'unsigned' => true,
51
+            ]);
52
+            $table->addColumn('calendardata', Type::BLOB, [
53
+                'notnull' => false,
54
+            ]);
55
+            $table->addColumn('uri', Type::STRING, [
56
+                'notnull' => false,
57
+                'length' => 255,
58
+            ]);
59
+            $table->addColumn('subscriptionid', Type::BIGINT, [
60
+                'notnull' => true,
61
+                'length' => 11,
62
+                'unsigned' => true,
63
+            ]);
64
+            $table->addColumn('lastmodified', Type::INTEGER, [
65
+                'notnull' => false,
66
+                'length' => 10,
67
+                'unsigned' => true,
68
+            ]);
69
+            $table->addColumn('etag', Type::STRING, [
70
+                'notnull' => false,
71
+                'length' => 32,
72
+            ]);
73
+            $table->addColumn('size', Type::BIGINT, [
74
+                'notnull' => true,
75
+                'length' => 11,
76
+                'unsigned' => true,
77
+            ]);
78
+            $table->addColumn('componenttype', Type::STRING, [
79
+                'notnull' => false,
80
+                'length' => 8,
81
+            ]);
82
+            $table->addColumn('firstoccurence', Type::BIGINT, [
83
+                'notnull' => false,
84
+                'length' => 11,
85
+                'unsigned' => true,
86
+            ]);
87
+            $table->addColumn('lastoccurence', Type::BIGINT, [
88
+                'notnull' => false,
89
+                'length' => 11,
90
+                'unsigned' => true,
91
+            ]);
92
+            $table->addColumn('uid', Type::STRING, [
93
+                'notnull' => false,
94
+                'length' => 255,
95
+            ]);
96
+            $table->addColumn('classification', Type::INTEGER, [
97
+                'notnull' => false,
98
+                'default' => 0,
99
+            ]);
100
+            $table->setPrimaryKey(['id']);
101
+            $table->addUniqueIndex(['subscriptionid', 'uri'], 'subobjects_index');
102
+        }
103 103
 
104
-		return $schema;
105
-	}
104
+        return $schema;
105
+    }
106 106
 }
107 107
 
108 108
 
Please login to merge, or discard this patch.
apps/dav/lib/BackgroundJob/RefreshWebcalJob.php 2 patches
Indentation   +293 added lines, -293 removed lines patch added patch discarded remove patch
@@ -44,297 +44,297 @@
 block discarded – undo
44 44
 
45 45
 class RefreshWebcalJob extends Job {
46 46
 
47
-	/** @var CalDavBackend */
48
-	private $calDavBackend;
49
-
50
-	/** @var IClientService */
51
-	private $clientService;
52
-
53
-	/** @var ILogger */
54
-	private $logger;
55
-
56
-	/** @var ITimeFactory */
57
-	private $timeFactory;
58
-
59
-	/** @var array */
60
-	private $subscription;
61
-
62
-	/**
63
-	 * RefreshWebcalJob constructor.
64
-	 *
65
-	 * @param CalDavBackend $calDavBackend
66
-	 * @param IClientService $clientService
67
-	 * @param ILogger $logger
68
-	 * @param ITimeFactory $timeFactory
69
-	 */
70
-	public function __construct(CalDavBackend $calDavBackend, IClientService $clientService, ILogger $logger, ITimeFactory $timeFactory) {
71
-		$this->calDavBackend = $calDavBackend;
72
-		$this->clientService = $clientService;
73
-		$this->logger = $logger;
74
-		$this->timeFactory = $timeFactory;
75
-	}
76
-
77
-	/**
78
-	 * this function is called at most every hour
79
-	 *
80
-	 * @inheritdoc
81
-	 */
82
-	public function execute($jobList, ILogger $logger = null) {
83
-		$subscription = $this->getSubscription($this->argument['principaluri'], $this->argument['uri']);
84
-		if (!$subscription) {
85
-			return;
86
-		}
87
-
88
-		// if no refresh rate was configured, just refresh once a week
89
-		$subscriptionId = $subscription['id'];
90
-		$refreshrate = $subscription['refreshrate'] ?? 'P1W';
91
-
92
-		try {
93
-			/** @var \DateInterval $dateInterval */
94
-			$dateInterval = DateTimeParser::parseDuration($refreshrate);
95
-		} catch(InvalidDataException $ex) {
96
-			$this->logger->logException($ex);
97
-			$this->logger->warning("Subscription $subscriptionId could not be refreshed, refreshrate in database is invalid");
98
-			return;
99
-		}
100
-
101
-		$interval = $this->getIntervalFromDateInterval($dateInterval);
102
-		if (($this->timeFactory->getTime() - $this->lastRun) <= $interval) {
103
-			return;
104
-		}
105
-
106
-		parent::execute($jobList, $logger);
107
-	}
108
-
109
-	/**
110
-	 * @param array $argument
111
-	 */
112
-	protected function run($argument) {
113
-		$subscription = $this->getSubscription($argument['principaluri'], $argument['uri']);
114
-		$mutations = [];
115
-		if (!$subscription) {
116
-			return;
117
-		}
118
-
119
-		$webcalData = $this->queryWebcalFeed($subscription, $mutations);
120
-		if (!$webcalData) {
121
-			return;
122
-		}
123
-
124
-		$stripTodos = $subscription['striptodos'] ?? true;
125
-		$stripAlarms = $subscription['stripalarms'] ?? true;
126
-		$stripAttachments = $subscription['stripattachments'] ?? true;
127
-
128
-		try {
129
-			$splitter = new ICalendar($webcalData, Reader::OPTION_FORGIVING);
130
-
131
-			// we wait with deleting all outdated events till we parsed the new ones
132
-			// in case the new calendar is broken and `new ICalendar` throws a ParseException
133
-			// the user will still see the old data
134
-			$this->calDavBackend->purgeAllCachedEventsForSubscription($subscription['id']);
135
-
136
-			while ($vObject = $splitter->getNext()) {
137
-				/** @var Component $vObject */
138
-				$uid = null;
139
-				$compName = null;
140
-
141
-				foreach ($vObject->getComponents() as $component) {
142
-					if ($component->name === 'VTIMEZONE') {
143
-						continue;
144
-					}
145
-
146
-					$uid = $component->{'UID'}->getValue();
147
-					$compName = $component->name;
148
-
149
-					if ($stripAlarms) {
150
-						unset($component->{'VALARM'});
151
-					}
152
-					if ($stripAttachments) {
153
-						unset($component->{'ATTACH'});
154
-					}
155
-				}
156
-
157
-				if ($stripTodos && $compName === 'VTODO') {
158
-					continue;
159
-				}
160
-
161
-				$uri = $uid . '.ics';
162
-				$calendarData = $vObject->serialize();
163
-				try {
164
-					$this->calDavBackend->addCachedEvent($subscription['id'], $uri, $calendarData);
165
-				} catch(BadRequest $ex) {
166
-					$this->logger->logException($ex);
167
-				}
168
-			}
169
-
170
-			$newRefreshRate = $this->checkWebcalDataForRefreshRate($subscription, $webcalData);
171
-			if ($newRefreshRate) {
172
-				$mutations['{http://apple.com/ns/ical/}refreshrate'] = $newRefreshRate;
173
-			}
174
-
175
-			$this->updateSubscription($subscription, $mutations);
176
-		} catch(ParseException $ex) {
177
-			$subscriptionId = $subscription['id'];
178
-
179
-			$this->logger->logException($ex);
180
-			$this->logger->warning("Subscription $subscriptionId could not be refreshed due to a parsing error");
181
-		}
182
-	}
183
-
184
-	/**
185
-	 * gets webcal feed from remote server
186
-	 *
187
-	 * @param array $subscription
188
-	 * @param array &$mutations
189
-	 * @return null|string
190
-	 */
191
-	private function queryWebcalFeed(array $subscription, array &$mutations) {
192
-		$client = $this->clientService->newClient();
193
-
194
-		$didBreak301Chain = false;
195
-		$latestLocation = null;
196
-
197
-		$handlerStack = HandlerStack::create();
198
-		$handlerStack->push(Middleware::mapRequest(function (RequestInterface $request) {
199
-			return $request
200
-				->withHeader('User-Agent', 'Nextcloud Webcal Crawler');
201
-		}));
202
-		$handlerStack->push(Middleware::mapResponse(function(ResponseInterface $response) use (&$didBreak301Chain, &$latestLocation) {
203
-			if (!$didBreak301Chain) {
204
-				if ($response->getStatusCode() !== 301) {
205
-					$didBreak301Chain = true;
206
-				} else {
207
-					$latestLocation = $response->getHeader('Location');
208
-				}
209
-			}
210
-			return $response;
211
-		}));
212
-
213
-		try {
214
-			$response = $client->get($subscription['source'], [
215
-				'allow_redirects' => [
216
-					'redirects' => 10
217
-				],
218
-				'handler' => $handlerStack,
219
-			]);
220
-
221
-			$body = $response->getBody();
222
-
223
-			if ($latestLocation) {
224
-				$mutations['{http://calendarserver.org/ns/}source'] = new Href($latestLocation);
225
-			}
226
-
227
-			return $body;
228
-		} catch(\Exception $ex) {
229
-			$subscriptionId = $subscription['id'];
230
-
231
-			$this->logger->logException($ex);
232
-			$this->logger->warning("Subscription $subscriptionId could not be refreshed due to a network error");
233
-
234
-			return null;
235
-		}
236
-	}
237
-
238
-	/**
239
-	 * loads subscription from backend and store it locally
240
-	 *
241
-	 * @param string $principalUri
242
-	 * @param string $uri
243
-	 * @return array|null
244
-	 */
245
-	private function getSubscription($principalUri, $uri) {
246
-		if ($this->subscription) {
247
-			return $this->subscription;
248
-		}
249
-
250
-		$subscriptions = array_filter(
251
-			$this->calDavBackend->getSubscriptionsForUser($principalUri),
252
-			function($sub) use ($uri) {
253
-				return $sub['uri'] === $uri;
254
-			}
255
-		);
256
-
257
-		if (\count($subscriptions) === 0) {
258
-			return null;
259
-		}
260
-
261
-		$this->subscription = $subscriptions[0];
262
-		return $this->subscription;
263
-	}
264
-
265
-	/**
266
-	 * get total number of seconds from DateInterval object
267
-	 *
268
-	 * @param \DateInterval $interval
269
-	 * @return int
270
-	 */
271
-	private function getIntervalFromDateInterval(\DateInterval $interval):int {
272
-		return $interval->s
273
-			+ ($interval->i * 60)
274
-			+ ($interval->h * 60 * 60)
275
-			+ ($interval->d * 60 * 60 * 24)
276
-			+ ($interval->m * 60 * 60 * 24 * 30)
277
-			+ ($interval->y * 60 * 60 * 24 * 365);
278
-	}
279
-
280
-	/**
281
-	 * check if:
282
-	 *  - current subscription stores a refreshrate
283
-	 *  - the webcal feed suggests a refreshrate
284
-	 *  - return suggested refreshrate if user didn't set a custom one
285
-	 *
286
-	 * @param array $subscription
287
-	 * @param string $webcalData
288
-	 * @return string|null
289
-	 */
290
-	private function checkWebcalDataForRefreshRate($subscription, $webcalData) {
291
-		// if there is no refreshrate stored in the database, check the webcal feed
292
-		// whether it suggests any refresh rate and store that in the database
293
-		if (isset($subscription['refreshrate']) && $subscription['refreshrate'] !== null) {
294
-			return null;
295
-		}
296
-
297
-		/** @var Component\VCalendar $vCalendar */
298
-		$vCalendar = Reader::read($webcalData);
299
-
300
-		$newRefreshrate = null;
301
-		if (isset($vCalendar->{'X-PUBLISHED-TTL'})) {
302
-			$newRefreshrate = $vCalendar->{'X-PUBLISHED-TTL'}->getValue();
303
-		}
304
-		if (isset($vCalendar->{'REFRESH-INTERVAL'})) {
305
-			$newRefreshrate = $vCalendar->{'REFRESH-INTERVAL'}->getValue();
306
-		}
307
-
308
-		if (!$newRefreshrate) {
309
-			return null;
310
-		}
311
-
312
-		// check if new refresh rate is even valid
313
-		try {
314
-			DateTimeParser::parseDuration($newRefreshrate);
315
-		} catch(InvalidDataException $ex) {
316
-			return null;
317
-		}
318
-
319
-		return $newRefreshrate;
320
-	}
321
-
322
-	/**
323
-	 * update subscription stored in database
324
-	 * used to set:
325
-	 *  - refreshrate
326
-	 *  - source
327
-	 *
328
-	 * @param array $subscription
329
-	 * @param array $mutations
330
-	 */
331
-	private function updateSubscription(array $subscription, array $mutations) {
332
-		if (empty($mutations)) {
333
-			return;
334
-		}
335
-
336
-		$propPatch = new PropPatch($mutations);
337
-		$this->calDavBackend->updateSubscription($subscription['id'], $propPatch);
338
-		$propPatch->commit();
339
-	}
47
+    /** @var CalDavBackend */
48
+    private $calDavBackend;
49
+
50
+    /** @var IClientService */
51
+    private $clientService;
52
+
53
+    /** @var ILogger */
54
+    private $logger;
55
+
56
+    /** @var ITimeFactory */
57
+    private $timeFactory;
58
+
59
+    /** @var array */
60
+    private $subscription;
61
+
62
+    /**
63
+     * RefreshWebcalJob constructor.
64
+     *
65
+     * @param CalDavBackend $calDavBackend
66
+     * @param IClientService $clientService
67
+     * @param ILogger $logger
68
+     * @param ITimeFactory $timeFactory
69
+     */
70
+    public function __construct(CalDavBackend $calDavBackend, IClientService $clientService, ILogger $logger, ITimeFactory $timeFactory) {
71
+        $this->calDavBackend = $calDavBackend;
72
+        $this->clientService = $clientService;
73
+        $this->logger = $logger;
74
+        $this->timeFactory = $timeFactory;
75
+    }
76
+
77
+    /**
78
+     * this function is called at most every hour
79
+     *
80
+     * @inheritdoc
81
+     */
82
+    public function execute($jobList, ILogger $logger = null) {
83
+        $subscription = $this->getSubscription($this->argument['principaluri'], $this->argument['uri']);
84
+        if (!$subscription) {
85
+            return;
86
+        }
87
+
88
+        // if no refresh rate was configured, just refresh once a week
89
+        $subscriptionId = $subscription['id'];
90
+        $refreshrate = $subscription['refreshrate'] ?? 'P1W';
91
+
92
+        try {
93
+            /** @var \DateInterval $dateInterval */
94
+            $dateInterval = DateTimeParser::parseDuration($refreshrate);
95
+        } catch(InvalidDataException $ex) {
96
+            $this->logger->logException($ex);
97
+            $this->logger->warning("Subscription $subscriptionId could not be refreshed, refreshrate in database is invalid");
98
+            return;
99
+        }
100
+
101
+        $interval = $this->getIntervalFromDateInterval($dateInterval);
102
+        if (($this->timeFactory->getTime() - $this->lastRun) <= $interval) {
103
+            return;
104
+        }
105
+
106
+        parent::execute($jobList, $logger);
107
+    }
108
+
109
+    /**
110
+     * @param array $argument
111
+     */
112
+    protected function run($argument) {
113
+        $subscription = $this->getSubscription($argument['principaluri'], $argument['uri']);
114
+        $mutations = [];
115
+        if (!$subscription) {
116
+            return;
117
+        }
118
+
119
+        $webcalData = $this->queryWebcalFeed($subscription, $mutations);
120
+        if (!$webcalData) {
121
+            return;
122
+        }
123
+
124
+        $stripTodos = $subscription['striptodos'] ?? true;
125
+        $stripAlarms = $subscription['stripalarms'] ?? true;
126
+        $stripAttachments = $subscription['stripattachments'] ?? true;
127
+
128
+        try {
129
+            $splitter = new ICalendar($webcalData, Reader::OPTION_FORGIVING);
130
+
131
+            // we wait with deleting all outdated events till we parsed the new ones
132
+            // in case the new calendar is broken and `new ICalendar` throws a ParseException
133
+            // the user will still see the old data
134
+            $this->calDavBackend->purgeAllCachedEventsForSubscription($subscription['id']);
135
+
136
+            while ($vObject = $splitter->getNext()) {
137
+                /** @var Component $vObject */
138
+                $uid = null;
139
+                $compName = null;
140
+
141
+                foreach ($vObject->getComponents() as $component) {
142
+                    if ($component->name === 'VTIMEZONE') {
143
+                        continue;
144
+                    }
145
+
146
+                    $uid = $component->{'UID'}->getValue();
147
+                    $compName = $component->name;
148
+
149
+                    if ($stripAlarms) {
150
+                        unset($component->{'VALARM'});
151
+                    }
152
+                    if ($stripAttachments) {
153
+                        unset($component->{'ATTACH'});
154
+                    }
155
+                }
156
+
157
+                if ($stripTodos && $compName === 'VTODO') {
158
+                    continue;
159
+                }
160
+
161
+                $uri = $uid . '.ics';
162
+                $calendarData = $vObject->serialize();
163
+                try {
164
+                    $this->calDavBackend->addCachedEvent($subscription['id'], $uri, $calendarData);
165
+                } catch(BadRequest $ex) {
166
+                    $this->logger->logException($ex);
167
+                }
168
+            }
169
+
170
+            $newRefreshRate = $this->checkWebcalDataForRefreshRate($subscription, $webcalData);
171
+            if ($newRefreshRate) {
172
+                $mutations['{http://apple.com/ns/ical/}refreshrate'] = $newRefreshRate;
173
+            }
174
+
175
+            $this->updateSubscription($subscription, $mutations);
176
+        } catch(ParseException $ex) {
177
+            $subscriptionId = $subscription['id'];
178
+
179
+            $this->logger->logException($ex);
180
+            $this->logger->warning("Subscription $subscriptionId could not be refreshed due to a parsing error");
181
+        }
182
+    }
183
+
184
+    /**
185
+     * gets webcal feed from remote server
186
+     *
187
+     * @param array $subscription
188
+     * @param array &$mutations
189
+     * @return null|string
190
+     */
191
+    private function queryWebcalFeed(array $subscription, array &$mutations) {
192
+        $client = $this->clientService->newClient();
193
+
194
+        $didBreak301Chain = false;
195
+        $latestLocation = null;
196
+
197
+        $handlerStack = HandlerStack::create();
198
+        $handlerStack->push(Middleware::mapRequest(function (RequestInterface $request) {
199
+            return $request
200
+                ->withHeader('User-Agent', 'Nextcloud Webcal Crawler');
201
+        }));
202
+        $handlerStack->push(Middleware::mapResponse(function(ResponseInterface $response) use (&$didBreak301Chain, &$latestLocation) {
203
+            if (!$didBreak301Chain) {
204
+                if ($response->getStatusCode() !== 301) {
205
+                    $didBreak301Chain = true;
206
+                } else {
207
+                    $latestLocation = $response->getHeader('Location');
208
+                }
209
+            }
210
+            return $response;
211
+        }));
212
+
213
+        try {
214
+            $response = $client->get($subscription['source'], [
215
+                'allow_redirects' => [
216
+                    'redirects' => 10
217
+                ],
218
+                'handler' => $handlerStack,
219
+            ]);
220
+
221
+            $body = $response->getBody();
222
+
223
+            if ($latestLocation) {
224
+                $mutations['{http://calendarserver.org/ns/}source'] = new Href($latestLocation);
225
+            }
226
+
227
+            return $body;
228
+        } catch(\Exception $ex) {
229
+            $subscriptionId = $subscription['id'];
230
+
231
+            $this->logger->logException($ex);
232
+            $this->logger->warning("Subscription $subscriptionId could not be refreshed due to a network error");
233
+
234
+            return null;
235
+        }
236
+    }
237
+
238
+    /**
239
+     * loads subscription from backend and store it locally
240
+     *
241
+     * @param string $principalUri
242
+     * @param string $uri
243
+     * @return array|null
244
+     */
245
+    private function getSubscription($principalUri, $uri) {
246
+        if ($this->subscription) {
247
+            return $this->subscription;
248
+        }
249
+
250
+        $subscriptions = array_filter(
251
+            $this->calDavBackend->getSubscriptionsForUser($principalUri),
252
+            function($sub) use ($uri) {
253
+                return $sub['uri'] === $uri;
254
+            }
255
+        );
256
+
257
+        if (\count($subscriptions) === 0) {
258
+            return null;
259
+        }
260
+
261
+        $this->subscription = $subscriptions[0];
262
+        return $this->subscription;
263
+    }
264
+
265
+    /**
266
+     * get total number of seconds from DateInterval object
267
+     *
268
+     * @param \DateInterval $interval
269
+     * @return int
270
+     */
271
+    private function getIntervalFromDateInterval(\DateInterval $interval):int {
272
+        return $interval->s
273
+            + ($interval->i * 60)
274
+            + ($interval->h * 60 * 60)
275
+            + ($interval->d * 60 * 60 * 24)
276
+            + ($interval->m * 60 * 60 * 24 * 30)
277
+            + ($interval->y * 60 * 60 * 24 * 365);
278
+    }
279
+
280
+    /**
281
+     * check if:
282
+     *  - current subscription stores a refreshrate
283
+     *  - the webcal feed suggests a refreshrate
284
+     *  - return suggested refreshrate if user didn't set a custom one
285
+     *
286
+     * @param array $subscription
287
+     * @param string $webcalData
288
+     * @return string|null
289
+     */
290
+    private function checkWebcalDataForRefreshRate($subscription, $webcalData) {
291
+        // if there is no refreshrate stored in the database, check the webcal feed
292
+        // whether it suggests any refresh rate and store that in the database
293
+        if (isset($subscription['refreshrate']) && $subscription['refreshrate'] !== null) {
294
+            return null;
295
+        }
296
+
297
+        /** @var Component\VCalendar $vCalendar */
298
+        $vCalendar = Reader::read($webcalData);
299
+
300
+        $newRefreshrate = null;
301
+        if (isset($vCalendar->{'X-PUBLISHED-TTL'})) {
302
+            $newRefreshrate = $vCalendar->{'X-PUBLISHED-TTL'}->getValue();
303
+        }
304
+        if (isset($vCalendar->{'REFRESH-INTERVAL'})) {
305
+            $newRefreshrate = $vCalendar->{'REFRESH-INTERVAL'}->getValue();
306
+        }
307
+
308
+        if (!$newRefreshrate) {
309
+            return null;
310
+        }
311
+
312
+        // check if new refresh rate is even valid
313
+        try {
314
+            DateTimeParser::parseDuration($newRefreshrate);
315
+        } catch(InvalidDataException $ex) {
316
+            return null;
317
+        }
318
+
319
+        return $newRefreshrate;
320
+    }
321
+
322
+    /**
323
+     * update subscription stored in database
324
+     * used to set:
325
+     *  - refreshrate
326
+     *  - source
327
+     *
328
+     * @param array $subscription
329
+     * @param array $mutations
330
+     */
331
+    private function updateSubscription(array $subscription, array $mutations) {
332
+        if (empty($mutations)) {
333
+            return;
334
+        }
335
+
336
+        $propPatch = new PropPatch($mutations);
337
+        $this->calDavBackend->updateSubscription($subscription['id'], $propPatch);
338
+        $propPatch->commit();
339
+    }
340 340
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
 		try {
93 93
 			/** @var \DateInterval $dateInterval */
94 94
 			$dateInterval = DateTimeParser::parseDuration($refreshrate);
95
-		} catch(InvalidDataException $ex) {
95
+		} catch (InvalidDataException $ex) {
96 96
 			$this->logger->logException($ex);
97 97
 			$this->logger->warning("Subscription $subscriptionId could not be refreshed, refreshrate in database is invalid");
98 98
 			return;
@@ -158,11 +158,11 @@  discard block
 block discarded – undo
158 158
 					continue;
159 159
 				}
160 160
 
161
-				$uri = $uid . '.ics';
161
+				$uri = $uid.'.ics';
162 162
 				$calendarData = $vObject->serialize();
163 163
 				try {
164 164
 					$this->calDavBackend->addCachedEvent($subscription['id'], $uri, $calendarData);
165
-				} catch(BadRequest $ex) {
165
+				} catch (BadRequest $ex) {
166 166
 					$this->logger->logException($ex);
167 167
 				}
168 168
 			}
@@ -173,7 +173,7 @@  discard block
 block discarded – undo
173 173
 			}
174 174
 
175 175
 			$this->updateSubscription($subscription, $mutations);
176
-		} catch(ParseException $ex) {
176
+		} catch (ParseException $ex) {
177 177
 			$subscriptionId = $subscription['id'];
178 178
 
179 179
 			$this->logger->logException($ex);
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
 		$latestLocation = null;
196 196
 
197 197
 		$handlerStack = HandlerStack::create();
198
-		$handlerStack->push(Middleware::mapRequest(function (RequestInterface $request) {
198
+		$handlerStack->push(Middleware::mapRequest(function(RequestInterface $request) {
199 199
 			return $request
200 200
 				->withHeader('User-Agent', 'Nextcloud Webcal Crawler');
201 201
 		}));
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
 			}
226 226
 
227 227
 			return $body;
228
-		} catch(\Exception $ex) {
228
+		} catch (\Exception $ex) {
229 229
 			$subscriptionId = $subscription['id'];
230 230
 
231 231
 			$this->logger->logException($ex);
@@ -312,7 +312,7 @@  discard block
 block discarded – undo
312 312
 		// check if new refresh rate is even valid
313 313
 		try {
314 314
 			DateTimeParser::parseDuration($newRefreshrate);
315
-		} catch(InvalidDataException $ex) {
315
+		} catch (InvalidDataException $ex) {
316 316
 			return null;
317 317
 		}
318 318
 
Please login to merge, or discard this patch.