1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* ownCloud - Calendar App |
4
|
|
|
* |
5
|
|
|
* @author Georg Ehrke |
6
|
|
|
* @copyright 2014 Georg Ehrke <[email protected]> |
7
|
|
|
* |
8
|
|
|
* This library is free software; you can redistribute it and/or |
9
|
|
|
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
10
|
|
|
* License as published by the Free Software Foundation; either |
11
|
|
|
* version 3 of the License, or any later version. |
12
|
|
|
* |
13
|
|
|
* This library is distributed in the hope that it will be useful, |
14
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
|
|
|
* GNU AFFERO GENERAL PUBLIC LICENSE for more details. |
17
|
|
|
* |
18
|
|
|
* You should have received a copy of the GNU Affero General Public |
19
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
20
|
|
|
* |
21
|
|
|
*/ |
22
|
|
|
namespace OCA\Calendar\Cache\Calendar; |
23
|
|
|
|
24
|
|
|
use OCA\Calendar\Backend\DoesNotExistException; |
25
|
|
|
use OCA\Calendar\Backend\MultipleObjectsReturnedException; |
26
|
|
|
use OCA\Calendar\Backend\TemporarilyNotAvailableException; |
27
|
|
|
use OCA\Calendar\CorruptDataException; |
28
|
|
|
use OCA\Calendar\IBackend; |
29
|
|
|
use OCA\Calendar\IBackendCollection; |
30
|
|
|
use OCA\Calendar\ICalendar; |
31
|
|
|
|
32
|
|
|
use OCA\Calendar\Utility\CalendarUtility; |
33
|
|
|
use OCP\ILogger; |
34
|
|
|
|
35
|
|
|
use OCP\AppFramework\Db\DoesNotExistException as DoesNotExistMapperException; |
36
|
|
|
use OCP\AppFramework\Db\MultipleObjectsReturnedException as MultipleObjectsReturnedMapperException; |
37
|
|
|
|
38
|
|
|
class Scanner { |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var IBackendCollection |
42
|
|
|
*/ |
43
|
|
|
protected $backends; |
44
|
|
|
|
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var \OCA\Calendar\Cache\Calendar\Cache |
48
|
|
|
*/ |
49
|
|
|
protected $cache; |
50
|
|
|
|
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @var ILogger |
54
|
|
|
*/ |
55
|
|
|
protected $logger; |
56
|
|
|
|
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @param IBackendCollection $backends |
60
|
|
|
* @param ILogger $logger |
61
|
|
|
*/ |
62
|
|
|
public function __construct(IBackendCollection $backends, ILogger $logger) { |
63
|
|
|
$this->backends = $backends; |
64
|
|
|
$this->cache = $backends->getCache(); |
65
|
|
|
$this->logger = $logger; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @param string $backendId |
71
|
|
|
* @param string $privateUri |
72
|
|
|
* @param string $userId |
73
|
|
|
* @param ICalendar $usersCalendar |
74
|
|
|
* @return mixed |
75
|
|
|
*/ |
76
|
|
|
public function scanCalendar($backendId, $privateUri, $userId, ICalendar &$usersCalendar=null) { |
77
|
|
|
$backend = $this->backends->find($backendId); |
78
|
|
|
|
79
|
|
|
if (!($backend instanceof IBackend)) { |
80
|
|
|
$this->logger->debug('Backend \'' . $backendId . '\' not found'); |
81
|
|
|
return null; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$calendar = $this->getRemoteAndDeleteIfNecessary($backend, $privateUri, $userId); |
85
|
|
|
if (!$calendar) { |
86
|
|
|
return null; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
$cachedCalendar = $this->getCached($backendId, $privateUri, $userId); |
90
|
|
|
if ($cachedCalendar) { |
91
|
|
|
if ($usersCalendar) { |
92
|
|
|
$calendar = $this->resetUnsupportedProperties($backend, $calendar, $usersCalendar); |
93
|
|
|
} else { |
94
|
|
|
$calendar = $this->resetUnsupportedProperties($backend, $calendar, $cachedCalendar); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
$cachedCalendar->overwriteWith($calendar); |
98
|
|
|
|
99
|
|
|
$this->updateCache($cachedCalendar); |
100
|
|
|
} else { |
101
|
|
|
CalendarUtility::generateURI($calendar, function($newUri) use ($calendar) { |
102
|
|
|
return $this->cache->doesExist($newUri, $calendar->getUserId()); |
103
|
|
|
}, true); |
104
|
|
|
$calendar = $this->addToCache($calendar); |
105
|
|
|
if ($usersCalendar) { |
106
|
|
|
$usersCalendar->setId($calendar->getId()); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* @param IBackend $backend |
114
|
|
|
* @param string $privateUri |
115
|
|
|
* @param string $userId |
116
|
|
|
* @return null|ICalendar |
117
|
|
|
*/ |
118
|
|
|
protected function getRemoteAndDeleteIfNecessary(IBackend $backend, $privateUri, $userId) { |
119
|
|
|
$calendarAPI = $backend->getCalendarAPI(); |
120
|
|
|
$msg = 'CalendarManager \'' . $backend->getId() . '\'::'; |
121
|
|
|
$msg .= '\'' . $privateUri . '\' of \'' . $userId . '\''; |
122
|
|
|
|
123
|
|
|
try { |
124
|
|
|
return $calendarAPI->find($privateUri, $userId); |
125
|
|
|
} catch(DoesNotExistException $ex) { |
126
|
|
|
$msg .= 'is not available, deleting from cache'; |
127
|
|
|
$this->logger->debug($msg); |
128
|
|
|
|
129
|
|
|
$this->removeFromCache($backend->getId(), $privateUri, $userId); |
130
|
|
|
return null; |
131
|
|
|
} catch(MultipleObjectsReturnedException $ex) { |
132
|
|
|
$msg .= 'available multiple times (please check backend!) '; |
133
|
|
|
$msg .= 'deleting from cache'; |
134
|
|
|
$this->logger->debug($msg); |
135
|
|
|
|
136
|
|
|
$this->removeFromCache($backend->getId(), $privateUri, $userId); |
137
|
|
|
return null; |
138
|
|
|
} catch(TemporarilyNotAvailableException $ex) { |
139
|
|
|
$msg .= 'temporarily not available, skipping for now'; |
140
|
|
|
$this->logger->debug($msg); |
141
|
|
|
|
142
|
|
|
return null; |
143
|
|
|
} catch(CorruptDataException $ex) { |
144
|
|
|
$msg .= 'is corrupted on backend, deleting from cache'; |
145
|
|
|
$this->logger->debug($msg); |
146
|
|
|
|
147
|
|
|
$this->removeFromCache($backend->getId(), $privateUri, $userId); |
148
|
|
|
return null; |
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* @param string $backendId |
155
|
|
|
* @param string $privateUri |
156
|
|
|
* @param string $userId |
157
|
|
|
* @return null|ICalendar |
158
|
|
|
*/ |
159
|
|
|
protected function getCached($backendId, $privateUri, $userId) { |
160
|
|
|
try { |
161
|
|
|
return $this->cache->findByPrivateUri($backendId, $privateUri, $userId); |
162
|
|
|
} catch(DoesNotExistMapperException $ex) { |
|
|
|
|
163
|
|
|
return null; |
164
|
|
|
} catch(MultipleObjectsReturnedMapperException $ex) { |
|
|
|
|
165
|
|
|
//$this->logger->warn($msg); TODO |
166
|
|
|
return null; |
167
|
|
|
} |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* @param ICalendar $calendar |
173
|
|
|
* @return ICalendar |
174
|
|
|
*/ |
175
|
|
|
protected function addToCache(ICalendar $calendar) { |
176
|
|
|
$calendar = $this->cache->insert($calendar); |
177
|
|
|
return $calendar; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* @param ICalendar $calendar |
183
|
|
|
*/ |
184
|
|
|
protected function updateCache(ICalendar $calendar) { |
185
|
|
|
$this->cache->update($calendar); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* @param string $backendId |
191
|
|
|
* @param string $privateUri |
192
|
|
|
* @param string $userId |
193
|
|
|
*/ |
194
|
|
|
protected function removeFromCache($backendId, $privateUri, $userId) { |
195
|
|
|
$this->removeFromCache($backendId, $privateUri, $userId); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* scan all |
201
|
|
|
* @param string $userId |
202
|
|
|
*/ |
203
|
|
|
public function scan($userId) { |
204
|
|
|
$backends = $this->backends->getObjects(); |
205
|
|
|
/* @var IBackend $backend */ |
206
|
|
|
foreach ($backends as $backend) { |
207
|
|
|
try { |
208
|
|
|
$backendId = $backend->getId(); |
209
|
|
|
$calendars = $backend->getCalendarAPI()->listAll($userId); |
210
|
|
|
|
211
|
|
|
foreach ($calendars as $privateUri) { |
212
|
|
|
try { |
213
|
|
|
$this->scanCalendar($backendId, $privateUri, $userId); |
214
|
|
|
} catch (\Exception $ex) { |
215
|
|
|
$this->logger->debug($ex->getMessage()); |
216
|
|
|
continue; |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
} catch(\Exception $ex) { |
220
|
|
|
$this->logger->debug($ex->getMessage()); |
221
|
|
|
} |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* walk over any calendars that are not fully scanned yet and scan them |
228
|
|
|
*/ |
229
|
|
|
protected function backgroundScan() { |
230
|
|
|
$scanned = []; |
231
|
|
|
while(($calendar = $this->cache->getIncomplete()) !== false && !in_array($calendar->getId(), $scanned)) { |
232
|
|
|
$this->scanCalendar($calendar->getBackend()->getId(), |
233
|
|
|
$calendar->getPrivateUri(), $calendar->getUserId()); |
234
|
|
|
$scanned[] = $calendar->getId(); |
235
|
|
|
} |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* @param IBackend $backend |
241
|
|
|
* @param ICalendar $calendar |
242
|
|
|
* @param ICalendar $cachedCalendar |
243
|
|
|
* @return ICalendar |
244
|
|
|
*/ |
245
|
|
|
protected function resetUnsupportedProperties(IBackend $backend, |
246
|
|
|
ICalendar $calendar, |
247
|
|
|
ICalendar $cachedCalendar) { |
248
|
|
|
$backendAPI = $backend->getBackendAPI(); |
249
|
|
|
|
250
|
|
|
if (!$backendAPI->canStoreColor()) { |
251
|
|
|
$calendar->setColor($cachedCalendar->getColor()); |
252
|
|
|
} |
253
|
|
|
if (!$backendAPI->canStoreComponents()) { |
254
|
|
|
$calendar->setComponents($cachedCalendar->getComponents()); |
255
|
|
|
} |
256
|
|
|
if (!$backendAPI->canStoreDescription()) { |
257
|
|
|
$calendar->setDescription($cachedCalendar->getDescription()); |
258
|
|
|
} |
259
|
|
|
if (!$backendAPI->canStoreDisplayname()) { |
260
|
|
|
$calendar->setDisplayname($cachedCalendar->getDisplayname()); |
261
|
|
|
} |
262
|
|
|
if (!$backendAPI->canStoreEnabled()) { |
263
|
|
|
$calendar->setEnabled($cachedCalendar->getEnabled()); |
264
|
|
|
} |
265
|
|
|
if (!$backendAPI->canStoreOrder()) { |
266
|
|
|
$calendar->setOrder($cachedCalendar->getOrder()); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
return $calendar; |
270
|
|
|
} |
271
|
|
|
} |
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.