Passed
Push — master ( ce9d3b...d52392 )
by Roeland
12:05 queued 12s
created

Application::boot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 17
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 24
rs 9.7
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright Copyright (c) 2016, ownCloud, Inc.
7
 *
8
 * @author Bjoern Schiessle <[email protected]>
9
 * @author Christoph Wurst <[email protected]>
10
 * @author Georg Ehrke <[email protected]>
11
 * @author Joas Schilling <[email protected]>
12
 * @author John Molakvoæ (skjnldsv) <[email protected]>
13
 * @author Roeland Jago Douma <[email protected]>
14
 * @author Thomas Citharel <[email protected]>
15
 * @author Thomas Müller <[email protected]>
16
 * @author Tobia De Koninck <[email protected]>
17
 *
18
 * @license AGPL-3.0
19
 *
20
 * This code is free software: you can redistribute it and/or modify
21
 * it under the terms of the GNU Affero General Public License, version 3,
22
 * as published by the Free Software Foundation.
23
 *
24
 * This program is distributed in the hope that it will be useful,
25
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
 * GNU Affero General Public License for more details.
28
 *
29
 * You should have received a copy of the GNU Affero General Public License, version 3,
30
 * along with this program. If not, see <http://www.gnu.org/licenses/>
31
 *
32
 */
33
34
namespace OCA\DAV\AppInfo;
35
36
use Exception;
37
use OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob;
38
use OCA\DAV\CalDAV\Activity\Backend;
39
use OCA\DAV\CalDAV\Activity\Provider\Event;
40
use OCA\DAV\CalDAV\BirthdayService;
41
use OCA\DAV\CalDAV\CalDavBackend;
42
use OCA\DAV\CalDAV\CalendarManager;
43
use OCA\DAV\CalDAV\Reminder\Backend as ReminderBackend;
44
use OCA\DAV\CalDAV\Reminder\NotificationProvider\AudioProvider;
45
use OCA\DAV\CalDAV\Reminder\NotificationProvider\EmailProvider;
46
use OCA\DAV\CalDAV\Reminder\NotificationProvider\PushProvider;
47
use OCA\DAV\CalDAV\Reminder\NotificationProviderManager;
48
use OCA\DAV\CalDAV\Reminder\Notifier;
49
use OCA\DAV\CalDAV\Reminder\ReminderService;
50
use OCA\DAV\CalDAV\WebcalCaching\RefreshWebcalService;
51
use OCA\DAV\Capabilities;
52
use OCA\DAV\CardDAV\CardDavBackend;
53
use OCA\DAV\CardDAV\ContactsManager;
54
use OCA\DAV\CardDAV\PhotoCache;
55
use OCA\DAV\CardDAV\SyncService;
56
use OCA\DAV\HookManager;
57
use OCP\AppFramework\App;
58
use OCP\AppFramework\Bootstrap\IBootContext;
59
use OCP\AppFramework\Bootstrap\IBootstrap;
60
use OCP\AppFramework\Bootstrap\IRegistrationContext;
61
use OCP\AppFramework\IAppContainer;
62
use OCP\Calendar\IManager as ICalendarManager;
63
use OCP\Contacts\IManager as IContactsManager;
64
use OCP\IConfig;
65
use OCP\IContainer;
66
use OCP\ILogger;
67
use OCP\IServerContainer;
68
use OCP\IUser;
69
use OCP\Notification\IManager as INotificationManager;
70
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
71
use Symfony\Component\EventDispatcher\GenericEvent;
72
use Throwable;
73
use function is_null;
74
use function strpos;
75
76
class Application extends App implements IBootstrap {
77
	public const APP_ID = 'dav';
78
79
	/**
80
	 * Application constructor.
81
	 */
82
	public function __construct() {
83
		parent::__construct(self::APP_ID);
84
	}
85
86
	public function register(IRegistrationContext $context): void {
87
		$context->registerServiceAlias('CardDAVSyncService', SyncService::class);
88
		$context->registerService(PhotoCache::class, function (IContainer $c) {
89
			/** @var IServerContainer $server */
90
			$server = $c->query(IServerContainer::class);
91
92
			return new PhotoCache(
93
				$server->getAppDataDir('dav-photocache'),
0 ignored issues
show
Bug introduced by
The method getAppDataDir() does not exist on OCP\IServerContainer. Since it exists in all sub-types, consider adding an abstract or default implementation to OCP\IServerContainer. ( Ignorable by Annotation )

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

93
				$server->/** @scrutinizer ignore-call */ 
94
             getAppDataDir('dav-photocache'),
Loading history...
94
				$server->getLogger()
95
			);
96
		});
97
98
		/*
99
		 * Register capabilities
100
		 */
101
		$context->registerCapability(Capabilities::class);
102
	}
103
104
	public function boot(IBootContext $context): void {
105
		// Load all dav apps
106
		\OC_App::loadApps(['dav']);
107
108
		$this->registerHooks(
109
			$context->getAppContainer()->query(HookManager::class),
110
			$context->getServerContainer()->getEventDispatcher(),
0 ignored issues
show
Deprecated Code introduced by
The function OCP\IServerContainer::getEventDispatcher() has been deprecated: 20.0.0 use \OCP\EventDispatcher\IEventDispatcher ( Ignorable by Annotation )

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

110
			/** @scrutinizer ignore-deprecated */ $context->getServerContainer()->getEventDispatcher(),

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
111
			$context->getAppContainer(),
112
			$context->getServerContainer()
113
		);
114
		$this->registerContactsManager(
115
			$context->getAppContainer()->query(IContactsManager::class),
116
			$context->getAppContainer()
117
		);
118
		$this->registerCalendarManager(
119
			$context->getAppContainer()->query(ICalendarManager::class),
120
			$context->getAppContainer()
121
		);
122
		$this->registerNotifier(
123
			$context->getServerContainer()->getNotificationManager()
124
		);
125
		$this->registerCalendarReminders(
126
			$context->getAppContainer()->query(NotificationProviderManager::class),
127
			$context->getAppContainer()->query(ILogger::class)
128
		);
129
	}
130
131
	private function registerHooks(HookManager $hm,
132
								   EventDispatcherInterface $dispatcher,
133
								   IAppContainer $container,
134
								   IServerContainer $serverContainer) {
135
		$hm->setup();
136
137
		// first time login event setup
138
		$dispatcher->addListener(IUser::class . '::firstLogin', function ($event) use ($hm) {
139
			if ($event instanceof GenericEvent) {
140
				$hm->firstLogin($event->getSubject());
141
			}
142
		});
143
144
		$birthdayListener = function ($event) use ($container) {
145
			if ($event instanceof GenericEvent) {
146
				/** @var BirthdayService $b */
147
				$b = $container->query(BirthdayService::class);
148
				$b->onCardChanged(
149
					(int) $event->getArgument('addressBookId'),
150
					(string) $event->getArgument('cardUri'),
151
					(string) $event->getArgument('cardData')
152
				);
153
			}
154
		};
155
156
		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', $birthdayListener);
157
		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $birthdayListener);
158
		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', function ($event) use ($container) {
159
			if ($event instanceof GenericEvent) {
160
				/** @var BirthdayService $b */
161
				$b = $container->query(BirthdayService::class);
162
				$b->onCardDeleted(
163
					(int) $event->getArgument('addressBookId'),
164
					(string) $event->getArgument('cardUri')
165
				);
166
			}
167
		});
