Passed
Push — master ( cdfad9...e39d65 )
by Joas
12:09 queued 10s
created
core/Migrations/Version17000Date20190514105811.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -37,42 +37,42 @@
 block discarded – undo
37 37
 
38 38
 class Version17000Date20190514105811 extends SimpleMigrationStep {
39 39
 
40
-	/**
41
-	 * @param IOutput $output
42
-	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
43
-	 * @param array $options
44
-	 * @return ISchemaWrapper
45
-	 */
46
-	public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
47
-		/** @var ISchemaWrapper $schema */
48
-		$schema = $schemaClosure();
49
-		if (!$schema->hasTable('filecache_extended')) {
50
-			$table = $schema->createTable('filecache_extended');
51
-			$table->addColumn('fileid', Types::BIGINT, [
52
-				'notnull' => true,
53
-				'length' => 4,
54
-				'unsigned' => true,
55
-			]);
56
-			$table->addColumn('metadata_etag', Types::STRING, [
57
-				'notnull' => false,
58
-				'length' => 40,
59
-			]);
60
-			$table->addColumn('creation_time', Types::BIGINT, [
61
-				'notnull' => true,
62
-				'length' => 20,
63
-				'default' => 0,
64
-			]);
65
-			$table->addColumn('upload_time', Types::BIGINT, [
66
-				'notnull' => true,
67
-				'length' => 20,
68
-				'default' => 0,
69
-			]);
70
-			$table->setPrimaryKey(['fileid'], 'fce_pk');
40
+    /**
41
+     * @param IOutput $output
42
+     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
43
+     * @param array $options
44
+     * @return ISchemaWrapper
45
+     */
46
+    public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
47
+        /** @var ISchemaWrapper $schema */
48
+        $schema = $schemaClosure();
49
+        if (!$schema->hasTable('filecache_extended')) {
50
+            $table = $schema->createTable('filecache_extended');
51
+            $table->addColumn('fileid', Types::BIGINT, [
52
+                'notnull' => true,
53
+                'length' => 4,
54
+                'unsigned' => true,
55
+            ]);
56
+            $table->addColumn('metadata_etag', Types::STRING, [
57
+                'notnull' => false,
58
+                'length' => 40,
59
+            ]);
60
+            $table->addColumn('creation_time', Types::BIGINT, [
61
+                'notnull' => true,
62
+                'length' => 20,
63
+                'default' => 0,
64
+            ]);
65
+            $table->addColumn('upload_time', Types::BIGINT, [
66
+                'notnull' => true,
67
+                'length' => 20,
68
+                'default' => 0,
69
+            ]);
70
+            $table->setPrimaryKey(['fileid'], 'fce_pk');
71 71
 //			$table->addUniqueIndex(['fileid'], 'fce_fileid_idx');
72
-			$table->addIndex(['creation_time'], 'fce_ctime_idx');
73
-			$table->addIndex(['upload_time'], 'fce_utime_idx');
74
-		}
72
+            $table->addIndex(['creation_time'], 'fce_ctime_idx');
73
+            $table->addIndex(['upload_time'], 'fce_utime_idx');
74
+        }
75 75
 
76
-		return $schema;
77
-	}
76
+        return $schema;
77
+    }
78 78
 }
Please login to merge, or discard this patch.
core/Application.php 2 patches
Indentation   +208 added lines, -208 removed lines patch added patch discarded remove patch
@@ -57,212 +57,212 @@
 block discarded – undo
57 57
  * @package OC\Core
58 58
  */
59 59
 class Application extends App {
60
-	public function __construct() {
61
-		parent::__construct('core');
62
-
63
-		$container = $this->getContainer();
64
-
65
-		$container->registerService('defaultMailAddress', function () {
66
-			return Util::getDefaultEmailAddress('lostpassword-noreply');
67
-		});
68
-
69
-		$server = $container->getServer();
70
-		/** @var IEventDispatcher $eventDispatcher */
71
-		$eventDispatcher = $server->query(IEventDispatcher::class);
72
-
73
-		$notificationManager = $server->getNotificationManager();
74
-		$notificationManager->registerNotifierService(RemoveLinkSharesNotifier::class);
75
-		$notificationManager->registerNotifierService(AuthenticationNotifier::class);
76
-
77
-		$oldEventDispatcher = $server->getEventDispatcher();
78
-
79
-		$oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_INDEXES_EVENT,
80
-			function (GenericEvent $event) use ($container) {
81
-				/** @var MissingIndexInformation $subject */
82
-				$subject = $event->getSubject();
83
-
84
-				$schema = new SchemaWrapper($container->query(IDBConnection::class));
85
-
86
-				if ($schema->hasTable('share')) {
87
-					$table = $schema->getTable('share');
88
-
89
-					if (!$table->hasIndex('share_with_index')) {
90
-						$subject->addHintForMissingSubject($table->getName(), 'share_with_index');
91
-					}
92
-					if (!$table->hasIndex('parent_index')) {
93
-						$subject->addHintForMissingSubject($table->getName(), 'parent_index');
94
-					}
95
-					if (!$table->hasIndex('owner_index')) {
96
-						$subject->addHintForMissingSubject($table->getName(), 'owner_index');
97
-					}
98
-					if (!$table->hasIndex('initiator_index')) {
99
-						$subject->addHintForMissingSubject($table->getName(), 'initiator_index');
100
-					}
101
-				}
102
-
103
-				if ($schema->hasTable('filecache')) {
104
-					$table = $schema->getTable('filecache');
105
-
106
-					if (!$table->hasIndex('fs_mtime')) {
107
-						$subject->addHintForMissingSubject($table->getName(), 'fs_mtime');
108
-					}
109
-
110
-					if (!$table->hasIndex('fs_size')) {
111
-						$subject->addHintForMissingSubject($table->getName(), 'fs_size');
112
-					}
113
-				}
114
-
115
-				if ($schema->hasTable('twofactor_providers')) {
116
-					$table = $schema->getTable('twofactor_providers');
117
-
118
-					if (!$table->hasIndex('twofactor_providers_uid')) {
119
-						$subject->addHintForMissingSubject($table->getName(), 'twofactor_providers_uid');
120
-					}
121
-				}
122
-
123
-				if ($schema->hasTable('login_flow_v2')) {
124
-					$table = $schema->getTable('login_flow_v2');
125
-
126
-					if (!$table->hasIndex('poll_token')) {
127
-						$subject->addHintForMissingSubject($table->getName(), 'poll_token');
128
-					}
129
-					if (!$table->hasIndex('login_token')) {
130
-						$subject->addHintForMissingSubject($table->getName(), 'login_token');
131
-					}
132
-					if (!$table->hasIndex('timestamp')) {
133
-						$subject->addHintForMissingSubject($table->getName(), 'timestamp');
134
-					}
135
-				}
136
-
137
-				if ($schema->hasTable('whats_new')) {
138
-					$table = $schema->getTable('whats_new');
139
-
140
-					if (!$table->hasIndex('version')) {
141
-						$subject->addHintForMissingSubject($table->getName(), 'version');
142
-					}
143
-				}
144
-
145
-				if ($schema->hasTable('cards')) {
146
-					$table = $schema->getTable('cards');
147
-
148
-					if (!$table->hasIndex('cards_abid')) {
149
-						$subject->addHintForMissingSubject($table->getName(), 'cards_abid');
150
-					}
151
-				}
152
-
153
-				if ($schema->hasTable('cards_properties')) {
154
-					$table = $schema->getTable('cards_properties');
155
-
156
-					if (!$table->hasIndex('cards_prop_abid')) {
157
-						$subject->addHintForMissingSubject($table->getName(), 'cards_prop_abid');
158
-					}
159
-				}
160
-
161
-				if ($schema->hasTable('calendarobjects_props')) {
162
-					$table = $schema->getTable('calendarobjects_props');
163
-
164
-					if (!$table->hasIndex('calendarobject_calid_index')) {
165
-						$subject->addHintForMissingSubject($table->getName(), 'calendarobject_calid_index');
166
-					}
167
-				}
168
-
169
-				if ($schema->hasTable('schedulingobjects')) {
170
-					$table = $schema->getTable('schedulingobjects');
171
-					if (!$table->hasIndex('schedulobj_principuri_index')) {
172
-						$subject->addHintForMissingSubject($table->getName(), 'schedulobj_principuri_index');
173
-					}
174
-				}
175
-
176
-				if ($schema->hasTable('properties')) {
177
-					$table = $schema->getTable('properties');
178
-					if (!$table->hasIndex('properties_path_index')) {
179
-						$subject->addHintForMissingSubject($table->getName(), 'properties_path_index');
180
-					}
181
-				}
182
-			}
183
-		);
184
-
185
-		$oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_PRIMARY_KEYS_EVENT,
186
-			function (GenericEvent $event) use ($container) {
187
-				/** @var MissingPrimaryKeyInformation $subject */
188
-				$subject = $event->getSubject();
189
-
190
-				$schema = new SchemaWrapper($container->query(IDBConnection::class));
191
-
192
-				if ($schema->hasTable('federated_reshares')) {
193
-					$table = $schema->getTable('federated_reshares');
194
-
195
-					if (!$table->hasPrimaryKey()) {
196
-						$subject->addHintForMissingSubject($table->getName());
197
-					}
198
-				}
199
-
200
-				if ($schema->hasTable('systemtag_object_mapping')) {
201
-					$table = $schema->getTable('systemtag_object_mapping');
202
-
203
-					if (!$table->hasPrimaryKey()) {
204
-						$subject->addHintForMissingSubject($table->getName());
205
-					}
206
-				}
207
-
208
-				if ($schema->hasTable('comments_read_markers')) {
209
-					$table = $schema->getTable('comments_read_markers');
210
-
211
-					if (!$table->hasPrimaryKey()) {
212
-						$subject->addHintForMissingSubject($table->getName());
213
-					}
214
-				}
215
-
216
-				if ($schema->hasTable('collres_resources')) {
217
-					$table = $schema->getTable('collres_resources');
218
-
219
-					if (!$table->hasPrimaryKey()) {
220
-						$subject->addHintForMissingSubject($table->getName());
221
-					}
222
-				}
223
-
224
-				if ($schema->hasTable('collres_accesscache')) {
225
-					$table = $schema->getTable('collres_accesscache');
226
-
227
-					if (!$table->hasPrimaryKey()) {
228
-						$subject->addHintForMissingSubject($table->getName());
229
-					}
230
-				}
231
-
232
-				if ($schema->hasTable('filecache_extended')) {
233
-					$table = $schema->getTable('filecache_extended');
234
-
235
-					if (!$table->hasPrimaryKey()) {
236
-						$subject->addHintForMissingSubject($table->getName());
237
-					}
238
-				}
239
-			}
240
-		);
241
-
242
-		$oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_COLUMNS_EVENT,
243
-			function (GenericEvent $event) use ($container) {
244
-				/** @var MissingColumnInformation $subject */
245
-				$subject = $event->getSubject();
246
-
247
-				$schema = new SchemaWrapper($container->query(IDBConnection::class));
248
-
249
-				if ($schema->hasTable('comments')) {
250
-					$table = $schema->getTable('comments');
251
-
252
-					if (!$table->hasColumn('reference_id')) {
253
-						$subject->addHintForMissingColumn($table->getName(), 'reference_id');
254
-					}
255
-				}
256
-			}
257
-		);
258
-
259
-		$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeActivityListener::class);
260
-		$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeNotificationsListener::class);
261
-		$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeEmailListener::class);
262
-		$eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeActivityListener::class);
263
-		$eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeNotificationsListener::class);
264
-		$eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeEmailListener::class);
265
-		$eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedStoreCleanupListener::class);
266
-		$eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedTokenCleanupListener::class);
267
-	}
60
+    public function __construct() {
61
+        parent::__construct('core');
62
+
63
+        $container = $this->getContainer();
64
+
65
+        $container->registerService('defaultMailAddress', function () {
66
+            return Util::getDefaultEmailAddress('lostpassword-noreply');
67
+        });
68
+
69
+        $server = $container->getServer();
70
+        /** @var IEventDispatcher $eventDispatcher */
71
+        $eventDispatcher = $server->query(IEventDispatcher::class);
72
+
73
+        $notificationManager = $server->getNotificationManager();
74
+        $notificationManager->registerNotifierService(RemoveLinkSharesNotifier::class);
75
+        $notificationManager->registerNotifierService(AuthenticationNotifier::class);
76
+
77
+        $oldEventDispatcher = $server->getEventDispatcher();
78
+
79
+        $oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_INDEXES_EVENT,
80
+            function (GenericEvent $event) use ($container) {
81
+                /** @var MissingIndexInformation $subject */
82
+                $subject = $event->getSubject();
83
+
84
+                $schema = new SchemaWrapper($container->query(IDBConnection::class));
85
+
86
+                if ($schema->hasTable('share')) {
87
+                    $table = $schema->getTable('share');
88
+
89
+                    if (!$table->hasIndex('share_with_index')) {
90
+                        $subject->addHintForMissingSubject($table->getName(), 'share_with_index');
91
+                    }
92
+                    if (!$table->hasIndex('parent_index')) {
93
+                        $subject->addHintForMissingSubject($table->getName(), 'parent_index');
94
+                    }
95
+                    if (!$table->hasIndex('owner_index')) {
96
+                        $subject->addHintForMissingSubject($table->getName(), 'owner_index');
97
+                    }
98
+                    if (!$table->hasIndex('initiator_index')) {
99
+                        $subject->addHintForMissingSubject($table->getName(), 'initiator_index');
100
+                    }
101
+                }
102
+
103
+                if ($schema->hasTable('filecache')) {
104
+                    $table = $schema->getTable('filecache');
105
+
106
+                    if (!$table->hasIndex('fs_mtime')) {
107
+                        $subject->addHintForMissingSubject($table->getName(), 'fs_mtime');
108
+                    }
109
+
110
+                    if (!$table->hasIndex('fs_size')) {
111
+                        $subject->addHintForMissingSubject($table->getName(), 'fs_size');
112
+                    }
113
+                }
114
+
115
+                if ($schema->hasTable('twofactor_providers')) {
116
+                    $table = $schema->getTable('twofactor_providers');
117
+
118
+                    if (!$table->hasIndex('twofactor_providers_uid')) {
119
+                        $subject->addHintForMissingSubject($table->getName(), 'twofactor_providers_uid');
120
+                    }
121
+                }
122
+
123
+                if ($schema->hasTable('login_flow_v2')) {
124
+                    $table = $schema->getTable('login_flow_v2');
125
+
126
+                    if (!$table->hasIndex('poll_token')) {
127
+                        $subject->addHintForMissingSubject($table->getName(), 'poll_token');
128
+                    }
129
+                    if (!$table->hasIndex('login_token')) {
130
+                        $subject->addHintForMissingSubject($table->getName(), 'login_token');
131
+                    }
132
+                    if (!$table->hasIndex('timestamp')) {
133
+                        $subject->addHintForMissingSubject($table->getName(), 'timestamp');
134
+                    }
135
+                }
136
+
137
+                if ($schema->hasTable('whats_new')) {
138
+                    $table = $schema->getTable('whats_new');
139
+
140
+                    if (!$table->hasIndex('version')) {
141
+                        $subject->addHintForMissingSubject($table->getName(), 'version');
142
+                    }
143
+                }
144
+
145
+                if ($schema->hasTable('cards')) {
146
+                    $table = $schema->getTable('cards');
147
+
148
+                    if (!$table->hasIndex('cards_abid')) {
149
+                        $subject->addHintForMissingSubject($table->getName(), 'cards_abid');
150
+                    }
151
+                }
152
+
153
+                if ($schema->hasTable('cards_properties')) {
154
+                    $table = $schema->getTable('cards_properties');
155
+
156
+                    if (!$table->hasIndex('cards_prop_abid')) {
157
+                        $subject->addHintForMissingSubject($table->getName(), 'cards_prop_abid');
158
+                    }
159
+                }
160
+
161
+                if ($schema->hasTable('calendarobjects_props')) {
162
+                    $table = $schema->getTable('calendarobjects_props');
163
+
164
+                    if (!$table->hasIndex('calendarobject_calid_index')) {
165
+                        $subject->addHintForMissingSubject($table->getName(), 'calendarobject_calid_index');
166
+                    }
167
+                }
168
+
169
+                if ($schema->hasTable('schedulingobjects')) {
170
+                    $table = $schema->getTable('schedulingobjects');
171
+                    if (!$table->hasIndex('schedulobj_principuri_index')) {
172
+                        $subject->addHintForMissingSubject($table->getName(), 'schedulobj_principuri_index');
173
+                    }
174
+                }
175
+
176
+                if ($schema->hasTable('properties')) {
177
+                    $table = $schema->getTable('properties');
178
+                    if (!$table->hasIndex('properties_path_index')) {
179
+                        $subject->addHintForMissingSubject($table->getName(), 'properties_path_index');
180
+                    }
181
+                }
182
+            }
183
+        );
184
+
185
+        $oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_PRIMARY_KEYS_EVENT,
186
+            function (GenericEvent $event) use ($container) {
187
+                /** @var MissingPrimaryKeyInformation $subject */
188
+                $subject = $event->getSubject();
189
+
190
+                $schema = new SchemaWrapper($container->query(IDBConnection::class));
191
+
192
+                if ($schema->hasTable('federated_reshares')) {
193
+                    $table = $schema->getTable('federated_reshares');
194
+
195
+                    if (!$table->hasPrimaryKey()) {
196
+                        $subject->addHintForMissingSubject($table->getName());
197
+                    }
198
+                }
199
+
200
+                if ($schema->hasTable('systemtag_object_mapping')) {
201
+                    $table = $schema->getTable('systemtag_object_mapping');
202
+
203
+                    if (!$table->hasPrimaryKey()) {
204
+                        $subject->addHintForMissingSubject($table->getName());
205
+                    }
206
+                }
207
+
208
+                if ($schema->hasTable('comments_read_markers')) {
209
+                    $table = $schema->getTable('comments_read_markers');
210
+
211
+                    if (!$table->hasPrimaryKey()) {
212
+                        $subject->addHintForMissingSubject($table->getName());
213
+                    }
214
+                }
215
+
216
+                if ($schema->hasTable('collres_resources')) {
217
+                    $table = $schema->getTable('collres_resources');
218
+
219
+                    if (!$table->hasPrimaryKey()) {
220
+                        $subject->addHintForMissingSubject($table->getName());
221
+                    }
222
+                }
223
+
224
+                if ($schema->hasTable('collres_accesscache')) {
225
+                    $table = $schema->getTable('collres_accesscache');
226
+
227
+                    if (!$table->hasPrimaryKey()) {
228
+                        $subject->addHintForMissingSubject($table->getName());
229
+                    }
230
+                }
231
+
232
+                if ($schema->hasTable('filecache_extended')) {
233
+                    $table = $schema->getTable('filecache_extended');
234
+
235
+                    if (!$table->hasPrimaryKey()) {
236
+                        $subject->addHintForMissingSubject($table->getName());
237
+                    }
238
+                }
239
+            }
240
+        );
241
+
242
+        $oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_COLUMNS_EVENT,
243
+            function (GenericEvent $event) use ($container) {
244
+                /** @var MissingColumnInformation $subject */
245
+                $subject = $event->getSubject();
246
+
247
+                $schema = new SchemaWrapper($container->query(IDBConnection::class));
248
+
249
+                if ($schema->hasTable('comments')) {
250
+                    $table = $schema->getTable('comments');
251
+
252
+                    if (!$table->hasColumn('reference_id')) {
253
+                        $subject->addHintForMissingColumn($table->getName(), 'reference_id');
254
+                    }
255
+                }
256
+            }
257
+        );
258
+
259
+        $eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeActivityListener::class);
260
+        $eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeNotificationsListener::class);
261
+        $eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeEmailListener::class);
262
+        $eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeActivityListener::class);
263
+        $eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeNotificationsListener::class);
264
+        $eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeEmailListener::class);
265
+        $eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedStoreCleanupListener::class);
266
+        $eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedTokenCleanupListener::class);
267
+    }
268 268
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -62,7 +62,7 @@  discard block
 block discarded – undo
62 62
 
63 63
 		$container = $this->getContainer();
64 64
 
65
-		$container->registerService('defaultMailAddress', function () {
65
+		$container->registerService('defaultMailAddress', function() {
66 66
 			return Util::getDefaultEmailAddress('lostpassword-noreply');
67 67
 		});
68 68
 
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
 		$oldEventDispatcher = $server->getEventDispatcher();
78 78
 
79 79
 		$oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_INDEXES_EVENT,
80
-			function (GenericEvent $event) use ($container) {
80
+			function(GenericEvent $event) use ($container) {
81 81
 				/** @var MissingIndexInformation $subject */
82 82
 				$subject = $event->getSubject();
83 83
 
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
 		);
184 184
 
185 185
 		$oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_PRIMARY_KEYS_EVENT,
186
-			function (GenericEvent $event) use ($container) {
186
+			function(GenericEvent $event) use ($container) {
187 187
 				/** @var MissingPrimaryKeyInformation $subject */
188 188
 				$subject = $event->getSubject();
189 189
 
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
 		);
241 241
 
242 242
 		$oldEventDispatcher->addListener(IDBConnection::CHECK_MISSING_COLUMNS_EVENT,
243
-			function (GenericEvent $event) use ($container) {
243
+			function(GenericEvent $event) use ($container) {
244 244
 				/** @var MissingColumnInformation $subject */
245 245
 				$subject = $event->getSubject();
246 246
 
Please login to merge, or discard this patch.
core/Command/Db/AddMissingPrimaryKeys.php 1 patch
Indentation   +128 added lines, -128 removed lines patch added patch discarded remove patch
@@ -50,132 +50,132 @@
 block discarded – undo
50 50
  */
51 51
 class AddMissingPrimaryKeys extends Command {
52 52
 
53
-	/** @var IDBConnection */
54
-	private $connection;
55
-
56
-	/** @var EventDispatcherInterface */
57
-	private $dispatcher;
58
-
59
-	public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) {
60
-		parent::__construct();
61
-
62
-		$this->connection = $connection;
63
-		$this->dispatcher = $dispatcher;
64
-	}
65
-
66
-	protected function configure() {
67
-		$this
68
-			->setName('db:add-missing-primary-keys')
69
-			->setDescription('Add missing primary keys to the database tables');
70
-	}
71
-
72
-	protected function execute(InputInterface $input, OutputInterface $output): int {
73
-		$this->addCorePrimaryKeys($output);
74
-
75
-		// Dispatch event so apps can also update indexes if needed
76
-		$event = new GenericEvent($output);
77
-		$this->dispatcher->dispatch(IDBConnection::ADD_MISSING_PRIMARY_KEYS_EVENT, $event);
78
-		return 0;
79
-	}
80
-
81
-	/**
82
-	 * add missing indices to the share table
83
-	 *
84
-	 * @param OutputInterface $output
85
-	 * @throws \Doctrine\DBAL\Schema\SchemaException
86
-	 */
87
-	private function addCorePrimaryKeys(OutputInterface $output) {
88
-		$output->writeln('<info>Check primary keys.</info>');
89
-
90
-		$schema = new SchemaWrapper($this->connection);
91
-		$updated = false;
92
-
93
-		if ($schema->hasTable('federated_reshares')) {
94
-			$table = $schema->getTable('federated_reshares');
95
-			if (!$table->hasPrimaryKey()) {
96
-				$output->writeln('<info>Adding primary key to the federated_reshares table, this can take some time...</info>');
97
-				$table->setPrimaryKey(['share_id'], 'federated_res_pk');
98
-				if ($table->hasIndex('share_id_index')) {
99
-					$table->dropIndex('share_id_index');
100
-				}
101
-				$this->connection->migrateToSchema($schema->getWrappedSchema());
102
-				$updated = true;
103
-				$output->writeln('<info>federated_reshares table updated successfully.</info>');
104
-			}
105
-		}
106
-
107
-		if ($schema->hasTable('systemtag_object_mapping')) {
108
-			$table = $schema->getTable('systemtag_object_mapping');
109
-			if (!$table->hasPrimaryKey()) {
110
-				$output->writeln('<info>Adding primary key to the systemtag_object_mapping table, this can take some time...</info>');
111
-				$table->setPrimaryKey(['objecttype', 'objectid', 'systemtagid'], 'som_pk');
112
-				if ($table->hasIndex('mapping')) {
113
-					$table->dropIndex('mapping');
114
-				}
115
-				$this->connection->migrateToSchema($schema->getWrappedSchema());
116
-				$updated = true;
117
-				$output->writeln('<info>systemtag_object_mapping table updated successfully.</info>');
118
-			}
119
-		}
120
-
121
-		if ($schema->hasTable('comments_read_markers')) {
122
-			$table = $schema->getTable('comments_read_markers');
123
-			if (!$table->hasPrimaryKey()) {
124
-				$output->writeln('<info>Adding primary key to the comments_read_markers table, this can take some time...</info>');
125
-				$table->setPrimaryKey(['user_id', 'object_type', 'object_id'], 'crm_pk');
126
-				if ($table->hasIndex('comments_marker_index')) {
127
-					$table->dropIndex('comments_marker_index');
128
-				}
129
-				$this->connection->migrateToSchema($schema->getWrappedSchema());
130
-				$updated = true;
131
-				$output->writeln('<info>comments_read_markers table updated successfully.</info>');
132
-			}
133
-		}
134
-
135
-		if ($schema->hasTable('collres_resources')) {
136
-			$table = $schema->getTable('collres_resources');
137
-			if (!$table->hasPrimaryKey()) {
138
-				$output->writeln('<info>Adding primary key to the collres_resources table, this can take some time...</info>');
139
-				$table->setPrimaryKey(['collection_id', 'resource_type', 'resource_id'], 'crr_pk');
140
-				if ($table->hasIndex('collres_unique_res')) {
141
-					$table->dropIndex('collres_unique_res');
142
-				}
143
-				$this->connection->migrateToSchema($schema->getWrappedSchema());
144
-				$updated = true;
145
-				$output->writeln('<info>collres_resources table updated successfully.</info>');
146
-			}
147
-		}
148
-
149
-		if ($schema->hasTable('collres_accesscache')) {
150
-			$table = $schema->getTable('collres_accesscache');
151
-			if (!$table->hasPrimaryKey()) {
152
-				$output->writeln('<info>Adding primary key to the collres_accesscache table, this can take some time...</info>');
153
-				$table->setPrimaryKey(['user_id', 'collection_id', 'resource_type', 'resource_id'], 'cra_pk');
154
-				if ($table->hasIndex('collres_unique_user')) {
155
-					$table->dropIndex('collres_unique_user');
156
-				}
157
-				$this->connection->migrateToSchema($schema->getWrappedSchema());
158
-				$updated = true;
159
-				$output->writeln('<info>collres_accesscache table updated successfully.</info>');
160
-			}
161
-		}
162
-
163
-		if ($schema->hasTable('filecache_extended')) {
164
-			$table = $schema->getTable('filecache_extended');
165
-			if (!$table->hasPrimaryKey()) {
166
-				$output->writeln('<info>Adding primary key to the filecache_extended table, this can take some time...</info>');
167
-				$table->setPrimaryKey(['fileid'], 'fce_pk');
168
-				if ($table->hasIndex('fce_fileid_idx')) {
169
-					$table->dropIndex('fce_fileid_idx');
170
-				}
171
-				$this->connection->migrateToSchema($schema->getWrappedSchema());
172
-				$updated = true;
173
-				$output->writeln('<info>filecache_extended table updated successfully.</info>');
174
-			}
175
-		}
176
-
177
-		if (!$updated) {
178
-			$output->writeln('<info>Done.</info>');
179
-		}
180
-	}
53
+    /** @var IDBConnection */
54
+    private $connection;
55
+
56
+    /** @var EventDispatcherInterface */
57
+    private $dispatcher;
58
+
59
+    public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) {
60
+        parent::__construct();
61
+
62
+        $this->connection = $connection;
63
+        $this->dispatcher = $dispatcher;
64
+    }
65
+
66
+    protected function configure() {
67
+        $this
68
+            ->setName('db:add-missing-primary-keys')
69
+            ->setDescription('Add missing primary keys to the database tables');
70
+    }
71
+
72
+    protected function execute(InputInterface $input, OutputInterface $output): int {
73
+        $this->addCorePrimaryKeys($output);
74
+
75
+        // Dispatch event so apps can also update indexes if needed
76
+        $event = new GenericEvent($output);
77
+        $this->dispatcher->dispatch(IDBConnection::ADD_MISSING_PRIMARY_KEYS_EVENT, $event);
78
+        return 0;
79
+    }
80
+
81
+    /**
82
+     * add missing indices to the share table
83
+     *
84
+     * @param OutputInterface $output
85
+     * @throws \Doctrine\DBAL\Schema\SchemaException
86
+     */
87
+    private function addCorePrimaryKeys(OutputInterface $output) {
88
+        $output->writeln('<info>Check primary keys.</info>');
89
+
90
+        $schema = new SchemaWrapper($this->connection);
91
+        $updated = false;
92
+
93
+        if ($schema->hasTable('federated_reshares')) {
94
+            $table = $schema->getTable('federated_reshares');
95
+            if (!$table->hasPrimaryKey()) {
96
+                $output->writeln('<info>Adding primary key to the federated_reshares table, this can take some time...</info>');
97
+                $table->setPrimaryKey(['share_id'], 'federated_res_pk');
98
+                if ($table->hasIndex('share_id_index')) {
99
+                    $table->dropIndex('share_id_index');
100
+                }
101
+                $this->connection->migrateToSchema($schema->getWrappedSchema());
102
+                $updated = true;
103
+                $output->writeln('<info>federated_reshares table updated successfully.</info>');
104
+            }
105
+        }
106
+
107
+        if ($schema->hasTable('systemtag_object_mapping')) {
108
+            $table = $schema->getTable('systemtag_object_mapping');
109
+            if (!$table->hasPrimaryKey()) {
110
+                $output->writeln('<info>Adding primary key to the systemtag_object_mapping table, this can take some time...</info>');
111
+                $table->setPrimaryKey(['objecttype', 'objectid', 'systemtagid'], 'som_pk');
112
+                if ($table->hasIndex('mapping')) {
113
+                    $table->dropIndex('mapping');
114
+                }
115
+                $this->connection->migrateToSchema($schema->getWrappedSchema());
116
+                $updated = true;
117
+                $output->writeln('<info>systemtag_object_mapping table updated successfully.</info>');
118
+            }
119
+        }
120
+
121
+        if ($schema->hasTable('comments_read_markers')) {
122
+            $table = $schema->getTable('comments_read_markers');
123
+            if (!$table->hasPrimaryKey()) {
124
+                $output->writeln('<info>Adding primary key to the comments_read_markers table, this can take some time...</info>');
125
+                $table->setPrimaryKey(['user_id', 'object_type', 'object_id'], 'crm_pk');
126
+                if ($table->hasIndex('comments_marker_index')) {
127
+                    $table->dropIndex('comments_marker_index');
128
+                }
129
+                $this->connection->migrateToSchema($schema->getWrappedSchema());
130
+                $updated = true;
131
+                $output->writeln('<info>comments_read_markers table updated successfully.</info>');
132
+            }
133
+        }
134
+
135
+        if ($schema->hasTable('collres_resources')) {
136
+            $table = $schema->getTable('collres_resources');
137
+            if (!$table->hasPrimaryKey()) {
138
+                $output->writeln('<info>Adding primary key to the collres_resources table, this can take some time...</info>');
139
+                $table->setPrimaryKey(['collection_id', 'resource_type', 'resource_id'], 'crr_pk');
140
+                if ($table->hasIndex('collres_unique_res')) {
141
+                    $table->dropIndex('collres_unique_res');
142
+                }
143
+                $this->connection->migrateToSchema($schema->getWrappedSchema());
144
+                $updated = true;
145
+                $output->writeln('<info>collres_resources table updated successfully.</info>');
146
+            }
147
+        }
148
+
149
+        if ($schema->hasTable('collres_accesscache')) {
150
+            $table = $schema->getTable('collres_accesscache');
151
+            if (!$table->hasPrimaryKey()) {
152
+                $output->writeln('<info>Adding primary key to the collres_accesscache table, this can take some time...</info>');
153
+                $table->setPrimaryKey(['user_id', 'collection_id', 'resource_type', 'resource_id'], 'cra_pk');
154
+                if ($table->hasIndex('collres_unique_user')) {
155
+                    $table->dropIndex('collres_unique_user');
156
+                }
157
+                $this->connection->migrateToSchema($schema->getWrappedSchema());
158
+                $updated = true;
159
+                $output->writeln('<info>collres_accesscache table updated successfully.</info>');
160
+            }
161
+        }
162
+
163
+        if ($schema->hasTable('filecache_extended')) {
164
+            $table = $schema->getTable('filecache_extended');
165
+            if (!$table->hasPrimaryKey()) {
166
+                $output->writeln('<info>Adding primary key to the filecache_extended table, this can take some time...</info>');
167
+                $table->setPrimaryKey(['fileid'], 'fce_pk');
168
+                if ($table->hasIndex('fce_fileid_idx')) {
169
+                    $table->dropIndex('fce_fileid_idx');
170
+                }
171
+                $this->connection->migrateToSchema($schema->getWrappedSchema());
172
+                $updated = true;
173
+                $output->writeln('<info>filecache_extended table updated successfully.</info>');
174
+            }
175
+        }
176
+
177
+        if (!$updated) {
178
+            $output->writeln('<info>Done.</info>');
179
+        }
180
+    }
181 181
 }
Please login to merge, or discard this patch.
apps/dav/composer/composer/autoload_classmap.php 1 patch
Spacing   +251 added lines, -251 removed lines patch added patch discarded remove patch
@@ -6,255 +6,255 @@
 block discarded – undo
6 6
 $baseDir = $vendorDir;
7 7
 
8 8
 return array(
9
-    'OCA\\DAV\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
10
-    'OCA\\DAV\\AppInfo\\PluginManager' => $baseDir . '/../lib/AppInfo/PluginManager.php',
11
-    'OCA\\DAV\\Avatars\\AvatarHome' => $baseDir . '/../lib/Avatars/AvatarHome.php',
12
-    'OCA\\DAV\\Avatars\\AvatarNode' => $baseDir . '/../lib/Avatars/AvatarNode.php',
13
-    'OCA\\DAV\\Avatars\\RootCollection' => $baseDir . '/../lib/Avatars/RootCollection.php',
14
-    'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => $baseDir . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
15
-    'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => $baseDir . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
16
-    'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => $baseDir . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
17
-    'OCA\\DAV\\BackgroundJob\\EventReminderJob' => $baseDir . '/../lib/BackgroundJob/EventReminderJob.php',
18
-    'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => $baseDir . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
19
-    'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => $baseDir . '/../lib/BackgroundJob/RefreshWebcalJob.php',
20
-    'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => $baseDir . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
21
-    'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => $baseDir . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
22
-    'OCA\\DAV\\BackgroundJob\\UploadCleanup' => $baseDir . '/../lib/BackgroundJob/UploadCleanup.php',
23
-    'OCA\\DAV\\CalDAV\\Activity\\Backend' => $baseDir . '/../lib/CalDAV/Activity/Backend.php',
24
-    'OCA\\DAV\\CalDAV\\Activity\\Filter\\Calendar' => $baseDir . '/../lib/CalDAV/Activity/Filter/Calendar.php',
25
-    'OCA\\DAV\\CalDAV\\Activity\\Filter\\Todo' => $baseDir . '/../lib/CalDAV/Activity/Filter/Todo.php',
26
-    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Base' => $baseDir . '/../lib/CalDAV/Activity/Provider/Base.php',
27
-    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Calendar' => $baseDir . '/../lib/CalDAV/Activity/Provider/Calendar.php',
28
-    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Event' => $baseDir . '/../lib/CalDAV/Activity/Provider/Event.php',
29
-    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Todo' => $baseDir . '/../lib/CalDAV/Activity/Provider/Todo.php',
30
-    'OCA\\DAV\\CalDAV\\Activity\\Setting\\CalDAVSetting' => $baseDir . '/../lib/CalDAV/Activity/Setting/CalDAVSetting.php',
31
-    'OCA\\DAV\\CalDAV\\Activity\\Setting\\Calendar' => $baseDir . '/../lib/CalDAV/Activity/Setting/Calendar.php',
32
-    'OCA\\DAV\\CalDAV\\Activity\\Setting\\Event' => $baseDir . '/../lib/CalDAV/Activity/Setting/Event.php',
33
-    'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => $baseDir . '/../lib/CalDAV/Activity/Setting/Todo.php',
34
-    'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => $baseDir . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
35
-    'OCA\\DAV\\CalDAV\\BirthdayService' => $baseDir . '/../lib/CalDAV/BirthdayService.php',
36
-    'OCA\\DAV\\CalDAV\\CachedSubscription' => $baseDir . '/../lib/CalDAV/CachedSubscription.php',
37
-    'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => $baseDir . '/../lib/CalDAV/CachedSubscriptionObject.php',
38
-    'OCA\\DAV\\CalDAV\\CalDavBackend' => $baseDir . '/../lib/CalDAV/CalDavBackend.php',
39
-    'OCA\\DAV\\CalDAV\\Calendar' => $baseDir . '/../lib/CalDAV/Calendar.php',
40
-    'OCA\\DAV\\CalDAV\\CalendarHome' => $baseDir . '/../lib/CalDAV/CalendarHome.php',
41
-    'OCA\\DAV\\CalDAV\\CalendarImpl' => $baseDir . '/../lib/CalDAV/CalendarImpl.php',
42
-    'OCA\\DAV\\CalDAV\\CalendarManager' => $baseDir . '/../lib/CalDAV/CalendarManager.php',
43
-    'OCA\\DAV\\CalDAV\\CalendarObject' => $baseDir . '/../lib/CalDAV/CalendarObject.php',
44
-    'OCA\\DAV\\CalDAV\\CalendarRoot' => $baseDir . '/../lib/CalDAV/CalendarRoot.php',
45
-    'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => $baseDir . '/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
46
-    'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => $baseDir . '/../lib/CalDAV/Integration/ExternalCalendar.php',
47
-    'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => $baseDir . '/../lib/CalDAV/Integration/ICalendarProvider.php',
48
-    'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => $baseDir . '/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
49
-    'OCA\\DAV\\CalDAV\\Outbox' => $baseDir . '/../lib/CalDAV/Outbox.php',
50
-    'OCA\\DAV\\CalDAV\\Plugin' => $baseDir . '/../lib/CalDAV/Plugin.php',
51
-    'OCA\\DAV\\CalDAV\\Principal\\Collection' => $baseDir . '/../lib/CalDAV/Principal/Collection.php',
52
-    'OCA\\DAV\\CalDAV\\Principal\\User' => $baseDir . '/../lib/CalDAV/Principal/User.php',
53
-    'OCA\\DAV\\CalDAV\\Proxy\\Proxy' => $baseDir . '/../lib/CalDAV/Proxy/Proxy.php',
54
-    'OCA\\DAV\\CalDAV\\Proxy\\ProxyMapper' => $baseDir . '/../lib/CalDAV/Proxy/ProxyMapper.php',
55
-    'OCA\\DAV\\CalDAV\\PublicCalendar' => $baseDir . '/../lib/CalDAV/PublicCalendar.php',
56
-    'OCA\\DAV\\CalDAV\\PublicCalendarObject' => $baseDir . '/../lib/CalDAV/PublicCalendarObject.php',
57
-    'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => $baseDir . '/../lib/CalDAV/PublicCalendarRoot.php',
58
-    'OCA\\DAV\\CalDAV\\Publishing\\PublishPlugin' => $baseDir . '/../lib/CalDAV/Publishing/PublishPlugin.php',
59
-    'OCA\\DAV\\CalDAV\\Publishing\\Xml\\Publisher' => $baseDir . '/../lib/CalDAV/Publishing/Xml/Publisher.php',
60
-    'OCA\\DAV\\CalDAV\\Reminder\\Backend' => $baseDir . '/../lib/CalDAV/Reminder/Backend.php',
61
-    'OCA\\DAV\\CalDAV\\Reminder\\INotificationProvider' => $baseDir . '/../lib/CalDAV/Reminder/INotificationProvider.php',
62
-    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProviderManager' => $baseDir . '/../lib/CalDAV/Reminder/NotificationProviderManager.php',
63
-    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AbstractProvider' => $baseDir . '/../lib/CalDAV/Reminder/NotificationProvider/AbstractProvider.php',
64
-    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AudioProvider' => $baseDir . '/../lib/CalDAV/Reminder/NotificationProvider/AudioProvider.php',
65
-    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\EmailProvider' => $baseDir . '/../lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php',
66
-    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\ProviderNotAvailableException' => $baseDir . '/../lib/CalDAV/Reminder/NotificationProvider/ProviderNotAvailableException.php',
67
-    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\PushProvider' => $baseDir . '/../lib/CalDAV/Reminder/NotificationProvider/PushProvider.php',
68
-    'OCA\\DAV\\CalDAV\\Reminder\\NotificationTypeDoesNotExistException' => $baseDir . '/../lib/CalDAV/Reminder/NotificationTypeDoesNotExistException.php',
69
-    'OCA\\DAV\\CalDAV\\Reminder\\Notifier' => $baseDir . '/../lib/CalDAV/Reminder/Notifier.php',
70
-    'OCA\\DAV\\CalDAV\\Reminder\\ReminderService' => $baseDir . '/../lib/CalDAV/Reminder/ReminderService.php',
71
-    'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
72
-    'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
73
-    'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
74
-    'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => $baseDir . '/../lib/CalDAV/Schedule/IMipPlugin.php',
75
-    'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => $baseDir . '/../lib/CalDAV/Schedule/Plugin.php',
76
-    'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => $baseDir . '/../lib/CalDAV/Search/SearchPlugin.php',
77
-    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/CompFilter.php',
78
-    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/LimitFilter.php',
79
-    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/OffsetFilter.php',
80
-    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/ParamFilter.php',
81
-    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
82
-    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
83
-    'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => $baseDir . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
84
-    'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => $baseDir . '/../lib/CalDAV/WebcalCaching/Plugin.php',
85
-    'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => $baseDir . '/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
86
-    'OCA\\DAV\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
87
-    'OCA\\DAV\\CardDAV\\AddressBook' => $baseDir . '/../lib/CardDAV/AddressBook.php',
88
-    'OCA\\DAV\\CardDAV\\AddressBookImpl' => $baseDir . '/../lib/CardDAV/AddressBookImpl.php',
89
-    'OCA\\DAV\\CardDAV\\AddressBookRoot' => $baseDir . '/../lib/CardDAV/AddressBookRoot.php',
90
-    'OCA\\DAV\\CardDAV\\CardDavBackend' => $baseDir . '/../lib/CardDAV/CardDavBackend.php',
91
-    'OCA\\DAV\\CardDAV\\ContactsManager' => $baseDir . '/../lib/CardDAV/ContactsManager.php',
92
-    'OCA\\DAV\\CardDAV\\Converter' => $baseDir . '/../lib/CardDAV/Converter.php',
93
-    'OCA\\DAV\\CardDAV\\HasPhotoPlugin' => $baseDir . '/../lib/CardDAV/HasPhotoPlugin.php',
94
-    'OCA\\DAV\\CardDAV\\ImageExportPlugin' => $baseDir . '/../lib/CardDAV/ImageExportPlugin.php',
95
-    'OCA\\DAV\\CardDAV\\Integration\\ExternalAddressBook' => $baseDir . '/../lib/CardDAV/Integration/ExternalAddressBook.php',
96
-    'OCA\\DAV\\CardDAV\\Integration\\IAddressBookProvider' => $baseDir . '/../lib/CardDAV/Integration/IAddressBookProvider.php',
97
-    'OCA\\DAV\\CardDAV\\MultiGetExportPlugin' => $baseDir . '/../lib/CardDAV/MultiGetExportPlugin.php',
98
-    'OCA\\DAV\\CardDAV\\PhotoCache' => $baseDir . '/../lib/CardDAV/PhotoCache.php',
99
-    'OCA\\DAV\\CardDAV\\Plugin' => $baseDir . '/../lib/CardDAV/Plugin.php',
100
-    'OCA\\DAV\\CardDAV\\SyncService' => $baseDir . '/../lib/CardDAV/SyncService.php',
101
-    'OCA\\DAV\\CardDAV\\SystemAddressbook' => $baseDir . '/../lib/CardDAV/SystemAddressbook.php',
102
-    'OCA\\DAV\\CardDAV\\UserAddressBooks' => $baseDir . '/../lib/CardDAV/UserAddressBooks.php',
103
-    'OCA\\DAV\\CardDAV\\Xml\\Groups' => $baseDir . '/../lib/CardDAV/Xml/Groups.php',
104
-    'OCA\\DAV\\Command\\CreateAddressBook' => $baseDir . '/../lib/Command/CreateAddressBook.php',
105
-    'OCA\\DAV\\Command\\CreateCalendar' => $baseDir . '/../lib/Command/CreateCalendar.php',
106
-    'OCA\\DAV\\Command\\ListCalendars' => $baseDir . '/../lib/Command/ListCalendars.php',
107
-    'OCA\\DAV\\Command\\MoveCalendar' => $baseDir . '/../lib/Command/MoveCalendar.php',
108
-    'OCA\\DAV\\Command\\RemoveInvalidShares' => $baseDir . '/../lib/Command/RemoveInvalidShares.php',
109
-    'OCA\\DAV\\Command\\SendEventReminders' => $baseDir . '/../lib/Command/SendEventReminders.php',
110
-    'OCA\\DAV\\Command\\SyncBirthdayCalendar' => $baseDir . '/../lib/Command/SyncBirthdayCalendar.php',
111
-    'OCA\\DAV\\Command\\SyncSystemAddressBook' => $baseDir . '/../lib/Command/SyncSystemAddressBook.php',
112
-    'OCA\\DAV\\Comments\\CommentNode' => $baseDir . '/../lib/Comments/CommentNode.php',
113
-    'OCA\\DAV\\Comments\\CommentsPlugin' => $baseDir . '/../lib/Comments/CommentsPlugin.php',
114
-    'OCA\\DAV\\Comments\\EntityCollection' => $baseDir . '/../lib/Comments/EntityCollection.php',
115
-    'OCA\\DAV\\Comments\\EntityTypeCollection' => $baseDir . '/../lib/Comments/EntityTypeCollection.php',
116
-    'OCA\\DAV\\Comments\\RootCollection' => $baseDir . '/../lib/Comments/RootCollection.php',
117
-    'OCA\\DAV\\Connector\\LegacyDAVACL' => $baseDir . '/../lib/Connector/LegacyDAVACL.php',
118
-    'OCA\\DAV\\Connector\\PublicAuth' => $baseDir . '/../lib/Connector/PublicAuth.php',
119
-    'OCA\\DAV\\Connector\\Sabre\\AnonymousOptionsPlugin' => $baseDir . '/../lib/Connector/Sabre/AnonymousOptionsPlugin.php',
120
-    'OCA\\DAV\\Connector\\Sabre\\AppEnabledPlugin' => $baseDir . '/../lib/Connector/Sabre/AppEnabledPlugin.php',
121
-    'OCA\\DAV\\Connector\\Sabre\\Auth' => $baseDir . '/../lib/Connector/Sabre/Auth.php',
122
-    'OCA\\DAV\\Connector\\Sabre\\BearerAuth' => $baseDir . '/../lib/Connector/Sabre/BearerAuth.php',
123
-    'OCA\\DAV\\Connector\\Sabre\\BlockLegacyClientPlugin' => $baseDir . '/../lib/Connector/Sabre/BlockLegacyClientPlugin.php',
124
-    'OCA\\DAV\\Connector\\Sabre\\CachingTree' => $baseDir . '/../lib/Connector/Sabre/CachingTree.php',
125
-    'OCA\\DAV\\Connector\\Sabre\\ChecksumList' => $baseDir . '/../lib/Connector/Sabre/ChecksumList.php',
126
-    'OCA\\DAV\\Connector\\Sabre\\CommentPropertiesPlugin' => $baseDir . '/../lib/Connector/Sabre/CommentPropertiesPlugin.php',
127
-    'OCA\\DAV\\Connector\\Sabre\\CopyEtagHeaderPlugin' => $baseDir . '/../lib/Connector/Sabre/CopyEtagHeaderPlugin.php',
128
-    'OCA\\DAV\\Connector\\Sabre\\DavAclPlugin' => $baseDir . '/../lib/Connector/Sabre/DavAclPlugin.php',
129
-    'OCA\\DAV\\Connector\\Sabre\\Directory' => $baseDir . '/../lib/Connector/Sabre/Directory.php',
130
-    'OCA\\DAV\\Connector\\Sabre\\DummyGetResponsePlugin' => $baseDir . '/../lib/Connector/Sabre/DummyGetResponsePlugin.php',
131
-    'OCA\\DAV\\Connector\\Sabre\\ExceptionLoggerPlugin' => $baseDir . '/../lib/Connector/Sabre/ExceptionLoggerPlugin.php',
132
-    'OCA\\DAV\\Connector\\Sabre\\Exception\\EntityTooLarge' => $baseDir . '/../lib/Connector/Sabre/Exception/EntityTooLarge.php',
133
-    'OCA\\DAV\\Connector\\Sabre\\Exception\\FileLocked' => $baseDir . '/../lib/Connector/Sabre/Exception/FileLocked.php',
134
-    'OCA\\DAV\\Connector\\Sabre\\Exception\\Forbidden' => $baseDir . '/../lib/Connector/Sabre/Exception/Forbidden.php',
135
-    'OCA\\DAV\\Connector\\Sabre\\Exception\\InvalidPath' => $baseDir . '/../lib/Connector/Sabre/Exception/InvalidPath.php',
136
-    'OCA\\DAV\\Connector\\Sabre\\Exception\\PasswordLoginForbidden' => $baseDir . '/../lib/Connector/Sabre/Exception/PasswordLoginForbidden.php',
137
-    'OCA\\DAV\\Connector\\Sabre\\Exception\\UnsupportedMediaType' => $baseDir . '/../lib/Connector/Sabre/Exception/UnsupportedMediaType.php',
138
-    'OCA\\DAV\\Connector\\Sabre\\FakeLockerPlugin' => $baseDir . '/../lib/Connector/Sabre/FakeLockerPlugin.php',
139
-    'OCA\\DAV\\Connector\\Sabre\\File' => $baseDir . '/../lib/Connector/Sabre/File.php',
140
-    'OCA\\DAV\\Connector\\Sabre\\FilesPlugin' => $baseDir . '/../lib/Connector/Sabre/FilesPlugin.php',
141
-    'OCA\\DAV\\Connector\\Sabre\\FilesReportPlugin' => $baseDir . '/../lib/Connector/Sabre/FilesReportPlugin.php',
142
-    'OCA\\DAV\\Connector\\Sabre\\LockPlugin' => $baseDir . '/../lib/Connector/Sabre/LockPlugin.php',
143
-    'OCA\\DAV\\Connector\\Sabre\\MaintenancePlugin' => $baseDir . '/../lib/Connector/Sabre/MaintenancePlugin.php',
144
-    'OCA\\DAV\\Connector\\Sabre\\Node' => $baseDir . '/../lib/Connector/Sabre/Node.php',
145
-    'OCA\\DAV\\Connector\\Sabre\\ObjectTree' => $baseDir . '/../lib/Connector/Sabre/ObjectTree.php',
146
-    'OCA\\DAV\\Connector\\Sabre\\Principal' => $baseDir . '/../lib/Connector/Sabre/Principal.php',
147
-    'OCA\\DAV\\Connector\\Sabre\\PropfindCompressionPlugin' => $baseDir . '/../lib/Connector/Sabre/PropfindCompressionPlugin.php',
148
-    'OCA\\DAV\\Connector\\Sabre\\QuotaPlugin' => $baseDir . '/../lib/Connector/Sabre/QuotaPlugin.php',
149
-    'OCA\\DAV\\Connector\\Sabre\\Server' => $baseDir . '/../lib/Connector/Sabre/Server.php',
150
-    'OCA\\DAV\\Connector\\Sabre\\ServerFactory' => $baseDir . '/../lib/Connector/Sabre/ServerFactory.php',
151
-    'OCA\\DAV\\Connector\\Sabre\\ShareTypeList' => $baseDir . '/../lib/Connector/Sabre/ShareTypeList.php',
152
-    'OCA\\DAV\\Connector\\Sabre\\ShareeList' => $baseDir . '/../lib/Connector/Sabre/ShareeList.php',
153
-    'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => $baseDir . '/../lib/Connector/Sabre/SharesPlugin.php',
154
-    'OCA\\DAV\\Connector\\Sabre\\TagList' => $baseDir . '/../lib/Connector/Sabre/TagList.php',
155
-    'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => $baseDir . '/../lib/Connector/Sabre/TagsPlugin.php',
156
-    'OCA\\DAV\\Controller\\BirthdayCalendarController' => $baseDir . '/../lib/Controller/BirthdayCalendarController.php',
157
-    'OCA\\DAV\\Controller\\DirectController' => $baseDir . '/../lib/Controller/DirectController.php',
158
-    'OCA\\DAV\\Controller\\InvitationResponseController' => $baseDir . '/../lib/Controller/InvitationResponseController.php',
159
-    'OCA\\DAV\\DAV\\CustomPropertiesBackend' => $baseDir . '/../lib/DAV/CustomPropertiesBackend.php',
160
-    'OCA\\DAV\\DAV\\GroupPrincipalBackend' => $baseDir . '/../lib/DAV/GroupPrincipalBackend.php',
161
-    'OCA\\DAV\\DAV\\PublicAuth' => $baseDir . '/../lib/DAV/PublicAuth.php',
162
-    'OCA\\DAV\\DAV\\Sharing\\Backend' => $baseDir . '/../lib/DAV/Sharing/Backend.php',
163
-    'OCA\\DAV\\DAV\\Sharing\\IShareable' => $baseDir . '/../lib/DAV/Sharing/IShareable.php',
164
-    'OCA\\DAV\\DAV\\Sharing\\Plugin' => $baseDir . '/../lib/DAV/Sharing/Plugin.php',
165
-    'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite' => $baseDir . '/../lib/DAV/Sharing/Xml/Invite.php',
166
-    'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest' => $baseDir . '/../lib/DAV/Sharing/Xml/ShareRequest.php',
167
-    'OCA\\DAV\\DAV\\SystemPrincipalBackend' => $baseDir . '/../lib/DAV/SystemPrincipalBackend.php',
168
-    'OCA\\DAV\\Db\\Direct' => $baseDir . '/../lib/Db/Direct.php',
169
-    'OCA\\DAV\\Db\\DirectMapper' => $baseDir . '/../lib/Db/DirectMapper.php',
170
-    'OCA\\DAV\\Direct\\DirectFile' => $baseDir . '/../lib/Direct/DirectFile.php',
171
-    'OCA\\DAV\\Direct\\DirectHome' => $baseDir . '/../lib/Direct/DirectHome.php',
172
-    'OCA\\DAV\\Direct\\Server' => $baseDir . '/../lib/Direct/Server.php',
173
-    'OCA\\DAV\\Direct\\ServerFactory' => $baseDir . '/../lib/Direct/ServerFactory.php',
174
-    'OCA\\DAV\\Events\\AddressBookCreatedEvent' => $baseDir . '/../lib/Events/AddressBookCreatedEvent.php',
175
-    'OCA\\DAV\\Events\\AddressBookDeletedEvent' => $baseDir . '/../lib/Events/AddressBookDeletedEvent.php',
176
-    'OCA\\DAV\\Events\\AddressBookShareUpdatedEvent' => $baseDir . '/../lib/Events/AddressBookShareUpdatedEvent.php',
177
-    'OCA\\DAV\\Events\\AddressBookUpdatedEvent' => $baseDir . '/../lib/Events/AddressBookUpdatedEvent.php',
178
-    'OCA\\DAV\\Events\\CachedCalendarObjectCreatedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectCreatedEvent.php',
179
-    'OCA\\DAV\\Events\\CachedCalendarObjectDeletedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectDeletedEvent.php',
180
-    'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
181
-    'OCA\\DAV\\Events\\CalendarCreatedEvent' => $baseDir . '/../lib/Events/CalendarCreatedEvent.php',
182
-    'OCA\\DAV\\Events\\CalendarDeletedEvent' => $baseDir . '/../lib/Events/CalendarDeletedEvent.php',
183
-    'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => $baseDir . '/../lib/Events/CalendarObjectCreatedEvent.php',
184
-    'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => $baseDir . '/../lib/Events/CalendarObjectDeletedEvent.php',
185
-    'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CalendarObjectUpdatedEvent.php',
186
-    'OCA\\DAV\\Events\\CalendarPublishedEvent' => $baseDir . '/../lib/Events/CalendarPublishedEvent.php',
187
-    'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => $baseDir . '/../lib/Events/CalendarShareUpdatedEvent.php',
188
-    'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => $baseDir . '/../lib/Events/CalendarUnpublishedEvent.php',
189
-    'OCA\\DAV\\Events\\CalendarUpdatedEvent' => $baseDir . '/../lib/Events/CalendarUpdatedEvent.php',
190
-    'OCA\\DAV\\Events\\CardCreatedEvent' => $baseDir . '/../lib/Events/CardCreatedEvent.php',
191
-    'OCA\\DAV\\Events\\CardDeletedEvent' => $baseDir . '/../lib/Events/CardDeletedEvent.php',
192
-    'OCA\\DAV\\Events\\CardUpdatedEvent' => $baseDir . '/../lib/Events/CardUpdatedEvent.php',
193
-    'OCA\\DAV\\Events\\SabrePluginAuthInitEvent' => $baseDir . '/../lib/Events/SabrePluginAuthInitEvent.php',
194
-    'OCA\\DAV\\Events\\SubscriptionCreatedEvent' => $baseDir . '/../lib/Events/SubscriptionCreatedEvent.php',
195
-    'OCA\\DAV\\Events\\SubscriptionDeletedEvent' => $baseDir . '/../lib/Events/SubscriptionDeletedEvent.php',
196
-    'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => $baseDir . '/../lib/Events/SubscriptionUpdatedEvent.php',
197
-    'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => $baseDir . '/../lib/Exception/UnsupportedLimitOnInitialSyncException.php',
198
-    'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => $baseDir . '/../lib/Files/BrowserErrorPagePlugin.php',
199
-    'OCA\\DAV\\Files\\FileSearchBackend' => $baseDir . '/../lib/Files/FileSearchBackend.php',
200
-    'OCA\\DAV\\Files\\FilesHome' => $baseDir . '/../lib/Files/FilesHome.php',
201
-    'OCA\\DAV\\Files\\LazySearchBackend' => $baseDir . '/../lib/Files/LazySearchBackend.php',
202
-    'OCA\\DAV\\Files\\RootCollection' => $baseDir . '/../lib/Files/RootCollection.php',
203
-    'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => $baseDir . '/../lib/Files/Sharing/FilesDropPlugin.php',
204
-    'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => $baseDir . '/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
205
-    'OCA\\DAV\\HookManager' => $baseDir . '/../lib/HookManager.php',
206
-    'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndex.php',
207
-    'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
208
-    'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => $baseDir . '/../lib/Migration/CalDAVRemoveEmptyValue.php',
209
-    'OCA\\DAV\\Migration\\ChunkCleanup' => $baseDir . '/../lib/Migration/ChunkCleanup.php',
210
-    'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => $baseDir . '/../lib/Migration/FixBirthdayCalendarComponent.php',
211
-    'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => $baseDir . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
212
-    'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => $baseDir . '/../lib/Migration/RegenerateBirthdayCalendars.php',
213
-    'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => $baseDir . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
214
-    'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => $baseDir . '/../lib/Migration/RemoveClassifiedEventActivity.php',
215
-    'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => $baseDir . '/../lib/Migration/RemoveOrphanEventsAndContacts.php',
216
-    'OCA\\DAV\\Migration\\Version1004Date20170825134824' => $baseDir . '/../lib/Migration/Version1004Date20170825134824.php',
217
-    'OCA\\DAV\\Migration\\Version1004Date20170919104507' => $baseDir . '/../lib/Migration/Version1004Date20170919104507.php',
218
-    'OCA\\DAV\\Migration\\Version1004Date20170924124212' => $baseDir . '/../lib/Migration/Version1004Date20170924124212.php',
219
-    'OCA\\DAV\\Migration\\Version1004Date20170926103422' => $baseDir . '/../lib/Migration/Version1004Date20170926103422.php',
220
-    'OCA\\DAV\\Migration\\Version1005Date20180413093149' => $baseDir . '/../lib/Migration/Version1005Date20180413093149.php',
221
-    'OCA\\DAV\\Migration\\Version1005Date20180530124431' => $baseDir . '/../lib/Migration/Version1005Date20180530124431.php',
222
-    'OCA\\DAV\\Migration\\Version1006Date20180619154313' => $baseDir . '/../lib/Migration/Version1006Date20180619154313.php',
223
-    'OCA\\DAV\\Migration\\Version1006Date20180628111625' => $baseDir . '/../lib/Migration/Version1006Date20180628111625.php',
224
-    'OCA\\DAV\\Migration\\Version1008Date20181030113700' => $baseDir . '/../lib/Migration/Version1008Date20181030113700.php',
225
-    'OCA\\DAV\\Migration\\Version1008Date20181105104826' => $baseDir . '/../lib/Migration/Version1008Date20181105104826.php',
226
-    'OCA\\DAV\\Migration\\Version1008Date20181105104833' => $baseDir . '/../lib/Migration/Version1008Date20181105104833.php',
227
-    'OCA\\DAV\\Migration\\Version1008Date20181105110300' => $baseDir . '/../lib/Migration/Version1008Date20181105110300.php',
228
-    'OCA\\DAV\\Migration\\Version1008Date20181105112049' => $baseDir . '/../lib/Migration/Version1008Date20181105112049.php',
229
-    'OCA\\DAV\\Migration\\Version1008Date20181114084440' => $baseDir . '/../lib/Migration/Version1008Date20181114084440.php',
230
-    'OCA\\DAV\\Migration\\Version1011Date20190725113607' => $baseDir . '/../lib/Migration/Version1011Date20190725113607.php',
231
-    'OCA\\DAV\\Migration\\Version1011Date20190806104428' => $baseDir . '/../lib/Migration/Version1011Date20190806104428.php',
232
-    'OCA\\DAV\\Migration\\Version1012Date20190808122342' => $baseDir . '/../lib/Migration/Version1012Date20190808122342.php',
233
-    'OCA\\DAV\\Migration\\Version1016Date20201109085907' => $baseDir . '/../lib/Migration/Version1016Date20201109085907.php',
234
-    'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
235
-    'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
236
-    'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
237
-    'OCA\\DAV\\Search\\ACalendarSearchProvider' => $baseDir . '/../lib/Search/ACalendarSearchProvider.php',
238
-    'OCA\\DAV\\Search\\ContactsSearchProvider' => $baseDir . '/../lib/Search/ContactsSearchProvider.php',
239
-    'OCA\\DAV\\Search\\EventsSearchProvider' => $baseDir . '/../lib/Search/EventsSearchProvider.php',
240
-    'OCA\\DAV\\Search\\TasksSearchProvider' => $baseDir . '/../lib/Search/TasksSearchProvider.php',
241
-    'OCA\\DAV\\Server' => $baseDir . '/../lib/Server.php',
242
-    'OCA\\DAV\\Settings\\CalDAVSettings' => $baseDir . '/../lib/Settings/CalDAVSettings.php',
243
-    'OCA\\DAV\\Storage\\PublicOwnerWrapper' => $baseDir . '/../lib/Storage/PublicOwnerWrapper.php',
244
-    'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => $baseDir . '/../lib/SystemTag/SystemTagMappingNode.php',
245
-    'OCA\\DAV\\SystemTag\\SystemTagNode' => $baseDir . '/../lib/SystemTag/SystemTagNode.php',
246
-    'OCA\\DAV\\SystemTag\\SystemTagPlugin' => $baseDir . '/../lib/SystemTag/SystemTagPlugin.php',
247
-    'OCA\\DAV\\SystemTag\\SystemTagsByIdCollection' => $baseDir . '/../lib/SystemTag/SystemTagsByIdCollection.php',
248
-    'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => $baseDir . '/../lib/SystemTag/SystemTagsObjectMappingCollection.php',
249
-    'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => $baseDir . '/../lib/SystemTag/SystemTagsObjectTypeCollection.php',
250
-    'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => $baseDir . '/../lib/SystemTag/SystemTagsRelationsCollection.php',
251
-    'OCA\\DAV\\Traits\\PrincipalProxyTrait' => $baseDir . '/../lib/Traits/PrincipalProxyTrait.php',
252
-    'OCA\\DAV\\Upload\\AssemblyStream' => $baseDir . '/../lib/Upload/AssemblyStream.php',
253
-    'OCA\\DAV\\Upload\\ChunkingPlugin' => $baseDir . '/../lib/Upload/ChunkingPlugin.php',
254
-    'OCA\\DAV\\Upload\\CleanupService' => $baseDir . '/../lib/Upload/CleanupService.php',
255
-    'OCA\\DAV\\Upload\\FutureFile' => $baseDir . '/../lib/Upload/FutureFile.php',
256
-    'OCA\\DAV\\Upload\\RootCollection' => $baseDir . '/../lib/Upload/RootCollection.php',
257
-    'OCA\\DAV\\Upload\\UploadFile' => $baseDir . '/../lib/Upload/UploadFile.php',
258
-    'OCA\\DAV\\Upload\\UploadFolder' => $baseDir . '/../lib/Upload/UploadFolder.php',
259
-    'OCA\\DAV\\Upload\\UploadHome' => $baseDir . '/../lib/Upload/UploadHome.php',
9
+    'OCA\\DAV\\AppInfo\\Application' => $baseDir.'/../lib/AppInfo/Application.php',
10
+    'OCA\\DAV\\AppInfo\\PluginManager' => $baseDir.'/../lib/AppInfo/PluginManager.php',
11
+    'OCA\\DAV\\Avatars\\AvatarHome' => $baseDir.'/../lib/Avatars/AvatarHome.php',
12
+    'OCA\\DAV\\Avatars\\AvatarNode' => $baseDir.'/../lib/Avatars/AvatarNode.php',
13
+    'OCA\\DAV\\Avatars\\RootCollection' => $baseDir.'/../lib/Avatars/RootCollection.php',
14
+    'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => $baseDir.'/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
15
+    'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => $baseDir.'/../lib/BackgroundJob/CleanupDirectLinksJob.php',
16
+    'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => $baseDir.'/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
17
+    'OCA\\DAV\\BackgroundJob\\EventReminderJob' => $baseDir.'/../lib/BackgroundJob/EventReminderJob.php',
18
+    'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => $baseDir.'/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
19
+    'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => $baseDir.'/../lib/BackgroundJob/RefreshWebcalJob.php',
20
+    'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => $baseDir.'/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
21
+    'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => $baseDir.'/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
22
+    'OCA\\DAV\\BackgroundJob\\UploadCleanup' => $baseDir.'/../lib/BackgroundJob/UploadCleanup.php',
23
+    'OCA\\DAV\\CalDAV\\Activity\\Backend' => $baseDir.'/../lib/CalDAV/Activity/Backend.php',
24
+    'OCA\\DAV\\CalDAV\\Activity\\Filter\\Calendar' => $baseDir.'/../lib/CalDAV/Activity/Filter/Calendar.php',
25
+    'OCA\\DAV\\CalDAV\\Activity\\Filter\\Todo' => $baseDir.'/../lib/CalDAV/Activity/Filter/Todo.php',
26
+    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Base' => $baseDir.'/../lib/CalDAV/Activity/Provider/Base.php',
27
+    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Calendar' => $baseDir.'/../lib/CalDAV/Activity/Provider/Calendar.php',
28
+    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Event' => $baseDir.'/../lib/CalDAV/Activity/Provider/Event.php',
29
+    'OCA\\DAV\\CalDAV\\Activity\\Provider\\Todo' => $baseDir.'/../lib/CalDAV/Activity/Provider/Todo.php',
30
+    'OCA\\DAV\\CalDAV\\Activity\\Setting\\CalDAVSetting' => $baseDir.'/../lib/CalDAV/Activity/Setting/CalDAVSetting.php',
31
+    'OCA\\DAV\\CalDAV\\Activity\\Setting\\Calendar' => $baseDir.'/../lib/CalDAV/Activity/Setting/Calendar.php',
32
+    'OCA\\DAV\\CalDAV\\Activity\\Setting\\Event' => $baseDir.'/../lib/CalDAV/Activity/Setting/Event.php',
33
+    'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => $baseDir.'/../lib/CalDAV/Activity/Setting/Todo.php',
34
+    'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => $baseDir.'/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
35
+    'OCA\\DAV\\CalDAV\\BirthdayService' => $baseDir.'/../lib/CalDAV/BirthdayService.php',
36
+    'OCA\\DAV\\CalDAV\\CachedSubscription' => $baseDir.'/../lib/CalDAV/CachedSubscription.php',
37
+    'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => $baseDir.'/../lib/CalDAV/CachedSubscriptionObject.php',
38
+    'OCA\\DAV\\CalDAV\\CalDavBackend' => $baseDir.'/../lib/CalDAV/CalDavBackend.php',
39
+    'OCA\\DAV\\CalDAV\\Calendar' => $baseDir.'/../lib/CalDAV/Calendar.php',
40
+    'OCA\\DAV\\CalDAV\\CalendarHome' => $baseDir.'/../lib/CalDAV/CalendarHome.php',
41
+    'OCA\\DAV\\CalDAV\\CalendarImpl' => $baseDir.'/../lib/CalDAV/CalendarImpl.php',
42
+    'OCA\\DAV\\CalDAV\\CalendarManager' => $baseDir.'/../lib/CalDAV/CalendarManager.php',
43
+    'OCA\\DAV\\CalDAV\\CalendarObject' => $baseDir.'/../lib/CalDAV/CalendarObject.php',
44
+    'OCA\\DAV\\CalDAV\\CalendarRoot' => $baseDir.'/../lib/CalDAV/CalendarRoot.php',
45
+    'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => $baseDir.'/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
46
+    'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => $baseDir.'/../lib/CalDAV/Integration/ExternalCalendar.php',
47
+    'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => $baseDir.'/../lib/CalDAV/Integration/ICalendarProvider.php',
48
+    'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => $baseDir.'/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
49
+    'OCA\\DAV\\CalDAV\\Outbox' => $baseDir.'/../lib/CalDAV/Outbox.php',
50
+    'OCA\\DAV\\CalDAV\\Plugin' => $baseDir.'/../lib/CalDAV/Plugin.php',
51
+    'OCA\\DAV\\CalDAV\\Principal\\Collection' => $baseDir.'/../lib/CalDAV/Principal/Collection.php',
52
+    'OCA\\DAV\\CalDAV\\Principal\\User' => $baseDir.'/../lib/CalDAV/Principal/User.php',
53
+    'OCA\\DAV\\CalDAV\\Proxy\\Proxy' => $baseDir.'/../lib/CalDAV/Proxy/Proxy.php',
54
+    'OCA\\DAV\\CalDAV\\Proxy\\ProxyMapper' => $baseDir.'/../lib/CalDAV/Proxy/ProxyMapper.php',
55
+    'OCA\\DAV\\CalDAV\\PublicCalendar' => $baseDir.'/../lib/CalDAV/PublicCalendar.php',
56
+    'OCA\\DAV\\CalDAV\\PublicCalendarObject' => $baseDir.'/../lib/CalDAV/PublicCalendarObject.php',
57
+    'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => $baseDir.'/../lib/CalDAV/PublicCalendarRoot.php',
58
+    'OCA\\DAV\\CalDAV\\Publishing\\PublishPlugin' => $baseDir.'/../lib/CalDAV/Publishing/PublishPlugin.php',
59
+    'OCA\\DAV\\CalDAV\\Publishing\\Xml\\Publisher' => $baseDir.'/../lib/CalDAV/Publishing/Xml/Publisher.php',
60
+    'OCA\\DAV\\CalDAV\\Reminder\\Backend' => $baseDir.'/../lib/CalDAV/Reminder/Backend.php',
61
+    'OCA\\DAV\\CalDAV\\Reminder\\INotificationProvider' => $baseDir.'/../lib/CalDAV/Reminder/INotificationProvider.php',
62
+    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProviderManager' => $baseDir.'/../lib/CalDAV/Reminder/NotificationProviderManager.php',
63
+    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AbstractProvider' => $baseDir.'/../lib/CalDAV/Reminder/NotificationProvider/AbstractProvider.php',
64
+    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AudioProvider' => $baseDir.'/../lib/CalDAV/Reminder/NotificationProvider/AudioProvider.php',
65
+    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\EmailProvider' => $baseDir.'/../lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php',
66
+    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\ProviderNotAvailableException' => $baseDir.'/../lib/CalDAV/Reminder/NotificationProvider/ProviderNotAvailableException.php',
67
+    'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\PushProvider' => $baseDir.'/../lib/CalDAV/Reminder/NotificationProvider/PushProvider.php',
68
+    'OCA\\DAV\\CalDAV\\Reminder\\NotificationTypeDoesNotExistException' => $baseDir.'/../lib/CalDAV/Reminder/NotificationTypeDoesNotExistException.php',
69
+    'OCA\\DAV\\CalDAV\\Reminder\\Notifier' => $baseDir.'/../lib/CalDAV/Reminder/Notifier.php',
70
+    'OCA\\DAV\\CalDAV\\Reminder\\ReminderService' => $baseDir.'/../lib/CalDAV/Reminder/ReminderService.php',
71
+    'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => $baseDir.'/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
72
+    'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => $baseDir.'/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
73
+    'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => $baseDir.'/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
74
+    'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => $baseDir.'/../lib/CalDAV/Schedule/IMipPlugin.php',
75
+    'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => $baseDir.'/../lib/CalDAV/Schedule/Plugin.php',
76
+    'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => $baseDir.'/../lib/CalDAV/Search/SearchPlugin.php',
77
+    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter' => $baseDir.'/../lib/CalDAV/Search/Xml/Filter/CompFilter.php',
78
+    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter' => $baseDir.'/../lib/CalDAV/Search/Xml/Filter/LimitFilter.php',
79
+    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter' => $baseDir.'/../lib/CalDAV/Search/Xml/Filter/OffsetFilter.php',
80
+    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter' => $baseDir.'/../lib/CalDAV/Search/Xml/Filter/ParamFilter.php',
81
+    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => $baseDir.'/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
82
+    'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => $baseDir.'/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
83
+    'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => $baseDir.'/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
84
+    'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => $baseDir.'/../lib/CalDAV/WebcalCaching/Plugin.php',
85
+    'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => $baseDir.'/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
86
+    'OCA\\DAV\\Capabilities' => $baseDir.'/../lib/Capabilities.php',
87
+    'OCA\\DAV\\CardDAV\\AddressBook' => $baseDir.'/../lib/CardDAV/AddressBook.php',
88
+    'OCA\\DAV\\CardDAV\\AddressBookImpl' => $baseDir.'/../lib/CardDAV/AddressBookImpl.php',
89
+    'OCA\\DAV\\CardDAV\\AddressBookRoot' => $baseDir.'/../lib/CardDAV/AddressBookRoot.php',
90
+    'OCA\\DAV\\CardDAV\\CardDavBackend' => $baseDir.'/../lib/CardDAV/CardDavBackend.php',
91
+    'OCA\\DAV\\CardDAV\\ContactsManager' => $baseDir.'/../lib/CardDAV/ContactsManager.php',
92
+    'OCA\\DAV\\CardDAV\\Converter' => $baseDir.'/../lib/CardDAV/Converter.php',
93
+    'OCA\\DAV\\CardDAV\\HasPhotoPlugin' => $baseDir.'/../lib/CardDAV/HasPhotoPlugin.php',
94
+    'OCA\\DAV\\CardDAV\\ImageExportPlugin' => $baseDir.'/../lib/CardDAV/ImageExportPlugin.php',
95
+    'OCA\\DAV\\CardDAV\\Integration\\ExternalAddressBook' => $baseDir.'/../lib/CardDAV/Integration/ExternalAddressBook.php',
96
+    'OCA\\DAV\\CardDAV\\Integration\\IAddressBookProvider' => $baseDir.'/../lib/CardDAV/Integration/IAddressBookProvider.php',
97
+    'OCA\\DAV\\CardDAV\\MultiGetExportPlugin' => $baseDir.'/../lib/CardDAV/MultiGetExportPlugin.php',
98
+    'OCA\\DAV\\CardDAV\\PhotoCache' => $baseDir.'/../lib/CardDAV/PhotoCache.php',
99
+    'OCA\\DAV\\CardDAV\\Plugin' => $baseDir.'/../lib/CardDAV/Plugin.php',
100
+    'OCA\\DAV\\CardDAV\\SyncService' => $baseDir.'/../lib/CardDAV/SyncService.php',
101
+    'OCA\\DAV\\CardDAV\\SystemAddressbook' => $baseDir.'/../lib/CardDAV/SystemAddressbook.php',
102
+    'OCA\\DAV\\CardDAV\\UserAddressBooks' => $baseDir.'/../lib/CardDAV/UserAddressBooks.php',
103
+    'OCA\\DAV\\CardDAV\\Xml\\Groups' => $baseDir.'/../lib/CardDAV/Xml/Groups.php',
104
+    'OCA\\DAV\\Command\\CreateAddressBook' => $baseDir.'/../lib/Command/CreateAddressBook.php',
105
+    'OCA\\DAV\\Command\\CreateCalendar' => $baseDir.'/../lib/Command/CreateCalendar.php',
106
+    'OCA\\DAV\\Command\\ListCalendars' => $baseDir.'/../lib/Command/ListCalendars.php',
107
+    'OCA\\DAV\\Command\\MoveCalendar' => $baseDir.'/../lib/Command/MoveCalendar.php',
108
+    'OCA\\DAV\\Command\\RemoveInvalidShares' => $baseDir.'/../lib/Command/RemoveInvalidShares.php',
109
+    'OCA\\DAV\\Command\\SendEventReminders' => $baseDir.'/../lib/Command/SendEventReminders.php',
110
+    'OCA\\DAV\\Command\\SyncBirthdayCalendar' => $baseDir.'/../lib/Command/SyncBirthdayCalendar.php',
111
+    'OCA\\DAV\\Command\\SyncSystemAddressBook' => $baseDir.'/../lib/Command/SyncSystemAddressBook.php',
112
+    'OCA\\DAV\\Comments\\CommentNode' => $baseDir.'/../lib/Comments/CommentNode.php',
113
+    'OCA\\DAV\\Comments\\CommentsPlugin' => $baseDir.'/../lib/Comments/CommentsPlugin.php',
114
+    'OCA\\DAV\\Comments\\EntityCollection' => $baseDir.'/../lib/Comments/EntityCollection.php',
115
+    'OCA\\DAV\\Comments\\EntityTypeCollection' => $baseDir.'/../lib/Comments/EntityTypeCollection.php',
116
+    'OCA\\DAV\\Comments\\RootCollection' => $baseDir.'/../lib/Comments/RootCollection.php',
117
+    'OCA\\DAV\\Connector\\LegacyDAVACL' => $baseDir.'/../lib/Connector/LegacyDAVACL.php',
118
+    'OCA\\DAV\\Connector\\PublicAuth' => $baseDir.'/../lib/Connector/PublicAuth.php',
119
+    'OCA\\DAV\\Connector\\Sabre\\AnonymousOptionsPlugin' => $baseDir.'/../lib/Connector/Sabre/AnonymousOptionsPlugin.php',
120
+    'OCA\\DAV\\Connector\\Sabre\\AppEnabledPlugin' => $baseDir.'/../lib/Connector/Sabre/AppEnabledPlugin.php',
121
+    'OCA\\DAV\\Connector\\Sabre\\Auth' => $baseDir.'/../lib/Connector/Sabre/Auth.php',
122
+    'OCA\\DAV\\Connector\\Sabre\\BearerAuth' => $baseDir.'/../lib/Connector/Sabre/BearerAuth.php',
123
+    'OCA\\DAV\\Connector\\Sabre\\BlockLegacyClientPlugin' => $baseDir.'/../lib/Connector/Sabre/BlockLegacyClientPlugin.php',
124
+    'OCA\\DAV\\Connector\\Sabre\\CachingTree' => $baseDir.'/../lib/Connector/Sabre/CachingTree.php',
125
+    'OCA\\DAV\\Connector\\Sabre\\ChecksumList' => $baseDir.'/../lib/Connector/Sabre/ChecksumList.php',
126
+    'OCA\\DAV\\Connector\\Sabre\\CommentPropertiesPlugin' => $baseDir.'/../lib/Connector/Sabre/CommentPropertiesPlugin.php',
127
+    'OCA\\DAV\\Connector\\Sabre\\CopyEtagHeaderPlugin' => $baseDir.'/../lib/Connector/Sabre/CopyEtagHeaderPlugin.php',
128
+    'OCA\\DAV\\Connector\\Sabre\\DavAclPlugin' => $baseDir.'/../lib/Connector/Sabre/DavAclPlugin.php',
129
+    'OCA\\DAV\\Connector\\Sabre\\Directory' => $baseDir.'/../lib/Connector/Sabre/Directory.php',
130
+    'OCA\\DAV\\Connector\\Sabre\\DummyGetResponsePlugin' => $baseDir.'/../lib/Connector/Sabre/DummyGetResponsePlugin.php',
131
+    'OCA\\DAV\\Connector\\Sabre\\ExceptionLoggerPlugin' => $baseDir.'/../lib/Connector/Sabre/ExceptionLoggerPlugin.php',
132
+    'OCA\\DAV\\Connector\\Sabre\\Exception\\EntityTooLarge' => $baseDir.'/../lib/Connector/Sabre/Exception/EntityTooLarge.php',
133
+    'OCA\\DAV\\Connector\\Sabre\\Exception\\FileLocked' => $baseDir.'/../lib/Connector/Sabre/Exception/FileLocked.php',
134
+    'OCA\\DAV\\Connector\\Sabre\\Exception\\Forbidden' => $baseDir.'/../lib/Connector/Sabre/Exception/Forbidden.php',
135
+    'OCA\\DAV\\Connector\\Sabre\\Exception\\InvalidPath' => $baseDir.'/../lib/Connector/Sabre/Exception/InvalidPath.php',
136
+    'OCA\\DAV\\Connector\\Sabre\\Exception\\PasswordLoginForbidden' => $baseDir.'/../lib/Connector/Sabre/Exception/PasswordLoginForbidden.php',
137
+    'OCA\\DAV\\Connector\\Sabre\\Exception\\UnsupportedMediaType' => $baseDir.'/../lib/Connector/Sabre/Exception/UnsupportedMediaType.php',
138
+    'OCA\\DAV\\Connector\\Sabre\\FakeLockerPlugin' => $baseDir.'/../lib/Connector/Sabre/FakeLockerPlugin.php',
139
+    'OCA\\DAV\\Connector\\Sabre\\File' => $baseDir.'/../lib/Connector/Sabre/File.php',
140
+    'OCA\\DAV\\Connector\\Sabre\\FilesPlugin' => $baseDir.'/../lib/Connector/Sabre/FilesPlugin.php',
141
+    'OCA\\DAV\\Connector\\Sabre\\FilesReportPlugin' => $baseDir.'/../lib/Connector/Sabre/FilesReportPlugin.php',
142
+    'OCA\\DAV\\Connector\\Sabre\\LockPlugin' => $baseDir.'/../lib/Connector/Sabre/LockPlugin.php',
143
+    'OCA\\DAV\\Connector\\Sabre\\MaintenancePlugin' => $baseDir.'/../lib/Connector/Sabre/MaintenancePlugin.php',
144
+    'OCA\\DAV\\Connector\\Sabre\\Node' => $baseDir.'/../lib/Connector/Sabre/Node.php',
145
+    'OCA\\DAV\\Connector\\Sabre\\ObjectTree' => $baseDir.'/../lib/Connector/Sabre/ObjectTree.php',
146
+    'OCA\\DAV\\Connector\\Sabre\\Principal' => $baseDir.'/../lib/Connector/Sabre/Principal.php',
147
+    'OCA\\DAV\\Connector\\Sabre\\PropfindCompressionPlugin' => $baseDir.'/../lib/Connector/Sabre/PropfindCompressionPlugin.php',
148
+    'OCA\\DAV\\Connector\\Sabre\\QuotaPlugin' => $baseDir.'/../lib/Connector/Sabre/QuotaPlugin.php',
149
+    'OCA\\DAV\\Connector\\Sabre\\Server' => $baseDir.'/../lib/Connector/Sabre/Server.php',
150
+    'OCA\\DAV\\Connector\\Sabre\\ServerFactory' => $baseDir.'/../lib/Connector/Sabre/ServerFactory.php',
151
+    'OCA\\DAV\\Connector\\Sabre\\ShareTypeList' => $baseDir.'/../lib/Connector/Sabre/ShareTypeList.php',
152
+    'OCA\\DAV\\Connector\\Sabre\\ShareeList' => $baseDir.'/../lib/Connector/Sabre/ShareeList.php',
153
+    'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => $baseDir.'/../lib/Connector/Sabre/SharesPlugin.php',
154
+    'OCA\\DAV\\Connector\\Sabre\\TagList' => $baseDir.'/../lib/Connector/Sabre/TagList.php',
155
+    'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => $baseDir.'/../lib/Connector/Sabre/TagsPlugin.php',
156
+    'OCA\\DAV\\Controller\\BirthdayCalendarController' => $baseDir.'/../lib/Controller/BirthdayCalendarController.php',
157
+    'OCA\\DAV\\Controller\\DirectController' => $baseDir.'/../lib/Controller/DirectController.php',
158
+    'OCA\\DAV\\Controller\\InvitationResponseController' => $baseDir.'/../lib/Controller/InvitationResponseController.php',
159
+    'OCA\\DAV\\DAV\\CustomPropertiesBackend' => $baseDir.'/../lib/DAV/CustomPropertiesBackend.php',
160
+    'OCA\\DAV\\DAV\\GroupPrincipalBackend' => $baseDir.'/../lib/DAV/GroupPrincipalBackend.php',
161
+    'OCA\\DAV\\DAV\\PublicAuth' => $baseDir.'/../lib/DAV/PublicAuth.php',
162
+    'OCA\\DAV\\DAV\\Sharing\\Backend' => $baseDir.'/../lib/DAV/Sharing/Backend.php',
163
+    'OCA\\DAV\\DAV\\Sharing\\IShareable' => $baseDir.'/../lib/DAV/Sharing/IShareable.php',
164
+    'OCA\\DAV\\DAV\\Sharing\\Plugin' => $baseDir.'/../lib/DAV/Sharing/Plugin.php',
165
+    'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite' => $baseDir.'/../lib/DAV/Sharing/Xml/Invite.php',
166
+    'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest' => $baseDir.'/../lib/DAV/Sharing/Xml/ShareRequest.php',
167
+    'OCA\\DAV\\DAV\\SystemPrincipalBackend' => $baseDir.'/../lib/DAV/SystemPrincipalBackend.php',
168
+    'OCA\\DAV\\Db\\Direct' => $baseDir.'/../lib/Db/Direct.php',
169
+    'OCA\\DAV\\Db\\DirectMapper' => $baseDir.'/../lib/Db/DirectMapper.php',
170
+    'OCA\\DAV\\Direct\\DirectFile' => $baseDir.'/../lib/Direct/DirectFile.php',
171
+    'OCA\\DAV\\Direct\\DirectHome' => $baseDir.'/../lib/Direct/DirectHome.php',
172
+    'OCA\\DAV\\Direct\\Server' => $baseDir.'/../lib/Direct/Server.php',
173
+    'OCA\\DAV\\Direct\\ServerFactory' => $baseDir.'/../lib/Direct/ServerFactory.php',
174
+    'OCA\\DAV\\Events\\AddressBookCreatedEvent' => $baseDir.'/../lib/Events/AddressBookCreatedEvent.php',
175
+    'OCA\\DAV\\Events\\AddressBookDeletedEvent' => $baseDir.'/../lib/Events/AddressBookDeletedEvent.php',
176
+    'OCA\\DAV\\Events\\AddressBookShareUpdatedEvent' => $baseDir.'/../lib/Events/AddressBookShareUpdatedEvent.php',
177
+    'OCA\\DAV\\Events\\AddressBookUpdatedEvent' => $baseDir.'/../lib/Events/AddressBookUpdatedEvent.php',
178
+    'OCA\\DAV\\Events\\CachedCalendarObjectCreatedEvent' => $baseDir.'/../lib/Events/CachedCalendarObjectCreatedEvent.php',
179
+    'OCA\\DAV\\Events\\CachedCalendarObjectDeletedEvent' => $baseDir.'/../lib/Events/CachedCalendarObjectDeletedEvent.php',
180
+    'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => $baseDir.'/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
181
+    'OCA\\DAV\\Events\\CalendarCreatedEvent' => $baseDir.'/../lib/Events/CalendarCreatedEvent.php',
182
+    'OCA\\DAV\\Events\\CalendarDeletedEvent' => $baseDir.'/../lib/Events/CalendarDeletedEvent.php',
183
+    'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => $baseDir.'/../lib/Events/CalendarObjectCreatedEvent.php',
184
+    'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => $baseDir.'/../lib/Events/CalendarObjectDeletedEvent.php',
185
+    'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => $baseDir.'/../lib/Events/CalendarObjectUpdatedEvent.php',
186
+    'OCA\\DAV\\Events\\CalendarPublishedEvent' => $baseDir.'/../lib/Events/CalendarPublishedEvent.php',
187
+    'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => $baseDir.'/../lib/Events/CalendarShareUpdatedEvent.php',
188
+    'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => $baseDir.'/../lib/Events/CalendarUnpublishedEvent.php',
189
+    'OCA\\DAV\\Events\\CalendarUpdatedEvent' => $baseDir.'/../lib/Events/CalendarUpdatedEvent.php',
190
+    'OCA\\DAV\\Events\\CardCreatedEvent' => $baseDir.'/../lib/Events/CardCreatedEvent.php',
191
+    'OCA\\DAV\\Events\\CardDeletedEvent' => $baseDir.'/../lib/Events/CardDeletedEvent.php',
192
+    'OCA\\DAV\\Events\\CardUpdatedEvent' => $baseDir.'/../lib/Events/CardUpdatedEvent.php',
193
+    'OCA\\DAV\\Events\\SabrePluginAuthInitEvent' => $baseDir.'/../lib/Events/SabrePluginAuthInitEvent.php',
194
+    'OCA\\DAV\\Events\\SubscriptionCreatedEvent' => $baseDir.'/../lib/Events/SubscriptionCreatedEvent.php',
195
+    'OCA\\DAV\\Events\\SubscriptionDeletedEvent' => $baseDir.'/../lib/Events/SubscriptionDeletedEvent.php',
196
+    'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => $baseDir.'/../lib/Events/SubscriptionUpdatedEvent.php',
197
+    'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => $baseDir.'/../lib/Exception/UnsupportedLimitOnInitialSyncException.php',
198
+    'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => $baseDir.'/../lib/Files/BrowserErrorPagePlugin.php',
199
+    'OCA\\DAV\\Files\\FileSearchBackend' => $baseDir.'/../lib/Files/FileSearchBackend.php',
200
+    'OCA\\DAV\\Files\\FilesHome' => $baseDir.'/../lib/Files/FilesHome.php',
201
+    'OCA\\DAV\\Files\\LazySearchBackend' => $baseDir.'/../lib/Files/LazySearchBackend.php',
202
+    'OCA\\DAV\\Files\\RootCollection' => $baseDir.'/../lib/Files/RootCollection.php',
203
+    'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => $baseDir.'/../lib/Files/Sharing/FilesDropPlugin.php',
204
+    'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => $baseDir.'/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
205
+    'OCA\\DAV\\HookManager' => $baseDir.'/../lib/HookManager.php',
206
+    'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir.'/../lib/Migration/BuildCalendarSearchIndex.php',
207
+    'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir.'/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
208
+    'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => $baseDir.'/../lib/Migration/CalDAVRemoveEmptyValue.php',
209
+    'OCA\\DAV\\Migration\\ChunkCleanup' => $baseDir.'/../lib/Migration/ChunkCleanup.php',
210
+    'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => $baseDir.'/../lib/Migration/FixBirthdayCalendarComponent.php',
211
+    'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => $baseDir.'/../lib/Migration/RefreshWebcalJobRegistrar.php',
212
+    'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => $baseDir.'/../lib/Migration/RegenerateBirthdayCalendars.php',
213
+    'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => $baseDir.'/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
214
+    'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => $baseDir.'/../lib/Migration/RemoveClassifiedEventActivity.php',
215
+    'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => $baseDir.'/../lib/Migration/RemoveOrphanEventsAndContacts.php',
216
+    'OCA\\DAV\\Migration\\Version1004Date20170825134824' => $baseDir.'/../lib/Migration/Version1004Date20170825134824.php',
217
+    'OCA\\DAV\\Migration\\Version1004Date20170919104507' => $baseDir.'/../lib/Migration/Version1004Date20170919104507.php',
218
+    'OCA\\DAV\\Migration\\Version1004Date20170924124212' => $baseDir.'/../lib/Migration/Version1004Date20170924124212.php',
219
+    'OCA\\DAV\\Migration\\Version1004Date20170926103422' => $baseDir.'/../lib/Migration/Version1004Date20170926103422.php',
220
+    'OCA\\DAV\\Migration\\Version1005Date20180413093149' => $baseDir.'/../lib/Migration/Version1005Date20180413093149.php',
221
+    'OCA\\DAV\\Migration\\Version1005Date20180530124431' => $baseDir.'/../lib/Migration/Version1005Date20180530124431.php',
222
+    'OCA\\DAV\\Migration\\Version1006Date20180619154313' => $baseDir.'/../lib/Migration/Version1006Date20180619154313.php',
223
+    'OCA\\DAV\\Migration\\Version1006Date20180628111625' => $baseDir.'/../lib/Migration/Version1006Date20180628111625.php',
224
+    'OCA\\DAV\\Migration\\Version1008Date20181030113700' => $baseDir.'/../lib/Migration/Version1008Date20181030113700.php',
225
+    'OCA\\DAV\\Migration\\Version1008Date20181105104826' => $baseDir.'/../lib/Migration/Version1008Date20181105104826.php',
226
+    'OCA\\DAV\\Migration\\Version1008Date20181105104833' => $baseDir.'/../lib/Migration/Version1008Date20181105104833.php',
227
+    'OCA\\DAV\\Migration\\Version1008Date20181105110300' => $baseDir.'/../lib/Migration/Version1008Date20181105110300.php',
228
+    'OCA\\DAV\\Migration\\Version1008Date20181105112049' => $baseDir.'/../lib/Migration/Version1008Date20181105112049.php',
229
+    'OCA\\DAV\\Migration\\Version1008Date20181114084440' => $baseDir.'/../lib/Migration/Version1008Date20181114084440.php',
230
+    'OCA\\DAV\\Migration\\Version1011Date20190725113607' => $baseDir.'/../lib/Migration/Version1011Date20190725113607.php',
231
+    'OCA\\DAV\\Migration\\Version1011Date20190806104428' => $baseDir.'/../lib/Migration/Version1011Date20190806104428.php',
232
+    'OCA\\DAV\\Migration\\Version1012Date20190808122342' => $baseDir.'/../lib/Migration/Version1012Date20190808122342.php',
233
+    'OCA\\DAV\\Migration\\Version1016Date20201109085907' => $baseDir.'/../lib/Migration/Version1016Date20201109085907.php',
234
+    'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir.'/../lib/Provisioning/Apple/AppleProvisioningNode.php',
235
+    'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir.'/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
236
+    'OCA\\DAV\\RootCollection' => $baseDir.'/../lib/RootCollection.php',
237
+    'OCA\\DAV\\Search\\ACalendarSearchProvider' => $baseDir.'/../lib/Search/ACalendarSearchProvider.php',
238
+    'OCA\\DAV\\Search\\ContactsSearchProvider' => $baseDir.'/../lib/Search/ContactsSearchProvider.php',
239
+    'OCA\\DAV\\Search\\EventsSearchProvider' => $baseDir.'/../lib/Search/EventsSearchProvider.php',
240
+    'OCA\\DAV\\Search\\TasksSearchProvider' => $baseDir.'/../lib/Search/TasksSearchProvider.php',
241
+    'OCA\\DAV\\Server' => $baseDir.'/../lib/Server.php',
242
+    'OCA\\DAV\\Settings\\CalDAVSettings' => $baseDir.'/../lib/Settings/CalDAVSettings.php',
243
+    'OCA\\DAV\\Storage\\PublicOwnerWrapper' => $baseDir.'/../lib/Storage/PublicOwnerWrapper.php',
244
+    'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => $baseDir.'/../lib/SystemTag/SystemTagMappingNode.php',
245
+    'OCA\\DAV\\SystemTag\\SystemTagNode' => $baseDir.'/../lib/SystemTag/SystemTagNode.php',
246
+    'OCA\\DAV\\SystemTag\\SystemTagPlugin' => $baseDir.'/../lib/SystemTag/SystemTagPlugin.php',
247
+    'OCA\\DAV\\SystemTag\\SystemTagsByIdCollection' => $baseDir.'/../lib/SystemTag/SystemTagsByIdCollection.php',
248
+    'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => $baseDir.'/../lib/SystemTag/SystemTagsObjectMappingCollection.php',
249
+    'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => $baseDir.'/../lib/SystemTag/SystemTagsObjectTypeCollection.php',
250
+    'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => $baseDir.'/../lib/SystemTag/SystemTagsRelationsCollection.php',
251
+    'OCA\\DAV\\Traits\\PrincipalProxyTrait' => $baseDir.'/../lib/Traits/PrincipalProxyTrait.php',
252
+    'OCA\\DAV\\Upload\\AssemblyStream' => $baseDir.'/../lib/Upload/AssemblyStream.php',
253
+    'OCA\\DAV\\Upload\\ChunkingPlugin' => $baseDir.'/../lib/Upload/ChunkingPlugin.php',
254
+    'OCA\\DAV\\Upload\\CleanupService' => $baseDir.'/../lib/Upload/CleanupService.php',
255
+    'OCA\\DAV\\Upload\\FutureFile' => $baseDir.'/../lib/Upload/FutureFile.php',
256
+    'OCA\\DAV\\Upload\\RootCollection' => $baseDir.'/../lib/Upload/RootCollection.php',
257
+    'OCA\\DAV\\Upload\\UploadFile' => $baseDir.'/../lib/Upload/UploadFile.php',
258
+    'OCA\\DAV\\Upload\\UploadFolder' => $baseDir.'/../lib/Upload/UploadFolder.php',
259
+    'OCA\\DAV\\Upload\\UploadHome' => $baseDir.'/../lib/Upload/UploadHome.php',
260 260
 );
Please login to merge, or discard this patch.
apps/dav/composer/composer/autoload_static.php 1 patch
Spacing   +258 added lines, -258 removed lines patch added patch discarded remove patch
@@ -6,277 +6,277 @@
 block discarded – undo
6 6
 
7 7
 class ComposerStaticInitDAV
8 8
 {
9
-    public static $prefixLengthsPsr4 = array (
9
+    public static $prefixLengthsPsr4 = array(
10 10
         'O' => 
11
-        array (
11
+        array(
12 12
             'OCA\\DAV\\' => 8,
13 13
         ),
14 14
     );
15 15
 
16
-    public static $prefixDirsPsr4 = array (
16
+    public static $prefixDirsPsr4 = array(
17 17
         'OCA\\DAV\\' => 
18
-        array (
19
-            0 => __DIR__ . '/..' . '/../lib',
18
+        array(
19
+            0 => __DIR__.'/..'.'/../lib',
20 20
         ),
21 21
     );
22 22
 
23
-    public static $classMap = array (
24
-        'OCA\\DAV\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
25
-        'OCA\\DAV\\AppInfo\\PluginManager' => __DIR__ . '/..' . '/../lib/AppInfo/PluginManager.php',
26
-        'OCA\\DAV\\Avatars\\AvatarHome' => __DIR__ . '/..' . '/../lib/Avatars/AvatarHome.php',
27
-        'OCA\\DAV\\Avatars\\AvatarNode' => __DIR__ . '/..' . '/../lib/Avatars/AvatarNode.php',
28
-        'OCA\\DAV\\Avatars\\RootCollection' => __DIR__ . '/..' . '/../lib/Avatars/RootCollection.php',
29
-        'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
30
-        'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
31
-        'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
32
-        'OCA\\DAV\\BackgroundJob\\EventReminderJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/EventReminderJob.php',
33
-        'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
34
-        'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/RefreshWebcalJob.php',
35
-        'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
36
-        'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
37
-        'OCA\\DAV\\BackgroundJob\\UploadCleanup' => __DIR__ . '/..' . '/../lib/BackgroundJob/UploadCleanup.php',
38
-        'OCA\\DAV\\CalDAV\\Activity\\Backend' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Backend.php',
39
-        'OCA\\DAV\\CalDAV\\Activity\\Filter\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Filter/Calendar.php',
40
-        'OCA\\DAV\\CalDAV\\Activity\\Filter\\Todo' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Filter/Todo.php',
41
-        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Base' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Provider/Base.php',
42
-        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Provider/Calendar.php',
43
-        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Event' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Provider/Event.php',
44
-        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Todo' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Provider/Todo.php',
45
-        'OCA\\DAV\\CalDAV\\Activity\\Setting\\CalDAVSetting' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/CalDAVSetting.php',
46
-        'OCA\\DAV\\CalDAV\\Activity\\Setting\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/Calendar.php',
47
-        'OCA\\DAV\\CalDAV\\Activity\\Setting\\Event' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/Event.php',
48
-        'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/Todo.php',
49
-        'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
50
-        'OCA\\DAV\\CalDAV\\BirthdayService' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayService.php',
51
-        'OCA\\DAV\\CalDAV\\CachedSubscription' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscription.php',
52
-        'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionObject.php',
53
-        'OCA\\DAV\\CalDAV\\CalDavBackend' => __DIR__ . '/..' . '/../lib/CalDAV/CalDavBackend.php',
54
-        'OCA\\DAV\\CalDAV\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Calendar.php',
55
-        'OCA\\DAV\\CalDAV\\CalendarHome' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarHome.php',
56
-        'OCA\\DAV\\CalDAV\\CalendarImpl' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarImpl.php',
57
-        'OCA\\DAV\\CalDAV\\CalendarManager' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarManager.php',
58
-        'OCA\\DAV\\CalDAV\\CalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarObject.php',
59
-        'OCA\\DAV\\CalDAV\\CalendarRoot' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarRoot.php',
60
-        'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
61
-        'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => __DIR__ . '/..' . '/../lib/CalDAV/Integration/ExternalCalendar.php',
62
-        'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Integration/ICalendarProvider.php',
63
-        'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => __DIR__ . '/..' . '/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
64
-        'OCA\\DAV\\CalDAV\\Outbox' => __DIR__ . '/..' . '/../lib/CalDAV/Outbox.php',
65
-        'OCA\\DAV\\CalDAV\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/Plugin.php',
66
-        'OCA\\DAV\\CalDAV\\Principal\\Collection' => __DIR__ . '/..' . '/../lib/CalDAV/Principal/Collection.php',
67
-        'OCA\\DAV\\CalDAV\\Principal\\User' => __DIR__ . '/..' . '/../lib/CalDAV/Principal/User.php',
68
-        'OCA\\DAV\\CalDAV\\Proxy\\Proxy' => __DIR__ . '/..' . '/../lib/CalDAV/Proxy/Proxy.php',
69
-        'OCA\\DAV\\CalDAV\\Proxy\\ProxyMapper' => __DIR__ . '/..' . '/../lib/CalDAV/Proxy/ProxyMapper.php',
70
-        'OCA\\DAV\\CalDAV\\PublicCalendar' => __DIR__ . '/..' . '/../lib/CalDAV/PublicCalendar.php',
71
-        'OCA\\DAV\\CalDAV\\PublicCalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/PublicCalendarObject.php',
72
-        'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => __DIR__ . '/..' . '/../lib/CalDAV/PublicCalendarRoot.php',
73
-        'OCA\\DAV\\CalDAV\\Publishing\\PublishPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Publishing/PublishPlugin.php',
74
-        'OCA\\DAV\\CalDAV\\Publishing\\Xml\\Publisher' => __DIR__ . '/..' . '/../lib/CalDAV/Publishing/Xml/Publisher.php',
75
-        'OCA\\DAV\\CalDAV\\Reminder\\Backend' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/Backend.php',
76
-        'OCA\\DAV\\CalDAV\\Reminder\\INotificationProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/INotificationProvider.php',
77
-        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProviderManager' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationProviderManager.php',
78
-        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AbstractProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationProvider/AbstractProvider.php',
79
-        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AudioProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationProvider/AudioProvider.php',
80
-        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\EmailProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php',
81
-        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\ProviderNotAvailableException' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationProvider/ProviderNotAvailableException.php',
82
-        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\PushProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationProvider/PushProvider.php',
83
-        'OCA\\DAV\\CalDAV\\Reminder\\NotificationTypeDoesNotExistException' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationTypeDoesNotExistException.php',
84
-        'OCA\\DAV\\CalDAV\\Reminder\\Notifier' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/Notifier.php',
85
-        'OCA\\DAV\\CalDAV\\Reminder\\ReminderService' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/ReminderService.php',
86
-        'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
87
-        'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
88
-        'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
89
-        'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/IMipPlugin.php',
90
-        'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/Plugin.php',
91
-        'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Search/SearchPlugin.php',
92
-        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/CompFilter.php',
93
-        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/LimitFilter.php',
94
-        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/OffsetFilter.php',
95
-        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/ParamFilter.php',
96
-        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
97
-        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
98
-        'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
99
-        'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/WebcalCaching/Plugin.php',
100
-        'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => __DIR__ . '/..' . '/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
101
-        'OCA\\DAV\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
102
-        'OCA\\DAV\\CardDAV\\AddressBook' => __DIR__ . '/..' . '/../lib/CardDAV/AddressBook.php',
103
-        'OCA\\DAV\\CardDAV\\AddressBookImpl' => __DIR__ . '/..' . '/../lib/CardDAV/AddressBookImpl.php',
104
-        'OCA\\DAV\\CardDAV\\AddressBookRoot' => __DIR__ . '/..' . '/../lib/CardDAV/AddressBookRoot.php',
105
-        'OCA\\DAV\\CardDAV\\CardDavBackend' => __DIR__ . '/..' . '/../lib/CardDAV/CardDavBackend.php',
106
-        'OCA\\DAV\\CardDAV\\ContactsManager' => __DIR__ . '/..' . '/../lib/CardDAV/ContactsManager.php',
107
-        'OCA\\DAV\\CardDAV\\Converter' => __DIR__ . '/..' . '/../lib/CardDAV/Converter.php',
108
-        'OCA\\DAV\\CardDAV\\HasPhotoPlugin' => __DIR__ . '/..' . '/../lib/CardDAV/HasPhotoPlugin.php',
109
-        'OCA\\DAV\\CardDAV\\ImageExportPlugin' => __DIR__ . '/..' . '/../lib/CardDAV/ImageExportPlugin.php',
110
-        'OCA\\DAV\\CardDAV\\Integration\\ExternalAddressBook' => __DIR__ . '/..' . '/../lib/CardDAV/Integration/ExternalAddressBook.php',
111
-        'OCA\\DAV\\CardDAV\\Integration\\IAddressBookProvider' => __DIR__ . '/..' . '/../lib/CardDAV/Integration/IAddressBookProvider.php',
112
-        'OCA\\DAV\\CardDAV\\MultiGetExportPlugin' => __DIR__ . '/..' . '/../lib/CardDAV/MultiGetExportPlugin.php',
113
-        'OCA\\DAV\\CardDAV\\PhotoCache' => __DIR__ . '/..' . '/../lib/CardDAV/PhotoCache.php',
114
-        'OCA\\DAV\\CardDAV\\Plugin' => __DIR__ . '/..' . '/../lib/CardDAV/Plugin.php',
115
-        'OCA\\DAV\\CardDAV\\SyncService' => __DIR__ . '/..' . '/../lib/CardDAV/SyncService.php',
116
-        'OCA\\DAV\\CardDAV\\SystemAddressbook' => __DIR__ . '/..' . '/../lib/CardDAV/SystemAddressbook.php',
117
-        'OCA\\DAV\\CardDAV\\UserAddressBooks' => __DIR__ . '/..' . '/../lib/CardDAV/UserAddressBooks.php',
118
-        'OCA\\DAV\\CardDAV\\Xml\\Groups' => __DIR__ . '/..' . '/../lib/CardDAV/Xml/Groups.php',
119
-        'OCA\\DAV\\Command\\CreateAddressBook' => __DIR__ . '/..' . '/../lib/Command/CreateAddressBook.php',
120
-        'OCA\\DAV\\Command\\CreateCalendar' => __DIR__ . '/..' . '/../lib/Command/CreateCalendar.php',
121
-        'OCA\\DAV\\Command\\ListCalendars' => __DIR__ . '/..' . '/../lib/Command/ListCalendars.php',
122
-        'OCA\\DAV\\Command\\MoveCalendar' => __DIR__ . '/..' . '/../lib/Command/MoveCalendar.php',
123
-        'OCA\\DAV\\Command\\RemoveInvalidShares' => __DIR__ . '/..' . '/../lib/Command/RemoveInvalidShares.php',
124
-        'OCA\\DAV\\Command\\SendEventReminders' => __DIR__ . '/..' . '/../lib/Command/SendEventReminders.php',
125
-        'OCA\\DAV\\Command\\SyncBirthdayCalendar' => __DIR__ . '/..' . '/../lib/Command/SyncBirthdayCalendar.php',
126
-        'OCA\\DAV\\Command\\SyncSystemAddressBook' => __DIR__ . '/..' . '/../lib/Command/SyncSystemAddressBook.php',
127
-        'OCA\\DAV\\Comments\\CommentNode' => __DIR__ . '/..' . '/../lib/Comments/CommentNode.php',
128
-        'OCA\\DAV\\Comments\\CommentsPlugin' => __DIR__ . '/..' . '/../lib/Comments/CommentsPlugin.php',
129
-        'OCA\\DAV\\Comments\\EntityCollection' => __DIR__ . '/..' . '/../lib/Comments/EntityCollection.php',
130
-        'OCA\\DAV\\Comments\\EntityTypeCollection' => __DIR__ . '/..' . '/../lib/Comments/EntityTypeCollection.php',
131
-        'OCA\\DAV\\Comments\\RootCollection' => __DIR__ . '/..' . '/../lib/Comments/RootCollection.php',
132
-        'OCA\\DAV\\Connector\\LegacyDAVACL' => __DIR__ . '/..' . '/../lib/Connector/LegacyDAVACL.php',
133
-        'OCA\\DAV\\Connector\\PublicAuth' => __DIR__ . '/..' . '/../lib/Connector/PublicAuth.php',
134
-        'OCA\\DAV\\Connector\\Sabre\\AnonymousOptionsPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/AnonymousOptionsPlugin.php',
135
-        'OCA\\DAV\\Connector\\Sabre\\AppEnabledPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/AppEnabledPlugin.php',
136
-        'OCA\\DAV\\Connector\\Sabre\\Auth' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Auth.php',
137
-        'OCA\\DAV\\Connector\\Sabre\\BearerAuth' => __DIR__ . '/..' . '/../lib/Connector/Sabre/BearerAuth.php',
138
-        'OCA\\DAV\\Connector\\Sabre\\BlockLegacyClientPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/BlockLegacyClientPlugin.php',
139
-        'OCA\\DAV\\Connector\\Sabre\\CachingTree' => __DIR__ . '/..' . '/../lib/Connector/Sabre/CachingTree.php',
140
-        'OCA\\DAV\\Connector\\Sabre\\ChecksumList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ChecksumList.php',
141
-        'OCA\\DAV\\Connector\\Sabre\\CommentPropertiesPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/CommentPropertiesPlugin.php',
142
-        'OCA\\DAV\\Connector\\Sabre\\CopyEtagHeaderPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/CopyEtagHeaderPlugin.php',
143
-        'OCA\\DAV\\Connector\\Sabre\\DavAclPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/DavAclPlugin.php',
144
-        'OCA\\DAV\\Connector\\Sabre\\Directory' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Directory.php',
145
-        'OCA\\DAV\\Connector\\Sabre\\DummyGetResponsePlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/DummyGetResponsePlugin.php',
146
-        'OCA\\DAV\\Connector\\Sabre\\ExceptionLoggerPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ExceptionLoggerPlugin.php',
147
-        'OCA\\DAV\\Connector\\Sabre\\Exception\\EntityTooLarge' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Exception/EntityTooLarge.php',
148
-        'OCA\\DAV\\Connector\\Sabre\\Exception\\FileLocked' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Exception/FileLocked.php',
149
-        'OCA\\DAV\\Connector\\Sabre\\Exception\\Forbidden' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Exception/Forbidden.php',
150
-        'OCA\\DAV\\Connector\\Sabre\\Exception\\InvalidPath' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Exception/InvalidPath.php',
151
-        'OCA\\DAV\\Connector\\Sabre\\Exception\\PasswordLoginForbidden' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Exception/PasswordLoginForbidden.php',
152
-        'OCA\\DAV\\Connector\\Sabre\\Exception\\UnsupportedMediaType' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Exception/UnsupportedMediaType.php',
153
-        'OCA\\DAV\\Connector\\Sabre\\FakeLockerPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/FakeLockerPlugin.php',
154
-        'OCA\\DAV\\Connector\\Sabre\\File' => __DIR__ . '/..' . '/../lib/Connector/Sabre/File.php',
155
-        'OCA\\DAV\\Connector\\Sabre\\FilesPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/FilesPlugin.php',
156
-        'OCA\\DAV\\Connector\\Sabre\\FilesReportPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/FilesReportPlugin.php',
157
-        'OCA\\DAV\\Connector\\Sabre\\LockPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/LockPlugin.php',
158
-        'OCA\\DAV\\Connector\\Sabre\\MaintenancePlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/MaintenancePlugin.php',
159
-        'OCA\\DAV\\Connector\\Sabre\\Node' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Node.php',
160
-        'OCA\\DAV\\Connector\\Sabre\\ObjectTree' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ObjectTree.php',
161
-        'OCA\\DAV\\Connector\\Sabre\\Principal' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Principal.php',
162
-        'OCA\\DAV\\Connector\\Sabre\\PropfindCompressionPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/PropfindCompressionPlugin.php',
163
-        'OCA\\DAV\\Connector\\Sabre\\QuotaPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/QuotaPlugin.php',
164
-        'OCA\\DAV\\Connector\\Sabre\\Server' => __DIR__ . '/..' . '/../lib/Connector/Sabre/Server.php',
165
-        'OCA\\DAV\\Connector\\Sabre\\ServerFactory' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ServerFactory.php',
166
-        'OCA\\DAV\\Connector\\Sabre\\ShareTypeList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ShareTypeList.php',
167
-        'OCA\\DAV\\Connector\\Sabre\\ShareeList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ShareeList.php',
168
-        'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/SharesPlugin.php',
169
-        'OCA\\DAV\\Connector\\Sabre\\TagList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/TagList.php',
170
-        'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/TagsPlugin.php',
171
-        'OCA\\DAV\\Controller\\BirthdayCalendarController' => __DIR__ . '/..' . '/../lib/Controller/BirthdayCalendarController.php',
172
-        'OCA\\DAV\\Controller\\DirectController' => __DIR__ . '/..' . '/../lib/Controller/DirectController.php',
173
-        'OCA\\DAV\\Controller\\InvitationResponseController' => __DIR__ . '/..' . '/../lib/Controller/InvitationResponseController.php',
174
-        'OCA\\DAV\\DAV\\CustomPropertiesBackend' => __DIR__ . '/..' . '/../lib/DAV/CustomPropertiesBackend.php',
175
-        'OCA\\DAV\\DAV\\GroupPrincipalBackend' => __DIR__ . '/..' . '/../lib/DAV/GroupPrincipalBackend.php',
176
-        'OCA\\DAV\\DAV\\PublicAuth' => __DIR__ . '/..' . '/../lib/DAV/PublicAuth.php',
177
-        'OCA\\DAV\\DAV\\Sharing\\Backend' => __DIR__ . '/..' . '/../lib/DAV/Sharing/Backend.php',
178
-        'OCA\\DAV\\DAV\\Sharing\\IShareable' => __DIR__ . '/..' . '/../lib/DAV/Sharing/IShareable.php',
179
-        'OCA\\DAV\\DAV\\Sharing\\Plugin' => __DIR__ . '/..' . '/../lib/DAV/Sharing/Plugin.php',
180
-        'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite' => __DIR__ . '/..' . '/../lib/DAV/Sharing/Xml/Invite.php',
181
-        'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest' => __DIR__ . '/..' . '/../lib/DAV/Sharing/Xml/ShareRequest.php',
182
-        'OCA\\DAV\\DAV\\SystemPrincipalBackend' => __DIR__ . '/..' . '/../lib/DAV/SystemPrincipalBackend.php',
183
-        'OCA\\DAV\\Db\\Direct' => __DIR__ . '/..' . '/../lib/Db/Direct.php',
184
-        'OCA\\DAV\\Db\\DirectMapper' => __DIR__ . '/..' . '/../lib/Db/DirectMapper.php',
185
-        'OCA\\DAV\\Direct\\DirectFile' => __DIR__ . '/..' . '/../lib/Direct/DirectFile.php',
186
-        'OCA\\DAV\\Direct\\DirectHome' => __DIR__ . '/..' . '/../lib/Direct/DirectHome.php',
187
-        'OCA\\DAV\\Direct\\Server' => __DIR__ . '/..' . '/../lib/Direct/Server.php',
188
-        'OCA\\DAV\\Direct\\ServerFactory' => __DIR__ . '/..' . '/../lib/Direct/ServerFactory.php',
189
-        'OCA\\DAV\\Events\\AddressBookCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/AddressBookCreatedEvent.php',
190
-        'OCA\\DAV\\Events\\AddressBookDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/AddressBookDeletedEvent.php',
191
-        'OCA\\DAV\\Events\\AddressBookShareUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/AddressBookShareUpdatedEvent.php',
192
-        'OCA\\DAV\\Events\\AddressBookUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/AddressBookUpdatedEvent.php',
193
-        'OCA\\DAV\\Events\\CachedCalendarObjectCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectCreatedEvent.php',
194
-        'OCA\\DAV\\Events\\CachedCalendarObjectDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectDeletedEvent.php',
195
-        'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
196
-        'OCA\\DAV\\Events\\CalendarCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarCreatedEvent.php',
197
-        'OCA\\DAV\\Events\\CalendarDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarDeletedEvent.php',
198
-        'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectCreatedEvent.php',
199
-        'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectDeletedEvent.php',
200
-        'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectUpdatedEvent.php',
201
-        'OCA\\DAV\\Events\\CalendarPublishedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarPublishedEvent.php',
202
-        'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarShareUpdatedEvent.php',
203
-        'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarUnpublishedEvent.php',
204
-        'OCA\\DAV\\Events\\CalendarUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarUpdatedEvent.php',
205
-        'OCA\\DAV\\Events\\CardCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CardCreatedEvent.php',
206
-        'OCA\\DAV\\Events\\CardDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CardDeletedEvent.php',
207
-        'OCA\\DAV\\Events\\CardUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CardUpdatedEvent.php',
208
-        'OCA\\DAV\\Events\\SabrePluginAuthInitEvent' => __DIR__ . '/..' . '/../lib/Events/SabrePluginAuthInitEvent.php',
209
-        'OCA\\DAV\\Events\\SubscriptionCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/SubscriptionCreatedEvent.php',
210
-        'OCA\\DAV\\Events\\SubscriptionDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/SubscriptionDeletedEvent.php',
211
-        'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/SubscriptionUpdatedEvent.php',
212
-        'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => __DIR__ . '/..' . '/../lib/Exception/UnsupportedLimitOnInitialSyncException.php',
213
-        'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => __DIR__ . '/..' . '/../lib/Files/BrowserErrorPagePlugin.php',
214
-        'OCA\\DAV\\Files\\FileSearchBackend' => __DIR__ . '/..' . '/../lib/Files/FileSearchBackend.php',
215
-        'OCA\\DAV\\Files\\FilesHome' => __DIR__ . '/..' . '/../lib/Files/FilesHome.php',
216
-        'OCA\\DAV\\Files\\LazySearchBackend' => __DIR__ . '/..' . '/../lib/Files/LazySearchBackend.php',
217
-        'OCA\\DAV\\Files\\RootCollection' => __DIR__ . '/..' . '/../lib/Files/RootCollection.php',
218
-        'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => __DIR__ . '/..' . '/../lib/Files/Sharing/FilesDropPlugin.php',
219
-        'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => __DIR__ . '/..' . '/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
220
-        'OCA\\DAV\\HookManager' => __DIR__ . '/..' . '/../lib/HookManager.php',
221
-        'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndex.php',
222
-        'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
223
-        'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => __DIR__ . '/..' . '/../lib/Migration/CalDAVRemoveEmptyValue.php',
224
-        'OCA\\DAV\\Migration\\ChunkCleanup' => __DIR__ . '/..' . '/../lib/Migration/ChunkCleanup.php',
225
-        'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => __DIR__ . '/..' . '/../lib/Migration/FixBirthdayCalendarComponent.php',
226
-        'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => __DIR__ . '/..' . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
227
-        'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/Migration/RegenerateBirthdayCalendars.php',
228
-        'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
229
-        'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => __DIR__ . '/..' . '/../lib/Migration/RemoveClassifiedEventActivity.php',
230
-        'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => __DIR__ . '/..' . '/../lib/Migration/RemoveOrphanEventsAndContacts.php',
231
-        'OCA\\DAV\\Migration\\Version1004Date20170825134824' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170825134824.php',
232
-        'OCA\\DAV\\Migration\\Version1004Date20170919104507' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170919104507.php',
233
-        'OCA\\DAV\\Migration\\Version1004Date20170924124212' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170924124212.php',
234
-        'OCA\\DAV\\Migration\\Version1004Date20170926103422' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170926103422.php',
235
-        'OCA\\DAV\\Migration\\Version1005Date20180413093149' => __DIR__ . '/..' . '/../lib/Migration/Version1005Date20180413093149.php',
236
-        'OCA\\DAV\\Migration\\Version1005Date20180530124431' => __DIR__ . '/..' . '/../lib/Migration/Version1005Date20180530124431.php',
237
-        'OCA\\DAV\\Migration\\Version1006Date20180619154313' => __DIR__ . '/..' . '/../lib/Migration/Version1006Date20180619154313.php',
238
-        'OCA\\DAV\\Migration\\Version1006Date20180628111625' => __DIR__ . '/..' . '/../lib/Migration/Version1006Date20180628111625.php',
239
-        'OCA\\DAV\\Migration\\Version1008Date20181030113700' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181030113700.php',
240
-        'OCA\\DAV\\Migration\\Version1008Date20181105104826' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181105104826.php',
241
-        'OCA\\DAV\\Migration\\Version1008Date20181105104833' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181105104833.php',
242
-        'OCA\\DAV\\Migration\\Version1008Date20181105110300' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181105110300.php',
243
-        'OCA\\DAV\\Migration\\Version1008Date20181105112049' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181105112049.php',
244
-        'OCA\\DAV\\Migration\\Version1008Date20181114084440' => __DIR__ . '/..' . '/../lib/Migration/Version1008Date20181114084440.php',
245
-        'OCA\\DAV\\Migration\\Version1011Date20190725113607' => __DIR__ . '/..' . '/../lib/Migration/Version1011Date20190725113607.php',
246
-        'OCA\\DAV\\Migration\\Version1011Date20190806104428' => __DIR__ . '/..' . '/../lib/Migration/Version1011Date20190806104428.php',
247
-        'OCA\\DAV\\Migration\\Version1012Date20190808122342' => __DIR__ . '/..' . '/../lib/Migration/Version1012Date20190808122342.php',
248
-        'OCA\\DAV\\Migration\\Version1016Date20201109085907' => __DIR__ . '/..' . '/../lib/Migration/Version1016Date20201109085907.php',
249
-        'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
250
-        'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
251
-        'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
252
-        'OCA\\DAV\\Search\\ACalendarSearchProvider' => __DIR__ . '/..' . '/../lib/Search/ACalendarSearchProvider.php',
253
-        'OCA\\DAV\\Search\\ContactsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/ContactsSearchProvider.php',
254
-        'OCA\\DAV\\Search\\EventsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/EventsSearchProvider.php',
255
-        'OCA\\DAV\\Search\\TasksSearchProvider' => __DIR__ . '/..' . '/../lib/Search/TasksSearchProvider.php',
256
-        'OCA\\DAV\\Server' => __DIR__ . '/..' . '/../lib/Server.php',
257
-        'OCA\\DAV\\Settings\\CalDAVSettings' => __DIR__ . '/..' . '/../lib/Settings/CalDAVSettings.php',
258
-        'OCA\\DAV\\Storage\\PublicOwnerWrapper' => __DIR__ . '/..' . '/../lib/Storage/PublicOwnerWrapper.php',
259
-        'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagMappingNode.php',
260
-        'OCA\\DAV\\SystemTag\\SystemTagNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagNode.php',
261
-        'OCA\\DAV\\SystemTag\\SystemTagPlugin' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagPlugin.php',
262
-        'OCA\\DAV\\SystemTag\\SystemTagsByIdCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsByIdCollection.php',
263
-        'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsObjectMappingCollection.php',
264
-        'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsObjectTypeCollection.php',
265
-        'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsRelationsCollection.php',
266
-        'OCA\\DAV\\Traits\\PrincipalProxyTrait' => __DIR__ . '/..' . '/../lib/Traits/PrincipalProxyTrait.php',
267
-        'OCA\\DAV\\Upload\\AssemblyStream' => __DIR__ . '/..' . '/../lib/Upload/AssemblyStream.php',
268
-        'OCA\\DAV\\Upload\\ChunkingPlugin' => __DIR__ . '/..' . '/../lib/Upload/ChunkingPlugin.php',
269
-        'OCA\\DAV\\Upload\\CleanupService' => __DIR__ . '/..' . '/../lib/Upload/CleanupService.php',
270
-        'OCA\\DAV\\Upload\\FutureFile' => __DIR__ . '/..' . '/../lib/Upload/FutureFile.php',
271
-        'OCA\\DAV\\Upload\\RootCollection' => __DIR__ . '/..' . '/../lib/Upload/RootCollection.php',
272
-        'OCA\\DAV\\Upload\\UploadFile' => __DIR__ . '/..' . '/../lib/Upload/UploadFile.php',
273
-        'OCA\\DAV\\Upload\\UploadFolder' => __DIR__ . '/..' . '/../lib/Upload/UploadFolder.php',
274
-        'OCA\\DAV\\Upload\\UploadHome' => __DIR__ . '/..' . '/../lib/Upload/UploadHome.php',
23
+    public static $classMap = array(
24
+        'OCA\\DAV\\AppInfo\\Application' => __DIR__.'/..'.'/../lib/AppInfo/Application.php',
25
+        'OCA\\DAV\\AppInfo\\PluginManager' => __DIR__.'/..'.'/../lib/AppInfo/PluginManager.php',
26
+        'OCA\\DAV\\Avatars\\AvatarHome' => __DIR__.'/..'.'/../lib/Avatars/AvatarHome.php',
27
+        'OCA\\DAV\\Avatars\\AvatarNode' => __DIR__.'/..'.'/../lib/Avatars/AvatarNode.php',
28
+        'OCA\\DAV\\Avatars\\RootCollection' => __DIR__.'/..'.'/../lib/Avatars/RootCollection.php',
29
+        'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => __DIR__.'/..'.'/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
30
+        'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => __DIR__.'/..'.'/../lib/BackgroundJob/CleanupDirectLinksJob.php',
31
+        'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => __DIR__.'/..'.'/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
32
+        'OCA\\DAV\\BackgroundJob\\EventReminderJob' => __DIR__.'/..'.'/../lib/BackgroundJob/EventReminderJob.php',
33
+        'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => __DIR__.'/..'.'/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
34
+        'OCA\\DAV\\BackgroundJob\\RefreshWebcalJob' => __DIR__.'/..'.'/../lib/BackgroundJob/RefreshWebcalJob.php',
35
+        'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => __DIR__.'/..'.'/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
36
+        'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => __DIR__.'/..'.'/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
37
+        'OCA\\DAV\\BackgroundJob\\UploadCleanup' => __DIR__.'/..'.'/../lib/BackgroundJob/UploadCleanup.php',
38
+        'OCA\\DAV\\CalDAV\\Activity\\Backend' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Backend.php',
39
+        'OCA\\DAV\\CalDAV\\Activity\\Filter\\Calendar' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Filter/Calendar.php',
40
+        'OCA\\DAV\\CalDAV\\Activity\\Filter\\Todo' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Filter/Todo.php',
41
+        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Base' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Provider/Base.php',
42
+        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Calendar' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Provider/Calendar.php',
43
+        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Event' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Provider/Event.php',
44
+        'OCA\\DAV\\CalDAV\\Activity\\Provider\\Todo' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Provider/Todo.php',
45
+        'OCA\\DAV\\CalDAV\\Activity\\Setting\\CalDAVSetting' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Setting/CalDAVSetting.php',
46
+        'OCA\\DAV\\CalDAV\\Activity\\Setting\\Calendar' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Setting/Calendar.php',
47
+        'OCA\\DAV\\CalDAV\\Activity\\Setting\\Event' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Setting/Event.php',
48
+        'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => __DIR__.'/..'.'/../lib/CalDAV/Activity/Setting/Todo.php',
49
+        'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => __DIR__.'/..'.'/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
50
+        'OCA\\DAV\\CalDAV\\BirthdayService' => __DIR__.'/..'.'/../lib/CalDAV/BirthdayService.php',
51
+        'OCA\\DAV\\CalDAV\\CachedSubscription' => __DIR__.'/..'.'/../lib/CalDAV/CachedSubscription.php',
52
+        'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => __DIR__.'/..'.'/../lib/CalDAV/CachedSubscriptionObject.php',
53
+        'OCA\\DAV\\CalDAV\\CalDavBackend' => __DIR__.'/..'.'/../lib/CalDAV/CalDavBackend.php',
54
+        'OCA\\DAV\\CalDAV\\Calendar' => __DIR__.'/..'.'/../lib/CalDAV/Calendar.php',
55
+        'OCA\\DAV\\CalDAV\\CalendarHome' => __DIR__.'/..'.'/../lib/CalDAV/CalendarHome.php',
56
+        'OCA\\DAV\\CalDAV\\CalendarImpl' => __DIR__.'/..'.'/../lib/CalDAV/CalendarImpl.php',
57
+        'OCA\\DAV\\CalDAV\\CalendarManager' => __DIR__.'/..'.'/../lib/CalDAV/CalendarManager.php',
58
+        'OCA\\DAV\\CalDAV\\CalendarObject' => __DIR__.'/..'.'/../lib/CalDAV/CalendarObject.php',
59
+        'OCA\\DAV\\CalDAV\\CalendarRoot' => __DIR__.'/..'.'/../lib/CalDAV/CalendarRoot.php',
60
+        'OCA\\DAV\\CalDAV\\ICSExportPlugin\\ICSExportPlugin' => __DIR__.'/..'.'/../lib/CalDAV/ICSExportPlugin/ICSExportPlugin.php',
61
+        'OCA\\DAV\\CalDAV\\Integration\\ExternalCalendar' => __DIR__.'/..'.'/../lib/CalDAV/Integration/ExternalCalendar.php',
62
+        'OCA\\DAV\\CalDAV\\Integration\\ICalendarProvider' => __DIR__.'/..'.'/../lib/CalDAV/Integration/ICalendarProvider.php',
63
+        'OCA\\DAV\\CalDAV\\InvitationResponse\\InvitationResponseServer' => __DIR__.'/..'.'/../lib/CalDAV/InvitationResponse/InvitationResponseServer.php',
64
+        'OCA\\DAV\\CalDAV\\Outbox' => __DIR__.'/..'.'/../lib/CalDAV/Outbox.php',
65
+        'OCA\\DAV\\CalDAV\\Plugin' => __DIR__.'/..'.'/../lib/CalDAV/Plugin.php',
66
+        'OCA\\DAV\\CalDAV\\Principal\\Collection' => __DIR__.'/..'.'/../lib/CalDAV/Principal/Collection.php',
67
+        'OCA\\DAV\\CalDAV\\Principal\\User' => __DIR__.'/..'.'/../lib/CalDAV/Principal/User.php',
68
+        'OCA\\DAV\\CalDAV\\Proxy\\Proxy' => __DIR__.'/..'.'/../lib/CalDAV/Proxy/Proxy.php',
69
+        'OCA\\DAV\\CalDAV\\Proxy\\ProxyMapper' => __DIR__.'/..'.'/../lib/CalDAV/Proxy/ProxyMapper.php',
70
+        'OCA\\DAV\\CalDAV\\PublicCalendar' => __DIR__.'/..'.'/../lib/CalDAV/PublicCalendar.php',
71
+        'OCA\\DAV\\CalDAV\\PublicCalendarObject' => __DIR__.'/..'.'/../lib/CalDAV/PublicCalendarObject.php',
72
+        'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => __DIR__.'/..'.'/../lib/CalDAV/PublicCalendarRoot.php',
73
+        'OCA\\DAV\\CalDAV\\Publishing\\PublishPlugin' => __DIR__.'/..'.'/../lib/CalDAV/Publishing/PublishPlugin.php',
74
+        'OCA\\DAV\\CalDAV\\Publishing\\Xml\\Publisher' => __DIR__.'/..'.'/../lib/CalDAV/Publishing/Xml/Publisher.php',
75
+        'OCA\\DAV\\CalDAV\\Reminder\\Backend' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/Backend.php',
76
+        'OCA\\DAV\\CalDAV\\Reminder\\INotificationProvider' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/INotificationProvider.php',
77
+        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProviderManager' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/NotificationProviderManager.php',
78
+        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AbstractProvider' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/NotificationProvider/AbstractProvider.php',
79
+        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\AudioProvider' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/NotificationProvider/AudioProvider.php',
80
+        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\EmailProvider' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php',
81
+        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\ProviderNotAvailableException' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/NotificationProvider/ProviderNotAvailableException.php',
82
+        'OCA\\DAV\\CalDAV\\Reminder\\NotificationProvider\\PushProvider' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/NotificationProvider/PushProvider.php',
83
+        'OCA\\DAV\\CalDAV\\Reminder\\NotificationTypeDoesNotExistException' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/NotificationTypeDoesNotExistException.php',
84
+        'OCA\\DAV\\CalDAV\\Reminder\\Notifier' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/Notifier.php',
85
+        'OCA\\DAV\\CalDAV\\Reminder\\ReminderService' => __DIR__.'/..'.'/../lib/CalDAV/Reminder/ReminderService.php',
86
+        'OCA\\DAV\\CalDAV\\ResourceBooking\\AbstractPrincipalBackend' => __DIR__.'/..'.'/../lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php',
87
+        'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => __DIR__.'/..'.'/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
88
+        'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => __DIR__.'/..'.'/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
89
+        'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => __DIR__.'/..'.'/../lib/CalDAV/Schedule/IMipPlugin.php',
90
+        'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => __DIR__.'/..'.'/../lib/CalDAV/Schedule/Plugin.php',
91
+        'OCA\\DAV\\CalDAV\\Search\\SearchPlugin' => __DIR__.'/..'.'/../lib/CalDAV/Search/SearchPlugin.php',
92
+        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter' => __DIR__.'/..'.'/../lib/CalDAV/Search/Xml/Filter/CompFilter.php',
93
+        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter' => __DIR__.'/..'.'/../lib/CalDAV/Search/Xml/Filter/LimitFilter.php',
94
+        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter' => __DIR__.'/..'.'/../lib/CalDAV/Search/Xml/Filter/OffsetFilter.php',
95
+        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter' => __DIR__.'/..'.'/../lib/CalDAV/Search/Xml/Filter/ParamFilter.php',
96
+        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => __DIR__.'/..'.'/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
97
+        'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => __DIR__.'/..'.'/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
98
+        'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => __DIR__.'/..'.'/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
99
+        'OCA\\DAV\\CalDAV\\WebcalCaching\\Plugin' => __DIR__.'/..'.'/../lib/CalDAV/WebcalCaching/Plugin.php',
100
+        'OCA\\DAV\\CalDAV\\WebcalCaching\\RefreshWebcalService' => __DIR__.'/..'.'/../lib/CalDAV/WebcalCaching/RefreshWebcalService.php',
101
+        'OCA\\DAV\\Capabilities' => __DIR__.'/..'.'/../lib/Capabilities.php',
102
+        'OCA\\DAV\\CardDAV\\AddressBook' => __DIR__.'/..'.'/../lib/CardDAV/AddressBook.php',
103
+        'OCA\\DAV\\CardDAV\\AddressBookImpl' => __DIR__.'/..'.'/../lib/CardDAV/AddressBookImpl.php',
104
+        'OCA\\DAV\\CardDAV\\AddressBookRoot' => __DIR__.'/..'.'/../lib/CardDAV/AddressBookRoot.php',
105
+        'OCA\\DAV\\CardDAV\\CardDavBackend' => __DIR__.'/..'.'/../lib/CardDAV/CardDavBackend.php',
106
+        'OCA\\DAV\\CardDAV\\ContactsManager' => __DIR__.'/..'.'/../lib/CardDAV/ContactsManager.php',
107
+        'OCA\\DAV\\CardDAV\\Converter' => __DIR__.'/..'.'/../lib/CardDAV/Converter.php',
108
+        'OCA\\DAV\\CardDAV\\HasPhotoPlugin' => __DIR__.'/..'.'/../lib/CardDAV/HasPhotoPlugin.php',
109
+        'OCA\\DAV\\CardDAV\\ImageExportPlugin' => __DIR__.'/..'.'/../lib/CardDAV/ImageExportPlugin.php',
110
+        'OCA\\DAV\\CardDAV\\Integration\\ExternalAddressBook' => __DIR__.'/..'.'/../lib/CardDAV/Integration/ExternalAddressBook.php',
111
+        'OCA\\DAV\\CardDAV\\Integration\\IAddressBookProvider' => __DIR__.'/..'.'/../lib/CardDAV/Integration/IAddressBookProvider.php',
112
+        'OCA\\DAV\\CardDAV\\MultiGetExportPlugin' => __DIR__.'/..'.'/../lib/CardDAV/MultiGetExportPlugin.php',
113
+        'OCA\\DAV\\CardDAV\\PhotoCache' => __DIR__.'/..'.'/../lib/CardDAV/PhotoCache.php',
114
+        'OCA\\DAV\\CardDAV\\Plugin' => __DIR__.'/..'.'/../lib/CardDAV/Plugin.php',
115
+        'OCA\\DAV\\CardDAV\\SyncService' => __DIR__.'/..'.'/../lib/CardDAV/SyncService.php',
116
+        'OCA\\DAV\\CardDAV\\SystemAddressbook' => __DIR__.'/..'.'/../lib/CardDAV/SystemAddressbook.php',
117
+        'OCA\\DAV\\CardDAV\\UserAddressBooks' => __DIR__.'/..'.'/../lib/CardDAV/UserAddressBooks.php',
118
+        'OCA\\DAV\\CardDAV\\Xml\\Groups' => __DIR__.'/..'.'/../lib/CardDAV/Xml/Groups.php',
119
+        'OCA\\DAV\\Command\\CreateAddressBook' => __DIR__.'/..'.'/../lib/Command/CreateAddressBook.php',
120
+        'OCA\\DAV\\Command\\CreateCalendar' => __DIR__.'/..'.'/../lib/Command/CreateCalendar.php',
121
+        'OCA\\DAV\\Command\\ListCalendars' => __DIR__.'/..'.'/../lib/Command/ListCalendars.php',
122
+        'OCA\\DAV\\Command\\MoveCalendar' => __DIR__.'/..'.'/../lib/Command/MoveCalendar.php',
123
+        'OCA\\DAV\\Command\\RemoveInvalidShares' => __DIR__.'/..'.'/../lib/Command/RemoveInvalidShares.php',
124
+        'OCA\\DAV\\Command\\SendEventReminders' => __DIR__.'/..'.'/../lib/Command/SendEventReminders.php',
125
+        'OCA\\DAV\\Command\\SyncBirthdayCalendar' => __DIR__.'/..'.'/../lib/Command/SyncBirthdayCalendar.php',
126
+        'OCA\\DAV\\Command\\SyncSystemAddressBook' => __DIR__.'/..'.'/../lib/Command/SyncSystemAddressBook.php',
127
+        'OCA\\DAV\\Comments\\CommentNode' => __DIR__.'/..'.'/../lib/Comments/CommentNode.php',
128
+        'OCA\\DAV\\Comments\\CommentsPlugin' => __DIR__.'/..'.'/../lib/Comments/CommentsPlugin.php',
129
+        'OCA\\DAV\\Comments\\EntityCollection' => __DIR__.'/..'.'/../lib/Comments/EntityCollection.php',
130
+        'OCA\\DAV\\Comments\\EntityTypeCollection' => __DIR__.'/..'.'/../lib/Comments/EntityTypeCollection.php',
131
+        'OCA\\DAV\\Comments\\RootCollection' => __DIR__.'/..'.'/../lib/Comments/RootCollection.php',
132
+        'OCA\\DAV\\Connector\\LegacyDAVACL' => __DIR__.'/..'.'/../lib/Connector/LegacyDAVACL.php',
133
+        'OCA\\DAV\\Connector\\PublicAuth' => __DIR__.'/..'.'/../lib/Connector/PublicAuth.php',
134
+        'OCA\\DAV\\Connector\\Sabre\\AnonymousOptionsPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/AnonymousOptionsPlugin.php',
135
+        'OCA\\DAV\\Connector\\Sabre\\AppEnabledPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/AppEnabledPlugin.php',
136
+        'OCA\\DAV\\Connector\\Sabre\\Auth' => __DIR__.'/..'.'/../lib/Connector/Sabre/Auth.php',
137
+        'OCA\\DAV\\Connector\\Sabre\\BearerAuth' => __DIR__.'/..'.'/../lib/Connector/Sabre/BearerAuth.php',
138
+        'OCA\\DAV\\Connector\\Sabre\\BlockLegacyClientPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/BlockLegacyClientPlugin.php',
139
+        'OCA\\DAV\\Connector\\Sabre\\CachingTree' => __DIR__.'/..'.'/../lib/Connector/Sabre/CachingTree.php',
140
+        'OCA\\DAV\\Connector\\Sabre\\ChecksumList' => __DIR__.'/..'.'/../lib/Connector/Sabre/ChecksumList.php',
141
+        'OCA\\DAV\\Connector\\Sabre\\CommentPropertiesPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/CommentPropertiesPlugin.php',
142
+        'OCA\\DAV\\Connector\\Sabre\\CopyEtagHeaderPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/CopyEtagHeaderPlugin.php',
143
+        'OCA\\DAV\\Connector\\Sabre\\DavAclPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/DavAclPlugin.php',
144
+        'OCA\\DAV\\Connector\\Sabre\\Directory' => __DIR__.'/..'.'/../lib/Connector/Sabre/Directory.php',
145
+        'OCA\\DAV\\Connector\\Sabre\\DummyGetResponsePlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/DummyGetResponsePlugin.php',
146
+        'OCA\\DAV\\Connector\\Sabre\\ExceptionLoggerPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/ExceptionLoggerPlugin.php',
147
+        'OCA\\DAV\\Connector\\Sabre\\Exception\\EntityTooLarge' => __DIR__.'/..'.'/../lib/Connector/Sabre/Exception/EntityTooLarge.php',
148
+        'OCA\\DAV\\Connector\\Sabre\\Exception\\FileLocked' => __DIR__.'/..'.'/../lib/Connector/Sabre/Exception/FileLocked.php',
149
+        'OCA\\DAV\\Connector\\Sabre\\Exception\\Forbidden' => __DIR__.'/..'.'/../lib/Connector/Sabre/Exception/Forbidden.php',
150
+        'OCA\\DAV\\Connector\\Sabre\\Exception\\InvalidPath' => __DIR__.'/..'.'/../lib/Connector/Sabre/Exception/InvalidPath.php',
151
+        'OCA\\DAV\\Connector\\Sabre\\Exception\\PasswordLoginForbidden' => __DIR__.'/..'.'/../lib/Connector/Sabre/Exception/PasswordLoginForbidden.php',
152
+        'OCA\\DAV\\Connector\\Sabre\\Exception\\UnsupportedMediaType' => __DIR__.'/..'.'/../lib/Connector/Sabre/Exception/UnsupportedMediaType.php',
153
+        'OCA\\DAV\\Connector\\Sabre\\FakeLockerPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/FakeLockerPlugin.php',
154
+        'OCA\\DAV\\Connector\\Sabre\\File' => __DIR__.'/..'.'/../lib/Connector/Sabre/File.php',
155
+        'OCA\\DAV\\Connector\\Sabre\\FilesPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/FilesPlugin.php',
156
+        'OCA\\DAV\\Connector\\Sabre\\FilesReportPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/FilesReportPlugin.php',
157
+        'OCA\\DAV\\Connector\\Sabre\\LockPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/LockPlugin.php',
158
+        'OCA\\DAV\\Connector\\Sabre\\MaintenancePlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/MaintenancePlugin.php',
159
+        'OCA\\DAV\\Connector\\Sabre\\Node' => __DIR__.'/..'.'/../lib/Connector/Sabre/Node.php',
160
+        'OCA\\DAV\\Connector\\Sabre\\ObjectTree' => __DIR__.'/..'.'/../lib/Connector/Sabre/ObjectTree.php',
161
+        'OCA\\DAV\\Connector\\Sabre\\Principal' => __DIR__.'/..'.'/../lib/Connector/Sabre/Principal.php',
162
+        'OCA\\DAV\\Connector\\Sabre\\PropfindCompressionPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/PropfindCompressionPlugin.php',
163
+        'OCA\\DAV\\Connector\\Sabre\\QuotaPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/QuotaPlugin.php',
164
+        'OCA\\DAV\\Connector\\Sabre\\Server' => __DIR__.'/..'.'/../lib/Connector/Sabre/Server.php',
165
+        'OCA\\DAV\\Connector\\Sabre\\ServerFactory' => __DIR__.'/..'.'/../lib/Connector/Sabre/ServerFactory.php',
166
+        'OCA\\DAV\\Connector\\Sabre\\ShareTypeList' => __DIR__.'/..'.'/../lib/Connector/Sabre/ShareTypeList.php',
167
+        'OCA\\DAV\\Connector\\Sabre\\ShareeList' => __DIR__.'/..'.'/../lib/Connector/Sabre/ShareeList.php',
168
+        'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/SharesPlugin.php',
169
+        'OCA\\DAV\\Connector\\Sabre\\TagList' => __DIR__.'/..'.'/../lib/Connector/Sabre/TagList.php',
170
+        'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => __DIR__.'/..'.'/../lib/Connector/Sabre/TagsPlugin.php',
171
+        'OCA\\DAV\\Controller\\BirthdayCalendarController' => __DIR__.'/..'.'/../lib/Controller/BirthdayCalendarController.php',
172
+        'OCA\\DAV\\Controller\\DirectController' => __DIR__.'/..'.'/../lib/Controller/DirectController.php',
173
+        'OCA\\DAV\\Controller\\InvitationResponseController' => __DIR__.'/..'.'/../lib/Controller/InvitationResponseController.php',
174
+        'OCA\\DAV\\DAV\\CustomPropertiesBackend' => __DIR__.'/..'.'/../lib/DAV/CustomPropertiesBackend.php',
175
+        'OCA\\DAV\\DAV\\GroupPrincipalBackend' => __DIR__.'/..'.'/../lib/DAV/GroupPrincipalBackend.php',
176
+        'OCA\\DAV\\DAV\\PublicAuth' => __DIR__.'/..'.'/../lib/DAV/PublicAuth.php',
177
+        'OCA\\DAV\\DAV\\Sharing\\Backend' => __DIR__.'/..'.'/../lib/DAV/Sharing/Backend.php',
178
+        'OCA\\DAV\\DAV\\Sharing\\IShareable' => __DIR__.'/..'.'/../lib/DAV/Sharing/IShareable.php',
179
+        'OCA\\DAV\\DAV\\Sharing\\Plugin' => __DIR__.'/..'.'/../lib/DAV/Sharing/Plugin.php',
180
+        'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite' => __DIR__.'/..'.'/../lib/DAV/Sharing/Xml/Invite.php',
181
+        'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest' => __DIR__.'/..'.'/../lib/DAV/Sharing/Xml/ShareRequest.php',
182
+        'OCA\\DAV\\DAV\\SystemPrincipalBackend' => __DIR__.'/..'.'/../lib/DAV/SystemPrincipalBackend.php',
183
+        'OCA\\DAV\\Db\\Direct' => __DIR__.'/..'.'/../lib/Db/Direct.php',
184
+        'OCA\\DAV\\Db\\DirectMapper' => __DIR__.'/..'.'/../lib/Db/DirectMapper.php',
185
+        'OCA\\DAV\\Direct\\DirectFile' => __DIR__.'/..'.'/../lib/Direct/DirectFile.php',
186
+        'OCA\\DAV\\Direct\\DirectHome' => __DIR__.'/..'.'/../lib/Direct/DirectHome.php',
187
+        'OCA\\DAV\\Direct\\Server' => __DIR__.'/..'.'/../lib/Direct/Server.php',
188
+        'OCA\\DAV\\Direct\\ServerFactory' => __DIR__.'/..'.'/../lib/Direct/ServerFactory.php',
189
+        'OCA\\DAV\\Events\\AddressBookCreatedEvent' => __DIR__.'/..'.'/../lib/Events/AddressBookCreatedEvent.php',
190
+        'OCA\\DAV\\Events\\AddressBookDeletedEvent' => __DIR__.'/..'.'/../lib/Events/AddressBookDeletedEvent.php',
191
+        'OCA\\DAV\\Events\\AddressBookShareUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/AddressBookShareUpdatedEvent.php',
192
+        'OCA\\DAV\\Events\\AddressBookUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/AddressBookUpdatedEvent.php',
193
+        'OCA\\DAV\\Events\\CachedCalendarObjectCreatedEvent' => __DIR__.'/..'.'/../lib/Events/CachedCalendarObjectCreatedEvent.php',
194
+        'OCA\\DAV\\Events\\CachedCalendarObjectDeletedEvent' => __DIR__.'/..'.'/../lib/Events/CachedCalendarObjectDeletedEvent.php',
195
+        'OCA\\DAV\\Events\\CachedCalendarObjectUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/CachedCalendarObjectUpdatedEvent.php',
196
+        'OCA\\DAV\\Events\\CalendarCreatedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarCreatedEvent.php',
197
+        'OCA\\DAV\\Events\\CalendarDeletedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarDeletedEvent.php',
198
+        'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarObjectCreatedEvent.php',
199
+        'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarObjectDeletedEvent.php',
200
+        'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarObjectUpdatedEvent.php',
201
+        'OCA\\DAV\\Events\\CalendarPublishedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarPublishedEvent.php',
202
+        'OCA\\DAV\\Events\\CalendarShareUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarShareUpdatedEvent.php',
203
+        'OCA\\DAV\\Events\\CalendarUnpublishedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarUnpublishedEvent.php',
204
+        'OCA\\DAV\\Events\\CalendarUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/CalendarUpdatedEvent.php',
205
+        'OCA\\DAV\\Events\\CardCreatedEvent' => __DIR__.'/..'.'/../lib/Events/CardCreatedEvent.php',
206
+        'OCA\\DAV\\Events\\CardDeletedEvent' => __DIR__.'/..'.'/../lib/Events/CardDeletedEvent.php',
207
+        'OCA\\DAV\\Events\\CardUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/CardUpdatedEvent.php',
208
+        'OCA\\DAV\\Events\\SabrePluginAuthInitEvent' => __DIR__.'/..'.'/../lib/Events/SabrePluginAuthInitEvent.php',
209
+        'OCA\\DAV\\Events\\SubscriptionCreatedEvent' => __DIR__.'/..'.'/../lib/Events/SubscriptionCreatedEvent.php',
210
+        'OCA\\DAV\\Events\\SubscriptionDeletedEvent' => __DIR__.'/..'.'/../lib/Events/SubscriptionDeletedEvent.php',
211
+        'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => __DIR__.'/..'.'/../lib/Events/SubscriptionUpdatedEvent.php',
212
+        'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => __DIR__.'/..'.'/../lib/Exception/UnsupportedLimitOnInitialSyncException.php',
213
+        'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => __DIR__.'/..'.'/../lib/Files/BrowserErrorPagePlugin.php',
214
+        'OCA\\DAV\\Files\\FileSearchBackend' => __DIR__.'/..'.'/../lib/Files/FileSearchBackend.php',
215
+        'OCA\\DAV\\Files\\FilesHome' => __DIR__.'/..'.'/../lib/Files/FilesHome.php',
216
+        'OCA\\DAV\\Files\\LazySearchBackend' => __DIR__.'/..'.'/../lib/Files/LazySearchBackend.php',
217
+        'OCA\\DAV\\Files\\RootCollection' => __DIR__.'/..'.'/../lib/Files/RootCollection.php',
218
+        'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => __DIR__.'/..'.'/../lib/Files/Sharing/FilesDropPlugin.php',
219
+        'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => __DIR__.'/..'.'/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
220
+        'OCA\\DAV\\HookManager' => __DIR__.'/..'.'/../lib/HookManager.php',
221
+        'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__.'/..'.'/../lib/Migration/BuildCalendarSearchIndex.php',
222
+        'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__.'/..'.'/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
223
+        'OCA\\DAV\\Migration\\CalDAVRemoveEmptyValue' => __DIR__.'/..'.'/../lib/Migration/CalDAVRemoveEmptyValue.php',
224
+        'OCA\\DAV\\Migration\\ChunkCleanup' => __DIR__.'/..'.'/../lib/Migration/ChunkCleanup.php',
225
+        'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => __DIR__.'/..'.'/../lib/Migration/FixBirthdayCalendarComponent.php',
226
+        'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => __DIR__.'/..'.'/../lib/Migration/RefreshWebcalJobRegistrar.php',
227
+        'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => __DIR__.'/..'.'/../lib/Migration/RegenerateBirthdayCalendars.php',
228
+        'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => __DIR__.'/..'.'/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
229
+        'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => __DIR__.'/..'.'/../lib/Migration/RemoveClassifiedEventActivity.php',
230
+        'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => __DIR__.'/..'.'/../lib/Migration/RemoveOrphanEventsAndContacts.php',
231
+        'OCA\\DAV\\Migration\\Version1004Date20170825134824' => __DIR__.'/..'.'/../lib/Migration/Version1004Date20170825134824.php',
232
+        'OCA\\DAV\\Migration\\Version1004Date20170919104507' => __DIR__.'/..'.'/../lib/Migration/Version1004Date20170919104507.php',
233
+        'OCA\\DAV\\Migration\\Version1004Date20170924124212' => __DIR__.'/..'.'/../lib/Migration/Version1004Date20170924124212.php',
234
+        'OCA\\DAV\\Migration\\Version1004Date20170926103422' => __DIR__.'/..'.'/../lib/Migration/Version1004Date20170926103422.php',
235
+        'OCA\\DAV\\Migration\\Version1005Date20180413093149' => __DIR__.'/..'.'/../lib/Migration/Version1005Date20180413093149.php',
236
+        'OCA\\DAV\\Migration\\Version1005Date20180530124431' => __DIR__.'/..'.'/../lib/Migration/Version1005Date20180530124431.php',
237
+        'OCA\\DAV\\Migration\\Version1006Date20180619154313' => __DIR__.'/..'.'/../lib/Migration/Version1006Date20180619154313.php',
238
+        'OCA\\DAV\\Migration\\Version1006Date20180628111625' => __DIR__.'/..'.'/../lib/Migration/Version1006Date20180628111625.php',
239
+        'OCA\\DAV\\Migration\\Version1008Date20181030113700' => __DIR__.'/..'.'/../lib/Migration/Version1008Date20181030113700.php',
240
+        'OCA\\DAV\\Migration\\Version1008Date20181105104826' => __DIR__.'/..'.'/../lib/Migration/Version1008Date20181105104826.php',
241
+        'OCA\\DAV\\Migration\\Version1008Date20181105104833' => __DIR__.'/..'.'/../lib/Migration/Version1008Date20181105104833.php',
242
+        'OCA\\DAV\\Migration\\Version1008Date20181105110300' => __DIR__.'/..'.'/../lib/Migration/Version1008Date20181105110300.php',
243
+        'OCA\\DAV\\Migration\\Version1008Date20181105112049' => __DIR__.'/..'.'/../lib/Migration/Version1008Date20181105112049.php',
244
+        'OCA\\DAV\\Migration\\Version1008Date20181114084440' => __DIR__.'/..'.'/../lib/Migration/Version1008Date20181114084440.php',
245
+        'OCA\\DAV\\Migration\\Version1011Date20190725113607' => __DIR__.'/..'.'/../lib/Migration/Version1011Date20190725113607.php',
246
+        'OCA\\DAV\\Migration\\Version1011Date20190806104428' => __DIR__.'/..'.'/../lib/Migration/Version1011Date20190806104428.php',
247
+        'OCA\\DAV\\Migration\\Version1012Date20190808122342' => __DIR__.'/..'.'/../lib/Migration/Version1012Date20190808122342.php',
248
+        'OCA\\DAV\\Migration\\Version1016Date20201109085907' => __DIR__.'/..'.'/../lib/Migration/Version1016Date20201109085907.php',
249
+        'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__.'/..'.'/../lib/Provisioning/Apple/AppleProvisioningNode.php',
250
+        'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__.'/..'.'/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
251
+        'OCA\\DAV\\RootCollection' => __DIR__.'/..'.'/../lib/RootCollection.php',
252
+        'OCA\\DAV\\Search\\ACalendarSearchProvider' => __DIR__.'/..'.'/../lib/Search/ACalendarSearchProvider.php',
253
+        'OCA\\DAV\\Search\\ContactsSearchProvider' => __DIR__.'/..'.'/../lib/Search/ContactsSearchProvider.php',
254
+        'OCA\\DAV\\Search\\EventsSearchProvider' => __DIR__.'/..'.'/../lib/Search/EventsSearchProvider.php',
255
+        'OCA\\DAV\\Search\\TasksSearchProvider' => __DIR__.'/..'.'/../lib/Search/TasksSearchProvider.php',
256
+        'OCA\\DAV\\Server' => __DIR__.'/..'.'/../lib/Server.php',
257
+        'OCA\\DAV\\Settings\\CalDAVSettings' => __DIR__.'/..'.'/../lib/Settings/CalDAVSettings.php',
258
+        'OCA\\DAV\\Storage\\PublicOwnerWrapper' => __DIR__.'/..'.'/../lib/Storage/PublicOwnerWrapper.php',
259
+        'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => __DIR__.'/..'.'/../lib/SystemTag/SystemTagMappingNode.php',
260
+        'OCA\\DAV\\SystemTag\\SystemTagNode' => __DIR__.'/..'.'/../lib/SystemTag/SystemTagNode.php',
261
+        'OCA\\DAV\\SystemTag\\SystemTagPlugin' => __DIR__.'/..'.'/../lib/SystemTag/SystemTagPlugin.php',
262
+        'OCA\\DAV\\SystemTag\\SystemTagsByIdCollection' => __DIR__.'/..'.'/../lib/SystemTag/SystemTagsByIdCollection.php',
263
+        'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => __DIR__.'/..'.'/../lib/SystemTag/SystemTagsObjectMappingCollection.php',
264
+        'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => __DIR__.'/..'.'/../lib/SystemTag/SystemTagsObjectTypeCollection.php',
265
+        'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => __DIR__.'/..'.'/../lib/SystemTag/SystemTagsRelationsCollection.php',
266
+        'OCA\\DAV\\Traits\\PrincipalProxyTrait' => __DIR__.'/..'.'/../lib/Traits/PrincipalProxyTrait.php',
267
+        'OCA\\DAV\\Upload\\AssemblyStream' => __DIR__.'/..'.'/../lib/Upload/AssemblyStream.php',
268
+        'OCA\\DAV\\Upload\\ChunkingPlugin' => __DIR__.'/..'.'/../lib/Upload/ChunkingPlugin.php',
269
+        'OCA\\DAV\\Upload\\CleanupService' => __DIR__.'/..'.'/../lib/Upload/CleanupService.php',
270
+        'OCA\\DAV\\Upload\\FutureFile' => __DIR__.'/..'.'/../lib/Upload/FutureFile.php',
271
+        'OCA\\DAV\\Upload\\RootCollection' => __DIR__.'/..'.'/../lib/Upload/RootCollection.php',
272
+        'OCA\\DAV\\Upload\\UploadFile' => __DIR__.'/..'.'/../lib/Upload/UploadFile.php',
273
+        'OCA\\DAV\\Upload\\UploadFolder' => __DIR__.'/..'.'/../lib/Upload/UploadFolder.php',
274
+        'OCA\\DAV\\Upload\\UploadHome' => __DIR__.'/..'.'/../lib/Upload/UploadHome.php',
275 275
     );
276 276
 
277 277
     public static function getInitializer(ClassLoader $loader)
278 278
     {
279
-        return \Closure::bind(function () use ($loader) {
279
+        return \Closure::bind(function() use ($loader) {
280 280
             $loader->prefixLengthsPsr4 = ComposerStaticInitDAV::$prefixLengthsPsr4;
281 281
             $loader->prefixDirsPsr4 = ComposerStaticInitDAV::$prefixDirsPsr4;
282 282
             $loader->classMap = ComposerStaticInitDAV::$classMap;
Please login to merge, or discard this patch.
apps/dav/lib/CalDAV/CalDavBackend.php 2 patches
Indentation   +2747 added lines, -2747 removed lines patch added patch discarded remove patch
@@ -95,2751 +95,2751 @@
 block discarded – undo
95 95
  * @package OCA\DAV\CalDAV
96 96
  */
97 97
 class CalDavBackend extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport {
98
-	public const CALENDAR_TYPE_CALENDAR = 0;
99
-	public const CALENDAR_TYPE_SUBSCRIPTION = 1;
100
-
101
-	public const PERSONAL_CALENDAR_URI = 'personal';
102
-	public const PERSONAL_CALENDAR_NAME = 'Personal';
103
-
104
-	public const RESOURCE_BOOKING_CALENDAR_URI = 'calendar';
105
-	public const RESOURCE_BOOKING_CALENDAR_NAME = 'Calendar';
106
-
107
-	/**
108
-	 * We need to specify a max date, because we need to stop *somewhere*
109
-	 *
110
-	 * On 32 bit system the maximum for a signed integer is 2147483647, so
111
-	 * MAX_DATE cannot be higher than date('Y-m-d', 2147483647) which results
112
-	 * in 2038-01-19 to avoid problems when the date is converted
113
-	 * to a unix timestamp.
114
-	 */
115
-	public const MAX_DATE = '2038-01-01';
116
-
117
-	public const ACCESS_PUBLIC = 4;
118
-	public const CLASSIFICATION_PUBLIC = 0;
119
-	public const CLASSIFICATION_PRIVATE = 1;
120
-	public const CLASSIFICATION_CONFIDENTIAL = 2;
121
-
122
-	/**
123
-	 * List of CalDAV properties, and how they map to database field names
124
-	 * Add your own properties by simply adding on to this array.
125
-	 *
126
-	 * Note that only string-based properties are supported here.
127
-	 *
128
-	 * @var array
129
-	 */
130
-	public $propertyMap = [
131
-		'{DAV:}displayname' => 'displayname',
132
-		'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description',
133
-		'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone',
134
-		'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
135
-		'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
136
-	];
137
-
138
-	/**
139
-	 * List of subscription properties, and how they map to database field names.
140
-	 *
141
-	 * @var array
142
-	 */
143
-	public $subscriptionPropertyMap = [
144
-		'{DAV:}displayname' => 'displayname',
145
-		'{http://apple.com/ns/ical/}refreshrate' => 'refreshrate',
146
-		'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
147
-		'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
148
-		'{http://calendarserver.org/ns/}subscribed-strip-todos' => 'striptodos',
149
-		'{http://calendarserver.org/ns/}subscribed-strip-alarms' => 'stripalarms',
150
-		'{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments',
151
-	];
152
-
153
-	/** @var array properties to index */
154
-	public static $indexProperties = ['CATEGORIES', 'COMMENT', 'DESCRIPTION',
155
-		'LOCATION', 'RESOURCES', 'STATUS', 'SUMMARY', 'ATTENDEE', 'CONTACT',
156
-		'ORGANIZER'];
157
-
158
-	/** @var array parameters to index */
159
-	public static $indexParameters = [
160
-		'ATTENDEE' => ['CN'],
161
-		'ORGANIZER' => ['CN'],
162
-	];
163
-
164
-	/**
165
-	 * @var string[] Map of uid => display name
166
-	 */
167
-	protected $userDisplayNames;
168
-
169
-	/** @var IDBConnection */
170
-	private $db;
171
-
172
-	/** @var Backend */
173
-	private $calendarSharingBackend;
174
-
175
-	/** @var Principal */
176
-	private $principalBackend;
177
-
178
-	/** @var IUserManager */
179
-	private $userManager;
180
-
181
-	/** @var ISecureRandom */
182
-	private $random;
183
-
184
-	/** @var ILogger */
185
-	private $logger;
186
-
187
-	/** @var IEventDispatcher */
188
-	private $dispatcher;
189
-
190
-	/** @var EventDispatcherInterface */
191
-	private $legacyDispatcher;
192
-
193
-	/** @var bool */
194
-	private $legacyEndpoint;
195
-
196
-	/** @var string */
197
-	private $dbObjectPropertiesTable = 'calendarobjects_props';
198
-
199
-	/**
200
-	 * CalDavBackend constructor.
201
-	 *
202
-	 * @param IDBConnection $db
203
-	 * @param Principal $principalBackend
204
-	 * @param IUserManager $userManager
205
-	 * @param IGroupManager $groupManager
206
-	 * @param ISecureRandom $random
207
-	 * @param ILogger $logger
208
-	 * @param IEventDispatcher $dispatcher
209
-	 * @param EventDispatcherInterface $legacyDispatcher
210
-	 * @param bool $legacyEndpoint
211
-	 */
212
-	public function __construct(IDBConnection $db,
213
-								Principal $principalBackend,
214
-								IUserManager $userManager,
215
-								IGroupManager $groupManager,
216
-								ISecureRandom $random,
217
-								ILogger $logger,
218
-								IEventDispatcher $dispatcher,
219
-								EventDispatcherInterface $legacyDispatcher,
220
-								bool $legacyEndpoint = false) {
221
-		$this->db = $db;
222
-		$this->principalBackend = $principalBackend;
223
-		$this->userManager = $userManager;
224
-		$this->calendarSharingBackend = new Backend($this->db, $this->userManager, $groupManager, $principalBackend, 'calendar');
225
-		$this->random = $random;
226
-		$this->logger = $logger;
227
-		$this->dispatcher = $dispatcher;
228
-		$this->legacyDispatcher = $legacyDispatcher;
229
-		$this->legacyEndpoint = $legacyEndpoint;
230
-	}
231
-
232
-	/**
233
-	 * Return the number of calendars for a principal
234
-	 *
235
-	 * By default this excludes the automatically generated birthday calendar
236
-	 *
237
-	 * @param $principalUri
238
-	 * @param bool $excludeBirthday
239
-	 * @return int
240
-	 */
241
-	public function getCalendarsForUserCount($principalUri, $excludeBirthday = true) {
242
-		$principalUri = $this->convertPrincipal($principalUri, true);
243
-		$query = $this->db->getQueryBuilder();
244
-		$query->select($query->func()->count('*'))
245
-			->from('calendars');
246
-
247
-		if ($principalUri === '') {
248
-			$query->where($query->expr()->emptyString('principaluri'));
249
-		} else {
250
-			$query->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)));
251
-		}
252
-
253
-		if ($excludeBirthday) {
254
-			$query->andWhere($query->expr()->neq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI)));
255
-		}
256
-
257
-		$result = $query->execute();
258
-		$column = (int)$result->fetchColumn();
259
-		$result->closeCursor();
260
-		return $column;
261
-	}
262
-
263
-	/**
264
-	 * Returns a list of calendars for a principal.
265
-	 *
266
-	 * Every project is an array with the following keys:
267
-	 *  * id, a unique id that will be used by other functions to modify the
268
-	 *    calendar. This can be the same as the uri or a database key.
269
-	 *  * uri, which the basename of the uri with which the calendar is
270
-	 *    accessed.
271
-	 *  * principaluri. The owner of the calendar. Almost always the same as
272
-	 *    principalUri passed to this method.
273
-	 *
274
-	 * Furthermore it can contain webdav properties in clark notation. A very
275
-	 * common one is '{DAV:}displayname'.
276
-	 *
277
-	 * Many clients also require:
278
-	 * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
279
-	 * For this property, you can just return an instance of
280
-	 * Sabre\CalDAV\Property\SupportedCalendarComponentSet.
281
-	 *
282
-	 * If you return {http://sabredav.org/ns}read-only and set the value to 1,
283
-	 * ACL will automatically be put in read-only mode.
284
-	 *
285
-	 * @param string $principalUri
286
-	 * @return array
287
-	 */
288
-	public function getCalendarsForUser($principalUri) {
289
-		$principalUriOriginal = $principalUri;
290
-		$principalUri = $this->convertPrincipal($principalUri, true);
291
-		$fields = array_values($this->propertyMap);
292
-		$fields[] = 'id';
293
-		$fields[] = 'uri';
294
-		$fields[] = 'synctoken';
295
-		$fields[] = 'components';
296
-		$fields[] = 'principaluri';
297
-		$fields[] = 'transparent';
298
-
299
-		// Making fields a comma-delimited list
300
-		$query = $this->db->getQueryBuilder();
301
-		$query->select($fields)
302
-			->from('calendars')
303
-			->orderBy('calendarorder', 'ASC');
304
-
305
-		if ($principalUri === '') {
306
-			$query->where($query->expr()->emptyString('principaluri'));
307
-		} else {
308
-			$query->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)));
309
-		}
310
-
311
-		$result = $query->execute();
312
-
313
-		$calendars = [];
314
-		while ($row = $result->fetch()) {
315
-			$row['principaluri'] = (string) $row['principaluri'];
316
-			$components = [];
317
-			if ($row['components']) {
318
-				$components = explode(',',$row['components']);
319
-			}
320
-
321
-			$calendar = [
322
-				'id' => $row['id'],
323
-				'uri' => $row['uri'],
324
-				'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
325
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
326
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
327
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
328
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
329
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
330
-			];
331
-
332
-			foreach ($this->propertyMap as $xmlName => $dbName) {
333
-				$calendar[$xmlName] = $row[$dbName];
334
-			}
335
-
336
-			$this->addOwnerPrincipal($calendar);
337
-
338
-			if (!isset($calendars[$calendar['id']])) {
339
-				$calendars[$calendar['id']] = $calendar;
340
-			}
341
-		}
342
-		$result->closeCursor();
343
-
344
-		// query for shared calendars
345
-		$principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true);
346
-		$principals = array_merge($principals, $this->principalBackend->getCircleMembership($principalUriOriginal));
347
-
348
-		$principals = array_map(function ($principal) {
349
-			return urldecode($principal);
350
-		}, $principals);
351
-		$principals[] = $principalUri;
352
-
353
-		$fields = array_values($this->propertyMap);
354
-		$fields[] = 'a.id';
355
-		$fields[] = 'a.uri';
356
-		$fields[] = 'a.synctoken';
357
-		$fields[] = 'a.components';
358
-		$fields[] = 'a.principaluri';
359
-		$fields[] = 'a.transparent';
360
-		$fields[] = 's.access';
361
-		$query = $this->db->getQueryBuilder();
362
-		$query->select($fields)
363
-			->from('dav_shares', 's')
364
-			->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id'))
365
-			->where($query->expr()->in('s.principaluri', $query->createParameter('principaluri')))
366
-			->andWhere($query->expr()->eq('s.type', $query->createParameter('type')))
367
-			->setParameter('type', 'calendar')
368
-			->setParameter('principaluri', $principals, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);
369
-
370
-		$result	= $query->execute();
371
-
372
-		$readOnlyPropertyName = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only';
373
-		while ($row = $result->fetch()) {
374
-			$row['principaluri'] = (string) $row['principaluri'];
375
-			if ($row['principaluri'] === $principalUri) {
376
-				continue;
377
-			}
378
-
379
-			$readOnly = (int) $row['access'] === Backend::ACCESS_READ;
380
-			if (isset($calendars[$row['id']])) {
381
-				if ($readOnly) {
382
-					// New share can not have more permissions then the old one.
383
-					continue;
384
-				}
385
-				if (isset($calendars[$row['id']][$readOnlyPropertyName]) &&
386
-					$calendars[$row['id']][$readOnlyPropertyName] === 0) {
387
-					// Old share is already read-write, no more permissions can be gained
388
-					continue;
389
-				}
390
-			}
391
-
392
-			list(, $name) = Uri\split($row['principaluri']);
393
-			$uri = $row['uri'] . '_shared_by_' . $name;
394
-			$row['displayname'] = $row['displayname'] . ' (' . $this->getUserDisplayName($name) . ')';
395
-			$components = [];
396
-			if ($row['components']) {
397
-				$components = explode(',',$row['components']);
398
-			}
399
-			$calendar = [
400
-				'id' => $row['id'],
401
-				'uri' => $uri,
402
-				'principaluri' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
403
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
404
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
405
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
406
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp('transparent'),
407
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
408
-				$readOnlyPropertyName => $readOnly,
409
-			];
410
-
411
-			foreach ($this->propertyMap as $xmlName => $dbName) {
412
-				$calendar[$xmlName] = $row[$dbName];
413
-			}
414
-
415
-			$this->addOwnerPrincipal($calendar);
416
-
417
-			$calendars[$calendar['id']] = $calendar;
418
-		}
419
-		$result->closeCursor();
420
-
421
-		return array_values($calendars);
422
-	}
423
-
424
-	/**
425
-	 * @param $principalUri
426
-	 * @return array
427
-	 */
428
-	public function getUsersOwnCalendars($principalUri) {
429
-		$principalUri = $this->convertPrincipal($principalUri, true);
430
-		$fields = array_values($this->propertyMap);
431
-		$fields[] = 'id';
432
-		$fields[] = 'uri';
433
-		$fields[] = 'synctoken';
434
-		$fields[] = 'components';
435
-		$fields[] = 'principaluri';
436
-		$fields[] = 'transparent';
437
-		// Making fields a comma-delimited list
438
-		$query = $this->db->getQueryBuilder();
439
-		$query->select($fields)->from('calendars')
440
-			->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
441
-			->orderBy('calendarorder', 'ASC');
442
-		$stmt = $query->execute();
443
-		$calendars = [];
444
-		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
445
-			$row['principaluri'] = (string) $row['principaluri'];
446
-			$components = [];
447
-			if ($row['components']) {
448
-				$components = explode(',',$row['components']);
449
-			}
450
-			$calendar = [
451
-				'id' => $row['id'],
452
-				'uri' => $row['uri'],
453
-				'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
454
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
455
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
456
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
457
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
458
-			];
459
-			foreach ($this->propertyMap as $xmlName => $dbName) {
460
-				$calendar[$xmlName] = $row[$dbName];
461
-			}
462
-
463
-			$this->addOwnerPrincipal($calendar);
464
-
465
-			if (!isset($calendars[$calendar['id']])) {
466
-				$calendars[$calendar['id']] = $calendar;
467
-			}
468
-		}
469
-		$stmt->closeCursor();
470
-		return array_values($calendars);
471
-	}
472
-
473
-
474
-	/**
475
-	 * @param $uid
476
-	 * @return string
477
-	 */
478
-	private function getUserDisplayName($uid) {
479
-		if (!isset($this->userDisplayNames[$uid])) {
480
-			$user = $this->userManager->get($uid);
481
-
482
-			if ($user instanceof IUser) {
483
-				$this->userDisplayNames[$uid] = $user->getDisplayName();
484
-			} else {
485
-				$this->userDisplayNames[$uid] = $uid;
486
-			}
487
-		}
488
-
489
-		return $this->userDisplayNames[$uid];
490
-	}
491
-
492
-	/**
493
-	 * @return array
494
-	 */
495
-	public function getPublicCalendars() {
496
-		$fields = array_values($this->propertyMap);
497
-		$fields[] = 'a.id';
498
-		$fields[] = 'a.uri';
499
-		$fields[] = 'a.synctoken';
500
-		$fields[] = 'a.components';
501
-		$fields[] = 'a.principaluri';
502
-		$fields[] = 'a.transparent';
503
-		$fields[] = 's.access';
504
-		$fields[] = 's.publicuri';
505
-		$calendars = [];
506
-		$query = $this->db->getQueryBuilder();
507
-		$result = $query->select($fields)
508
-			->from('dav_shares', 's')
509
-			->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id'))
510
-			->where($query->expr()->in('s.access', $query->createNamedParameter(self::ACCESS_PUBLIC)))
511
-			->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar')))
512
-			->execute();
513
-
514
-		while ($row = $result->fetch()) {
515
-			$row['principaluri'] = (string) $row['principaluri'];
516
-			list(, $name) = Uri\split($row['principaluri']);
517
-			$row['displayname'] = $row['displayname'] . "($name)";
518
-			$components = [];
519
-			if ($row['components']) {
520
-				$components = explode(',',$row['components']);
521
-			}
522
-			$calendar = [
523
-				'id' => $row['id'],
524
-				'uri' => $row['publicuri'],
525
-				'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
526
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
527
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
528
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
529
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
530
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], $this->legacyEndpoint),
531
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ,
532
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
533
-			];
534
-
535
-			foreach ($this->propertyMap as $xmlName => $dbName) {
536
-				$calendar[$xmlName] = $row[$dbName];
537
-			}
538
-
539
-			$this->addOwnerPrincipal($calendar);
540
-
541
-			if (!isset($calendars[$calendar['id']])) {
542
-				$calendars[$calendar['id']] = $calendar;
543
-			}
544
-		}
545
-		$result->closeCursor();
546
-
547
-		return array_values($calendars);
548
-	}
549
-
550
-	/**
551
-	 * @param string $uri
552
-	 * @return array
553
-	 * @throws NotFound
554
-	 */
555
-	public function getPublicCalendar($uri) {
556
-		$fields = array_values($this->propertyMap);
557
-		$fields[] = 'a.id';
558
-		$fields[] = 'a.uri';
559
-		$fields[] = 'a.synctoken';
560
-		$fields[] = 'a.components';
561
-		$fields[] = 'a.principaluri';
562
-		$fields[] = 'a.transparent';
563
-		$fields[] = 's.access';
564
-		$fields[] = 's.publicuri';
565
-		$query = $this->db->getQueryBuilder();
566
-		$result = $query->select($fields)
567
-			->from('dav_shares', 's')
568
-			->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id'))
569
-			->where($query->expr()->in('s.access', $query->createNamedParameter(self::ACCESS_PUBLIC)))
570
-			->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar')))
571
-			->andWhere($query->expr()->eq('s.publicuri', $query->createNamedParameter($uri)))
572
-			->execute();
573
-
574
-		$row = $result->fetch(\PDO::FETCH_ASSOC);
575
-
576
-		$result->closeCursor();
577
-
578
-		if ($row === false) {
579
-			throw new NotFound('Node with name \'' . $uri . '\' could not be found');
580
-		}
581
-
582
-		$row['principaluri'] = (string) $row['principaluri'];
583
-		list(, $name) = Uri\split($row['principaluri']);
584
-		$row['displayname'] = $row['displayname'] . ' ' . "($name)";
585
-		$components = [];
586
-		if ($row['components']) {
587
-			$components = explode(',',$row['components']);
588
-		}
589
-		$calendar = [
590
-			'id' => $row['id'],
591
-			'uri' => $row['publicuri'],
592
-			'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
593
-			'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
594
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
595
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
596
-			'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
597
-			'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
598
-			'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ,
599
-			'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
600
-		];
601
-
602
-		foreach ($this->propertyMap as $xmlName => $dbName) {
603
-			$calendar[$xmlName] = $row[$dbName];
604
-		}
605
-
606
-		$this->addOwnerPrincipal($calendar);
607
-
608
-		return $calendar;
609
-	}
610
-
611
-	/**
612
-	 * @param string $principal
613
-	 * @param string $uri
614
-	 * @return array|null
615
-	 */
616
-	public function getCalendarByUri($principal, $uri) {
617
-		$fields = array_values($this->propertyMap);
618
-		$fields[] = 'id';
619
-		$fields[] = 'uri';
620
-		$fields[] = 'synctoken';
621
-		$fields[] = 'components';
622
-		$fields[] = 'principaluri';
623
-		$fields[] = 'transparent';
624
-
625
-		// Making fields a comma-delimited list
626
-		$query = $this->db->getQueryBuilder();
627
-		$query->select($fields)->from('calendars')
628
-			->where($query->expr()->eq('uri', $query->createNamedParameter($uri)))
629
-			->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($principal)))
630
-			->setMaxResults(1);
631
-		$stmt = $query->execute();
632
-
633
-		$row = $stmt->fetch(\PDO::FETCH_ASSOC);
634
-		$stmt->closeCursor();
635
-		if ($row === false) {
636
-			return null;
637
-		}
638
-
639
-		$row['principaluri'] = (string) $row['principaluri'];
640
-		$components = [];
641
-		if ($row['components']) {
642
-			$components = explode(',',$row['components']);
643
-		}
644
-
645
-		$calendar = [
646
-			'id' => $row['id'],
647
-			'uri' => $row['uri'],
648
-			'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
649
-			'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
650
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
651
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
652
-			'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
653
-		];
654
-
655
-		foreach ($this->propertyMap as $xmlName => $dbName) {
656
-			$calendar[$xmlName] = $row[$dbName];
657
-		}
658
-
659
-		$this->addOwnerPrincipal($calendar);
660
-
661
-		return $calendar;
662
-	}
663
-
664
-	/**
665
-	 * @param $calendarId
666
-	 * @return array|null
667
-	 */
668
-	public function getCalendarById($calendarId) {
669
-		$fields = array_values($this->propertyMap);
670
-		$fields[] = 'id';
671
-		$fields[] = 'uri';
672
-		$fields[] = 'synctoken';
673
-		$fields[] = 'components';
674
-		$fields[] = 'principaluri';
675
-		$fields[] = 'transparent';
676
-
677
-		// Making fields a comma-delimited list
678
-		$query = $this->db->getQueryBuilder();
679
-		$query->select($fields)->from('calendars')
680
-			->where($query->expr()->eq('id', $query->createNamedParameter($calendarId)))
681
-			->setMaxResults(1);
682
-		$stmt = $query->execute();
683
-
684
-		$row = $stmt->fetch(\PDO::FETCH_ASSOC);
685
-		$stmt->closeCursor();
686
-		if ($row === false) {
687
-			return null;
688
-		}
689
-
690
-		$row['principaluri'] = (string) $row['principaluri'];
691
-		$components = [];
692
-		if ($row['components']) {
693
-			$components = explode(',',$row['components']);
694
-		}
695
-
696
-		$calendar = [
697
-			'id' => $row['id'],
698
-			'uri' => $row['uri'],
699
-			'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
700
-			'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
701
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
702
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
703
-			'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
704
-		];
705
-
706
-		foreach ($this->propertyMap as $xmlName => $dbName) {
707
-			$calendar[$xmlName] = $row[$dbName];
708
-		}
709
-
710
-		$this->addOwnerPrincipal($calendar);
711
-
712
-		return $calendar;
713
-	}
714
-
715
-	/**
716
-	 * @param $subscriptionId
717
-	 */
718
-	public function getSubscriptionById($subscriptionId) {
719
-		$fields = array_values($this->subscriptionPropertyMap);
720
-		$fields[] = 'id';
721
-		$fields[] = 'uri';
722
-		$fields[] = 'source';
723
-		$fields[] = 'synctoken';
724
-		$fields[] = 'principaluri';
725
-		$fields[] = 'lastmodified';
726
-
727
-		$query = $this->db->getQueryBuilder();
728
-		$query->select($fields)
729
-			->from('calendarsubscriptions')
730
-			->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId)))
731
-			->orderBy('calendarorder', 'asc');
732
-		$stmt = $query->execute();
733
-
734
-		$row = $stmt->fetch(\PDO::FETCH_ASSOC);
735
-		$stmt->closeCursor();
736
-		if ($row === false) {
737
-			return null;
738
-		}
739
-
740
-		$row['principaluri'] = (string) $row['principaluri'];
741
-		$subscription = [
742
-			'id' => $row['id'],
743
-			'uri' => $row['uri'],
744
-			'principaluri' => $row['principaluri'],
745
-			'source' => $row['source'],
746
-			'lastmodified' => $row['lastmodified'],
747
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
748
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
749
-		];
750
-
751
-		foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
752
-			if (!is_null($row[$dbName])) {
753
-				$subscription[$xmlName] = $row[$dbName];
754
-			}
755
-		}
756
-
757
-		return $subscription;
758
-	}
759
-
760
-	/**
761
-	 * Creates a new calendar for a principal.
762
-	 *
763
-	 * If the creation was a success, an id must be returned that can be used to reference
764
-	 * this calendar in other methods, such as updateCalendar.
765
-	 *
766
-	 * @param string $principalUri
767
-	 * @param string $calendarUri
768
-	 * @param array $properties
769
-	 * @return int
770
-	 */
771
-	public function createCalendar($principalUri, $calendarUri, array $properties) {
772
-		$values = [
773
-			'principaluri' => $this->convertPrincipal($principalUri, true),
774
-			'uri' => $calendarUri,
775
-			'synctoken' => 1,
776
-			'transparent' => 0,
777
-			'components' => 'VEVENT,VTODO',
778
-			'displayname' => $calendarUri
779
-		];
780
-
781
-		// Default value
782
-		$sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
783
-		if (isset($properties[$sccs])) {
784
-			if (!($properties[$sccs] instanceof SupportedCalendarComponentSet)) {
785
-				throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Property\SupportedCalendarComponentSet');
786
-			}
787
-			$values['components'] = implode(',',$properties[$sccs]->getValue());
788
-		} elseif (isset($properties['components'])) {
789
-			// Allow to provide components internally without having
790
-			// to create a SupportedCalendarComponentSet object
791
-			$values['components'] = $properties['components'];
792
-		}
793
-
794
-		$transp = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
795
-		if (isset($properties[$transp])) {
796
-			$values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent');
797
-		}
798
-
799
-		foreach ($this->propertyMap as $xmlName => $dbName) {
800
-			if (isset($properties[$xmlName])) {
801
-				$values[$dbName] = $properties[$xmlName];
802
-			}
803
-		}
804
-
805
-		$query = $this->db->getQueryBuilder();
806
-		$query->insert('calendars');
807
-		foreach ($values as $column => $value) {
808
-			$query->setValue($column, $query->createNamedParameter($value));
809
-		}
810
-		$query->execute();
811
-		$calendarId = $query->getLastInsertId();
812
-
813
-		$calendarData = $this->getCalendarById($calendarId);
814
-		$this->dispatcher->dispatchTyped(new CalendarCreatedEvent((int)$calendarId, $calendarData));
815
-		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', new GenericEvent(
816
-			'\OCA\DAV\CalDAV\CalDavBackend::createCalendar',
817
-			[
818
-				'calendarId' => $calendarId,
819
-				'calendarData' => $calendarData,
820
-			]));
821
-
822
-		return $calendarId;
823
-	}
824
-
825
-	/**
826
-	 * Updates properties for a calendar.
827
-	 *
828
-	 * The list of mutations is stored in a Sabre\DAV\PropPatch object.
829
-	 * To do the actual updates, you must tell this object which properties
830
-	 * you're going to process with the handle() method.
831
-	 *
832
-	 * Calling the handle method is like telling the PropPatch object "I
833
-	 * promise I can handle updating this property".
834
-	 *
835
-	 * Read the PropPatch documentation for more info and examples.
836
-	 *
837
-	 * @param mixed $calendarId
838
-	 * @param PropPatch $propPatch
839
-	 * @return void
840
-	 */
841
-	public function updateCalendar($calendarId, PropPatch $propPatch) {
842
-		$supportedProperties = array_keys($this->propertyMap);
843
-		$supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
844
-
845
-		$propPatch->handle($supportedProperties, function ($mutations) use ($calendarId) {
846
-			$newValues = [];
847
-			foreach ($mutations as $propertyName => $propertyValue) {
848
-				switch ($propertyName) {
849
-					case '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp':
850
-						$fieldName = 'transparent';
851
-						$newValues[$fieldName] = (int) ($propertyValue->getValue() === 'transparent');
852
-						break;
853
-					default:
854
-						$fieldName = $this->propertyMap[$propertyName];
855
-						$newValues[$fieldName] = $propertyValue;
856
-						break;
857
-				}
858
-			}
859
-			$query = $this->db->getQueryBuilder();
860
-			$query->update('calendars');
861
-			foreach ($newValues as $fieldName => $value) {
862
-				$query->set($fieldName, $query->createNamedParameter($value));
863
-			}
864
-			$query->where($query->expr()->eq('id', $query->createNamedParameter($calendarId)));
865
-			$query->execute();
866
-
867
-			$this->addChange($calendarId, "", 2);
868
-
869
-			$calendarData = $this->getCalendarById($calendarId);
870
-			$shares = $this->getShares($calendarId);
871
-			$this->dispatcher->dispatchTyped(new CalendarUpdatedEvent((int)$calendarId, $calendarData, $shares, $mutations));
872
-			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', new GenericEvent(
873
-				'\OCA\DAV\CalDAV\CalDavBackend::updateCalendar',
874
-				[
875
-					'calendarId' => $calendarId,
876
-					'calendarData' => $calendarData,
877
-					'shares' => $shares,
878
-					'propertyMutations' => $mutations,
879
-				]));
880
-
881
-			return true;
882
-		});
883
-	}
884
-
885
-	/**
886
-	 * Delete a calendar and all it's objects
887
-	 *
888
-	 * @param mixed $calendarId
889
-	 * @return void
890
-	 */
891
-	public function deleteCalendar($calendarId) {
892
-		$calendarData = $this->getCalendarById($calendarId);
893
-		$shares = $this->getShares($calendarId);
894
-
895
-		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', new GenericEvent(
896
-			'\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar',
897
-			[
898
-				'calendarId' => $calendarId,
899
-				'calendarData' => $calendarData,
900
-				'shares' => $shares,
901
-			]));
902
-
903
-		$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `calendartype` = ?');
904
-		$stmt->execute([$calendarId, self::CALENDAR_TYPE_CALENDAR]);
905
-
906
-		$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendars` WHERE `id` = ?');
907
-		$stmt->execute([$calendarId]);
908
-
909
-		$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarchanges` WHERE `calendarid` = ? AND `calendartype` = ?');
910
-		$stmt->execute([$calendarId, self::CALENDAR_TYPE_CALENDAR]);
911
-
912
-		$this->calendarSharingBackend->deleteAllShares($calendarId);
913
-
914
-		$query = $this->db->getQueryBuilder();
915
-		$query->delete($this->dbObjectPropertiesTable)
916
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
917
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)))
918
-			->execute();
919
-
920
-		if ($calendarData) {
921
-			$this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int)$calendarId, $calendarData, $shares));
922
-		}
923
-	}
924
-
925
-	/**
926
-	 * Delete all of an user's shares
927
-	 *
928
-	 * @param string $principaluri
929
-	 * @return void
930
-	 */
931
-	public function deleteAllSharesByUser($principaluri) {
932
-		$this->calendarSharingBackend->deleteAllSharesByUser($principaluri);
933
-	}
934
-
935
-	/**
936
-	 * Returns all calendar objects within a calendar.
937
-	 *
938
-	 * Every item contains an array with the following keys:
939
-	 *   * calendardata - The iCalendar-compatible calendar data
940
-	 *   * uri - a unique key which will be used to construct the uri. This can
941
-	 *     be any arbitrary string, but making sure it ends with '.ics' is a
942
-	 *     good idea. This is only the basename, or filename, not the full
943
-	 *     path.
944
-	 *   * lastmodified - a timestamp of the last modification time
945
-	 *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
946
-	 *   '"abcdef"')
947
-	 *   * size - The size of the calendar objects, in bytes.
948
-	 *   * component - optional, a string containing the type of object, such
949
-	 *     as 'vevent' or 'vtodo'. If specified, this will be used to populate
950
-	 *     the Content-Type header.
951
-	 *
952
-	 * Note that the etag is optional, but it's highly encouraged to return for
953
-	 * speed reasons.
954
-	 *
955
-	 * The calendardata is also optional. If it's not returned
956
-	 * 'getCalendarObject' will be called later, which *is* expected to return
957
-	 * calendardata.
958
-	 *
959
-	 * If neither etag or size are specified, the calendardata will be
960
-	 * used/fetched to determine these numbers. If both are specified the
961
-	 * amount of times this is needed is reduced by a great degree.
962
-	 *
963
-	 * @param mixed $calendarId
964
-	 * @param int $calendarType
965
-	 * @return array
966
-	 */
967
-	public function getCalendarObjects($calendarId, $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
968
-		$query = $this->db->getQueryBuilder();
969
-		$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification'])
970
-			->from('calendarobjects')
971
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
972
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
973
-		$stmt = $query->execute();
974
-
975
-		$result = [];
976
-		foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
977
-			$result[] = [
978
-				'id' => $row['id'],
979
-				'uri' => $row['uri'],
980
-				'lastmodified' => $row['lastmodified'],
981
-				'etag' => '"' . $row['etag'] . '"',
982
-				'calendarid' => $row['calendarid'],
983
-				'size' => (int)$row['size'],
984
-				'component' => strtolower($row['componenttype']),
985
-				'classification' => (int)$row['classification']
986
-			];
987
-		}
988
-		$stmt->closeCursor();
989
-
990
-		return $result;
991
-	}
992
-
993
-	/**
994
-	 * Returns information from a single calendar object, based on it's object
995
-	 * uri.
996
-	 *
997
-	 * The object uri is only the basename, or filename and not a full path.
998
-	 *
999
-	 * The returned array must have the same keys as getCalendarObjects. The
1000
-	 * 'calendardata' object is required here though, while it's not required
1001
-	 * for getCalendarObjects.
1002
-	 *
1003
-	 * This method must return null if the object did not exist.
1004
-	 *
1005
-	 * @param mixed $calendarId
1006
-	 * @param string $objectUri
1007
-	 * @param int $calendarType
1008
-	 * @return array|null
1009
-	 */
1010
-	public function getCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1011
-		$query = $this->db->getQueryBuilder();
1012
-		$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
1013
-			->from('calendarobjects')
1014
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1015
-			->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
1016
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
1017
-		$stmt = $query->execute();
1018
-		$row = $stmt->fetch(\PDO::FETCH_ASSOC);
1019
-		$stmt->closeCursor();
1020
-
1021
-		if (!$row) {
1022
-			return null;
1023
-		}
1024
-
1025
-		return [
1026
-			'id' => $row['id'],
1027
-			'uri' => $row['uri'],
1028
-			'lastmodified' => $row['lastmodified'],
1029
-			'etag' => '"' . $row['etag'] . '"',
1030
-			'calendarid' => $row['calendarid'],
1031
-			'size' => (int)$row['size'],
1032
-			'calendardata' => $this->readBlob($row['calendardata']),
1033
-			'component' => strtolower($row['componenttype']),
1034
-			'classification' => (int)$row['classification']
1035
-		];
1036
-	}
1037
-
1038
-	/**
1039
-	 * Returns a list of calendar objects.
1040
-	 *
1041
-	 * This method should work identical to getCalendarObject, but instead
1042
-	 * return all the calendar objects in the list as an array.
1043
-	 *
1044
-	 * If the backend supports this, it may allow for some speed-ups.
1045
-	 *
1046
-	 * @param mixed $calendarId
1047
-	 * @param string[] $uris
1048
-	 * @param int $calendarType
1049
-	 * @return array
1050
-	 */
1051
-	public function getMultipleCalendarObjects($calendarId, array $uris, $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
1052
-		if (empty($uris)) {
1053
-			return [];
1054
-		}
1055
-
1056
-		$chunks = array_chunk($uris, 100);
1057
-		$objects = [];
1058
-
1059
-		$query = $this->db->getQueryBuilder();
1060
-		$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
1061
-			->from('calendarobjects')
1062
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1063
-			->andWhere($query->expr()->in('uri', $query->createParameter('uri')))
1064
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
1065
-
1066
-		foreach ($chunks as $uris) {
1067
-			$query->setParameter('uri', $uris, IQueryBuilder::PARAM_STR_ARRAY);
1068
-			$result = $query->execute();
1069
-
1070
-			while ($row = $result->fetch()) {
1071
-				$objects[] = [
1072
-					'id' => $row['id'],
1073
-					'uri' => $row['uri'],
1074
-					'lastmodified' => $row['lastmodified'],
1075
-					'etag' => '"' . $row['etag'] . '"',
1076
-					'calendarid' => $row['calendarid'],
1077
-					'size' => (int)$row['size'],
1078
-					'calendardata' => $this->readBlob($row['calendardata']),
1079
-					'component' => strtolower($row['componenttype']),
1080
-					'classification' => (int)$row['classification']
1081
-				];
1082
-			}
1083
-			$result->closeCursor();
1084
-		}
1085
-
1086
-		return $objects;
1087
-	}
1088
-
1089
-	/**
1090
-	 * Creates a new calendar object.
1091
-	 *
1092
-	 * The object uri is only the basename, or filename and not a full path.
1093
-	 *
1094
-	 * It is possible return an etag from this function, which will be used in
1095
-	 * the response to this PUT request. Note that the ETag must be surrounded
1096
-	 * by double-quotes.
1097
-	 *
1098
-	 * However, you should only really return this ETag if you don't mangle the
1099
-	 * calendar-data. If the result of a subsequent GET to this object is not
1100
-	 * the exact same as this request body, you should omit the ETag.
1101
-	 *
1102
-	 * @param mixed $calendarId
1103
-	 * @param string $objectUri
1104
-	 * @param string $calendarData
1105
-	 * @param int $calendarType
1106
-	 * @return string
1107
-	 */
1108
-	public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1109
-		$extraData = $this->getDenormalizedData($calendarData);
1110
-
1111
-		$q = $this->db->getQueryBuilder();
1112
-		$q->select($q->func()->count('*'))
1113
-			->from('calendarobjects')
1114
-			->where($q->expr()->eq('calendarid', $q->createNamedParameter($calendarId)))
1115
-			->andWhere($q->expr()->eq('uid', $q->createNamedParameter($extraData['uid'])))
1116
-			->andWhere($q->expr()->eq('calendartype', $q->createNamedParameter($calendarType)));
1117
-
1118
-		$result = $q->execute();
1119
-		$count = (int) $result->fetchColumn();
1120
-		$result->closeCursor();
1121
-
1122
-		if ($count !== 0) {
1123
-			throw new \Sabre\DAV\Exception\BadRequest('Calendar object with uid already exists in this calendar collection.');
1124
-		}
1125
-
1126
-		$query = $this->db->getQueryBuilder();
1127
-		$query->insert('calendarobjects')
1128
-			->values([
1129
-				'calendarid' => $query->createNamedParameter($calendarId),
1130
-				'uri' => $query->createNamedParameter($objectUri),
1131
-				'calendardata' => $query->createNamedParameter($calendarData, IQueryBuilder::PARAM_LOB),
1132
-				'lastmodified' => $query->createNamedParameter(time()),
1133
-				'etag' => $query->createNamedParameter($extraData['etag']),
1134
-				'size' => $query->createNamedParameter($extraData['size']),
1135
-				'componenttype' => $query->createNamedParameter($extraData['componentType']),
1136
-				'firstoccurence' => $query->createNamedParameter($extraData['firstOccurence']),
1137
-				'lastoccurence' => $query->createNamedParameter($extraData['lastOccurence']),
1138
-				'classification' => $query->createNamedParameter($extraData['classification']),
1139
-				'uid' => $query->createNamedParameter($extraData['uid']),
1140
-				'calendartype' => $query->createNamedParameter($calendarType),
1141
-			])
1142
-			->execute();
1143
-
1144
-		$this->updateProperties($calendarId, $objectUri, $calendarData, $calendarType);
1145
-		$this->addChange($calendarId, $objectUri, 1, $calendarType);
1146
-
1147
-		$objectRow = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
1148
-		if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
1149
-			$calendarRow = $this->getCalendarById($calendarId);
1150
-			$shares = $this->getShares($calendarId);
1151
-
1152
-			$this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
1153
-			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', new GenericEvent(
1154
-				'\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject',
1155
-				[
1156
-					'calendarId' => $calendarId,
1157
-					'calendarData' => $calendarRow,
1158
-					'shares' => $shares,
1159
-					'objectData' => $objectRow,
1160
-				]
1161
-			));
1162
-		} else {
1163
-			$subscriptionRow = $this->getSubscriptionById($calendarId);
1164
-
1165
-			$this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
1166
-			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject', new GenericEvent(
1167
-				'\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject',
1168
-				[
1169
-					'subscriptionId' => $calendarId,
1170
-					'calendarData' => $subscriptionRow,
1171
-					'shares' => [],
1172
-					'objectData' => $objectRow,
1173
-				]
1174
-			));
1175
-		}
1176
-
1177
-		return '"' . $extraData['etag'] . '"';
1178
-	}
1179
-
1180
-	/**
1181
-	 * Updates an existing calendarobject, based on it's uri.
1182
-	 *
1183
-	 * The object uri is only the basename, or filename and not a full path.
1184
-	 *
1185
-	 * It is possible return an etag from this function, which will be used in
1186
-	 * the response to this PUT request. Note that the ETag must be surrounded
1187
-	 * by double-quotes.
1188
-	 *
1189
-	 * However, you should only really return this ETag if you don't mangle the
1190
-	 * calendar-data. If the result of a subsequent GET to this object is not
1191
-	 * the exact same as this request body, you should omit the ETag.
1192
-	 *
1193
-	 * @param mixed $calendarId
1194
-	 * @param string $objectUri
1195
-	 * @param string $calendarData
1196
-	 * @param int $calendarType
1197
-	 * @return string
1198
-	 */
1199
-	public function updateCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1200
-		$extraData = $this->getDenormalizedData($calendarData);
1201
-		$query = $this->db->getQueryBuilder();
1202
-		$query->update('calendarobjects')
1203
-				->set('calendardata', $query->createNamedParameter($calendarData, IQueryBuilder::PARAM_LOB))
1204
-				->set('lastmodified', $query->createNamedParameter(time()))
1205
-				->set('etag', $query->createNamedParameter($extraData['etag']))
1206
-				->set('size', $query->createNamedParameter($extraData['size']))
1207
-				->set('componenttype', $query->createNamedParameter($extraData['componentType']))
1208
-				->set('firstoccurence', $query->createNamedParameter($extraData['firstOccurence']))
1209
-				->set('lastoccurence', $query->createNamedParameter($extraData['lastOccurence']))
1210
-				->set('classification', $query->createNamedParameter($extraData['classification']))
1211
-				->set('uid', $query->createNamedParameter($extraData['uid']))
1212
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1213
-			->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
1214
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
1215
-			->execute();
1216
-
1217
-		$this->updateProperties($calendarId, $objectUri, $calendarData, $calendarType);
1218
-		$this->addChange($calendarId, $objectUri, 2, $calendarType);
1219
-
1220
-		$objectRow = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
1221
-		if (is_array($objectRow)) {
1222
-			if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
1223
-				$calendarRow = $this->getCalendarById($calendarId);
1224
-				$shares = $this->getShares($calendarId);
1225
-
1226
-				$this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
1227
-				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', new GenericEvent(
1228
-					'\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject',
1229
-					[
1230
-						'calendarId' => $calendarId,
1231
-						'calendarData' => $calendarRow,
1232
-						'shares' => $shares,
1233
-						'objectData' => $objectRow,
1234
-					]
1235
-				));
1236
-			} else {
1237
-				$subscriptionRow = $this->getSubscriptionById($calendarId);
1238
-
1239
-				$this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
1240
-				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject', new GenericEvent(
1241
-					'\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject',
1242
-					[
1243
-						'subscriptionId' => $calendarId,
1244
-						'calendarData' => $subscriptionRow,
1245
-						'shares' => [],
1246
-						'objectData' => $objectRow,
1247
-					]
1248
-				));
1249
-			}
1250
-		}
1251
-
1252
-		return '"' . $extraData['etag'] . '"';
1253
-	}
1254
-
1255
-	/**
1256
-	 * @param int $calendarObjectId
1257
-	 * @param int $classification
1258
-	 */
1259
-	public function setClassification($calendarObjectId, $classification) {
1260
-		if (!in_array($classification, [
1261
-			self::CLASSIFICATION_PUBLIC, self::CLASSIFICATION_PRIVATE, self::CLASSIFICATION_CONFIDENTIAL
1262
-		])) {
1263
-			throw new \InvalidArgumentException();
1264
-		}
1265
-		$query = $this->db->getQueryBuilder();
1266
-		$query->update('calendarobjects')
1267
-			->set('classification', $query->createNamedParameter($classification))
1268
-			->where($query->expr()->eq('id', $query->createNamedParameter($calendarObjectId)))
1269
-			->execute();
1270
-	}
1271
-
1272
-	/**
1273
-	 * Deletes an existing calendar object.
1274
-	 *
1275
-	 * The object uri is only the basename, or filename and not a full path.
1276
-	 *
1277
-	 * @param mixed $calendarId
1278
-	 * @param string $objectUri
1279
-	 * @param int $calendarType
1280
-	 * @return void
1281
-	 */
1282
-	public function deleteCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1283
-		$data = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
1284
-		if (is_array($data)) {
1285
-			if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
1286
-				$calendarRow = $this->getCalendarById($calendarId);
1287
-				$shares = $this->getShares($calendarId);
1288
-
1289
-				$this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent((int)$calendarId, $calendarRow, $shares, $data));
1290
-				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', new GenericEvent(
1291
-					'\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject',
1292
-					[
1293
-						'calendarId' => $calendarId,
1294
-						'calendarData' => $calendarRow,
1295
-						'shares' => $shares,
1296
-						'objectData' => $data,
1297
-					]
1298
-				));
1299
-			} else {
1300
-				$subscriptionRow = $this->getSubscriptionById($calendarId);
1301
-
1302
-				$this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent((int)$calendarId, $subscriptionRow, [], $data));
1303
-				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject', new GenericEvent(
1304
-					'\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject',
1305
-					[
1306
-						'subscriptionId' => $calendarId,
1307
-						'calendarData' => $subscriptionRow,
1308
-						'shares' => [],
1309
-						'objectData' => $data,
1310
-					]
1311
-				));
1312
-			}
1313
-		}
1314
-
1315
-		$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `uri` = ? AND `calendartype` = ?');
1316
-		$stmt->execute([$calendarId, $objectUri, $calendarType]);
1317
-
1318
-		if (is_array($data)) {
1319
-			$this->purgeProperties($calendarId, $data['id'], $calendarType);
1320
-		}
1321
-
1322
-		$this->addChange($calendarId, $objectUri, 3, $calendarType);
1323
-	}
1324
-
1325
-	/**
1326
-	 * Performs a calendar-query on the contents of this calendar.
1327
-	 *
1328
-	 * The calendar-query is defined in RFC4791 : CalDAV. Using the
1329
-	 * calendar-query it is possible for a client to request a specific set of
1330
-	 * object, based on contents of iCalendar properties, date-ranges and
1331
-	 * iCalendar component types (VTODO, VEVENT).
1332
-	 *
1333
-	 * This method should just return a list of (relative) urls that match this
1334
-	 * query.
1335
-	 *
1336
-	 * The list of filters are specified as an array. The exact array is
1337
-	 * documented by Sabre\CalDAV\CalendarQueryParser.
1338
-	 *
1339
-	 * Note that it is extremely likely that getCalendarObject for every path
1340
-	 * returned from this method will be called almost immediately after. You
1341
-	 * may want to anticipate this to speed up these requests.
1342
-	 *
1343
-	 * This method provides a default implementation, which parses *all* the
1344
-	 * iCalendar objects in the specified calendar.
1345
-	 *
1346
-	 * This default may well be good enough for personal use, and calendars
1347
-	 * that aren't very large. But if you anticipate high usage, big calendars
1348
-	 * or high loads, you are strongly advised to optimize certain paths.
1349
-	 *
1350
-	 * The best way to do so is override this method and to optimize
1351
-	 * specifically for 'common filters'.
1352
-	 *
1353
-	 * Requests that are extremely common are:
1354
-	 *   * requests for just VEVENTS
1355
-	 *   * requests for just VTODO
1356
-	 *   * requests with a time-range-filter on either VEVENT or VTODO.
1357
-	 *
1358
-	 * ..and combinations of these requests. It may not be worth it to try to
1359
-	 * handle every possible situation and just rely on the (relatively
1360
-	 * easy to use) CalendarQueryValidator to handle the rest.
1361
-	 *
1362
-	 * Note that especially time-range-filters may be difficult to parse. A
1363
-	 * time-range filter specified on a VEVENT must for instance also handle
1364
-	 * recurrence rules correctly.
1365
-	 * A good example of how to interprete all these filters can also simply
1366
-	 * be found in Sabre\CalDAV\CalendarQueryFilter. This class is as correct
1367
-	 * as possible, so it gives you a good idea on what type of stuff you need
1368
-	 * to think of.
1369
-	 *
1370
-	 * @param mixed $calendarId
1371
-	 * @param array $filters
1372
-	 * @param int $calendarType
1373
-	 * @return array
1374
-	 */
1375
-	public function calendarQuery($calendarId, array $filters, $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
1376
-		$componentType = null;
1377
-		$requirePostFilter = true;
1378
-		$timeRange = null;
1379
-
1380
-		// if no filters were specified, we don't need to filter after a query
1381
-		if (!$filters['prop-filters'] && !$filters['comp-filters']) {
1382
-			$requirePostFilter = false;
1383
-		}
1384
-
1385
-		// Figuring out if there's a component filter
1386
-		if (count($filters['comp-filters']) > 0 && !$filters['comp-filters'][0]['is-not-defined']) {
1387
-			$componentType = $filters['comp-filters'][0]['name'];
1388
-
1389
-			// Checking if we need post-filters
1390
-			if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['time-range'] && !$filters['comp-filters'][0]['prop-filters']) {
1391
-				$requirePostFilter = false;
1392
-			}
1393
-			// There was a time-range filter
1394
-			if ($componentType === 'VEVENT' && isset($filters['comp-filters'][0]['time-range']) && is_array($filters['comp-filters'][0]['time-range'])) {
1395
-				$timeRange = $filters['comp-filters'][0]['time-range'];
1396
-
1397
-				// If start time OR the end time is not specified, we can do a
1398
-				// 100% accurate mysql query.
1399
-				if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && (!$timeRange['start'] || !$timeRange['end'])) {
1400
-					$requirePostFilter = false;
1401
-				}
1402
-			}
1403
-		}
1404
-		$columns = ['uri'];
1405
-		if ($requirePostFilter) {
1406
-			$columns = ['uri', 'calendardata'];
1407
-		}
1408
-		$query = $this->db->getQueryBuilder();
1409
-		$query->select($columns)
1410
-			->from('calendarobjects')
1411
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1412
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
1413
-
1414
-		if ($componentType) {
1415
-			$query->andWhere($query->expr()->eq('componenttype', $query->createNamedParameter($componentType)));
1416
-		}
1417
-
1418
-		if ($timeRange && $timeRange['start']) {
1419
-			$query->andWhere($query->expr()->gt('lastoccurence', $query->createNamedParameter($timeRange['start']->getTimeStamp())));
1420
-		}
1421
-		if ($timeRange && $timeRange['end']) {
1422
-			$query->andWhere($query->expr()->lt('firstoccurence', $query->createNamedParameter($timeRange['end']->getTimeStamp())));
1423
-		}
1424
-
1425
-		$stmt = $query->execute();
1426
-
1427
-		$result = [];
1428
-		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1429
-			if ($requirePostFilter) {
1430
-				// validateFilterForObject will parse the calendar data
1431
-				// catch parsing errors
1432
-				try {
1433
-					$matches = $this->validateFilterForObject($row, $filters);
1434
-				} catch (ParseException $ex) {
1435
-					$this->logger->logException($ex, [
1436
-						'app' => 'dav',
1437
-						'message' => 'Caught parsing exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$calendarId.' uri:'.$row['uri']
1438
-					]);
1439
-					continue;
1440
-				} catch (InvalidDataException $ex) {
1441
-					$this->logger->logException($ex, [
1442
-						'app' => 'dav',
1443
-						'message' => 'Caught invalid data exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$calendarId.' uri:'.$row['uri']
1444
-					]);
1445
-					continue;
1446
-				}
1447
-
1448
-				if (!$matches) {
1449
-					continue;
1450
-				}
1451
-			}
1452
-			$result[] = $row['uri'];
1453
-		}
1454
-
1455
-		return $result;
1456
-	}
1457
-
1458
-	/**
1459
-	 * custom Nextcloud search extension for CalDAV
1460
-	 *
1461
-	 * TODO - this should optionally cover cached calendar objects as well
1462
-	 *
1463
-	 * @param string $principalUri
1464
-	 * @param array $filters
1465
-	 * @param integer|null $limit
1466
-	 * @param integer|null $offset
1467
-	 * @return array
1468
-	 */
1469
-	public function calendarSearch($principalUri, array $filters, $limit = null, $offset = null) {
1470
-		$calendars = $this->getCalendarsForUser($principalUri);
1471
-		$ownCalendars = [];
1472
-		$sharedCalendars = [];
1473
-
1474
-		$uriMapper = [];
1475
-
1476
-		foreach ($calendars as $calendar) {
1477
-			if ($calendar['{http://owncloud.org/ns}owner-principal'] === $principalUri) {
1478
-				$ownCalendars[] = $calendar['id'];
1479
-			} else {
1480
-				$sharedCalendars[] = $calendar['id'];
1481
-			}
1482
-			$uriMapper[$calendar['id']] = $calendar['uri'];
1483
-		}
1484
-		if (count($ownCalendars) === 0 && count($sharedCalendars) === 0) {
1485
-			return [];
1486
-		}
1487
-
1488
-		$query = $this->db->getQueryBuilder();
1489
-		// Calendar id expressions
1490
-		$calendarExpressions = [];
1491
-		foreach ($ownCalendars as $id) {
1492
-			$calendarExpressions[] = $query->expr()->andX(
1493
-				$query->expr()->eq('c.calendarid',
1494
-					$query->createNamedParameter($id)),
1495
-				$query->expr()->eq('c.calendartype',
1496
-						$query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1497
-		}
1498
-		foreach ($sharedCalendars as $id) {
1499
-			$calendarExpressions[] = $query->expr()->andX(
1500
-				$query->expr()->eq('c.calendarid',
1501
-					$query->createNamedParameter($id)),
1502
-				$query->expr()->eq('c.classification',
1503
-					$query->createNamedParameter(self::CLASSIFICATION_PUBLIC)),
1504
-				$query->expr()->eq('c.calendartype',
1505
-					$query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1506
-		}
1507
-
1508
-		if (count($calendarExpressions) === 1) {
1509
-			$calExpr = $calendarExpressions[0];
1510
-		} else {
1511
-			$calExpr = call_user_func_array([$query->expr(), 'orX'], $calendarExpressions);
1512
-		}
1513
-
1514
-		// Component expressions
1515
-		$compExpressions = [];
1516
-		foreach ($filters['comps'] as $comp) {
1517
-			$compExpressions[] = $query->expr()
1518
-				->eq('c.componenttype', $query->createNamedParameter($comp));
1519
-		}
1520
-
1521
-		if (count($compExpressions) === 1) {
1522
-			$compExpr = $compExpressions[0];
1523
-		} else {
1524
-			$compExpr = call_user_func_array([$query->expr(), 'orX'], $compExpressions);
1525
-		}
1526
-
1527
-		if (!isset($filters['props'])) {
1528
-			$filters['props'] = [];
1529
-		}
1530
-		if (!isset($filters['params'])) {
1531
-			$filters['params'] = [];
1532
-		}
1533
-
1534
-		$propParamExpressions = [];
1535
-		foreach ($filters['props'] as $prop) {
1536
-			$propParamExpressions[] = $query->expr()->andX(
1537
-				$query->expr()->eq('i.name', $query->createNamedParameter($prop)),
1538
-				$query->expr()->isNull('i.parameter')
1539
-			);
1540
-		}
1541
-		foreach ($filters['params'] as $param) {
1542
-			$propParamExpressions[] = $query->expr()->andX(
1543
-				$query->expr()->eq('i.name', $query->createNamedParameter($param['property'])),
1544
-				$query->expr()->eq('i.parameter', $query->createNamedParameter($param['parameter']))
1545
-			);
1546
-		}
1547
-
1548
-		if (count($propParamExpressions) === 1) {
1549
-			$propParamExpr = $propParamExpressions[0];
1550
-		} else {
1551
-			$propParamExpr = call_user_func_array([$query->expr(), 'orX'], $propParamExpressions);
1552
-		}
1553
-
1554
-		$query->select(['c.calendarid', 'c.uri'])
1555
-			->from($this->dbObjectPropertiesTable, 'i')
1556
-			->join('i', 'calendarobjects', 'c', $query->expr()->eq('i.objectid', 'c.id'))
1557
-			->where($calExpr)
1558
-			->andWhere($compExpr)
1559
-			->andWhere($propParamExpr)
1560
-			->andWhere($query->expr()->iLike('i.value',
1561
-				$query->createNamedParameter('%'.$this->db->escapeLikeParameter($filters['search-term']).'%')));
1562
-
1563
-		if ($offset) {
1564
-			$query->setFirstResult($offset);
1565
-		}
1566
-		if ($limit) {
1567
-			$query->setMaxResults($limit);
1568
-		}
1569
-
1570
-		$stmt = $query->execute();
1571
-
1572
-		$result = [];
1573
-		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1574
-			$path = $uriMapper[$row['calendarid']] . '/' . $row['uri'];
1575
-			if (!in_array($path, $result)) {
1576
-				$result[] = $path;
1577
-			}
1578
-		}
1579
-
1580
-		return $result;
1581
-	}
1582
-
1583
-	/**
1584
-	 * used for Nextcloud's calendar API
1585
-	 *
1586
-	 * @param array $calendarInfo
1587
-	 * @param string $pattern
1588
-	 * @param array $searchProperties
1589
-	 * @param array $options
1590
-	 * @param integer|null $limit
1591
-	 * @param integer|null $offset
1592
-	 *
1593
-	 * @return array
1594
-	 */
1595
-	public function search(array $calendarInfo, $pattern, array $searchProperties,
1596
-						   array $options, $limit, $offset) {
1597
-		$outerQuery = $this->db->getQueryBuilder();
1598
-		$innerQuery = $this->db->getQueryBuilder();
1599
-
1600
-		$innerQuery->selectDistinct('op.objectid')
1601
-			->from($this->dbObjectPropertiesTable, 'op')
1602
-			->andWhere($innerQuery->expr()->eq('op.calendarid',
1603
-				$outerQuery->createNamedParameter($calendarInfo['id'])))
1604
-			->andWhere($innerQuery->expr()->eq('op.calendartype',
1605
-				$outerQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1606
-
1607
-		// only return public items for shared calendars for now
1608
-		if ($calendarInfo['principaluri'] !== $calendarInfo['{http://owncloud.org/ns}owner-principal']) {
1609
-			$innerQuery->andWhere($innerQuery->expr()->eq('c.classification',
1610
-				$outerQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
1611
-		}
1612
-
1613
-		$or = $innerQuery->expr()->orX();
1614
-		foreach ($searchProperties as $searchProperty) {
1615
-			$or->add($innerQuery->expr()->eq('op.name',
1616
-				$outerQuery->createNamedParameter($searchProperty)));
1617
-		}
1618
-		$innerQuery->andWhere($or);
1619
-
1620
-		if ($pattern !== '') {
1621
-			$innerQuery->andWhere($innerQuery->expr()->iLike('op.value',
1622
-				$outerQuery->createNamedParameter('%' .
1623
-					$this->db->escapeLikeParameter($pattern) . '%')));
1624
-		}
1625
-
1626
-		$outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid', 'c.uri')
1627
-			->from('calendarobjects', 'c');
1628
-
1629
-		if (isset($options['timerange'])) {
1630
-			if (isset($options['timerange']['start']) && $options['timerange']['start'] instanceof DateTime) {
1631
-				$outerQuery->andWhere($outerQuery->expr()->gt('lastoccurence',
1632
-					$outerQuery->createNamedParameter($options['timerange']['start']->getTimeStamp())));
1633
-			}
1634
-			if (isset($options['timerange']['end']) && $options['timerange']['end'] instanceof DateTime) {
1635
-				$outerQuery->andWhere($outerQuery->expr()->lt('firstoccurence',
1636
-					$outerQuery->createNamedParameter($options['timerange']['end']->getTimeStamp())));
1637
-			}
1638
-		}
1639
-
1640
-		if (isset($options['types'])) {
1641
-			$or = $outerQuery->expr()->orX();
1642
-			foreach ($options['types'] as $type) {
1643
-				$or->add($outerQuery->expr()->eq('componenttype',
1644
-					$outerQuery->createNamedParameter($type)));
1645
-			}
1646
-			$outerQuery->andWhere($or);
1647
-		}
1648
-
1649
-		$outerQuery->andWhere($outerQuery->expr()->in('c.id',
1650
-			$outerQuery->createFunction($innerQuery->getSQL())));
1651
-
1652
-		if ($offset) {
1653
-			$outerQuery->setFirstResult($offset);
1654
-		}
1655
-		if ($limit) {
1656
-			$outerQuery->setMaxResults($limit);
1657
-		}
1658
-
1659
-		$result = $outerQuery->execute();
1660
-		$calendarObjects = $result->fetchAll();
1661
-
1662
-		return array_map(function ($o) {
1663
-			$calendarData = Reader::read($o['calendardata']);
1664
-			$comps = $calendarData->getComponents();
1665
-			$objects = [];
1666
-			$timezones = [];
1667
-			foreach ($comps as $comp) {
1668
-				if ($comp instanceof VTimeZone) {
1669
-					$timezones[] = $comp;
1670
-				} else {
1671
-					$objects[] = $comp;
1672
-				}
1673
-			}
1674
-
1675
-			return [
1676
-				'id' => $o['id'],
1677
-				'type' => $o['componenttype'],
1678
-				'uid' => $o['uid'],
1679
-				'uri' => $o['uri'],
1680
-				'objects' => array_map(function ($c) {
1681
-					return $this->transformSearchData($c);
1682
-				}, $objects),
1683
-				'timezones' => array_map(function ($c) {
1684
-					return $this->transformSearchData($c);
1685
-				}, $timezones),
1686
-			];
1687
-		}, $calendarObjects);
1688
-	}
1689
-
1690
-	/**
1691
-	 * @param Component $comp
1692
-	 * @return array
1693
-	 */
1694
-	private function transformSearchData(Component $comp) {
1695
-		$data = [];
1696
-		/** @var Component[] $subComponents */
1697
-		$subComponents = $comp->getComponents();
1698
-		/** @var Property[] $properties */
1699
-		$properties = array_filter($comp->children(), function ($c) {
1700
-			return $c instanceof Property;
1701
-		});
1702
-		$validationRules = $comp->getValidationRules();
1703
-
1704
-		foreach ($subComponents as $subComponent) {
1705
-			$name = $subComponent->name;
1706
-			if (!isset($data[$name])) {
1707
-				$data[$name] = [];
1708
-			}
1709
-			$data[$name][] = $this->transformSearchData($subComponent);
1710
-		}
1711
-
1712
-		foreach ($properties as $property) {
1713
-			$name = $property->name;
1714
-			if (!isset($validationRules[$name])) {
1715
-				$validationRules[$name] = '*';
1716
-			}
1717
-
1718
-			$rule = $validationRules[$property->name];
1719
-			if ($rule === '+' || $rule === '*') { // multiple
1720
-				if (!isset($data[$name])) {
1721
-					$data[$name] = [];
1722
-				}
1723
-
1724
-				$data[$name][] = $this->transformSearchProperty($property);
1725
-			} else { // once
1726
-				$data[$name] = $this->transformSearchProperty($property);
1727
-			}
1728
-		}
1729
-
1730
-		return $data;
1731
-	}
1732
-
1733
-	/**
1734
-	 * @param Property $prop
1735
-	 * @return array
1736
-	 */
1737
-	private function transformSearchProperty(Property $prop) {
1738
-		// No need to check Date, as it extends DateTime
1739
-		if ($prop instanceof Property\ICalendar\DateTime) {
1740
-			$value = $prop->getDateTime();
1741
-		} else {
1742
-			$value = $prop->getValue();
1743
-		}
1744
-
1745
-		return [
1746
-			$value,
1747
-			$prop->parameters()
1748
-		];
1749
-	}
1750
-
1751
-	/**
1752
-	 * @param string $principalUri
1753
-	 * @param string $pattern
1754
-	 * @param array $componentTypes
1755
-	 * @param array $searchProperties
1756
-	 * @param array $searchParameters
1757
-	 * @param array $options
1758
-	 * @return array
1759
-	 */
1760
-	public function searchPrincipalUri(string $principalUri,
1761
-									   string $pattern,
1762
-									   array $componentTypes,
1763
-									   array $searchProperties,
1764
-									   array $searchParameters,
1765
-									   array $options = []): array {
1766
-		$escapePattern = !\array_key_exists('escape_like_param', $options) || $options['escape_like_param'] !== false;
1767
-
1768
-		$calendarObjectIdQuery = $this->db->getQueryBuilder();
1769
-		$calendarOr = $calendarObjectIdQuery->expr()->orX();
1770
-		$searchOr = $calendarObjectIdQuery->expr()->orX();
1771
-
1772
-		// Fetch calendars and subscription
1773
-		$calendars = $this->getCalendarsForUser($principalUri);
1774
-		$subscriptions = $this->getSubscriptionsForUser($principalUri);
1775
-		foreach ($calendars as $calendar) {
1776
-			$calendarAnd = $calendarObjectIdQuery->expr()->andX();
1777
-			$calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$calendar['id'])));
1778
-			$calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1779
-
1780
-			// If it's shared, limit search to public events
1781
-			if ($calendar['principaluri'] !== $calendar['{http://owncloud.org/ns}owner-principal']) {
1782
-				$calendarAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
1783
-			}
1784
-
1785
-			$calendarOr->add($calendarAnd);
1786
-		}
1787
-		foreach ($subscriptions as $subscription) {
1788
-			$subscriptionAnd = $calendarObjectIdQuery->expr()->andX();
1789
-			$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$subscription['id'])));
1790
-			$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)));
1791
-
1792
-			// If it's shared, limit search to public events
1793
-			if ($subscription['principaluri'] !== $subscription['{http://owncloud.org/ns}owner-principal']) {
1794
-				$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
1795
-			}
1796
-
1797
-			$calendarOr->add($subscriptionAnd);
1798
-		}
1799
-
1800
-		foreach ($searchProperties as $property) {
1801
-			$propertyAnd = $calendarObjectIdQuery->expr()->andX();
1802
-			$propertyAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
1803
-			$propertyAnd->add($calendarObjectIdQuery->expr()->isNull('cob.parameter'));
1804
-
1805
-			$searchOr->add($propertyAnd);
1806
-		}
1807
-		foreach ($searchParameters as $property => $parameter) {
1808
-			$parameterAnd = $calendarObjectIdQuery->expr()->andX();
1809
-			$parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
1810
-			$parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.parameter', $calendarObjectIdQuery->createNamedParameter($parameter, IQueryBuilder::PARAM_STR_ARRAY)));
1811
-
1812
-			$searchOr->add($parameterAnd);
1813
-		}
1814
-
1815
-		if ($calendarOr->count() === 0) {
1816
-			return [];
1817
-		}
1818
-		if ($searchOr->count() === 0) {
1819
-			return [];
1820
-		}
1821
-
1822
-		$calendarObjectIdQuery->selectDistinct('cob.objectid')
1823
-			->from($this->dbObjectPropertiesTable, 'cob')
1824
-			->leftJoin('cob', 'calendarobjects', 'co', $calendarObjectIdQuery->expr()->eq('co.id', 'cob.objectid'))
1825
-			->andWhere($calendarObjectIdQuery->expr()->in('co.componenttype', $calendarObjectIdQuery->createNamedParameter($componentTypes, IQueryBuilder::PARAM_STR_ARRAY)))
1826
-			->andWhere($calendarOr)
1827
-			->andWhere($searchOr);
1828
-
1829
-		if ('' !== $pattern) {
1830
-			if (!$escapePattern) {
1831
-				$calendarObjectIdQuery->andWhere($calendarObjectIdQuery->expr()->ilike('cob.value', $calendarObjectIdQuery->createNamedParameter($pattern)));
1832
-			} else {
1833
-				$calendarObjectIdQuery->andWhere($calendarObjectIdQuery->expr()->ilike('cob.value', $calendarObjectIdQuery->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%')));
1834
-			}
1835
-		}
1836
-
1837
-		if (isset($options['limit'])) {
1838
-			$calendarObjectIdQuery->setMaxResults($options['limit']);
1839
-		}
1840
-		if (isset($options['offset'])) {
1841
-			$calendarObjectIdQuery->setFirstResult($options['offset']);
1842
-		}
1843
-
1844
-		$result = $calendarObjectIdQuery->execute();
1845
-		$matches = $result->fetchAll();
1846
-		$result->closeCursor();
1847
-		$matches = array_map(static function (array $match):int {
1848
-			return (int) $match['objectid'];
1849
-		}, $matches);
1850
-
1851
-		$query = $this->db->getQueryBuilder();
1852
-		$query->select('calendardata', 'uri', 'calendarid', 'calendartype')
1853
-			->from('calendarobjects')
1854
-			->where($query->expr()->in('id', $query->createNamedParameter($matches, IQueryBuilder::PARAM_INT_ARRAY)));
1855
-
1856
-		$result = $query->execute();
1857
-		$calendarObjects = $result->fetchAll();
1858
-		$result->closeCursor();
1859
-
1860
-		return array_map(function (array $array): array {
1861
-			$array['calendarid'] = (int)$array['calendarid'];
1862
-			$array['calendartype'] = (int)$array['calendartype'];
1863
-			$array['calendardata'] = $this->readBlob($array['calendardata']);
1864
-
1865
-			return $array;
1866
-		}, $calendarObjects);
1867
-	}
1868
-
1869
-	/**
1870
-	 * Searches through all of a users calendars and calendar objects to find
1871
-	 * an object with a specific UID.
1872
-	 *
1873
-	 * This method should return the path to this object, relative to the
1874
-	 * calendar home, so this path usually only contains two parts:
1875
-	 *
1876
-	 * calendarpath/objectpath.ics
1877
-	 *
1878
-	 * If the uid is not found, return null.
1879
-	 *
1880
-	 * This method should only consider * objects that the principal owns, so
1881
-	 * any calendars owned by other principals that also appear in this
1882
-	 * collection should be ignored.
1883
-	 *
1884
-	 * @param string $principalUri
1885
-	 * @param string $uid
1886
-	 * @return string|null
1887
-	 */
1888
-	public function getCalendarObjectByUID($principalUri, $uid) {
1889
-		$query = $this->db->getQueryBuilder();
1890
-		$query->selectAlias('c.uri', 'calendaruri')->selectAlias('co.uri', 'objecturi')
1891
-			->from('calendarobjects', 'co')
1892
-			->leftJoin('co', 'calendars', 'c', $query->expr()->eq('co.calendarid', 'c.id'))
1893
-			->where($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)))
1894
-			->andWhere($query->expr()->eq('co.uid', $query->createNamedParameter($uid)));
1895
-
1896
-		$stmt = $query->execute();
1897
-
1898
-		if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1899
-			return $row['calendaruri'] . '/' . $row['objecturi'];
1900
-		}
1901
-
1902
-		return null;
1903
-	}
1904
-
1905
-	/**
1906
-	 * The getChanges method returns all the changes that have happened, since
1907
-	 * the specified syncToken in the specified calendar.
1908
-	 *
1909
-	 * This function should return an array, such as the following:
1910
-	 *
1911
-	 * [
1912
-	 *   'syncToken' => 'The current synctoken',
1913
-	 *   'added'   => [
1914
-	 *      'new.txt',
1915
-	 *   ],
1916
-	 *   'modified'   => [
1917
-	 *      'modified.txt',
1918
-	 *   ],
1919
-	 *   'deleted' => [
1920
-	 *      'foo.php.bak',
1921
-	 *      'old.txt'
1922
-	 *   ]
1923
-	 * );
1924
-	 *
1925
-	 * The returned syncToken property should reflect the *current* syncToken
1926
-	 * of the calendar, as reported in the {http://sabredav.org/ns}sync-token
1927
-	 * property This is * needed here too, to ensure the operation is atomic.
1928
-	 *
1929
-	 * If the $syncToken argument is specified as null, this is an initial
1930
-	 * sync, and all members should be reported.
1931
-	 *
1932
-	 * The modified property is an array of nodenames that have changed since
1933
-	 * the last token.
1934
-	 *
1935
-	 * The deleted property is an array with nodenames, that have been deleted
1936
-	 * from collection.
1937
-	 *
1938
-	 * The $syncLevel argument is basically the 'depth' of the report. If it's
1939
-	 * 1, you only have to report changes that happened only directly in
1940
-	 * immediate descendants. If it's 2, it should also include changes from
1941
-	 * the nodes below the child collections. (grandchildren)
1942
-	 *
1943
-	 * The $limit argument allows a client to specify how many results should
1944
-	 * be returned at most. If the limit is not specified, it should be treated
1945
-	 * as infinite.
1946
-	 *
1947
-	 * If the limit (infinite or not) is higher than you're willing to return,
1948
-	 * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception.
1949
-	 *
1950
-	 * If the syncToken is expired (due to data cleanup) or unknown, you must
1951
-	 * return null.
1952
-	 *
1953
-	 * The limit is 'suggestive'. You are free to ignore it.
1954
-	 *
1955
-	 * @param string $calendarId
1956
-	 * @param string $syncToken
1957
-	 * @param int $syncLevel
1958
-	 * @param int $limit
1959
-	 * @param int $calendarType
1960
-	 * @return array
1961
-	 */
1962
-	public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1963
-		// Current synctoken
1964
-		$stmt = $this->db->prepare('SELECT `synctoken` FROM `*PREFIX*calendars` WHERE `id` = ?');
1965
-		$stmt->execute([ $calendarId ]);
1966
-		$currentToken = $stmt->fetchColumn(0);
1967
-
1968
-		if (is_null($currentToken)) {
1969
-			return null;
1970
-		}
1971
-
1972
-		$result = [
1973
-			'syncToken' => $currentToken,
1974
-			'added' => [],
1975
-			'modified' => [],
1976
-			'deleted' => [],
1977
-		];
1978
-
1979
-		if ($syncToken) {
1980
-			$query = "SELECT `uri`, `operation` FROM `*PREFIX*calendarchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `calendarid` = ? AND `calendartype` = ? ORDER BY `synctoken`";
1981
-			if ($limit > 0) {
1982
-				$query .= " LIMIT " . (int)$limit;
1983
-			}
1984
-
1985
-			// Fetching all changes
1986
-			$stmt = $this->db->prepare($query);
1987
-			$stmt->execute([$syncToken, $currentToken, $calendarId, $calendarType]);
1988
-
1989
-			$changes = [];
1990
-
1991
-			// This loop ensures that any duplicates are overwritten, only the
1992
-			// last change on a node is relevant.
1993
-			while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1994
-				$changes[$row['uri']] = $row['operation'];
1995
-			}
1996
-
1997
-			foreach ($changes as $uri => $operation) {
1998
-				switch ($operation) {
1999
-					case 1:
2000
-						$result['added'][] = $uri;
2001
-						break;
2002
-					case 2:
2003
-						$result['modified'][] = $uri;
2004
-						break;
2005
-					case 3:
2006
-						$result['deleted'][] = $uri;
2007
-						break;
2008
-				}
2009
-			}
2010
-		} else {
2011
-			// No synctoken supplied, this is the initial sync.
2012
-			$query = "SELECT `uri` FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `calendartype` = ?";
2013
-			$stmt = $this->db->prepare($query);
2014
-			$stmt->execute([$calendarId, $calendarType]);
2015
-
2016
-			$result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
2017
-		}
2018
-		return $result;
2019
-	}
2020
-
2021
-	/**
2022
-	 * Returns a list of subscriptions for a principal.
2023
-	 *
2024
-	 * Every subscription is an array with the following keys:
2025
-	 *  * id, a unique id that will be used by other functions to modify the
2026
-	 *    subscription. This can be the same as the uri or a database key.
2027
-	 *  * uri. This is just the 'base uri' or 'filename' of the subscription.
2028
-	 *  * principaluri. The owner of the subscription. Almost always the same as
2029
-	 *    principalUri passed to this method.
2030
-	 *
2031
-	 * Furthermore, all the subscription info must be returned too:
2032
-	 *
2033
-	 * 1. {DAV:}displayname
2034
-	 * 2. {http://apple.com/ns/ical/}refreshrate
2035
-	 * 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos
2036
-	 *    should not be stripped).
2037
-	 * 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms
2038
-	 *    should not be stripped).
2039
-	 * 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if
2040
-	 *    attachments should not be stripped).
2041
-	 * 6. {http://calendarserver.org/ns/}source (Must be a
2042
-	 *     Sabre\DAV\Property\Href).
2043
-	 * 7. {http://apple.com/ns/ical/}calendar-color
2044
-	 * 8. {http://apple.com/ns/ical/}calendar-order
2045
-	 * 9. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
2046
-	 *    (should just be an instance of
2047
-	 *    Sabre\CalDAV\Property\SupportedCalendarComponentSet, with a bunch of
2048
-	 *    default components).
2049
-	 *
2050
-	 * @param string $principalUri
2051
-	 * @return array
2052
-	 */
2053
-	public function getSubscriptionsForUser($principalUri) {
2054
-		$fields = array_values($this->subscriptionPropertyMap);
2055
-		$fields[] = 'id';
2056
-		$fields[] = 'uri';
2057
-		$fields[] = 'source';
2058
-		$fields[] = 'principaluri';
2059
-		$fields[] = 'lastmodified';
2060
-		$fields[] = 'synctoken';
2061
-
2062
-		$query = $this->db->getQueryBuilder();
2063
-		$query->select($fields)
2064
-			->from('calendarsubscriptions')
2065
-			->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2066
-			->orderBy('calendarorder', 'asc');
2067
-		$stmt = $query->execute();
2068
-
2069
-		$subscriptions = [];
2070
-		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
2071
-			$subscription = [
2072
-				'id' => $row['id'],
2073
-				'uri' => $row['uri'],
2074
-				'principaluri' => $row['principaluri'],
2075
-				'source' => $row['source'],
2076
-				'lastmodified' => $row['lastmodified'],
2077
-
2078
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
2079
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
2080
-			];
2081
-
2082
-			foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
2083
-				if (!is_null($row[$dbName])) {
2084
-					$subscription[$xmlName] = $row[$dbName];
2085
-				}
2086
-			}
2087
-
2088
-			$subscriptions[] = $subscription;
2089
-		}
2090
-
2091
-		return $subscriptions;
2092
-	}
2093
-
2094
-	/**
2095
-	 * Creates a new subscription for a principal.
2096
-	 *
2097
-	 * If the creation was a success, an id must be returned that can be used to reference
2098
-	 * this subscription in other methods, such as updateSubscription.
2099
-	 *
2100
-	 * @param string $principalUri
2101
-	 * @param string $uri
2102
-	 * @param array $properties
2103
-	 * @return mixed
2104
-	 */
2105
-	public function createSubscription($principalUri, $uri, array $properties) {
2106
-		if (!isset($properties['{http://calendarserver.org/ns/}source'])) {
2107
-			throw new Forbidden('The {http://calendarserver.org/ns/}source property is required when creating subscriptions');
2108
-		}
2109
-
2110
-		$values = [
2111
-			'principaluri' => $principalUri,
2112
-			'uri' => $uri,
2113
-			'source' => $properties['{http://calendarserver.org/ns/}source']->getHref(),
2114
-			'lastmodified' => time(),
2115
-		];
2116
-
2117
-		$propertiesBoolean = ['striptodos', 'stripalarms', 'stripattachments'];
2118
-
2119
-		foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
2120
-			if (array_key_exists($xmlName, $properties)) {
2121
-				$values[$dbName] = $properties[$xmlName];
2122
-				if (in_array($dbName, $propertiesBoolean)) {
2123
-					$values[$dbName] = true;
2124
-				}
2125
-			}
2126
-		}
2127
-
2128
-		$valuesToInsert = [];
2129
-
2130
-		$query = $this->db->getQueryBuilder();
2131
-
2132
-		foreach (array_keys($values) as $name) {
2133
-			$valuesToInsert[$name] = $query->createNamedParameter($values[$name]);
2134
-		}
2135
-
2136
-		$query->insert('calendarsubscriptions')
2137
-			->values($valuesToInsert)
2138
-			->execute();
2139
-
2140
-		$subscriptionId = $this->db->lastInsertId('*PREFIX*calendarsubscriptions');
2141
-
2142
-		$subscriptionRow = $this->getSubscriptionById($subscriptionId);
2143
-		$this->dispatcher->dispatchTyped(new SubscriptionCreatedEvent((int)$subscriptionId, $subscriptionRow));
2144
-		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createSubscription', new GenericEvent(
2145
-			'\OCA\DAV\CalDAV\CalDavBackend::createSubscription',
2146
-			[
2147
-				'subscriptionId' => $subscriptionId,
2148
-				'subscriptionData' => $subscriptionRow,
2149
-			]));
2150
-
2151
-		return $subscriptionId;
2152
-	}
2153
-
2154
-	/**
2155
-	 * Updates a subscription
2156
-	 *
2157
-	 * The list of mutations is stored in a Sabre\DAV\PropPatch object.
2158
-	 * To do the actual updates, you must tell this object which properties
2159
-	 * you're going to process with the handle() method.
2160
-	 *
2161
-	 * Calling the handle method is like telling the PropPatch object "I
2162
-	 * promise I can handle updating this property".
2163
-	 *
2164
-	 * Read the PropPatch documentation for more info and examples.
2165
-	 *
2166
-	 * @param mixed $subscriptionId
2167
-	 * @param PropPatch $propPatch
2168
-	 * @return void
2169
-	 */
2170
-	public function updateSubscription($subscriptionId, PropPatch $propPatch) {
2171
-		$supportedProperties = array_keys($this->subscriptionPropertyMap);
2172
-		$supportedProperties[] = '{http://calendarserver.org/ns/}source';
2173
-
2174
-		$propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) {
2175
-			$newValues = [];
2176
-
2177
-			foreach ($mutations as $propertyName => $propertyValue) {
2178
-				if ($propertyName === '{http://calendarserver.org/ns/}source') {
2179
-					$newValues['source'] = $propertyValue->getHref();
2180
-				} else {
2181
-					$fieldName = $this->subscriptionPropertyMap[$propertyName];
2182
-					$newValues[$fieldName] = $propertyValue;
2183
-				}
2184
-			}
2185
-
2186
-			$query = $this->db->getQueryBuilder();
2187
-			$query->update('calendarsubscriptions')
2188
-				->set('lastmodified', $query->createNamedParameter(time()));
2189
-			foreach ($newValues as $fieldName => $value) {
2190
-				$query->set($fieldName, $query->createNamedParameter($value));
2191
-			}
2192
-			$query->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId)))
2193
-				->execute();
2194
-
2195
-			$subscriptionRow = $this->getSubscriptionById($subscriptionId);
2196
-			$this->dispatcher->dispatchTyped(new SubscriptionUpdatedEvent((int)$subscriptionId, $subscriptionRow, [], $mutations));
2197
-			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateSubscription', new GenericEvent(
2198
-				'\OCA\DAV\CalDAV\CalDavBackend::updateSubscription',
2199
-				[
2200
-					'subscriptionId' => $subscriptionId,
2201
-					'subscriptionData' => $subscriptionRow,
2202
-					'propertyMutations' => $mutations,
2203
-				]));
2204
-
2205
-			return true;
2206
-		});
2207
-	}
2208
-
2209
-	/**
2210
-	 * Deletes a subscription.
2211
-	 *
2212
-	 * @param mixed $subscriptionId
2213
-	 * @return void
2214
-	 */
2215
-	public function deleteSubscription($subscriptionId) {
2216
-		$subscriptionRow = $this->getSubscriptionById($subscriptionId);
2217
-
2218
-		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription', new GenericEvent(
2219
-			'\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription',
2220
-			[
2221
-				'subscriptionId' => $subscriptionId,
2222
-				'subscriptionData' => $this->getSubscriptionById($subscriptionId),
2223
-			]));
2224
-
2225
-		$query = $this->db->getQueryBuilder();
2226
-		$query->delete('calendarsubscriptions')
2227
-			->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId)))
2228
-			->execute();
2229
-
2230
-		$query = $this->db->getQueryBuilder();
2231
-		$query->delete('calendarobjects')
2232
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2233
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2234
-			->execute();
2235
-
2236
-		$query->delete('calendarchanges')
2237
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2238
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2239
-			->execute();
2240
-
2241
-		$query->delete($this->dbObjectPropertiesTable)
2242
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2243
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2244
-			->execute();
2245
-
2246
-		if ($subscriptionRow) {
2247
-			$this->dispatcher->dispatchTyped(new SubscriptionDeletedEvent((int)$subscriptionId, $subscriptionRow, []));
2248
-		}
2249
-	}
2250
-
2251
-	/**
2252
-	 * Returns a single scheduling object for the inbox collection.
2253
-	 *
2254
-	 * The returned array should contain the following elements:
2255
-	 *   * uri - A unique basename for the object. This will be used to
2256
-	 *           construct a full uri.
2257
-	 *   * calendardata - The iCalendar object
2258
-	 *   * lastmodified - The last modification date. Can be an int for a unix
2259
-	 *                    timestamp, or a PHP DateTime object.
2260
-	 *   * etag - A unique token that must change if the object changed.
2261
-	 *   * size - The size of the object, in bytes.
2262
-	 *
2263
-	 * @param string $principalUri
2264
-	 * @param string $objectUri
2265
-	 * @return array
2266
-	 */
2267
-	public function getSchedulingObject($principalUri, $objectUri) {
2268
-		$query = $this->db->getQueryBuilder();
2269
-		$stmt = $query->select(['uri', 'calendardata', 'lastmodified', 'etag', 'size'])
2270
-			->from('schedulingobjects')
2271
-			->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2272
-			->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
2273
-			->execute();
2274
-
2275
-		$row = $stmt->fetch(\PDO::FETCH_ASSOC);
2276
-
2277
-		if (!$row) {
2278
-			return null;
2279
-		}
2280
-
2281
-		return [
2282
-			'uri' => $row['uri'],
2283
-			'calendardata' => $row['calendardata'],
2284
-			'lastmodified' => $row['lastmodified'],
2285
-			'etag' => '"' . $row['etag'] . '"',
2286
-			'size' => (int)$row['size'],
2287
-		];
2288
-	}
2289
-
2290
-	/**
2291
-	 * Returns all scheduling objects for the inbox collection.
2292
-	 *
2293
-	 * These objects should be returned as an array. Every item in the array
2294
-	 * should follow the same structure as returned from getSchedulingObject.
2295
-	 *
2296
-	 * The main difference is that 'calendardata' is optional.
2297
-	 *
2298
-	 * @param string $principalUri
2299
-	 * @return array
2300
-	 */
2301
-	public function getSchedulingObjects($principalUri) {
2302
-		$query = $this->db->getQueryBuilder();
2303
-		$stmt = $query->select(['uri', 'calendardata', 'lastmodified', 'etag', 'size'])
2304
-				->from('schedulingobjects')
2305
-				->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2306
-				->execute();
2307
-
2308
-		$result = [];
2309
-		foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
2310
-			$result[] = [
2311
-				'calendardata' => $row['calendardata'],
2312
-				'uri' => $row['uri'],
2313
-				'lastmodified' => $row['lastmodified'],
2314
-				'etag' => '"' . $row['etag'] . '"',
2315
-				'size' => (int)$row['size'],
2316
-			];
2317
-		}
2318
-
2319
-		return $result;
2320
-	}
2321
-
2322
-	/**
2323
-	 * Deletes a scheduling object from the inbox collection.
2324
-	 *
2325
-	 * @param string $principalUri
2326
-	 * @param string $objectUri
2327
-	 * @return void
2328
-	 */
2329
-	public function deleteSchedulingObject($principalUri, $objectUri) {
2330
-		$query = $this->db->getQueryBuilder();
2331
-		$query->delete('schedulingobjects')
2332
-				->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2333
-				->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
2334
-				->execute();
2335
-	}
2336
-
2337
-	/**
2338
-	 * Creates a new scheduling object. This should land in a users' inbox.
2339
-	 *
2340
-	 * @param string $principalUri
2341
-	 * @param string $objectUri
2342
-	 * @param string $objectData
2343
-	 * @return void
2344
-	 */
2345
-	public function createSchedulingObject($principalUri, $objectUri, $objectData) {
2346
-		$query = $this->db->getQueryBuilder();
2347
-		$query->insert('schedulingobjects')
2348
-			->values([
2349
-				'principaluri' => $query->createNamedParameter($principalUri),
2350
-				'calendardata' => $query->createNamedParameter($objectData, IQueryBuilder::PARAM_LOB),
2351
-				'uri' => $query->createNamedParameter($objectUri),
2352
-				'lastmodified' => $query->createNamedParameter(time()),
2353
-				'etag' => $query->createNamedParameter(md5($objectData)),
2354
-				'size' => $query->createNamedParameter(strlen($objectData))
2355
-			])
2356
-			->execute();
2357
-	}
2358
-
2359
-	/**
2360
-	 * Adds a change record to the calendarchanges table.
2361
-	 *
2362
-	 * @param mixed $calendarId
2363
-	 * @param string $objectUri
2364
-	 * @param int $operation 1 = add, 2 = modify, 3 = delete.
2365
-	 * @param int $calendarType
2366
-	 * @return void
2367
-	 */
2368
-	protected function addChange($calendarId, $objectUri, $operation, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
2369
-		$table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions';
2370
-
2371
-		$query = $this->db->getQueryBuilder();
2372
-		$query->select('synctoken')
2373
-			->from($table)
2374
-			->where($query->expr()->eq('id', $query->createNamedParameter($calendarId)));
2375
-		$result = $query->execute();
2376
-		$syncToken = (int)$result->fetchColumn();
2377
-		$result->closeCursor();
2378
-
2379
-		$query = $this->db->getQueryBuilder();
2380
-		$query->insert('calendarchanges')
2381
-			->values([
2382
-				'uri' => $query->createNamedParameter($objectUri),
2383
-				'synctoken' => $query->createNamedParameter($syncToken),
2384
-				'calendarid' => $query->createNamedParameter($calendarId),
2385
-				'operation' => $query->createNamedParameter($operation),
2386
-				'calendartype' => $query->createNamedParameter($calendarType),
2387
-			])
2388
-			->execute();
2389
-
2390
-		$stmt = $this->db->prepare("UPDATE `*PREFIX*$table` SET `synctoken` = `synctoken` + 1 WHERE `id` = ?");
2391
-		$stmt->execute([
2392
-			$calendarId
2393
-		]);
2394
-	}
2395
-
2396
-	/**
2397
-	 * Parses some information from calendar objects, used for optimized
2398
-	 * calendar-queries.
2399
-	 *
2400
-	 * Returns an array with the following keys:
2401
-	 *   * etag - An md5 checksum of the object without the quotes.
2402
-	 *   * size - Size of the object in bytes
2403
-	 *   * componentType - VEVENT, VTODO or VJOURNAL
2404
-	 *   * firstOccurence
2405
-	 *   * lastOccurence
2406
-	 *   * uid - value of the UID property
2407
-	 *
2408
-	 * @param string $calendarData
2409
-	 * @return array
2410
-	 */
2411
-	public function getDenormalizedData($calendarData) {
2412
-		$vObject = Reader::read($calendarData);
2413
-		$vEvents = [];
2414
-		$componentType = null;
2415
-		$component = null;
2416
-		$firstOccurrence = null;
2417
-		$lastOccurrence = null;
2418
-		$uid = null;
2419
-		$classification = self::CLASSIFICATION_PUBLIC;
2420
-		$hasDTSTART = false;
2421
-		foreach ($vObject->getComponents() as $component) {
2422
-			if ($component->name !== 'VTIMEZONE') {
2423
-				// Finding all VEVENTs, and track them
2424
-				if ($component->name === 'VEVENT') {
2425
-					array_push($vEvents, $component);
2426
-					if ($component->DTSTART) {
2427
-						$hasDTSTART = true;
2428
-					}
2429
-				}
2430
-				// Track first component type and uid
2431
-				if ($uid === null) {
2432
-					$componentType = $component->name;
2433
-					$uid = (string)$component->UID;
2434
-				}
2435
-			}
2436
-		}
2437
-		if (!$componentType) {
2438
-			throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
2439
-		}
2440
-
2441
-		if ($hasDTSTART) {
2442
-			$component = $vEvents[0];
2443
-
2444
-			// Finding the last occurrence is a bit harder
2445
-			if (!isset($component->RRULE) && count($vEvents) === 1) {
2446
-				$firstOccurrence = $component->DTSTART->getDateTime()->getTimeStamp();
2447
-				if (isset($component->DTEND)) {
2448
-					$lastOccurrence = $component->DTEND->getDateTime()->getTimeStamp();
2449
-				} elseif (isset($component->DURATION)) {
2450
-					$endDate = clone $component->DTSTART->getDateTime();
2451
-					$endDate->add(DateTimeParser::parse($component->DURATION->getValue()));
2452
-					$lastOccurrence = $endDate->getTimeStamp();
2453
-				} elseif (!$component->DTSTART->hasTime()) {
2454
-					$endDate = clone $component->DTSTART->getDateTime();
2455
-					$endDate->modify('+1 day');
2456
-					$lastOccurrence = $endDate->getTimeStamp();
2457
-				} else {
2458
-					$lastOccurrence = $firstOccurrence;
2459
-				}
2460
-			} else {
2461
-				$it = new EventIterator($vEvents);
2462
-				$maxDate = new DateTime(self::MAX_DATE);
2463
-				$firstOccurrence = $it->getDtStart()->getTimestamp();
2464
-				if ($it->isInfinite()) {
2465
-					$lastOccurrence = $maxDate->getTimestamp();
2466
-				} else {
2467
-					$end = $it->getDtEnd();
2468
-					while ($it->valid() && $end < $maxDate) {
2469
-						$end = $it->getDtEnd();
2470
-						$it->next();
2471
-					}
2472
-					$lastOccurrence = $end->getTimestamp();
2473
-				}
2474
-			}
2475
-		}
2476
-
2477
-		if ($component->CLASS) {
2478
-			$classification = CalDavBackend::CLASSIFICATION_PRIVATE;
2479
-			switch ($component->CLASS->getValue()) {
2480
-				case 'PUBLIC':
2481
-					$classification = CalDavBackend::CLASSIFICATION_PUBLIC;
2482
-					break;
2483
-				case 'CONFIDENTIAL':
2484
-					$classification = CalDavBackend::CLASSIFICATION_CONFIDENTIAL;
2485
-					break;
2486
-			}
2487
-		}
2488
-		return [
2489
-			'etag' => md5($calendarData),
2490
-			'size' => strlen($calendarData),
2491
-			'componentType' => $componentType,
2492
-			'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence),
2493
-			'lastOccurence' => $lastOccurrence,
2494
-			'uid' => $uid,
2495
-			'classification' => $classification
2496
-		];
2497
-	}
2498
-
2499
-	/**
2500
-	 * @param $cardData
2501
-	 * @return bool|string
2502
-	 */
2503
-	private function readBlob($cardData) {
2504
-		if (is_resource($cardData)) {
2505
-			return stream_get_contents($cardData);
2506
-		}
2507
-
2508
-		return $cardData;
2509
-	}
2510
-
2511
-	/**
2512
-	 * @param IShareable $shareable
2513
-	 * @param array $add
2514
-	 * @param array $remove
2515
-	 */
2516
-	public function updateShares($shareable, $add, $remove) {
2517
-		$calendarId = $shareable->getResourceId();
2518
-		$calendarRow = $this->getCalendarById($calendarId);
2519
-		$oldShares = $this->getShares($calendarId);
2520
-
2521
-		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateShares', new GenericEvent(
2522
-			'\OCA\DAV\CalDAV\CalDavBackend::updateShares',
2523
-			[
2524
-				'calendarId' => $calendarId,
2525
-				'calendarData' => $calendarRow,
2526
-				'shares' => $oldShares,
2527
-				'add' => $add,
2528
-				'remove' => $remove,
2529
-			]));
2530
-		$this->calendarSharingBackend->updateShares($shareable, $add, $remove);
2531
-
2532
-		$this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent((int)$calendarId, $calendarRow, $oldShares, $add, $remove));
2533
-	}
2534
-
2535
-	/**
2536
-	 * @param int $resourceId
2537
-	 * @param int $calendarType
2538
-	 * @return array
2539
-	 */
2540
-	public function getShares($resourceId, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
2541
-		return $this->calendarSharingBackend->getShares($resourceId);
2542
-	}
2543
-
2544
-	/**
2545
-	 * @param boolean $value
2546
-	 * @param \OCA\DAV\CalDAV\Calendar $calendar
2547
-	 * @return string|null
2548
-	 */
2549
-	public function setPublishStatus($value, $calendar) {
2550
-		$calendarId = $calendar->getResourceId();
2551
-		$calendarData = $this->getCalendarById($calendarId);
2552
-		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::publishCalendar', new GenericEvent(
2553
-			'\OCA\DAV\CalDAV\CalDavBackend::updateShares',
2554
-			[
2555
-				'calendarId' => $calendarId,
2556
-				'calendarData' => $calendarData,
2557
-				'public' => $value,
2558
-			]));
2559
-
2560
-		$query = $this->db->getQueryBuilder();
2561
-		if ($value) {
2562
-			$publicUri = $this->random->generate(16, ISecureRandom::CHAR_HUMAN_READABLE);
2563
-			$query->insert('dav_shares')
2564
-				->values([
2565
-					'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()),
2566
-					'type' => $query->createNamedParameter('calendar'),
2567
-					'access' => $query->createNamedParameter(self::ACCESS_PUBLIC),
2568
-					'resourceid' => $query->createNamedParameter($calendar->getResourceId()),
2569
-					'publicuri' => $query->createNamedParameter($publicUri)
2570
-				]);
2571
-			$query->execute();
2572
-
2573
-			$this->dispatcher->dispatchTyped(new CalendarPublishedEvent((int)$calendarId, $calendarData, $publicUri));
2574
-			return $publicUri;
2575
-		}
2576
-		$query->delete('dav_shares')
2577
-			->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId())))
2578
-			->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)));
2579
-		$query->execute();
2580
-
2581
-		$this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent((int)$calendarId, $calendarData));
2582
-		return null;
2583
-	}
2584
-
2585
-	/**
2586
-	 * @param \OCA\DAV\CalDAV\Calendar $calendar
2587
-	 * @return mixed
2588
-	 */
2589
-	public function getPublishStatus($calendar) {
2590
-		$query = $this->db->getQueryBuilder();
2591
-		$result = $query->select('publicuri')
2592
-			->from('dav_shares')
2593
-			->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId())))
2594
-			->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)))
2595
-			->execute();
2596
-
2597
-		$row = $result->fetch();
2598
-		$result->closeCursor();
2599
-		return $row ? reset($row) : false;
2600
-	}
2601
-
2602
-	/**
2603
-	 * @param int $resourceId
2604
-	 * @param array $acl
2605
-	 * @return array
2606
-	 */
2607
-	public function applyShareAcl($resourceId, $acl) {
2608
-		return $this->calendarSharingBackend->applyShareAcl($resourceId, $acl);
2609
-	}
2610
-
2611
-
2612
-
2613
-	/**
2614
-	 * update properties table
2615
-	 *
2616
-	 * @param int $calendarId
2617
-	 * @param string $objectUri
2618
-	 * @param string $calendarData
2619
-	 * @param int $calendarType
2620
-	 */
2621
-	public function updateProperties($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
2622
-		$objectId = $this->getCalendarObjectId($calendarId, $objectUri, $calendarType);
2623
-
2624
-		try {
2625
-			$vCalendar = $this->readCalendarData($calendarData);
2626
-		} catch (\Exception $ex) {
2627
-			return;
2628
-		}
2629
-
2630
-		$this->purgeProperties($calendarId, $objectId);
2631
-
2632
-		$query = $this->db->getQueryBuilder();
2633
-		$query->insert($this->dbObjectPropertiesTable)
2634
-			->values(
2635
-				[
2636
-					'calendarid' => $query->createNamedParameter($calendarId),
2637
-					'calendartype' => $query->createNamedParameter($calendarType),
2638
-					'objectid' => $query->createNamedParameter($objectId),
2639
-					'name' => $query->createParameter('name'),
2640
-					'parameter' => $query->createParameter('parameter'),
2641
-					'value' => $query->createParameter('value'),
2642
-				]
2643
-			);
2644
-
2645
-		$indexComponents = ['VEVENT', 'VJOURNAL', 'VTODO'];
2646
-		foreach ($vCalendar->getComponents() as $component) {
2647
-			if (!in_array($component->name, $indexComponents)) {
2648
-				continue;
2649
-			}
2650
-
2651
-			foreach ($component->children() as $property) {
2652
-				if (in_array($property->name, self::$indexProperties)) {
2653
-					$value = $property->getValue();
2654
-					// is this a shitty db?
2655
-					if (!$this->db->supports4ByteText()) {
2656
-						$value = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $value);
2657
-					}
2658
-					$value = mb_substr($value, 0, 254);
2659
-
2660
-					$query->setParameter('name', $property->name);
2661
-					$query->setParameter('parameter', null);
2662
-					$query->setParameter('value', $value);
2663
-					$query->execute();
2664
-				}
2665
-
2666
-				if (array_key_exists($property->name, self::$indexParameters)) {
2667
-					$parameters = $property->parameters();
2668
-					$indexedParametersForProperty = self::$indexParameters[$property->name];
2669
-
2670
-					foreach ($parameters as $key => $value) {
2671
-						if (in_array($key, $indexedParametersForProperty)) {
2672
-							// is this a shitty db?
2673
-							if ($this->db->supports4ByteText()) {
2674
-								$value = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $value);
2675
-							}
2676
-
2677
-							$query->setParameter('name', $property->name);
2678
-							$query->setParameter('parameter', mb_substr($key, 0, 254));
2679
-							$query->setParameter('value', mb_substr($value, 0, 254));
2680
-							$query->execute();
2681
-						}
2682
-					}
2683
-				}
2684
-			}
2685
-		}
2686
-	}
2687
-
2688
-	/**
2689
-	 * deletes all birthday calendars
2690
-	 */
2691
-	public function deleteAllBirthdayCalendars() {
2692
-		$query = $this->db->getQueryBuilder();
2693
-		$result = $query->select(['id'])->from('calendars')
2694
-			->where($query->expr()->eq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI)))
2695
-			->execute();
2696
-
2697
-		$ids = $result->fetchAll();
2698
-		foreach ($ids as $id) {
2699
-			$this->deleteCalendar($id['id']);
2700
-		}
2701
-	}
2702
-
2703
-	/**
2704
-	 * @param $subscriptionId
2705
-	 */
2706
-	public function purgeAllCachedEventsForSubscription($subscriptionId) {
2707
-		$query = $this->db->getQueryBuilder();
2708
-		$query->select('uri')
2709
-			->from('calendarobjects')
2710
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2711
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)));
2712
-		$stmt = $query->execute();
2713
-
2714
-		$uris = [];
2715
-		foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
2716
-			$uris[] = $row['uri'];
2717
-		}
2718
-		$stmt->closeCursor();
2719
-
2720
-		$query = $this->db->getQueryBuilder();
2721
-		$query->delete('calendarobjects')
2722
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2723
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2724
-			->execute();
2725
-
2726
-		$query->delete('calendarchanges')
2727
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2728
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2729
-			->execute();
2730
-
2731
-		$query->delete($this->dbObjectPropertiesTable)
2732
-			->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2733
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2734
-			->execute();
2735
-
2736
-		foreach ($uris as $uri) {
2737
-			$this->addChange($subscriptionId, $uri, 3, self::CALENDAR_TYPE_SUBSCRIPTION);
2738
-		}
2739
-	}
2740
-
2741
-	/**
2742
-	 * Move a calendar from one user to another
2743
-	 *
2744
-	 * @param string $uriName
2745
-	 * @param string $uriOrigin
2746
-	 * @param string $uriDestination
2747
-	 */
2748
-	public function moveCalendar($uriName, $uriOrigin, $uriDestination) {
2749
-		$query = $this->db->getQueryBuilder();
2750
-		$query->update('calendars')
2751
-			->set('principaluri', $query->createNamedParameter($uriDestination))
2752
-			->where($query->expr()->eq('principaluri', $query->createNamedParameter($uriOrigin)))
2753
-			->andWhere($query->expr()->eq('uri', $query->createNamedParameter($uriName)))
2754
-			->execute();
2755
-	}
2756
-
2757
-	/**
2758
-	 * read VCalendar data into a VCalendar object
2759
-	 *
2760
-	 * @param string $objectData
2761
-	 * @return VCalendar
2762
-	 */
2763
-	protected function readCalendarData($objectData) {
2764
-		return Reader::read($objectData);
2765
-	}
2766
-
2767
-	/**
2768
-	 * delete all properties from a given calendar object
2769
-	 *
2770
-	 * @param int $calendarId
2771
-	 * @param int $objectId
2772
-	 */
2773
-	protected function purgeProperties($calendarId, $objectId) {
2774
-		$query = $this->db->getQueryBuilder();
2775
-		$query->delete($this->dbObjectPropertiesTable)
2776
-			->where($query->expr()->eq('objectid', $query->createNamedParameter($objectId)))
2777
-			->andWhere($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)));
2778
-		$query->execute();
2779
-	}
2780
-
2781
-	/**
2782
-	 * get ID from a given calendar object
2783
-	 *
2784
-	 * @param int $calendarId
2785
-	 * @param string $uri
2786
-	 * @param int $calendarType
2787
-	 * @return int
2788
-	 */
2789
-	protected function getCalendarObjectId($calendarId, $uri, $calendarType):int {
2790
-		$query = $this->db->getQueryBuilder();
2791
-		$query->select('id')
2792
-			->from('calendarobjects')
2793
-			->where($query->expr()->eq('uri', $query->createNamedParameter($uri)))
2794
-			->andWhere($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
2795
-			->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
2796
-
2797
-		$result = $query->execute();
2798
-		$objectIds = $result->fetch();
2799
-		$result->closeCursor();
2800
-
2801
-		if (!isset($objectIds['id'])) {
2802
-			throw new \InvalidArgumentException('Calendarobject does not exists: ' . $uri);
2803
-		}
2804
-
2805
-		return (int)$objectIds['id'];
2806
-	}
2807
-
2808
-	/**
2809
-	 * return legacy endpoint principal name to new principal name
2810
-	 *
2811
-	 * @param $principalUri
2812
-	 * @param $toV2
2813
-	 * @return string
2814
-	 */
2815
-	private function convertPrincipal($principalUri, $toV2) {
2816
-		if ($this->principalBackend->getPrincipalPrefix() === 'principals') {
2817
-			list(, $name) = Uri\split($principalUri);
2818
-			if ($toV2 === true) {
2819
-				return "principals/users/$name";
2820
-			}
2821
-			return "principals/$name";
2822
-		}
2823
-		return $principalUri;
2824
-	}
2825
-
2826
-	/**
2827
-	 * adds information about an owner to the calendar data
2828
-	 *
2829
-	 * @param $calendarInfo
2830
-	 */
2831
-	private function addOwnerPrincipal(&$calendarInfo) {
2832
-		$ownerPrincipalKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal';
2833
-		$displaynameKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}owner-displayname';
2834
-		if (isset($calendarInfo[$ownerPrincipalKey])) {
2835
-			$uri = $calendarInfo[$ownerPrincipalKey];
2836
-		} else {
2837
-			$uri = $calendarInfo['principaluri'];
2838
-		}
2839
-
2840
-		$principalInformation = $this->principalBackend->getPrincipalByPath($uri);
2841
-		if (isset($principalInformation['{DAV:}displayname'])) {
2842
-			$calendarInfo[$displaynameKey] = $principalInformation['{DAV:}displayname'];
2843
-		}
2844
-	}
98
+    public const CALENDAR_TYPE_CALENDAR = 0;
99
+    public const CALENDAR_TYPE_SUBSCRIPTION = 1;
100
+
101
+    public const PERSONAL_CALENDAR_URI = 'personal';
102
+    public const PERSONAL_CALENDAR_NAME = 'Personal';
103
+
104
+    public const RESOURCE_BOOKING_CALENDAR_URI = 'calendar';
105
+    public const RESOURCE_BOOKING_CALENDAR_NAME = 'Calendar';
106
+
107
+    /**
108
+     * We need to specify a max date, because we need to stop *somewhere*
109
+     *
110
+     * On 32 bit system the maximum for a signed integer is 2147483647, so
111
+     * MAX_DATE cannot be higher than date('Y-m-d', 2147483647) which results
112
+     * in 2038-01-19 to avoid problems when the date is converted
113
+     * to a unix timestamp.
114
+     */
115
+    public const MAX_DATE = '2038-01-01';
116
+
117
+    public const ACCESS_PUBLIC = 4;
118
+    public const CLASSIFICATION_PUBLIC = 0;
119
+    public const CLASSIFICATION_PRIVATE = 1;
120
+    public const CLASSIFICATION_CONFIDENTIAL = 2;
121
+
122
+    /**
123
+     * List of CalDAV properties, and how they map to database field names
124
+     * Add your own properties by simply adding on to this array.
125
+     *
126
+     * Note that only string-based properties are supported here.
127
+     *
128
+     * @var array
129
+     */
130
+    public $propertyMap = [
131
+        '{DAV:}displayname' => 'displayname',
132
+        '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description',
133
+        '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone',
134
+        '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
135
+        '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
136
+    ];
137
+
138
+    /**
139
+     * List of subscription properties, and how they map to database field names.
140
+     *
141
+     * @var array
142
+     */
143
+    public $subscriptionPropertyMap = [
144
+        '{DAV:}displayname' => 'displayname',
145
+        '{http://apple.com/ns/ical/}refreshrate' => 'refreshrate',
146
+        '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
147
+        '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
148
+        '{http://calendarserver.org/ns/}subscribed-strip-todos' => 'striptodos',
149
+        '{http://calendarserver.org/ns/}subscribed-strip-alarms' => 'stripalarms',
150
+        '{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments',
151
+    ];
152
+
153
+    /** @var array properties to index */
154
+    public static $indexProperties = ['CATEGORIES', 'COMMENT', 'DESCRIPTION',
155
+        'LOCATION', 'RESOURCES', 'STATUS', 'SUMMARY', 'ATTENDEE', 'CONTACT',
156
+        'ORGANIZER'];
157
+
158
+    /** @var array parameters to index */
159
+    public static $indexParameters = [
160
+        'ATTENDEE' => ['CN'],
161
+        'ORGANIZER' => ['CN'],
162
+    ];
163
+
164
+    /**
165
+     * @var string[] Map of uid => display name
166
+     */
167
+    protected $userDisplayNames;
168
+
169
+    /** @var IDBConnection */
170
+    private $db;
171
+
172
+    /** @var Backend */
173
+    private $calendarSharingBackend;
174
+
175
+    /** @var Principal */
176
+    private $principalBackend;
177
+
178
+    /** @var IUserManager */
179
+    private $userManager;
180
+
181
+    /** @var ISecureRandom */
182
+    private $random;
183
+
184
+    /** @var ILogger */
185
+    private $logger;
186
+
187
+    /** @var IEventDispatcher */
188
+    private $dispatcher;
189
+
190
+    /** @var EventDispatcherInterface */
191
+    private $legacyDispatcher;
192
+
193
+    /** @var bool */
194
+    private $legacyEndpoint;
195
+
196
+    /** @var string */
197
+    private $dbObjectPropertiesTable = 'calendarobjects_props';
198
+
199
+    /**
200
+     * CalDavBackend constructor.
201
+     *
202
+     * @param IDBConnection $db
203
+     * @param Principal $principalBackend
204
+     * @param IUserManager $userManager
205
+     * @param IGroupManager $groupManager
206
+     * @param ISecureRandom $random
207
+     * @param ILogger $logger
208
+     * @param IEventDispatcher $dispatcher
209
+     * @param EventDispatcherInterface $legacyDispatcher
210
+     * @param bool $legacyEndpoint
211
+     */
212
+    public function __construct(IDBConnection $db,
213
+                                Principal $principalBackend,
214
+                                IUserManager $userManager,
215
+                                IGroupManager $groupManager,
216
+                                ISecureRandom $random,
217
+                                ILogger $logger,
218
+                                IEventDispatcher $dispatcher,
219
+                                EventDispatcherInterface $legacyDispatcher,
220
+                                bool $legacyEndpoint = false) {
221
+        $this->db = $db;
222
+        $this->principalBackend = $principalBackend;
223
+        $this->userManager = $userManager;
224
+        $this->calendarSharingBackend = new Backend($this->db, $this->userManager, $groupManager, $principalBackend, 'calendar');
225
+        $this->random = $random;
226
+        $this->logger = $logger;
227
+        $this->dispatcher = $dispatcher;
228
+        $this->legacyDispatcher = $legacyDispatcher;
229
+        $this->legacyEndpoint = $legacyEndpoint;
230
+    }
231
+
232
+    /**
233
+     * Return the number of calendars for a principal
234
+     *
235
+     * By default this excludes the automatically generated birthday calendar
236
+     *
237
+     * @param $principalUri
238
+     * @param bool $excludeBirthday
239
+     * @return int
240
+     */
241
+    public function getCalendarsForUserCount($principalUri, $excludeBirthday = true) {
242
+        $principalUri = $this->convertPrincipal($principalUri, true);
243
+        $query = $this->db->getQueryBuilder();
244
+        $query->select($query->func()->count('*'))
245
+            ->from('calendars');
246
+
247
+        if ($principalUri === '') {
248
+            $query->where($query->expr()->emptyString('principaluri'));
249
+        } else {
250
+            $query->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)));
251
+        }
252
+
253
+        if ($excludeBirthday) {
254
+            $query->andWhere($query->expr()->neq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI)));
255
+        }
256
+
257
+        $result = $query->execute();
258
+        $column = (int)$result->fetchColumn();
259
+        $result->closeCursor();
260
+        return $column;
261
+    }
262
+
263
+    /**
264
+     * Returns a list of calendars for a principal.
265
+     *
266
+     * Every project is an array with the following keys:
267
+     *  * id, a unique id that will be used by other functions to modify the
268
+     *    calendar. This can be the same as the uri or a database key.
269
+     *  * uri, which the basename of the uri with which the calendar is
270
+     *    accessed.
271
+     *  * principaluri. The owner of the calendar. Almost always the same as
272
+     *    principalUri passed to this method.
273
+     *
274
+     * Furthermore it can contain webdav properties in clark notation. A very
275
+     * common one is '{DAV:}displayname'.
276
+     *
277
+     * Many clients also require:
278
+     * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
279
+     * For this property, you can just return an instance of
280
+     * Sabre\CalDAV\Property\SupportedCalendarComponentSet.
281
+     *
282
+     * If you return {http://sabredav.org/ns}read-only and set the value to 1,
283
+     * ACL will automatically be put in read-only mode.
284
+     *
285
+     * @param string $principalUri
286
+     * @return array
287
+     */
288
+    public function getCalendarsForUser($principalUri) {
289
+        $principalUriOriginal = $principalUri;
290
+        $principalUri = $this->convertPrincipal($principalUri, true);
291
+        $fields = array_values($this->propertyMap);
292
+        $fields[] = 'id';
293
+        $fields[] = 'uri';
294
+        $fields[] = 'synctoken';
295
+        $fields[] = 'components';
296
+        $fields[] = 'principaluri';
297
+        $fields[] = 'transparent';
298
+
299
+        // Making fields a comma-delimited list
300
+        $query = $this->db->getQueryBuilder();
301
+        $query->select($fields)
302
+            ->from('calendars')
303
+            ->orderBy('calendarorder', 'ASC');
304
+
305
+        if ($principalUri === '') {
306
+            $query->where($query->expr()->emptyString('principaluri'));
307
+        } else {
308
+            $query->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)));
309
+        }
310
+
311
+        $result = $query->execute();
312
+
313
+        $calendars = [];
314
+        while ($row = $result->fetch()) {
315
+            $row['principaluri'] = (string) $row['principaluri'];
316
+            $components = [];
317
+            if ($row['components']) {
318
+                $components = explode(',',$row['components']);
319
+            }
320
+
321
+            $calendar = [
322
+                'id' => $row['id'],
323
+                'uri' => $row['uri'],
324
+                'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
325
+                '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
326
+                '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
327
+                '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
328
+                '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
329
+                '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
330
+            ];
331
+
332
+            foreach ($this->propertyMap as $xmlName => $dbName) {
333
+                $calendar[$xmlName] = $row[$dbName];
334
+            }
335
+
336
+            $this->addOwnerPrincipal($calendar);
337
+
338
+            if (!isset($calendars[$calendar['id']])) {
339
+                $calendars[$calendar['id']] = $calendar;
340
+            }
341
+        }
342
+        $result->closeCursor();
343
+
344
+        // query for shared calendars
345
+        $principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true);
346
+        $principals = array_merge($principals, $this->principalBackend->getCircleMembership($principalUriOriginal));
347
+
348
+        $principals = array_map(function ($principal) {
349
+            return urldecode($principal);
350
+        }, $principals);
351
+        $principals[] = $principalUri;
352
+
353
+        $fields = array_values($this->propertyMap);
354
+        $fields[] = 'a.id';
355
+        $fields[] = 'a.uri';
356
+        $fields[] = 'a.synctoken';
357
+        $fields[] = 'a.components';
358
+        $fields[] = 'a.principaluri';
359
+        $fields[] = 'a.transparent';
360
+        $fields[] = 's.access';
361
+        $query = $this->db->getQueryBuilder();
362
+        $query->select($fields)
363
+            ->from('dav_shares', 's')
364
+            ->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id'))
365
+            ->where($query->expr()->in('s.principaluri', $query->createParameter('principaluri')))
366
+            ->andWhere($query->expr()->eq('s.type', $query->createParameter('type')))
367
+            ->setParameter('type', 'calendar')
368
+            ->setParameter('principaluri', $principals, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);
369
+
370
+        $result	= $query->execute();
371
+
372
+        $readOnlyPropertyName = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only';
373
+        while ($row = $result->fetch()) {
374
+            $row['principaluri'] = (string) $row['principaluri'];
375
+            if ($row['principaluri'] === $principalUri) {
376
+                continue;
377
+            }
378
+
379
+            $readOnly = (int) $row['access'] === Backend::ACCESS_READ;
380
+            if (isset($calendars[$row['id']])) {
381
+                if ($readOnly) {
382
+                    // New share can not have more permissions then the old one.
383
+                    continue;
384
+                }
385
+                if (isset($calendars[$row['id']][$readOnlyPropertyName]) &&
386
+                    $calendars[$row['id']][$readOnlyPropertyName] === 0) {
387
+                    // Old share is already read-write, no more permissions can be gained
388
+                    continue;
389
+                }
390
+            }
391
+
392
+            list(, $name) = Uri\split($row['principaluri']);
393
+            $uri = $row['uri'] . '_shared_by_' . $name;
394
+            $row['displayname'] = $row['displayname'] . ' (' . $this->getUserDisplayName($name) . ')';
395
+            $components = [];
396
+            if ($row['components']) {
397
+                $components = explode(',',$row['components']);
398
+            }
399
+            $calendar = [
400
+                'id' => $row['id'],
401
+                'uri' => $uri,
402
+                'principaluri' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
403
+                '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
404
+                '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
405
+                '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
406
+                '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp('transparent'),
407
+                '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
408
+                $readOnlyPropertyName => $readOnly,
409
+            ];
410
+
411
+            foreach ($this->propertyMap as $xmlName => $dbName) {
412
+                $calendar[$xmlName] = $row[$dbName];
413
+            }
414
+
415
+            $this->addOwnerPrincipal($calendar);
416
+
417
+            $calendars[$calendar['id']] = $calendar;
418
+        }
419
+        $result->closeCursor();
420
+
421
+        return array_values($calendars);
422
+    }
423
+
424
+    /**
425
+     * @param $principalUri
426
+     * @return array
427
+     */
428
+    public function getUsersOwnCalendars($principalUri) {
429
+        $principalUri = $this->convertPrincipal($principalUri, true);
430
+        $fields = array_values($this->propertyMap);
431
+        $fields[] = 'id';
432
+        $fields[] = 'uri';
433
+        $fields[] = 'synctoken';
434
+        $fields[] = 'components';
435
+        $fields[] = 'principaluri';
436
+        $fields[] = 'transparent';
437
+        // Making fields a comma-delimited list
438
+        $query = $this->db->getQueryBuilder();
439
+        $query->select($fields)->from('calendars')
440
+            ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
441
+            ->orderBy('calendarorder', 'ASC');
442
+        $stmt = $query->execute();
443
+        $calendars = [];
444
+        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
445
+            $row['principaluri'] = (string) $row['principaluri'];
446
+            $components = [];
447
+            if ($row['components']) {
448
+                $components = explode(',',$row['components']);
449
+            }
450
+            $calendar = [
451
+                'id' => $row['id'],
452
+                'uri' => $row['uri'],
453
+                'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
454
+                '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
455
+                '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
456
+                '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
457
+                '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
458
+            ];
459
+            foreach ($this->propertyMap as $xmlName => $dbName) {
460
+                $calendar[$xmlName] = $row[$dbName];
461
+            }
462
+
463
+            $this->addOwnerPrincipal($calendar);
464
+
465
+            if (!isset($calendars[$calendar['id']])) {
466
+                $calendars[$calendar['id']] = $calendar;
467
+            }
468
+        }
469
+        $stmt->closeCursor();
470
+        return array_values($calendars);
471
+    }
472
+
473
+
474
+    /**
475
+     * @param $uid
476
+     * @return string
477
+     */
478
+    private function getUserDisplayName($uid) {
479
+        if (!isset($this->userDisplayNames[$uid])) {
480
+            $user = $this->userManager->get($uid);
481
+
482
+            if ($user instanceof IUser) {
483
+                $this->userDisplayNames[$uid] = $user->getDisplayName();
484
+            } else {
485
+                $this->userDisplayNames[$uid] = $uid;
486
+            }
487
+        }
488
+
489
+        return $this->userDisplayNames[$uid];
490
+    }
491
+
492
+    /**
493
+     * @return array
494
+     */
495
+    public function getPublicCalendars() {
496
+        $fields = array_values($this->propertyMap);
497
+        $fields[] = 'a.id';
498
+        $fields[] = 'a.uri';
499
+        $fields[] = 'a.synctoken';
500
+        $fields[] = 'a.components';
501
+        $fields[] = 'a.principaluri';
502
+        $fields[] = 'a.transparent';
503
+        $fields[] = 's.access';
504
+        $fields[] = 's.publicuri';
505
+        $calendars = [];
506
+        $query = $this->db->getQueryBuilder();
507
+        $result = $query->select($fields)
508
+            ->from('dav_shares', 's')
509
+            ->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id'))
510
+            ->where($query->expr()->in('s.access', $query->createNamedParameter(self::ACCESS_PUBLIC)))
511
+            ->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar')))
512
+            ->execute();
513
+
514
+        while ($row = $result->fetch()) {
515
+            $row['principaluri'] = (string) $row['principaluri'];
516
+            list(, $name) = Uri\split($row['principaluri']);
517
+            $row['displayname'] = $row['displayname'] . "($name)";
518
+            $components = [];
519
+            if ($row['components']) {
520
+                $components = explode(',',$row['components']);
521
+            }
522
+            $calendar = [
523
+                'id' => $row['id'],
524
+                'uri' => $row['publicuri'],
525
+                'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
526
+                '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
527
+                '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
528
+                '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
529
+                '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
530
+                '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], $this->legacyEndpoint),
531
+                '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ,
532
+                '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
533
+            ];
534
+
535
+            foreach ($this->propertyMap as $xmlName => $dbName) {
536
+                $calendar[$xmlName] = $row[$dbName];
537
+            }
538
+
539
+            $this->addOwnerPrincipal($calendar);
540
+
541
+            if (!isset($calendars[$calendar['id']])) {
542
+                $calendars[$calendar['id']] = $calendar;
543
+            }
544
+        }
545
+        $result->closeCursor();
546
+
547
+        return array_values($calendars);
548
+    }
549
+
550
+    /**
551
+     * @param string $uri
552
+     * @return array
553
+     * @throws NotFound
554
+     */
555
+    public function getPublicCalendar($uri) {
556
+        $fields = array_values($this->propertyMap);
557
+        $fields[] = 'a.id';
558
+        $fields[] = 'a.uri';
559
+        $fields[] = 'a.synctoken';
560
+        $fields[] = 'a.components';
561
+        $fields[] = 'a.principaluri';
562
+        $fields[] = 'a.transparent';
563
+        $fields[] = 's.access';
564
+        $fields[] = 's.publicuri';
565
+        $query = $this->db->getQueryBuilder();
566
+        $result = $query->select($fields)
567
+            ->from('dav_shares', 's')
568
+            ->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id'))
569
+            ->where($query->expr()->in('s.access', $query->createNamedParameter(self::ACCESS_PUBLIC)))
570
+            ->andWhere($query->expr()->eq('s.type', $query->createNamedParameter('calendar')))
571
+            ->andWhere($query->expr()->eq('s.publicuri', $query->createNamedParameter($uri)))
572
+            ->execute();
573
+
574
+        $row = $result->fetch(\PDO::FETCH_ASSOC);
575
+
576
+        $result->closeCursor();
577
+
578
+        if ($row === false) {
579
+            throw new NotFound('Node with name \'' . $uri . '\' could not be found');
580
+        }
581
+
582
+        $row['principaluri'] = (string) $row['principaluri'];
583
+        list(, $name) = Uri\split($row['principaluri']);
584
+        $row['displayname'] = $row['displayname'] . ' ' . "($name)";
585
+        $components = [];
586
+        if ($row['components']) {
587
+            $components = explode(',',$row['components']);
588
+        }
589
+        $calendar = [
590
+            'id' => $row['id'],
591
+            'uri' => $row['publicuri'],
592
+            'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
593
+            '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
594
+            '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
595
+            '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
596
+            '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
597
+            '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
598
+            '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ,
599
+            '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
600
+        ];
601
+
602
+        foreach ($this->propertyMap as $xmlName => $dbName) {
603
+            $calendar[$xmlName] = $row[$dbName];
604
+        }
605
+
606
+        $this->addOwnerPrincipal($calendar);
607
+
608
+        return $calendar;
609
+    }
610
+
611
+    /**
612
+     * @param string $principal
613
+     * @param string $uri
614
+     * @return array|null
615
+     */
616
+    public function getCalendarByUri($principal, $uri) {
617
+        $fields = array_values($this->propertyMap);
618
+        $fields[] = 'id';
619
+        $fields[] = 'uri';
620
+        $fields[] = 'synctoken';
621
+        $fields[] = 'components';
622
+        $fields[] = 'principaluri';
623
+        $fields[] = 'transparent';
624
+
625
+        // Making fields a comma-delimited list
626
+        $query = $this->db->getQueryBuilder();
627
+        $query->select($fields)->from('calendars')
628
+            ->where($query->expr()->eq('uri', $query->createNamedParameter($uri)))
629
+            ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($principal)))
630
+            ->setMaxResults(1);
631
+        $stmt = $query->execute();
632
+
633
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
634
+        $stmt->closeCursor();
635
+        if ($row === false) {
636
+            return null;
637
+        }
638
+
639
+        $row['principaluri'] = (string) $row['principaluri'];
640
+        $components = [];
641
+        if ($row['components']) {
642
+            $components = explode(',',$row['components']);
643
+        }
644
+
645
+        $calendar = [
646
+            'id' => $row['id'],
647
+            'uri' => $row['uri'],
648
+            'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
649
+            '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
650
+            '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
651
+            '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
652
+            '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
653
+        ];
654
+
655
+        foreach ($this->propertyMap as $xmlName => $dbName) {
656
+            $calendar[$xmlName] = $row[$dbName];
657
+        }
658
+
659
+        $this->addOwnerPrincipal($calendar);
660
+
661
+        return $calendar;
662
+    }
663
+
664
+    /**
665
+     * @param $calendarId
666
+     * @return array|null
667
+     */
668
+    public function getCalendarById($calendarId) {
669
+        $fields = array_values($this->propertyMap);
670
+        $fields[] = 'id';
671
+        $fields[] = 'uri';
672
+        $fields[] = 'synctoken';
673
+        $fields[] = 'components';
674
+        $fields[] = 'principaluri';
675
+        $fields[] = 'transparent';
676
+
677
+        // Making fields a comma-delimited list
678
+        $query = $this->db->getQueryBuilder();
679
+        $query->select($fields)->from('calendars')
680
+            ->where($query->expr()->eq('id', $query->createNamedParameter($calendarId)))
681
+            ->setMaxResults(1);
682
+        $stmt = $query->execute();
683
+
684
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
685
+        $stmt->closeCursor();
686
+        if ($row === false) {
687
+            return null;
688
+        }
689
+
690
+        $row['principaluri'] = (string) $row['principaluri'];
691
+        $components = [];
692
+        if ($row['components']) {
693
+            $components = explode(',',$row['components']);
694
+        }
695
+
696
+        $calendar = [
697
+            'id' => $row['id'],
698
+            'uri' => $row['uri'],
699
+            'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
700
+            '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
701
+            '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
702
+            '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
703
+            '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
704
+        ];
705
+
706
+        foreach ($this->propertyMap as $xmlName => $dbName) {
707
+            $calendar[$xmlName] = $row[$dbName];
708
+        }
709
+
710
+        $this->addOwnerPrincipal($calendar);
711
+
712
+        return $calendar;
713
+    }
714
+
715
+    /**
716
+     * @param $subscriptionId
717
+     */
718
+    public function getSubscriptionById($subscriptionId) {
719
+        $fields = array_values($this->subscriptionPropertyMap);
720
+        $fields[] = 'id';
721
+        $fields[] = 'uri';
722
+        $fields[] = 'source';
723
+        $fields[] = 'synctoken';
724
+        $fields[] = 'principaluri';
725
+        $fields[] = 'lastmodified';
726
+
727
+        $query = $this->db->getQueryBuilder();
728
+        $query->select($fields)
729
+            ->from('calendarsubscriptions')
730
+            ->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId)))
731
+            ->orderBy('calendarorder', 'asc');
732
+        $stmt = $query->execute();
733
+
734
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
735
+        $stmt->closeCursor();
736
+        if ($row === false) {
737
+            return null;
738
+        }
739
+
740
+        $row['principaluri'] = (string) $row['principaluri'];
741
+        $subscription = [
742
+            'id' => $row['id'],
743
+            'uri' => $row['uri'],
744
+            'principaluri' => $row['principaluri'],
745
+            'source' => $row['source'],
746
+            'lastmodified' => $row['lastmodified'],
747
+            '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
748
+            '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
749
+        ];
750
+
751
+        foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
752
+            if (!is_null($row[$dbName])) {
753
+                $subscription[$xmlName] = $row[$dbName];
754
+            }
755
+        }
756
+
757
+        return $subscription;
758
+    }
759
+
760
+    /**
761
+     * Creates a new calendar for a principal.
762
+     *
763
+     * If the creation was a success, an id must be returned that can be used to reference
764
+     * this calendar in other methods, such as updateCalendar.
765
+     *
766
+     * @param string $principalUri
767
+     * @param string $calendarUri
768
+     * @param array $properties
769
+     * @return int
770
+     */
771
+    public function createCalendar($principalUri, $calendarUri, array $properties) {
772
+        $values = [
773
+            'principaluri' => $this->convertPrincipal($principalUri, true),
774
+            'uri' => $calendarUri,
775
+            'synctoken' => 1,
776
+            'transparent' => 0,
777
+            'components' => 'VEVENT,VTODO',
778
+            'displayname' => $calendarUri
779
+        ];
780
+
781
+        // Default value
782
+        $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
783
+        if (isset($properties[$sccs])) {
784
+            if (!($properties[$sccs] instanceof SupportedCalendarComponentSet)) {
785
+                throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Property\SupportedCalendarComponentSet');
786
+            }
787
+            $values['components'] = implode(',',$properties[$sccs]->getValue());
788
+        } elseif (isset($properties['components'])) {
789
+            // Allow to provide components internally without having
790
+            // to create a SupportedCalendarComponentSet object
791
+            $values['components'] = $properties['components'];
792
+        }
793
+
794
+        $transp = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
795
+        if (isset($properties[$transp])) {
796
+            $values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent');
797
+        }
798
+
799
+        foreach ($this->propertyMap as $xmlName => $dbName) {
800
+            if (isset($properties[$xmlName])) {
801
+                $values[$dbName] = $properties[$xmlName];
802
+            }
803
+        }
804
+
805
+        $query = $this->db->getQueryBuilder();
806
+        $query->insert('calendars');
807
+        foreach ($values as $column => $value) {
808
+            $query->setValue($column, $query->createNamedParameter($value));
809
+        }
810
+        $query->execute();
811
+        $calendarId = $query->getLastInsertId();
812
+
813
+        $calendarData = $this->getCalendarById($calendarId);
814
+        $this->dispatcher->dispatchTyped(new CalendarCreatedEvent((int)$calendarId, $calendarData));
815
+        $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', new GenericEvent(
816
+            '\OCA\DAV\CalDAV\CalDavBackend::createCalendar',
817
+            [
818
+                'calendarId' => $calendarId,
819
+                'calendarData' => $calendarData,
820
+            ]));
821
+
822
+        return $calendarId;
823
+    }
824
+
825
+    /**
826
+     * Updates properties for a calendar.
827
+     *
828
+     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
829
+     * To do the actual updates, you must tell this object which properties
830
+     * you're going to process with the handle() method.
831
+     *
832
+     * Calling the handle method is like telling the PropPatch object "I
833
+     * promise I can handle updating this property".
834
+     *
835
+     * Read the PropPatch documentation for more info and examples.
836
+     *
837
+     * @param mixed $calendarId
838
+     * @param PropPatch $propPatch
839
+     * @return void
840
+     */
841
+    public function updateCalendar($calendarId, PropPatch $propPatch) {
842
+        $supportedProperties = array_keys($this->propertyMap);
843
+        $supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
844
+
845
+        $propPatch->handle($supportedProperties, function ($mutations) use ($calendarId) {
846
+            $newValues = [];
847
+            foreach ($mutations as $propertyName => $propertyValue) {
848
+                switch ($propertyName) {
849
+                    case '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp':
850
+                        $fieldName = 'transparent';
851
+                        $newValues[$fieldName] = (int) ($propertyValue->getValue() === 'transparent');
852
+                        break;
853
+                    default:
854
+                        $fieldName = $this->propertyMap[$propertyName];
855
+                        $newValues[$fieldName] = $propertyValue;
856
+                        break;
857
+                }
858
+            }
859
+            $query = $this->db->getQueryBuilder();
860
+            $query->update('calendars');
861
+            foreach ($newValues as $fieldName => $value) {
862
+                $query->set($fieldName, $query->createNamedParameter($value));
863
+            }
864
+            $query->where($query->expr()->eq('id', $query->createNamedParameter($calendarId)));
865
+            $query->execute();
866
+
867
+            $this->addChange($calendarId, "", 2);
868
+
869
+            $calendarData = $this->getCalendarById($calendarId);
870
+            $shares = $this->getShares($calendarId);
871
+            $this->dispatcher->dispatchTyped(new CalendarUpdatedEvent((int)$calendarId, $calendarData, $shares, $mutations));
872
+            $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', new GenericEvent(
873
+                '\OCA\DAV\CalDAV\CalDavBackend::updateCalendar',
874
+                [
875
+                    'calendarId' => $calendarId,
876
+                    'calendarData' => $calendarData,
877
+                    'shares' => $shares,
878
+                    'propertyMutations' => $mutations,
879
+                ]));
880
+
881
+            return true;
882
+        });
883
+    }
884
+
885
+    /**
886
+     * Delete a calendar and all it's objects
887
+     *
888
+     * @param mixed $calendarId
889
+     * @return void
890
+     */
891
+    public function deleteCalendar($calendarId) {
892
+        $calendarData = $this->getCalendarById($calendarId);
893
+        $shares = $this->getShares($calendarId);
894
+
895
+        $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', new GenericEvent(
896
+            '\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar',
897
+            [
898
+                'calendarId' => $calendarId,
899
+                'calendarData' => $calendarData,
900
+                'shares' => $shares,
901
+            ]));
902
+
903
+        $stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `calendartype` = ?');
904
+        $stmt->execute([$calendarId, self::CALENDAR_TYPE_CALENDAR]);
905
+
906
+        $stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendars` WHERE `id` = ?');
907
+        $stmt->execute([$calendarId]);
908
+
909
+        $stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarchanges` WHERE `calendarid` = ? AND `calendartype` = ?');
910
+        $stmt->execute([$calendarId, self::CALENDAR_TYPE_CALENDAR]);
911
+
912
+        $this->calendarSharingBackend->deleteAllShares($calendarId);
913
+
914
+        $query = $this->db->getQueryBuilder();
915
+        $query->delete($this->dbObjectPropertiesTable)
916
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
917
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)))
918
+            ->execute();
919
+
920
+        if ($calendarData) {
921
+            $this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int)$calendarId, $calendarData, $shares));
922
+        }
923
+    }
924
+
925
+    /**
926
+     * Delete all of an user's shares
927
+     *
928
+     * @param string $principaluri
929
+     * @return void
930
+     */
931
+    public function deleteAllSharesByUser($principaluri) {
932
+        $this->calendarSharingBackend->deleteAllSharesByUser($principaluri);
933
+    }
934
+
935
+    /**
936
+     * Returns all calendar objects within a calendar.
937
+     *
938
+     * Every item contains an array with the following keys:
939
+     *   * calendardata - The iCalendar-compatible calendar data
940
+     *   * uri - a unique key which will be used to construct the uri. This can
941
+     *     be any arbitrary string, but making sure it ends with '.ics' is a
942
+     *     good idea. This is only the basename, or filename, not the full
943
+     *     path.
944
+     *   * lastmodified - a timestamp of the last modification time
945
+     *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
946
+     *   '"abcdef"')
947
+     *   * size - The size of the calendar objects, in bytes.
948
+     *   * component - optional, a string containing the type of object, such
949
+     *     as 'vevent' or 'vtodo'. If specified, this will be used to populate
950
+     *     the Content-Type header.
951
+     *
952
+     * Note that the etag is optional, but it's highly encouraged to return for
953
+     * speed reasons.
954
+     *
955
+     * The calendardata is also optional. If it's not returned
956
+     * 'getCalendarObject' will be called later, which *is* expected to return
957
+     * calendardata.
958
+     *
959
+     * If neither etag or size are specified, the calendardata will be
960
+     * used/fetched to determine these numbers. If both are specified the
961
+     * amount of times this is needed is reduced by a great degree.
962
+     *
963
+     * @param mixed $calendarId
964
+     * @param int $calendarType
965
+     * @return array
966
+     */
967
+    public function getCalendarObjects($calendarId, $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
968
+        $query = $this->db->getQueryBuilder();
969
+        $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification'])
970
+            ->from('calendarobjects')
971
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
972
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
973
+        $stmt = $query->execute();
974
+
975
+        $result = [];
976
+        foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
977
+            $result[] = [
978
+                'id' => $row['id'],
979
+                'uri' => $row['uri'],
980
+                'lastmodified' => $row['lastmodified'],
981
+                'etag' => '"' . $row['etag'] . '"',
982
+                'calendarid' => $row['calendarid'],
983
+                'size' => (int)$row['size'],
984
+                'component' => strtolower($row['componenttype']),
985
+                'classification' => (int)$row['classification']
986
+            ];
987
+        }
988
+        $stmt->closeCursor();
989
+
990
+        return $result;
991
+    }
992
+
993
+    /**
994
+     * Returns information from a single calendar object, based on it's object
995
+     * uri.
996
+     *
997
+     * The object uri is only the basename, or filename and not a full path.
998
+     *
999
+     * The returned array must have the same keys as getCalendarObjects. The
1000
+     * 'calendardata' object is required here though, while it's not required
1001
+     * for getCalendarObjects.
1002
+     *
1003
+     * This method must return null if the object did not exist.
1004
+     *
1005
+     * @param mixed $calendarId
1006
+     * @param string $objectUri
1007
+     * @param int $calendarType
1008
+     * @return array|null
1009
+     */
1010
+    public function getCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1011
+        $query = $this->db->getQueryBuilder();
1012
+        $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
1013
+            ->from('calendarobjects')
1014
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1015
+            ->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
1016
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
1017
+        $stmt = $query->execute();
1018
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
1019
+        $stmt->closeCursor();
1020
+
1021
+        if (!$row) {
1022
+            return null;
1023
+        }
1024
+
1025
+        return [
1026
+            'id' => $row['id'],
1027
+            'uri' => $row['uri'],
1028
+            'lastmodified' => $row['lastmodified'],
1029
+            'etag' => '"' . $row['etag'] . '"',
1030
+            'calendarid' => $row['calendarid'],
1031
+            'size' => (int)$row['size'],
1032
+            'calendardata' => $this->readBlob($row['calendardata']),
1033
+            'component' => strtolower($row['componenttype']),
1034
+            'classification' => (int)$row['classification']
1035
+        ];
1036
+    }
1037
+
1038
+    /**
1039
+     * Returns a list of calendar objects.
1040
+     *
1041
+     * This method should work identical to getCalendarObject, but instead
1042
+     * return all the calendar objects in the list as an array.
1043
+     *
1044
+     * If the backend supports this, it may allow for some speed-ups.
1045
+     *
1046
+     * @param mixed $calendarId
1047
+     * @param string[] $uris
1048
+     * @param int $calendarType
1049
+     * @return array
1050
+     */
1051
+    public function getMultipleCalendarObjects($calendarId, array $uris, $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
1052
+        if (empty($uris)) {
1053
+            return [];
1054
+        }
1055
+
1056
+        $chunks = array_chunk($uris, 100);
1057
+        $objects = [];
1058
+
1059
+        $query = $this->db->getQueryBuilder();
1060
+        $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
1061
+            ->from('calendarobjects')
1062
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1063
+            ->andWhere($query->expr()->in('uri', $query->createParameter('uri')))
1064
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
1065
+
1066
+        foreach ($chunks as $uris) {
1067
+            $query->setParameter('uri', $uris, IQueryBuilder::PARAM_STR_ARRAY);
1068
+            $result = $query->execute();
1069
+
1070
+            while ($row = $result->fetch()) {
1071
+                $objects[] = [
1072
+                    'id' => $row['id'],
1073
+                    'uri' => $row['uri'],
1074
+                    'lastmodified' => $row['lastmodified'],
1075
+                    'etag' => '"' . $row['etag'] . '"',
1076
+                    'calendarid' => $row['calendarid'],
1077
+                    'size' => (int)$row['size'],
1078
+                    'calendardata' => $this->readBlob($row['calendardata']),
1079
+                    'component' => strtolower($row['componenttype']),
1080
+                    'classification' => (int)$row['classification']
1081
+                ];
1082
+            }
1083
+            $result->closeCursor();
1084
+        }
1085
+
1086
+        return $objects;
1087
+    }
1088
+
1089
+    /**
1090
+     * Creates a new calendar object.
1091
+     *
1092
+     * The object uri is only the basename, or filename and not a full path.
1093
+     *
1094
+     * It is possible return an etag from this function, which will be used in
1095
+     * the response to this PUT request. Note that the ETag must be surrounded
1096
+     * by double-quotes.
1097
+     *
1098
+     * However, you should only really return this ETag if you don't mangle the
1099
+     * calendar-data. If the result of a subsequent GET to this object is not
1100
+     * the exact same as this request body, you should omit the ETag.
1101
+     *
1102
+     * @param mixed $calendarId
1103
+     * @param string $objectUri
1104
+     * @param string $calendarData
1105
+     * @param int $calendarType
1106
+     * @return string
1107
+     */
1108
+    public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1109
+        $extraData = $this->getDenormalizedData($calendarData);
1110
+
1111
+        $q = $this->db->getQueryBuilder();
1112
+        $q->select($q->func()->count('*'))
1113
+            ->from('calendarobjects')
1114
+            ->where($q->expr()->eq('calendarid', $q->createNamedParameter($calendarId)))
1115
+            ->andWhere($q->expr()->eq('uid', $q->createNamedParameter($extraData['uid'])))
1116
+            ->andWhere($q->expr()->eq('calendartype', $q->createNamedParameter($calendarType)));
1117
+
1118
+        $result = $q->execute();
1119
+        $count = (int) $result->fetchColumn();
1120
+        $result->closeCursor();
1121
+
1122
+        if ($count !== 0) {
1123
+            throw new \Sabre\DAV\Exception\BadRequest('Calendar object with uid already exists in this calendar collection.');
1124
+        }
1125
+
1126
+        $query = $this->db->getQueryBuilder();
1127
+        $query->insert('calendarobjects')
1128
+            ->values([
1129
+                'calendarid' => $query->createNamedParameter($calendarId),
1130
+                'uri' => $query->createNamedParameter($objectUri),
1131
+                'calendardata' => $query->createNamedParameter($calendarData, IQueryBuilder::PARAM_LOB),
1132
+                'lastmodified' => $query->createNamedParameter(time()),
1133
+                'etag' => $query->createNamedParameter($extraData['etag']),
1134
+                'size' => $query->createNamedParameter($extraData['size']),
1135
+                'componenttype' => $query->createNamedParameter($extraData['componentType']),
1136
+                'firstoccurence' => $query->createNamedParameter($extraData['firstOccurence']),
1137
+                'lastoccurence' => $query->createNamedParameter($extraData['lastOccurence']),
1138
+                'classification' => $query->createNamedParameter($extraData['classification']),
1139
+                'uid' => $query->createNamedParameter($extraData['uid']),
1140
+                'calendartype' => $query->createNamedParameter($calendarType),
1141
+            ])
1142
+            ->execute();
1143
+
1144
+        $this->updateProperties($calendarId, $objectUri, $calendarData, $calendarType);
1145
+        $this->addChange($calendarId, $objectUri, 1, $calendarType);
1146
+
1147
+        $objectRow = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
1148
+        if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
1149
+            $calendarRow = $this->getCalendarById($calendarId);
1150
+            $shares = $this->getShares($calendarId);
1151
+
1152
+            $this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
1153
+            $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', new GenericEvent(
1154
+                '\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject',
1155
+                [
1156
+                    'calendarId' => $calendarId,
1157
+                    'calendarData' => $calendarRow,
1158
+                    'shares' => $shares,
1159
+                    'objectData' => $objectRow,
1160
+                ]
1161
+            ));
1162
+        } else {
1163
+            $subscriptionRow = $this->getSubscriptionById($calendarId);
1164
+
1165
+            $this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
1166
+            $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject', new GenericEvent(
1167
+                '\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject',
1168
+                [
1169
+                    'subscriptionId' => $calendarId,
1170
+                    'calendarData' => $subscriptionRow,
1171
+                    'shares' => [],
1172
+                    'objectData' => $objectRow,
1173
+                ]
1174
+            ));
1175
+        }
1176
+
1177
+        return '"' . $extraData['etag'] . '"';
1178
+    }
1179
+
1180
+    /**
1181
+     * Updates an existing calendarobject, based on it's uri.
1182
+     *
1183
+     * The object uri is only the basename, or filename and not a full path.
1184
+     *
1185
+     * It is possible return an etag from this function, which will be used in
1186
+     * the response to this PUT request. Note that the ETag must be surrounded
1187
+     * by double-quotes.
1188
+     *
1189
+     * However, you should only really return this ETag if you don't mangle the
1190
+     * calendar-data. If the result of a subsequent GET to this object is not
1191
+     * the exact same as this request body, you should omit the ETag.
1192
+     *
1193
+     * @param mixed $calendarId
1194
+     * @param string $objectUri
1195
+     * @param string $calendarData
1196
+     * @param int $calendarType
1197
+     * @return string
1198
+     */
1199
+    public function updateCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1200
+        $extraData = $this->getDenormalizedData($calendarData);
1201
+        $query = $this->db->getQueryBuilder();
1202
+        $query->update('calendarobjects')
1203
+                ->set('calendardata', $query->createNamedParameter($calendarData, IQueryBuilder::PARAM_LOB))
1204
+                ->set('lastmodified', $query->createNamedParameter(time()))
1205
+                ->set('etag', $query->createNamedParameter($extraData['etag']))
1206
+                ->set('size', $query->createNamedParameter($extraData['size']))
1207
+                ->set('componenttype', $query->createNamedParameter($extraData['componentType']))
1208
+                ->set('firstoccurence', $query->createNamedParameter($extraData['firstOccurence']))
1209
+                ->set('lastoccurence', $query->createNamedParameter($extraData['lastOccurence']))
1210
+                ->set('classification', $query->createNamedParameter($extraData['classification']))
1211
+                ->set('uid', $query->createNamedParameter($extraData['uid']))
1212
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1213
+            ->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
1214
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
1215
+            ->execute();
1216
+
1217
+        $this->updateProperties($calendarId, $objectUri, $calendarData, $calendarType);
1218
+        $this->addChange($calendarId, $objectUri, 2, $calendarType);
1219
+
1220
+        $objectRow = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
1221
+        if (is_array($objectRow)) {
1222
+            if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
1223
+                $calendarRow = $this->getCalendarById($calendarId);
1224
+                $shares = $this->getShares($calendarId);
1225
+
1226
+                $this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
1227
+                $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', new GenericEvent(
1228
+                    '\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject',
1229
+                    [
1230
+                        'calendarId' => $calendarId,
1231
+                        'calendarData' => $calendarRow,
1232
+                        'shares' => $shares,
1233
+                        'objectData' => $objectRow,
1234
+                    ]
1235
+                ));
1236
+            } else {
1237
+                $subscriptionRow = $this->getSubscriptionById($calendarId);
1238
+
1239
+                $this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
1240
+                $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject', new GenericEvent(
1241
+                    '\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject',
1242
+                    [
1243
+                        'subscriptionId' => $calendarId,
1244
+                        'calendarData' => $subscriptionRow,
1245
+                        'shares' => [],
1246
+                        'objectData' => $objectRow,
1247
+                    ]
1248
+                ));
1249
+            }
1250
+        }
1251
+
1252
+        return '"' . $extraData['etag'] . '"';
1253
+    }
1254
+
1255
+    /**
1256
+     * @param int $calendarObjectId
1257
+     * @param int $classification
1258
+     */
1259
+    public function setClassification($calendarObjectId, $classification) {
1260
+        if (!in_array($classification, [
1261
+            self::CLASSIFICATION_PUBLIC, self::CLASSIFICATION_PRIVATE, self::CLASSIFICATION_CONFIDENTIAL
1262
+        ])) {
1263
+            throw new \InvalidArgumentException();
1264
+        }
1265
+        $query = $this->db->getQueryBuilder();
1266
+        $query->update('calendarobjects')
1267
+            ->set('classification', $query->createNamedParameter($classification))
1268
+            ->where($query->expr()->eq('id', $query->createNamedParameter($calendarObjectId)))
1269
+            ->execute();
1270
+    }
1271
+
1272
+    /**
1273
+     * Deletes an existing calendar object.
1274
+     *
1275
+     * The object uri is only the basename, or filename and not a full path.
1276
+     *
1277
+     * @param mixed $calendarId
1278
+     * @param string $objectUri
1279
+     * @param int $calendarType
1280
+     * @return void
1281
+     */
1282
+    public function deleteCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1283
+        $data = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
1284
+        if (is_array($data)) {
1285
+            if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
1286
+                $calendarRow = $this->getCalendarById($calendarId);
1287
+                $shares = $this->getShares($calendarId);
1288
+
1289
+                $this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent((int)$calendarId, $calendarRow, $shares, $data));
1290
+                $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', new GenericEvent(
1291
+                    '\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject',
1292
+                    [
1293
+                        'calendarId' => $calendarId,
1294
+                        'calendarData' => $calendarRow,
1295
+                        'shares' => $shares,
1296
+                        'objectData' => $data,
1297
+                    ]
1298
+                ));
1299
+            } else {
1300
+                $subscriptionRow = $this->getSubscriptionById($calendarId);
1301
+
1302
+                $this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent((int)$calendarId, $subscriptionRow, [], $data));
1303
+                $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject', new GenericEvent(
1304
+                    '\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject',
1305
+                    [
1306
+                        'subscriptionId' => $calendarId,
1307
+                        'calendarData' => $subscriptionRow,
1308
+                        'shares' => [],
1309
+                        'objectData' => $data,
1310
+                    ]
1311
+                ));
1312
+            }
1313
+        }
1314
+
1315
+        $stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `uri` = ? AND `calendartype` = ?');
1316
+        $stmt->execute([$calendarId, $objectUri, $calendarType]);
1317
+
1318
+        if (is_array($data)) {
1319
+            $this->purgeProperties($calendarId, $data['id'], $calendarType);
1320
+        }
1321
+
1322
+        $this->addChange($calendarId, $objectUri, 3, $calendarType);
1323
+    }
1324
+
1325
+    /**
1326
+     * Performs a calendar-query on the contents of this calendar.
1327
+     *
1328
+     * The calendar-query is defined in RFC4791 : CalDAV. Using the
1329
+     * calendar-query it is possible for a client to request a specific set of
1330
+     * object, based on contents of iCalendar properties, date-ranges and
1331
+     * iCalendar component types (VTODO, VEVENT).
1332
+     *
1333
+     * This method should just return a list of (relative) urls that match this
1334
+     * query.
1335
+     *
1336
+     * The list of filters are specified as an array. The exact array is
1337
+     * documented by Sabre\CalDAV\CalendarQueryParser.
1338
+     *
1339
+     * Note that it is extremely likely that getCalendarObject for every path
1340
+     * returned from this method will be called almost immediately after. You
1341
+     * may want to anticipate this to speed up these requests.
1342
+     *
1343
+     * This method provides a default implementation, which parses *all* the
1344
+     * iCalendar objects in the specified calendar.
1345
+     *
1346
+     * This default may well be good enough for personal use, and calendars
1347
+     * that aren't very large. But if you anticipate high usage, big calendars
1348
+     * or high loads, you are strongly advised to optimize certain paths.
1349
+     *
1350
+     * The best way to do so is override this method and to optimize
1351
+     * specifically for 'common filters'.
1352
+     *
1353
+     * Requests that are extremely common are:
1354
+     *   * requests for just VEVENTS
1355
+     *   * requests for just VTODO
1356
+     *   * requests with a time-range-filter on either VEVENT or VTODO.
1357
+     *
1358
+     * ..and combinations of these requests. It may not be worth it to try to
1359
+     * handle every possible situation and just rely on the (relatively
1360
+     * easy to use) CalendarQueryValidator to handle the rest.
1361
+     *
1362
+     * Note that especially time-range-filters may be difficult to parse. A
1363
+     * time-range filter specified on a VEVENT must for instance also handle
1364
+     * recurrence rules correctly.
1365
+     * A good example of how to interprete all these filters can also simply
1366
+     * be found in Sabre\CalDAV\CalendarQueryFilter. This class is as correct
1367
+     * as possible, so it gives you a good idea on what type of stuff you need
1368
+     * to think of.
1369
+     *
1370
+     * @param mixed $calendarId
1371
+     * @param array $filters
1372
+     * @param int $calendarType
1373
+     * @return array
1374
+     */
1375
+    public function calendarQuery($calendarId, array $filters, $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
1376
+        $componentType = null;
1377
+        $requirePostFilter = true;
1378
+        $timeRange = null;
1379
+
1380
+        // if no filters were specified, we don't need to filter after a query
1381
+        if (!$filters['prop-filters'] && !$filters['comp-filters']) {
1382
+            $requirePostFilter = false;
1383
+        }
1384
+
1385
+        // Figuring out if there's a component filter
1386
+        if (count($filters['comp-filters']) > 0 && !$filters['comp-filters'][0]['is-not-defined']) {
1387
+            $componentType = $filters['comp-filters'][0]['name'];
1388
+
1389
+            // Checking if we need post-filters
1390
+            if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['time-range'] && !$filters['comp-filters'][0]['prop-filters']) {
1391
+                $requirePostFilter = false;
1392
+            }
1393
+            // There was a time-range filter
1394
+            if ($componentType === 'VEVENT' && isset($filters['comp-filters'][0]['time-range']) && is_array($filters['comp-filters'][0]['time-range'])) {
1395
+                $timeRange = $filters['comp-filters'][0]['time-range'];
1396
+
1397
+                // If start time OR the end time is not specified, we can do a
1398
+                // 100% accurate mysql query.
1399
+                if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && (!$timeRange['start'] || !$timeRange['end'])) {
1400
+                    $requirePostFilter = false;
1401
+                }
1402
+            }
1403
+        }
1404
+        $columns = ['uri'];
1405
+        if ($requirePostFilter) {
1406
+            $columns = ['uri', 'calendardata'];
1407
+        }
1408
+        $query = $this->db->getQueryBuilder();
1409
+        $query->select($columns)
1410
+            ->from('calendarobjects')
1411
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
1412
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
1413
+
1414
+        if ($componentType) {
1415
+            $query->andWhere($query->expr()->eq('componenttype', $query->createNamedParameter($componentType)));
1416
+        }
1417
+
1418
+        if ($timeRange && $timeRange['start']) {
1419
+            $query->andWhere($query->expr()->gt('lastoccurence', $query->createNamedParameter($timeRange['start']->getTimeStamp())));
1420
+        }
1421
+        if ($timeRange && $timeRange['end']) {
1422
+            $query->andWhere($query->expr()->lt('firstoccurence', $query->createNamedParameter($timeRange['end']->getTimeStamp())));
1423
+        }
1424
+
1425
+        $stmt = $query->execute();
1426
+
1427
+        $result = [];
1428
+        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1429
+            if ($requirePostFilter) {
1430
+                // validateFilterForObject will parse the calendar data
1431
+                // catch parsing errors
1432
+                try {
1433
+                    $matches = $this->validateFilterForObject($row, $filters);
1434
+                } catch (ParseException $ex) {
1435
+                    $this->logger->logException($ex, [
1436
+                        'app' => 'dav',
1437
+                        'message' => 'Caught parsing exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$calendarId.' uri:'.$row['uri']
1438
+                    ]);
1439
+                    continue;
1440
+                } catch (InvalidDataException $ex) {
1441
+                    $this->logger->logException($ex, [
1442
+                        'app' => 'dav',
1443
+                        'message' => 'Caught invalid data exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$calendarId.' uri:'.$row['uri']
1444
+                    ]);
1445
+                    continue;
1446
+                }
1447
+
1448
+                if (!$matches) {
1449
+                    continue;
1450
+                }
1451
+            }
1452
+            $result[] = $row['uri'];
1453
+        }
1454
+
1455
+        return $result;
1456
+    }
1457
+
1458
+    /**
1459
+     * custom Nextcloud search extension for CalDAV
1460
+     *
1461
+     * TODO - this should optionally cover cached calendar objects as well
1462
+     *
1463
+     * @param string $principalUri
1464
+     * @param array $filters
1465
+     * @param integer|null $limit
1466
+     * @param integer|null $offset
1467
+     * @return array
1468
+     */
1469
+    public function calendarSearch($principalUri, array $filters, $limit = null, $offset = null) {
1470
+        $calendars = $this->getCalendarsForUser($principalUri);
1471
+        $ownCalendars = [];
1472
+        $sharedCalendars = [];
1473
+
1474
+        $uriMapper = [];
1475
+
1476
+        foreach ($calendars as $calendar) {
1477
+            if ($calendar['{http://owncloud.org/ns}owner-principal'] === $principalUri) {
1478
+                $ownCalendars[] = $calendar['id'];
1479
+            } else {
1480
+                $sharedCalendars[] = $calendar['id'];
1481
+            }
1482
+            $uriMapper[$calendar['id']] = $calendar['uri'];
1483
+        }
1484
+        if (count($ownCalendars) === 0 && count($sharedCalendars) === 0) {
1485
+            return [];
1486
+        }
1487
+
1488
+        $query = $this->db->getQueryBuilder();
1489
+        // Calendar id expressions
1490
+        $calendarExpressions = [];
1491
+        foreach ($ownCalendars as $id) {
1492
+            $calendarExpressions[] = $query->expr()->andX(
1493
+                $query->expr()->eq('c.calendarid',
1494
+                    $query->createNamedParameter($id)),
1495
+                $query->expr()->eq('c.calendartype',
1496
+                        $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1497
+        }
1498
+        foreach ($sharedCalendars as $id) {
1499
+            $calendarExpressions[] = $query->expr()->andX(
1500
+                $query->expr()->eq('c.calendarid',
1501
+                    $query->createNamedParameter($id)),
1502
+                $query->expr()->eq('c.classification',
1503
+                    $query->createNamedParameter(self::CLASSIFICATION_PUBLIC)),
1504
+                $query->expr()->eq('c.calendartype',
1505
+                    $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1506
+        }
1507
+
1508
+        if (count($calendarExpressions) === 1) {
1509
+            $calExpr = $calendarExpressions[0];
1510
+        } else {
1511
+            $calExpr = call_user_func_array([$query->expr(), 'orX'], $calendarExpressions);
1512
+        }
1513
+
1514
+        // Component expressions
1515
+        $compExpressions = [];
1516
+        foreach ($filters['comps'] as $comp) {
1517
+            $compExpressions[] = $query->expr()
1518
+                ->eq('c.componenttype', $query->createNamedParameter($comp));
1519
+        }
1520
+
1521
+        if (count($compExpressions) === 1) {
1522
+            $compExpr = $compExpressions[0];
1523
+        } else {
1524
+            $compExpr = call_user_func_array([$query->expr(), 'orX'], $compExpressions);
1525
+        }
1526
+
1527
+        if (!isset($filters['props'])) {
1528
+            $filters['props'] = [];
1529
+        }
1530
+        if (!isset($filters['params'])) {
1531
+            $filters['params'] = [];
1532
+        }
1533
+
1534
+        $propParamExpressions = [];
1535
+        foreach ($filters['props'] as $prop) {
1536
+            $propParamExpressions[] = $query->expr()->andX(
1537
+                $query->expr()->eq('i.name', $query->createNamedParameter($prop)),
1538
+                $query->expr()->isNull('i.parameter')
1539
+            );
1540
+        }
1541
+        foreach ($filters['params'] as $param) {
1542
+            $propParamExpressions[] = $query->expr()->andX(
1543
+                $query->expr()->eq('i.name', $query->createNamedParameter($param['property'])),
1544
+                $query->expr()->eq('i.parameter', $query->createNamedParameter($param['parameter']))
1545
+            );
1546
+        }
1547
+
1548
+        if (count($propParamExpressions) === 1) {
1549
+            $propParamExpr = $propParamExpressions[0];
1550
+        } else {
1551
+            $propParamExpr = call_user_func_array([$query->expr(), 'orX'], $propParamExpressions);
1552
+        }
1553
+
1554
+        $query->select(['c.calendarid', 'c.uri'])
1555
+            ->from($this->dbObjectPropertiesTable, 'i')
1556
+            ->join('i', 'calendarobjects', 'c', $query->expr()->eq('i.objectid', 'c.id'))
1557
+            ->where($calExpr)
1558
+            ->andWhere($compExpr)
1559
+            ->andWhere($propParamExpr)
1560
+            ->andWhere($query->expr()->iLike('i.value',
1561
+                $query->createNamedParameter('%'.$this->db->escapeLikeParameter($filters['search-term']).'%')));
1562
+
1563
+        if ($offset) {
1564
+            $query->setFirstResult($offset);
1565
+        }
1566
+        if ($limit) {
1567
+            $query->setMaxResults($limit);
1568
+        }
1569
+
1570
+        $stmt = $query->execute();
1571
+
1572
+        $result = [];
1573
+        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1574
+            $path = $uriMapper[$row['calendarid']] . '/' . $row['uri'];
1575
+            if (!in_array($path, $result)) {
1576
+                $result[] = $path;
1577
+            }
1578
+        }
1579
+
1580
+        return $result;
1581
+    }
1582
+
1583
+    /**
1584
+     * used for Nextcloud's calendar API
1585
+     *
1586
+     * @param array $calendarInfo
1587
+     * @param string $pattern
1588
+     * @param array $searchProperties
1589
+     * @param array $options
1590
+     * @param integer|null $limit
1591
+     * @param integer|null $offset
1592
+     *
1593
+     * @return array
1594
+     */
1595
+    public function search(array $calendarInfo, $pattern, array $searchProperties,
1596
+                            array $options, $limit, $offset) {
1597
+        $outerQuery = $this->db->getQueryBuilder();
1598
+        $innerQuery = $this->db->getQueryBuilder();
1599
+
1600
+        $innerQuery->selectDistinct('op.objectid')
1601
+            ->from($this->dbObjectPropertiesTable, 'op')
1602
+            ->andWhere($innerQuery->expr()->eq('op.calendarid',
1603
+                $outerQuery->createNamedParameter($calendarInfo['id'])))
1604
+            ->andWhere($innerQuery->expr()->eq('op.calendartype',
1605
+                $outerQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1606
+
1607
+        // only return public items for shared calendars for now
1608
+        if ($calendarInfo['principaluri'] !== $calendarInfo['{http://owncloud.org/ns}owner-principal']) {
1609
+            $innerQuery->andWhere($innerQuery->expr()->eq('c.classification',
1610
+                $outerQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
1611
+        }
1612
+
1613
+        $or = $innerQuery->expr()->orX();
1614
+        foreach ($searchProperties as $searchProperty) {
1615
+            $or->add($innerQuery->expr()->eq('op.name',
1616
+                $outerQuery->createNamedParameter($searchProperty)));
1617
+        }
1618
+        $innerQuery->andWhere($or);
1619
+
1620
+        if ($pattern !== '') {
1621
+            $innerQuery->andWhere($innerQuery->expr()->iLike('op.value',
1622
+                $outerQuery->createNamedParameter('%' .
1623
+                    $this->db->escapeLikeParameter($pattern) . '%')));
1624
+        }
1625
+
1626
+        $outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid', 'c.uri')
1627
+            ->from('calendarobjects', 'c');
1628
+
1629
+        if (isset($options['timerange'])) {
1630
+            if (isset($options['timerange']['start']) && $options['timerange']['start'] instanceof DateTime) {
1631
+                $outerQuery->andWhere($outerQuery->expr()->gt('lastoccurence',
1632
+                    $outerQuery->createNamedParameter($options['timerange']['start']->getTimeStamp())));
1633
+            }
1634
+            if (isset($options['timerange']['end']) && $options['timerange']['end'] instanceof DateTime) {
1635
+                $outerQuery->andWhere($outerQuery->expr()->lt('firstoccurence',
1636
+                    $outerQuery->createNamedParameter($options['timerange']['end']->getTimeStamp())));
1637
+            }
1638
+        }
1639
+
1640
+        if (isset($options['types'])) {
1641
+            $or = $outerQuery->expr()->orX();
1642
+            foreach ($options['types'] as $type) {
1643
+                $or->add($outerQuery->expr()->eq('componenttype',
1644
+                    $outerQuery->createNamedParameter($type)));
1645
+            }
1646
+            $outerQuery->andWhere($or);
1647
+        }
1648
+
1649
+        $outerQuery->andWhere($outerQuery->expr()->in('c.id',
1650
+            $outerQuery->createFunction($innerQuery->getSQL())));
1651
+
1652
+        if ($offset) {
1653
+            $outerQuery->setFirstResult($offset);
1654
+        }
1655
+        if ($limit) {
1656
+            $outerQuery->setMaxResults($limit);
1657
+        }
1658
+
1659
+        $result = $outerQuery->execute();
1660
+        $calendarObjects = $result->fetchAll();
1661
+
1662
+        return array_map(function ($o) {
1663
+            $calendarData = Reader::read($o['calendardata']);
1664
+            $comps = $calendarData->getComponents();
1665
+            $objects = [];
1666
+            $timezones = [];
1667
+            foreach ($comps as $comp) {
1668
+                if ($comp instanceof VTimeZone) {
1669
+                    $timezones[] = $comp;
1670
+                } else {
1671
+                    $objects[] = $comp;
1672
+                }
1673
+            }
1674
+
1675
+            return [
1676
+                'id' => $o['id'],
1677
+                'type' => $o['componenttype'],
1678
+                'uid' => $o['uid'],
1679
+                'uri' => $o['uri'],
1680
+                'objects' => array_map(function ($c) {
1681
+                    return $this->transformSearchData($c);
1682
+                }, $objects),
1683
+                'timezones' => array_map(function ($c) {
1684
+                    return $this->transformSearchData($c);
1685
+                }, $timezones),
1686
+            ];
1687
+        }, $calendarObjects);
1688
+    }
1689
+
1690
+    /**
1691
+     * @param Component $comp
1692
+     * @return array
1693
+     */
1694
+    private function transformSearchData(Component $comp) {
1695
+        $data = [];
1696
+        /** @var Component[] $subComponents */
1697
+        $subComponents = $comp->getComponents();
1698
+        /** @var Property[] $properties */
1699
+        $properties = array_filter($comp->children(), function ($c) {
1700
+            return $c instanceof Property;
1701
+        });
1702
+        $validationRules = $comp->getValidationRules();
1703
+
1704
+        foreach ($subComponents as $subComponent) {
1705
+            $name = $subComponent->name;
1706
+            if (!isset($data[$name])) {
1707
+                $data[$name] = [];
1708
+            }
1709
+            $data[$name][] = $this->transformSearchData($subComponent);
1710
+        }
1711
+
1712
+        foreach ($properties as $property) {
1713
+            $name = $property->name;
1714
+            if (!isset($validationRules[$name])) {
1715
+                $validationRules[$name] = '*';
1716
+            }
1717
+
1718
+            $rule = $validationRules[$property->name];
1719
+            if ($rule === '+' || $rule === '*') { // multiple
1720
+                if (!isset($data[$name])) {
1721
+                    $data[$name] = [];
1722
+                }
1723
+
1724
+                $data[$name][] = $this->transformSearchProperty($property);
1725
+            } else { // once
1726
+                $data[$name] = $this->transformSearchProperty($property);
1727
+            }
1728
+        }
1729
+
1730
+        return $data;
1731
+    }
1732
+
1733
+    /**
1734
+     * @param Property $prop
1735
+     * @return array
1736
+     */
1737
+    private function transformSearchProperty(Property $prop) {
1738
+        // No need to check Date, as it extends DateTime
1739
+        if ($prop instanceof Property\ICalendar\DateTime) {
1740
+            $value = $prop->getDateTime();
1741
+        } else {
1742
+            $value = $prop->getValue();
1743
+        }
1744
+
1745
+        return [
1746
+            $value,
1747
+            $prop->parameters()
1748
+        ];
1749
+    }
1750
+
1751
+    /**
1752
+     * @param string $principalUri
1753
+     * @param string $pattern
1754
+     * @param array $componentTypes
1755
+     * @param array $searchProperties
1756
+     * @param array $searchParameters
1757
+     * @param array $options
1758
+     * @return array
1759
+     */
1760
+    public function searchPrincipalUri(string $principalUri,
1761
+                                        string $pattern,
1762
+                                        array $componentTypes,
1763
+                                        array $searchProperties,
1764
+                                        array $searchParameters,
1765
+                                        array $options = []): array {
1766
+        $escapePattern = !\array_key_exists('escape_like_param', $options) || $options['escape_like_param'] !== false;
1767
+
1768
+        $calendarObjectIdQuery = $this->db->getQueryBuilder();
1769
+        $calendarOr = $calendarObjectIdQuery->expr()->orX();
1770
+        $searchOr = $calendarObjectIdQuery->expr()->orX();
1771
+
1772
+        // Fetch calendars and subscription
1773
+        $calendars = $this->getCalendarsForUser($principalUri);
1774
+        $subscriptions = $this->getSubscriptionsForUser($principalUri);
1775
+        foreach ($calendars as $calendar) {
1776
+            $calendarAnd = $calendarObjectIdQuery->expr()->andX();
1777
+            $calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$calendar['id'])));
1778
+            $calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1779
+
1780
+            // If it's shared, limit search to public events
1781
+            if ($calendar['principaluri'] !== $calendar['{http://owncloud.org/ns}owner-principal']) {
1782
+                $calendarAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
1783
+            }
1784
+
1785
+            $calendarOr->add($calendarAnd);
1786
+        }
1787
+        foreach ($subscriptions as $subscription) {
1788
+            $subscriptionAnd = $calendarObjectIdQuery->expr()->andX();
1789
+            $subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$subscription['id'])));
1790
+            $subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)));
1791
+
1792
+            // If it's shared, limit search to public events
1793
+            if ($subscription['principaluri'] !== $subscription['{http://owncloud.org/ns}owner-principal']) {
1794
+                $subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
1795
+            }
1796
+
1797
+            $calendarOr->add($subscriptionAnd);
1798
+        }
1799
+
1800
+        foreach ($searchProperties as $property) {
1801
+            $propertyAnd = $calendarObjectIdQuery->expr()->andX();
1802
+            $propertyAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
1803
+            $propertyAnd->add($calendarObjectIdQuery->expr()->isNull('cob.parameter'));
1804
+
1805
+            $searchOr->add($propertyAnd);
1806
+        }
1807
+        foreach ($searchParameters as $property => $parameter) {
1808
+            $parameterAnd = $calendarObjectIdQuery->expr()->andX();
1809
+            $parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
1810
+            $parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.parameter', $calendarObjectIdQuery->createNamedParameter($parameter, IQueryBuilder::PARAM_STR_ARRAY)));
1811
+
1812
+            $searchOr->add($parameterAnd);
1813
+        }
1814
+
1815
+        if ($calendarOr->count() === 0) {
1816
+            return [];
1817
+        }
1818
+        if ($searchOr->count() === 0) {
1819
+            return [];
1820
+        }
1821
+
1822
+        $calendarObjectIdQuery->selectDistinct('cob.objectid')
1823
+            ->from($this->dbObjectPropertiesTable, 'cob')
1824
+            ->leftJoin('cob', 'calendarobjects', 'co', $calendarObjectIdQuery->expr()->eq('co.id', 'cob.objectid'))
1825
+            ->andWhere($calendarObjectIdQuery->expr()->in('co.componenttype', $calendarObjectIdQuery->createNamedParameter($componentTypes, IQueryBuilder::PARAM_STR_ARRAY)))
1826
+            ->andWhere($calendarOr)
1827
+            ->andWhere($searchOr);
1828
+
1829
+        if ('' !== $pattern) {
1830
+            if (!$escapePattern) {
1831
+                $calendarObjectIdQuery->andWhere($calendarObjectIdQuery->expr()->ilike('cob.value', $calendarObjectIdQuery->createNamedParameter($pattern)));
1832
+            } else {
1833
+                $calendarObjectIdQuery->andWhere($calendarObjectIdQuery->expr()->ilike('cob.value', $calendarObjectIdQuery->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%')));
1834
+            }
1835
+        }
1836
+
1837
+        if (isset($options['limit'])) {
1838
+            $calendarObjectIdQuery->setMaxResults($options['limit']);
1839
+        }
1840
+        if (isset($options['offset'])) {
1841
+            $calendarObjectIdQuery->setFirstResult($options['offset']);
1842
+        }
1843
+
1844
+        $result = $calendarObjectIdQuery->execute();
1845
+        $matches = $result->fetchAll();
1846
+        $result->closeCursor();
1847
+        $matches = array_map(static function (array $match):int {
1848
+            return (int) $match['objectid'];
1849
+        }, $matches);
1850
+
1851
+        $query = $this->db->getQueryBuilder();
1852
+        $query->select('calendardata', 'uri', 'calendarid', 'calendartype')
1853
+            ->from('calendarobjects')
1854
+            ->where($query->expr()->in('id', $query->createNamedParameter($matches, IQueryBuilder::PARAM_INT_ARRAY)));
1855
+
1856
+        $result = $query->execute();
1857
+        $calendarObjects = $result->fetchAll();
1858
+        $result->closeCursor();
1859
+
1860
+        return array_map(function (array $array): array {
1861
+            $array['calendarid'] = (int)$array['calendarid'];
1862
+            $array['calendartype'] = (int)$array['calendartype'];
1863
+            $array['calendardata'] = $this->readBlob($array['calendardata']);
1864
+
1865
+            return $array;
1866
+        }, $calendarObjects);
1867
+    }
1868
+
1869
+    /**
1870
+     * Searches through all of a users calendars and calendar objects to find
1871
+     * an object with a specific UID.
1872
+     *
1873
+     * This method should return the path to this object, relative to the
1874
+     * calendar home, so this path usually only contains two parts:
1875
+     *
1876
+     * calendarpath/objectpath.ics
1877
+     *
1878
+     * If the uid is not found, return null.
1879
+     *
1880
+     * This method should only consider * objects that the principal owns, so
1881
+     * any calendars owned by other principals that also appear in this
1882
+     * collection should be ignored.
1883
+     *
1884
+     * @param string $principalUri
1885
+     * @param string $uid
1886
+     * @return string|null
1887
+     */
1888
+    public function getCalendarObjectByUID($principalUri, $uid) {
1889
+        $query = $this->db->getQueryBuilder();
1890
+        $query->selectAlias('c.uri', 'calendaruri')->selectAlias('co.uri', 'objecturi')
1891
+            ->from('calendarobjects', 'co')
1892
+            ->leftJoin('co', 'calendars', 'c', $query->expr()->eq('co.calendarid', 'c.id'))
1893
+            ->where($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)))
1894
+            ->andWhere($query->expr()->eq('co.uid', $query->createNamedParameter($uid)));
1895
+
1896
+        $stmt = $query->execute();
1897
+
1898
+        if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1899
+            return $row['calendaruri'] . '/' . $row['objecturi'];
1900
+        }
1901
+
1902
+        return null;
1903
+    }
1904
+
1905
+    /**
1906
+     * The getChanges method returns all the changes that have happened, since
1907
+     * the specified syncToken in the specified calendar.
1908
+     *
1909
+     * This function should return an array, such as the following:
1910
+     *
1911
+     * [
1912
+     *   'syncToken' => 'The current synctoken',
1913
+     *   'added'   => [
1914
+     *      'new.txt',
1915
+     *   ],
1916
+     *   'modified'   => [
1917
+     *      'modified.txt',
1918
+     *   ],
1919
+     *   'deleted' => [
1920
+     *      'foo.php.bak',
1921
+     *      'old.txt'
1922
+     *   ]
1923
+     * );
1924
+     *
1925
+     * The returned syncToken property should reflect the *current* syncToken
1926
+     * of the calendar, as reported in the {http://sabredav.org/ns}sync-token
1927
+     * property This is * needed here too, to ensure the operation is atomic.
1928
+     *
1929
+     * If the $syncToken argument is specified as null, this is an initial
1930
+     * sync, and all members should be reported.
1931
+     *
1932
+     * The modified property is an array of nodenames that have changed since
1933
+     * the last token.
1934
+     *
1935
+     * The deleted property is an array with nodenames, that have been deleted
1936
+     * from collection.
1937
+     *
1938
+     * The $syncLevel argument is basically the 'depth' of the report. If it's
1939
+     * 1, you only have to report changes that happened only directly in
1940
+     * immediate descendants. If it's 2, it should also include changes from
1941
+     * the nodes below the child collections. (grandchildren)
1942
+     *
1943
+     * The $limit argument allows a client to specify how many results should
1944
+     * be returned at most. If the limit is not specified, it should be treated
1945
+     * as infinite.
1946
+     *
1947
+     * If the limit (infinite or not) is higher than you're willing to return,
1948
+     * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception.
1949
+     *
1950
+     * If the syncToken is expired (due to data cleanup) or unknown, you must
1951
+     * return null.
1952
+     *
1953
+     * The limit is 'suggestive'. You are free to ignore it.
1954
+     *
1955
+     * @param string $calendarId
1956
+     * @param string $syncToken
1957
+     * @param int $syncLevel
1958
+     * @param int $limit
1959
+     * @param int $calendarType
1960
+     * @return array
1961
+     */
1962
+    public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1963
+        // Current synctoken
1964
+        $stmt = $this->db->prepare('SELECT `synctoken` FROM `*PREFIX*calendars` WHERE `id` = ?');
1965
+        $stmt->execute([ $calendarId ]);
1966
+        $currentToken = $stmt->fetchColumn(0);
1967
+
1968
+        if (is_null($currentToken)) {
1969
+            return null;
1970
+        }
1971
+
1972
+        $result = [
1973
+            'syncToken' => $currentToken,
1974
+            'added' => [],
1975
+            'modified' => [],
1976
+            'deleted' => [],
1977
+        ];
1978
+
1979
+        if ($syncToken) {
1980
+            $query = "SELECT `uri`, `operation` FROM `*PREFIX*calendarchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `calendarid` = ? AND `calendartype` = ? ORDER BY `synctoken`";
1981
+            if ($limit > 0) {
1982
+                $query .= " LIMIT " . (int)$limit;
1983
+            }
1984
+
1985
+            // Fetching all changes
1986
+            $stmt = $this->db->prepare($query);
1987
+            $stmt->execute([$syncToken, $currentToken, $calendarId, $calendarType]);
1988
+
1989
+            $changes = [];
1990
+
1991
+            // This loop ensures that any duplicates are overwritten, only the
1992
+            // last change on a node is relevant.
1993
+            while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1994
+                $changes[$row['uri']] = $row['operation'];
1995
+            }
1996
+
1997
+            foreach ($changes as $uri => $operation) {
1998
+                switch ($operation) {
1999
+                    case 1:
2000
+                        $result['added'][] = $uri;
2001
+                        break;
2002
+                    case 2:
2003
+                        $result['modified'][] = $uri;
2004
+                        break;
2005
+                    case 3:
2006
+                        $result['deleted'][] = $uri;
2007
+                        break;
2008
+                }
2009
+            }
2010
+        } else {
2011
+            // No synctoken supplied, this is the initial sync.
2012
+            $query = "SELECT `uri` FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ? AND `calendartype` = ?";
2013
+            $stmt = $this->db->prepare($query);
2014
+            $stmt->execute([$calendarId, $calendarType]);
2015
+
2016
+            $result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
2017
+        }
2018
+        return $result;
2019
+    }
2020
+
2021
+    /**
2022
+     * Returns a list of subscriptions for a principal.
2023
+     *
2024
+     * Every subscription is an array with the following keys:
2025
+     *  * id, a unique id that will be used by other functions to modify the
2026
+     *    subscription. This can be the same as the uri or a database key.
2027
+     *  * uri. This is just the 'base uri' or 'filename' of the subscription.
2028
+     *  * principaluri. The owner of the subscription. Almost always the same as
2029
+     *    principalUri passed to this method.
2030
+     *
2031
+     * Furthermore, all the subscription info must be returned too:
2032
+     *
2033
+     * 1. {DAV:}displayname
2034
+     * 2. {http://apple.com/ns/ical/}refreshrate
2035
+     * 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos
2036
+     *    should not be stripped).
2037
+     * 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms
2038
+     *    should not be stripped).
2039
+     * 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if
2040
+     *    attachments should not be stripped).
2041
+     * 6. {http://calendarserver.org/ns/}source (Must be a
2042
+     *     Sabre\DAV\Property\Href).
2043
+     * 7. {http://apple.com/ns/ical/}calendar-color
2044
+     * 8. {http://apple.com/ns/ical/}calendar-order
2045
+     * 9. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
2046
+     *    (should just be an instance of
2047
+     *    Sabre\CalDAV\Property\SupportedCalendarComponentSet, with a bunch of
2048
+     *    default components).
2049
+     *
2050
+     * @param string $principalUri
2051
+     * @return array
2052
+     */
2053
+    public function getSubscriptionsForUser($principalUri) {
2054
+        $fields = array_values($this->subscriptionPropertyMap);
2055
+        $fields[] = 'id';
2056
+        $fields[] = 'uri';
2057
+        $fields[] = 'source';
2058
+        $fields[] = 'principaluri';
2059
+        $fields[] = 'lastmodified';
2060
+        $fields[] = 'synctoken';
2061
+
2062
+        $query = $this->db->getQueryBuilder();
2063
+        $query->select($fields)
2064
+            ->from('calendarsubscriptions')
2065
+            ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2066
+            ->orderBy('calendarorder', 'asc');
2067
+        $stmt = $query->execute();
2068
+
2069
+        $subscriptions = [];
2070
+        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
2071
+            $subscription = [
2072
+                'id' => $row['id'],
2073
+                'uri' => $row['uri'],
2074
+                'principaluri' => $row['principaluri'],
2075
+                'source' => $row['source'],
2076
+                'lastmodified' => $row['lastmodified'],
2077
+
2078
+                '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
2079
+                '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
2080
+            ];
2081
+
2082
+            foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
2083
+                if (!is_null($row[$dbName])) {
2084
+                    $subscription[$xmlName] = $row[$dbName];
2085
+                }
2086
+            }
2087
+
2088
+            $subscriptions[] = $subscription;
2089
+        }
2090
+
2091
+        return $subscriptions;
2092
+    }
2093
+
2094
+    /**
2095
+     * Creates a new subscription for a principal.
2096
+     *
2097
+     * If the creation was a success, an id must be returned that can be used to reference
2098
+     * this subscription in other methods, such as updateSubscription.
2099
+     *
2100
+     * @param string $principalUri
2101
+     * @param string $uri
2102
+     * @param array $properties
2103
+     * @return mixed
2104
+     */
2105
+    public function createSubscription($principalUri, $uri, array $properties) {
2106
+        if (!isset($properties['{http://calendarserver.org/ns/}source'])) {
2107
+            throw new Forbidden('The {http://calendarserver.org/ns/}source property is required when creating subscriptions');
2108
+        }
2109
+
2110
+        $values = [
2111
+            'principaluri' => $principalUri,
2112
+            'uri' => $uri,
2113
+            'source' => $properties['{http://calendarserver.org/ns/}source']->getHref(),
2114
+            'lastmodified' => time(),
2115
+        ];
2116
+
2117
+        $propertiesBoolean = ['striptodos', 'stripalarms', 'stripattachments'];
2118
+
2119
+        foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
2120
+            if (array_key_exists($xmlName, $properties)) {
2121
+                $values[$dbName] = $properties[$xmlName];
2122
+                if (in_array($dbName, $propertiesBoolean)) {
2123
+                    $values[$dbName] = true;
2124
+                }
2125
+            }
2126
+        }
2127
+
2128
+        $valuesToInsert = [];
2129
+
2130
+        $query = $this->db->getQueryBuilder();
2131
+
2132
+        foreach (array_keys($values) as $name) {
2133
+            $valuesToInsert[$name] = $query->createNamedParameter($values[$name]);
2134
+        }
2135
+
2136
+        $query->insert('calendarsubscriptions')
2137
+            ->values($valuesToInsert)
2138
+            ->execute();
2139
+
2140
+        $subscriptionId = $this->db->lastInsertId('*PREFIX*calendarsubscriptions');
2141
+
2142
+        $subscriptionRow = $this->getSubscriptionById($subscriptionId);
2143
+        $this->dispatcher->dispatchTyped(new SubscriptionCreatedEvent((int)$subscriptionId, $subscriptionRow));
2144
+        $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createSubscription', new GenericEvent(
2145
+            '\OCA\DAV\CalDAV\CalDavBackend::createSubscription',
2146
+            [
2147
+                'subscriptionId' => $subscriptionId,
2148
+                'subscriptionData' => $subscriptionRow,
2149
+            ]));
2150
+
2151
+        return $subscriptionId;
2152
+    }
2153
+
2154
+    /**
2155
+     * Updates a subscription
2156
+     *
2157
+     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
2158
+     * To do the actual updates, you must tell this object which properties
2159
+     * you're going to process with the handle() method.
2160
+     *
2161
+     * Calling the handle method is like telling the PropPatch object "I
2162
+     * promise I can handle updating this property".
2163
+     *
2164
+     * Read the PropPatch documentation for more info and examples.
2165
+     *
2166
+     * @param mixed $subscriptionId
2167
+     * @param PropPatch $propPatch
2168
+     * @return void
2169
+     */
2170
+    public function updateSubscription($subscriptionId, PropPatch $propPatch) {
2171
+        $supportedProperties = array_keys($this->subscriptionPropertyMap);
2172
+        $supportedProperties[] = '{http://calendarserver.org/ns/}source';
2173
+
2174
+        $propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) {
2175
+            $newValues = [];
2176
+
2177
+            foreach ($mutations as $propertyName => $propertyValue) {
2178
+                if ($propertyName === '{http://calendarserver.org/ns/}source') {
2179
+                    $newValues['source'] = $propertyValue->getHref();
2180
+                } else {
2181
+                    $fieldName = $this->subscriptionPropertyMap[$propertyName];
2182
+                    $newValues[$fieldName] = $propertyValue;
2183
+                }
2184
+            }
2185
+
2186
+            $query = $this->db->getQueryBuilder();
2187
+            $query->update('calendarsubscriptions')
2188
+                ->set('lastmodified', $query->createNamedParameter(time()));
2189
+            foreach ($newValues as $fieldName => $value) {
2190
+                $query->set($fieldName, $query->createNamedParameter($value));
2191
+            }
2192
+            $query->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId)))
2193
+                ->execute();
2194
+
2195
+            $subscriptionRow = $this->getSubscriptionById($subscriptionId);
2196
+            $this->dispatcher->dispatchTyped(new SubscriptionUpdatedEvent((int)$subscriptionId, $subscriptionRow, [], $mutations));
2197
+            $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateSubscription', new GenericEvent(
2198
+                '\OCA\DAV\CalDAV\CalDavBackend::updateSubscription',
2199
+                [
2200
+                    'subscriptionId' => $subscriptionId,
2201
+                    'subscriptionData' => $subscriptionRow,
2202
+                    'propertyMutations' => $mutations,
2203
+                ]));
2204
+
2205
+            return true;
2206
+        });
2207
+    }
2208
+
2209
+    /**
2210
+     * Deletes a subscription.
2211
+     *
2212
+     * @param mixed $subscriptionId
2213
+     * @return void
2214
+     */
2215
+    public function deleteSubscription($subscriptionId) {
2216
+        $subscriptionRow = $this->getSubscriptionById($subscriptionId);
2217
+
2218
+        $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription', new GenericEvent(
2219
+            '\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription',
2220
+            [
2221
+                'subscriptionId' => $subscriptionId,
2222
+                'subscriptionData' => $this->getSubscriptionById($subscriptionId),
2223
+            ]));
2224
+
2225
+        $query = $this->db->getQueryBuilder();
2226
+        $query->delete('calendarsubscriptions')
2227
+            ->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId)))
2228
+            ->execute();
2229
+
2230
+        $query = $this->db->getQueryBuilder();
2231
+        $query->delete('calendarobjects')
2232
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2233
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2234
+            ->execute();
2235
+
2236
+        $query->delete('calendarchanges')
2237
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2238
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2239
+            ->execute();
2240
+
2241
+        $query->delete($this->dbObjectPropertiesTable)
2242
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2243
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2244
+            ->execute();
2245
+
2246
+        if ($subscriptionRow) {
2247
+            $this->dispatcher->dispatchTyped(new SubscriptionDeletedEvent((int)$subscriptionId, $subscriptionRow, []));
2248
+        }
2249
+    }
2250
+
2251
+    /**
2252
+     * Returns a single scheduling object for the inbox collection.
2253
+     *
2254
+     * The returned array should contain the following elements:
2255
+     *   * uri - A unique basename for the object. This will be used to
2256
+     *           construct a full uri.
2257
+     *   * calendardata - The iCalendar object
2258
+     *   * lastmodified - The last modification date. Can be an int for a unix
2259
+     *                    timestamp, or a PHP DateTime object.
2260
+     *   * etag - A unique token that must change if the object changed.
2261
+     *   * size - The size of the object, in bytes.
2262
+     *
2263
+     * @param string $principalUri
2264
+     * @param string $objectUri
2265
+     * @return array
2266
+     */
2267
+    public function getSchedulingObject($principalUri, $objectUri) {
2268
+        $query = $this->db->getQueryBuilder();
2269
+        $stmt = $query->select(['uri', 'calendardata', 'lastmodified', 'etag', 'size'])
2270
+            ->from('schedulingobjects')
2271
+            ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2272
+            ->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
2273
+            ->execute();
2274
+
2275
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
2276
+
2277
+        if (!$row) {
2278
+            return null;
2279
+        }
2280
+
2281
+        return [
2282
+            'uri' => $row['uri'],
2283
+            'calendardata' => $row['calendardata'],
2284
+            'lastmodified' => $row['lastmodified'],
2285
+            'etag' => '"' . $row['etag'] . '"',
2286
+            'size' => (int)$row['size'],
2287
+        ];
2288
+    }
2289
+
2290
+    /**
2291
+     * Returns all scheduling objects for the inbox collection.
2292
+     *
2293
+     * These objects should be returned as an array. Every item in the array
2294
+     * should follow the same structure as returned from getSchedulingObject.
2295
+     *
2296
+     * The main difference is that 'calendardata' is optional.
2297
+     *
2298
+     * @param string $principalUri
2299
+     * @return array
2300
+     */
2301
+    public function getSchedulingObjects($principalUri) {
2302
+        $query = $this->db->getQueryBuilder();
2303
+        $stmt = $query->select(['uri', 'calendardata', 'lastmodified', 'etag', 'size'])
2304
+                ->from('schedulingobjects')
2305
+                ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2306
+                ->execute();
2307
+
2308
+        $result = [];
2309
+        foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
2310
+            $result[] = [
2311
+                'calendardata' => $row['calendardata'],
2312
+                'uri' => $row['uri'],
2313
+                'lastmodified' => $row['lastmodified'],
2314
+                'etag' => '"' . $row['etag'] . '"',
2315
+                'size' => (int)$row['size'],
2316
+            ];
2317
+        }
2318
+
2319
+        return $result;
2320
+    }
2321
+
2322
+    /**
2323
+     * Deletes a scheduling object from the inbox collection.
2324
+     *
2325
+     * @param string $principalUri
2326
+     * @param string $objectUri
2327
+     * @return void
2328
+     */
2329
+    public function deleteSchedulingObject($principalUri, $objectUri) {
2330
+        $query = $this->db->getQueryBuilder();
2331
+        $query->delete('schedulingobjects')
2332
+                ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
2333
+                ->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
2334
+                ->execute();
2335
+    }
2336
+
2337
+    /**
2338
+     * Creates a new scheduling object. This should land in a users' inbox.
2339
+     *
2340
+     * @param string $principalUri
2341
+     * @param string $objectUri
2342
+     * @param string $objectData
2343
+     * @return void
2344
+     */
2345
+    public function createSchedulingObject($principalUri, $objectUri, $objectData) {
2346
+        $query = $this->db->getQueryBuilder();
2347
+        $query->insert('schedulingobjects')
2348
+            ->values([
2349
+                'principaluri' => $query->createNamedParameter($principalUri),
2350
+                'calendardata' => $query->createNamedParameter($objectData, IQueryBuilder::PARAM_LOB),
2351
+                'uri' => $query->createNamedParameter($objectUri),
2352
+                'lastmodified' => $query->createNamedParameter(time()),
2353
+                'etag' => $query->createNamedParameter(md5($objectData)),
2354
+                'size' => $query->createNamedParameter(strlen($objectData))
2355
+            ])
2356
+            ->execute();
2357
+    }
2358
+
2359
+    /**
2360
+     * Adds a change record to the calendarchanges table.
2361
+     *
2362
+     * @param mixed $calendarId
2363
+     * @param string $objectUri
2364
+     * @param int $operation 1 = add, 2 = modify, 3 = delete.
2365
+     * @param int $calendarType
2366
+     * @return void
2367
+     */
2368
+    protected function addChange($calendarId, $objectUri, $operation, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
2369
+        $table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions';
2370
+
2371
+        $query = $this->db->getQueryBuilder();
2372
+        $query->select('synctoken')
2373
+            ->from($table)
2374
+            ->where($query->expr()->eq('id', $query->createNamedParameter($calendarId)));
2375
+        $result = $query->execute();
2376
+        $syncToken = (int)$result->fetchColumn();
2377
+        $result->closeCursor();
2378
+
2379
+        $query = $this->db->getQueryBuilder();
2380
+        $query->insert('calendarchanges')
2381
+            ->values([
2382
+                'uri' => $query->createNamedParameter($objectUri),
2383
+                'synctoken' => $query->createNamedParameter($syncToken),
2384
+                'calendarid' => $query->createNamedParameter($calendarId),
2385
+                'operation' => $query->createNamedParameter($operation),
2386
+                'calendartype' => $query->createNamedParameter($calendarType),
2387
+            ])
2388
+            ->execute();
2389
+
2390
+        $stmt = $this->db->prepare("UPDATE `*PREFIX*$table` SET `synctoken` = `synctoken` + 1 WHERE `id` = ?");
2391
+        $stmt->execute([
2392
+            $calendarId
2393
+        ]);
2394
+    }
2395
+
2396
+    /**
2397
+     * Parses some information from calendar objects, used for optimized
2398
+     * calendar-queries.
2399
+     *
2400
+     * Returns an array with the following keys:
2401
+     *   * etag - An md5 checksum of the object without the quotes.
2402
+     *   * size - Size of the object in bytes
2403
+     *   * componentType - VEVENT, VTODO or VJOURNAL
2404
+     *   * firstOccurence
2405
+     *   * lastOccurence
2406
+     *   * uid - value of the UID property
2407
+     *
2408
+     * @param string $calendarData
2409
+     * @return array
2410
+     */
2411
+    public function getDenormalizedData($calendarData) {
2412
+        $vObject = Reader::read($calendarData);
2413
+        $vEvents = [];
2414
+        $componentType = null;
2415
+        $component = null;
2416
+        $firstOccurrence = null;
2417
+        $lastOccurrence = null;
2418
+        $uid = null;
2419
+        $classification = self::CLASSIFICATION_PUBLIC;
2420
+        $hasDTSTART = false;
2421
+        foreach ($vObject->getComponents() as $component) {
2422
+            if ($component->name !== 'VTIMEZONE') {
2423
+                // Finding all VEVENTs, and track them
2424
+                if ($component->name === 'VEVENT') {
2425
+                    array_push($vEvents, $component);
2426
+                    if ($component->DTSTART) {
2427
+                        $hasDTSTART = true;
2428
+                    }
2429
+                }
2430
+                // Track first component type and uid
2431
+                if ($uid === null) {
2432
+                    $componentType = $component->name;
2433
+                    $uid = (string)$component->UID;
2434
+                }
2435
+            }
2436
+        }
2437
+        if (!$componentType) {
2438
+            throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
2439
+        }
2440
+
2441
+        if ($hasDTSTART) {
2442
+            $component = $vEvents[0];
2443
+
2444
+            // Finding the last occurrence is a bit harder
2445
+            if (!isset($component->RRULE) && count($vEvents) === 1) {
2446
+                $firstOccurrence = $component->DTSTART->getDateTime()->getTimeStamp();
2447
+                if (isset($component->DTEND)) {
2448
+                    $lastOccurrence = $component->DTEND->getDateTime()->getTimeStamp();
2449
+                } elseif (isset($component->DURATION)) {
2450
+                    $endDate = clone $component->DTSTART->getDateTime();
2451
+                    $endDate->add(DateTimeParser::parse($component->DURATION->getValue()));
2452
+                    $lastOccurrence = $endDate->getTimeStamp();
2453
+                } elseif (!$component->DTSTART->hasTime()) {
2454
+                    $endDate = clone $component->DTSTART->getDateTime();
2455
+                    $endDate->modify('+1 day');
2456
+                    $lastOccurrence = $endDate->getTimeStamp();
2457
+                } else {
2458
+                    $lastOccurrence = $firstOccurrence;
2459
+                }
2460
+            } else {
2461
+                $it = new EventIterator($vEvents);
2462
+                $maxDate = new DateTime(self::MAX_DATE);
2463
+                $firstOccurrence = $it->getDtStart()->getTimestamp();
2464
+                if ($it->isInfinite()) {
2465
+                    $lastOccurrence = $maxDate->getTimestamp();
2466
+                } else {
2467
+                    $end = $it->getDtEnd();
2468
+                    while ($it->valid() && $end < $maxDate) {
2469
+                        $end = $it->getDtEnd();
2470
+                        $it->next();
2471
+                    }
2472
+                    $lastOccurrence = $end->getTimestamp();
2473
+                }
2474
+            }
2475
+        }
2476
+
2477
+        if ($component->CLASS) {
2478
+            $classification = CalDavBackend::CLASSIFICATION_PRIVATE;
2479
+            switch ($component->CLASS->getValue()) {
2480
+                case 'PUBLIC':
2481
+                    $classification = CalDavBackend::CLASSIFICATION_PUBLIC;
2482
+                    break;
2483
+                case 'CONFIDENTIAL':
2484
+                    $classification = CalDavBackend::CLASSIFICATION_CONFIDENTIAL;
2485
+                    break;
2486
+            }
2487
+        }
2488
+        return [
2489
+            'etag' => md5($calendarData),
2490
+            'size' => strlen($calendarData),
2491
+            'componentType' => $componentType,
2492
+            'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence),
2493
+            'lastOccurence' => $lastOccurrence,
2494
+            'uid' => $uid,
2495
+            'classification' => $classification
2496
+        ];
2497
+    }
2498
+
2499
+    /**
2500
+     * @param $cardData
2501
+     * @return bool|string
2502
+     */
2503
+    private function readBlob($cardData) {
2504
+        if (is_resource($cardData)) {
2505
+            return stream_get_contents($cardData);
2506
+        }
2507
+
2508
+        return $cardData;
2509
+    }
2510
+
2511
+    /**
2512
+     * @param IShareable $shareable
2513
+     * @param array $add
2514
+     * @param array $remove
2515
+     */
2516
+    public function updateShares($shareable, $add, $remove) {
2517
+        $calendarId = $shareable->getResourceId();
2518
+        $calendarRow = $this->getCalendarById($calendarId);
2519
+        $oldShares = $this->getShares($calendarId);
2520
+
2521
+        $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateShares', new GenericEvent(
2522
+            '\OCA\DAV\CalDAV\CalDavBackend::updateShares',
2523
+            [
2524
+                'calendarId' => $calendarId,
2525
+                'calendarData' => $calendarRow,
2526
+                'shares' => $oldShares,
2527
+                'add' => $add,
2528
+                'remove' => $remove,
2529
+            ]));
2530
+        $this->calendarSharingBackend->updateShares($shareable, $add, $remove);
2531
+
2532
+        $this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent((int)$calendarId, $calendarRow, $oldShares, $add, $remove));
2533
+    }
2534
+
2535
+    /**
2536
+     * @param int $resourceId
2537
+     * @param int $calendarType
2538
+     * @return array
2539
+     */
2540
+    public function getShares($resourceId, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
2541
+        return $this->calendarSharingBackend->getShares($resourceId);
2542
+    }
2543
+
2544
+    /**
2545
+     * @param boolean $value
2546
+     * @param \OCA\DAV\CalDAV\Calendar $calendar
2547
+     * @return string|null
2548
+     */
2549
+    public function setPublishStatus($value, $calendar) {
2550
+        $calendarId = $calendar->getResourceId();
2551
+        $calendarData = $this->getCalendarById($calendarId);
2552
+        $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::publishCalendar', new GenericEvent(
2553
+            '\OCA\DAV\CalDAV\CalDavBackend::updateShares',
2554
+            [
2555
+                'calendarId' => $calendarId,
2556
+                'calendarData' => $calendarData,
2557
+                'public' => $value,
2558
+            ]));
2559
+
2560
+        $query = $this->db->getQueryBuilder();
2561
+        if ($value) {
2562
+            $publicUri = $this->random->generate(16, ISecureRandom::CHAR_HUMAN_READABLE);
2563
+            $query->insert('dav_shares')
2564
+                ->values([
2565
+                    'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()),
2566
+                    'type' => $query->createNamedParameter('calendar'),
2567
+                    'access' => $query->createNamedParameter(self::ACCESS_PUBLIC),
2568
+                    'resourceid' => $query->createNamedParameter($calendar->getResourceId()),
2569
+                    'publicuri' => $query->createNamedParameter($publicUri)
2570
+                ]);
2571
+            $query->execute();
2572
+
2573
+            $this->dispatcher->dispatchTyped(new CalendarPublishedEvent((int)$calendarId, $calendarData, $publicUri));
2574
+            return $publicUri;
2575
+        }
2576
+        $query->delete('dav_shares')
2577
+            ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId())))
2578
+            ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)));
2579
+        $query->execute();
2580
+
2581
+        $this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent((int)$calendarId, $calendarData));
2582
+        return null;
2583
+    }
2584
+
2585
+    /**
2586
+     * @param \OCA\DAV\CalDAV\Calendar $calendar
2587
+     * @return mixed
2588
+     */
2589
+    public function getPublishStatus($calendar) {
2590
+        $query = $this->db->getQueryBuilder();
2591
+        $result = $query->select('publicuri')
2592
+            ->from('dav_shares')
2593
+            ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId())))
2594
+            ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)))
2595
+            ->execute();
2596
+
2597
+        $row = $result->fetch();
2598
+        $result->closeCursor();
2599
+        return $row ? reset($row) : false;
2600
+    }
2601
+
2602
+    /**
2603
+     * @param int $resourceId
2604
+     * @param array $acl
2605
+     * @return array
2606
+     */
2607
+    public function applyShareAcl($resourceId, $acl) {
2608
+        return $this->calendarSharingBackend->applyShareAcl($resourceId, $acl);
2609
+    }
2610
+
2611
+
2612
+
2613
+    /**
2614
+     * update properties table
2615
+     *
2616
+     * @param int $calendarId
2617
+     * @param string $objectUri
2618
+     * @param string $calendarData
2619
+     * @param int $calendarType
2620
+     */
2621
+    public function updateProperties($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
2622
+        $objectId = $this->getCalendarObjectId($calendarId, $objectUri, $calendarType);
2623
+
2624
+        try {
2625
+            $vCalendar = $this->readCalendarData($calendarData);
2626
+        } catch (\Exception $ex) {
2627
+            return;
2628
+        }
2629
+
2630
+        $this->purgeProperties($calendarId, $objectId);
2631
+
2632
+        $query = $this->db->getQueryBuilder();
2633
+        $query->insert($this->dbObjectPropertiesTable)
2634
+            ->values(
2635
+                [
2636
+                    'calendarid' => $query->createNamedParameter($calendarId),
2637
+                    'calendartype' => $query->createNamedParameter($calendarType),
2638
+                    'objectid' => $query->createNamedParameter($objectId),
2639
+                    'name' => $query->createParameter('name'),
2640
+                    'parameter' => $query->createParameter('parameter'),
2641
+                    'value' => $query->createParameter('value'),
2642
+                ]
2643
+            );
2644
+
2645
+        $indexComponents = ['VEVENT', 'VJOURNAL', 'VTODO'];
2646
+        foreach ($vCalendar->getComponents() as $component) {
2647
+            if (!in_array($component->name, $indexComponents)) {
2648
+                continue;
2649
+            }
2650
+
2651
+            foreach ($component->children() as $property) {
2652
+                if (in_array($property->name, self::$indexProperties)) {
2653
+                    $value = $property->getValue();
2654
+                    // is this a shitty db?
2655
+                    if (!$this->db->supports4ByteText()) {
2656
+                        $value = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $value);
2657
+                    }
2658
+                    $value = mb_substr($value, 0, 254);
2659
+
2660
+                    $query->setParameter('name', $property->name);
2661
+                    $query->setParameter('parameter', null);
2662
+                    $query->setParameter('value', $value);
2663
+                    $query->execute();
2664
+                }
2665
+
2666
+                if (array_key_exists($property->name, self::$indexParameters)) {
2667
+                    $parameters = $property->parameters();
2668
+                    $indexedParametersForProperty = self::$indexParameters[$property->name];
2669
+
2670
+                    foreach ($parameters as $key => $value) {
2671
+                        if (in_array($key, $indexedParametersForProperty)) {
2672
+                            // is this a shitty db?
2673
+                            if ($this->db->supports4ByteText()) {
2674
+                                $value = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $value);
2675
+                            }
2676
+
2677
+                            $query->setParameter('name', $property->name);
2678
+                            $query->setParameter('parameter', mb_substr($key, 0, 254));
2679
+                            $query->setParameter('value', mb_substr($value, 0, 254));
2680
+                            $query->execute();
2681
+                        }
2682
+                    }
2683
+                }
2684
+            }
2685
+        }
2686
+    }
2687
+
2688
+    /**
2689
+     * deletes all birthday calendars
2690
+     */
2691
+    public function deleteAllBirthdayCalendars() {
2692
+        $query = $this->db->getQueryBuilder();
2693
+        $result = $query->select(['id'])->from('calendars')
2694
+            ->where($query->expr()->eq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI)))
2695
+            ->execute();
2696
+
2697
+        $ids = $result->fetchAll();
2698
+        foreach ($ids as $id) {
2699
+            $this->deleteCalendar($id['id']);
2700
+        }
2701
+    }
2702
+
2703
+    /**
2704
+     * @param $subscriptionId
2705
+     */
2706
+    public function purgeAllCachedEventsForSubscription($subscriptionId) {
2707
+        $query = $this->db->getQueryBuilder();
2708
+        $query->select('uri')
2709
+            ->from('calendarobjects')
2710
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2711
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)));
2712
+        $stmt = $query->execute();
2713
+
2714
+        $uris = [];
2715
+        foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
2716
+            $uris[] = $row['uri'];
2717
+        }
2718
+        $stmt->closeCursor();
2719
+
2720
+        $query = $this->db->getQueryBuilder();
2721
+        $query->delete('calendarobjects')
2722
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2723
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2724
+            ->execute();
2725
+
2726
+        $query->delete('calendarchanges')
2727
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2728
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2729
+            ->execute();
2730
+
2731
+        $query->delete($this->dbObjectPropertiesTable)
2732
+            ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId)))
2733
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)))
2734
+            ->execute();
2735
+
2736
+        foreach ($uris as $uri) {
2737
+            $this->addChange($subscriptionId, $uri, 3, self::CALENDAR_TYPE_SUBSCRIPTION);
2738
+        }
2739
+    }
2740
+
2741
+    /**
2742
+     * Move a calendar from one user to another
2743
+     *
2744
+     * @param string $uriName
2745
+     * @param string $uriOrigin
2746
+     * @param string $uriDestination
2747
+     */
2748
+    public function moveCalendar($uriName, $uriOrigin, $uriDestination) {
2749
+        $query = $this->db->getQueryBuilder();
2750
+        $query->update('calendars')
2751
+            ->set('principaluri', $query->createNamedParameter($uriDestination))
2752
+            ->where($query->expr()->eq('principaluri', $query->createNamedParameter($uriOrigin)))
2753
+            ->andWhere($query->expr()->eq('uri', $query->createNamedParameter($uriName)))
2754
+            ->execute();
2755
+    }
2756
+
2757
+    /**
2758
+     * read VCalendar data into a VCalendar object
2759
+     *
2760
+     * @param string $objectData
2761
+     * @return VCalendar
2762
+     */
2763
+    protected function readCalendarData($objectData) {
2764
+        return Reader::read($objectData);
2765
+    }
2766
+
2767
+    /**
2768
+     * delete all properties from a given calendar object
2769
+     *
2770
+     * @param int $calendarId
2771
+     * @param int $objectId
2772
+     */
2773
+    protected function purgeProperties($calendarId, $objectId) {
2774
+        $query = $this->db->getQueryBuilder();
2775
+        $query->delete($this->dbObjectPropertiesTable)
2776
+            ->where($query->expr()->eq('objectid', $query->createNamedParameter($objectId)))
2777
+            ->andWhere($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)));
2778
+        $query->execute();
2779
+    }
2780
+
2781
+    /**
2782
+     * get ID from a given calendar object
2783
+     *
2784
+     * @param int $calendarId
2785
+     * @param string $uri
2786
+     * @param int $calendarType
2787
+     * @return int
2788
+     */
2789
+    protected function getCalendarObjectId($calendarId, $uri, $calendarType):int {
2790
+        $query = $this->db->getQueryBuilder();
2791
+        $query->select('id')
2792
+            ->from('calendarobjects')
2793
+            ->where($query->expr()->eq('uri', $query->createNamedParameter($uri)))
2794
+            ->andWhere($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
2795
+            ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)));
2796
+
2797
+        $result = $query->execute();
2798
+        $objectIds = $result->fetch();
2799
+        $result->closeCursor();
2800
+
2801
+        if (!isset($objectIds['id'])) {
2802
+            throw new \InvalidArgumentException('Calendarobject does not exists: ' . $uri);
2803
+        }
2804
+
2805
+        return (int)$objectIds['id'];
2806
+    }
2807
+
2808
+    /**
2809
+     * return legacy endpoint principal name to new principal name
2810
+     *
2811
+     * @param $principalUri
2812
+     * @param $toV2
2813
+     * @return string
2814
+     */
2815
+    private function convertPrincipal($principalUri, $toV2) {
2816
+        if ($this->principalBackend->getPrincipalPrefix() === 'principals') {
2817
+            list(, $name) = Uri\split($principalUri);
2818
+            if ($toV2 === true) {
2819
+                return "principals/users/$name";
2820
+            }
2821
+            return "principals/$name";
2822
+        }
2823
+        return $principalUri;
2824
+    }
2825
+
2826
+    /**
2827
+     * adds information about an owner to the calendar data
2828
+     *
2829
+     * @param $calendarInfo
2830
+     */
2831
+    private function addOwnerPrincipal(&$calendarInfo) {
2832
+        $ownerPrincipalKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal';
2833
+        $displaynameKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}owner-displayname';
2834
+        if (isset($calendarInfo[$ownerPrincipalKey])) {
2835
+            $uri = $calendarInfo[$ownerPrincipalKey];
2836
+        } else {
2837
+            $uri = $calendarInfo['principaluri'];
2838
+        }
2839
+
2840
+        $principalInformation = $this->principalBackend->getPrincipalByPath($uri);
2841
+        if (isset($principalInformation['{DAV:}displayname'])) {
2842
+            $calendarInfo[$displaynameKey] = $principalInformation['{DAV:}displayname'];
2843
+        }
2844
+    }
2845 2845
 }
Please login to merge, or discard this patch.
Spacing   +117 added lines, -117 removed lines patch added patch discarded remove patch
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
 		}
256 256
 
257 257
 		$result = $query->execute();
258
-		$column = (int)$result->fetchColumn();
258
+		$column = (int) $result->fetchColumn();
259 259
 		$result->closeCursor();
260 260
 		return $column;
261 261
 	}
@@ -315,18 +315,18 @@  discard block
 block discarded – undo
315 315
 			$row['principaluri'] = (string) $row['principaluri'];
316 316
 			$components = [];
317 317
 			if ($row['components']) {
318
-				$components = explode(',',$row['components']);
318
+				$components = explode(',', $row['components']);
319 319
 			}
320 320
 
321 321
 			$calendar = [
322 322
 				'id' => $row['id'],
323 323
 				'uri' => $row['uri'],
324 324
 				'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
325
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
326
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
327
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
328
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
329
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
325
+				'{'.Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'),
326
+				'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
327
+				'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
328
+				'{'.Plugin::NS_CALDAV.'}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
329
+				'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
330 330
 			];
331 331
 
332 332
 			foreach ($this->propertyMap as $xmlName => $dbName) {
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
 		$principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true);
346 346
 		$principals = array_merge($principals, $this->principalBackend->getCircleMembership($principalUriOriginal));
347 347
 
348
-		$principals = array_map(function ($principal) {
348
+		$principals = array_map(function($principal) {
349 349
 			return urldecode($principal);
350 350
 		}, $principals);
351 351
 		$principals[] = $principalUri;
@@ -367,9 +367,9 @@  discard block
 block discarded – undo
367 367
 			->setParameter('type', 'calendar')
368 368
 			->setParameter('principaluri', $principals, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);
369 369
 
370
-		$result	= $query->execute();
370
+		$result = $query->execute();
371 371
 
372
-		$readOnlyPropertyName = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only';
372
+		$readOnlyPropertyName = '{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}read-only';
373 373
 		while ($row = $result->fetch()) {
374 374
 			$row['principaluri'] = (string) $row['principaluri'];
375 375
 			if ($row['principaluri'] === $principalUri) {
@@ -390,21 +390,21 @@  discard block
 block discarded – undo
390 390
 			}
391 391
 
392 392
 			list(, $name) = Uri\split($row['principaluri']);
393
-			$uri = $row['uri'] . '_shared_by_' . $name;
394
-			$row['displayname'] = $row['displayname'] . ' (' . $this->getUserDisplayName($name) . ')';
393
+			$uri = $row['uri'].'_shared_by_'.$name;
394
+			$row['displayname'] = $row['displayname'].' ('.$this->getUserDisplayName($name).')';
395 395
 			$components = [];
396 396
 			if ($row['components']) {
397
-				$components = explode(',',$row['components']);
397
+				$components = explode(',', $row['components']);
398 398
 			}
399 399
 			$calendar = [
400 400
 				'id' => $row['id'],
401 401
 				'uri' => $uri,
402 402
 				'principaluri' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint),
403
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
404
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
405
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
406
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp('transparent'),
407
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
403
+				'{'.Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'),
404
+				'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
405
+				'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
406
+				'{'.Plugin::NS_CALDAV.'}schedule-calendar-transp' => new ScheduleCalendarTransp('transparent'),
407
+				'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
408 408
 				$readOnlyPropertyName => $readOnly,
409 409
 			];
410 410
 
@@ -445,16 +445,16 @@  discard block
 block discarded – undo
445 445
 			$row['principaluri'] = (string) $row['principaluri'];
446 446
 			$components = [];
447 447
 			if ($row['components']) {
448
-				$components = explode(',',$row['components']);
448
+				$components = explode(',', $row['components']);
449 449
 			}
450 450
 			$calendar = [
451 451
 				'id' => $row['id'],
452 452
 				'uri' => $row['uri'],
453 453
 				'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
454
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
455
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
456
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
457
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
454
+				'{'.Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'),
455
+				'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
456
+				'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
457
+				'{'.Plugin::NS_CALDAV.'}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
458 458
 			];
459 459
 			foreach ($this->propertyMap as $xmlName => $dbName) {
460 460
 				$calendar[$xmlName] = $row[$dbName];
@@ -514,22 +514,22 @@  discard block
 block discarded – undo
514 514
 		while ($row = $result->fetch()) {
515 515
 			$row['principaluri'] = (string) $row['principaluri'];
516 516
 			list(, $name) = Uri\split($row['principaluri']);
517
-			$row['displayname'] = $row['displayname'] . "($name)";
517
+			$row['displayname'] = $row['displayname']."($name)";
518 518
 			$components = [];
519 519
 			if ($row['components']) {
520
-				$components = explode(',',$row['components']);
520
+				$components = explode(',', $row['components']);
521 521
 			}
522 522
 			$calendar = [
523 523
 				'id' => $row['id'],
524 524
 				'uri' => $row['publicuri'],
525 525
 				'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
526
-				'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
527
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
528
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
529
-				'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
530
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], $this->legacyEndpoint),
531
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ,
532
-				'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
526
+				'{'.Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'),
527
+				'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
528
+				'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
529
+				'{'.Plugin::NS_CALDAV.'}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
530
+				'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}owner-principal' => $this->convertPrincipal($row['principaluri'], $this->legacyEndpoint),
531
+				'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}read-only' => (int) $row['access'] === Backend::ACCESS_READ,
532
+				'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}public' => (int) $row['access'] === self::ACCESS_PUBLIC,
533 533
 			];
534 534
 
535 535
 			foreach ($this->propertyMap as $xmlName => $dbName) {
@@ -576,27 +576,27 @@  discard block
 block discarded – undo
576 576
 		$result->closeCursor();
577 577
 
578 578
 		if ($row === false) {
579
-			throw new NotFound('Node with name \'' . $uri . '\' could not be found');
579
+			throw new NotFound('Node with name \''.$uri.'\' could not be found');
580 580
 		}
581 581
 
582 582
 		$row['principaluri'] = (string) $row['principaluri'];
583 583
 		list(, $name) = Uri\split($row['principaluri']);
584
-		$row['displayname'] = $row['displayname'] . ' ' . "($name)";
584
+		$row['displayname'] = $row['displayname'].' '."($name)";
585 585
 		$components = [];
586 586
 		if ($row['components']) {
587
-			$components = explode(',',$row['components']);
587
+			$components = explode(',', $row['components']);
588 588
 		}
589 589
 		$calendar = [
590 590
 			'id' => $row['id'],
591 591
 			'uri' => $row['publicuri'],
592 592
 			'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
593
-			'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
594
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
595
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
596
-			'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
597
-			'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
598
-			'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ,
599
-			'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC,
593
+			'{'.Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'),
594
+			'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
595
+			'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
596
+			'{'.Plugin::NS_CALDAV.'}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
597
+			'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}owner-principal' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
598
+			'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}read-only' => (int) $row['access'] === Backend::ACCESS_READ,
599
+			'{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}public' => (int) $row['access'] === self::ACCESS_PUBLIC,
600 600
 		];
601 601
 
602 602
 		foreach ($this->propertyMap as $xmlName => $dbName) {
@@ -639,17 +639,17 @@  discard block
 block discarded – undo
639 639
 		$row['principaluri'] = (string) $row['principaluri'];
640 640
 		$components = [];
641 641
 		if ($row['components']) {
642
-			$components = explode(',',$row['components']);
642
+			$components = explode(',', $row['components']);
643 643
 		}
644 644
 
645 645
 		$calendar = [
646 646
 			'id' => $row['id'],
647 647
 			'uri' => $row['uri'],
648 648
 			'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
649
-			'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
650
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
651
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
652
-			'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
649
+			'{'.Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'),
650
+			'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
651
+			'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
652
+			'{'.Plugin::NS_CALDAV.'}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
653 653
 		];
654 654
 
655 655
 		foreach ($this->propertyMap as $xmlName => $dbName) {
@@ -690,17 +690,17 @@  discard block
 block discarded – undo
690 690
 		$row['principaluri'] = (string) $row['principaluri'];
691 691
 		$components = [];
692 692
 		if ($row['components']) {
693
-			$components = explode(',',$row['components']);
693
+			$components = explode(',', $row['components']);
694 694
 		}
695 695
 
696 696
 		$calendar = [
697 697
 			'id' => $row['id'],
698 698
 			'uri' => $row['uri'],
699 699
 			'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
700
-			'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
701
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
702
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
703
-			'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
700
+			'{'.Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'),
701
+			'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
702
+			'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
703
+			'{'.Plugin::NS_CALDAV.'}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
704 704
 		];
705 705
 
706 706
 		foreach ($this->propertyMap as $xmlName => $dbName) {
@@ -744,8 +744,8 @@  discard block
 block discarded – undo
744 744
 			'principaluri' => $row['principaluri'],
745 745
 			'source' => $row['source'],
746 746
 			'lastmodified' => $row['lastmodified'],
747
-			'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
748
-			'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
747
+			'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
748
+			'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
749 749
 		];
750 750
 
751 751
 		foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
@@ -782,16 +782,16 @@  discard block
 block discarded – undo
782 782
 		$sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
783 783
 		if (isset($properties[$sccs])) {
784 784
 			if (!($properties[$sccs] instanceof SupportedCalendarComponentSet)) {
785
-				throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Property\SupportedCalendarComponentSet');
785
+				throw new DAV\Exception('The '.$sccs.' property must be of type: \Sabre\CalDAV\Property\SupportedCalendarComponentSet');
786 786
 			}
787
-			$values['components'] = implode(',',$properties[$sccs]->getValue());
787
+			$values['components'] = implode(',', $properties[$sccs]->getValue());
788 788
 		} elseif (isset($properties['components'])) {
789 789
 			// Allow to provide components internally without having
790 790
 			// to create a SupportedCalendarComponentSet object
791 791
 			$values['components'] = $properties['components'];
792 792
 		}
793 793
 
794
-		$transp = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
794
+		$transp = '{'.Plugin::NS_CALDAV.'}schedule-calendar-transp';
795 795
 		if (isset($properties[$transp])) {
796 796
 			$values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent');
797 797
 		}
@@ -811,7 +811,7 @@  discard block
 block discarded – undo
811 811
 		$calendarId = $query->getLastInsertId();
812 812
 
813 813
 		$calendarData = $this->getCalendarById($calendarId);
814
-		$this->dispatcher->dispatchTyped(new CalendarCreatedEvent((int)$calendarId, $calendarData));
814
+		$this->dispatcher->dispatchTyped(new CalendarCreatedEvent((int) $calendarId, $calendarData));
815 815
 		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', new GenericEvent(
816 816
 			'\OCA\DAV\CalDAV\CalDavBackend::createCalendar',
817 817
 			[
@@ -840,13 +840,13 @@  discard block
 block discarded – undo
840 840
 	 */
841 841
 	public function updateCalendar($calendarId, PropPatch $propPatch) {
842 842
 		$supportedProperties = array_keys($this->propertyMap);
843
-		$supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
843
+		$supportedProperties[] = '{'.Plugin::NS_CALDAV.'}schedule-calendar-transp';
844 844
 
845
-		$propPatch->handle($supportedProperties, function ($mutations) use ($calendarId) {
845
+		$propPatch->handle($supportedProperties, function($mutations) use ($calendarId) {
846 846
 			$newValues = [];
847 847
 			foreach ($mutations as $propertyName => $propertyValue) {
848 848
 				switch ($propertyName) {
849
-					case '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp':
849
+					case '{'.Plugin::NS_CALDAV.'}schedule-calendar-transp':
850 850
 						$fieldName = 'transparent';
851 851
 						$newValues[$fieldName] = (int) ($propertyValue->getValue() === 'transparent');
852 852
 						break;
@@ -868,7 +868,7 @@  discard block
 block discarded – undo
868 868
 
869 869
 			$calendarData = $this->getCalendarById($calendarId);
870 870
 			$shares = $this->getShares($calendarId);
871
-			$this->dispatcher->dispatchTyped(new CalendarUpdatedEvent((int)$calendarId, $calendarData, $shares, $mutations));
871
+			$this->dispatcher->dispatchTyped(new CalendarUpdatedEvent((int) $calendarId, $calendarData, $shares, $mutations));
872 872
 			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', new GenericEvent(
873 873
 				'\OCA\DAV\CalDAV\CalDavBackend::updateCalendar',
874 874
 				[
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
 			->execute();
919 919
 
920 920
 		if ($calendarData) {
921
-			$this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int)$calendarId, $calendarData, $shares));
921
+			$this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int) $calendarId, $calendarData, $shares));
922 922
 		}
923 923
 	}
924 924
 
@@ -978,11 +978,11 @@  discard block
 block discarded – undo
978 978
 				'id' => $row['id'],
979 979
 				'uri' => $row['uri'],
980 980
 				'lastmodified' => $row['lastmodified'],
981
-				'etag' => '"' . $row['etag'] . '"',
981
+				'etag' => '"'.$row['etag'].'"',
982 982
 				'calendarid' => $row['calendarid'],
983
-				'size' => (int)$row['size'],
983
+				'size' => (int) $row['size'],
984 984
 				'component' => strtolower($row['componenttype']),
985
-				'classification' => (int)$row['classification']
985
+				'classification' => (int) $row['classification']
986 986
 			];
987 987
 		}
988 988
 		$stmt->closeCursor();
@@ -1026,12 +1026,12 @@  discard block
 block discarded – undo
1026 1026
 			'id' => $row['id'],
1027 1027
 			'uri' => $row['uri'],
1028 1028
 			'lastmodified' => $row['lastmodified'],
1029
-			'etag' => '"' . $row['etag'] . '"',
1029
+			'etag' => '"'.$row['etag'].'"',
1030 1030
 			'calendarid' => $row['calendarid'],
1031
-			'size' => (int)$row['size'],
1031
+			'size' => (int) $row['size'],
1032 1032
 			'calendardata' => $this->readBlob($row['calendardata']),
1033 1033
 			'component' => strtolower($row['componenttype']),
1034
-			'classification' => (int)$row['classification']
1034
+			'classification' => (int) $row['classification']
1035 1035
 		];
1036 1036
 	}
1037 1037
 
@@ -1072,12 +1072,12 @@  discard block
 block discarded – undo
1072 1072
 					'id' => $row['id'],
1073 1073
 					'uri' => $row['uri'],
1074 1074
 					'lastmodified' => $row['lastmodified'],
1075
-					'etag' => '"' . $row['etag'] . '"',
1075
+					'etag' => '"'.$row['etag'].'"',
1076 1076
 					'calendarid' => $row['calendarid'],
1077
-					'size' => (int)$row['size'],
1077
+					'size' => (int) $row['size'],
1078 1078
 					'calendardata' => $this->readBlob($row['calendardata']),
1079 1079
 					'component' => strtolower($row['componenttype']),
1080
-					'classification' => (int)$row['classification']
1080
+					'classification' => (int) $row['classification']
1081 1081
 				];
1082 1082
 			}
1083 1083
 			$result->closeCursor();
@@ -1149,7 +1149,7 @@  discard block
 block discarded – undo
1149 1149
 			$calendarRow = $this->getCalendarById($calendarId);
1150 1150
 			$shares = $this->getShares($calendarId);
1151 1151
 
1152
-			$this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
1152
+			$this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent((int) $calendarId, $calendarRow, $shares, $objectRow));
1153 1153
 			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', new GenericEvent(
1154 1154
 				'\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject',
1155 1155
 				[
@@ -1162,7 +1162,7 @@  discard block
 block discarded – undo
1162 1162
 		} else {
1163 1163
 			$subscriptionRow = $this->getSubscriptionById($calendarId);
1164 1164
 
1165
-			$this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
1165
+			$this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent((int) $calendarId, $subscriptionRow, [], $objectRow));
1166 1166
 			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject', new GenericEvent(
1167 1167
 				'\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject',
1168 1168
 				[
@@ -1174,7 +1174,7 @@  discard block
 block discarded – undo
1174 1174
 			));
1175 1175
 		}
1176 1176
 
1177
-		return '"' . $extraData['etag'] . '"';
1177
+		return '"'.$extraData['etag'].'"';
1178 1178
 	}
1179 1179
 
1180 1180
 	/**
@@ -1223,7 +1223,7 @@  discard block
 block discarded – undo
1223 1223
 				$calendarRow = $this->getCalendarById($calendarId);
1224 1224
 				$shares = $this->getShares($calendarId);
1225 1225
 
1226
-				$this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
1226
+				$this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent((int) $calendarId, $calendarRow, $shares, $objectRow));
1227 1227
 				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', new GenericEvent(
1228 1228
 					'\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject',
1229 1229
 					[
@@ -1236,7 +1236,7 @@  discard block
 block discarded – undo
1236 1236
 			} else {
1237 1237
 				$subscriptionRow = $this->getSubscriptionById($calendarId);
1238 1238
 
1239
-				$this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
1239
+				$this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent((int) $calendarId, $subscriptionRow, [], $objectRow));
1240 1240
 				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject', new GenericEvent(
1241 1241
 					'\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject',
1242 1242
 					[
@@ -1249,7 +1249,7 @@  discard block
 block discarded – undo
1249 1249
 			}
1250 1250
 		}
1251 1251
 
1252
-		return '"' . $extraData['etag'] . '"';
1252
+		return '"'.$extraData['etag'].'"';
1253 1253
 	}
1254 1254
 
1255 1255
 	/**
@@ -1286,7 +1286,7 @@  discard block
 block discarded – undo
1286 1286
 				$calendarRow = $this->getCalendarById($calendarId);
1287 1287
 				$shares = $this->getShares($calendarId);
1288 1288
 
1289
-				$this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent((int)$calendarId, $calendarRow, $shares, $data));
1289
+				$this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent((int) $calendarId, $calendarRow, $shares, $data));
1290 1290
 				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', new GenericEvent(
1291 1291
 					'\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject',
1292 1292
 					[
@@ -1299,7 +1299,7 @@  discard block
 block discarded – undo
1299 1299
 			} else {
1300 1300
 				$subscriptionRow = $this->getSubscriptionById($calendarId);
1301 1301
 
1302
-				$this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent((int)$calendarId, $subscriptionRow, [], $data));
1302
+				$this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent((int) $calendarId, $subscriptionRow, [], $data));
1303 1303
 				$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject', new GenericEvent(
1304 1304
 					'\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject',
1305 1305
 					[
@@ -1571,7 +1571,7 @@  discard block
 block discarded – undo
1571 1571
 
1572 1572
 		$result = [];
1573 1573
 		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1574
-			$path = $uriMapper[$row['calendarid']] . '/' . $row['uri'];
1574
+			$path = $uriMapper[$row['calendarid']].'/'.$row['uri'];
1575 1575
 			if (!in_array($path, $result)) {
1576 1576
 				$result[] = $path;
1577 1577
 			}
@@ -1619,8 +1619,8 @@  discard block
 block discarded – undo
1619 1619
 
1620 1620
 		if ($pattern !== '') {
1621 1621
 			$innerQuery->andWhere($innerQuery->expr()->iLike('op.value',
1622
-				$outerQuery->createNamedParameter('%' .
1623
-					$this->db->escapeLikeParameter($pattern) . '%')));
1622
+				$outerQuery->createNamedParameter('%'.
1623
+					$this->db->escapeLikeParameter($pattern).'%')));
1624 1624
 		}
1625 1625
 
1626 1626
 		$outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid', 'c.uri')
@@ -1659,7 +1659,7 @@  discard block
 block discarded – undo
1659 1659
 		$result = $outerQuery->execute();
1660 1660
 		$calendarObjects = $result->fetchAll();
1661 1661
 
1662
-		return array_map(function ($o) {
1662
+		return array_map(function($o) {
1663 1663
 			$calendarData = Reader::read($o['calendardata']);
1664 1664
 			$comps = $calendarData->getComponents();
1665 1665
 			$objects = [];
@@ -1677,10 +1677,10 @@  discard block
 block discarded – undo
1677 1677
 				'type' => $o['componenttype'],
1678 1678
 				'uid' => $o['uid'],
1679 1679
 				'uri' => $o['uri'],
1680
-				'objects' => array_map(function ($c) {
1680
+				'objects' => array_map(function($c) {
1681 1681
 					return $this->transformSearchData($c);
1682 1682
 				}, $objects),
1683
-				'timezones' => array_map(function ($c) {
1683
+				'timezones' => array_map(function($c) {
1684 1684
 					return $this->transformSearchData($c);
1685 1685
 				}, $timezones),
1686 1686
 			];
@@ -1696,7 +1696,7 @@  discard block
 block discarded – undo
1696 1696
 		/** @var Component[] $subComponents */
1697 1697
 		$subComponents = $comp->getComponents();
1698 1698
 		/** @var Property[] $properties */
1699
-		$properties = array_filter($comp->children(), function ($c) {
1699
+		$properties = array_filter($comp->children(), function($c) {
1700 1700
 			return $c instanceof Property;
1701 1701
 		});
1702 1702
 		$validationRules = $comp->getValidationRules();
@@ -1774,7 +1774,7 @@  discard block
 block discarded – undo
1774 1774
 		$subscriptions = $this->getSubscriptionsForUser($principalUri);
1775 1775
 		foreach ($calendars as $calendar) {
1776 1776
 			$calendarAnd = $calendarObjectIdQuery->expr()->andX();
1777
-			$calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$calendar['id'])));
1777
+			$calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int) $calendar['id'])));
1778 1778
 			$calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
1779 1779
 
1780 1780
 			// If it's shared, limit search to public events
@@ -1786,7 +1786,7 @@  discard block
 block discarded – undo
1786 1786
 		}
1787 1787
 		foreach ($subscriptions as $subscription) {
1788 1788
 			$subscriptionAnd = $calendarObjectIdQuery->expr()->andX();
1789
-			$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$subscription['id'])));
1789
+			$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int) $subscription['id'])));
1790 1790
 			$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)));
1791 1791
 
1792 1792
 			// If it's shared, limit search to public events
@@ -1830,7 +1830,7 @@  discard block
 block discarded – undo
1830 1830
 			if (!$escapePattern) {
1831 1831
 				$calendarObjectIdQuery->andWhere($calendarObjectIdQuery->expr()->ilike('cob.value', $calendarObjectIdQuery->createNamedParameter($pattern)));
1832 1832
 			} else {
1833
-				$calendarObjectIdQuery->andWhere($calendarObjectIdQuery->expr()->ilike('cob.value', $calendarObjectIdQuery->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%')));
1833
+				$calendarObjectIdQuery->andWhere($calendarObjectIdQuery->expr()->ilike('cob.value', $calendarObjectIdQuery->createNamedParameter('%'.$this->db->escapeLikeParameter($pattern).'%')));
1834 1834
 			}
1835 1835
 		}
1836 1836
 
@@ -1844,7 +1844,7 @@  discard block
 block discarded – undo
1844 1844
 		$result = $calendarObjectIdQuery->execute();
1845 1845
 		$matches = $result->fetchAll();
1846 1846
 		$result->closeCursor();
1847
-		$matches = array_map(static function (array $match):int {
1847
+		$matches = array_map(static function(array $match):int {
1848 1848
 			return (int) $match['objectid'];
1849 1849
 		}, $matches);
1850 1850
 
@@ -1857,9 +1857,9 @@  discard block
 block discarded – undo
1857 1857
 		$calendarObjects = $result->fetchAll();
1858 1858
 		$result->closeCursor();
1859 1859
 
1860
-		return array_map(function (array $array): array {
1861
-			$array['calendarid'] = (int)$array['calendarid'];
1862
-			$array['calendartype'] = (int)$array['calendartype'];
1860
+		return array_map(function(array $array): array {
1861
+			$array['calendarid'] = (int) $array['calendarid'];
1862
+			$array['calendartype'] = (int) $array['calendartype'];
1863 1863
 			$array['calendardata'] = $this->readBlob($array['calendardata']);
1864 1864
 
1865 1865
 			return $array;
@@ -1896,7 +1896,7 @@  discard block
 block discarded – undo
1896 1896
 		$stmt = $query->execute();
1897 1897
 
1898 1898
 		if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1899
-			return $row['calendaruri'] . '/' . $row['objecturi'];
1899
+			return $row['calendaruri'].'/'.$row['objecturi'];
1900 1900
 		}
1901 1901
 
1902 1902
 		return null;
@@ -1962,7 +1962,7 @@  discard block
 block discarded – undo
1962 1962
 	public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
1963 1963
 		// Current synctoken
1964 1964
 		$stmt = $this->db->prepare('SELECT `synctoken` FROM `*PREFIX*calendars` WHERE `id` = ?');
1965
-		$stmt->execute([ $calendarId ]);
1965
+		$stmt->execute([$calendarId]);
1966 1966
 		$currentToken = $stmt->fetchColumn(0);
1967 1967
 
1968 1968
 		if (is_null($currentToken)) {
@@ -1979,7 +1979,7 @@  discard block
 block discarded – undo
1979 1979
 		if ($syncToken) {
1980 1980
 			$query = "SELECT `uri`, `operation` FROM `*PREFIX*calendarchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `calendarid` = ? AND `calendartype` = ? ORDER BY `synctoken`";
1981 1981
 			if ($limit > 0) {
1982
-				$query .= " LIMIT " . (int)$limit;
1982
+				$query .= " LIMIT ".(int) $limit;
1983 1983
 			}
1984 1984
 
1985 1985
 			// Fetching all changes
@@ -2075,8 +2075,8 @@  discard block
 block discarded – undo
2075 2075
 				'source' => $row['source'],
2076 2076
 				'lastmodified' => $row['lastmodified'],
2077 2077
 
2078
-				'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
2079
-				'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
2078
+				'{'.Plugin::NS_CALDAV.'}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
2079
+				'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
2080 2080
 			];
2081 2081
 
2082 2082
 			foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
@@ -2140,7 +2140,7 @@  discard block
 block discarded – undo
2140 2140
 		$subscriptionId = $this->db->lastInsertId('*PREFIX*calendarsubscriptions');
2141 2141
 
2142 2142
 		$subscriptionRow = $this->getSubscriptionById($subscriptionId);
2143
-		$this->dispatcher->dispatchTyped(new SubscriptionCreatedEvent((int)$subscriptionId, $subscriptionRow));
2143
+		$this->dispatcher->dispatchTyped(new SubscriptionCreatedEvent((int) $subscriptionId, $subscriptionRow));
2144 2144
 		$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createSubscription', new GenericEvent(
2145 2145
 			'\OCA\DAV\CalDAV\CalDavBackend::createSubscription',
2146 2146
 			[
@@ -2171,7 +2171,7 @@  discard block
 block discarded – undo
2171 2171
 		$supportedProperties = array_keys($this->subscriptionPropertyMap);
2172 2172
 		$supportedProperties[] = '{http://calendarserver.org/ns/}source';
2173 2173
 
2174
-		$propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) {
2174
+		$propPatch->handle($supportedProperties, function($mutations) use ($subscriptionId) {
2175 2175
 			$newValues = [];
2176 2176
 
2177 2177
 			foreach ($mutations as $propertyName => $propertyValue) {
@@ -2193,7 +2193,7 @@  discard block
 block discarded – undo
2193 2193
 				->execute();
2194 2194
 
2195 2195
 			$subscriptionRow = $this->getSubscriptionById($subscriptionId);
2196
-			$this->dispatcher->dispatchTyped(new SubscriptionUpdatedEvent((int)$subscriptionId, $subscriptionRow, [], $mutations));
2196
+			$this->dispatcher->dispatchTyped(new SubscriptionUpdatedEvent((int) $subscriptionId, $subscriptionRow, [], $mutations));
2197 2197
 			$this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateSubscription', new GenericEvent(
2198 2198
 				'\OCA\DAV\CalDAV\CalDavBackend::updateSubscription',
2199 2199
 				[
@@ -2244,7 +2244,7 @@  discard block
 block discarded – undo
2244 2244
 			->execute();
2245 2245
 
2246 2246
 		if ($subscriptionRow) {
2247
-			$this->dispatcher->dispatchTyped(new SubscriptionDeletedEvent((int)$subscriptionId, $subscriptionRow, []));
2247
+			$this->dispatcher->dispatchTyped(new SubscriptionDeletedEvent((int) $subscriptionId, $subscriptionRow, []));
2248 2248
 		}
2249 2249
 	}
2250 2250
 
@@ -2282,8 +2282,8 @@  discard block
 block discarded – undo
2282 2282
 			'uri' => $row['uri'],
2283 2283
 			'calendardata' => $row['calendardata'],
2284 2284
 			'lastmodified' => $row['lastmodified'],
2285
-			'etag' => '"' . $row['etag'] . '"',
2286
-			'size' => (int)$row['size'],
2285
+			'etag' => '"'.$row['etag'].'"',
2286
+			'size' => (int) $row['size'],
2287 2287
 		];
2288 2288
 	}
2289 2289
 
@@ -2311,8 +2311,8 @@  discard block
 block discarded – undo
2311 2311
 				'calendardata' => $row['calendardata'],
2312 2312
 				'uri' => $row['uri'],
2313 2313
 				'lastmodified' => $row['lastmodified'],
2314
-				'etag' => '"' . $row['etag'] . '"',
2315
-				'size' => (int)$row['size'],
2314
+				'etag' => '"'.$row['etag'].'"',
2315
+				'size' => (int) $row['size'],
2316 2316
 			];
2317 2317
 		}
2318 2318
 
@@ -2366,14 +2366,14 @@  discard block
 block discarded – undo
2366 2366
 	 * @return void
2367 2367
 	 */
2368 2368
 	protected function addChange($calendarId, $objectUri, $operation, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
2369
-		$table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions';
2369
+		$table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars' : 'calendarsubscriptions';
2370 2370
 
2371 2371
 		$query = $this->db->getQueryBuilder();
2372 2372
 		$query->select('synctoken')
2373 2373
 			->from($table)
2374 2374
 			->where($query->expr()->eq('id', $query->createNamedParameter($calendarId)));
2375 2375
 		$result = $query->execute();
2376
-		$syncToken = (int)$result->fetchColumn();
2376
+		$syncToken = (int) $result->fetchColumn();
2377 2377
 		$result->closeCursor();
2378 2378
 
2379 2379
 		$query = $this->db->getQueryBuilder();
@@ -2430,7 +2430,7 @@  discard block
 block discarded – undo
2430 2430
 				// Track first component type and uid
2431 2431
 				if ($uid === null) {
2432 2432
 					$componentType = $component->name;
2433
-					$uid = (string)$component->UID;
2433
+					$uid = (string) $component->UID;
2434 2434
 				}
2435 2435
 			}
2436 2436
 		}
@@ -2529,7 +2529,7 @@  discard block
 block discarded – undo
2529 2529
 			]));
2530 2530
 		$this->calendarSharingBackend->updateShares($shareable, $add, $remove);
2531 2531
 
2532
-		$this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent((int)$calendarId, $calendarRow, $oldShares, $add, $remove));
2532
+		$this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent((int) $calendarId, $calendarRow, $oldShares, $add, $remove));
2533 2533
 	}
2534 2534
 
2535 2535
 	/**
@@ -2570,7 +2570,7 @@  discard block
 block discarded – undo
2570 2570
 				]);
2571 2571
 			$query->execute();
2572 2572
 
2573
-			$this->dispatcher->dispatchTyped(new CalendarPublishedEvent((int)$calendarId, $calendarData, $publicUri));
2573
+			$this->dispatcher->dispatchTyped(new CalendarPublishedEvent((int) $calendarId, $calendarData, $publicUri));
2574 2574
 			return $publicUri;
2575 2575
 		}
2576 2576
 		$query->delete('dav_shares')
@@ -2578,7 +2578,7 @@  discard block
 block discarded – undo
2578 2578
 			->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)));
2579 2579
 		$query->execute();
2580 2580
 
2581
-		$this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent((int)$calendarId, $calendarData));
2581
+		$this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent((int) $calendarId, $calendarData));
2582 2582
 		return null;
2583 2583
 	}
2584 2584
 
@@ -2799,10 +2799,10 @@  discard block
 block discarded – undo
2799 2799
 		$result->closeCursor();
2800 2800
 
2801 2801
 		if (!isset($objectIds['id'])) {
2802
-			throw new \InvalidArgumentException('Calendarobject does not exists: ' . $uri);
2802
+			throw new \InvalidArgumentException('Calendarobject does not exists: '.$uri);
2803 2803
 		}
2804 2804
 
2805
-		return (int)$objectIds['id'];
2805
+		return (int) $objectIds['id'];
2806 2806
 	}
2807 2807
 
2808 2808
 	/**
@@ -2829,8 +2829,8 @@  discard block
 block discarded – undo
2829 2829
 	 * @param $calendarInfo
2830 2830
 	 */
2831 2831
 	private function addOwnerPrincipal(&$calendarInfo) {
2832
-		$ownerPrincipalKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal';
2833
-		$displaynameKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}owner-displayname';
2832
+		$ownerPrincipalKey = '{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}owner-principal';
2833
+		$displaynameKey = '{'.\OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD.'}owner-displayname';
2834 2834
 		if (isset($calendarInfo[$ownerPrincipalKey])) {
2835 2835
 			$uri = $calendarInfo[$ownerPrincipalKey];
2836 2836
 		} else {
Please login to merge, or discard this patch.
apps/dav/lib/Migration/Version1016Date20201109085907.php 1 patch
Indentation   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -32,30 +32,30 @@
 block discarded – undo
32 32
 use OCP\Migration\SimpleMigrationStep;
33 33
 
34 34
 class Version1016Date20201109085907 extends SimpleMigrationStep {
35
-	/**
36
-	 * @param IOutput $output
37
-	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
38
-	 * @param array $options
39
-	 * @return null|ISchemaWrapper
40
-	 */
41
-	public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
42
-		/** @var ISchemaWrapper $schema */
43
-		$schema = $schemaClosure();
44
-
45
-		$result = $this->ensureColumnIsNullable($schema, 'calendar_reminders', 'is_recurring');
46
-
47
-		return $result ? $schema : null;
48
-	}
49
-
50
-	protected function ensureColumnIsNullable(ISchemaWrapper $schema, string $tableName, string $columnName): bool {
51
-		$table = $schema->getTable($tableName);
52
-		$column = $table->getColumn($columnName);
53
-
54
-		if ($column->getNotnull()) {
55
-			$column->setNotnull(false);
56
-			return true;
57
-		}
58
-
59
-		return false;
60
-	}
35
+    /**
36
+     * @param IOutput $output
37
+     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
38
+     * @param array $options
39
+     * @return null|ISchemaWrapper
40
+     */
41
+    public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
42
+        /** @var ISchemaWrapper $schema */
43
+        $schema = $schemaClosure();
44
+
45
+        $result = $this->ensureColumnIsNullable($schema, 'calendar_reminders', 'is_recurring');
46
+
47
+        return $result ? $schema : null;
48
+    }
49
+
50
+    protected function ensureColumnIsNullable(ISchemaWrapper $schema, string $tableName, string $columnName): bool {
51
+        $table = $schema->getTable($tableName);
52
+        $column = $table->getColumn($columnName);
53
+
54
+        if ($column->getNotnull()) {
55
+            $column->setNotnull(false);
56
+            return true;
57
+        }
58
+
59
+        return false;
60
+    }
61 61
 }
Please login to merge, or discard this patch.
apps/dav/lib/Migration/Version1012Date20190808122342.php 1 patch
Indentation   +77 added lines, -77 removed lines patch added patch discarded remove patch
@@ -38,86 +38,86 @@
 block discarded – undo
38 38
  */
39 39
 class Version1012Date20190808122342 extends SimpleMigrationStep {
40 40
 
41
-	/**
42
-	 * @param IOutput $output
43
-	 * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
44
-	 * @param array $options
45
-	 * @return null|ISchemaWrapper
46
-	 * @since 17.0.0
47
-	 */
48
-	public function changeSchema(IOutput $output,
49
-								 \Closure $schemaClosure,
50
-								 array $options):?ISchemaWrapper {
51
-		/** @var ISchemaWrapper $schema */
52
-		$schema = $schemaClosure();
41
+    /**
42
+     * @param IOutput $output
43
+     * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
44
+     * @param array $options
45
+     * @return null|ISchemaWrapper
46
+     * @since 17.0.0
47
+     */
48
+    public function changeSchema(IOutput $output,
49
+                                    \Closure $schemaClosure,
50
+                                    array $options):?ISchemaWrapper {
51
+        /** @var ISchemaWrapper $schema */
52
+        $schema = $schemaClosure();
53 53
 
54
-		if (!$schema->hasTable('calendar_reminders')) {
55
-			$table = $schema->createTable('calendar_reminders');
54
+        if (!$schema->hasTable('calendar_reminders')) {
55
+            $table = $schema->createTable('calendar_reminders');
56 56
 
57
-			$table->addColumn('id', Types::BIGINT, [
58
-				'autoincrement' => true,
59
-				'notnull' => true,
60
-				'length' => 11,
61
-				'unsigned' => true,
62
-			]);
63
-			$table->addColumn('calendar_id', Types::BIGINT, [
64
-				'notnull' => true,
65
-				'length' => 11,
66
-			]);
67
-			$table->addColumn('object_id', Types::BIGINT, [
68
-				'notnull' => true,
69
-				'length' => 11,
70
-			]);
71
-			$table->addColumn('is_recurring', Types::SMALLINT, [
72
-				'notnull' => false,
73
-				'length' => 1,
74
-			]);
75
-			$table->addColumn('uid', Types::STRING, [
76
-				'notnull' => true,
77
-				'length' => 255,
78
-			]);
79
-			$table->addColumn('recurrence_id', Types::BIGINT, [
80
-				'notnull' => false,
81
-				'length' => 11,
82
-				'unsigned' => true,
83
-			]);
84
-			$table->addColumn('is_recurrence_exception', Types::SMALLINT, [
85
-				'notnull' => true,
86
-				'length' => 1,
87
-			]);
88
-			$table->addColumn('event_hash', Types::STRING, [
89
-				'notnull' => true,
90
-				'length' => 255,
91
-			]);
92
-			$table->addColumn('alarm_hash', Types::STRING, [
93
-				'notnull' => true,
94
-				'length' => 255,
95
-			]);
96
-			$table->addColumn('type', Types::STRING, [
97
-				'notnull' => true,
98
-				'length' => 255,
99
-			]);
100
-			$table->addColumn('is_relative', Types::SMALLINT, [
101
-				'notnull' => true,
102
-				'length' => 1,
103
-			]);
104
-			$table->addColumn('notification_date', Types::BIGINT, [
105
-				'notnull' => true,
106
-				'length' => 11,
107
-				'unsigned' => true,
108
-			]);
109
-			$table->addColumn('is_repeat_based', Types::SMALLINT, [
110
-				'notnull' => true,
111
-				'length' => 1,
112
-			]);
57
+            $table->addColumn('id', Types::BIGINT, [
58
+                'autoincrement' => true,
59
+                'notnull' => true,
60
+                'length' => 11,
61
+                'unsigned' => true,
62
+            ]);
63
+            $table->addColumn('calendar_id', Types::BIGINT, [
64
+                'notnull' => true,
65
+                'length' => 11,
66
+            ]);
67
+            $table->addColumn('object_id', Types::BIGINT, [
68
+                'notnull' => true,
69
+                'length' => 11,
70
+            ]);
71
+            $table->addColumn('is_recurring', Types::SMALLINT, [
72
+                'notnull' => false,
73
+                'length' => 1,
74
+            ]);
75
+            $table->addColumn('uid', Types::STRING, [
76
+                'notnull' => true,
77
+                'length' => 255,
78
+            ]);
79
+            $table->addColumn('recurrence_id', Types::BIGINT, [
80
+                'notnull' => false,
81
+                'length' => 11,
82
+                'unsigned' => true,
83
+            ]);
84
+            $table->addColumn('is_recurrence_exception', Types::SMALLINT, [
85
+                'notnull' => true,
86
+                'length' => 1,
87
+            ]);
88
+            $table->addColumn('event_hash', Types::STRING, [
89
+                'notnull' => true,
90
+                'length' => 255,
91
+            ]);
92
+            $table->addColumn('alarm_hash', Types::STRING, [
93
+                'notnull' => true,
94
+                'length' => 255,
95
+            ]);
96
+            $table->addColumn('type', Types::STRING, [
97
+                'notnull' => true,
98
+                'length' => 255,
99
+            ]);
100
+            $table->addColumn('is_relative', Types::SMALLINT, [
101
+                'notnull' => true,
102
+                'length' => 1,
103
+            ]);
104
+            $table->addColumn('notification_date', Types::BIGINT, [
105
+                'notnull' => true,
106
+                'length' => 11,
107
+                'unsigned' => true,
108
+            ]);
109
+            $table->addColumn('is_repeat_based', Types::SMALLINT, [
110
+                'notnull' => true,
111
+                'length' => 1,
112
+            ]);
113 113
 
114
-			$table->setPrimaryKey(['id']);
115
-			$table->addIndex(['object_id'], 'calendar_reminder_objid');
116
-			$table->addIndex(['uid', 'recurrence_id'], 'calendar_reminder_uidrec');
114
+            $table->setPrimaryKey(['id']);
115
+            $table->addIndex(['object_id'], 'calendar_reminder_objid');
116
+            $table->addIndex(['uid', 'recurrence_id'], 'calendar_reminder_uidrec');
117 117
 
118
-			return $schema;
119
-		}
118
+            return $schema;
119
+        }
120 120
 
121
-		return null;
122
-	}
121
+        return null;
122
+    }
123 123
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/CheckSetupController.php 1 patch
Indentation   +665 added lines, -665 removed lines patch added patch discarded remove patch
@@ -76,292 +76,292 @@  discard block
 block discarded – undo
76 76
 use Symfony\Component\EventDispatcher\GenericEvent;
77 77
 
78 78
 class CheckSetupController extends Controller {
79
-	/** @var IConfig */
80
-	private $config;
81
-	/** @var IClientService */
82
-	private $clientService;
83
-	/** @var IURLGenerator */
84
-	private $urlGenerator;
85
-	/** @var IL10N */
86
-	private $l10n;
87
-	/** @var Checker */
88
-	private $checker;
89
-	/** @var ILogger */
90
-	private $logger;
91
-	/** @var EventDispatcherInterface */
92
-	private $dispatcher;
93
-	/** @var IDBConnection|Connection */
94
-	private $db;
95
-	/** @var ILockingProvider */
96
-	private $lockingProvider;
97
-	/** @var IDateTimeFormatter */
98
-	private $dateTimeFormatter;
99
-	/** @var MemoryInfo */
100
-	private $memoryInfo;
101
-	/** @var ISecureRandom */
102
-	private $secureRandom;
103
-	/** @var IniGetWrapper */
104
-	private $iniGetWrapper;
105
-
106
-	public function __construct($AppName,
107
-								IRequest $request,
108
-								IConfig $config,
109
-								IClientService $clientService,
110
-								IURLGenerator $urlGenerator,
111
-								IL10N $l10n,
112
-								Checker $checker,
113
-								ILogger $logger,
114
-								EventDispatcherInterface $dispatcher,
115
-								IDBConnection $db,
116
-								ILockingProvider $lockingProvider,
117
-								IDateTimeFormatter $dateTimeFormatter,
118
-								MemoryInfo $memoryInfo,
119
-								ISecureRandom $secureRandom,
120
-								IniGetWrapper $iniGetWrapper) {
121
-		parent::__construct($AppName, $request);
122
-		$this->config = $config;
123
-		$this->clientService = $clientService;
124
-		$this->urlGenerator = $urlGenerator;
125
-		$this->l10n = $l10n;
126
-		$this->checker = $checker;
127
-		$this->logger = $logger;
128
-		$this->dispatcher = $dispatcher;
129
-		$this->db = $db;
130
-		$this->lockingProvider = $lockingProvider;
131
-		$this->dateTimeFormatter = $dateTimeFormatter;
132
-		$this->memoryInfo = $memoryInfo;
133
-		$this->secureRandom = $secureRandom;
134
-		$this->iniGetWrapper = $iniGetWrapper;
135
-	}
136
-
137
-	/**
138
-	 * Checks if the server can connect to the internet using HTTPS and HTTP
139
-	 * @return bool
140
-	 */
141
-	private function hasInternetConnectivityProblems(): bool {
142
-		if ($this->config->getSystemValue('has_internet_connection', true) === false) {
143
-			return false;
144
-		}
145
-
146
-		$siteArray = $this->config->getSystemValue('connectivity_check_domains', [
147
-			'www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org'
148
-		]);
149
-
150
-		foreach ($siteArray as $site) {
151
-			if ($this->isSiteReachable($site)) {
152
-				return false;
153
-			}
154
-		}
155
-		return true;
156
-	}
157
-
158
-	/**
159
-	 * Checks if the Nextcloud server can connect to a specific URL using both HTTPS and HTTP
160
-	 * @return bool
161
-	 */
162
-	private function isSiteReachable($sitename) {
163
-		$httpSiteName = 'http://' . $sitename . '/';
164
-		$httpsSiteName = 'https://' . $sitename . '/';
165
-
166
-		try {
167
-			$client = $this->clientService->newClient();
168
-			$client->get($httpSiteName);
169
-			$client->get($httpsSiteName);
170
-		} catch (\Exception $e) {
171
-			$this->logger->logException($e, ['app' => 'internet_connection_check']);
172
-			return false;
173
-		}
174
-		return true;
175
-	}
176
-
177
-	/**
178
-	 * Checks whether a local memcache is installed or not
179
-	 * @return bool
180
-	 */
181
-	private function isMemcacheConfigured() {
182
-		return $this->config->getSystemValue('memcache.local', null) !== null;
183
-	}
184
-
185
-	/**
186
-	 * Whether PHP can generate "secure" pseudorandom integers
187
-	 *
188
-	 * @return bool
189
-	 */
190
-	private function isRandomnessSecure() {
191
-		try {
192
-			$this->secureRandom->generate(1);
193
-		} catch (\Exception $ex) {
194
-			return false;
195
-		}
196
-		return true;
197
-	}
198
-
199
-	/**
200
-	 * Public for the sake of unit-testing
201
-	 *
202
-	 * @return array
203
-	 */
204
-	protected function getCurlVersion() {
205
-		return curl_version();
206
-	}
207
-
208
-	/**
209
-	 * Check if the used  SSL lib is outdated. Older OpenSSL and NSS versions do
210
-	 * have multiple bugs which likely lead to problems in combination with
211
-	 * functionality required by ownCloud such as SNI.
212
-	 *
213
-	 * @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
214
-	 * @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
215
-	 * @return string
216
-	 */
217
-	private function isUsedTlsLibOutdated() {
218
-		// Don't run check when:
219
-		// 1. Server has `has_internet_connection` set to false
220
-		// 2. AppStore AND S2S is disabled
221
-		if (!$this->config->getSystemValue('has_internet_connection', true)) {
222
-			return '';
223
-		}
224
-		if (!$this->config->getSystemValue('appstoreenabled', true)
225
-			&& $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'no'
226
-			&& $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'no') {
227
-			return '';
228
-		}
229
-
230
-		$versionString = $this->getCurlVersion();
231
-		if (isset($versionString['ssl_version'])) {
232
-			$versionString = $versionString['ssl_version'];
233
-		} else {
234
-			return '';
235
-		}
236
-
237
-		$features = (string)$this->l10n->t('installing and updating apps via the app store or Federated Cloud Sharing');
238
-		if (!$this->config->getSystemValue('appstoreenabled', true)) {
239
-			$features = (string)$this->l10n->t('Federated Cloud Sharing');
240
-		}
241
-
242
-		// Check if at least OpenSSL after 1.01d or 1.0.2b
243
-		if (strpos($versionString, 'OpenSSL/') === 0) {
244
-			$majorVersion = substr($versionString, 8, 5);
245
-			$patchRelease = substr($versionString, 13, 6);
246
-
247
-			if (($majorVersion === '1.0.1' && ord($patchRelease) < ord('d')) ||
248
-				($majorVersion === '1.0.2' && ord($patchRelease) < ord('b'))) {
249
-				return $this->l10n->t('cURL is using an outdated %1$s version (%2$s). Please update your operating system or features such as %3$s will not work reliably.', ['OpenSSL', $versionString, $features]);
250
-			}
251
-		}
252
-
253
-		// Check if NSS and perform heuristic check
254
-		if (strpos($versionString, 'NSS/') === 0) {
255
-			try {
256
-				$firstClient = $this->clientService->newClient();
257
-				$firstClient->get('https://nextcloud.com/');
258
-
259
-				$secondClient = $this->clientService->newClient();
260
-				$secondClient->get('https://nextcloud.com/');
261
-			} catch (ClientException $e) {
262
-				if ($e->getResponse()->getStatusCode() === 400) {
263
-					return $this->l10n->t('cURL is using an outdated %1$s version (%2$s). Please update your operating system or features such as %3$s will not work reliably.', ['NSS', $versionString, $features]);
264
-				}
265
-			}
266
-		}
267
-
268
-		return '';
269
-	}
270
-
271
-	/**
272
-	 * Whether the version is outdated
273
-	 *
274
-	 * @return bool
275
-	 */
276
-	protected function isPhpOutdated(): bool {
277
-		return PHP_VERSION_ID < 70300;
278
-	}
279
-
280
-	/**
281
-	 * Whether the php version is still supported (at time of release)
282
-	 * according to: https://secure.php.net/supported-versions.php
283
-	 *
284
-	 * @return array
285
-	 */
286
-	private function isPhpSupported(): array {
287
-		return ['eol' => $this->isPhpOutdated(), 'version' => PHP_VERSION];
288
-	}
289
-
290
-	/**
291
-	 * Check if the reverse proxy configuration is working as expected
292
-	 *
293
-	 * @return bool
294
-	 */
295
-	private function forwardedForHeadersWorking() {
296
-		$trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
297
-		$remoteAddress = $this->request->getHeader('REMOTE_ADDR');
298
-
299
-		if (empty($trustedProxies) && $this->request->getHeader('X-Forwarded-Host') !== '') {
300
-			return false;
301
-		}
302
-
303
-		if (\is_array($trustedProxies) && \in_array($remoteAddress, $trustedProxies, true)) {
304
-			return $remoteAddress !== $this->request->getRemoteAddress();
305
-		}
306
-
307
-		// either not enabled or working correctly
308
-		return true;
309
-	}
310
-
311
-	/**
312
-	 * Checks if the correct memcache module for PHP is installed. Only
313
-	 * fails if memcached is configured and the working module is not installed.
314
-	 *
315
-	 * @return bool
316
-	 */
317
-	private function isCorrectMemcachedPHPModuleInstalled() {
318
-		if ($this->config->getSystemValue('memcache.distributed', null) !== '\OC\Memcache\Memcached') {
319
-			return true;
320
-		}
321
-
322
-		// there are two different memcached modules for PHP
323
-		// we only support memcached and not memcache
324
-		// https://code.google.com/p/memcached/wiki/PHPClientComparison
325
-		return !(!extension_loaded('memcached') && extension_loaded('memcache'));
326
-	}
327
-
328
-	/**
329
-	 * Checks if set_time_limit is not disabled.
330
-	 *
331
-	 * @return bool
332
-	 */
333
-	private function isSettimelimitAvailable() {
334
-		if (function_exists('set_time_limit')
335
-			&& strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
336
-			return true;
337
-		}
338
-
339
-		return false;
340
-	}
341
-
342
-	/**
343
-	 * @return RedirectResponse
344
-	 */
345
-	public function rescanFailedIntegrityCheck() {
346
-		$this->checker->runInstanceVerification();
347
-		return new RedirectResponse(
348
-			$this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'overview'])
349
-		);
350
-	}
351
-
352
-	/**
353
-	 * @NoCSRFRequired
354
-	 * @return DataResponse
355
-	 */
356
-	public function getFailedIntegrityCheckFiles() {
357
-		if (!$this->checker->isCodeCheckEnforced()) {
358
-			return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.');
359
-		}
360
-
361
-		$completeResults = $this->checker->getResults();
362
-
363
-		if (!empty($completeResults)) {
364
-			$formattedTextResponse = 'Technical information
79
+    /** @var IConfig */
80
+    private $config;
81
+    /** @var IClientService */
82
+    private $clientService;
83
+    /** @var IURLGenerator */
84
+    private $urlGenerator;
85
+    /** @var IL10N */
86
+    private $l10n;
87
+    /** @var Checker */
88
+    private $checker;
89
+    /** @var ILogger */
90
+    private $logger;
91
+    /** @var EventDispatcherInterface */
92
+    private $dispatcher;
93
+    /** @var IDBConnection|Connection */
94
+    private $db;
95
+    /** @var ILockingProvider */
96
+    private $lockingProvider;
97
+    /** @var IDateTimeFormatter */
98
+    private $dateTimeFormatter;
99
+    /** @var MemoryInfo */
100
+    private $memoryInfo;
101
+    /** @var ISecureRandom */
102
+    private $secureRandom;
103
+    /** @var IniGetWrapper */
104
+    private $iniGetWrapper;
105
+
106
+    public function __construct($AppName,
107
+                                IRequest $request,
108
+                                IConfig $config,
109
+                                IClientService $clientService,
110
+                                IURLGenerator $urlGenerator,
111
+                                IL10N $l10n,
112
+                                Checker $checker,
113
+                                ILogger $logger,
114
+                                EventDispatcherInterface $dispatcher,
115
+                                IDBConnection $db,
116
+                                ILockingProvider $lockingProvider,
117
+                                IDateTimeFormatter $dateTimeFormatter,
118
+                                MemoryInfo $memoryInfo,
119
+                                ISecureRandom $secureRandom,
120
+                                IniGetWrapper $iniGetWrapper) {
121
+        parent::__construct($AppName, $request);
122
+        $this->config = $config;
123
+        $this->clientService = $clientService;
124
+        $this->urlGenerator = $urlGenerator;
125
+        $this->l10n = $l10n;
126
+        $this->checker = $checker;
127
+        $this->logger = $logger;
128
+        $this->dispatcher = $dispatcher;
129
+        $this->db = $db;
130
+        $this->lockingProvider = $lockingProvider;
131
+        $this->dateTimeFormatter = $dateTimeFormatter;
132
+        $this->memoryInfo = $memoryInfo;
133
+        $this->secureRandom = $secureRandom;
134
+        $this->iniGetWrapper = $iniGetWrapper;
135
+    }
136
+
137
+    /**
138
+     * Checks if the server can connect to the internet using HTTPS and HTTP
139
+     * @return bool
140
+     */
141
+    private function hasInternetConnectivityProblems(): bool {
142
+        if ($this->config->getSystemValue('has_internet_connection', true) === false) {
143
+            return false;
144
+        }
145
+
146
+        $siteArray = $this->config->getSystemValue('connectivity_check_domains', [
147
+            'www.nextcloud.com', 'www.startpage.com', 'www.eff.org', 'www.edri.org'
148
+        ]);
149
+
150
+        foreach ($siteArray as $site) {
151
+            if ($this->isSiteReachable($site)) {
152
+                return false;
153
+            }
154
+        }
155
+        return true;
156
+    }
157
+
158
+    /**
159
+     * Checks if the Nextcloud server can connect to a specific URL using both HTTPS and HTTP
160
+     * @return bool
161
+     */
162
+    private function isSiteReachable($sitename) {
163
+        $httpSiteName = 'http://' . $sitename . '/';
164
+        $httpsSiteName = 'https://' . $sitename . '/';
165
+
166
+        try {
167
+            $client = $this->clientService->newClient();
168
+            $client->get($httpSiteName);
169
+            $client->get($httpsSiteName);
170
+        } catch (\Exception $e) {
171
+            $this->logger->logException($e, ['app' => 'internet_connection_check']);
172
+            return false;
173
+        }
174
+        return true;
175
+    }
176
+
177
+    /**
178
+     * Checks whether a local memcache is installed or not
179
+     * @return bool
180
+     */
181
+    private function isMemcacheConfigured() {
182
+        return $this->config->getSystemValue('memcache.local', null) !== null;
183
+    }
184
+
185
+    /**
186
+     * Whether PHP can generate "secure" pseudorandom integers
187
+     *
188
+     * @return bool
189
+     */
190
+    private function isRandomnessSecure() {
191
+        try {
192
+            $this->secureRandom->generate(1);
193
+        } catch (\Exception $ex) {
194
+            return false;
195
+        }
196
+        return true;
197
+    }
198
+
199
+    /**
200
+     * Public for the sake of unit-testing
201
+     *
202
+     * @return array
203
+     */
204
+    protected function getCurlVersion() {
205
+        return curl_version();
206
+    }
207
+
208
+    /**
209
+     * Check if the used  SSL lib is outdated. Older OpenSSL and NSS versions do
210
+     * have multiple bugs which likely lead to problems in combination with
211
+     * functionality required by ownCloud such as SNI.
212
+     *
213
+     * @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
214
+     * @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
215
+     * @return string
216
+     */
217
+    private function isUsedTlsLibOutdated() {
218
+        // Don't run check when:
219
+        // 1. Server has `has_internet_connection` set to false
220
+        // 2. AppStore AND S2S is disabled
221
+        if (!$this->config->getSystemValue('has_internet_connection', true)) {
222
+            return '';
223
+        }
224
+        if (!$this->config->getSystemValue('appstoreenabled', true)
225
+            && $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'no'
226
+            && $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'no') {
227
+            return '';
228
+        }
229
+
230
+        $versionString = $this->getCurlVersion();
231
+        if (isset($versionString['ssl_version'])) {
232
+            $versionString = $versionString['ssl_version'];
233
+        } else {
234
+            return '';
235
+        }
236
+
237
+        $features = (string)$this->l10n->t('installing and updating apps via the app store or Federated Cloud Sharing');
238
+        if (!$this->config->getSystemValue('appstoreenabled', true)) {
239
+            $features = (string)$this->l10n->t('Federated Cloud Sharing');
240
+        }
241
+
242
+        // Check if at least OpenSSL after 1.01d or 1.0.2b
243
+        if (strpos($versionString, 'OpenSSL/') === 0) {
244
+            $majorVersion = substr($versionString, 8, 5);
245
+            $patchRelease = substr($versionString, 13, 6);
246
+
247
+            if (($majorVersion === '1.0.1' && ord($patchRelease) < ord('d')) ||
248
+                ($majorVersion === '1.0.2' && ord($patchRelease) < ord('b'))) {
249
+                return $this->l10n->t('cURL is using an outdated %1$s version (%2$s). Please update your operating system or features such as %3$s will not work reliably.', ['OpenSSL', $versionString, $features]);
250
+            }
251
+        }
252
+
253
+        // Check if NSS and perform heuristic check
254
+        if (strpos($versionString, 'NSS/') === 0) {
255
+            try {
256
+                $firstClient = $this->clientService->newClient();
257
+                $firstClient->get('https://nextcloud.com/');
258
+
259
+                $secondClient = $this->clientService->newClient();
260
+                $secondClient->get('https://nextcloud.com/');
261
+            } catch (ClientException $e) {
262
+                if ($e->getResponse()->getStatusCode() === 400) {
263
+                    return $this->l10n->t('cURL is using an outdated %1$s version (%2$s). Please update your operating system or features such as %3$s will not work reliably.', ['NSS', $versionString, $features]);
264
+                }
265
+            }
266
+        }
267
+
268
+        return '';
269
+    }
270
+
271
+    /**
272
+     * Whether the version is outdated
273
+     *
274
+     * @return bool
275
+     */
276
+    protected function isPhpOutdated(): bool {
277
+        return PHP_VERSION_ID < 70300;
278
+    }
279
+
280
+    /**
281
+     * Whether the php version is still supported (at time of release)
282
+     * according to: https://secure.php.net/supported-versions.php
283
+     *
284
+     * @return array
285
+     */
286
+    private function isPhpSupported(): array {
287
+        return ['eol' => $this->isPhpOutdated(), 'version' => PHP_VERSION];
288
+    }
289
+
290
+    /**
291
+     * Check if the reverse proxy configuration is working as expected
292
+     *
293
+     * @return bool
294
+     */
295
+    private function forwardedForHeadersWorking() {
296
+        $trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
297
+        $remoteAddress = $this->request->getHeader('REMOTE_ADDR');
298
+
299
+        if (empty($trustedProxies) && $this->request->getHeader('X-Forwarded-Host') !== '') {
300
+            return false;
301
+        }
302
+
303
+        if (\is_array($trustedProxies) && \in_array($remoteAddress, $trustedProxies, true)) {
304
+            return $remoteAddress !== $this->request->getRemoteAddress();
305
+        }
306
+
307
+        // either not enabled or working correctly
308
+        return true;
309
+    }
310
+
311
+    /**
312
+     * Checks if the correct memcache module for PHP is installed. Only
313
+     * fails if memcached is configured and the working module is not installed.
314
+     *
315
+     * @return bool
316
+     */
317
+    private function isCorrectMemcachedPHPModuleInstalled() {
318
+        if ($this->config->getSystemValue('memcache.distributed', null) !== '\OC\Memcache\Memcached') {
319
+            return true;
320
+        }
321
+
322
+        // there are two different memcached modules for PHP
323
+        // we only support memcached and not memcache
324
+        // https://code.google.com/p/memcached/wiki/PHPClientComparison
325
+        return !(!extension_loaded('memcached') && extension_loaded('memcache'));
326
+    }
327
+
328
+    /**
329
+     * Checks if set_time_limit is not disabled.
330
+     *
331
+     * @return bool
332
+     */
333
+    private function isSettimelimitAvailable() {
334
+        if (function_exists('set_time_limit')
335
+            && strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
336
+            return true;
337
+        }
338
+
339
+        return false;
340
+    }
341
+
342
+    /**
343
+     * @return RedirectResponse
344
+     */
345
+    public function rescanFailedIntegrityCheck() {
346
+        $this->checker->runInstanceVerification();
347
+        return new RedirectResponse(
348
+            $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'overview'])
349
+        );
350
+    }
351
+
352
+    /**
353
+     * @NoCSRFRequired
354
+     * @return DataResponse
355
+     */
356
+    public function getFailedIntegrityCheckFiles() {
357
+        if (!$this->checker->isCodeCheckEnforced()) {
358
+            return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.');
359
+        }
360
+
361
+        $completeResults = $this->checker->getResults();
362
+
363
+        if (!empty($completeResults)) {
364
+            $formattedTextResponse = 'Technical information
365 365
 =====================
366 366
 The following list covers which files have failed the integrity check. Please read
367 367
 the previous linked documentation to learn more about the errors and how to fix
@@ -370,386 +370,386 @@  discard block
 block discarded – undo
370 370
 Results
371 371
 =======
372 372
 ';
373
-			foreach ($completeResults as $context => $contextResult) {
374
-				$formattedTextResponse .= "- $context\n";
375
-
376
-				foreach ($contextResult as $category => $result) {
377
-					$formattedTextResponse .= "\t- $category\n";
378
-					if ($category !== 'EXCEPTION') {
379
-						foreach ($result as $key => $results) {
380
-							$formattedTextResponse .= "\t\t- $key\n";
381
-						}
382
-					} else {
383
-						foreach ($result as $key => $results) {
384
-							$formattedTextResponse .= "\t\t- $results\n";
385
-						}
386
-					}
387
-				}
388
-			}
389
-
390
-			$formattedTextResponse .= '
373
+            foreach ($completeResults as $context => $contextResult) {
374
+                $formattedTextResponse .= "- $context\n";
375
+
376
+                foreach ($contextResult as $category => $result) {
377
+                    $formattedTextResponse .= "\t- $category\n";
378
+                    if ($category !== 'EXCEPTION') {
379
+                        foreach ($result as $key => $results) {
380
+                            $formattedTextResponse .= "\t\t- $key\n";
381
+                        }
382
+                    } else {
383
+                        foreach ($result as $key => $results) {
384
+                            $formattedTextResponse .= "\t\t- $results\n";
385
+                        }
386
+                    }
387
+                }
388
+            }
389
+
390
+            $formattedTextResponse .= '
391 391
 Raw output
392 392
 ==========
393 393
 ';
394
-			$formattedTextResponse .= print_r($completeResults, true);
395
-		} else {
396
-			$formattedTextResponse = 'No errors have been found.';
397
-		}
398
-
399
-
400
-		$response = new DataDisplayResponse(
401
-			$formattedTextResponse,
402
-			Http::STATUS_OK,
403
-			[
404
-				'Content-Type' => 'text/plain',
405
-			]
406
-		);
407
-
408
-		return $response;
409
-	}
410
-
411
-	/**
412
-	 * Checks whether a PHP opcache is properly set up
413
-	 * @return bool
414
-	 */
415
-	protected function isOpcacheProperlySetup() {
416
-		if (!$this->iniGetWrapper->getBool('opcache.enable')) {
417
-			return false;
418
-		}
419
-
420
-		if (!$this->iniGetWrapper->getBool('opcache.save_comments')) {
421
-			return false;
422
-		}
423
-
424
-		if ($this->iniGetWrapper->getNumeric('opcache.max_accelerated_files') < 10000) {
425
-			return false;
426
-		}
427
-
428
-		if ($this->iniGetWrapper->getNumeric('opcache.memory_consumption') < 128) {
429
-			return false;
430
-		}
431
-
432
-		if ($this->iniGetWrapper->getNumeric('opcache.interned_strings_buffer') < 8) {
433
-			return false;
434
-		}
435
-
436
-		return true;
437
-	}
438
-
439
-	/**
440
-	 * Check if the required FreeType functions are present
441
-	 * @return bool
442
-	 */
443
-	protected function hasFreeTypeSupport() {
444
-		return function_exists('imagettfbbox') && function_exists('imagettftext');
445
-	}
446
-
447
-	protected function hasMissingIndexes(): array {
448
-		$indexInfo = new MissingIndexInformation();
449
-		// Dispatch event so apps can also hint for pending index updates if needed
450
-		$event = new GenericEvent($indexInfo);
451
-		$this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_INDEXES_EVENT, $event);
452
-
453
-		return $indexInfo->getListOfMissingIndexes();
454
-	}
455
-
456
-	protected function hasMissingPrimaryKeys(): array {
457
-		$info = new MissingPrimaryKeyInformation();
458
-		// Dispatch event so apps can also hint for pending index updates if needed
459
-		$event = new GenericEvent($info);
460
-		$this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_PRIMARY_KEYS_EVENT, $event);
461
-
462
-		return $info->getListOfMissingPrimaryKeys();
463
-	}
464
-
465
-	protected function hasMissingColumns(): array {
466
-		$indexInfo = new MissingColumnInformation();
467
-		// Dispatch event so apps can also hint for pending index updates if needed
468
-		$event = new GenericEvent($indexInfo);
469
-		$this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_COLUMNS_EVENT, $event);
470
-
471
-		return $indexInfo->getListOfMissingColumns();
472
-	}
473
-
474
-	protected function isSqliteUsed() {
475
-		return strpos($this->config->getSystemValue('dbtype'), 'sqlite') !== false;
476
-	}
477
-
478
-	protected function isReadOnlyConfig(): bool {
479
-		return \OC_Helper::isReadOnlyConfigEnabled();
480
-	}
481
-
482
-	protected function hasValidTransactionIsolationLevel(): bool {
483
-		try {
484
-			if ($this->db->getDatabasePlatform() instanceof SqlitePlatform) {
485
-				return true;
486
-			}
487
-
488
-			return $this->db->getTransactionIsolation() === Connection::TRANSACTION_READ_COMMITTED;
489
-		} catch (DBALException $e) {
490
-			// ignore
491
-		}
492
-
493
-		return true;
494
-	}
495
-
496
-	protected function hasFileinfoInstalled(): bool {
497
-		return \OC_Util::fileInfoLoaded();
498
-	}
499
-
500
-	protected function hasWorkingFileLocking(): bool {
501
-		return !($this->lockingProvider instanceof NoopLockingProvider);
502
-	}
503
-
504
-	protected function getSuggestedOverwriteCliURL(): string {
505
-		$suggestedOverwriteCliUrl = '';
506
-		if ($this->config->getSystemValue('overwrite.cli.url', '') === '') {
507
-			$suggestedOverwriteCliUrl = $this->request->getServerProtocol() . '://' . $this->request->getInsecureServerHost() . \OC::$WEBROOT;
508
-			if (!$this->config->getSystemValue('config_is_read_only', false)) {
509
-				// Set the overwrite URL when it was not set yet.
510
-				$this->config->setSystemValue('overwrite.cli.url', $suggestedOverwriteCliUrl);
511
-				$suggestedOverwriteCliUrl = '';
512
-			}
513
-		}
514
-		return $suggestedOverwriteCliUrl;
515
-	}
516
-
517
-	protected function getLastCronInfo(): array {
518
-		$lastCronRun = $this->config->getAppValue('core', 'lastcron', 0);
519
-		return [
520
-			'diffInSeconds' => time() - $lastCronRun,
521
-			'relativeTime' => $this->dateTimeFormatter->formatTimeSpan($lastCronRun),
522
-			'backgroundJobsUrl' => $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'server']) . '#backgroundjobs',
523
-		];
524
-	}
525
-
526
-	protected function getCronErrors() {
527
-		$errors = json_decode($this->config->getAppValue('core', 'cronErrors', ''), true);
528
-
529
-		if (is_array($errors)) {
530
-			return $errors;
531
-		}
532
-
533
-		return [];
534
-	}
535
-
536
-	protected function hasOpcacheLoaded(): bool {
537
-		return extension_loaded('Zend OPcache');
538
-	}
539
-
540
-	/**
541
-	 * Iterates through the configured app roots and
542
-	 * tests if the subdirectories are owned by the same user than the current user.
543
-	 *
544
-	 * @return array
545
-	 */
546
-	protected function getAppDirsWithDifferentOwner(): array {
547
-		$currentUser = posix_getuid();
548
-		$appDirsWithDifferentOwner = [[]];
549
-
550
-		foreach (OC::$APPSROOTS as $appRoot) {
551
-			if ($appRoot['writable'] === true) {
552
-				$appDirsWithDifferentOwner[] = $this->getAppDirsWithDifferentOwnerForAppRoot($currentUser, $appRoot);
553
-			}
554
-		}
555
-
556
-		$appDirsWithDifferentOwner = array_merge(...$appDirsWithDifferentOwner);
557
-		sort($appDirsWithDifferentOwner);
558
-
559
-		return $appDirsWithDifferentOwner;
560
-	}
561
-
562
-	/**
563
-	 * Tests if the directories for one apps directory are writable by the current user.
564
-	 *
565
-	 * @param int $currentUser The current user
566
-	 * @param array $appRoot The app root config
567
-	 * @return string[] The none writable directory paths inside the app root
568
-	 */
569
-	private function getAppDirsWithDifferentOwnerForAppRoot(int $currentUser, array $appRoot): array {
570
-		$appDirsWithDifferentOwner = [];
571
-		$appsPath = $appRoot['path'];
572
-		$appsDir = new DirectoryIterator($appRoot['path']);
573
-
574
-		foreach ($appsDir as $fileInfo) {
575
-			if ($fileInfo->isDir() && !$fileInfo->isDot()) {
576
-				$absAppPath = $appsPath . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
577
-				$appDirUser = fileowner($absAppPath);
578
-				if ($appDirUser !== $currentUser) {
579
-					$appDirsWithDifferentOwner[] = $absAppPath;
580
-				}
581
-			}
582
-		}
583
-
584
-		return $appDirsWithDifferentOwner;
585
-	}
586
-
587
-	/**
588
-	 * Checks for potential PHP modules that would improve the instance
589
-	 *
590
-	 * @return string[] A list of PHP modules that is recommended
591
-	 */
592
-	protected function hasRecommendedPHPModules(): array {
593
-		$recommendedPHPModules = [];
594
-
595
-		if (!extension_loaded('intl')) {
596
-			$recommendedPHPModules[] = 'intl';
597
-		}
598
-
599
-		if (!extension_loaded('bcmath')) {
600
-			$recommendedPHPModules[] = 'bcmath';
601
-		}
602
-
603
-		if (!extension_loaded('gmp')) {
604
-			$recommendedPHPModules[] = 'gmp';
605
-		}
606
-
607
-		if ($this->config->getAppValue('theming', 'enabled', 'no') === 'yes') {
608
-			if (!extension_loaded('imagick')) {
609
-				$recommendedPHPModules[] = 'imagick';
610
-			}
611
-		}
612
-
613
-		return $recommendedPHPModules;
614
-	}
615
-
616
-	protected function isMysqlUsedWithoutUTF8MB4(): bool {
617
-		return ($this->config->getSystemValue('dbtype', 'sqlite') === 'mysql') && ($this->config->getSystemValue('mysql.utf8mb4', false) === false);
618
-	}
619
-
620
-	protected function hasBigIntConversionPendingColumns(): array {
621
-		// copy of ConvertFilecacheBigInt::getColumnsByTable()
622
-		$tables = [
623
-			'activity' => ['activity_id', 'object_id'],
624
-			'activity_mq' => ['mail_id'],
625
-			'authtoken' => ['id'],
626
-			'bruteforce_attempts' => ['id'],
627
-			'filecache' => ['fileid', 'storage', 'parent', 'mimetype', 'mimepart', 'mtime', 'storage_mtime'],
628
-			'filecache_extended' => ['fileid'],
629
-			'file_locks' => ['id'],
630
-			'jobs' => ['id'],
631
-			'mimetypes' => ['id'],
632
-			'mounts' => ['id', 'storage_id', 'root_id', 'mount_id'],
633
-			'storages' => ['numeric_id'],
634
-		];
635
-
636
-		$schema = new SchemaWrapper($this->db);
637
-		$isSqlite = $this->db->getDatabasePlatform() instanceof SqlitePlatform;
638
-		$pendingColumns = [];
639
-
640
-		foreach ($tables as $tableName => $columns) {
641
-			if (!$schema->hasTable($tableName)) {
642
-				continue;
643
-			}
644
-
645
-			$table = $schema->getTable($tableName);
646
-			foreach ($columns as $columnName) {
647
-				$column = $table->getColumn($columnName);
648
-				$isAutoIncrement = $column->getAutoincrement();
649
-				$isAutoIncrementOnSqlite = $isSqlite && $isAutoIncrement;
650
-				if ($column->getType()->getName() !== Types::BIGINT && !$isAutoIncrementOnSqlite) {
651
-					$pendingColumns[] = $tableName . '.' . $columnName;
652
-				}
653
-			}
654
-		}
655
-
656
-		return $pendingColumns;
657
-	}
658
-
659
-	protected function isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(): bool {
660
-		$objectStore = $this->config->getSystemValue('objectstore', null);
661
-		$objectStoreMultibucket = $this->config->getSystemValue('objectstore_multibucket', null);
662
-
663
-		if (!isset($objectStoreMultibucket) && !isset($objectStore)) {
664
-			return true;
665
-		}
666
-
667
-		if (isset($objectStoreMultibucket['class']) && $objectStoreMultibucket['class'] !== 'OC\\Files\\ObjectStore\\S3') {
668
-			return true;
669
-		}
670
-
671
-		if (isset($objectStore['class']) && $objectStore['class'] !== 'OC\\Files\\ObjectStore\\S3') {
672
-			return true;
673
-		}
674
-
675
-		$tempPath = sys_get_temp_dir();
676
-		if (!is_dir($tempPath)) {
677
-			$this->logger->error('Error while checking the temporary PHP path - it was not properly set to a directory. value: ' . $tempPath);
678
-			return false;
679
-		}
680
-		$freeSpaceInTemp = disk_free_space($tempPath);
681
-		if ($freeSpaceInTemp === false) {
682
-			$this->logger->error('Error while checking the available disk space of temporary PHP path - no free disk space returned. temporary path: ' . $tempPath);
683
-			return false;
684
-		}
685
-
686
-		$freeSpaceInTempInGB = $freeSpaceInTemp / 1024 / 1024 / 1024;
687
-		if ($freeSpaceInTempInGB > 50) {
688
-			return true;
689
-		}
690
-
691
-		$this->logger->warning('Checking the available space in the temporary path resulted in ' . round($freeSpaceInTempInGB, 1) . ' GB instead of the recommended 50GB. Path: ' . $tempPath);
692
-		return false;
693
-	}
694
-
695
-	protected function imageMagickLacksSVGSupport(): bool {
696
-		return extension_loaded('imagick') && count(\Imagick::queryFormats('SVG')) === 0;
697
-	}
698
-
699
-	/**
700
-	 * @return DataResponse
701
-	 */
702
-	public function check() {
703
-		$phpDefaultCharset = new PhpDefaultCharset();
704
-		$phpOutputBuffering = new PhpOutputBuffering();
705
-		$legacySSEKeyFormat = new LegacySSEKeyFormat($this->l10n, $this->config, $this->urlGenerator);
706
-		$checkUserCertificates = new CheckUserCertificates($this->l10n, $this->config, $this->urlGenerator);
707
-
708
-		return new DataResponse(
709
-			[
710
-				'isGetenvServerWorking' => !empty(getenv('PATH')),
711
-				'isReadOnlyConfig' => $this->isReadOnlyConfig(),
712
-				'hasValidTransactionIsolationLevel' => $this->hasValidTransactionIsolationLevel(),
713
-				'hasFileinfoInstalled' => $this->hasFileinfoInstalled(),
714
-				'hasWorkingFileLocking' => $this->hasWorkingFileLocking(),
715
-				'suggestedOverwriteCliURL' => $this->getSuggestedOverwriteCliURL(),
716
-				'cronInfo' => $this->getLastCronInfo(),
717
-				'cronErrors' => $this->getCronErrors(),
718
-				'serverHasInternetConnectionProblems' => $this->hasInternetConnectivityProblems(),
719
-				'isMemcacheConfigured' => $this->isMemcacheConfigured(),
720
-				'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
721
-				'isRandomnessSecure' => $this->isRandomnessSecure(),
722
-				'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
723
-				'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
724
-				'phpSupported' => $this->isPhpSupported(),
725
-				'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(),
726
-				'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
727
-				'isCorrectMemcachedPHPModuleInstalled' => $this->isCorrectMemcachedPHPModuleInstalled(),
728
-				'hasPassedCodeIntegrityCheck' => $this->checker->hasPassedCheck(),
729
-				'codeIntegrityCheckerDocumentation' => $this->urlGenerator->linkToDocs('admin-code-integrity'),
730
-				'isOpcacheProperlySetup' => $this->isOpcacheProperlySetup(),
731
-				'hasOpcacheLoaded' => $this->hasOpcacheLoaded(),
732
-				'phpOpcacheDocumentation' => $this->urlGenerator->linkToDocs('admin-php-opcache'),
733
-				'isSettimelimitAvailable' => $this->isSettimelimitAvailable(),
734
-				'hasFreeTypeSupport' => $this->hasFreeTypeSupport(),
735
-				'missingPrimaryKeys' => $this->hasMissingPrimaryKeys(),
736
-				'missingIndexes' => $this->hasMissingIndexes(),
737
-				'missingColumns' => $this->hasMissingColumns(),
738
-				'isSqliteUsed' => $this->isSqliteUsed(),
739
-				'databaseConversionDocumentation' => $this->urlGenerator->linkToDocs('admin-db-conversion'),
740
-				'isMemoryLimitSufficient' => $this->memoryInfo->isMemoryLimitSufficient(),
741
-				'appDirsWithDifferentOwner' => $this->getAppDirsWithDifferentOwner(),
742
-				'recommendedPHPModules' => $this->hasRecommendedPHPModules(),
743
-				'pendingBigIntConversionColumns' => $this->hasBigIntConversionPendingColumns(),
744
-				'isMysqlUsedWithoutUTF8MB4' => $this->isMysqlUsedWithoutUTF8MB4(),
745
-				'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed' => $this->isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(),
746
-				'reverseProxyGeneratedURL' => $this->urlGenerator->getAbsoluteURL('index.php'),
747
-				'imageMagickLacksSVGSupport' => $this->imageMagickLacksSVGSupport(),
748
-				PhpDefaultCharset::class => ['pass' => $phpDefaultCharset->run(), 'description' => $phpDefaultCharset->description(), 'severity' => $phpDefaultCharset->severity()],
749
-				PhpOutputBuffering::class => ['pass' => $phpOutputBuffering->run(), 'description' => $phpOutputBuffering->description(), 'severity' => $phpOutputBuffering->severity()],
750
-				LegacySSEKeyFormat::class => ['pass' => $legacySSEKeyFormat->run(), 'description' => $legacySSEKeyFormat->description(), 'severity' => $legacySSEKeyFormat->severity(), 'linkToDocumentation' => $legacySSEKeyFormat->linkToDocumentation()],
751
-				CheckUserCertificates::class => ['pass' => $checkUserCertificates->run(), 'description' => $checkUserCertificates->description(), 'severity' => $checkUserCertificates->severity(), 'elements' => $checkUserCertificates->elements()],
752
-			]
753
-		);
754
-	}
394
+            $formattedTextResponse .= print_r($completeResults, true);
395
+        } else {
396
+            $formattedTextResponse = 'No errors have been found.';
397
+        }
398
+
399
+
400
+        $response = new DataDisplayResponse(
401
+            $formattedTextResponse,
402
+            Http::STATUS_OK,
403
+            [
404
+                'Content-Type' => 'text/plain',
405
+            ]
406
+        );
407
+
408
+        return $response;
409
+    }
410
+
411
+    /**
412
+     * Checks whether a PHP opcache is properly set up
413
+     * @return bool
414
+     */
415
+    protected function isOpcacheProperlySetup() {
416
+        if (!$this->iniGetWrapper->getBool('opcache.enable')) {
417
+            return false;
418
+        }
419
+
420
+        if (!$this->iniGetWrapper->getBool('opcache.save_comments')) {
421
+            return false;
422
+        }
423
+
424
+        if ($this->iniGetWrapper->getNumeric('opcache.max_accelerated_files') < 10000) {
425
+            return false;
426
+        }
427
+
428
+        if ($this->iniGetWrapper->getNumeric('opcache.memory_consumption') < 128) {
429
+            return false;
430
+        }
431
+
432
+        if ($this->iniGetWrapper->getNumeric('opcache.interned_strings_buffer') < 8) {
433
+            return false;
434
+        }
435
+
436
+        return true;
437
+    }
438
+
439
+    /**
440
+     * Check if the required FreeType functions are present
441
+     * @return bool
442
+     */
443
+    protected function hasFreeTypeSupport() {
444
+        return function_exists('imagettfbbox') && function_exists('imagettftext');
445
+    }
446
+
447
+    protected function hasMissingIndexes(): array {
448
+        $indexInfo = new MissingIndexInformation();
449
+        // Dispatch event so apps can also hint for pending index updates if needed
450
+        $event = new GenericEvent($indexInfo);
451
+        $this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_INDEXES_EVENT, $event);
452
+
453
+        return $indexInfo->getListOfMissingIndexes();
454
+    }
455
+
456
+    protected function hasMissingPrimaryKeys(): array {
457
+        $info = new MissingPrimaryKeyInformation();
458
+        // Dispatch event so apps can also hint for pending index updates if needed
459
+        $event = new GenericEvent($info);
460
+        $this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_PRIMARY_KEYS_EVENT, $event);
461
+
462
+        return $info->getListOfMissingPrimaryKeys();
463
+    }
464
+
465
+    protected function hasMissingColumns(): array {
466
+        $indexInfo = new MissingColumnInformation();
467
+        // Dispatch event so apps can also hint for pending index updates if needed
468
+        $event = new GenericEvent($indexInfo);
469
+        $this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_COLUMNS_EVENT, $event);
470
+
471
+        return $indexInfo->getListOfMissingColumns();
472
+    }
473
+
474
+    protected function isSqliteUsed() {
475
+        return strpos($this->config->getSystemValue('dbtype'), 'sqlite') !== false;
476
+    }
477
+
478
+    protected function isReadOnlyConfig(): bool {
479
+        return \OC_Helper::isReadOnlyConfigEnabled();
480
+    }
481
+
482
+    protected function hasValidTransactionIsolationLevel(): bool {
483
+        try {
484
+            if ($this->db->getDatabasePlatform() instanceof SqlitePlatform) {
485
+                return true;
486
+            }
487
+
488
+            return $this->db->getTransactionIsolation() === Connection::TRANSACTION_READ_COMMITTED;
489
+        } catch (DBALException $e) {
490
+            // ignore
491
+        }
492
+
493
+        return true;
494
+    }
495
+
496
+    protected function hasFileinfoInstalled(): bool {
497
+        return \OC_Util::fileInfoLoaded();
498
+    }
499
+
500
+    protected function hasWorkingFileLocking(): bool {
501
+        return !($this->lockingProvider instanceof NoopLockingProvider);
502
+    }
503
+
504
+    protected function getSuggestedOverwriteCliURL(): string {
505
+        $suggestedOverwriteCliUrl = '';
506
+        if ($this->config->getSystemValue('overwrite.cli.url', '') === '') {
507
+            $suggestedOverwriteCliUrl = $this->request->getServerProtocol() . '://' . $this->request->getInsecureServerHost() . \OC::$WEBROOT;
508
+            if (!$this->config->getSystemValue('config_is_read_only', false)) {
509
+                // Set the overwrite URL when it was not set yet.
510
+                $this->config->setSystemValue('overwrite.cli.url', $suggestedOverwriteCliUrl);
511
+                $suggestedOverwriteCliUrl = '';
512
+            }
513
+        }
514
+        return $suggestedOverwriteCliUrl;
515
+    }
516
+
517
+    protected function getLastCronInfo(): array {
518
+        $lastCronRun = $this->config->getAppValue('core', 'lastcron', 0);
519
+        return [
520
+            'diffInSeconds' => time() - $lastCronRun,
521
+            'relativeTime' => $this->dateTimeFormatter->formatTimeSpan($lastCronRun),
522
+            'backgroundJobsUrl' => $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'server']) . '#backgroundjobs',
523
+        ];
524
+    }
525
+
526
+    protected function getCronErrors() {
527
+        $errors = json_decode($this->config->getAppValue('core', 'cronErrors', ''), true);
528
+
529
+        if (is_array($errors)) {
530
+            return $errors;
531
+        }
532
+
533
+        return [];
534
+    }
535
+
536
+    protected function hasOpcacheLoaded(): bool {
537
+        return extension_loaded('Zend OPcache');
538
+    }
539
+
540
+    /**
541
+     * Iterates through the configured app roots and
542
+     * tests if the subdirectories are owned by the same user than the current user.
543
+     *
544
+     * @return array
545
+     */
546
+    protected function getAppDirsWithDifferentOwner(): array {
547
+        $currentUser = posix_getuid();
548
+        $appDirsWithDifferentOwner = [[]];
549
+
550
+        foreach (OC::$APPSROOTS as $appRoot) {
551
+            if ($appRoot['writable'] === true) {
552
+                $appDirsWithDifferentOwner[] = $this->getAppDirsWithDifferentOwnerForAppRoot($currentUser, $appRoot);
553
+            }
554
+        }
555
+
556
+        $appDirsWithDifferentOwner = array_merge(...$appDirsWithDifferentOwner);
557
+        sort($appDirsWithDifferentOwner);
558
+
559
+        return $appDirsWithDifferentOwner;
560
+    }
561
+
562
+    /**
563
+     * Tests if the directories for one apps directory are writable by the current user.
564
+     *
565
+     * @param int $currentUser The current user
566
+     * @param array $appRoot The app root config
567
+     * @return string[] The none writable directory paths inside the app root
568
+     */
569
+    private function getAppDirsWithDifferentOwnerForAppRoot(int $currentUser, array $appRoot): array {
570
+        $appDirsWithDifferentOwner = [];
571
+        $appsPath = $appRoot['path'];
572
+        $appsDir = new DirectoryIterator($appRoot['path']);
573
+
574
+        foreach ($appsDir as $fileInfo) {
575
+            if ($fileInfo->isDir() && !$fileInfo->isDot()) {
576
+                $absAppPath = $appsPath . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
577
+                $appDirUser = fileowner($absAppPath);
578
+                if ($appDirUser !== $currentUser) {
579
+                    $appDirsWithDifferentOwner[] = $absAppPath;
580
+                }
581
+            }
582
+        }
583
+
584
+        return $appDirsWithDifferentOwner;
585
+    }
586
+
587
+    /**
588
+     * Checks for potential PHP modules that would improve the instance
589
+     *
590
+     * @return string[] A list of PHP modules that is recommended
591
+     */
592
+    protected function hasRecommendedPHPModules(): array {
593
+        $recommendedPHPModules = [];
594
+
595
+        if (!extension_loaded('intl')) {
596
+            $recommendedPHPModules[] = 'intl';
597
+        }
598
+
599
+        if (!extension_loaded('bcmath')) {
600
+            $recommendedPHPModules[] = 'bcmath';
601
+        }
602
+
603
+        if (!extension_loaded('gmp')) {
604
+            $recommendedPHPModules[] = 'gmp';
605
+        }
606
+
607
+        if ($this->config->getAppValue('theming', 'enabled', 'no') === 'yes') {
608
+            if (!extension_loaded('imagick')) {
609
+                $recommendedPHPModules[] = 'imagick';
610
+            }
611
+        }
612
+
613
+        return $recommendedPHPModules;
614
+    }
615
+
616
+    protected function isMysqlUsedWithoutUTF8MB4(): bool {
617
+        return ($this->config->getSystemValue('dbtype', 'sqlite') === 'mysql') && ($this->config->getSystemValue('mysql.utf8mb4', false) === false);
618
+    }
619
+
620
+    protected function hasBigIntConversionPendingColumns(): array {
621
+        // copy of ConvertFilecacheBigInt::getColumnsByTable()
622
+        $tables = [
623
+            'activity' => ['activity_id', 'object_id'],
624
+            'activity_mq' => ['mail_id'],
625
+            'authtoken' => ['id'],
626
+            'bruteforce_attempts' => ['id'],
627
+            'filecache' => ['fileid', 'storage', 'parent', 'mimetype', 'mimepart', 'mtime', 'storage_mtime'],
628
+            'filecache_extended' => ['fileid'],
629
+            'file_locks' => ['id'],
630
+            'jobs' => ['id'],
631
+            'mimetypes' => ['id'],
632
+            'mounts' => ['id', 'storage_id', 'root_id', 'mount_id'],
633
+            'storages' => ['numeric_id'],
634
+        ];
635
+
636
+        $schema = new SchemaWrapper($this->db);
637
+        $isSqlite = $this->db->getDatabasePlatform() instanceof SqlitePlatform;
638
+        $pendingColumns = [];
639
+
640
+        foreach ($tables as $tableName => $columns) {
641
+            if (!$schema->hasTable($tableName)) {
642
+                continue;
643
+            }
644
+
645
+            $table = $schema->getTable($tableName);
646
+            foreach ($columns as $columnName) {
647
+                $column = $table->getColumn($columnName);
648
+                $isAutoIncrement = $column->getAutoincrement();
649
+                $isAutoIncrementOnSqlite = $isSqlite && $isAutoIncrement;
650
+                if ($column->getType()->getName() !== Types::BIGINT && !$isAutoIncrementOnSqlite) {
651
+                    $pendingColumns[] = $tableName . '.' . $columnName;
652
+                }
653
+            }
654
+        }
655
+
656
+        return $pendingColumns;
657
+    }
658
+
659
+    protected function isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(): bool {
660
+        $objectStore = $this->config->getSystemValue('objectstore', null);
661
+        $objectStoreMultibucket = $this->config->getSystemValue('objectstore_multibucket', null);
662
+
663
+        if (!isset($objectStoreMultibucket) && !isset($objectStore)) {
664
+            return true;
665
+        }
666
+
667
+        if (isset($objectStoreMultibucket['class']) && $objectStoreMultibucket['class'] !== 'OC\\Files\\ObjectStore\\S3') {
668
+            return true;
669
+        }
670
+
671
+        if (isset($objectStore['class']) && $objectStore['class'] !== 'OC\\Files\\ObjectStore\\S3') {
672
+            return true;
673
+        }
674
+
675
+        $tempPath = sys_get_temp_dir();
676
+        if (!is_dir($tempPath)) {
677
+            $this->logger->error('Error while checking the temporary PHP path - it was not properly set to a directory. value: ' . $tempPath);
678
+            return false;
679
+        }
680
+        $freeSpaceInTemp = disk_free_space($tempPath);
681
+        if ($freeSpaceInTemp === false) {
682
+            $this->logger->error('Error while checking the available disk space of temporary PHP path - no free disk space returned. temporary path: ' . $tempPath);
683
+            return false;
684
+        }
685
+
686
+        $freeSpaceInTempInGB = $freeSpaceInTemp / 1024 / 1024 / 1024;
687
+        if ($freeSpaceInTempInGB > 50) {
688
+            return true;
689
+        }
690
+
691
+        $this->logger->warning('Checking the available space in the temporary path resulted in ' . round($freeSpaceInTempInGB, 1) . ' GB instead of the recommended 50GB. Path: ' . $tempPath);
692
+        return false;
693
+    }
694
+
695
+    protected function imageMagickLacksSVGSupport(): bool {
696
+        return extension_loaded('imagick') && count(\Imagick::queryFormats('SVG')) === 0;
697
+    }
698
+
699
+    /**
700
+     * @return DataResponse
701
+     */
702
+    public function check() {
703
+        $phpDefaultCharset = new PhpDefaultCharset();
704
+        $phpOutputBuffering = new PhpOutputBuffering();
705
+        $legacySSEKeyFormat = new LegacySSEKeyFormat($this->l10n, $this->config, $this->urlGenerator);
706
+        $checkUserCertificates = new CheckUserCertificates($this->l10n, $this->config, $this->urlGenerator);
707
+
708
+        return new DataResponse(
709
+            [
710
+                'isGetenvServerWorking' => !empty(getenv('PATH')),
711
+                'isReadOnlyConfig' => $this->isReadOnlyConfig(),
712
+                'hasValidTransactionIsolationLevel' => $this->hasValidTransactionIsolationLevel(),
713
+                'hasFileinfoInstalled' => $this->hasFileinfoInstalled(),
714
+                'hasWorkingFileLocking' => $this->hasWorkingFileLocking(),
715
+                'suggestedOverwriteCliURL' => $this->getSuggestedOverwriteCliURL(),
716
+                'cronInfo' => $this->getLastCronInfo(),
717
+                'cronErrors' => $this->getCronErrors(),
718
+                'serverHasInternetConnectionProblems' => $this->hasInternetConnectivityProblems(),
719
+                'isMemcacheConfigured' => $this->isMemcacheConfigured(),
720
+                'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
721
+                'isRandomnessSecure' => $this->isRandomnessSecure(),
722
+                'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
723
+                'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
724
+                'phpSupported' => $this->isPhpSupported(),
725
+                'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(),
726
+                'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
727
+                'isCorrectMemcachedPHPModuleInstalled' => $this->isCorrectMemcachedPHPModuleInstalled(),
728
+                'hasPassedCodeIntegrityCheck' => $this->checker->hasPassedCheck(),
729
+                'codeIntegrityCheckerDocumentation' => $this->urlGenerator->linkToDocs('admin-code-integrity'),
730
+                'isOpcacheProperlySetup' => $this->isOpcacheProperlySetup(),
731
+                'hasOpcacheLoaded' => $this->hasOpcacheLoaded(),
732
+                'phpOpcacheDocumentation' => $this->urlGenerator->linkToDocs('admin-php-opcache'),
733
+                'isSettimelimitAvailable' => $this->isSettimelimitAvailable(),
734
+                'hasFreeTypeSupport' => $this->hasFreeTypeSupport(),
735
+                'missingPrimaryKeys' => $this->hasMissingPrimaryKeys(),
736
+                'missingIndexes' => $this->hasMissingIndexes(),
737
+                'missingColumns' => $this->hasMissingColumns(),
738
+                'isSqliteUsed' => $this->isSqliteUsed(),
739
+                'databaseConversionDocumentation' => $this->urlGenerator->linkToDocs('admin-db-conversion'),
740
+                'isMemoryLimitSufficient' => $this->memoryInfo->isMemoryLimitSufficient(),
741
+                'appDirsWithDifferentOwner' => $this->getAppDirsWithDifferentOwner(),
742
+                'recommendedPHPModules' => $this->hasRecommendedPHPModules(),
743
+                'pendingBigIntConversionColumns' => $this->hasBigIntConversionPendingColumns(),
744
+                'isMysqlUsedWithoutUTF8MB4' => $this->isMysqlUsedWithoutUTF8MB4(),
745
+                'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed' => $this->isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(),
746
+                'reverseProxyGeneratedURL' => $this->urlGenerator->getAbsoluteURL('index.php'),
747
+                'imageMagickLacksSVGSupport' => $this->imageMagickLacksSVGSupport(),
748
+                PhpDefaultCharset::class => ['pass' => $phpDefaultCharset->run(), 'description' => $phpDefaultCharset->description(), 'severity' => $phpDefaultCharset->severity()],
749
+                PhpOutputBuffering::class => ['pass' => $phpOutputBuffering->run(), 'description' => $phpOutputBuffering->description(), 'severity' => $phpOutputBuffering->severity()],
750
+                LegacySSEKeyFormat::class => ['pass' => $legacySSEKeyFormat->run(), 'description' => $legacySSEKeyFormat->description(), 'severity' => $legacySSEKeyFormat->severity(), 'linkToDocumentation' => $legacySSEKeyFormat->linkToDocumentation()],
751
+                CheckUserCertificates::class => ['pass' => $checkUserCertificates->run(), 'description' => $checkUserCertificates->description(), 'severity' => $checkUserCertificates->severity(), 'elements' => $checkUserCertificates->elements()],
752
+            ]
753
+        );
754
+    }
755 755
 }
Please login to merge, or discard this patch.