Skip to content

Commit 7f3aa26

Browse files
author
tchapi
committed
Add automatic update
1 parent bfa6af3 commit 7f3aa26

3 files changed

Lines changed: 115 additions & 8 deletions

File tree

src/Controller/DAVController.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
use App\Entity\Principal;
66
use App\Entity\User;
7+
use App\Plugins\BirthdayCalendarPlugin;
78
use App\Plugins\DavisIMipPlugin;
89
use App\Plugins\PublicAwareDAVACLPlugin;
910
use App\Services\BasicAuth;
11+
use App\Services\BirthdayService;
1012
use App\Services\IMAPAuth;
1113
use App\Services\LDAPAuth;
1214
use Doctrine\ORM\EntityManagerInterface;
@@ -100,6 +102,11 @@ class DAVController extends AbstractController
100102
*/
101103
protected $mailer;
102104

105+
/**
106+
* @var BirthdayService
107+
*/
108+
protected $birthdayService;
109+
103110
/**
104111
* Base URI of the server.
105112
*
@@ -142,7 +149,7 @@ class DAVController extends AbstractController
142149
*/
143150
protected $server;
144151

145-
public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend, IMAPAuth $IMAPAuthBackend, LDAPAuth $LDAPAuthBackend, UrlGeneratorInterface $router, EntityManagerInterface $entityManager, LoggerInterface $logger, string $publicDir, bool $calDAVEnabled = true, bool $cardDAVEnabled = true, bool $webDAVEnabled = false, bool $publicCalendarsEnabled = true, ?string $inviteAddress = null, ?string $authMethod = null, ?string $authRealm = null, ?string $webdavPublicDir = null, ?string $webdavHomesDir = null, ?string $webdavTmpDir = null)
152+
public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend, IMAPAuth $IMAPAuthBackend, LDAPAuth $LDAPAuthBackend, UrlGeneratorInterface $router, EntityManagerInterface $entityManager, LoggerInterface $logger, BirthdayService $birthdayService, string $publicDir, bool $calDAVEnabled = true, bool $cardDAVEnabled = true, bool $webDAVEnabled = false, bool $publicCalendarsEnabled = true, ?string $inviteAddress = null, ?string $authMethod = null, ?string $authRealm = null, ?string $webdavPublicDir = null, ?string $webdavHomesDir = null, ?string $webdavTmpDir = null)
146153
{
147154
$this->publicDir = $publicDir;
148155

@@ -159,6 +166,7 @@ public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend
159166
$this->em = $entityManager;
160167
$this->logger = $logger;
161168
$this->mailer = $mailer;
169+
$this->birthdayService = $birthdayService;
162170
$this->baseUri = $router->generate('dav', ['path' => '']);
163171

164172
$this->basicAuthBackend = $basicAuthBackend;
@@ -272,6 +280,10 @@ private function initServer(string $authMethod, string $authRealm = User::DEFAUL
272280
$this->server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin());
273281
}
274282