168
169
		$clearPhotoCache = function ($event) use ($container) {
170
			if ($event instanceof GenericEvent) {
171
				/** @var PhotoCache $p */
172
				$p = $container->query(PhotoCache::class);
173
				$p->delete(
174
					$event->getArgument('addressBookId'),
175
					$event->getArgument('cardUri')
176
				);
177
			}
178
		};
179
		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $clearPhotoCache);
180
		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', $clearPhotoCache);
181
182
		$dispatcher->addListener('OC\AccountManager::userUpdated', function (GenericEvent $event) use ($container) {
183
			$user = $event->getSubject();
184
			/** @var SyncService $syncService */
185
			$syncService = $container->query(SyncService::class);
186
			$syncService->updateUser($user);
187
		});
188
189
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', function (GenericEvent $event) use ($container) {
190
			/** @var Backend $backend */
191
			$backend = $container->query(Backend::class);
192
			$backend->onCalendarAdd(
193
				$event->getArgument('calendarData')
194
			);
195
		});
196
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', function (GenericEvent $event) use ($container) {
197
			/** @var Backend $backend */
198
			$backend = $container->query(Backend::class);
199
			$backend->onCalendarUpdate(
200
				$event->getArgument('calendarData'),
201
				$event->getArgument('shares'),
202
				$event->getArgument('propertyMutations')
203
			);