283+
if ($this->cardDAVEnabled && $this->calDAVEnabled) {
284+
$this->server->addPlugin(new BirthdayCalendarPlugin($this->birthdayService));
285+
}
286+
275287
// WebDAV plugins
276288
if ($this->webDAVEnabled && $this->webdavTmpDir && $this->webdavPublicDir) {
277289
if (!is_dir($this->webdavTmpDir) || !is_dir($this->webdavPublicDir)) {
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace App\Plugins;
4+
5+
use App\Services\BirthdayService;
6+
use Sabre\CardDAV;
7+
use Sabre\DAV;
8+
9+
class BirthdayCalendarPlugin extends DAV\ServerPlugin
10+
{
11+
/**
12+
* @var BirthdayService
13+
*/
14+
protected $birthdayService;
15+
16+
/**
17+
* @var DAV\Server
18+
*/
19+
protected $server;
20+
21+
public function __construct(BirthdayService $birthdayService)
22+
{
23+
$this->birthdayService = $birthdayService;
24+
}
25+
26+
public function initialize(DAV\Server $server)
27+
{
28+
$this->server = $server;
29+
30+
// Hook into card creation
31+
$server->on('afterCreateFile', [$this, 'afterCardCreate']);
32+
33+
// Hook into card updates
34+
$server->on('afterWriteContent', [$this, 'afterCardUpdate']);
35+
36+
// Hook into card deletion
37+
// Note: The node no longer exists at afterCardDelete so we
38+
// use beforeCardDelete for simplicity
39+
$server->on('beforeUnbind', [$this, 'beforeCardDelete']);
40+
}
41+
42+
private function resyncCurrentPrincipal()
43+
{
44+
$authPlugin = $this->server->getPlugin('auth');
45+
46+
if (!$authPlugin) {
47+
return null;
48+
}
49+
50+
$principal = $authPlugin->getCurrentPrincipal();
51+
52+
if ($principal) {
53+
$this->birthdayService->syncPrincipal($principal);
54+
}
55+
}
56+
57+
public function afterCardCreate($path, DAV\ICollection $parentNode)
58+
{
59+
if (!$parentNode instanceof CardDAV\IAddressBook) {
60+
return;
61+
}
62+
63+
$principal = $this->resyncCurrentPrincipal();
64+
}
65+
66+
public function afterCardUpdate($path, DAV\IFile $node)
67+
{
68+
if (!$node instanceof CardDAV\ICard) {
69+
return;
70+
}
71+
72+
$principal = $this->resyncCurrentPrincipal();
73+
}
74+
75+
public function beforeCardDelete($path)
76+
{
77+
$node = $this->server->tree->getNodeForPath($path);
78+
79+
if (!$node instanceof CardDAV\ICard) {
80+
return;
81+
}
82+
83+
$principal = $this->resyncCurrentPrincipal();
84+
}
85+
86+
public function getPluginName(): string
87+
{
88+
return 'birthday-calendar';
89+
}
90+
}

src/Services/BirthdayService.php

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ public function buildDataFromContact(string $cardData): ?VCalendar
239239
return $vCal;
240240
}
241241

242-
public function resetForUser(string $username): void
242+
public function resetForPrincipal(string $principal): void
243243
{
244-
$calendarInstance = $this->doctrine->getRepository(CalendarInstance::class)->findOneBy(['principalUri' => Principal::PREFIX.$username, 'uri' => Constants::BIRTHDAY_CALENDAR_URI]);
244+
$calendarInstance = $this->doctrine->getRepository(CalendarInstance::class)->findOneBy(['principalUri' => $principal, 'uri' => Constants::BIRTHDAY_CALENDAR_URI]);
245245

246246
if (!$calendarInstance) {
247247
return; // The user's birthday calendar doesn't exist, no need to purge it
@@ -259,19 +259,24 @@ public function resetForUser(string $username): void
259259

260260
public function syncUser(string $username): void
261261
{
262-
if (!$this->shouldBirthdayCalendarExist(Principal::PREFIX.$username)) {
263-
$this->deleteBirthdayCalendar(Principal::PREFIX.$username);
262+
$this->syncPrincipal(Principal::PREFIX.$username);
263+
}
264+
265+
public function syncPrincipal(string $principal): void
266+
{
267+
if (!$this->shouldBirthdayCalendarExist($principal)) {
268+
$this->deleteBirthdayCalendar($principal);
264269

265270
return;
266271
}
267272

268-
$calendarInstance = $this->ensureBirthdayCalendarExists(Principal::PREFIX.$username);
273+
$calendarInstance = $this->ensureBirthdayCalendarExists($principal);
269274

270275
// Reset the calendar
271-
$this->resetForUser($username);
276+
$this->resetForPrincipal($principal);
272277

273278
// Get all address books that should be included and iterate
274-
$addressbooks = $this->doctrine->getRepository(AddressBook::class)->findBy(['principalUri' => Principal::PREFIX.$username, 'includedInBirthdayCalendar' => true]);
279+
$addressbooks = $this->doctrine->getRepository(AddressBook::class)->findBy(['principalUri' => $principal, 'includedInBirthdayCalendar' => true]);
275280
foreach ($addressbooks as $book) {
276281
$cards = $this->doctrine->getRepository(Card::class)->findByAddressBook($book);
277282

0 commit comments

Comments
 (0)