204
		});
205
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', function (GenericEvent $event) use ($container) {
206
			/** @var Backend $backend */
207
			$backend = $container->query(Backend::class);
208
			$backend->onCalendarDelete(
209
				$event->getArgument('calendarData'),
210
				$event->getArgument('shares')
211
			);
212
213
			/** @var ReminderBackend $reminderBackend */
214
			$reminderBackend = $container->query(ReminderBackend::class);
215
			$reminderBackend->cleanRemindersForCalendar(
216
				(int) $event->getArgument('calendarId')
217
			);
218
		});
219
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateShares', function (GenericEvent $event) use ($container) {
220
			/** @var Backend $backend */
221
			$backend = $container->query(Backend::class);
222
			$backend->onCalendarUpdateShares(
223
				$event->getArgument('calendarData'),
224
				$event->getArgument('shares'),
225
				$event->getArgument('add'),
226
				$event->getArgument('remove')
227
			);
228
229
			// Here we should recalculate if reminders should be sent to new or old sharees
230
		});
231
232
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::publishCalendar', function (GenericEvent $event) use ($container) {
233
			/** @var Backend $backend */
234
			$backend = $container->query(Backend::class);
235
			$backend->onCalendarPublication(
236
				$event->getArgument('calendarData'),
237
				$event->getArgument('public')
238
			);
239
		});
240
241
		$listener = function (GenericEvent $event, $eventName) use ($container) {
242
			/** @var Backend $backend */
243
			$backend = $container->query(Backend::class);
244
245
			$subject = Event::SUBJECT_OBJECT_ADD;
246
			if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject') {
247
				$subject = Event::SUBJECT_OBJECT_UPDATE;
248
			} elseif ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject') {
249
				$subject = Event::SUBJECT_OBJECT_DELETE;
250
			}
251
			$backend->onTouchCalendarObject(
252
				$subject,
253
				$event->getArgument('calendarData'),
254
				$event->getArgument('shares'),
255
				$event->getArgument('objectData')
256
			);
257
258
			/** @var ReminderService $reminderBackend */
259
			$reminderService = $container->query(ReminderService::class);
260
261
			$reminderService->onTouchCalendarObject(
262
				$eventName,
263
				$event->getArgument('objectData')
264
			);
265
		};
266
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $listener);
267
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', $listener);
268
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', $listener);
269
270
		/**
271
		 * In case the user has set their default calendar to this one
272
		 */
273
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', function (GenericEvent $event) use ($serverContainer) {
274
			/** @var IConfig $config */
275
			$config = $serverContainer->getConfig();
276
			$principalUri = $event->getArgument('calendarData')['principaluri'];
277
			if (strpos($principalUri, 'principals/users') === 0) {
278
				list(, $UID) = \Sabre\Uri\split($principalUri);
279
				$uri = $event->getArgument('calendarData')['uri'];
280
				if ($config->getUserValue($UID, 'dav', 'defaultCalendar') === $uri) {
281
					$config->deleteUserValue($UID, 'dav', 'defaultCalendar');
282
				}
283
			}
284
		});
285
286
		$dispatcher->addListener('OCP\Federation\TrustedServerEvent::remove',
287
			function (GenericEvent $event) {
288
				/** @var CardDavBackend $cardDavBackend */
289
				$cardDavBackend = \OC::$server->query(CardDavBackend::class);
290
				$addressBookUri = $event->getSubject();
291
				$addressBook = $cardDavBackend->getAddressBooksByUri('principals/system/system', $addressBookUri);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $addressBook is correct as $cardDavBackend->getAddr...stem', $addressBookUri) targeting OCA\DAV\CardDAV\CardDavB...:getAddressBooksByUri() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
292
				if (!is_null($addressBook)) {
0 ignored issues
show
introduced by
The condition is_null($addressBook) is always true.
Loading history...
293
					$cardDavBackend->deleteAddressBook($addressBook['id']);
294
				}
295
			}
296
		);
297
298
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createSubscription',
299
			function (GenericEvent $event) use ($container, $serverContainer) {
300
				$jobList = $serverContainer->getJobList();
301
				$subscriptionData = $event->getArgument('subscriptionData');
302
303
				/**
304
				 * Initial subscription refetch
305
				 *
306
				 * @var RefreshWebcalService $refreshWebcalService
307
				 */
308
				$refreshWebcalService = $container->query(RefreshWebcalService::class);
309
				$refreshWebcalService->refreshSubscription(
310
					(string) $subscriptionData['principaluri'],
311
					(string) $subscriptionData['uri']
312
				);
313
314
				$jobList->add(\OCA\DAV\BackgroundJob\RefreshWebcalJob::class, [
315
					'principaluri' => $subscriptionData['principaluri'],
316
					'uri' => $subscriptionData['uri']
317
				]);
318
			}
319
		);
320
321
		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription',
322
			function (GenericEvent $event) use ($container, $serverContainer) {
323
				$jobList = $serverContainer->getJobList();
324
				$subscriptionData = $event->getArgument('subscriptionData');
325
326
				$jobList->remove(\OCA\DAV\BackgroundJob\RefreshWebcalJob::class, [
327
					'principaluri' => $subscriptionData['principaluri'],
328
					'uri' => $subscriptionData['uri']
329
				]);
330
331
				/** @var CalDavBackend $calDavBackend */
332
				$calDavBackend = $container->query(CalDavBackend::class);
333
				$calDavBackend->purgeAllCachedEventsForSubscription($subscriptionData['id']);
334
			}
335
		);
336
337
		$eventHandler = function () use ($container, $serverContainer) {
338
			try {
339
				/** @var UpdateCalendarResourcesRoomsBackgroundJob $job */
340
				$job = $container->query(UpdateCalendarResourcesRoomsBackgroundJob::class);
341
				$job->run([]);
342
				$serverContainer->getJobList()->setLastRun($job);
343
			} catch (Exception $ex) {
344
				$serverContainer->getLogger()->logException($ex);
345
			}
346
		};
347
348
		$dispatcher->addListener('\OCP\Calendar\Resource\ForceRefreshEvent', $eventHandler);
349
		$dispatcher->addListener('\OCP\Calendar\Room\ForceRefreshEvent', $eventHandler);
350
	}
351
352
	private function registerContactsManager(IContactsManager $cm, IAppContainer $container): void {
353
		$cm->register(function () use ($container, $cm): void {
354
			$user = \OC::$server->getUserSession()->getUser();
355
			if (!is_null($user)) {
356
				$this->setupContactsProvider($cm, $container, $user->getUID());
357
			} else {
358
				$this->setupSystemContactsProvider($cm, $container);
359
			}
360
		});
361
	}
362
363
	private function setupContactsProvider(IContactsManager $contactsManager,
364
										   IAppContainer $container,
365
										   string $userID): void {
366
		/** @var ContactsManager $cm */
367
		$cm = $container->query(ContactsManager::class);
368
		$urlGenerator = $container->getServer()->getURLGenerator();
369
		$cm->setupContactsProvider($contactsManager, $userID, $urlGenerator);
370
	}
371
372
	private function setupSystemContactsProvider(IContactsManager $contactsManager,
373
												 IAppContainer $container): void {
374
		/** @var ContactsManager $cm */
375
		$cm = $container->query(ContactsManager::class);
376
		$urlGenerator = $container->getServer()->getURLGenerator();
377
		$cm->setupSystemContactsProvider($contactsManager, $urlGenerator);
378
	}
379
380
	private function registerCalendarManager(ICalendarManager $calendarManager,
381
											 IAppContainer $container): void {
382
		$calendarManager->register(function () use ($container, $calendarManager) {
383
			$user = \OC::$server->getUserSession()->getUser();
384
			if ($user !== null) {
385
				$this->setupCalendarProvider($calendarManager, $container, $user->getUID());
386
			}
387
		});
388
	}
389
390
	private function setupCalendarProvider(ICalendarManager $calendarManager,
391
										   IAppContainer $container,
392
										   $userId) {
393
		$cm = $container->query(CalendarManager::class);
394
		$cm->setupCalendarProvider($calendarManager, $userId);
395
	}
396
397
	private function registerNotifier(INotificationManager $manager): void {
398
		$manager->registerNotifierService(Notifier::class);
399
	}
400
401
	private function registerCalendarReminders(NotificationProviderManager $manager,
402
											   ILogger $logger): void {
403
		try {
404
			$manager->registerProvider(AudioProvider::class);
405
			$manager->registerProvider(EmailProvider::class);
406
			$manager->registerProvider(PushProvider::class);
407
		} catch (Throwable $ex) {
408
			$logger->logException($ex);
409
		}
410
	}
411
}
412